1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
7 * Copyright (c) 2017 Google Inc.
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Multisample Tests
24 *//*--------------------------------------------------------------------*/
25
26 #include "vktPipelineMultisampleTests.hpp"
27 #include "vktPipelineMultisampleImageTests.hpp"
28 #include "vktPipelineMultisampleSampleLocationsExtTests.hpp"
29 #include "vktPipelineMultisampleMixedAttachmentSamplesTests.hpp"
30 #include "vktPipelineMultisampleShaderFragmentMaskTests.hpp"
31 #include "vktPipelineClearUtil.hpp"
32 #include "vktPipelineImageUtil.hpp"
33 #include "vktPipelineVertexUtil.hpp"
34 #include "vktPipelineReferenceRenderer.hpp"
35 #include "vktTestCase.hpp"
36 #include "vktTestCaseUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkMemUtil.hpp"
39 #include "vkPrograms.hpp"
40 #include "vkQueryUtil.hpp"
41 #include "vkRef.hpp"
42 #include "vkRefUtil.hpp"
43 #include "vkCmdUtil.hpp"
44 #include "vkTypeUtil.hpp"
45 #include "vkObjUtil.hpp"
46 #include "vkBufferWithMemory.hpp"
47 #include "vkImageWithMemory.hpp"
48 #include "vkBuilderUtil.hpp"
49 #include "vkBarrierUtil.hpp"
50 #include "tcuImageCompare.hpp"
51 #include "tcuTestLog.hpp"
52 #include "deUniquePtr.hpp"
53 #include "deSharedPtr.hpp"
54 #include "deStringUtil.hpp"
55 #include "deMemory.h"
56
57 #include <sstream>
58 #include <vector>
59 #include <map>
60 #include <memory>
61 #include <algorithm>
62 #include <set>
63 #include <array>
64
65 namespace vkt
66 {
67 namespace pipeline
68 {
69
70 using namespace vk;
71
72 namespace
73 {
74 enum GeometryType
75 {
76 GEOMETRY_TYPE_OPAQUE_TRIANGLE,
77 GEOMETRY_TYPE_OPAQUE_LINE,
78 GEOMETRY_TYPE_OPAQUE_POINT,
79 GEOMETRY_TYPE_OPAQUE_QUAD,
80 GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH, //!< placed at z = 0.5
81 GEOMETRY_TYPE_TRANSLUCENT_QUAD,
82 GEOMETRY_TYPE_INVISIBLE_TRIANGLE,
83 GEOMETRY_TYPE_INVISIBLE_QUAD,
84 GEOMETRY_TYPE_GRADIENT_QUAD
85 };
86
87 enum TestModeBits
88 {
89 TEST_MODE_DEPTH_BIT = 1u,
90 TEST_MODE_STENCIL_BIT = 2u,
91 };
92 typedef deUint32 TestModeFlags;
93
94 enum RenderType
95 {
96 // resolve multisample rendering to single sampled image
97 RENDER_TYPE_RESOLVE = 0u,
98
99 // copy samples to an array of single sampled images
100 RENDER_TYPE_COPY_SAMPLES = 1u,
101
102 // render first with only depth/stencil and then with color + depth/stencil
103 RENDER_TYPE_DEPTHSTENCIL_ONLY = 2u,
104
105 // render using color attachment at location 1 and location 0 set as unused
106 RENDER_TYPE_UNUSED_ATTACHMENT = 3u
107 };
108
109 enum ImageBackingMode
110 {
111 IMAGE_BACKING_MODE_REGULAR = 0u,
112 IMAGE_BACKING_MODE_SPARSE
113 };
114
115 struct MultisampleTestParams
116 {
117 GeometryType geometryType;
118 float pointSize;
119 ImageBackingMode backingMode;
120 };
121
122 void initMultisamplePrograms (SourceCollections& sources, MultisampleTestParams params);
123 bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples);
124 bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format);
125 VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void);
126 deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image);
127 VkImageAspectFlags getImageAspectFlags (const VkFormat format);
128 VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType);
129 std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType);
130 VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil);
131
132 class MultisampleTest : public vkt::TestCase
133 {
134 public:
135
136 MultisampleTest (tcu::TestContext& testContext,
137 const std::string& name,
138 const std::string& description,
139 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
140 const VkPipelineColorBlendAttachmentState& blendState,
141 GeometryType geometryType,
142 float pointSize,
143 ImageBackingMode backingMode);
~MultisampleTest(void)144 virtual ~MultisampleTest (void) {}
145
146 virtual void initPrograms (SourceCollections& programCollection) const;
147 virtual TestInstance* createInstance (Context& context) const;
148 virtual void checkSupport (Context& context) const;
149
150 protected:
151 virtual TestInstance* createMultisampleTestInstance (Context& context,
152 VkPrimitiveTopology topology,
153 float pointSize,
154 const std::vector<Vertex4RGBA>& vertices,
155 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
156 const VkPipelineColorBlendAttachmentState& colorBlendState) const = 0;
157 VkPipelineMultisampleStateCreateInfo m_multisampleStateParams;
158 const VkPipelineColorBlendAttachmentState m_colorBlendState;
159 const GeometryType m_geometryType;
160 const float m_pointSize;
161 const ImageBackingMode m_backingMode;
162 std::vector<VkSampleMask> m_sampleMask;
163 };
164
165 class RasterizationSamplesTest : public MultisampleTest
166 {
167 public:
168 RasterizationSamplesTest (tcu::TestContext& testContext,
169 const std::string& name,
170 const std::string& description,
171 VkSampleCountFlagBits rasterizationSamples,
172 GeometryType geometryType,
173 float pointSize,
174 ImageBackingMode backingMode,
175 TestModeFlags modeFlags = 0u);
~RasterizationSamplesTest(void)176 virtual ~RasterizationSamplesTest (void) {}
177
178 protected:
179 virtual TestInstance* createMultisampleTestInstance (Context& context,
180 VkPrimitiveTopology topology,
181 float pointSize,
182 const std::vector<Vertex4RGBA>& vertices,
183 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
184 const VkPipelineColorBlendAttachmentState& colorBlendState) const;
185
186 static VkPipelineMultisampleStateCreateInfo getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples);
187
188 const ImageBackingMode m_backingMode;
189 const TestModeFlags m_modeFlags;
190 };
191
192 class MinSampleShadingTest : public MultisampleTest
193 {
194 public:
195 MinSampleShadingTest (tcu::TestContext& testContext,
196 const std::string& name,
197 const std::string& description,
198 VkSampleCountFlagBits rasterizationSamples,
199 float minSampleShading,
200 GeometryType geometryType,
201 float pointSize,
202 ImageBackingMode backingMode,
203 const bool minSampleShadingEnabled = true);
~MinSampleShadingTest(void)204 virtual ~MinSampleShadingTest (void) {}
205
206 protected:
207 virtual void initPrograms (SourceCollections& programCollection) const;
208 virtual void checkSupport (Context& context) const;
209 virtual TestInstance* createMultisampleTestInstance (Context& context,
210 VkPrimitiveTopology topology,
211 float pointSize,
212 const std::vector<Vertex4RGBA>& vertices,
213 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
214 const VkPipelineColorBlendAttachmentState& colorBlendState) const;
215
216 static VkPipelineMultisampleStateCreateInfo getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples,
217 float minSampleShading,
218 bool minSampleShadingEnabled);
219
220 const float m_pointSize;
221 const ImageBackingMode m_backingMode;
222 const bool m_minSampleShadingEnabled;
223 };
224
225 class SampleMaskTest : public MultisampleTest
226 {
227 public:
228 SampleMaskTest (tcu::TestContext& testContext,
229 const std::string& name,
230 const std::string& description,
231 VkSampleCountFlagBits rasterizationSamples,
232 const std::vector<VkSampleMask>& sampleMask,
233 GeometryType geometryType,
234 float pointSize,
235 ImageBackingMode backingMode);
236
~SampleMaskTest(void)237 virtual ~SampleMaskTest (void) {}
238
239 protected:
240 virtual TestInstance* createMultisampleTestInstance (Context& context,
241 VkPrimitiveTopology topology,
242 float pointSize,
243 const std::vector<Vertex4RGBA>& vertices,
244 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
245 const VkPipelineColorBlendAttachmentState& colorBlendState) const;
246
247 static VkPipelineMultisampleStateCreateInfo getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask);
248
249 const ImageBackingMode m_backingMode;
250 };
251
252 class AlphaToOneTest : public MultisampleTest
253 {
254 public:
255 AlphaToOneTest (tcu::TestContext& testContext,
256 const std::string& name,
257 const std::string& description,
258 VkSampleCountFlagBits rasterizationSamples,
259 ImageBackingMode backingMode);
260
~AlphaToOneTest(void)261 virtual ~AlphaToOneTest (void) {}
262
263 protected:
264 virtual void checkSupport (Context& context) const;
265 virtual TestInstance* createMultisampleTestInstance (Context& context,
266 VkPrimitiveTopology topology,
267 float pointSize,
268 const std::vector<Vertex4RGBA>& vertices,
269 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
270 const VkPipelineColorBlendAttachmentState& colorBlendState) const;
271
272 static VkPipelineMultisampleStateCreateInfo getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples);
273 static VkPipelineColorBlendAttachmentState getAlphaToOneBlendState (void);
274
275 const ImageBackingMode m_backingMode;
276 };
277
278 class AlphaToCoverageTest : public MultisampleTest
279 {
280 public:
281 AlphaToCoverageTest (tcu::TestContext& testContext,
282 const std::string& name,
283 const std::string& description,
284 VkSampleCountFlagBits rasterizationSamples,
285 GeometryType geometryType,
286 ImageBackingMode backingMode);
287
~AlphaToCoverageTest(void)288 virtual ~AlphaToCoverageTest (void) {}
289
290 protected:
291 virtual TestInstance* createMultisampleTestInstance (Context& context,
292 VkPrimitiveTopology topology,
293 float pointSize,
294 const std::vector<Vertex4RGBA>& vertices,
295 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
296 const VkPipelineColorBlendAttachmentState& colorBlendState) const;
297
298 static VkPipelineMultisampleStateCreateInfo getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples);
299
300 GeometryType m_geometryType;
301 const ImageBackingMode m_backingMode;
302 };
303
304 class AlphaToCoverageNoColorAttachmentTest : public MultisampleTest
305 {
306 public:
307 AlphaToCoverageNoColorAttachmentTest (tcu::TestContext& testContext,
308 const std::string& name,
309 const std::string& description,
310 VkSampleCountFlagBits rasterizationSamples,
311 GeometryType geometryType,
312 ImageBackingMode backingMode);
313
~AlphaToCoverageNoColorAttachmentTest(void)314 virtual ~AlphaToCoverageNoColorAttachmentTest (void) {}
315
316 protected:
317 virtual TestInstance* createMultisampleTestInstance (Context& context,
318 VkPrimitiveTopology topology,
319 float pointSize,
320 const std::vector<Vertex4RGBA>& vertices,
321 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
322 const VkPipelineColorBlendAttachmentState& colorBlendState) const;
323
324 static VkPipelineMultisampleStateCreateInfo getStateParams (VkSampleCountFlagBits rasterizationSamples);
325
326 GeometryType m_geometryType;
327 const ImageBackingMode m_backingMode;
328 };
329
330 class AlphaToCoverageColorUnusedAttachmentTest : public MultisampleTest
331 {
332 public:
333 AlphaToCoverageColorUnusedAttachmentTest (tcu::TestContext& testContext,
334 const std::string& name,
335 const std::string& description,
336 VkSampleCountFlagBits rasterizationSamples,
337 GeometryType geometryType,
338 ImageBackingMode backingMode);
339
~AlphaToCoverageColorUnusedAttachmentTest(void)340 virtual ~AlphaToCoverageColorUnusedAttachmentTest (void) {}
341
342 protected:
343 virtual void initPrograms (SourceCollections& programCollection) const;
344
345 virtual TestInstance* createMultisampleTestInstance (Context& context,
346 VkPrimitiveTopology topology,
347 float pointSize,
348 const std::vector<Vertex4RGBA>& vertices,
349 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
350 const VkPipelineColorBlendAttachmentState& colorBlendState) const;
351
352 static VkPipelineMultisampleStateCreateInfo getStateParams (VkSampleCountFlagBits rasterizationSamples);
353
354 GeometryType m_geometryType;
355 const ImageBackingMode m_backingMode;
356 };
357
358 class SampleMaskWithDepthTestTest : public vkt::TestCase
359 {
360 public:
361 SampleMaskWithDepthTestTest (tcu::TestContext& testContext,
362 const std::string& name,
363 const std::string& description,
364 const VkSampleCountFlagBits rasterizationSamples,
365 const bool enablePostDepthCoverage = false);
366
~SampleMaskWithDepthTestTest(void)367 ~SampleMaskWithDepthTestTest (void) {}
368
369 void initPrograms (SourceCollections& programCollection) const;
370 TestInstance* createInstance (Context& context) const;
371 virtual void checkSupport (Context& context) const;
372 private:
373 const VkSampleCountFlagBits m_rasterizationSamples;
374 const bool m_enablePostDepthCoverage;
375 };
376
377 typedef de::SharedPtr<Unique<VkPipeline> > VkPipelineSp;
378
379 class MultisampleRenderer
380 {
381 public:
382 MultisampleRenderer (Context& context,
383 const VkFormat colorFormat,
384 const tcu::IVec2& renderSize,
385 const VkPrimitiveTopology topology,
386 const std::vector<Vertex4RGBA>& vertices,
387 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
388 const VkPipelineColorBlendAttachmentState& blendState,
389 const RenderType renderType,
390 const ImageBackingMode backingMode);
391
392 MultisampleRenderer (Context& context,
393 const VkFormat colorFormat,
394 const VkFormat depthStencilFormat,
395 const tcu::IVec2& renderSize,
396 const bool useDepth,
397 const bool useStencil,
398 const deUint32 numTopologies,
399 const VkPrimitiveTopology* pTopology,
400 const std::vector<Vertex4RGBA>* pVertices,
401 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
402 const VkPipelineColorBlendAttachmentState& blendState,
403 const RenderType renderType,
404 const ImageBackingMode backingMode,
405 const float depthClearValue = 1.0f);
406
407 virtual ~MultisampleRenderer (void);
408
409 de::MovePtr<tcu::TextureLevel> render (void);
410 de::MovePtr<tcu::TextureLevel> getSingleSampledImage (deUint32 sampleId);
411
412 protected:
413 void initialize (Context& context,
414 const deUint32 numTopologies,
415 const VkPrimitiveTopology* pTopology,
416 const std::vector<Vertex4RGBA>* pVertices);
417
418 Context& m_context;
419
420 const Unique<VkSemaphore> m_bindSemaphore;
421
422 const VkFormat m_colorFormat;
423 const VkFormat m_depthStencilFormat;
424 tcu::IVec2 m_renderSize;
425 const bool m_useDepth;
426 const bool m_useStencil;
427
428 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams;
429 const VkPipelineColorBlendAttachmentState m_colorBlendState;
430
431 const RenderType m_renderType;
432
433 Move<VkImage> m_colorImage;
434 de::MovePtr<Allocation> m_colorImageAlloc;
435 Move<VkImageView> m_colorAttachmentView;
436
437 Move<VkImage> m_resolveImage;
438 de::MovePtr<Allocation> m_resolveImageAlloc;
439 Move<VkImageView> m_resolveAttachmentView;
440
441 struct PerSampleImage
442 {
443 Move<VkImage> m_image;
444 de::MovePtr<Allocation> m_imageAlloc;
445 Move<VkImageView> m_attachmentView;
446 };
447 std::vector<de::SharedPtr<PerSampleImage> > m_perSampleImages;
448
449 Move<VkImage> m_depthStencilImage;
450 de::MovePtr<Allocation> m_depthStencilImageAlloc;
451 Move<VkImageView> m_depthStencilAttachmentView;
452
453 Move<VkRenderPass> m_renderPass;
454 Move<VkFramebuffer> m_framebuffer;
455
456 Move<VkShaderModule> m_vertexShaderModule;
457 Move<VkShaderModule> m_fragmentShaderModule;
458
459 Move<VkShaderModule> m_copySampleVertexShaderModule;
460 Move<VkShaderModule> m_copySampleFragmentShaderModule;
461
462 Move<VkBuffer> m_vertexBuffer;
463 de::MovePtr<Allocation> m_vertexBufferAlloc;
464
465 Move<VkPipelineLayout> m_pipelineLayout;
466 std::vector<VkPipelineSp> m_graphicsPipelines;
467
468 Move<VkDescriptorSetLayout> m_copySampleDesciptorLayout;
469 Move<VkDescriptorPool> m_copySampleDesciptorPool;
470 Move<VkDescriptorSet> m_copySampleDesciptorSet;
471
472 Move<VkPipelineLayout> m_copySamplePipelineLayout;
473 std::vector<VkPipelineSp> m_copySamplePipelines;
474
475 Move<VkCommandPool> m_cmdPool;
476 Move<VkCommandBuffer> m_cmdBuffer;
477
478 std::vector<de::SharedPtr<Allocation> > m_allocations;
479
480 ImageBackingMode m_backingMode;
481 const float m_depthClearValue;
482 };
483
484 class RasterizationSamplesInstance : public vkt::TestInstance
485 {
486 public:
487 RasterizationSamplesInstance (Context& context,
488 VkPrimitiveTopology topology,
489 float pointSize,
490 const std::vector<Vertex4RGBA>& vertices,
491 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
492 const VkPipelineColorBlendAttachmentState& blendState,
493 const TestModeFlags modeFlags,
494 ImageBackingMode backingMode);
~RasterizationSamplesInstance(void)495 virtual ~RasterizationSamplesInstance (void) {}
496
497 virtual tcu::TestStatus iterate (void);
498
499 protected:
500 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result);
501
502 const VkFormat m_colorFormat;
503 const tcu::IVec2 m_renderSize;
504 const VkPrimitiveTopology m_primitiveTopology;
505 const float m_pointSize;
506 const std::vector<Vertex4RGBA> m_vertices;
507 const std::vector<Vertex4RGBA> m_fullQuadVertices; //!< used by depth/stencil case
508 const TestModeFlags m_modeFlags;
509 de::MovePtr<MultisampleRenderer> m_multisampleRenderer;
510 };
511
512 class MinSampleShadingInstance : public vkt::TestInstance
513 {
514 public:
515 MinSampleShadingInstance (Context& context,
516 VkPrimitiveTopology topology,
517 float pointSize,
518 const std::vector<Vertex4RGBA>& vertices,
519 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
520 const VkPipelineColorBlendAttachmentState& blendState,
521 ImageBackingMode backingMode);
~MinSampleShadingInstance(void)522 virtual ~MinSampleShadingInstance (void) {}
523
524 virtual tcu::TestStatus iterate (void);
525
526 protected:
527 virtual tcu::TestStatus verifySampleShadedImage (const std::vector<tcu::TextureLevel>& testShadingImages,
528 const tcu::ConstPixelBufferAccess& noSampleshadingImage);
529
530 const VkFormat m_colorFormat;
531 const tcu::IVec2 m_renderSize;
532 const VkPrimitiveTopology m_primitiveTopology;
533 const std::vector<Vertex4RGBA> m_vertices;
534 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams;
535 const VkPipelineColorBlendAttachmentState m_colorBlendState;
536 const ImageBackingMode m_backingMode;
537 };
538
539 class MinSampleShadingDisabledInstance : public MinSampleShadingInstance
540 {
541 public:
542 MinSampleShadingDisabledInstance (Context& context,
543 VkPrimitiveTopology topology,
544 float pointSize,
545 const std::vector<Vertex4RGBA>& vertices,
546 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
547 const VkPipelineColorBlendAttachmentState& blendState,
548 ImageBackingMode backingMode);
~MinSampleShadingDisabledInstance(void)549 virtual ~MinSampleShadingDisabledInstance (void) {}
550
551 protected:
552 virtual tcu::TestStatus verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages,
553 const tcu::ConstPixelBufferAccess& noSampleshadingImage);
554 };
555
556 class SampleMaskInstance : public vkt::TestInstance
557 {
558 public:
559 SampleMaskInstance (Context& context,
560 VkPrimitiveTopology topology,
561 float pointSize,
562 const std::vector<Vertex4RGBA>& vertices,
563 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
564 const VkPipelineColorBlendAttachmentState& blendState,
565 ImageBackingMode backingMode);
~SampleMaskInstance(void)566 virtual ~SampleMaskInstance (void) {}
567
568 virtual tcu::TestStatus iterate (void);
569
570 protected:
571 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& testShadingImage,
572 const tcu::ConstPixelBufferAccess& minShadingImage,
573 const tcu::ConstPixelBufferAccess& maxShadingImage);
574 const VkFormat m_colorFormat;
575 const tcu::IVec2 m_renderSize;
576 const VkPrimitiveTopology m_primitiveTopology;
577 const std::vector<Vertex4RGBA> m_vertices;
578 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams;
579 const VkPipelineColorBlendAttachmentState m_colorBlendState;
580 const ImageBackingMode m_backingMode;
581 };
582
583 class AlphaToOneInstance : public vkt::TestInstance
584 {
585 public:
586 AlphaToOneInstance (Context& context,
587 VkPrimitiveTopology topology,
588 const std::vector<Vertex4RGBA>& vertices,
589 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
590 const VkPipelineColorBlendAttachmentState& blendState,
591 ImageBackingMode backingMode);
~AlphaToOneInstance(void)592 virtual ~AlphaToOneInstance (void) {}
593
594 virtual tcu::TestStatus iterate (void);
595
596 protected:
597 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& alphaOneImage,
598 const tcu::ConstPixelBufferAccess& noAlphaOneImage);
599 const VkFormat m_colorFormat;
600 const tcu::IVec2 m_renderSize;
601 const VkPrimitiveTopology m_primitiveTopology;
602 const std::vector<Vertex4RGBA> m_vertices;
603 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams;
604 const VkPipelineColorBlendAttachmentState m_colorBlendState;
605 const ImageBackingMode m_backingMode;
606 };
607
608 class AlphaToCoverageInstance : public vkt::TestInstance
609 {
610 public:
611 AlphaToCoverageInstance (Context& context,
612 VkPrimitiveTopology topology,
613 const std::vector<Vertex4RGBA>& vertices,
614 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
615 const VkPipelineColorBlendAttachmentState& blendState,
616 GeometryType geometryType,
617 ImageBackingMode backingMode);
~AlphaToCoverageInstance(void)618 virtual ~AlphaToCoverageInstance (void) {}
619
620 virtual tcu::TestStatus iterate (void);
621
622 protected:
623 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result);
624 const VkFormat m_colorFormat;
625 const tcu::IVec2 m_renderSize;
626 const VkPrimitiveTopology m_primitiveTopology;
627 const std::vector<Vertex4RGBA> m_vertices;
628 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams;
629 const VkPipelineColorBlendAttachmentState m_colorBlendState;
630 const GeometryType m_geometryType;
631 const ImageBackingMode m_backingMode;
632 };
633
634 class AlphaToCoverageNoColorAttachmentInstance : public vkt::TestInstance
635 {
636 public:
637 AlphaToCoverageNoColorAttachmentInstance (Context& context,
638 VkPrimitiveTopology topology,
639 const std::vector<Vertex4RGBA>& vertices,
640 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
641 const VkPipelineColorBlendAttachmentState& blendState,
642 GeometryType geometryType,
643 ImageBackingMode backingMode);
~AlphaToCoverageNoColorAttachmentInstance(void)644 virtual ~AlphaToCoverageNoColorAttachmentInstance (void) {}
645
646 virtual tcu::TestStatus iterate (void);
647
648 protected:
649 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result);
650 const VkFormat m_colorFormat;
651 const VkFormat m_depthStencilFormat;
652 const tcu::IVec2 m_renderSize;
653 const VkPrimitiveTopology m_primitiveTopology;
654 const std::vector<Vertex4RGBA> m_vertices;
655 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams;
656 const VkPipelineColorBlendAttachmentState m_colorBlendState;
657 const GeometryType m_geometryType;
658 const ImageBackingMode m_backingMode;
659 };
660
661 class AlphaToCoverageColorUnusedAttachmentInstance : public vkt::TestInstance
662 {
663 public:
664 AlphaToCoverageColorUnusedAttachmentInstance (Context& context,
665 VkPrimitiveTopology topology,
666 const std::vector<Vertex4RGBA>& vertices,
667 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
668 const VkPipelineColorBlendAttachmentState& blendState,
669 GeometryType geometryType,
670 ImageBackingMode backingMode);
~AlphaToCoverageColorUnusedAttachmentInstance(void)671 virtual ~AlphaToCoverageColorUnusedAttachmentInstance (void) {}
672
673 virtual tcu::TestStatus iterate (void);
674
675 protected:
676 virtual tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result);
677 const VkFormat m_colorFormat;
678 const tcu::IVec2 m_renderSize;
679 const VkPrimitiveTopology m_primitiveTopology;
680 const std::vector<Vertex4RGBA> m_vertices;
681 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams;
682 const VkPipelineColorBlendAttachmentState m_colorBlendState;
683 const GeometryType m_geometryType;
684 const ImageBackingMode m_backingMode;
685 };
686
687 class SampleMaskWithDepthTestInstance : public vkt::TestInstance
688 {
689 public:
690 SampleMaskWithDepthTestInstance (Context& context,
691 const VkSampleCountFlagBits rasterizationSamples,
692 const bool enablePostDepthCoverage);
~SampleMaskWithDepthTestInstance(void)693 ~SampleMaskWithDepthTestInstance (void) {}
694
695 tcu::TestStatus iterate (void);
696
697 protected:
698 VkPipelineMultisampleStateCreateInfo getMultisampleState (const VkSampleCountFlagBits rasterizationSamples);
699 std::vector<Vertex4RGBA> generateVertices (void);
700 tcu::TestStatus verifyImage (const tcu::ConstPixelBufferAccess& result);
701
702 struct SampleCoverage
703 {
SampleCoveragevkt::pipeline::__anon16de12d60111::SampleMaskWithDepthTestInstance::SampleCoverage704 SampleCoverage() {};
SampleCoveragevkt::pipeline::__anon16de12d60111::SampleMaskWithDepthTestInstance::SampleCoverage705 SampleCoverage(deUint32 min_, deUint32 max_)
706 : min(min_), max(max_) {};
707
708 deUint32 min;
709 deUint32 max;
710 };
711
712 const VkSampleCountFlagBits m_rasterizationSamples;
713 const bool m_enablePostDepthCoverage;
714 const VkFormat m_colorFormat;
715 const VkFormat m_depthStencilFormat;
716 const tcu::IVec2 m_renderSize;
717 const bool m_useDepth;
718 const bool m_useStencil;
719 const VkPrimitiveTopology m_topology;
720 const tcu::Vec4 m_renderColor;
721 const std::vector<Vertex4RGBA> m_vertices;
722 const VkPipelineMultisampleStateCreateInfo m_multisampleStateParams;
723 const VkPipelineColorBlendAttachmentState m_blendState;
724 const RenderType m_renderType;
725 const ImageBackingMode m_imageBackingMode;
726 const float m_depthClearValue;
727 std::map<VkSampleCountFlagBits, SampleCoverage> m_refCoverageAfterDepthTest;
728 };
729
730
731 // Helper functions
732
initMultisamplePrograms(SourceCollections & sources,MultisampleTestParams params)733 void initMultisamplePrograms (SourceCollections& sources, MultisampleTestParams params)
734 {
735 const std::string pointSize = params.geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? (std::string(" gl_PointSize = ") + de::toString(params.pointSize) + ".0f;\n") : std::string("");
736 std::ostringstream vertexSource;
737
738 vertexSource <<
739 "#version 310 es\n"
740 "layout(location = 0) in vec4 position;\n"
741 "layout(location = 1) in vec4 color;\n"
742 "layout(location = 0) out highp vec4 vtxColor;\n"
743 "void main (void)\n"
744 "{\n"
745 " gl_Position = position;\n"
746 " vtxColor = color;\n"
747 << pointSize
748 << "}\n";
749
750 static const char* fragmentSource =
751 "#version 310 es\n"
752 "layout(location = 0) in highp vec4 vtxColor;\n"
753 "layout(location = 0) out highp vec4 fragColor;\n"
754 "void main (void)\n"
755 "{\n"
756 " fragColor = vtxColor;\n"
757 "}\n";
758
759 sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
760 sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
761 }
762
initSampleShadingPrograms(SourceCollections & sources,MultisampleTestParams params)763 void initSampleShadingPrograms (SourceCollections& sources, MultisampleTestParams params)
764 {
765 {
766 const std::string pointSize = params.geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? (std::string(" gl_PointSize = ") + de::toString(params.pointSize) + ".0f;\n") : std::string("");
767 std::ostringstream vertexSource;
768
769 vertexSource <<
770 "#version 440\n"
771 "layout(location = 0) in vec4 position;\n"
772 "layout(location = 1) in vec4 color;\n"
773 "void main (void)\n"
774 "{\n"
775 " gl_Position = position;\n"
776 << pointSize
777 << "}\n";
778
779 static const char* fragmentSource =
780 "#version 440\n"
781 "layout(location = 0) out highp vec4 fragColor;\n"
782 "void main (void)\n"
783 "{\n"
784 " fragColor = vec4(fract(gl_FragCoord.xy), 0.0, 1.0);\n"
785 "}\n";
786
787 sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
788 sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
789 }
790
791 {
792 static const char* vertexSource =
793 "#version 440\n"
794 "void main (void)\n"
795 "{\n"
796 " const vec4 positions[4] = vec4[4](\n"
797 " vec4(-1.0, -1.0, 0.0, 1.0),\n"
798 " vec4(-1.0, 1.0, 0.0, 1.0),\n"
799 " vec4( 1.0, -1.0, 0.0, 1.0),\n"
800 " vec4( 1.0, 1.0, 0.0, 1.0)\n"
801 " );\n"
802 " gl_Position = positions[gl_VertexIndex];\n"
803 "}\n";
804
805 static const char* fragmentSource =
806 "#version 440\n"
807 "precision highp float;\n"
808 "layout(location = 0) out highp vec4 fragColor;\n"
809 "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n"
810 "layout(push_constant) uniform PushConstantsBlock\n"
811 "{\n"
812 " int sampleId;\n"
813 "} pushConstants;\n"
814 "void main (void)\n"
815 "{\n"
816 " fragColor = subpassLoad(imageMS, pushConstants.sampleId);\n"
817 "}\n";
818
819 sources.glslSources.add("quad_vert") << glu::VertexSource(vertexSource);
820 sources.glslSources.add("copy_sample_frag") << glu::FragmentSource(fragmentSource);
821 }
822 }
823
initAlphaToCoverageColorUnusedAttachmentPrograms(SourceCollections & sources)824 void initAlphaToCoverageColorUnusedAttachmentPrograms (SourceCollections& sources)
825 {
826 std::ostringstream vertexSource;
827
828 vertexSource <<
829 "#version 310 es\n"
830 "layout(location = 0) in vec4 position;\n"
831 "layout(location = 1) in vec4 color;\n"
832 "layout(location = 0) out highp vec4 vtxColor;\n"
833 "void main (void)\n"
834 "{\n"
835 " gl_Position = position;\n"
836 " vtxColor = color;\n"
837 "}\n";
838
839 // Location 0 is unused, but the alpha for coverage is written there. Location 1 has no alpha channel.
840 static const char* fragmentSource =
841 "#version 310 es\n"
842 "layout(location = 0) in highp vec4 vtxColor;\n"
843 "layout(location = 0) out highp vec4 fragColor0;\n"
844 "layout(location = 1) out highp vec3 fragColor1;\n"
845 "void main (void)\n"
846 "{\n"
847 " fragColor0 = vtxColor;\n"
848 " fragColor1 = vtxColor.rgb;\n"
849 "}\n";
850
851 sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
852 sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
853 }
854
isSupportedSampleCount(const InstanceInterface & instanceInterface,VkPhysicalDevice physicalDevice,VkSampleCountFlagBits rasterizationSamples)855 bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples)
856 {
857 VkPhysicalDeviceProperties deviceProperties;
858
859 instanceInterface.getPhysicalDeviceProperties(physicalDevice, &deviceProperties);
860
861 return !!(deviceProperties.limits.framebufferColorSampleCounts & rasterizationSamples);
862 }
863
getDefaultColorBlendAttachmentState(void)864 VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void)
865 {
866 const VkPipelineColorBlendAttachmentState colorBlendState =
867 {
868 false, // VkBool32 blendEnable;
869 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
870 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
871 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
872 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
873 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
874 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
875 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask;
876 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
877 };
878
879 return colorBlendState;
880 }
881
getUniqueColorsCount(const tcu::ConstPixelBufferAccess & image)882 deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image)
883 {
884 DE_ASSERT(image.getFormat().getPixelSize() == 4);
885
886 std::map<deUint32, deUint32> histogram; // map<pixel value, number of occurrences>
887 const deUint32 pixelCount = image.getWidth() * image.getHeight() * image.getDepth();
888
889 for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
890 {
891 const deUint32 pixelValue = *((const deUint32*)image.getDataPtr() + pixelNdx);
892
893 if (histogram.find(pixelValue) != histogram.end())
894 histogram[pixelValue]++;
895 else
896 histogram[pixelValue] = 1;
897 }
898
899 return (deUint32)histogram.size();
900 }
901
getImageAspectFlags(const VkFormat format)902 VkImageAspectFlags getImageAspectFlags (const VkFormat format)
903 {
904 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
905
906 if (tcuFormat.order == tcu::TextureFormat::DS) return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
907 else if (tcuFormat.order == tcu::TextureFormat::D) return VK_IMAGE_ASPECT_DEPTH_BIT;
908 else if (tcuFormat.order == tcu::TextureFormat::S) return VK_IMAGE_ASPECT_STENCIL_BIT;
909
910 DE_ASSERT(false);
911 return 0u;
912 }
913
generateVertices(const GeometryType geometryType)914 std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType)
915 {
916 std::vector<Vertex4RGBA> vertices;
917
918 switch (geometryType)
919 {
920 case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
921 case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:
922 {
923 Vertex4RGBA vertexData[3] =
924 {
925 {
926 tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
927 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
928 },
929 {
930 tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
931 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
932 },
933 {
934 tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
935 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
936 }
937 };
938
939 if (geometryType == GEOMETRY_TYPE_INVISIBLE_TRIANGLE)
940 {
941 for (int i = 0; i < 3; i++)
942 vertexData[i].color = tcu::Vec4();
943 }
944
945 vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 3);
946 break;
947 }
948
949 case GEOMETRY_TYPE_OPAQUE_LINE:
950 {
951 const Vertex4RGBA vertexData[2] =
952 {
953 {
954 tcu::Vec4(-0.75f, 0.25f, 0.0f, 1.0f),
955 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
956 },
957 {
958 tcu::Vec4(0.75f, -0.25f, 0.0f, 1.0f),
959 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
960 }
961 };
962
963 vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 2);
964 break;
965 }
966
967 case GEOMETRY_TYPE_OPAQUE_POINT:
968 {
969 const Vertex4RGBA vertex =
970 {
971 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
972 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
973 };
974
975 vertices = std::vector<Vertex4RGBA>(1, vertex);
976 break;
977 }
978
979 case GEOMETRY_TYPE_OPAQUE_QUAD:
980 case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
981 case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
982 case GEOMETRY_TYPE_INVISIBLE_QUAD:
983 case GEOMETRY_TYPE_GRADIENT_QUAD:
984 {
985 Vertex4RGBA vertexData[4] =
986 {
987 {
988 tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
989 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
990 },
991 {
992 tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f),
993 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
994 },
995 {
996 tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
997 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
998 },
999 {
1000 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
1001 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1002 }
1003 };
1004
1005 if (geometryType == GEOMETRY_TYPE_TRANSLUCENT_QUAD)
1006 {
1007 for (int i = 0; i < 4; i++)
1008 vertexData[i].color.w() = 0.25f;
1009 }
1010 else if (geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD)
1011 {
1012 for (int i = 0; i < 4; i++)
1013 vertexData[i].color.w() = 0.0f;
1014 }
1015 else if (geometryType == GEOMETRY_TYPE_GRADIENT_QUAD)
1016 {
1017 vertexData[0].color.w() = 0.0f;
1018 vertexData[2].color.w() = 0.0f;
1019 }
1020 else if (geometryType == GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH)
1021 {
1022 for (int i = 0; i < 4; i++)
1023 vertexData[i].position.z() = 0.5f;
1024 }
1025
1026 vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 4);
1027 break;
1028 }
1029
1030 default:
1031 DE_ASSERT(false);
1032 }
1033 return vertices;
1034 }
1035
getPrimitiveTopology(const GeometryType geometryType)1036 VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType)
1037 {
1038 switch (geometryType)
1039 {
1040 case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
1041 case GEOMETRY_TYPE_INVISIBLE_TRIANGLE: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1042
1043 case GEOMETRY_TYPE_OPAQUE_LINE: return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
1044 case GEOMETRY_TYPE_OPAQUE_POINT: return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
1045
1046 case GEOMETRY_TYPE_OPAQUE_QUAD:
1047 case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
1048 case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
1049 case GEOMETRY_TYPE_INVISIBLE_QUAD:
1050 case GEOMETRY_TYPE_GRADIENT_QUAD: return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
1051
1052 default:
1053 DE_ASSERT(false);
1054 return VK_PRIMITIVE_TOPOLOGY_LAST;
1055 }
1056 }
1057
isSupportedDepthStencilFormat(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkFormat format)1058 bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
1059 {
1060 VkFormatProperties formatProps;
1061 vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
1062 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
1063 }
1064
findSupportedDepthStencilFormat(Context & context,const bool useDepth,const bool useStencil)1065 VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil)
1066 {
1067 if (useDepth && !useStencil)
1068 return VK_FORMAT_D16_UNORM; // must be supported
1069
1070 const InstanceInterface& vki = context.getInstanceInterface();
1071 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
1072
1073 // One of these formats must be supported.
1074
1075 if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
1076 return VK_FORMAT_D24_UNORM_S8_UINT;
1077
1078 if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D32_SFLOAT_S8_UINT))
1079 return VK_FORMAT_D32_SFLOAT_S8_UINT;
1080
1081 return VK_FORMAT_UNDEFINED;
1082 }
1083
1084
1085 // MultisampleTest
1086
MultisampleTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType,float pointSize,ImageBackingMode backingMode)1087 MultisampleTest::MultisampleTest (tcu::TestContext& testContext,
1088 const std::string& name,
1089 const std::string& description,
1090 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
1091 const VkPipelineColorBlendAttachmentState& blendState,
1092 GeometryType geometryType,
1093 float pointSize,
1094 ImageBackingMode backingMode)
1095 : vkt::TestCase (testContext, name, description)
1096 , m_multisampleStateParams (multisampleStateParams)
1097 , m_colorBlendState (blendState)
1098 , m_geometryType (geometryType)
1099 , m_pointSize (pointSize)
1100 , m_backingMode (backingMode)
1101 {
1102 if (m_multisampleStateParams.pSampleMask)
1103 {
1104 // Copy pSampleMask to avoid dependencies with other classes
1105
1106 const deUint32 maskCount = deCeilFloatToInt32(float(m_multisampleStateParams.rasterizationSamples) / 32);
1107
1108 for (deUint32 maskNdx = 0; maskNdx < maskCount; maskNdx++)
1109 m_sampleMask.push_back(m_multisampleStateParams.pSampleMask[maskNdx]);
1110
1111 m_multisampleStateParams.pSampleMask = m_sampleMask.data();
1112 }
1113 }
1114
initPrograms(SourceCollections & programCollection) const1115 void MultisampleTest::initPrograms (SourceCollections& programCollection) const
1116 {
1117 MultisampleTestParams params = {m_geometryType, m_pointSize, m_backingMode};
1118 initMultisamplePrograms(programCollection, params);
1119 }
1120
createInstance(Context & context) const1121 TestInstance* MultisampleTest::createInstance (Context& context) const
1122 {
1123 return createMultisampleTestInstance(context, getPrimitiveTopology(m_geometryType), m_pointSize, generateVertices(m_geometryType), m_multisampleStateParams, m_colorBlendState);
1124 }
1125
checkSupport(Context & context) const1126 void MultisampleTest::checkSupport (Context& context) const
1127 {
1128 if (m_geometryType == GEOMETRY_TYPE_OPAQUE_POINT && m_pointSize > 1.0f)
1129 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);
1130 }
1131
1132 // RasterizationSamplesTest
1133
RasterizationSamplesTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,GeometryType geometryType,float pointSize,ImageBackingMode backingMode,TestModeFlags modeFlags)1134 RasterizationSamplesTest::RasterizationSamplesTest (tcu::TestContext& testContext,
1135 const std::string& name,
1136 const std::string& description,
1137 VkSampleCountFlagBits rasterizationSamples,
1138 GeometryType geometryType,
1139 float pointSize,
1140 ImageBackingMode backingMode,
1141 TestModeFlags modeFlags)
1142 : MultisampleTest (testContext, name, description, getRasterizationSamplesStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode)
1143 , m_backingMode (backingMode)
1144 , m_modeFlags (modeFlags)
1145 {
1146 }
1147
getRasterizationSamplesStateParams(VkSampleCountFlagBits rasterizationSamples)1148 VkPipelineMultisampleStateCreateInfo RasterizationSamplesTest::getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples)
1149 {
1150 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1151 {
1152 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1153 DE_NULL, // const void* pNext;
1154 0u, // VkPipelineMultisampleStateCreateFlags flags;
1155 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
1156 false, // VkBool32 sampleShadingEnable;
1157 0.0f, // float minSampleShading;
1158 DE_NULL, // const VkSampleMask* pSampleMask;
1159 false, // VkBool32 alphaToCoverageEnable;
1160 false // VkBool32 alphaToOneEnable;
1161 };
1162
1163 return multisampleStateParams;
1164 }
1165
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1166 TestInstance* RasterizationSamplesTest::createMultisampleTestInstance (Context& context,
1167 VkPrimitiveTopology topology,
1168 float pointSize,
1169 const std::vector<Vertex4RGBA>& vertices,
1170 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
1171 const VkPipelineColorBlendAttachmentState& colorBlendState) const
1172 {
1173 return new RasterizationSamplesInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_modeFlags, m_backingMode);
1174 }
1175
1176
1177 // MinSampleShadingTest
1178
MinSampleShadingTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,float minSampleShading,GeometryType geometryType,float pointSize,ImageBackingMode backingMode,const bool minSampleShadingEnabled)1179 MinSampleShadingTest::MinSampleShadingTest (tcu::TestContext& testContext,
1180 const std::string& name,
1181 const std::string& description,
1182 VkSampleCountFlagBits rasterizationSamples,
1183 float minSampleShading,
1184 GeometryType geometryType,
1185 float pointSize,
1186 ImageBackingMode backingMode,
1187 const bool minSampleShadingEnabled)
1188 : MultisampleTest (testContext, name, description, getMinSampleShadingStateParams(rasterizationSamples, minSampleShading, minSampleShadingEnabled), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode)
1189 , m_pointSize (pointSize)
1190 , m_backingMode (backingMode)
1191 , m_minSampleShadingEnabled (minSampleShadingEnabled)
1192 {
1193 }
1194
checkSupport(Context & context) const1195 void MinSampleShadingTest::checkSupport (Context& context) const
1196 {
1197 MultisampleTest::checkSupport(context);
1198
1199 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING);
1200 }
1201
initPrograms(SourceCollections & programCollection) const1202 void MinSampleShadingTest::initPrograms (SourceCollections& programCollection) const
1203 {
1204 MultisampleTestParams params = {m_geometryType, m_pointSize, m_backingMode};
1205 initSampleShadingPrograms(programCollection, params);
1206 }
1207
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1208 TestInstance* MinSampleShadingTest::createMultisampleTestInstance (Context& context,
1209 VkPrimitiveTopology topology,
1210 float pointSize,
1211 const std::vector<Vertex4RGBA>& vertices,
1212 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
1213 const VkPipelineColorBlendAttachmentState& colorBlendState) const
1214 {
1215 if (m_minSampleShadingEnabled)
1216 return new MinSampleShadingInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode);
1217 else
1218 return new MinSampleShadingDisabledInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode);
1219 }
1220
getMinSampleShadingStateParams(VkSampleCountFlagBits rasterizationSamples,float minSampleShading,bool minSampleShadingEnabled)1221 VkPipelineMultisampleStateCreateInfo MinSampleShadingTest::getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading, bool minSampleShadingEnabled)
1222 {
1223 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1224 {
1225 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1226 DE_NULL, // const void* pNext;
1227 0u, // VkPipelineMultisampleStateCreateFlags flags;
1228 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
1229 minSampleShadingEnabled ? VK_TRUE : VK_FALSE, // VkBool32 sampleShadingEnable;
1230 minSampleShading, // float minSampleShading;
1231 DE_NULL, // const VkSampleMask* pSampleMask;
1232 false, // VkBool32 alphaToCoverageEnable;
1233 false // VkBool32 alphaToOneEnable;
1234 };
1235
1236 return multisampleStateParams;
1237 }
1238
1239
1240 // SampleMaskTest
1241
SampleMaskTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,const std::vector<VkSampleMask> & sampleMask,GeometryType geometryType,float pointSize,ImageBackingMode backingMode)1242 SampleMaskTest::SampleMaskTest (tcu::TestContext& testContext,
1243 const std::string& name,
1244 const std::string& description,
1245 VkSampleCountFlagBits rasterizationSamples,
1246 const std::vector<VkSampleMask>& sampleMask,
1247 GeometryType geometryType,
1248 float pointSize,
1249 ImageBackingMode backingMode)
1250 : MultisampleTest (testContext, name, description, getSampleMaskStateParams(rasterizationSamples, sampleMask), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode)
1251 , m_backingMode (backingMode)
1252 {
1253 }
1254
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1255 TestInstance* SampleMaskTest::createMultisampleTestInstance (Context& context,
1256 VkPrimitiveTopology topology,
1257 float pointSize,
1258 const std::vector<Vertex4RGBA>& vertices,
1259 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
1260 const VkPipelineColorBlendAttachmentState& colorBlendState) const
1261 {
1262 DE_UNREF(pointSize);
1263 return new SampleMaskInstance(context, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode);
1264 }
1265
getSampleMaskStateParams(VkSampleCountFlagBits rasterizationSamples,const std::vector<VkSampleMask> & sampleMask)1266 VkPipelineMultisampleStateCreateInfo SampleMaskTest::getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask)
1267 {
1268 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1269 {
1270 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1271 DE_NULL, // const void* pNext;
1272 0u, // VkPipelineMultisampleStateCreateFlags flags;
1273 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
1274 false, // VkBool32 sampleShadingEnable;
1275 0.0f, // float minSampleShading;
1276 sampleMask.data(), // const VkSampleMask* pSampleMask;
1277 false, // VkBool32 alphaToCoverageEnable;
1278 false // VkBool32 alphaToOneEnable;
1279 };
1280
1281 return multisampleStateParams;
1282 }
1283
1284
1285 // AlphaToOneTest
1286
AlphaToOneTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,ImageBackingMode backingMode)1287 AlphaToOneTest::AlphaToOneTest (tcu::TestContext& testContext,
1288 const std::string& name,
1289 const std::string& description,
1290 VkSampleCountFlagBits rasterizationSamples,
1291 ImageBackingMode backingMode)
1292 : MultisampleTest (testContext, name, description, getAlphaToOneStateParams(rasterizationSamples), getAlphaToOneBlendState(), GEOMETRY_TYPE_GRADIENT_QUAD, 1.0f, backingMode)
1293 , m_backingMode(backingMode)
1294 {
1295 }
1296
checkSupport(Context & context) const1297 void AlphaToOneTest::checkSupport (Context& context) const
1298 {
1299 MultisampleTest::checkSupport(context);
1300
1301 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_ALPHA_TO_ONE);
1302 }
1303
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1304 TestInstance* AlphaToOneTest::createMultisampleTestInstance (Context& context,
1305 VkPrimitiveTopology topology,
1306 float pointSize,
1307 const std::vector<Vertex4RGBA>& vertices,
1308 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
1309 const VkPipelineColorBlendAttachmentState& colorBlendState) const
1310 {
1311 DE_UNREF(pointSize);
1312 return new AlphaToOneInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_backingMode);
1313 }
1314
getAlphaToOneStateParams(VkSampleCountFlagBits rasterizationSamples)1315 VkPipelineMultisampleStateCreateInfo AlphaToOneTest::getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples)
1316 {
1317 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1318 {
1319 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1320 DE_NULL, // const void* pNext;
1321 0u, // VkPipelineMultisampleStateCreateFlags flags;
1322 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
1323 false, // VkBool32 sampleShadingEnable;
1324 0.0f, // float minSampleShading;
1325 DE_NULL, // const VkSampleMask* pSampleMask;
1326 false, // VkBool32 alphaToCoverageEnable;
1327 true // VkBool32 alphaToOneEnable;
1328 };
1329
1330 return multisampleStateParams;
1331 }
1332
getAlphaToOneBlendState(void)1333 VkPipelineColorBlendAttachmentState AlphaToOneTest::getAlphaToOneBlendState (void)
1334 {
1335 const VkPipelineColorBlendAttachmentState colorBlendState =
1336 {
1337 true, // VkBool32 blendEnable;
1338 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
1339 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor;
1340 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
1341 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
1342 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstAlphaBlendFactor;
1343 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
1344 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask;
1345 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
1346 };
1347
1348 return colorBlendState;
1349 }
1350
1351
1352 // AlphaToCoverageTest
1353
AlphaToCoverageTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,GeometryType geometryType,ImageBackingMode backingMode)1354 AlphaToCoverageTest::AlphaToCoverageTest (tcu::TestContext& testContext,
1355 const std::string& name,
1356 const std::string& description,
1357 VkSampleCountFlagBits rasterizationSamples,
1358 GeometryType geometryType,
1359 ImageBackingMode backingMode)
1360 : MultisampleTest (testContext, name, description, getAlphaToCoverageStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode)
1361 , m_geometryType (geometryType)
1362 , m_backingMode (backingMode)
1363 {
1364 }
1365
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1366 TestInstance* AlphaToCoverageTest::createMultisampleTestInstance (Context& context,
1367 VkPrimitiveTopology topology,
1368 float pointSize,
1369 const std::vector<Vertex4RGBA>& vertices,
1370 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
1371 const VkPipelineColorBlendAttachmentState& colorBlendState) const
1372 {
1373 DE_UNREF(pointSize);
1374 return new AlphaToCoverageInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode);
1375 }
1376
getAlphaToCoverageStateParams(VkSampleCountFlagBits rasterizationSamples)1377 VkPipelineMultisampleStateCreateInfo AlphaToCoverageTest::getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples)
1378 {
1379 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1380 {
1381 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1382 DE_NULL, // const void* pNext;
1383 0u, // VkPipelineMultisampleStateCreateFlags flags;
1384 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
1385 false, // VkBool32 sampleShadingEnable;
1386 0.0f, // float minSampleShading;
1387 DE_NULL, // const VkSampleMask* pSampleMask;
1388 true, // VkBool32 alphaToCoverageEnable;
1389 false // VkBool32 alphaToOneEnable;
1390 };
1391
1392 return multisampleStateParams;
1393 }
1394
1395 // AlphaToCoverageNoColorAttachmentTest
1396
AlphaToCoverageNoColorAttachmentTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,GeometryType geometryType,ImageBackingMode backingMode)1397 AlphaToCoverageNoColorAttachmentTest::AlphaToCoverageNoColorAttachmentTest (tcu::TestContext& testContext,
1398 const std::string& name,
1399 const std::string& description,
1400 VkSampleCountFlagBits rasterizationSamples,
1401 GeometryType geometryType,
1402 ImageBackingMode backingMode)
1403 : MultisampleTest (testContext, name, description, getStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode)
1404 , m_geometryType (geometryType)
1405 , m_backingMode (backingMode)
1406 {
1407 }
1408
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1409 TestInstance* AlphaToCoverageNoColorAttachmentTest::createMultisampleTestInstance (Context& context,
1410 VkPrimitiveTopology topology,
1411 float pointSize,
1412 const std::vector<Vertex4RGBA>& vertices,
1413 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
1414 const VkPipelineColorBlendAttachmentState& colorBlendState) const
1415 {
1416 DE_UNREF(pointSize);
1417 return new AlphaToCoverageNoColorAttachmentInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode);
1418 }
1419
getStateParams(VkSampleCountFlagBits rasterizationSamples)1420 VkPipelineMultisampleStateCreateInfo AlphaToCoverageNoColorAttachmentTest::getStateParams (VkSampleCountFlagBits rasterizationSamples)
1421 {
1422 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1423 {
1424 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1425 DE_NULL, // const void* pNext;
1426 0u, // VkPipelineMultisampleStateCreateFlags flags;
1427 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
1428 false, // VkBool32 sampleShadingEnable;
1429 0.0f, // float minSampleShading;
1430 DE_NULL, // const VkSampleMask* pSampleMask;
1431 true, // VkBool32 alphaToCoverageEnable;
1432 false // VkBool32 alphaToOneEnable;
1433 };
1434
1435 return multisampleStateParams;
1436 }
1437
1438 // AlphaToCoverageColorUnusedAttachmentTest
1439
AlphaToCoverageColorUnusedAttachmentTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,VkSampleCountFlagBits rasterizationSamples,GeometryType geometryType,ImageBackingMode backingMode)1440 AlphaToCoverageColorUnusedAttachmentTest::AlphaToCoverageColorUnusedAttachmentTest (tcu::TestContext& testContext,
1441 const std::string& name,
1442 const std::string& description,
1443 VkSampleCountFlagBits rasterizationSamples,
1444 GeometryType geometryType,
1445 ImageBackingMode backingMode)
1446 : MultisampleTest (testContext, name, description, getStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode)
1447 , m_geometryType (geometryType)
1448 , m_backingMode (backingMode)
1449 {
1450 }
1451
initPrograms(SourceCollections & programCollection) const1452 void AlphaToCoverageColorUnusedAttachmentTest::initPrograms (SourceCollections& programCollection) const
1453 {
1454 initAlphaToCoverageColorUnusedAttachmentPrograms(programCollection);
1455 }
1456
createMultisampleTestInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState) const1457 TestInstance* AlphaToCoverageColorUnusedAttachmentTest::createMultisampleTestInstance (Context& context,
1458 VkPrimitiveTopology topology,
1459 float pointSize,
1460 const std::vector<Vertex4RGBA>& vertices,
1461 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
1462 const VkPipelineColorBlendAttachmentState& colorBlendState) const
1463 {
1464 DE_UNREF(pointSize);
1465 return new AlphaToCoverageColorUnusedAttachmentInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode);
1466 }
1467
getStateParams(VkSampleCountFlagBits rasterizationSamples)1468 VkPipelineMultisampleStateCreateInfo AlphaToCoverageColorUnusedAttachmentTest::getStateParams (VkSampleCountFlagBits rasterizationSamples)
1469 {
1470 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1471 {
1472 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1473 DE_NULL, // const void* pNext;
1474 0u, // VkPipelineMultisampleStateCreateFlags flags;
1475 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
1476 false, // VkBool32 sampleShadingEnable;
1477 0.0f, // float minSampleShading;
1478 DE_NULL, // const VkSampleMask* pSampleMask;
1479 true, // VkBool32 alphaToCoverageEnable;
1480 false // VkBool32 alphaToOneEnable;
1481 };
1482
1483 return multisampleStateParams;
1484 }
1485
1486 // SampleMaskWithDepthTestTest
1487
SampleMaskWithDepthTestTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const VkSampleCountFlagBits rasterizationSamples,const bool enablePostDepthCoverage)1488 SampleMaskWithDepthTestTest::SampleMaskWithDepthTestTest (tcu::TestContext& testContext,
1489 const std::string& name,
1490 const std::string& description,
1491 const VkSampleCountFlagBits rasterizationSamples,
1492 const bool enablePostDepthCoverage)
1493 : vkt::TestCase (testContext, name, description)
1494 , m_rasterizationSamples (rasterizationSamples)
1495 , m_enablePostDepthCoverage (enablePostDepthCoverage)
1496 {
1497 }
1498
checkSupport(Context & context) const1499 void SampleMaskWithDepthTestTest::checkSupport (Context& context) const
1500 {
1501 if (!context.getDeviceProperties().limits.standardSampleLocations)
1502 TCU_THROW(NotSupportedError, "standardSampleLocations required");
1503
1504 context.requireDeviceFunctionality("VK_EXT_post_depth_coverage");
1505 }
1506
initPrograms(SourceCollections & programCollection) const1507 void SampleMaskWithDepthTestTest::initPrograms (SourceCollections& programCollection) const
1508 {
1509 DE_ASSERT((int)m_rasterizationSamples <= 32);
1510
1511 static const char* vertexSource =
1512 "#version 440\n"
1513 "layout(location = 0) in vec4 position;\n"
1514 "layout(location = 1) in vec4 color;\n"
1515 "layout(location = 0) out vec4 vtxColor;\n"
1516 "out gl_PerVertex\n"
1517 "{\n"
1518 " vec4 gl_Position;\n"
1519 "};\n"
1520 "\n"
1521 "void main (void)\n"
1522 "{\n"
1523 " gl_Position = position;\n"
1524 " vtxColor = color;\n"
1525 "}\n";
1526
1527 std::ostringstream fragmentSource;
1528 fragmentSource <<
1529 "#version 440\n"
1530 << (m_enablePostDepthCoverage ? "#extension GL_ARB_post_depth_coverage : require\n" : "") <<
1531 "layout(early_fragment_tests) in;\n"
1532 << (m_enablePostDepthCoverage ? "layout(post_depth_coverage) in;\n" : "") <<
1533 "layout(location = 0) in vec4 vtxColor;\n"
1534 "layout(location = 0) out vec4 fragColor;\n"
1535 "void main (void)\n"
1536 "{\n"
1537 " const int coveredSamples = bitCount(gl_SampleMaskIn[0]);\n"
1538 " fragColor = vtxColor * (1.0 / " << (int)m_rasterizationSamples << " * coveredSamples);\n"
1539 "}\n";
1540
1541 programCollection.glslSources.add("color_vert") << glu::VertexSource(vertexSource);
1542 programCollection.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str());
1543 }
1544
createInstance(Context & context) const1545 TestInstance* SampleMaskWithDepthTestTest::createInstance (Context& context) const
1546 {
1547 return new SampleMaskWithDepthTestInstance(context, m_rasterizationSamples, m_enablePostDepthCoverage);
1548 }
1549
1550 // RasterizationSamplesInstance
1551
RasterizationSamplesInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,const TestModeFlags modeFlags,ImageBackingMode backingMode)1552 RasterizationSamplesInstance::RasterizationSamplesInstance (Context& context,
1553 VkPrimitiveTopology topology,
1554 float pointSize,
1555 const std::vector<Vertex4RGBA>& vertices,
1556 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
1557 const VkPipelineColorBlendAttachmentState& blendState,
1558 const TestModeFlags modeFlags,
1559 ImageBackingMode backingMode)
1560 : vkt::TestInstance (context)
1561 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
1562 , m_renderSize (32, 32)
1563 , m_primitiveTopology (topology)
1564 , m_pointSize (pointSize)
1565 , m_vertices (vertices)
1566 , m_fullQuadVertices (generateVertices(GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH))
1567 , m_modeFlags (modeFlags)
1568 {
1569 if (m_modeFlags != 0)
1570 {
1571 const bool useDepth = (m_modeFlags & TEST_MODE_DEPTH_BIT) != 0;
1572 const bool useStencil = (m_modeFlags & TEST_MODE_STENCIL_BIT) != 0;
1573 const VkFormat depthStencilFormat = findSupportedDepthStencilFormat(context, useDepth, useStencil);
1574
1575 if (depthStencilFormat == VK_FORMAT_UNDEFINED)
1576 TCU_THROW(NotSupportedError, "Required depth/stencil format is not supported");
1577
1578 const VkPrimitiveTopology pTopology[2] = { m_primitiveTopology, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP };
1579 const std::vector<Vertex4RGBA> pVertices[2] = { m_vertices, m_fullQuadVertices };
1580
1581 m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
1582 new MultisampleRenderer(
1583 context, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil, 2u, pTopology, pVertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE, backingMode));
1584 }
1585 else
1586 {
1587 m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
1588 new MultisampleRenderer(context, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE, backingMode));
1589 }
1590 }
1591
iterate(void)1592 tcu::TestStatus RasterizationSamplesInstance::iterate (void)
1593 {
1594 de::MovePtr<tcu::TextureLevel> level(m_multisampleRenderer->render());
1595 return verifyImage(level->getAccess());
1596 }
1597
verifyImage(const tcu::ConstPixelBufferAccess & result)1598 tcu::TestStatus RasterizationSamplesInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
1599 {
1600 // Verify range of unique pixels
1601 {
1602 const deUint32 numUniqueColors = getUniqueColorsCount(result);
1603 const deUint32 minUniqueColors = (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST && m_pointSize == 1.0f) ? 2 : 3;
1604
1605 tcu::TestLog& log = m_context.getTestContext().getLog();
1606
1607 log << tcu::TestLog::Message
1608 << "\nMin. unique colors expected: " << minUniqueColors << "\n"
1609 << "Unique colors found: " << numUniqueColors << "\n"
1610 << tcu::TestLog::EndMessage;
1611
1612 if (numUniqueColors < minUniqueColors)
1613 return tcu::TestStatus::fail("Unique colors out of expected bounds");
1614 }
1615
1616 // Verify shape of the rendered primitive (fuzzy-compare)
1617 {
1618 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat);
1619 const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat();
1620 const ColorVertexShader vertexShader;
1621 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuDepthFormat);
1622 const rr::Program program (&vertexShader, &fragmentShader);
1623 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
1624 rr::RenderState renderState (refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);
1625
1626 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
1627 {
1628 VkPhysicalDeviceProperties deviceProperties;
1629
1630 m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties);
1631
1632 // gl_PointSize is clamped to pointSizeRange
1633 renderState.point.pointSize = deFloatMin(m_pointSize, deviceProperties.limits.pointSizeRange[1]);
1634 }
1635
1636 if (m_modeFlags == 0)
1637 {
1638 refRenderer.colorClear(tcu::Vec4(0.0f));
1639 refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
1640 }
1641 else
1642 {
1643 // For depth/stencil case the primitive is invisible and the surroundings are filled red.
1644 refRenderer.colorClear(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
1645 refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
1646 }
1647
1648 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "FuzzyImageCompare", "Image comparison", refRenderer.getAccess(), result, 0.05f, tcu::COMPARE_LOG_RESULT))
1649 return tcu::TestStatus::fail("Primitive has unexpected shape");
1650 }
1651
1652 return tcu::TestStatus::pass("Primitive rendered, unique colors within expected bounds");
1653 }
1654
1655
1656 // MinSampleShadingInstance
1657
MinSampleShadingInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & colorBlendState,ImageBackingMode backingMode)1658 MinSampleShadingInstance::MinSampleShadingInstance (Context& context,
1659 VkPrimitiveTopology topology,
1660 float pointSize,
1661 const std::vector<Vertex4RGBA>& vertices,
1662 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
1663 const VkPipelineColorBlendAttachmentState& colorBlendState,
1664 ImageBackingMode backingMode)
1665 : vkt::TestInstance (context)
1666 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
1667 , m_renderSize (32, 32)
1668 , m_primitiveTopology (topology)
1669 , m_vertices (vertices)
1670 , m_multisampleStateParams (multisampleStateParams)
1671 , m_colorBlendState (colorBlendState)
1672 , m_backingMode (backingMode)
1673 {
1674 DE_UNREF(pointSize);
1675 }
1676
iterate(void)1677 tcu::TestStatus MinSampleShadingInstance::iterate (void)
1678 {
1679 de::MovePtr<tcu::TextureLevel> noSampleshadingImage;
1680 std::vector<tcu::TextureLevel> sampleShadedImages;
1681
1682 // Render and resolve without sample shading
1683 {
1684 VkPipelineMultisampleStateCreateInfo multisampleStateParms = m_multisampleStateParams;
1685 multisampleStateParms.sampleShadingEnable = VK_FALSE;
1686 multisampleStateParms.minSampleShading = 0.0;
1687
1688 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleStateParms, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1689 noSampleshadingImage = renderer.render();
1690 }
1691
1692 // Render with test minSampleShading and collect per-sample images
1693 {
1694 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_COPY_SAMPLES, m_backingMode);
1695 renderer.render();
1696
1697 sampleShadedImages.resize(m_multisampleStateParams.rasterizationSamples);
1698 for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
1699 {
1700 sampleShadedImages[sampleId] = *renderer.getSingleSampledImage(sampleId);
1701 }
1702 }
1703
1704 // Log images
1705 {
1706 tcu::TestLog& testLog = m_context.getTestContext().getLog();
1707
1708 testLog << tcu::TestLog::ImageSet("Images", "Images")
1709 << tcu::TestLog::Image("noSampleshadingImage", "Image rendered without sample shading", noSampleshadingImage->getAccess());
1710
1711 for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
1712 {
1713 testLog << tcu::TestLog::Image("sampleShadedImage", "One sample of sample shaded image", sampleShadedImages[sampleId].getAccess());
1714 }
1715 testLog << tcu::TestLog::EndImageSet;
1716 }
1717
1718 return verifySampleShadedImage(sampleShadedImages, noSampleshadingImage->getAccess());
1719 }
1720
verifySampleShadedImage(const std::vector<tcu::TextureLevel> & sampleShadedImages,const tcu::ConstPixelBufferAccess & noSampleshadingImage)1721 tcu::TestStatus MinSampleShadingInstance::verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& noSampleshadingImage)
1722 {
1723 const deUint32 pixelCount = noSampleshadingImage.getWidth() * noSampleshadingImage.getHeight() * noSampleshadingImage.getDepth();
1724
1725 bool anyPixelCovered = false;
1726
1727 for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
1728 {
1729 const deUint32 noSampleShadingValue = *((const deUint32*)noSampleshadingImage.getDataPtr() + pixelNdx);
1730
1731 if (noSampleShadingValue == 0)
1732 {
1733 // non-covered pixel, continue
1734 continue;
1735 }
1736 else
1737 {
1738 anyPixelCovered = true;
1739 }
1740
1741 int numNotCoveredSamples = 0;
1742
1743 std::map<deUint32, deUint32> histogram; // map<pixel value, number of occurrences>
1744
1745 // Collect histogram of occurrences or each pixel across all samples
1746 for (size_t i = 0; i < sampleShadedImages.size(); ++i)
1747 {
1748 const deUint32 sampleShadedValue = *((const deUint32*)sampleShadedImages[i].getAccess().getDataPtr() + pixelNdx);
1749
1750 if (sampleShadedValue == 0)
1751 {
1752 numNotCoveredSamples++;
1753 continue;
1754 }
1755
1756 if (histogram.find(sampleShadedValue) != histogram.end())
1757 histogram[sampleShadedValue]++;
1758 else
1759 histogram[sampleShadedValue] = 1;
1760 }
1761
1762 if (numNotCoveredSamples == static_cast<int>(sampleShadedImages.size()))
1763 {
1764 return tcu::TestStatus::fail("Got uncovered pixel, where covered samples were expected");
1765 }
1766
1767 const int uniqueColorsCount = (int)histogram.size();
1768 const int expectedUniqueSamplesCount = static_cast<int>(m_multisampleStateParams.minSampleShading * static_cast<float>(sampleShadedImages.size()) + 0.5f);
1769
1770 if (uniqueColorsCount + numNotCoveredSamples < expectedUniqueSamplesCount)
1771 {
1772 return tcu::TestStatus::fail("Got less unique colors than requested through minSampleShading");
1773 }
1774 }
1775
1776 if (!anyPixelCovered)
1777 {
1778 return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShading");
1779 }
1780
1781 return tcu::TestStatus::pass("Got proper count of unique colors");
1782 }
1783
MinSampleShadingDisabledInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,ImageBackingMode backingMode)1784 MinSampleShadingDisabledInstance::MinSampleShadingDisabledInstance (Context& context,
1785 VkPrimitiveTopology topology,
1786 float pointSize,
1787 const std::vector<Vertex4RGBA>& vertices,
1788 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
1789 const VkPipelineColorBlendAttachmentState& blendState,
1790 ImageBackingMode backingMode)
1791 : MinSampleShadingInstance (context, topology, pointSize, vertices, multisampleStateParams, blendState, backingMode)
1792 {
1793 }
1794
verifySampleShadedImage(const std::vector<tcu::TextureLevel> & sampleShadedImages,const tcu::ConstPixelBufferAccess & noSampleshadingImage)1795 tcu::TestStatus MinSampleShadingDisabledInstance::verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages,
1796 const tcu::ConstPixelBufferAccess& noSampleshadingImage)
1797 {
1798 const deUint32 samplesCount = (int)sampleShadedImages.size();
1799 const deUint32 width = noSampleshadingImage.getWidth();
1800 const deUint32 height = noSampleshadingImage.getHeight();
1801 const deUint32 depth = noSampleshadingImage.getDepth();
1802 const tcu::UVec4 zeroPixel = tcu::UVec4();
1803 bool anyPixelCovered = false;
1804
1805 DE_ASSERT(depth == 1);
1806 DE_UNREF(depth);
1807
1808 for (deUint32 y = 0; y < height; ++y)
1809 for (deUint32 x = 0; x < width; ++x)
1810 {
1811 const tcu::UVec4 noSampleShadingValue = noSampleshadingImage.getPixelUint(x, y);
1812
1813 if (noSampleShadingValue == zeroPixel)
1814 continue;
1815
1816 anyPixelCovered = true;
1817 tcu::UVec4 sampleShadingValue = tcu::UVec4();
1818
1819 // Collect histogram of occurrences or each pixel across all samples
1820 for (size_t i = 0; i < samplesCount; ++i)
1821 {
1822 const tcu::UVec4 sampleShadedValue = sampleShadedImages[i].getAccess().getPixelUint(x, y);
1823
1824 sampleShadingValue += sampleShadedValue;
1825 }
1826
1827 sampleShadingValue = sampleShadingValue / samplesCount;
1828
1829 if (sampleShadingValue.w() != 255)
1830 {
1831 return tcu::TestStatus::fail("Invalid Alpha channel value");
1832 }
1833
1834 if (sampleShadingValue != noSampleShadingValue)
1835 {
1836 return tcu::TestStatus::fail("Invalid color");
1837 }
1838 }
1839
1840 if (!anyPixelCovered)
1841 {
1842 return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShadingDisabled");
1843 }
1844
1845 return tcu::TestStatus::pass("Got proper count of unique colors");
1846 }
1847
SampleMaskInstance(Context & context,VkPrimitiveTopology topology,float pointSize,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,ImageBackingMode backingMode)1848 SampleMaskInstance::SampleMaskInstance (Context& context,
1849 VkPrimitiveTopology topology,
1850 float pointSize,
1851 const std::vector<Vertex4RGBA>& vertices,
1852 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
1853 const VkPipelineColorBlendAttachmentState& blendState,
1854 ImageBackingMode backingMode)
1855 : vkt::TestInstance (context)
1856 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
1857 , m_renderSize (32, 32)
1858 , m_primitiveTopology (topology)
1859 , m_vertices (vertices)
1860 , m_multisampleStateParams (multisampleStateParams)
1861 , m_colorBlendState (blendState)
1862 , m_backingMode (backingMode)
1863 {
1864 DE_UNREF(pointSize);
1865 }
1866
iterate(void)1867 tcu::TestStatus SampleMaskInstance::iterate (void)
1868 {
1869 de::MovePtr<tcu::TextureLevel> testSampleMaskImage;
1870 de::MovePtr<tcu::TextureLevel> minSampleMaskImage;
1871 de::MovePtr<tcu::TextureLevel> maxSampleMaskImage;
1872
1873 // Render with test flags
1874 {
1875 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1876 testSampleMaskImage = renderer.render();
1877 }
1878
1879 // Render with all flags off
1880 {
1881 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams;
1882 const std::vector<VkSampleMask> sampleMask (multisampleParams.rasterizationSamples / 32, (VkSampleMask)0);
1883
1884 multisampleParams.pSampleMask = sampleMask.data();
1885
1886 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1887 minSampleMaskImage = renderer.render();
1888 }
1889
1890 // Render with all flags on
1891 {
1892 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams;
1893 const std::vector<VkSampleMask> sampleMask (multisampleParams.rasterizationSamples / 32, ~((VkSampleMask)0));
1894
1895 multisampleParams.pSampleMask = sampleMask.data();
1896
1897 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
1898 maxSampleMaskImage = renderer.render();
1899 }
1900
1901 return verifyImage(testSampleMaskImage->getAccess(), minSampleMaskImage->getAccess(), maxSampleMaskImage->getAccess());
1902 }
1903
verifyImage(const tcu::ConstPixelBufferAccess & testSampleMaskImage,const tcu::ConstPixelBufferAccess & minSampleMaskImage,const tcu::ConstPixelBufferAccess & maxSampleMaskImage)1904 tcu::TestStatus SampleMaskInstance::verifyImage (const tcu::ConstPixelBufferAccess& testSampleMaskImage,
1905 const tcu::ConstPixelBufferAccess& minSampleMaskImage,
1906 const tcu::ConstPixelBufferAccess& maxSampleMaskImage)
1907 {
1908 const deUint32 testColorCount = getUniqueColorsCount(testSampleMaskImage);
1909 const deUint32 minColorCount = getUniqueColorsCount(minSampleMaskImage);
1910 const deUint32 maxColorCount = getUniqueColorsCount(maxSampleMaskImage);
1911
1912 tcu::TestLog& log = m_context.getTestContext().getLog();
1913
1914 log << tcu::TestLog::Message
1915 << "\nColors found: " << testColorCount << "\n"
1916 << "Min. colors expected: " << minColorCount << "\n"
1917 << "Max. colors expected: " << maxColorCount << "\n"
1918 << tcu::TestLog::EndMessage;
1919
1920 if (minColorCount > testColorCount || testColorCount > maxColorCount)
1921 return tcu::TestStatus::fail("Unique colors out of expected bounds");
1922 else
1923 return tcu::TestStatus::pass("Unique colors within expected bounds");
1924 }
1925
testRasterSamplesConsistency(Context & context,MultisampleTestParams params)1926 tcu::TestStatus testRasterSamplesConsistency (Context& context, MultisampleTestParams params)
1927 {
1928 const VkSampleCountFlagBits samples[] =
1929 {
1930 VK_SAMPLE_COUNT_1_BIT,
1931 VK_SAMPLE_COUNT_2_BIT,
1932 VK_SAMPLE_COUNT_4_BIT,
1933 VK_SAMPLE_COUNT_8_BIT,
1934 VK_SAMPLE_COUNT_16_BIT,
1935 VK_SAMPLE_COUNT_32_BIT,
1936 VK_SAMPLE_COUNT_64_BIT
1937 };
1938
1939 const Vertex4RGBA vertexData[3] =
1940 {
1941 {
1942 tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
1943 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1944 },
1945 {
1946 tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
1947 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1948 },
1949 {
1950 tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
1951 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1952 }
1953 };
1954
1955 const std::vector<Vertex4RGBA> vertices (vertexData, vertexData + 3);
1956 deUint32 prevUniqueColors = 2;
1957 int renderCount = 0;
1958
1959 // Do not render with 1 sample (start with samplesNdx = 1).
1960 for (int samplesNdx = 1; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
1961 {
1962 if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), samples[samplesNdx]))
1963 continue;
1964
1965 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1966 {
1967 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1968 DE_NULL, // const void* pNext;
1969 0u, // VkPipelineMultisampleStateCreateFlags flags;
1970 samples[samplesNdx], // VkSampleCountFlagBits rasterizationSamples;
1971 false, // VkBool32 sampleShadingEnable;
1972 0.0f, // float minSampleShading;
1973 DE_NULL, // const VkSampleMask* pSampleMask;
1974 false, // VkBool32 alphaToCoverageEnable;
1975 false // VkBool32 alphaToOneEnable;
1976 };
1977
1978 MultisampleRenderer renderer (context, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState(), RENDER_TYPE_RESOLVE, params.backingMode);
1979 de::MovePtr<tcu::TextureLevel> result = renderer.render();
1980 const deUint32 uniqueColors = getUniqueColorsCount(result->getAccess());
1981
1982 renderCount++;
1983
1984 if (prevUniqueColors > uniqueColors)
1985 {
1986 std::ostringstream message;
1987
1988 message << "More unique colors generated with " << samples[samplesNdx - 1] << " than with " << samples[samplesNdx];
1989 return tcu::TestStatus::fail(message.str());
1990 }
1991
1992 prevUniqueColors = uniqueColors;
1993 }
1994
1995 if (renderCount == 0)
1996 throw tcu::NotSupportedError("Multisampling is unsupported");
1997
1998 return tcu::TestStatus::pass("Number of unique colors increases as the sample count increases");
1999 }
2000
2001
2002 // AlphaToOneInstance
2003
AlphaToOneInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,ImageBackingMode backingMode)2004 AlphaToOneInstance::AlphaToOneInstance (Context& context,
2005 VkPrimitiveTopology topology,
2006 const std::vector<Vertex4RGBA>& vertices,
2007 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
2008 const VkPipelineColorBlendAttachmentState& blendState,
2009 ImageBackingMode backingMode)
2010 : vkt::TestInstance (context)
2011 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
2012 , m_renderSize (32, 32)
2013 , m_primitiveTopology (topology)
2014 , m_vertices (vertices)
2015 , m_multisampleStateParams (multisampleStateParams)
2016 , m_colorBlendState (blendState)
2017 , m_backingMode (backingMode)
2018 {
2019 }
2020
iterate(void)2021 tcu::TestStatus AlphaToOneInstance::iterate (void)
2022 {
2023 DE_ASSERT(m_multisampleStateParams.alphaToOneEnable);
2024 DE_ASSERT(m_colorBlendState.blendEnable);
2025
2026 de::MovePtr<tcu::TextureLevel> alphaOneImage;
2027 de::MovePtr<tcu::TextureLevel> noAlphaOneImage;
2028
2029 // Render with blend enabled and alpha to one on
2030 {
2031 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
2032 alphaOneImage = renderer.render();
2033 }
2034
2035 // Render with blend enabled and alpha to one off
2036 {
2037 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams;
2038 multisampleParams.alphaToOneEnable = false;
2039
2040 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
2041 noAlphaOneImage = renderer.render();
2042 }
2043
2044 return verifyImage(alphaOneImage->getAccess(), noAlphaOneImage->getAccess());
2045 }
2046
verifyImage(const tcu::ConstPixelBufferAccess & alphaOneImage,const tcu::ConstPixelBufferAccess & noAlphaOneImage)2047 tcu::TestStatus AlphaToOneInstance::verifyImage (const tcu::ConstPixelBufferAccess& alphaOneImage,
2048 const tcu::ConstPixelBufferAccess& noAlphaOneImage)
2049 {
2050 for (int y = 0; y < m_renderSize.y(); y++)
2051 {
2052 for (int x = 0; x < m_renderSize.x(); x++)
2053 {
2054 if (alphaOneImage.getPixel(x, y).w() != 1.0)
2055 {
2056 std::ostringstream message;
2057 message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " doesn't have alpha set to 1";
2058 return tcu::TestStatus::fail(message.str());
2059 }
2060
2061 if (!tcu::boolAll(tcu::greaterThanEqual(alphaOneImage.getPixel(x, y), noAlphaOneImage.getPixel(x, y))))
2062 {
2063 std::ostringstream message;
2064 message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " >= " << noAlphaOneImage.getPixel(x, y);
2065 return tcu::TestStatus::fail(message.str());
2066 }
2067 }
2068 }
2069
2070 return tcu::TestStatus::pass("Image rendered with alpha-to-one contains pixels of image rendered with no alpha-to-one");
2071 }
2072
2073
2074 // AlphaToCoverageInstance
2075
AlphaToCoverageInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType,ImageBackingMode backingMode)2076 AlphaToCoverageInstance::AlphaToCoverageInstance (Context& context,
2077 VkPrimitiveTopology topology,
2078 const std::vector<Vertex4RGBA>& vertices,
2079 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
2080 const VkPipelineColorBlendAttachmentState& blendState,
2081 GeometryType geometryType,
2082 ImageBackingMode backingMode)
2083 : vkt::TestInstance (context)
2084 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
2085 , m_renderSize (32, 32)
2086 , m_primitiveTopology (topology)
2087 , m_vertices (vertices)
2088 , m_multisampleStateParams (multisampleStateParams)
2089 , m_colorBlendState (blendState)
2090 , m_geometryType (geometryType)
2091 , m_backingMode (backingMode)
2092 {
2093 }
2094
iterate(void)2095 tcu::TestStatus AlphaToCoverageInstance::iterate (void)
2096 {
2097 DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2098
2099 de::MovePtr<tcu::TextureLevel> result;
2100 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode);
2101
2102 result = renderer.render();
2103
2104 return verifyImage(result->getAccess());
2105 }
2106
verifyImage(const tcu::ConstPixelBufferAccess & result)2107 tcu::TestStatus AlphaToCoverageInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
2108 {
2109 float maxColorValue;
2110
2111 switch (m_geometryType)
2112 {
2113 case GEOMETRY_TYPE_OPAQUE_QUAD:
2114 maxColorValue = 1.01f;
2115 break;
2116
2117 case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
2118 maxColorValue = 0.52f;
2119 break;
2120
2121 case GEOMETRY_TYPE_INVISIBLE_QUAD:
2122 maxColorValue = 0.01f;
2123 break;
2124
2125 default:
2126 maxColorValue = 0.0f;
2127 DE_ASSERT(false);
2128 }
2129
2130 for (int y = 0; y < m_renderSize.y(); y++)
2131 {
2132 for (int x = 0; x < m_renderSize.x(); x++)
2133 {
2134 if (result.getPixel(x, y).x() > maxColorValue)
2135 {
2136 std::ostringstream message;
2137 message << "Pixel is not below the threshold value (" << result.getPixel(x, y).x() << " > " << maxColorValue << ")";
2138 return tcu::TestStatus::fail(message.str());
2139 }
2140 }
2141 }
2142
2143 return tcu::TestStatus::pass("Image matches reference value");
2144 }
2145
2146 // AlphaToCoverageNoColorAttachmentInstance
2147
AlphaToCoverageNoColorAttachmentInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType,ImageBackingMode backingMode)2148 AlphaToCoverageNoColorAttachmentInstance::AlphaToCoverageNoColorAttachmentInstance (Context& context,
2149 VkPrimitiveTopology topology,
2150 const std::vector<Vertex4RGBA>& vertices,
2151 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
2152 const VkPipelineColorBlendAttachmentState& blendState,
2153 GeometryType geometryType,
2154 ImageBackingMode backingMode)
2155 : vkt::TestInstance (context)
2156 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
2157 , m_depthStencilFormat (VK_FORMAT_D16_UNORM)
2158 , m_renderSize (32, 32)
2159 , m_primitiveTopology (topology)
2160 , m_vertices (vertices)
2161 , m_multisampleStateParams (multisampleStateParams)
2162 , m_colorBlendState (blendState)
2163 , m_geometryType (geometryType)
2164 , m_backingMode (backingMode)
2165 {
2166 }
2167
iterate(void)2168 tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::iterate (void)
2169 {
2170 DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2171
2172 de::MovePtr<tcu::TextureLevel> result;
2173 MultisampleRenderer renderer (m_context, m_colorFormat, m_depthStencilFormat, m_renderSize, true, false, 1u, &m_primitiveTopology, &m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_DEPTHSTENCIL_ONLY, m_backingMode, 1.0f);
2174
2175 result = renderer.render();
2176
2177 return verifyImage(result->getAccess());
2178 }
2179
verifyImage(const tcu::ConstPixelBufferAccess & result)2180 tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
2181 {
2182 for (int y = 0; y < m_renderSize.y(); y++)
2183 {
2184 for (int x = 0; x < m_renderSize.x(); x++)
2185 {
2186 // Expect full red for each pixel. Fail if clear color is showing.
2187 if (result.getPixel(x, y).x() < 1.0f)
2188 {
2189 // Log result image when failing.
2190 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet;
2191
2192 return tcu::TestStatus::fail("Fail");
2193 }
2194 }
2195 }
2196
2197 return tcu::TestStatus::pass("Pass");
2198 }
2199
2200 // AlphaToCoverageColorUnusedAttachmentInstance
2201
AlphaToCoverageColorUnusedAttachmentInstance(Context & context,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,GeometryType geometryType,ImageBackingMode backingMode)2202 AlphaToCoverageColorUnusedAttachmentInstance::AlphaToCoverageColorUnusedAttachmentInstance (Context& context,
2203 VkPrimitiveTopology topology,
2204 const std::vector<Vertex4RGBA>& vertices,
2205 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
2206 const VkPipelineColorBlendAttachmentState& blendState,
2207 GeometryType geometryType,
2208 ImageBackingMode backingMode)
2209 : vkt::TestInstance (context)
2210 , m_colorFormat (VK_FORMAT_R5G6B5_UNORM_PACK16)
2211 , m_renderSize (32, 32)
2212 , m_primitiveTopology (topology)
2213 , m_vertices (vertices)
2214 , m_multisampleStateParams (multisampleStateParams)
2215 , m_colorBlendState (blendState)
2216 , m_geometryType (geometryType)
2217 , m_backingMode (backingMode)
2218 {
2219 }
2220
iterate(void)2221 tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::iterate (void)
2222 {
2223 DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2224
2225 de::MovePtr<tcu::TextureLevel> result;
2226 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_UNUSED_ATTACHMENT, m_backingMode);
2227
2228 result = renderer.render();
2229
2230 return verifyImage(result->getAccess());
2231 }
2232
verifyImage(const tcu::ConstPixelBufferAccess & result)2233 tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
2234 {
2235 for (int y = 0; y < m_renderSize.y(); y++)
2236 {
2237 for (int x = 0; x < m_renderSize.x(); x++)
2238 {
2239 // Quad color gets written to color buffer at location 1, and the alpha value to location 0 which is unused.
2240 // The coverage should still be affected by the alpha written to location 0.
2241 if ((m_geometryType == GEOMETRY_TYPE_OPAQUE_QUAD && result.getPixel(x, y).x() < 1.0f)
2242 || (m_geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD && result.getPixel(x, y).x() > 0.0f))
2243 {
2244 // Log result image when failing.
2245 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet;
2246
2247 return tcu::TestStatus::fail("Fail");
2248 }
2249 }
2250 }
2251
2252 return tcu::TestStatus::pass("Pass");
2253 }
2254
2255 // SampleMaskWithDepthTestInstance
2256
SampleMaskWithDepthTestInstance(Context & context,const VkSampleCountFlagBits rasterizationSamples,const bool enablePostDepthCoverage)2257 SampleMaskWithDepthTestInstance::SampleMaskWithDepthTestInstance (Context& context,
2258 const VkSampleCountFlagBits rasterizationSamples,
2259 const bool enablePostDepthCoverage)
2260 : vkt::TestInstance (context)
2261 , m_rasterizationSamples (rasterizationSamples)
2262 , m_enablePostDepthCoverage (enablePostDepthCoverage)
2263 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
2264 , m_depthStencilFormat (VK_FORMAT_D16_UNORM)
2265 , m_renderSize (tcu::IVec2(3, 3))
2266 , m_useDepth (true)
2267 , m_useStencil (false)
2268 , m_topology (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
2269 , m_renderColor (tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f))
2270 , m_vertices (generateVertices())
2271 , m_multisampleStateParams (getMultisampleState(rasterizationSamples))
2272 , m_blendState (getDefaultColorBlendAttachmentState())
2273 , m_renderType (RENDER_TYPE_RESOLVE)
2274 , m_imageBackingMode (IMAGE_BACKING_MODE_REGULAR)
2275 , m_depthClearValue (0.667f)
2276 {
2277 m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_2_BIT] = SampleCoverage(1u, 1u); // !< Sample coverage of the diagonally halved pixel,
2278 m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_4_BIT] = SampleCoverage(2u, 2u); // !< with max possible subPixelPrecisionBits threshold
2279 m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_8_BIT] = SampleCoverage(2u, 6u); // !<
2280 m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_16_BIT] = SampleCoverage(6u, 11u); // !<
2281 }
2282
iterate(void)2283 tcu::TestStatus SampleMaskWithDepthTestInstance::iterate (void)
2284 {
2285 de::MovePtr<tcu::TextureLevel> result;
2286
2287 MultisampleRenderer renderer (m_context, m_colorFormat, m_depthStencilFormat, m_renderSize, m_useDepth, m_useStencil, 1u, &m_topology,
2288 &m_vertices, m_multisampleStateParams, m_blendState, m_renderType, m_imageBackingMode, m_depthClearValue);
2289 result = renderer.render();
2290
2291 return verifyImage(result->getAccess());
2292 }
2293
getMultisampleState(const VkSampleCountFlagBits rasterizationSamples)2294 VkPipelineMultisampleStateCreateInfo SampleMaskWithDepthTestInstance::getMultisampleState (const VkSampleCountFlagBits rasterizationSamples)
2295 {
2296 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2297 {
2298 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
2299 DE_NULL, // const void* pNext;
2300 0u, // VkPipelineMultisampleStateCreateFlags flags;
2301 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
2302 false, // VkBool32 sampleShadingEnable;
2303 0.0f, // float minSampleShading;
2304 DE_NULL, // const VkSampleMask* pSampleMask;
2305 false, // VkBool32 alphaToCoverageEnable;
2306 false // VkBool32 alphaToOneEnable;
2307 };
2308
2309 return multisampleStateParams;
2310 }
2311
generateVertices(void)2312 std::vector<Vertex4RGBA> SampleMaskWithDepthTestInstance::generateVertices (void)
2313 {
2314 std::vector<Vertex4RGBA> vertices;
2315
2316 {
2317 const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), m_renderColor };
2318 vertices.push_back(vertexInput);
2319 }
2320 {
2321 const Vertex4RGBA vertexInput = { tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), m_renderColor };
2322 vertices.push_back(vertexInput);
2323 }
2324 {
2325 const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), m_renderColor };
2326 vertices.push_back(vertexInput);
2327 }
2328
2329 return vertices;
2330 }
2331
verifyImage(const tcu::ConstPixelBufferAccess & result)2332 tcu::TestStatus SampleMaskWithDepthTestInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
2333 {
2334 bool pass = true;
2335 const int width = result.getWidth();
2336 const int height = result.getHeight();
2337 tcu::TestLog& log = m_context.getTestContext().getLog();
2338
2339 DE_ASSERT(width == 3);
2340 DE_ASSERT(height == 3);
2341
2342 const tcu::Vec4 clearColor = tcu::Vec4(0.0f);
2343
2344 for (int x = 0; x < width; ++x)
2345 for (int y = 0; y < height; ++y)
2346 {
2347 const tcu::Vec4 resultPixel = result.getPixel(x, y);
2348
2349 if (x + y == 0)
2350 {
2351 if (resultPixel != m_renderColor)
2352 {
2353 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
2354 << " Reference: " << m_renderColor << tcu::TestLog::EndMessage;
2355 pass = false;
2356 }
2357 }
2358 else if (x + y == 1)
2359 {
2360 // default: m_rasterizationSamples bits set in FS's gl_SampleMaskIn[0] (before depth test)
2361 // post_depth_coverage: m_refCoverageAfterDepthTest[m_rasterizationSamples] bits set in FS's gl_SampleMaskIn[0] (after depth test)
2362 const float threshold = 0.02f;
2363 const float minCoverage = (m_enablePostDepthCoverage ? (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples : 1.0f)
2364 * ((float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples);
2365 const float maxCoverage = (m_enablePostDepthCoverage ? (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples : 1.0f)
2366 * ((float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples);
2367
2368 bool localPass = true;
2369 for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx)
2370 {
2371 if (m_renderColor[componentNdx] != 0.0f && (resultPixel[componentNdx] <= m_renderColor[componentNdx] * (minCoverage - threshold)
2372 || resultPixel[componentNdx] >= m_renderColor[componentNdx] * (maxCoverage + threshold)))
2373 localPass = false;
2374 }
2375
2376 if (!localPass)
2377 {
2378 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
2379 << " Reference range ( " << m_renderColor * (minCoverage - threshold) << " ; " << m_renderColor * (maxCoverage + threshold) << " )" << tcu::TestLog::EndMessage;
2380 pass = false;
2381 }
2382 }
2383 else
2384 {
2385 if (resultPixel != clearColor)
2386 {
2387 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
2388 << " Reference: " << clearColor << tcu::TestLog::EndMessage;
2389 pass = false;
2390 }
2391 }
2392 }
2393
2394 if (pass)
2395 return tcu::TestStatus::pass("Passed");
2396 else
2397 return tcu::TestStatus::fail("Failed");
2398 }
2399
2400 // MultisampleRenderer
2401
MultisampleRenderer(Context & context,const VkFormat colorFormat,const tcu::IVec2 & renderSize,const VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,const RenderType renderType,const ImageBackingMode backingMode)2402 MultisampleRenderer::MultisampleRenderer (Context& context,
2403 const VkFormat colorFormat,
2404 const tcu::IVec2& renderSize,
2405 const VkPrimitiveTopology topology,
2406 const std::vector<Vertex4RGBA>& vertices,
2407 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
2408 const VkPipelineColorBlendAttachmentState& blendState,
2409 const RenderType renderType,
2410 const ImageBackingMode backingMode)
2411 : m_context (context)
2412 , m_bindSemaphore (createSemaphore(context.getDeviceInterface(), context.getDevice()))
2413 , m_colorFormat (colorFormat)
2414 , m_depthStencilFormat (VK_FORMAT_UNDEFINED)
2415 , m_renderSize (renderSize)
2416 , m_useDepth (false)
2417 , m_useStencil (false)
2418 , m_multisampleStateParams (multisampleStateParams)
2419 , m_colorBlendState (blendState)
2420 , m_renderType (renderType)
2421 , m_backingMode (backingMode)
2422 , m_depthClearValue (1.0f)
2423 {
2424 initialize(context, 1u, &topology, &vertices);
2425 }
2426
MultisampleRenderer(Context & context,const VkFormat colorFormat,const VkFormat depthStencilFormat,const tcu::IVec2 & renderSize,const bool useDepth,const bool useStencil,const deUint32 numTopologies,const VkPrimitiveTopology * pTopology,const std::vector<Vertex4RGBA> * pVertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,const RenderType renderType,const ImageBackingMode backingMode,const float depthClearValue)2427 MultisampleRenderer::MultisampleRenderer (Context& context,
2428 const VkFormat colorFormat,
2429 const VkFormat depthStencilFormat,
2430 const tcu::IVec2& renderSize,
2431 const bool useDepth,
2432 const bool useStencil,
2433 const deUint32 numTopologies,
2434 const VkPrimitiveTopology* pTopology,
2435 const std::vector<Vertex4RGBA>* pVertices,
2436 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
2437 const VkPipelineColorBlendAttachmentState& blendState,
2438 const RenderType renderType,
2439 const ImageBackingMode backingMode,
2440 const float depthClearValue)
2441 : m_context (context)
2442 , m_bindSemaphore (createSemaphore(context.getDeviceInterface(), context.getDevice()))
2443 , m_colorFormat (colorFormat)
2444 , m_depthStencilFormat (depthStencilFormat)
2445 , m_renderSize (renderSize)
2446 , m_useDepth (useDepth)
2447 , m_useStencil (useStencil)
2448 , m_multisampleStateParams (multisampleStateParams)
2449 , m_colorBlendState (blendState)
2450 , m_renderType (renderType)
2451 , m_backingMode (backingMode)
2452 , m_depthClearValue (depthClearValue)
2453 {
2454 initialize(context, numTopologies, pTopology, pVertices);
2455 }
2456
initialize(Context & context,const deUint32 numTopologies,const VkPrimitiveTopology * pTopology,const std::vector<Vertex4RGBA> * pVertices)2457 void MultisampleRenderer::initialize (Context& context,
2458 const deUint32 numTopologies,
2459 const VkPrimitiveTopology* pTopology,
2460 const std::vector<Vertex4RGBA>* pVertices)
2461 {
2462 if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), m_multisampleStateParams.rasterizationSamples))
2463 throw tcu::NotSupportedError("Unsupported number of rasterization samples");
2464
2465 const DeviceInterface& vk = context.getDeviceInterface();
2466 const VkDevice vkDevice = context.getDevice();
2467 const VkPhysicalDeviceFeatures features = context.getDeviceFeatures();
2468 const deUint32 queueFamilyIndices[] = { context.getUniversalQueueFamilyIndex(), context.getSparseQueueFamilyIndex() };
2469 const bool sparse = m_backingMode == IMAGE_BACKING_MODE_SPARSE;
2470 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
2471 const VkImageCreateFlags imageCreateFlags = sparse ? (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) : 0u;
2472 const VkSharingMode sharingMode = (sparse && context.getUniversalQueueFamilyIndex() != context.getSparseQueueFamilyIndex()) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
2473 Allocator& memAlloc = m_context.getDefaultAllocator();
2474 const bool usesResolveImage = m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT;
2475
2476 if (sparse)
2477 {
2478 bool sparseSamplesSupported = false;
2479 switch(m_multisampleStateParams.rasterizationSamples)
2480 {
2481 case VK_SAMPLE_COUNT_2_BIT:
2482 sparseSamplesSupported = features.sparseResidency2Samples;
2483 break;
2484 case VK_SAMPLE_COUNT_4_BIT:
2485 sparseSamplesSupported = features.sparseResidency4Samples;
2486 break;
2487 case VK_SAMPLE_COUNT_8_BIT:
2488 sparseSamplesSupported = features.sparseResidency8Samples;
2489 break;
2490 case VK_SAMPLE_COUNT_16_BIT:
2491 sparseSamplesSupported = features.sparseResidency16Samples;
2492 break;
2493 default:
2494 break;
2495 }
2496
2497 if (!sparseSamplesSupported)
2498 throw tcu::NotSupportedError("Unsupported number of rasterization samples for sparse residency");
2499 }
2500
2501 if (sparse && !context.getDeviceFeatures().sparseBinding)
2502 throw tcu::NotSupportedError("No sparseBinding support");
2503
2504 // Create color image
2505 {
2506 const VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2507 (m_renderType == RENDER_TYPE_COPY_SAMPLES ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0u);
2508
2509 const VkImageCreateInfo colorImageParams =
2510 {
2511 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2512 DE_NULL, // const void* pNext;
2513 imageCreateFlags, // VkImageCreateFlags flags;
2514 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2515 m_colorFormat, // VkFormat format;
2516 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent;
2517 1u, // deUint32 mipLevels;
2518 1u, // deUint32 arrayLayers;
2519 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples;
2520 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2521 imageUsageFlags, // VkImageUsageFlags usage;
2522 sharingMode, // VkSharingMode sharingMode;
2523 sharingMode == VK_SHARING_MODE_CONCURRENT ? 2u : 1u, // deUint32 queueFamilyIndexCount;
2524 queueFamilyIndices, // const deUint32* pQueueFamilyIndices;
2525 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2526 };
2527
2528 if (sparse && !checkSparseImageFormatSupport(context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams))
2529 TCU_THROW(NotSupportedError, "The image format does not support sparse operations.");
2530
2531 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
2532
2533 // Allocate and bind color image memory
2534 if (sparse)
2535 {
2536 allocateAndBindSparseImage(vk, vkDevice, context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams, *m_bindSemaphore, context.getSparseQueue(), memAlloc, m_allocations, mapVkFormat(m_colorFormat), *m_colorImage);
2537 }
2538 else
2539 {
2540 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
2541 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
2542 }
2543 }
2544
2545 // Create resolve image
2546 if (usesResolveImage)
2547 {
2548 const VkImageCreateInfo resolveImageParams =
2549 {
2550 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2551 DE_NULL, // const void* pNext;
2552 0u, // VkImageCreateFlags flags;
2553 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2554 m_colorFormat, // VkFormat format;
2555 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent;
2556 1u, // deUint32 mipLevels;
2557 1u, // deUint32 arrayLayers;
2558 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2559 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2560 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage;
2561 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2562 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2563 1u, // deUint32 queueFamilyIndexCount;
2564 queueFamilyIndices, // const deUint32* pQueueFamilyIndices;
2565 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2566 };
2567
2568 m_resolveImage = createImage(vk, vkDevice, &resolveImageParams);
2569
2570 // Allocate and bind resolve image memory
2571 m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any);
2572 VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset()));
2573
2574 // Create resolve attachment view
2575 {
2576 const VkImageViewCreateInfo resolveAttachmentViewParams =
2577 {
2578 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2579 DE_NULL, // const void* pNext;
2580 0u, // VkImageViewCreateFlags flags;
2581 *m_resolveImage, // VkImage image;
2582 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2583 m_colorFormat, // VkFormat format;
2584 componentMappingRGBA, // VkComponentMapping components;
2585 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
2586 };
2587
2588 m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams);
2589 }
2590 }
2591
2592 // Create per-sample output images
2593 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2594 {
2595 const VkImageCreateInfo perSampleImageParams =
2596 {
2597 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2598 DE_NULL, // const void* pNext;
2599 0u, // VkImageCreateFlags flags;
2600 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2601 m_colorFormat, // VkFormat format;
2602 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent;
2603 1u, // deUint32 mipLevels;
2604 1u, // deUint32 arrayLayers;
2605 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2606 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2607 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage;
2608 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
2609 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2610 1u, // deUint32 queueFamilyIndexCount;
2611 queueFamilyIndices, // const deUint32* pQueueFamilyIndices;
2612 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2613 };
2614
2615 m_perSampleImages.resize(static_cast<size_t>(m_multisampleStateParams.rasterizationSamples));
2616
2617 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2618 {
2619 m_perSampleImages[i] = de::SharedPtr<PerSampleImage>(new PerSampleImage);
2620 PerSampleImage& image = *m_perSampleImages[i];
2621
2622 image.m_image = createImage(vk, vkDevice, &perSampleImageParams);
2623
2624 // Allocate and bind image memory
2625 image.m_imageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image.m_image), MemoryRequirement::Any);
2626 VK_CHECK(vk.bindImageMemory(vkDevice, *image.m_image, image.m_imageAlloc->getMemory(), image.m_imageAlloc->getOffset()));
2627
2628 // Create per-sample attachment view
2629 {
2630 const VkImageViewCreateInfo perSampleAttachmentViewParams =
2631 {
2632 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2633 DE_NULL, // const void* pNext;
2634 0u, // VkImageViewCreateFlags flags;
2635 *image.m_image, // VkImage image;
2636 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2637 m_colorFormat, // VkFormat format;
2638 componentMappingRGBA, // VkComponentMapping components;
2639 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
2640 };
2641
2642 image.m_attachmentView = createImageView(vk, vkDevice, &perSampleAttachmentViewParams);
2643 }
2644 }
2645 }
2646
2647 // Create a depth/stencil image
2648 if (m_useDepth || m_useStencil)
2649 {
2650 const VkImageCreateInfo depthStencilImageParams =
2651 {
2652 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2653 DE_NULL, // const void* pNext;
2654 0u, // VkImageCreateFlags flags;
2655 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2656 m_depthStencilFormat, // VkFormat format;
2657 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent;
2658 1u, // deUint32 mipLevels;
2659 1u, // deUint32 arrayLayers;
2660 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples;
2661 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2662 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // VkImageUsageFlags usage;
2663 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2664 1u, // deUint32 queueFamilyIndexCount;
2665 queueFamilyIndices, // const deUint32* pQueueFamilyIndices;
2666 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2667 };
2668
2669 m_depthStencilImage = createImage(vk, vkDevice, &depthStencilImageParams);
2670
2671 // Allocate and bind depth/stencil image memory
2672 m_depthStencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthStencilImage), MemoryRequirement::Any);
2673 VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthStencilImage, m_depthStencilImageAlloc->getMemory(), m_depthStencilImageAlloc->getOffset()));
2674 }
2675
2676 // Create color attachment view
2677 {
2678 const VkImageViewCreateInfo colorAttachmentViewParams =
2679 {
2680 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2681 DE_NULL, // const void* pNext;
2682 0u, // VkImageViewCreateFlags flags;
2683 *m_colorImage, // VkImage image;
2684 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2685 m_colorFormat, // VkFormat format;
2686 componentMappingRGBA, // VkComponentMapping components;
2687 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
2688 };
2689
2690 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
2691 }
2692
2693 VkImageAspectFlags depthStencilAttachmentAspect = (VkImageAspectFlagBits)0;
2694
2695 // Create depth/stencil attachment view
2696 if (m_useDepth || m_useStencil)
2697 {
2698 depthStencilAttachmentAspect = getImageAspectFlags(m_depthStencilFormat);
2699
2700 const VkImageViewCreateInfo depthStencilAttachmentViewParams =
2701 {
2702 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2703 DE_NULL, // const void* pNext;
2704 0u, // VkImageViewCreateFlags flags;
2705 *m_depthStencilImage, // VkImage image;
2706 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2707 m_depthStencilFormat, // VkFormat format;
2708 componentMappingRGBA, // VkComponentMapping components;
2709 { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
2710 };
2711
2712 m_depthStencilAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
2713 }
2714
2715 // Create render pass
2716 {
2717 std::vector<VkAttachmentDescription> attachmentDescriptions;
2718 {
2719 const VkAttachmentDescription colorAttachmentDescription =
2720 {
2721 0u, // VkAttachmentDescriptionFlags flags;
2722 m_colorFormat, // VkFormat format;
2723 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples;
2724 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2725 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2726 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2727 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2728 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
2729 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
2730 };
2731 attachmentDescriptions.push_back(colorAttachmentDescription);
2732 }
2733
2734 deUint32 resolveAttachmentIndex = VK_ATTACHMENT_UNUSED;
2735
2736 if (usesResolveImage)
2737 {
2738 resolveAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
2739
2740 const VkAttachmentDescription resolveAttachmentDescription =
2741 {
2742 0u, // VkAttachmentDescriptionFlags flags;
2743 m_colorFormat, // VkFormat format;
2744 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2745 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2746 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2747 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2748 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2749 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
2750 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
2751 };
2752 attachmentDescriptions.push_back(resolveAttachmentDescription);
2753 }
2754
2755 deUint32 perSampleAttachmentIndex = VK_ATTACHMENT_UNUSED;
2756
2757 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2758 {
2759 perSampleAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
2760
2761 const VkAttachmentDescription perSampleAttachmentDescription =
2762 {
2763 0u, // VkAttachmentDescriptionFlags flags;
2764 m_colorFormat, // VkFormat format;
2765 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
2766 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2767 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2768 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2769 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2770 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
2771 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
2772 };
2773
2774 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2775 {
2776 attachmentDescriptions.push_back(perSampleAttachmentDescription);
2777 }
2778 }
2779
2780 deUint32 depthStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
2781
2782 if (m_useDepth || m_useStencil)
2783 {
2784 depthStencilAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
2785
2786 const VkAttachmentDescription depthStencilAttachmentDescription =
2787 {
2788 0u, // VkAttachmentDescriptionFlags flags;
2789 m_depthStencilFormat, // VkFormat format;
2790 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples;
2791 (m_useDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE), // VkAttachmentLoadOp loadOp;
2792 (m_useDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE), // VkAttachmentStoreOp storeOp;
2793 (m_useStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE), // VkAttachmentStoreOp stencilLoadOp;
2794 (m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE), // VkAttachmentStoreOp stencilStoreOp;
2795 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
2796 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
2797 };
2798 attachmentDescriptions.push_back(depthStencilAttachmentDescription);
2799 };
2800
2801 const VkAttachmentReference colorAttachmentReference =
2802 {
2803 0u, // deUint32 attachment;
2804 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
2805 };
2806
2807 const VkAttachmentReference inputAttachmentReference =
2808 {
2809 0u, // deUint32 attachment;
2810 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout layout;
2811 };
2812
2813 const VkAttachmentReference resolveAttachmentReference =
2814 {
2815 resolveAttachmentIndex, // deUint32 attachment;
2816 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
2817 };
2818
2819 const VkAttachmentReference colorAttachmentReferencesUnusedAttachment[] =
2820 {
2821 {
2822 VK_ATTACHMENT_UNUSED, // deUint32 attachment
2823 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout
2824 },
2825 {
2826 0u, // deUint32 attachment
2827 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
2828 }
2829 };
2830
2831 const VkAttachmentReference resolveAttachmentReferencesUnusedAttachment[] =
2832 {
2833 {
2834 VK_ATTACHMENT_UNUSED, // deUint32 attachment
2835 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout
2836 },
2837 {
2838 resolveAttachmentIndex, // deUint32 attachment
2839 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
2840 }
2841 };
2842
2843 std::vector<VkAttachmentReference> perSampleAttachmentReferences(m_perSampleImages.size());
2844 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2845 {
2846 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2847 {
2848 const VkAttachmentReference perSampleAttachmentReference =
2849 {
2850 perSampleAttachmentIndex + static_cast<deUint32>(i), // deUint32 attachment;
2851 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
2852 };
2853 perSampleAttachmentReferences[i] = perSampleAttachmentReference;
2854 }
2855 }
2856
2857 const VkAttachmentReference depthStencilAttachmentReference =
2858 {
2859 depthStencilAttachmentIndex, // deUint32 attachment;
2860 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout;
2861 };
2862
2863 std::vector<VkSubpassDescription> subpassDescriptions;
2864 std::vector<VkSubpassDependency> subpassDependencies;
2865
2866 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
2867 {
2868 const VkSubpassDescription subpassDescription0 =
2869 {
2870 0u, // VkSubpassDescriptionFlags flags
2871 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
2872 0u, // deUint32 inputAttachmentCount
2873 DE_NULL, // const VkAttachmentReference* pInputAttachments
2874 0u, // deUint32 colorAttachmentCount
2875 DE_NULL, // const VkAttachmentReference* pColorAttachments
2876 DE_NULL, // const VkAttachmentReference* pResolveAttachments
2877 &depthStencilAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment
2878 0u, // deUint32 preserveAttachmentCount
2879 DE_NULL // const VkAttachmentReference* pPreserveAttachments
2880 };
2881
2882 const VkSubpassDescription subpassDescription1 =
2883 {
2884 0u, // VkSubpassDescriptionFlags flags
2885 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
2886 0u, // deUint32 inputAttachmentCount
2887 DE_NULL, // const VkAttachmentReference* pInputAttachments
2888 1u, // deUint32 colorAttachmentCount
2889 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments
2890 &resolveAttachmentReference, // const VkAttachmentReference* pResolveAttachments
2891 &depthStencilAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment
2892 0u, // deUint32 preserveAttachmentCount
2893 DE_NULL // const VkAttachmentReference* pPreserveAttachments
2894 };
2895
2896 const VkSubpassDependency subpassDependency =
2897 {
2898 0u, // deUint32 srcSubpass
2899 1u, // deUint32 dstSubpass
2900 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags srcStageMask
2901 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags dstStageMask
2902 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
2903 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask
2904 0u // VkDependencyFlags dependencyFlags
2905 };
2906
2907 subpassDescriptions.push_back(subpassDescription0);
2908 subpassDescriptions.push_back(subpassDescription1);
2909 subpassDependencies.push_back(subpassDependency);
2910 }
2911 else if (m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT)
2912 {
2913 const VkSubpassDescription renderSubpassDescription =
2914 {
2915 0u, // VkSubpassDescriptionFlags flags
2916 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
2917 0u, // deUint32 inputAttachmentCount
2918 DE_NULL, // const VkAttachmentReference* pInputAttachments
2919 2u, // deUint32 colorAttachmentCount
2920 colorAttachmentReferencesUnusedAttachment, // const VkAttachmentReference* pColorAttachments
2921 resolveAttachmentReferencesUnusedAttachment, // const VkAttachmentReference* pResolveAttachments
2922 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment
2923 0u, // deUint32 preserveAttachmentCount
2924 DE_NULL // const VkAttachmentReference* pPreserveAttachments
2925 };
2926
2927 subpassDescriptions.push_back(renderSubpassDescription);
2928 }
2929 else
2930 {
2931 {
2932 const VkSubpassDescription renderSubpassDescription =
2933 {
2934 0u, // VkSubpassDescriptionFlags flags;
2935 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2936 0u, // deUint32 inputAttachmentCount;
2937 DE_NULL, // const VkAttachmentReference* pInputAttachments;
2938 1u, // deUint32 colorAttachmentCount;
2939 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
2940 usesResolveImage ? &resolveAttachmentReference : DE_NULL, // const VkAttachmentReference* pResolveAttachments;
2941 (m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL), // const VkAttachmentReference* pDepthStencilAttachment;
2942 0u, // deUint32 preserveAttachmentCount;
2943 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
2944 };
2945 subpassDescriptions.push_back(renderSubpassDescription);
2946 }
2947
2948 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
2949 {
2950
2951 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
2952 {
2953 const VkSubpassDescription copySampleSubpassDescription =
2954 {
2955 0u, // VkSubpassDescriptionFlags flags;
2956 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2957 1u, // deUint32 inputAttachmentCount;
2958 &inputAttachmentReference, // const VkAttachmentReference* pInputAttachments;
2959 1u, // deUint32 colorAttachmentCount;
2960 &perSampleAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments;
2961 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
2962 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
2963 0u, // deUint32 preserveAttachmentCount;
2964 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
2965 };
2966 subpassDescriptions.push_back(copySampleSubpassDescription);
2967
2968 const VkSubpassDependency copySampleSubpassDependency =
2969 {
2970 0u, // deUint32 srcSubpass
2971 1u + static_cast<deUint32>(i), // deUint32 dstSubpass
2972 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
2973 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask
2974 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
2975 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask
2976 0u, // VkDependencyFlags dependencyFlags
2977 };
2978 subpassDependencies.push_back(copySampleSubpassDependency);
2979 }
2980 // the very last sample pass must synchronize with all prior subpasses
2981 for (size_t i = 0; i < (m_perSampleImages.size() - 1); ++i)
2982 {
2983 const VkSubpassDependency storeSubpassDependency =
2984 {
2985 1u + static_cast<deUint32>(i), // deUint32 srcSubpass
2986 static_cast<deUint32>(m_perSampleImages.size()), // deUint32 dstSubpass
2987 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
2988 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask
2989 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
2990 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask
2991 0u, // VkDependencyFlags dependencyFlags
2992 };
2993 subpassDependencies.push_back(storeSubpassDependency);
2994 }
2995 }
2996 }
2997
2998 const VkRenderPassCreateInfo renderPassParams =
2999 {
3000 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
3001 DE_NULL, // const void* pNext;
3002 0u, // VkRenderPassCreateFlags flags;
3003 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount;
3004 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
3005 (deUint32)subpassDescriptions.size(), // deUint32 subpassCount;
3006 &subpassDescriptions[0], // const VkSubpassDescription* pSubpasses;
3007 (deUint32)subpassDependencies.size(), // deUint32 dependencyCount;
3008 subpassDependencies.size() != 0 ? &subpassDependencies[0] : DE_NULL
3009 };
3010
3011 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
3012 }
3013
3014 // Create framebuffer
3015 {
3016 std::vector<VkImageView> attachments;
3017 attachments.push_back(*m_colorAttachmentView);
3018 if (usesResolveImage)
3019 {
3020 attachments.push_back(*m_resolveAttachmentView);
3021 }
3022 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3023 {
3024 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3025 {
3026 attachments.push_back(*m_perSampleImages[i]->m_attachmentView);
3027 }
3028 }
3029
3030 if (m_useDepth || m_useStencil)
3031 {
3032 attachments.push_back(*m_depthStencilAttachmentView);
3033 }
3034
3035 const VkFramebufferCreateInfo framebufferParams =
3036 {
3037 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
3038 DE_NULL, // const void* pNext;
3039 0u, // VkFramebufferCreateFlags flags;
3040 *m_renderPass, // VkRenderPass renderPass;
3041 (deUint32)attachments.size(), // deUint32 attachmentCount;
3042 &attachments[0], // const VkImageView* pAttachments;
3043 (deUint32)m_renderSize.x(), // deUint32 width;
3044 (deUint32)m_renderSize.y(), // deUint32 height;
3045 1u // deUint32 layers;
3046 };
3047
3048 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
3049 }
3050
3051 // Create pipeline layout
3052 {
3053 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
3054 {
3055 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
3056 DE_NULL, // const void* pNext;
3057 0u, // VkPipelineLayoutCreateFlags flags;
3058 0u, // deUint32 setLayoutCount;
3059 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
3060 0u, // deUint32 pushConstantRangeCount;
3061 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
3062 };
3063
3064 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
3065
3066 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3067 {
3068
3069 // Create descriptor set layout
3070 const VkDescriptorSetLayoutBinding layoutBinding =
3071 {
3072 0u, // deUint32 binding;
3073 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType;
3074 1u, // deUint32 descriptorCount;
3075 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
3076 DE_NULL, // const VkSampler* pImmutableSamplers;
3077 };
3078
3079 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutParams =
3080 {
3081 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType
3082 DE_NULL, // const void* pNext
3083 0u, // VkDescriptorSetLayoutCreateFlags flags
3084 1u, // deUint32 bindingCount
3085 &layoutBinding // const VkDescriptorSetLayoutBinding* pBindings
3086 };
3087 m_copySampleDesciptorLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
3088
3089 // Create pipeline layout
3090
3091 const VkPushConstantRange pushConstantRange =
3092 {
3093 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
3094 0u, // deUint32 offset;
3095 sizeof(deInt32) // deUint32 size;
3096 };
3097 const VkPipelineLayoutCreateInfo copySamplePipelineLayoutParams =
3098 {
3099 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
3100 DE_NULL, // const void* pNext;
3101 0u, // VkPipelineLayoutCreateFlags flags;
3102 1u, // deUint32 setLayoutCount;
3103 &m_copySampleDesciptorLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
3104 1u, // deUint32 pushConstantRangeCount;
3105 &pushConstantRange // const VkPushConstantRange* pPushConstantRanges;
3106 };
3107 m_copySamplePipelineLayout = createPipelineLayout(vk, vkDevice, ©SamplePipelineLayoutParams);
3108 }
3109 }
3110
3111 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
3112 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
3113
3114 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3115 {
3116 m_copySampleVertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("quad_vert"), 0);
3117 m_copySampleFragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("copy_sample_frag"), 0);
3118 }
3119
3120 // Create pipeline
3121 {
3122 const VkVertexInputBindingDescription vertexInputBindingDescription =
3123 {
3124 0u, // deUint32 binding;
3125 sizeof(Vertex4RGBA), // deUint32 stride;
3126 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
3127 };
3128
3129 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
3130 {
3131 {
3132 0u, // deUint32 location;
3133 0u, // deUint32 binding;
3134 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
3135 0u // deUint32 offset;
3136 },
3137 {
3138 1u, // deUint32 location;
3139 0u, // deUint32 binding;
3140 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
3141 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offset;
3142 }
3143 };
3144
3145 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
3146 {
3147 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
3148 DE_NULL, // const void* pNext;
3149 0u, // VkPipelineVertexInputStateCreateFlags flags;
3150 1u, // deUint32 vertexBindingDescriptionCount;
3151 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
3152 2u, // deUint32 vertexAttributeDescriptionCount;
3153 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
3154 };
3155
3156 const std::vector<VkViewport> viewports (1, makeViewport(m_renderSize));
3157 const std::vector<VkRect2D> scissors (1, makeRect2D(m_renderSize));
3158
3159 const deUint32 attachmentCount = m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT ? 2u : 1u;
3160
3161 std::vector<VkPipelineColorBlendAttachmentState> attachments;
3162
3163 for (deUint32 attachmentIdx = 0; attachmentIdx < attachmentCount; attachmentIdx++)
3164 attachments.push_back(m_colorBlendState);
3165
3166 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
3167 {
3168 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
3169 DE_NULL, // const void* pNext;
3170 0u, // VkPipelineColorBlendStateCreateFlags flags;
3171 false, // VkBool32 logicOpEnable;
3172 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
3173 attachmentCount, // deUint32 attachmentCount;
3174 attachments.data(), // const VkPipelineColorBlendAttachmentState* pAttachments;
3175 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
3176 };
3177
3178 const VkStencilOpState stencilOpState =
3179 {
3180 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
3181 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp;
3182 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
3183 VK_COMPARE_OP_GREATER, // VkCompareOp compareOp;
3184 1u, // deUint32 compareMask;
3185 1u, // deUint32 writeMask;
3186 1u, // deUint32 reference;
3187 };
3188
3189 const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
3190 {
3191 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
3192 DE_NULL, // const void* pNext;
3193 0u, // VkPipelineDepthStencilStateCreateFlags flags;
3194 m_useDepth, // VkBool32 depthTestEnable;
3195 m_useDepth, // VkBool32 depthWriteEnable;
3196 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
3197 false, // VkBool32 depthBoundsTestEnable;
3198 m_useStencil, // VkBool32 stencilTestEnable;
3199 stencilOpState, // VkStencilOpState front;
3200 stencilOpState, // VkStencilOpState back;
3201 0.0f, // float minDepthBounds;
3202 1.0f, // float maxDepthBounds;
3203 };
3204
3205 const deUint32 numSubpasses = m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY ? 2u : 1u;
3206
3207 for (deUint32 subpassIdx = 0; subpassIdx < numSubpasses; subpassIdx++)
3208 for (deUint32 i = 0u; i < numTopologies; ++i)
3209 {
3210 m_graphicsPipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(vk, // const DeviceInterface& vk
3211 vkDevice, // const VkDevice device
3212 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
3213 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
3214 DE_NULL, // const VkShaderModule tessellationControlModule
3215 DE_NULL, // const VkShaderModule tessellationEvalModule
3216 DE_NULL, // const VkShaderModule geometryShaderModule
3217 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
3218 *m_renderPass, // const VkRenderPass renderPass
3219 viewports, // const std::vector<VkViewport>& viewports
3220 scissors, // const std::vector<VkRect2D>& scissors
3221 pTopology[i], // const VkPrimitiveTopology topology
3222 subpassIdx, // const deUint32 subpass
3223 0u, // const deUint32 patchControlPoints
3224 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
3225 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
3226 &m_multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
3227 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
3228 &colorBlendStateParams)))); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
3229 }
3230 }
3231
3232 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3233 {
3234 // Create pipelines for copying samples to single sampled images
3235 {
3236 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
3237 {
3238 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
3239 DE_NULL, // const void* pNext;
3240 0u, // VkPipelineVertexInputStateCreateFlags flags;
3241 0u, // deUint32 vertexBindingDescriptionCount;
3242 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
3243 0u, // deUint32 vertexAttributeDescriptionCount;
3244 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
3245 };
3246
3247 const std::vector<VkViewport> viewports (1, makeViewport(m_renderSize));
3248 const std::vector<VkRect2D> scissors (1, makeRect2D(m_renderSize));
3249
3250 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
3251 {
3252 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
3253 DE_NULL, // const void* pNext;
3254 0u, // VkPipelineColorBlendStateCreateFlags flags;
3255 false, // VkBool32 logicOpEnable;
3256 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
3257 1u, // deUint32 attachmentCount;
3258 &m_colorBlendState, // const VkPipelineColorBlendAttachmentState* pAttachments;
3259 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
3260 };
3261
3262 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3263 {
3264 // Pipeline is to be used in subpasses subsequent to sample-shading subpass
3265 m_copySamplePipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(vk, // const DeviceInterface& vk
3266 vkDevice, // const VkDevice device
3267 *m_copySamplePipelineLayout, // const VkPipelineLayout pipelineLayout
3268 *m_copySampleVertexShaderModule, // const VkShaderModule vertexShaderModule
3269 DE_NULL, // const VkShaderModule tessellationControlModule
3270 DE_NULL, // const VkShaderModule tessellationEvalModule
3271 DE_NULL, // const VkShaderModule geometryShaderModule
3272 *m_copySampleFragmentShaderModule, // const VkShaderModule fragmentShaderModule
3273 *m_renderPass, // const VkRenderPass renderPass
3274 viewports, // const std::vector<VkViewport>& viewports
3275 scissors, // const std::vector<VkRect2D>& scissors
3276 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // const VkPrimitiveTopology topology
3277 1u + (deUint32)i, // const deUint32 subpass
3278 0u, // const deUint32 patchControlPoints
3279 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
3280 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
3281 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
3282 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
3283 &colorBlendStateParams)))); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
3284 }
3285 }
3286
3287
3288 const VkDescriptorPoolSize descriptorPoolSize =
3289 {
3290 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType type;
3291 1u // deUint32 descriptorCount;
3292 };
3293
3294 const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo =
3295 {
3296 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType
3297 DE_NULL, // const void* pNext
3298 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags
3299 1u, // deUint32 maxSets
3300 1u, // deUint32 poolSizeCount
3301 &descriptorPoolSize // const VkDescriptorPoolSize* pPoolSizes
3302 };
3303
3304 m_copySampleDesciptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
3305
3306 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
3307 {
3308 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
3309 DE_NULL, // const void* pNext
3310 *m_copySampleDesciptorPool, // VkDescriptorPool descriptorPool
3311 1u, // deUint32 descriptorSetCount
3312 &m_copySampleDesciptorLayout.get(), // const VkDescriptorSetLayout* pSetLayouts
3313 };
3314
3315 m_copySampleDesciptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
3316
3317 const VkDescriptorImageInfo imageInfo =
3318 {
3319 DE_NULL,
3320 *m_colorAttachmentView,
3321 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
3322 };
3323 const VkWriteDescriptorSet descriptorWrite =
3324 {
3325 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
3326 DE_NULL, // const void* pNext;
3327 *m_copySampleDesciptorSet, // VkDescriptorSet dstSet;
3328 0u, // deUint32 dstBinding;
3329 0u, // deUint32 dstArrayElement;
3330 1u, // deUint32 descriptorCount;
3331 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType;
3332 &imageInfo, // const VkDescriptorImageInfo* pImageInfo;
3333 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo;
3334 DE_NULL, // const VkBufferView* pTexelBufferView;
3335 };
3336 vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
3337 }
3338
3339 // Create vertex buffer
3340 {
3341 const VkBufferCreateInfo vertexBufferParams =
3342 {
3343 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
3344 DE_NULL, // const void* pNext;
3345 0u, // VkBufferCreateFlags flags;
3346 1024u, // VkDeviceSize size;
3347 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
3348 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3349 1u, // deUint32 queueFamilyIndexCount;
3350 &queueFamilyIndices[0] // const deUint32* pQueueFamilyIndices;
3351 };
3352
3353 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
3354 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
3355
3356 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
3357
3358 // Load vertices into vertex buffer
3359 {
3360 Vertex4RGBA* pDst = static_cast<Vertex4RGBA*>(m_vertexBufferAlloc->getHostPtr());
3361
3362 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
3363 {
3364 DE_ASSERT(numTopologies == 1);
3365
3366 std::vector<Vertex4RGBA> vertices = pVertices[0];
3367
3368 // Set alpha to zero for the first draw. This should prevent depth writes because of zero coverage.
3369 for (size_t i = 0; i < vertices.size(); i++)
3370 vertices[i].color.w() = 0.0f;
3371
3372 deMemcpy(pDst, &vertices[0], vertices.size() * sizeof(Vertex4RGBA));
3373
3374 pDst += vertices.size();
3375
3376 // The second draw uses original vertices which are pure red.
3377 deMemcpy(pDst, &pVertices[0][0], pVertices[0].size() * sizeof(Vertex4RGBA));
3378 }
3379 else
3380 {
3381 for (deUint32 i = 0u; i < numTopologies; ++i)
3382 {
3383 deMemcpy(pDst, &pVertices[i][0], pVertices[i].size() * sizeof(Vertex4RGBA));
3384 pDst += pVertices[i].size();
3385 }
3386 }
3387 }
3388 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
3389 }
3390
3391 // Create command pool
3392 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndices[0]);
3393
3394 // Create command buffer
3395 {
3396 VkClearValue colorClearValue;
3397 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
3398 {
3399 colorClearValue.color.float32[0] = 0.25;
3400 colorClearValue.color.float32[1] = 0.25;
3401 colorClearValue.color.float32[2] = 0.25;
3402 colorClearValue.color.float32[3] = 1.0f;
3403 }
3404 else
3405 {
3406 colorClearValue.color.float32[0] = 0.0f;
3407 colorClearValue.color.float32[1] = 0.0f;
3408 colorClearValue.color.float32[2] = 0.0f;
3409 colorClearValue.color.float32[3] = 0.0f;
3410 }
3411
3412 VkClearValue depthStencilClearValue;
3413 depthStencilClearValue.depthStencil.depth = m_depthClearValue;
3414 depthStencilClearValue.depthStencil.stencil = 0u;
3415
3416 std::vector<VkClearValue> clearValues;
3417 clearValues.push_back(colorClearValue);
3418 if (usesResolveImage)
3419 {
3420 clearValues.push_back(colorClearValue);
3421 }
3422 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3423 {
3424 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3425 {
3426 clearValues.push_back(colorClearValue);
3427 }
3428 }
3429 if (m_useDepth || m_useStencil)
3430 {
3431 clearValues.push_back(depthStencilClearValue);
3432 }
3433
3434 vk::VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
3435 std::vector<VkImageMemoryBarrier> imageLayoutBarriers;
3436
3437 {
3438 const VkImageMemoryBarrier colorImageBarrier =
3439 // color attachment image
3440 {
3441 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3442 DE_NULL, // const void* pNext;
3443 0u, // VkAccessFlags srcAccessMask;
3444 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
3445 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
3446 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
3447 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3448 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3449 *m_colorImage, // VkImage image;
3450 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
3451 };
3452 imageLayoutBarriers.push_back(colorImageBarrier);
3453 }
3454 if (usesResolveImage)
3455 {
3456 const VkImageMemoryBarrier resolveImageBarrier =
3457 // resolve attachment image
3458 {
3459 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3460 DE_NULL, // const void* pNext;
3461 0u, // VkAccessFlags srcAccessMask;
3462 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
3463 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
3464 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
3465 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3466 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3467 *m_resolveImage, // VkImage image;
3468 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
3469 };
3470 imageLayoutBarriers.push_back(resolveImageBarrier);
3471 }
3472 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3473 {
3474 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3475 {
3476 const VkImageMemoryBarrier perSampleImageBarrier =
3477 // resolve attachment image
3478 {
3479 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3480 DE_NULL, // const void* pNext;
3481 0u, // VkAccessFlags srcAccessMask;
3482 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
3483 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
3484 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
3485 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3486 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3487 *m_perSampleImages[i]->m_image, // VkImage image;
3488 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
3489 };
3490 imageLayoutBarriers.push_back(perSampleImageBarrier);
3491 }
3492 }
3493 if (m_useDepth || m_useStencil)
3494 {
3495 const VkImageMemoryBarrier depthStencilImageBarrier =
3496 // depth/stencil attachment image
3497 {
3498 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3499 DE_NULL, // const void* pNext;
3500 0u, // VkAccessFlags srcAccessMask;
3501 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
3502 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
3503 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
3504 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3505 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3506 *m_depthStencilImage, // VkImage image;
3507 { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
3508 };
3509 imageLayoutBarriers.push_back(depthStencilImageBarrier);
3510 dstStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
3511 };
3512
3513 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3514
3515 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
3516
3517 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, dstStageMask, (VkDependencyFlags)0,
3518 0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), &imageLayoutBarriers[0]);
3519
3520 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)clearValues.size(), &clearValues[0]);
3521
3522 VkDeviceSize vertexBufferOffset = 0u;
3523
3524 for (deUint32 i = 0u; i < numTopologies; ++i)
3525 {
3526 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[i]);
3527 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
3528 vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[i].size(), 1, 0, 0);
3529
3530 vertexBufferOffset += static_cast<VkDeviceSize>(pVertices[i].size() * sizeof(Vertex4RGBA));
3531 }
3532
3533 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
3534 {
3535 // The first draw was without color buffer and zero coverage. The depth buffer is expected to still have the clear value.
3536 vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
3537 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[1]);
3538 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
3539 // The depth test should pass as the first draw didn't touch the depth buffer.
3540 vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[0].size(), 1, 0, 0);
3541 }
3542 else if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3543 {
3544 // Copy each sample id to single sampled image
3545 for (deInt32 sampleId = 0; sampleId < (deInt32)m_perSampleImages.size(); ++sampleId)
3546 {
3547 vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
3548 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_copySamplePipelines[sampleId]);
3549 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_copySamplePipelineLayout, 0u, 1u, &m_copySampleDesciptorSet.get(), 0u, DE_NULL);
3550 vk.cmdPushConstants(*m_cmdBuffer, *m_copySamplePipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(deInt32), &sampleId);
3551 vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
3552 }
3553 }
3554
3555 endRenderPass(vk, *m_cmdBuffer);
3556
3557 endCommandBuffer(vk, *m_cmdBuffer);
3558 }
3559 }
3560
~MultisampleRenderer(void)3561 MultisampleRenderer::~MultisampleRenderer (void)
3562 {
3563 }
3564
render(void)3565 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::render (void)
3566 {
3567 const DeviceInterface& vk = m_context.getDeviceInterface();
3568 const VkDevice vkDevice = m_context.getDevice();
3569 const VkQueue queue = m_context.getUniversalQueue();
3570 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3571
3572 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
3573
3574 if (m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT)
3575 {
3576 return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>());
3577 }
3578 else
3579 {
3580 return de::MovePtr<tcu::TextureLevel>();
3581 }
3582 }
3583
getSingleSampledImage(deUint32 sampleId)3584 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::getSingleSampledImage (deUint32 sampleId)
3585 {
3586 return readColorAttachment(m_context.getDeviceInterface(), m_context.getDevice(), m_context.getUniversalQueue(), m_context.getUniversalQueueFamilyIndex(), m_context.getDefaultAllocator(), *m_perSampleImages[sampleId]->m_image, m_colorFormat, m_renderSize.cast<deUint32>());
3587 }
3588
3589 // Multisample tests with subpasses using no attachments.
3590 class VariableRateTestCase : public vkt::TestCase
3591 {
3592 public:
3593 using SampleCounts = std::vector<vk::VkSampleCountFlagBits>;
3594
3595 struct PushConstants
3596 {
3597 int width;
3598 int height;
3599 int samples;
3600 };
3601
3602 struct TestParams
3603 {
3604 bool nonEmptyFramebuffer; // Empty framebuffer or not.
3605 vk::VkSampleCountFlagBits fbCount; // If not empty, framebuffer sample count.
3606 bool unusedAttachment; // If not empty, create unused attachment or not.
3607 SampleCounts subpassCounts; // Counts for the different subpasses.
3608 };
3609
3610 static const deInt32 kWidth = 256u;
3611 static const deInt32 kHeight = 256u;
3612
3613 VariableRateTestCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params);
~VariableRateTestCase(void)3614 virtual ~VariableRateTestCase (void) {}
3615
3616 virtual void initPrograms (vk::SourceCollections& programCollection) const;
3617 virtual TestInstance* createInstance (Context& context) const;
3618 virtual void checkSupport (Context& context) const;
3619
3620 static constexpr vk::VkFormat kColorFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
3621
3622 private:
3623 TestParams m_params;
3624 };
3625
3626 class VariableRateTestInstance : public vkt::TestInstance
3627 {
3628 public:
3629 using TestParams = VariableRateTestCase::TestParams;
3630
3631 VariableRateTestInstance (Context& context, const TestParams& counts);
~VariableRateTestInstance(void)3632 virtual ~VariableRateTestInstance (void) {}
3633
3634 virtual tcu::TestStatus iterate (void);
3635
3636 private:
3637 TestParams m_params;
3638 };
3639
VariableRateTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams & params)3640 VariableRateTestCase::VariableRateTestCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
3641 : vkt::TestCase (testCtx, name, description)
3642 , m_params (params)
3643 {
3644 }
3645
initPrograms(vk::SourceCollections & programCollection) const3646 void VariableRateTestCase::initPrograms (vk::SourceCollections& programCollection) const
3647 {
3648 std::stringstream vertSrc;
3649
3650 vertSrc << "#version 450\n"
3651 << "\n"
3652 << "layout(location=0) in vec2 inPos;\n"
3653 << "\n"
3654 << "void main() {\n"
3655 << " gl_Position = vec4(inPos, 0.0, 1.0);\n"
3656 << "}\n"
3657 ;
3658
3659 std::stringstream fragSrc;
3660
3661 fragSrc << "#version 450\n"
3662 << "\n"
3663 << "layout(set=0, binding=0, std430) buffer OutBuffer {\n"
3664 << " int coverage[];\n"
3665 << "} out_buffer;\n"
3666 << "\n"
3667 << "layout(push_constant) uniform PushConstants {\n"
3668 << " int width;\n"
3669 << " int height;\n"
3670 << " int samples;\n"
3671 << "} push_constants;\n"
3672 << "\n"
3673 << "void main() {\n"
3674 << " ivec2 coord = ivec2(floor(gl_FragCoord.xy));\n"
3675 << " int pos = ((coord.y * push_constants.width) + coord.x) * push_constants.samples + int(gl_SampleID);\n"
3676 << " out_buffer.coverage[pos] = 1;\n"
3677 << "}\n"
3678 ;
3679
3680 programCollection.glslSources.add("vert") << glu::VertexSource(vertSrc.str());
3681 programCollection.glslSources.add("frag") << glu::FragmentSource(fragSrc.str());
3682 }
3683
createInstance(Context & context) const3684 TestInstance* VariableRateTestCase::createInstance (Context& context) const
3685 {
3686 return new VariableRateTestInstance(context, m_params);
3687 }
3688
checkSupport(Context & context) const3689 void VariableRateTestCase::checkSupport (Context& context) const
3690 {
3691 const auto& vki = context.getInstanceInterface();
3692 const auto physicalDevice = context.getPhysicalDevice();
3693
3694 // When using multiple subpasses, require variableMultisampleRate.
3695 if (m_params.subpassCounts.size() > 1)
3696 {
3697 if (!vk::getPhysicalDeviceFeatures(vki, physicalDevice).variableMultisampleRate)
3698 TCU_THROW(NotSupportedError, "Variable multisample rate not supported");
3699 }
3700
3701 // Check if sampleRateShading is supported.
3702 if(!vk::getPhysicalDeviceFeatures(vki, physicalDevice).sampleRateShading)
3703 TCU_THROW(NotSupportedError, "Sample rate shading is not supported");
3704
3705 // Make sure all subpass sample counts are supported.
3706 const auto properties = vk::getPhysicalDeviceProperties(vki, physicalDevice);
3707 const auto& supportedCounts = properties.limits.framebufferNoAttachmentsSampleCounts;
3708
3709 for (const auto count : m_params.subpassCounts)
3710 {
3711 if ((supportedCounts & count) == 0u)
3712 TCU_THROW(NotSupportedError, "Sample count combination not supported");
3713 }
3714
3715 if (m_params.nonEmptyFramebuffer)
3716 {
3717 // Check the framebuffer sample count is supported.
3718 const auto formatProperties = vk::getPhysicalDeviceImageFormatProperties(vki, physicalDevice, kColorFormat, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0u);
3719 if ((formatProperties.sampleCounts & m_params.fbCount) == 0u)
3720 TCU_THROW(NotSupportedError, "Sample count of " + de::toString(m_params.fbCount) + " not supported for color attachment");
3721 }
3722 }
3723
zeroOutAndFlush(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::BufferWithMemory & buffer,vk::VkDeviceSize size)3724 void zeroOutAndFlush(const vk::DeviceInterface& vkd, vk::VkDevice device, vk::BufferWithMemory& buffer, vk::VkDeviceSize size)
3725 {
3726 auto& alloc = buffer.getAllocation();
3727 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(size));
3728 vk::flushAlloc(vkd, device, alloc);
3729 }
3730
VariableRateTestInstance(Context & context,const TestParams & params)3731 VariableRateTestInstance::VariableRateTestInstance (Context& context, const TestParams& params)
3732 : vkt::TestInstance (context)
3733 , m_params (params)
3734 {
3735 }
3736
iterate(void)3737 tcu::TestStatus VariableRateTestInstance::iterate (void)
3738 {
3739 using PushConstants = VariableRateTestCase::PushConstants;
3740
3741 const auto& vkd = m_context.getDeviceInterface();
3742 const auto device = m_context.getDevice();
3743 auto& allocator = m_context.getDefaultAllocator();
3744 const auto& queue = m_context.getUniversalQueue();
3745 const auto queueIndex = m_context.getUniversalQueueFamilyIndex();
3746
3747 const vk::VkDeviceSize kWidth = static_cast<vk::VkDeviceSize>(VariableRateTestCase::kWidth);
3748 const vk::VkDeviceSize kHeight = static_cast<vk::VkDeviceSize>(VariableRateTestCase::kHeight);
3749 constexpr auto kColorFormat = VariableRateTestCase::kColorFormat;
3750
3751 const auto kWidth32 = static_cast<deUint32>(kWidth);
3752 const auto kHeight32 = static_cast<deUint32>(kHeight);
3753
3754 std::vector<std::unique_ptr<vk::BufferWithMemory>> referenceBuffers;
3755 std::vector<std::unique_ptr<vk::BufferWithMemory>> outputBuffers;
3756 std::vector<size_t> bufferNumElements;
3757 std::vector<vk::VkDeviceSize> bufferSizes;
3758
3759 // Create reference and output buffers.
3760 for (const auto count : m_params.subpassCounts)
3761 {
3762 bufferNumElements.push_back(static_cast<size_t>(kWidth * kHeight * count));
3763 bufferSizes.push_back(bufferNumElements.back() * sizeof(deInt32));
3764 const auto bufferCreateInfo = vk::makeBufferCreateInfo(bufferSizes.back(), vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3765
3766 referenceBuffers.emplace_back (new vk::BufferWithMemory{vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible});
3767 outputBuffers.emplace_back (new vk::BufferWithMemory{vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible});
3768 }
3769
3770 // Descriptor set layout.
3771 vk::DescriptorSetLayoutBuilder builder;
3772 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_FRAGMENT_BIT);
3773 const auto descriptorSetLayout = builder.build(vkd, device);
3774
3775 // Pipeline layout.
3776 const vk::VkPushConstantRange pushConstantRange =
3777 {
3778 vk::VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
3779 0u, // deUint32 offset;
3780 static_cast<deUint32>(sizeof(PushConstants)), // deUint32 size;
3781 };
3782
3783 const vk::VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
3784 {
3785 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
3786 nullptr, // const void* pNext;
3787 0u, // VkPipelineLayoutCreateFlags flags;
3788 1u, // deUint32 setLayoutCount;
3789 &descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
3790 1u, // deUint32 pushConstantRangeCount;
3791 &pushConstantRange, // const VkPushConstantRange* pPushConstantRanges;
3792 };
3793 const auto pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
3794
3795 // Subpass with no attachments.
3796 const vk::VkSubpassDescription emptySubpassDescription =
3797 {
3798 0u, // VkSubpassDescriptionFlags flags;
3799 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
3800 0u, // deUint32 inputAttachmentCount;
3801 nullptr, // const VkAttachmentReference* pInputAttachments;
3802 0u, // deUint32 colorAttachmentCount;
3803 nullptr, // const VkAttachmentReference* pColorAttachments;
3804 nullptr, // const VkAttachmentReference* pResolveAttachments;
3805 nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
3806 0u, // deUint32 preserveAttachmentCount;
3807 nullptr, // const deUint32* pPreserveAttachments;
3808 };
3809
3810 // Unused attachment reference.
3811 const vk::VkAttachmentReference unusedAttachmentReference =
3812 {
3813 VK_ATTACHMENT_UNUSED, // deUint32 attachment;
3814 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout;
3815 };
3816
3817 // Subpass with unused attachment.
3818 const vk::VkSubpassDescription unusedAttachmentSubpassDescription =
3819 {
3820 0u, // VkSubpassDescriptionFlags flags;
3821 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
3822 0u, // deUint32 inputAttachmentCount;
3823 nullptr, // const VkAttachmentReference* pInputAttachments;
3824 1u, // deUint32 colorAttachmentCount;
3825 &unusedAttachmentReference, // const VkAttachmentReference* pColorAttachments;
3826 nullptr, // const VkAttachmentReference* pResolveAttachments;
3827 nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
3828 0u, // deUint32 preserveAttachmentCount;
3829 nullptr, // const deUint32* pPreserveAttachments;
3830 };
3831
3832 // Renderpass with multiple subpasses.
3833 vk::VkRenderPassCreateInfo renderPassCreateInfo =
3834 {
3835 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
3836 nullptr, // const void* pNext;
3837 0u, // VkRenderPassCreateFlags flags;
3838 0u, // deUint32 attachmentCount;
3839 nullptr, // const VkAttachmentDescription* pAttachments;
3840 0u, // deUint32 subpassCount;
3841 nullptr, // const VkSubpassDescription* pSubpasses;
3842 0u, // deUint32 dependencyCount;
3843 nullptr, // const VkSubpassDependency* pDependencies;
3844 };
3845
3846 std::vector<vk::VkSubpassDescription> subpassesVector;
3847
3848 for (size_t i = 0; i < m_params.subpassCounts.size(); ++i)
3849 subpassesVector.push_back(emptySubpassDescription);
3850 renderPassCreateInfo.subpassCount = static_cast<deUint32>(subpassesVector.size());
3851 renderPassCreateInfo.pSubpasses = subpassesVector.data();
3852 const auto renderPassMultiplePasses = vk::createRenderPass(vkd, device, &renderPassCreateInfo);
3853
3854 // Render pass with single subpass.
3855 const vk::VkAttachmentDescription colorAttachmentDescription =
3856 {
3857 0u, // VkAttachmentDescriptionFlags flags;
3858 kColorFormat, // VkFormat format;
3859 m_params.fbCount, // VkSampleCountFlagBits samples;
3860 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
3861 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
3862 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
3863 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
3864 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3865 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
3866 };
3867
3868 if (m_params.nonEmptyFramebuffer)
3869 {
3870 renderPassCreateInfo.attachmentCount = 1u;
3871 renderPassCreateInfo.pAttachments = &colorAttachmentDescription;
3872 }
3873 renderPassCreateInfo.subpassCount = 1u;
3874 renderPassCreateInfo.pSubpasses = ((m_params.nonEmptyFramebuffer && m_params.unusedAttachment) ? &unusedAttachmentSubpassDescription : &emptySubpassDescription);
3875 const auto renderPassSingleSubpass = vk::createRenderPass(vkd, device, &renderPassCreateInfo);
3876
3877 // Framebuffers.
3878 vk::VkFramebufferCreateInfo framebufferCreateInfo =
3879 {
3880 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
3881 nullptr, // const void* pNext;
3882 0u, // VkFramebufferCreateFlags flags;
3883 DE_NULL, // VkRenderPass renderPass;
3884 0u, // deUint32 attachmentCount;
3885 nullptr, // const VkImageView* pAttachments;
3886 kWidth32, // deUint32 width;
3887 kHeight32, // deUint32 height;
3888 1u, // deUint32 layers;
3889 };
3890
3891 // Framebuffer for multiple-subpasses render pass.
3892 framebufferCreateInfo.renderPass = renderPassMultiplePasses.get();
3893 const auto framebufferMultiplePasses = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3894
3895 // Framebuffer for single-subpass render pass.
3896 std::unique_ptr<vk::ImageWithMemory> imagePtr;
3897 vk::Move<vk::VkImageView> imageView;
3898
3899 if (m_params.nonEmptyFramebuffer)
3900 {
3901 const vk::VkImageCreateInfo imageCreateInfo =
3902 {
3903 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3904 nullptr, // const void* pNext;
3905 0u, // VkImageCreateFlags flags;
3906 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType;
3907 kColorFormat, // VkFormat format;
3908 vk::makeExtent3D(kWidth32, kHeight32, 1u), // VkExtent3D extent;
3909 1u, // deUint32 mipLevels;
3910 1u, // deUint32 arrayLayers;
3911 m_params.fbCount, // VkSampleCountFlagBits samples;
3912 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
3913 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags usage;
3914 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3915 0u, // deUint32 queueFamilyIndexCount;
3916 nullptr, // const deUint32* pQueueFamilyIndices;
3917 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3918 };
3919 imagePtr.reset(new vk::ImageWithMemory{vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any});
3920
3921 const auto subresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
3922 imageView = vk::makeImageView(vkd, device, imagePtr->get(), vk::VK_IMAGE_VIEW_TYPE_2D, kColorFormat, subresourceRange);
3923
3924 framebufferCreateInfo.attachmentCount = 1u;
3925 framebufferCreateInfo.pAttachments = &imageView.get();
3926 }
3927 framebufferCreateInfo.renderPass = renderPassSingleSubpass.get();
3928 const auto framebufferSingleSubpass = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3929
3930 // Shader modules and stages.
3931 const auto vertModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
3932 const auto fragModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
3933
3934 std::vector<vk::VkPipelineShaderStageCreateInfo> shaderStages;
3935
3936 vk::VkPipelineShaderStageCreateInfo shaderStageCreateInfo =
3937 {
3938 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
3939 nullptr, // const void* pNext;
3940 0u, // VkPipelineShaderStageCreateFlags flags;
3941 vk::VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
3942 vertModule.get(), // VkShaderModule module;
3943 "main", // const char* pName;
3944 nullptr, // const VkSpecializationInfo* pSpecializationInfo;
3945 };
3946
3947 shaderStages.push_back(shaderStageCreateInfo);
3948 shaderStageCreateInfo.stage = vk::VK_SHADER_STAGE_FRAGMENT_BIT;
3949 shaderStageCreateInfo.module = fragModule.get();
3950 shaderStages.push_back(shaderStageCreateInfo);
3951
3952 // Vertices, input state and assembly.
3953 const std::vector<tcu::Vec2> vertices =
3954 {
3955 { -0.987f, -0.964f },
3956 { 0.982f, -0.977f },
3957 { 0.005f, 0.891f },
3958 };
3959
3960 const auto vertexBinding = vk::makeVertexInputBindingDescription(0u, static_cast<deUint32>(sizeof(decltype(vertices)::value_type)), vk::VK_VERTEX_INPUT_RATE_VERTEX);
3961 const auto vertexAttribute = vk::makeVertexInputAttributeDescription(0u, 0u, vk::VK_FORMAT_R32G32_SFLOAT, 0u);
3962
3963 const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
3964 {
3965 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
3966 nullptr, // const void* pNext;
3967 0u, // VkPipelineVertexInputStateCreateFlags flags;
3968 1u, // deUint32 vertexBindingDescriptionCount;
3969 &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
3970 1u, // deUint32 vertexAttributeDescriptionCount;
3971 &vertexAttribute, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
3972 };
3973
3974 const vk::VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo =
3975 {
3976 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
3977 nullptr, // const void* pNext;
3978 0u, // VkPipelineInputAssemblyStateCreateFlags flags;
3979 vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
3980 VK_FALSE, // VkBool32 primitiveRestartEnable;
3981 };
3982
3983 // Graphics pipelines to create output buffers.
3984 const auto viewport = vk::makeViewport(kWidth32, kHeight32);
3985 const auto scissor = vk::makeRect2D(kWidth32, kHeight32);
3986
3987 const vk::VkPipelineViewportStateCreateInfo viewportStateCreateInfo =
3988 {
3989 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
3990 nullptr, // const void* pNext;
3991 0u, // VkPipelineViewportStateCreateFlags flags;
3992 1u, // deUint32 viewportCount;
3993 &viewport, // const VkViewport* pViewports;
3994 1u, // deUint32 scissorCount;
3995 &scissor, // const VkRect2D* pScissors;
3996 };
3997
3998 const vk::VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
3999 {
4000 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
4001 nullptr, // const void* pNext;
4002 0u, // VkPipelineRasterizationStateCreateFlags flags;
4003 VK_FALSE, // VkBool32 depthClampEnable;
4004 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
4005 vk::VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
4006 vk::VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
4007 vk::VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
4008 VK_FALSE, // VkBool32 depthBiasEnable;
4009 0.0f, // float depthBiasConstantFactor;
4010 0.0f, // float depthBiasClamp;
4011 0.0f, // float depthBiasSlopeFactor;
4012 1.0f, // float lineWidth;
4013 };
4014
4015 vk::VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo =
4016 {
4017 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
4018 nullptr, // const void* pNext;
4019 0u, // VkPipelineMultisampleStateCreateFlags flags;
4020 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
4021 VK_FALSE, // VkBool32 sampleShadingEnable;
4022 0.0f, // float minSampleShading;
4023 nullptr, // const VkSampleMask* pSampleMask;
4024 VK_FALSE, // VkBool32 alphaToCoverageEnable;
4025 VK_FALSE, // VkBool32 alphaToOneEnable;
4026 };
4027
4028 std::vector<vk::Move<vk::VkPipeline>> outputPipelines;
4029
4030 for (const auto samples : m_params.subpassCounts)
4031 {
4032 multisampleStateCreateInfo.rasterizationSamples = samples;
4033
4034 const vk::VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo =
4035 {
4036 vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
4037 nullptr, // const void* pNext;
4038 0u, // VkPipelineCreateFlags flags;
4039 static_cast<deUint32>(shaderStages.size()), // deUint32 stageCount;
4040 shaderStages.data(), // const VkPipelineShaderStageCreateInfo* pStages;
4041 &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
4042 &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
4043 nullptr, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
4044 &viewportStateCreateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
4045 &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
4046 &multisampleStateCreateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
4047 nullptr, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
4048 nullptr, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
4049 nullptr, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
4050 pipelineLayout.get(), // VkPipelineLayout layout;
4051 renderPassSingleSubpass.get(), // VkRenderPass renderPass;
4052 0u, // deUint32 subpass;
4053 DE_NULL, // VkPipeline basePipelineHandle;
4054 0, // deInt32 basePipelineIndex;
4055 };
4056
4057 outputPipelines.push_back(vk::createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineCreateInfo));
4058 }
4059
4060 // Graphics pipelines with variable rate but using several subpasses.
4061 std::vector<vk::Move<vk::VkPipeline>> referencePipelines;
4062
4063 for (size_t i = 0; i < m_params.subpassCounts.size(); ++i)
4064 {
4065 multisampleStateCreateInfo.rasterizationSamples = m_params.subpassCounts[i];
4066
4067 const vk::VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo =
4068 {
4069 vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
4070 nullptr, // const void* pNext;
4071 0u, // VkPipelineCreateFlags flags;
4072 static_cast<deUint32>(shaderStages.size()), // deUint32 stageCount;
4073 shaderStages.data(), // const VkPipelineShaderStageCreateInfo* pStages;
4074 &vertexInputStateCreateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
4075 &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
4076 nullptr, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
4077 &viewportStateCreateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
4078 &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
4079 &multisampleStateCreateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
4080 nullptr, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
4081 nullptr, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
4082 nullptr, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
4083 pipelineLayout.get(), // VkPipelineLayout layout;
4084 renderPassMultiplePasses.get(), // VkRenderPass renderPass;
4085 static_cast<deUint32>(i), // deUint32 subpass;
4086 DE_NULL, // VkPipeline basePipelineHandle;
4087 0, // deInt32 basePipelineIndex;
4088 };
4089
4090 referencePipelines.push_back(vk::createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineCreateInfo));
4091 }
4092
4093 // Prepare vertex, reference and output buffers.
4094 const auto vertexBufferSize = vertices.size() * sizeof(decltype(vertices)::value_type);
4095 const auto vertexBufferCreateInfo = vk::makeBufferCreateInfo(static_cast<VkDeviceSize>(vertexBufferSize), vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
4096 vk::BufferWithMemory vertexBuffer {vkd, device, allocator, vertexBufferCreateInfo, MemoryRequirement::HostVisible};
4097 auto& vertexAlloc = vertexBuffer.getAllocation();
4098
4099 deMemcpy(vertexAlloc.getHostPtr(), vertices.data(), vertexBufferSize);
4100 vk::flushAlloc(vkd, device, vertexAlloc);
4101
4102 for (size_t i = 0; i < referenceBuffers.size(); ++i)
4103 {
4104 zeroOutAndFlush(vkd, device, *referenceBuffers[i], bufferSizes[i]);
4105 zeroOutAndFlush(vkd, device, *outputBuffers[i], bufferSizes[i]);
4106 }
4107
4108 // Prepare descriptor sets.
4109 const deUint32 totalSets = static_cast<deUint32>(referenceBuffers.size() * 2u);
4110 vk::DescriptorPoolBuilder poolBuilder;
4111 poolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, static_cast<deUint32>(referenceBuffers.size() * 2u));
4112 const auto descriptorPool = poolBuilder.build(vkd, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, totalSets);
4113
4114 std::vector<vk::Move<vk::VkDescriptorSet>> referenceSets (referenceBuffers.size());
4115 std::vector<vk::Move<vk::VkDescriptorSet>> outputSets (outputBuffers.size());
4116
4117 for (auto& set : referenceSets)
4118 set = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
4119 for (auto& set : outputSets)
4120 set = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
4121
4122 vk::DescriptorSetUpdateBuilder updateBuilder;
4123
4124 for (size_t i = 0; i < referenceSets.size(); ++i)
4125 {
4126 const auto descriptorBufferInfo = vk::makeDescriptorBufferInfo(referenceBuffers[i]->get(), 0u, bufferSizes[i]);
4127 updateBuilder.writeSingle(referenceSets[i].get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo);
4128 }
4129 for (size_t i = 0; i < outputSets.size(); ++i)
4130 {
4131 const auto descriptorBufferInfo = vk::makeDescriptorBufferInfo(outputBuffers[i]->get(), 0u, bufferSizes[i]);
4132 updateBuilder.writeSingle(outputSets[i].get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo);
4133 }
4134
4135 updateBuilder.update(vkd, device);
4136
4137 // Prepare command pool.
4138 const auto cmdPool = vk::makeCommandPool(vkd, device, queueIndex);
4139 const auto cmdBufferPtr = vk::allocateCommandBuffer(vkd , device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4140 const auto cmdBuffer = cmdBufferPtr.get();
4141
4142 vk::VkBufferMemoryBarrier storageBufferDevToHostBarrier =
4143 {
4144 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
4145 nullptr, // const void* pNext;
4146 vk::VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4147 vk::VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
4148 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4149 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4150 DE_NULL, // VkBuffer buffer;
4151 0u, // VkDeviceSize offset;
4152 VK_WHOLE_SIZE, // VkDeviceSize size;
4153 };
4154
4155 // Record command buffer.
4156 const vk::VkDeviceSize vertexBufferOffset = 0u;
4157 const auto renderArea = vk::makeRect2D(kWidth32, kHeight32);
4158 PushConstants pushConstants = { static_cast<int>(kWidth), static_cast<int>(kHeight), 0 };
4159
4160 vk::beginCommandBuffer(vkd, cmdBuffer);
4161
4162 // Render output buffers.
4163 vk::beginRenderPass(vkd, cmdBuffer, renderPassSingleSubpass.get(), framebufferSingleSubpass.get(), renderArea);
4164 for (size_t i = 0; i < outputBuffers.size(); ++i)
4165 {
4166 vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, outputPipelines[i].get());
4167 vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &outputSets[i].get(), 0u, nullptr);
4168 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
4169 pushConstants.samples = static_cast<int>(m_params.subpassCounts[i]);
4170 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pushConstantRange.stageFlags, pushConstantRange.offset, pushConstantRange.size, &pushConstants);
4171 vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(vertices.size()), 1u, 0u, 0u);
4172 }
4173 vk::endRenderPass(vkd, cmdBuffer);
4174 for (size_t i = 0; i < outputBuffers.size(); ++i)
4175 {
4176 storageBufferDevToHostBarrier.buffer = outputBuffers[i]->get();
4177 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &storageBufferDevToHostBarrier, 0u, nullptr);
4178 }
4179
4180 // Render reference buffers.
4181 vk::beginRenderPass(vkd, cmdBuffer, renderPassMultiplePasses.get(), framebufferMultiplePasses.get(), renderArea);
4182 for (size_t i = 0; i < referenceBuffers.size(); ++i)
4183 {
4184 if (i > 0)
4185 vkd.cmdNextSubpass(cmdBuffer, vk::VK_SUBPASS_CONTENTS_INLINE);
4186 vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, referencePipelines[i].get());
4187 vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &referenceSets[i].get(), 0u, nullptr);
4188 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
4189 pushConstants.samples = static_cast<int>(m_params.subpassCounts[i]);
4190 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pushConstantRange.stageFlags, pushConstantRange.offset, pushConstantRange.size, &pushConstants);
4191 vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(vertices.size()), 1u, 0u, 0u);
4192 }
4193 vk::endRenderPass(vkd, cmdBuffer);
4194 for (size_t i = 0; i < referenceBuffers.size(); ++i)
4195 {
4196 storageBufferDevToHostBarrier.buffer = referenceBuffers[i]->get();
4197 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &storageBufferDevToHostBarrier, 0u, nullptr);
4198 }
4199
4200 vk::endCommandBuffer(vkd, cmdBuffer);
4201
4202 // Run all pipelines.
4203 vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
4204
4205 // Invalidate reference allocs.
4206 #undef LOG_BUFFER_CONTENTS
4207 #ifdef LOG_BUFFER_CONTENTS
4208 auto& log = m_context.getTestContext().getLog();
4209 #endif
4210 for (size_t i = 0; i < referenceBuffers.size(); ++i)
4211 {
4212 auto& buffer = referenceBuffers[i];
4213 auto& alloc = buffer->getAllocation();
4214 vk::invalidateAlloc(vkd, device, alloc);
4215
4216 #ifdef LOG_BUFFER_CONTENTS
4217 std::vector<deInt32> bufferValues(bufferNumElements[i]);
4218 deMemcpy(bufferValues.data(), alloc.getHostPtr(), bufferSizes[i]);
4219
4220 std::ostringstream msg;
4221 for (const auto value : bufferValues)
4222 msg << " " << value;
4223 log << tcu::TestLog::Message << "Reference buffer values with " << m_params[i] << " samples:" << msg.str() << tcu::TestLog::EndMessage;
4224 #endif
4225 }
4226
4227 for (size_t i = 0; i < outputBuffers.size(); ++i)
4228 {
4229 auto& buffer = outputBuffers[i];
4230 auto& alloc = buffer->getAllocation();
4231 vk::invalidateAlloc(vkd, device, alloc);
4232
4233 #ifdef LOG_BUFFER_CONTENTS
4234 std::vector<deInt32> bufferValues(bufferNumElements[i]);
4235 deMemcpy(bufferValues.data(), alloc.getHostPtr(), bufferSizes[i]);
4236
4237 std::ostringstream msg;
4238 for (const auto value : bufferValues)
4239 msg << " " << value;
4240 log << tcu::TestLog::Message << "Output buffer values with " << m_params[i] << " samples:" << msg.str() << tcu::TestLog::EndMessage;
4241 #endif
4242
4243 if (deMemCmp(alloc.getHostPtr(), referenceBuffers[i]->getAllocation().getHostPtr(), static_cast<size_t>(bufferSizes[i])) != 0)
4244 return tcu::TestStatus::fail("Buffer mismatch in output buffer " + de::toString(i));
4245 }
4246
4247 return tcu::TestStatus::pass("Pass");
4248 }
4249
4250 using ElementsVector = std::vector<vk::VkSampleCountFlagBits>;
4251 using CombinationVector = std::vector<ElementsVector>;
4252
combinationsRecursive(const ElementsVector & elements,size_t requestedSize,CombinationVector & solutions,ElementsVector & partial)4253 void combinationsRecursive(const ElementsVector& elements, size_t requestedSize, CombinationVector& solutions, ElementsVector& partial)
4254 {
4255 if (partial.size() == requestedSize)
4256 solutions.push_back(partial);
4257 else
4258 {
4259 for (const auto& elem : elements)
4260 {
4261 partial.push_back(elem);
4262 combinationsRecursive(elements, requestedSize, solutions, partial);
4263 partial.pop_back();
4264 }
4265 }
4266 }
4267
combinations(const ElementsVector & elements,size_t requestedSize)4268 CombinationVector combinations(const ElementsVector& elements, size_t requestedSize)
4269 {
4270 CombinationVector solutions;
4271 ElementsVector partial;
4272
4273 combinationsRecursive(elements, requestedSize, solutions, partial);
4274 return solutions;
4275 }
4276
4277 } // anonymous
4278
createMultisampleTests(tcu::TestContext & testCtx)4279 tcu::TestCaseGroup* createMultisampleTests (tcu::TestContext& testCtx)
4280 {
4281 const VkSampleCountFlagBits samples[] =
4282 {
4283 VK_SAMPLE_COUNT_2_BIT,
4284 VK_SAMPLE_COUNT_4_BIT,
4285 VK_SAMPLE_COUNT_8_BIT,
4286 VK_SAMPLE_COUNT_16_BIT,
4287 VK_SAMPLE_COUNT_32_BIT,
4288 VK_SAMPLE_COUNT_64_BIT
4289 };
4290
4291 de::MovePtr<tcu::TestCaseGroup> multisampleTests (new tcu::TestCaseGroup(testCtx, "multisample", ""));
4292
4293 // Rasterization samples tests
4294 {
4295 de::MovePtr<tcu::TestCaseGroup> rasterizationSamplesTests(new tcu::TestCaseGroup(testCtx, "raster_samples", ""));
4296
4297 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4298 {
4299 std::ostringstream caseName;
4300 caseName << "samples_" << samples[samplesNdx];
4301
4302 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4303
4304 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4305 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4306 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4307 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));
4308
4309 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_DEPTH_BIT));
4310 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_STENCIL_BIT));
4311 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT));
4312
4313 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4314 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4315 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4316 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));
4317
4318 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_DEPTH_BIT));
4319 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_STENCIL_BIT));
4320 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT));
4321
4322 rasterizationSamplesTests->addChild(samplesTests.release());
4323 }
4324
4325 multisampleTests->addChild(rasterizationSamplesTests.release());
4326 }
4327
4328 // Raster samples consistency check
4329 {
4330 de::MovePtr<tcu::TestCaseGroup> rasterSamplesConsistencyTests (new tcu::TestCaseGroup(testCtx, "raster_samples_consistency", ""));
4331 MultisampleTestParams paramsRegular = {GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR};
4332 MultisampleTestParams paramsSparse = {GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE};
4333
4334 addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
4335 "unique_colors_check",
4336 "",
4337 initMultisamplePrograms,
4338 testRasterSamplesConsistency,
4339 paramsRegular);
4340
4341 addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
4342 "unique_colors_check_sparse",
4343 "",
4344 initMultisamplePrograms,
4345 testRasterSamplesConsistency,
4346 paramsSparse);
4347
4348 multisampleTests->addChild(rasterSamplesConsistencyTests.release());
4349 }
4350
4351 // minSampleShading tests
4352 {
4353 struct TestConfig
4354 {
4355 const char* name;
4356 float minSampleShading;
4357 };
4358
4359 const TestConfig testConfigs[] =
4360 {
4361 { "min_0_0", 0.0f },
4362 { "min_0_25", 0.25f },
4363 { "min_0_5", 0.5f },
4364 { "min_0_75", 0.75f },
4365 { "min_1_0", 1.0f }
4366 };
4367
4368 {
4369 de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading", ""));
4370
4371 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
4372 {
4373 const TestConfig& testConfig = testConfigs[configNdx];
4374 de::MovePtr<tcu::TestCaseGroup> minShadingValueTests (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
4375
4376 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4377 {
4378 std::ostringstream caseName;
4379 caseName << "samples_" << samples[samplesNdx];
4380
4381 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4382
4383 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4384 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4385 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_1px", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4386 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));
4387
4388 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle_sparse", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4389 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line_sparse", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4390 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_1px_sparse", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4391 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_sparse", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));
4392
4393 minShadingValueTests->addChild(samplesTests.release());
4394 }
4395
4396 minSampleShadingTests->addChild(minShadingValueTests.release());
4397 }
4398
4399 multisampleTests->addChild(minSampleShadingTests.release());
4400 }
4401
4402 {
4403 de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading_enabled", ""));
4404
4405 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
4406 {
4407 const TestConfig& testConfig = testConfigs[configNdx];
4408 de::MovePtr<tcu::TestCaseGroup> minShadingValueTests (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
4409
4410 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4411 {
4412 std::ostringstream caseName;
4413 caseName << "samples_" << samples[samplesNdx];
4414
4415 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4416
4417 samplesTests->addChild(new MinSampleShadingTest(testCtx, "quad", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_QUAD, 1.0f, IMAGE_BACKING_MODE_REGULAR, true));
4418
4419 minShadingValueTests->addChild(samplesTests.release());
4420 }
4421
4422 minSampleShadingTests->addChild(minShadingValueTests.release());
4423 }
4424
4425 multisampleTests->addChild(minSampleShadingTests.release());
4426 }
4427
4428 {
4429 de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading_disabled", ""));
4430
4431 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
4432 {
4433 const TestConfig& testConfig = testConfigs[configNdx];
4434 de::MovePtr<tcu::TestCaseGroup> minShadingValueTests (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
4435
4436 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4437 {
4438 std::ostringstream caseName;
4439 caseName << "samples_" << samples[samplesNdx];
4440
4441 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4442
4443 samplesTests->addChild(new MinSampleShadingTest(testCtx, "quad", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_QUAD, 1.0f, IMAGE_BACKING_MODE_REGULAR, false));
4444
4445 minShadingValueTests->addChild(samplesTests.release());
4446 }
4447
4448 minSampleShadingTests->addChild(minShadingValueTests.release());
4449 }
4450
4451 multisampleTests->addChild(minSampleShadingTests.release());
4452 }
4453 }
4454
4455 // SampleMask tests
4456 {
4457 struct TestConfig
4458 {
4459 const char* name;
4460 const char* description;
4461 VkSampleMask sampleMask;
4462 };
4463
4464 const TestConfig testConfigs[] =
4465 {
4466 { "mask_all_on", "All mask bits are off", 0x0 },
4467 { "mask_all_off", "All mask bits are on", 0xFFFFFFFF },
4468 { "mask_one", "All mask elements are 0x1", 0x1},
4469 { "mask_random", "All mask elements are 0xAAAAAAAA", 0xAAAAAAAA },
4470 };
4471
4472 de::MovePtr<tcu::TestCaseGroup> sampleMaskTests(new tcu::TestCaseGroup(testCtx, "sample_mask", ""));
4473
4474 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
4475 {
4476 const TestConfig& testConfig = testConfigs[configNdx];
4477 de::MovePtr<tcu::TestCaseGroup> sampleMaskValueTests (new tcu::TestCaseGroup(testCtx, testConfig.name, testConfig.description));
4478
4479 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4480 {
4481 std::ostringstream caseName;
4482 caseName << "samples_" << samples[samplesNdx];
4483
4484 const deUint32 sampleMaskCount = samples[samplesNdx] / 32;
4485 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4486
4487 std::vector<VkSampleMask> mask;
4488 for (deUint32 maskNdx = 0; maskNdx < sampleMaskCount; maskNdx++)
4489 mask.push_back(testConfig.sampleMask);
4490
4491 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4492 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4493 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR));
4494 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR));
4495
4496 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4497 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4498 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE));
4499 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_sparse", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE));
4500
4501 sampleMaskValueTests->addChild(samplesTests.release());
4502 }
4503
4504 sampleMaskTests->addChild(sampleMaskValueTests.release());
4505 }
4506
4507 multisampleTests->addChild(sampleMaskTests.release());
4508
4509 }
4510
4511 // AlphaToOne tests
4512 {
4513 de::MovePtr<tcu::TestCaseGroup> alphaToOneTests(new tcu::TestCaseGroup(testCtx, "alpha_to_one", ""));
4514
4515 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4516 {
4517 std::ostringstream caseName;
4518 caseName << "samples_" << samples[samplesNdx];
4519
4520 alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx], IMAGE_BACKING_MODE_REGULAR));
4521
4522 caseName << "_sparse";
4523 alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx], IMAGE_BACKING_MODE_SPARSE));
4524 }
4525
4526 multisampleTests->addChild(alphaToOneTests.release());
4527 }
4528
4529 // AlphaToCoverageEnable tests
4530 {
4531 de::MovePtr<tcu::TestCaseGroup> alphaToCoverageTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage", ""));
4532
4533 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4534 {
4535 std::ostringstream caseName;
4536 caseName << "samples_" << samples[samplesNdx];
4537
4538 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4539
4540 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4541 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_REGULAR));
4542 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4543
4544 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4545 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_SPARSE));
4546 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4547
4548 alphaToCoverageTests->addChild(samplesTests.release());
4549 }
4550 multisampleTests->addChild(alphaToCoverageTests.release());
4551 }
4552
4553 // AlphaToCoverageEnable without color buffer tests
4554 {
4555 de::MovePtr<tcu::TestCaseGroup> alphaToCoverageNoColorAttachmentTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage_no_color_attachment", ""));
4556
4557 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4558 {
4559 std::ostringstream caseName;
4560 caseName << "samples_" << samples[samplesNdx];
4561
4562 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4563
4564 samplesTests->addChild(new AlphaToCoverageNoColorAttachmentTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4565 samplesTests->addChild(new AlphaToCoverageNoColorAttachmentTest(testCtx, "alpha_opaque_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4566
4567 alphaToCoverageNoColorAttachmentTests->addChild(samplesTests.release());
4568 }
4569 multisampleTests->addChild(alphaToCoverageNoColorAttachmentTests.release());
4570 }
4571
4572 // AlphaToCoverageEnable with unused color attachment:
4573 // Set color output at location 0 as unused, but use the alpha write to control coverage for rendering to color buffer at location 1.
4574 {
4575 de::MovePtr<tcu::TestCaseGroup> alphaToCoverageColorUnusedAttachmentTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage_unused_attachment", ""));
4576
4577 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
4578 {
4579 std::ostringstream caseName;
4580 caseName << "samples_" << samples[samplesNdx];
4581
4582 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
4583
4584 samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4585 samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_opaque_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4586 samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_invisible", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR));
4587 samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_invisible_sparse", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE));
4588
4589 alphaToCoverageColorUnusedAttachmentTests->addChild(samplesTests.release());
4590 }
4591 multisampleTests->addChild(alphaToCoverageColorUnusedAttachmentTests.release());
4592 }
4593
4594 // Sampling from a multisampled image texture (texelFetch)
4595 {
4596 multisampleTests->addChild(createMultisampleSampledImageTests(testCtx));
4597 }
4598
4599 // Load/store on a multisampled rendered image (different kinds of access: color attachment write, storage image, etc.)
4600 {
4601 multisampleTests->addChild(createMultisampleStorageImageTests(testCtx));
4602 }
4603
4604 // Sampling from a multisampled image texture (texelFetch), checking supersample positions
4605 {
4606 multisampleTests->addChild(createMultisampleStandardSamplePositionTests(testCtx));
4607 }
4608
4609 // VK_EXT_sample_locations
4610 {
4611 multisampleTests->addChild(createMultisampleSampleLocationsExtTests(testCtx));
4612 }
4613
4614 // VK_AMD_mixed_attachment samples and VK_AMD_shader_fragment_mask
4615 {
4616 multisampleTests->addChild(createMultisampleMixedAttachmentSamplesTests(testCtx));
4617 multisampleTests->addChild(createMultisampleShaderFragmentMaskTests(testCtx));
4618 }
4619
4620 // Sample mask with and without vk_ext_post_depth_coverage
4621 {
4622 const vk::VkSampleCountFlagBits standardSamplesSet[] =
4623 {
4624 vk::VK_SAMPLE_COUNT_2_BIT,
4625 vk::VK_SAMPLE_COUNT_4_BIT,
4626 vk::VK_SAMPLE_COUNT_8_BIT,
4627 vk::VK_SAMPLE_COUNT_16_BIT
4628 };
4629
4630 de::MovePtr<tcu::TestCaseGroup> sampleMaskWithDepthTestGroup(new tcu::TestCaseGroup(testCtx, "sample_mask_with_depth_test", ""));
4631
4632 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(standardSamplesSet); ++ndx)
4633 {
4634 std::ostringstream caseName;
4635 caseName << "samples_" << standardSamplesSet[ndx];
4636
4637 sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), "", standardSamplesSet[ndx]));
4638
4639 caseName << "_post_depth_coverage";
4640 sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), "", standardSamplesSet[ndx], true));
4641
4642 }
4643 multisampleTests->addChild(sampleMaskWithDepthTestGroup.release());
4644 }
4645
4646 {
4647 static const std::vector<vk::VkSampleCountFlagBits> kSampleCounts =
4648 {
4649 vk::VK_SAMPLE_COUNT_1_BIT,
4650 vk::VK_SAMPLE_COUNT_2_BIT,
4651 vk::VK_SAMPLE_COUNT_4_BIT,
4652 vk::VK_SAMPLE_COUNT_8_BIT,
4653 vk::VK_SAMPLE_COUNT_16_BIT,
4654 vk::VK_SAMPLE_COUNT_32_BIT,
4655 vk::VK_SAMPLE_COUNT_64_BIT,
4656 };
4657
4658 static const std::array<bool, 2> unusedAttachmentFlag = {{ false, true }};
4659
4660 {
4661 de::MovePtr<tcu::TestCaseGroup> variableRateGroup(new tcu::TestCaseGroup(testCtx, "variable_rate", "Tests for multisample variable rate in subpasses"));
4662
4663 // 2 and 3 subpasses should be good enough.
4664 static const std::vector<size_t> combinationSizes = { 2, 3 };
4665
4666 // Basic cases.
4667 for (const auto size : combinationSizes)
4668 {
4669 const auto combs = combinations(kSampleCounts, size);
4670 for (const auto& comb : combs)
4671 {
4672 // Check sample counts actually vary between some of the subpasses.
4673 std::set<vk::VkSampleCountFlagBits> uniqueVals(begin(comb), end(comb));
4674 if (uniqueVals.size() < 2)
4675 continue;
4676
4677 std::ostringstream name;
4678 std::ostringstream desc;
4679
4680 bool first = true;
4681 for (const auto& count : comb)
4682 {
4683 name << (first ? "" : "_") << count;
4684 desc << (first ? "Subpasses with counts " : ", ") << count;
4685 first = false;
4686 }
4687
4688 const VariableRateTestCase::TestParams params =
4689 {
4690 false, // bool nonEmptyFramebuffer;
4691 vk::VK_SAMPLE_COUNT_1_BIT, // vk::VkSampleCountFlagBits fbCount;
4692 false, // bool unusedAttachment;
4693 comb, // SampleCounts subpassCounts;
4694 };
4695 variableRateGroup->addChild(new VariableRateTestCase(testCtx, name.str(), desc.str(), params));
4696 }
4697 }
4698
4699 // Cases with non-empty framebuffers: only 2 subpasses to avoid a large number of combinations.
4700 {
4701 // Use one more sample count for the framebuffer attachment. It will be taken from the last item.
4702 auto combs = combinations(kSampleCounts, 2 + 1);
4703 for (auto& comb : combs)
4704 {
4705 // Framebuffer sample count.
4706 const auto fbCount = comb.back();
4707 comb.pop_back();
4708
4709 // Check sample counts actually vary between some of the subpasses.
4710 std::set<vk::VkSampleCountFlagBits> uniqueVals(begin(comb), end(comb));
4711 if (uniqueVals.size() < 2)
4712 continue;
4713
4714 for (const auto flag : unusedAttachmentFlag)
4715 {
4716 std::ostringstream name;
4717 std::ostringstream desc;
4718
4719 desc << "Framebuffer with sample count " << fbCount << " and subpasses with counts ";
4720
4721 bool first = true;
4722 for (const auto& count : comb)
4723 {
4724 name << (first ? "" : "_") << count;
4725 desc << (first ? "" : ", ") << count;
4726 first = false;
4727 }
4728
4729 name << "_fb_" << fbCount;
4730
4731 if (flag)
4732 {
4733 name << "_unused";
4734 desc << " and unused attachments";
4735 }
4736
4737 const VariableRateTestCase::TestParams params =
4738 {
4739 true, // bool nonEmptyFramebuffer;
4740 fbCount, // vk::VkSampleCountFlagBits fbCount;
4741 flag, // bool unusedAttachment;
4742 comb, // SampleCounts subpassCounts;
4743 };
4744 variableRateGroup->addChild(new VariableRateTestCase(testCtx, name.str(), desc.str(), params));
4745 }
4746 }
4747 }
4748
4749 multisampleTests->addChild(variableRateGroup.release());
4750 }
4751
4752 {
4753 de::MovePtr<tcu::TestCaseGroup> mixedCountGroup(new tcu::TestCaseGroup(testCtx, "mixed_count", "Tests for mixed sample count in empty subpass and framebuffer"));
4754
4755 const auto combs = combinations(kSampleCounts, 2);
4756 for (const auto& comb : combs)
4757 {
4758 // Check different sample count.
4759 DE_ASSERT(comb.size() == 2u);
4760 const auto& fbCount = comb[0];
4761 const auto& emptyCount = comb[1];
4762
4763 if (fbCount == emptyCount)
4764 continue;
4765
4766 const std::string fbCountStr = de::toString(fbCount);
4767 const std::string emptyCountStr = de::toString(emptyCount);
4768
4769 for (const auto flag : unusedAttachmentFlag)
4770 {
4771 const std::string nameSuffix = (flag ? "unused" : "");
4772 const std::string descSuffix = (flag ? "one unused attachment reference" : "no attachment references");
4773 const std::string name = fbCountStr + "_" + emptyCountStr + (nameSuffix.empty() ? "" : "_") + nameSuffix;
4774 const std::string desc = "Framebuffer with " + fbCountStr + " samples, subpass with " + emptyCountStr + " samples and " + descSuffix;
4775
4776 const VariableRateTestCase::TestParams params =
4777 {
4778 true, // bool nonEmptyFramebuffer;
4779 fbCount, // vk::VkSampleCountFlagBits fbCount;
4780 flag, // bool unusedAttachment;
4781 VariableRateTestCase::SampleCounts(1u, emptyCount), // SampleCounts subpassCounts;
4782 };
4783 mixedCountGroup->addChild(new VariableRateTestCase(testCtx, name, desc, params));
4784 }
4785 }
4786
4787 multisampleTests->addChild(mixedCountGroup.release());
4788 }
4789 }
4790
4791 return multisampleTests.release();
4792 }
4793
4794 } // pipeline
4795 } // vkt
4796