1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2017 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Tests for render passses with multisample attachments
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktRenderPassMultisampleTests.hpp"
25
26 #include "vktTestCaseUtil.hpp"
27 #include "vktTestGroupUtil.hpp"
28
29 #include "vkDefs.hpp"
30 #include "vkDeviceUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vkPlatform.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkRef.hpp"
37 #include "vkRefUtil.hpp"
38 #include "vkTypeUtil.hpp"
39
40 #include "tcuFloat.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuFormatUtil.hpp"
43 #include "tcuMaybe.hpp"
44 #include "tcuResultCollector.hpp"
45 #include "tcuTestLog.hpp"
46 #include "tcuTextureUtil.hpp"
47 #include "tcuVectorUtil.hpp"
48
49 #include "deUniquePtr.hpp"
50 #include "deSharedPtr.hpp"
51
52 using namespace vk;
53
54 using tcu::BVec4;
55 using tcu::IVec2;
56 using tcu::IVec4;
57 using tcu::UVec2;
58 using tcu::UVec4;
59 using tcu::Vec2;
60 using tcu::Vec4;
61
62 using tcu::Maybe;
63 using tcu::just;
64 using tcu::nothing;
65
66 using tcu::ConstPixelBufferAccess;
67 using tcu::PixelBufferAccess;
68
69 using tcu::TestLog;
70
71 using std::pair;
72 using std::string;
73 using std::vector;
74
75 typedef de::SharedPtr<vk::Unique<VkImage> > VkImageSp;
76 typedef de::SharedPtr<vk::Unique<VkImageView> > VkImageViewSp;
77 typedef de::SharedPtr<vk::Unique<VkBuffer> > VkBufferSp;
78 typedef de::SharedPtr<vk::Unique<VkPipeline> > VkPipelineSp;
79
80 namespace vkt
81 {
82 namespace
83 {
84 enum
85 {
86 MAX_COLOR_ATTACHMENT_COUNT = 4u
87 };
88
89 template<typename T>
safeSharedPtr(T * ptr)90 de::SharedPtr<T> safeSharedPtr (T* ptr)
91 {
92 try
93 {
94 return de::SharedPtr<T>(ptr);
95 }
96 catch (...)
97 {
98 delete ptr;
99 throw;
100 }
101 }
102
getImageAspectFlags(VkFormat vkFormat)103 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
104 {
105 const tcu::TextureFormat format (mapVkFormat(vkFormat));
106 const bool hasDepth (tcu::hasDepthComponent(format.order));
107 const bool hasStencil (tcu::hasStencilComponent(format.order));
108
109 if (hasDepth || hasStencil)
110 {
111 return (hasDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : (VkImageAspectFlagBits)0u)
112 | (hasStencil ? VK_IMAGE_ASPECT_STENCIL_BIT : (VkImageAspectFlagBits)0u);
113 }
114 else
115 return VK_IMAGE_ASPECT_COLOR_BIT;
116 }
117
bindBufferMemory(const DeviceInterface & vk,VkDevice device,VkBuffer buffer,VkDeviceMemory mem,VkDeviceSize memOffset)118 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
119 {
120 VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
121 }
122
bindImageMemory(const DeviceInterface & vk,VkDevice device,VkImage image,VkDeviceMemory mem,VkDeviceSize memOffset)123 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
124 {
125 VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
126 }
127
createBufferMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkBuffer buffer)128 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface& vk,
129 VkDevice device,
130 Allocator& allocator,
131 VkBuffer buffer)
132 {
133 de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
134 bindBufferMemory(vk, device, buffer, allocation->getMemory(), allocation->getOffset());
135 return allocation;
136 }
137
createImageMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkImage image)138 de::MovePtr<Allocation> createImageMemory (const DeviceInterface& vk,
139 VkDevice device,
140 Allocator& allocator,
141 VkImage image)
142 {
143 de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), MemoryRequirement::Any));
144 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
145 return allocation;
146 }
147
createImage(const DeviceInterface & vk,VkDevice device,VkImageCreateFlags flags,VkImageType imageType,VkFormat format,VkExtent3D extent,deUint32 mipLevels,deUint32 arrayLayers,VkSampleCountFlagBits samples,VkImageTiling tiling,VkImageUsageFlags usage,VkSharingMode sharingMode,deUint32 queueFamilyCount,const deUint32 * pQueueFamilyIndices,VkImageLayout initialLayout)148 Move<VkImage> createImage (const DeviceInterface& vk,
149 VkDevice device,
150 VkImageCreateFlags flags,
151 VkImageType imageType,
152 VkFormat format,
153 VkExtent3D extent,
154 deUint32 mipLevels,
155 deUint32 arrayLayers,
156 VkSampleCountFlagBits samples,
157 VkImageTiling tiling,
158 VkImageUsageFlags usage,
159 VkSharingMode sharingMode,
160 deUint32 queueFamilyCount,
161 const deUint32* pQueueFamilyIndices,
162 VkImageLayout initialLayout)
163 {
164 const VkImageCreateInfo pCreateInfo =
165 {
166 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
167 DE_NULL,
168 flags,
169 imageType,
170 format,
171 extent,
172 mipLevels,
173 arrayLayers,
174 samples,
175 tiling,
176 usage,
177 sharingMode,
178 queueFamilyCount,
179 pQueueFamilyIndices,
180 initialLayout
181 };
182 return createImage(vk, device, &pCreateInfo);
183 }
184
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags flags,VkImage image,VkImageViewType viewType,VkFormat format,VkComponentMapping components,VkImageSubresourceRange subresourceRange)185 Move<VkImageView> createImageView (const DeviceInterface& vk,
186 VkDevice device,
187 VkImageViewCreateFlags flags,
188 VkImage image,
189 VkImageViewType viewType,
190 VkFormat format,
191 VkComponentMapping components,
192 VkImageSubresourceRange subresourceRange)
193 {
194 const VkImageViewCreateInfo pCreateInfo =
195 {
196 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
197 DE_NULL,
198 flags,
199 image,
200 viewType,
201 format,
202 components,
203 subresourceRange,
204 };
205 return createImageView(vk, device, &pCreateInfo);
206 }
207
createImage(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const DeviceInterface & vkd,VkDevice device,VkFormat vkFormat,VkSampleCountFlagBits sampleCountBit,VkImageUsageFlags usage,deUint32 width,deUint32 height)208 Move<VkImage> createImage (const InstanceInterface& vki,
209 VkPhysicalDevice physicalDevice,
210 const DeviceInterface& vkd,
211 VkDevice device,
212 VkFormat vkFormat,
213 VkSampleCountFlagBits sampleCountBit,
214 VkImageUsageFlags usage,
215 deUint32 width,
216 deUint32 height)
217 {
218 try
219 {
220 const tcu::TextureFormat format (mapVkFormat(vkFormat));
221 const VkImageType imageType (VK_IMAGE_TYPE_2D);
222 const VkImageTiling imageTiling (VK_IMAGE_TILING_OPTIMAL);
223 const VkFormatProperties formatProperties (getPhysicalDeviceFormatProperties(vki, physicalDevice, vkFormat));
224 const VkImageFormatProperties imageFormatProperties (getPhysicalDeviceImageFormatProperties(vki, physicalDevice, vkFormat, imageType, imageTiling, usage, 0u));
225 const VkExtent3D imageExtent =
226 {
227 width,
228 height,
229 1u
230 };
231
232 if ((tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
233 && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)
234 TCU_THROW(NotSupportedError, "Format can't be used as depth stencil attachment");
235
236 if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
237 && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
238 TCU_THROW(NotSupportedError, "Format can't be used as color attachment");
239
240 if (imageFormatProperties.maxExtent.width < imageExtent.width
241 || imageFormatProperties.maxExtent.height < imageExtent.height
242 || ((imageFormatProperties.sampleCounts & sampleCountBit) == 0))
243 {
244 TCU_THROW(NotSupportedError, "Image type not supported");
245 }
246
247 return createImage(vkd, device, 0u, imageType, vkFormat, imageExtent, 1u, 1u, sampleCountBit, imageTiling, usage, VK_SHARING_MODE_EXCLUSIVE, 0u, DE_NULL, VK_IMAGE_LAYOUT_UNDEFINED);
248 }
249 catch (const vk::Error& error)
250 {
251 if (error.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
252 TCU_THROW(NotSupportedError, "Image format not supported");
253
254 throw;
255 }
256 }
257
createImageAttachmentView(const DeviceInterface & vkd,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect)258 Move<VkImageView> createImageAttachmentView (const DeviceInterface& vkd,
259 VkDevice device,
260 VkImage image,
261 VkFormat format,
262 VkImageAspectFlags aspect)
263 {
264 const VkImageSubresourceRange range =
265 {
266 aspect,
267 0u,
268 1u,
269 0u,
270 1u
271 };
272
273 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
274 }
275
createSrcPrimaryInputImageView(const DeviceInterface & vkd,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect)276 Move<VkImageView> createSrcPrimaryInputImageView (const DeviceInterface& vkd,
277 VkDevice device,
278 VkImage image,
279 VkFormat format,
280 VkImageAspectFlags aspect)
281 {
282 const VkImageSubresourceRange range =
283 {
284 aspect == (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)
285 ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT
286 : aspect,
287 0u,
288 1u,
289 0u,
290 1u
291 };
292
293 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
294 }
295
createSrcSecondaryInputImageView(const DeviceInterface & vkd,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect)296 Move<VkImageView> createSrcSecondaryInputImageView (const DeviceInterface& vkd,
297 VkDevice device,
298 VkImage image,
299 VkFormat format,
300 VkImageAspectFlags aspect)
301 {
302 if (aspect == (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT))
303 {
304 const VkImageSubresourceRange range =
305 {
306 VK_IMAGE_ASPECT_STENCIL_BIT,
307 0u,
308 1u,
309 0u,
310 1u
311 };
312
313 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
314 }
315 else
316 return Move<VkImageView>();
317 }
318
getPixelSize(VkFormat vkFormat)319 VkDeviceSize getPixelSize (VkFormat vkFormat)
320 {
321 const tcu::TextureFormat format (mapVkFormat(vkFormat));
322
323 return format.getPixelSize();
324 }
325
createBuffer(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 width,deUint32 height)326 Move<VkBuffer> createBuffer (const DeviceInterface& vkd,
327 VkDevice device,
328 VkFormat format,
329 deUint32 width,
330 deUint32 height)
331 {
332 const VkBufferUsageFlags bufferUsage (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
333 const VkDeviceSize pixelSize (getPixelSize(format));
334 const VkBufferCreateInfo createInfo =
335 {
336 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
337 DE_NULL,
338 0u,
339
340 width * height * pixelSize,
341 bufferUsage,
342
343 VK_SHARING_MODE_EXCLUSIVE,
344 0u,
345 DE_NULL
346 };
347 return createBuffer(vkd, device, &createInfo);
348 }
349
sampleCountBitFromomSampleCount(deUint32 count)350 VkSampleCountFlagBits sampleCountBitFromomSampleCount (deUint32 count)
351 {
352 switch (count)
353 {
354 case 1: return VK_SAMPLE_COUNT_1_BIT;
355 case 2: return VK_SAMPLE_COUNT_2_BIT;
356 case 4: return VK_SAMPLE_COUNT_4_BIT;
357 case 8: return VK_SAMPLE_COUNT_8_BIT;
358 case 16: return VK_SAMPLE_COUNT_16_BIT;
359 case 32: return VK_SAMPLE_COUNT_32_BIT;
360 case 64: return VK_SAMPLE_COUNT_64_BIT;
361
362 default:
363 DE_FATAL("Invalid sample count");
364 return (VkSampleCountFlagBits)(0x1u << count);
365 }
366 }
367
createMultisampleImages(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 sampleCount,deUint32 width,deUint32 height)368 std::vector<VkImageSp> createMultisampleImages (const InstanceInterface& vki,
369 VkPhysicalDevice physicalDevice,
370 const DeviceInterface& vkd,
371 VkDevice device,
372 VkFormat format,
373 deUint32 sampleCount,
374 deUint32 width,
375 deUint32 height)
376 {
377 std::vector<VkImageSp> images (sampleCount);
378
379 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
380 images[imageNdx] = safeSharedPtr(new vk::Unique<VkImage>(createImage(vki, physicalDevice, vkd, device, format, sampleCountBitFromomSampleCount(sampleCount), VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, width, height)));
381
382 return images;
383 }
384
createSingleSampleImages(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 sampleCount,deUint32 width,deUint32 height)385 std::vector<VkImageSp> createSingleSampleImages (const InstanceInterface& vki,
386 VkPhysicalDevice physicalDevice,
387 const DeviceInterface& vkd,
388 VkDevice device,
389 VkFormat format,
390 deUint32 sampleCount,
391 deUint32 width,
392 deUint32 height)
393 {
394 std::vector<VkImageSp> images (sampleCount);
395
396 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
397 images[imageNdx] = safeSharedPtr(new vk::Unique<VkImage>(createImage(vki, physicalDevice, vkd, device, format, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, width, height)));
398
399 return images;
400 }
401
createImageMemory(const DeviceInterface & vkd,VkDevice device,Allocator & allocator,const std::vector<VkImageSp> images)402 std::vector<de::SharedPtr<Allocation> > createImageMemory (const DeviceInterface& vkd,
403 VkDevice device,
404 Allocator& allocator,
405 const std::vector<VkImageSp> images)
406 {
407 std::vector<de::SharedPtr<Allocation> > memory (images.size());
408
409 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
410 memory[memoryNdx] = safeSharedPtr(createImageMemory(vkd, device, allocator, **images[memoryNdx]).release());
411
412 return memory;
413 }
414
createImageAttachmentViews(const DeviceInterface & vkd,VkDevice device,const std::vector<VkImageSp> & images,VkFormat format,VkImageAspectFlagBits aspect)415 std::vector<VkImageViewSp> createImageAttachmentViews (const DeviceInterface& vkd,
416 VkDevice device,
417 const std::vector<VkImageSp>& images,
418 VkFormat format,
419 VkImageAspectFlagBits aspect)
420 {
421 std::vector<VkImageViewSp> views (images.size());
422
423 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
424 views[imageNdx] = safeSharedPtr(new vk::Unique<VkImageView>(createImageAttachmentView(vkd, device, **images[imageNdx], format, aspect)));
425
426 return views;
427 }
428
createBuffers(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 sampleCount,deUint32 width,deUint32 height)429 std::vector<VkBufferSp> createBuffers (const DeviceInterface& vkd,
430 VkDevice device,
431 VkFormat format,
432 deUint32 sampleCount,
433 deUint32 width,
434 deUint32 height)
435 {
436 std::vector<VkBufferSp> buffers (sampleCount);
437
438 for (size_t bufferNdx = 0; bufferNdx < buffers.size(); bufferNdx++)
439 buffers[bufferNdx] = safeSharedPtr(new vk::Unique<VkBuffer>(createBuffer(vkd, device, format, width, height)));
440
441 return buffers;
442 }
443
createBufferMemory(const DeviceInterface & vkd,VkDevice device,Allocator & allocator,const std::vector<VkBufferSp> buffers)444 std::vector<de::SharedPtr<Allocation> > createBufferMemory (const DeviceInterface& vkd,
445 VkDevice device,
446 Allocator& allocator,
447 const std::vector<VkBufferSp> buffers)
448 {
449 std::vector<de::SharedPtr<Allocation> > memory (buffers.size());
450
451 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
452 memory[memoryNdx] = safeSharedPtr(createBufferMemory(vkd, device, allocator, **buffers[memoryNdx]).release());
453
454 return memory;
455 }
456
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat srcFormat,VkFormat dstFormat,deUint32 sampleCount)457 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
458 VkDevice device,
459 VkFormat srcFormat,
460 VkFormat dstFormat,
461 deUint32 sampleCount)
462 {
463 const VkSampleCountFlagBits samples (sampleCountBitFromomSampleCount(sampleCount));
464 const deUint32 splitSubpassCount (deDivRoundUp32(sampleCount, MAX_COLOR_ATTACHMENT_COUNT));
465 const tcu::TextureFormat format (mapVkFormat(srcFormat));
466 const bool isDepthStencilFormat (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order));
467 vector<VkSubpassDescription> subpasses;
468 vector<vector<VkAttachmentReference> > dstAttachmentRefs (splitSubpassCount);
469 vector<vector<VkAttachmentReference> > dstResolveAttachmentRefs (splitSubpassCount);
470 vector<VkAttachmentDescription> attachments;
471 vector<VkSubpassDependency> dependencies;
472 const VkAttachmentReference srcAttachmentRef =
473 {
474 0u,
475 isDepthStencilFormat
476 ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
477 : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
478 };
479 const VkAttachmentReference srcAttachmentInputRef =
480 {
481 0u,
482 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
483 };
484
485 {
486 const VkAttachmentDescription srcAttachment =
487 {
488 0u,
489
490 srcFormat,
491 samples,
492
493 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
494 VK_ATTACHMENT_STORE_OP_DONT_CARE,
495
496 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
497 VK_ATTACHMENT_STORE_OP_DONT_CARE,
498
499 VK_IMAGE_LAYOUT_UNDEFINED,
500 VK_IMAGE_LAYOUT_GENERAL
501 };
502
503 attachments.push_back(srcAttachment);
504 }
505
506 for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < splitSubpassCount; splitSubpassIndex++)
507 {
508 for (deUint32 sampleNdx = 0; sampleNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, sampleCount - splitSubpassIndex * MAX_COLOR_ATTACHMENT_COUNT); sampleNdx++)
509 {
510 // Multisample color attachment
511 {
512 const VkAttachmentDescription dstAttachment =
513 {
514 0u,
515
516 dstFormat,
517 samples,
518
519 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
520 VK_ATTACHMENT_STORE_OP_DONT_CARE,
521
522 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
523 VK_ATTACHMENT_STORE_OP_DONT_CARE,
524
525 VK_IMAGE_LAYOUT_UNDEFINED,
526 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
527 };
528 const VkAttachmentReference dstAttachmentRef =
529 {
530 (deUint32)attachments.size(),
531 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
532 };
533
534 attachments.push_back(dstAttachment);
535 dstAttachmentRefs[splitSubpassIndex].push_back(dstAttachmentRef);
536 }
537 // Resolve attachment
538 {
539 const VkAttachmentDescription dstAttachment =
540 {
541 0u,
542
543 dstFormat,
544 VK_SAMPLE_COUNT_1_BIT,
545
546 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
547 VK_ATTACHMENT_STORE_OP_STORE,
548
549 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
550 VK_ATTACHMENT_STORE_OP_STORE,
551
552 VK_IMAGE_LAYOUT_UNDEFINED,
553 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
554 };
555 const VkAttachmentReference dstAttachmentRef =
556 {
557 (deUint32)attachments.size(),
558 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
559 };
560
561 attachments.push_back(dstAttachment);
562 dstResolveAttachmentRefs[splitSubpassIndex].push_back(dstAttachmentRef);
563 }
564 }
565 }
566
567 {
568 {
569 const VkSubpassDescription subpass =
570 {
571 (VkSubpassDescriptionFlags)0,
572 VK_PIPELINE_BIND_POINT_GRAPHICS,
573
574 0u,
575 DE_NULL,
576
577 isDepthStencilFormat ? 0u : 1u,
578 isDepthStencilFormat ? DE_NULL : &srcAttachmentRef,
579 DE_NULL,
580
581 isDepthStencilFormat ? &srcAttachmentRef : DE_NULL,
582 0u,
583 DE_NULL
584 };
585
586 subpasses.push_back(subpass);
587 }
588
589 for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < splitSubpassCount; splitSubpassIndex++)
590 {
591 {
592 const VkSubpassDescription subpass =
593 {
594 (VkSubpassDescriptionFlags)0,
595 VK_PIPELINE_BIND_POINT_GRAPHICS,
596
597 1u,
598 &srcAttachmentInputRef,
599
600 (deUint32)dstAttachmentRefs[splitSubpassIndex].size(),
601 &dstAttachmentRefs[splitSubpassIndex][0],
602 &dstResolveAttachmentRefs[splitSubpassIndex][0],
603
604 DE_NULL,
605 0u,
606 DE_NULL
607 };
608 subpasses.push_back(subpass);
609 }
610 {
611 const VkSubpassDependency dependency =
612 {
613 0u, splitSubpassIndex + 1,
614 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
615 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
616
617 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
618 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
619
620 VK_DEPENDENCY_BY_REGION_BIT
621 };
622
623 dependencies.push_back(dependency);
624 }
625 };
626 const VkRenderPassCreateInfo createInfo =
627 {
628 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
629 DE_NULL,
630 (VkRenderPassCreateFlags)0u,
631
632 (deUint32)attachments.size(),
633 &attachments[0],
634
635 (deUint32)subpasses.size(),
636 &subpasses[0],
637
638 (deUint32)dependencies.size(),
639 &dependencies[0]
640 };
641
642 return createRenderPass(vkd, device, &createInfo);
643 }
644 }
645
createFramebuffer(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkImageView srcImageView,const std::vector<VkImageViewSp> & dstMultisampleImageViews,const std::vector<VkImageViewSp> & dstSinglesampleImageViews,deUint32 width,deUint32 height)646 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vkd,
647 VkDevice device,
648 VkRenderPass renderPass,
649 VkImageView srcImageView,
650 const std::vector<VkImageViewSp>& dstMultisampleImageViews,
651 const std::vector<VkImageViewSp>& dstSinglesampleImageViews,
652 deUint32 width,
653 deUint32 height)
654 {
655 std::vector<VkImageView> attachments;
656
657 attachments.reserve(dstMultisampleImageViews.size() + dstSinglesampleImageViews.size() + 1u);
658
659 attachments.push_back(srcImageView);
660
661 DE_ASSERT(dstMultisampleImageViews.size() == dstSinglesampleImageViews.size());
662
663 for (size_t ndx = 0; ndx < dstMultisampleImageViews.size(); ndx++)
664 {
665 attachments.push_back(**dstMultisampleImageViews[ndx]);
666 attachments.push_back(**dstSinglesampleImageViews[ndx]);
667 }
668
669 const VkFramebufferCreateInfo createInfo =
670 {
671 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
672 DE_NULL,
673 0u,
674
675 renderPass,
676 (deUint32)attachments.size(),
677 &attachments[0],
678
679 width,
680 height,
681 1u
682 };
683
684 return createFramebuffer(vkd, device, &createInfo);
685 }
686
createRenderPipelineLayout(const DeviceInterface & vkd,VkDevice device)687 Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface& vkd,
688 VkDevice device)
689 {
690 const VkPushConstantRange pushConstant =
691 {
692 VK_SHADER_STAGE_FRAGMENT_BIT,
693 0u,
694 4u
695 };
696 const VkPipelineLayoutCreateInfo createInfo =
697 {
698 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
699 DE_NULL,
700 (vk::VkPipelineLayoutCreateFlags)0,
701
702 0u,
703 DE_NULL,
704
705 1u,
706 &pushConstant
707 };
708
709 return createPipelineLayout(vkd, device, &createInfo);
710 }
711
createRenderPipeline(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkPipelineLayout pipelineLayout,const vk::ProgramCollection<vk::ProgramBinary> & binaryCollection,deUint32 width,deUint32 height,deUint32 sampleCount)712 Move<VkPipeline> createRenderPipeline (const DeviceInterface& vkd,
713 VkDevice device,
714 VkRenderPass renderPass,
715 VkPipelineLayout pipelineLayout,
716 const vk::ProgramCollection<vk::ProgramBinary>& binaryCollection,
717 deUint32 width,
718 deUint32 height,
719 deUint32 sampleCount)
720 {
721 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
722 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
723 const VkSpecializationInfo emptyShaderSpecializations =
724 {
725 0u,
726 DE_NULL,
727
728 0u,
729 DE_NULL
730 };
731 // Disable blending
732 const VkPipelineColorBlendAttachmentState attachmentBlendState =
733 {
734 VK_FALSE,
735 VK_BLEND_FACTOR_SRC_ALPHA,
736 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
737 VK_BLEND_OP_ADD,
738 VK_BLEND_FACTOR_ONE,
739 VK_BLEND_FACTOR_ONE,
740 VK_BLEND_OP_ADD,
741 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
742 };
743 const VkPipelineShaderStageCreateInfo shaderStages[2] =
744 {
745 {
746 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
747 DE_NULL,
748 (VkPipelineShaderStageCreateFlags)0u,
749 VK_SHADER_STAGE_VERTEX_BIT,
750 *vertexShaderModule,
751 "main",
752 &emptyShaderSpecializations
753 },
754 {
755 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
756 DE_NULL,
757 (VkPipelineShaderStageCreateFlags)0u,
758 VK_SHADER_STAGE_FRAGMENT_BIT,
759 *fragmentShaderModule,
760 "main",
761 &emptyShaderSpecializations
762 }
763 };
764 const VkPipelineVertexInputStateCreateInfo vertexInputState =
765 {
766 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
767 DE_NULL,
768 (VkPipelineVertexInputStateCreateFlags)0u,
769
770 0u,
771 DE_NULL,
772
773 0u,
774 DE_NULL
775 };
776 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
777 {
778 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
779 DE_NULL,
780
781 (VkPipelineInputAssemblyStateCreateFlags)0u,
782 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
783 VK_FALSE
784 };
785 const VkViewport viewport =
786 {
787 0.0f, 0.0f,
788 (float)width, (float)height,
789
790 0.0f, 1.0f
791 };
792 const VkRect2D scissor =
793 {
794 { 0u, 0u },
795 { width, height }
796 };
797 const VkPipelineViewportStateCreateInfo viewportState =
798 {
799 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
800 DE_NULL,
801 (VkPipelineViewportStateCreateFlags)0u,
802
803 1u,
804 &viewport,
805
806 1u,
807 &scissor
808 };
809 const VkPipelineRasterizationStateCreateInfo rasterState =
810 {
811 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
812 DE_NULL,
813 (VkPipelineRasterizationStateCreateFlags)0u,
814 VK_TRUE,
815 VK_FALSE,
816 VK_POLYGON_MODE_FILL,
817 VK_CULL_MODE_NONE,
818 VK_FRONT_FACE_COUNTER_CLOCKWISE,
819 VK_FALSE,
820 0.0f,
821 0.0f,
822 0.0f,
823 1.0f
824 };
825 const VkPipelineMultisampleStateCreateInfo multisampleState =
826 {
827 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
828 DE_NULL,
829 (VkPipelineMultisampleStateCreateFlags)0u,
830
831 sampleCountBitFromomSampleCount(sampleCount),
832 VK_FALSE,
833 0.0f,
834 DE_NULL,
835 VK_FALSE,
836 VK_FALSE,
837 };
838 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
839 {
840 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
841 DE_NULL,
842 (VkPipelineDepthStencilStateCreateFlags)0u,
843
844 VK_TRUE,
845 VK_TRUE,
846 VK_COMPARE_OP_ALWAYS,
847 VK_FALSE,
848 VK_TRUE,
849 {
850 VK_STENCIL_OP_KEEP,
851 VK_STENCIL_OP_INCREMENT_AND_WRAP,
852 VK_STENCIL_OP_KEEP,
853 VK_COMPARE_OP_ALWAYS,
854 ~0u,
855 ~0u,
856 0xFFu / (sampleCount + 1)
857 },
858 {
859 VK_STENCIL_OP_KEEP,
860 VK_STENCIL_OP_INCREMENT_AND_WRAP,
861 VK_STENCIL_OP_KEEP,
862 VK_COMPARE_OP_ALWAYS,
863 ~0u,
864 ~0u,
865 0xFFu / (sampleCount + 1)
866 },
867
868 0.0f,
869 1.0f
870 };
871 const VkPipelineColorBlendStateCreateInfo blendState =
872 {
873 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
874 DE_NULL,
875 (VkPipelineColorBlendStateCreateFlags)0u,
876
877 VK_FALSE,
878 VK_LOGIC_OP_COPY,
879 1u,
880 &attachmentBlendState,
881 { 0.0f, 0.0f, 0.0f, 0.0f }
882 };
883 const VkGraphicsPipelineCreateInfo createInfo =
884 {
885 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
886 DE_NULL,
887 (VkPipelineCreateFlags)0u,
888
889 2,
890 shaderStages,
891
892 &vertexInputState,
893 &inputAssemblyState,
894 DE_NULL,
895 &viewportState,
896 &rasterState,
897 &multisampleState,
898 &depthStencilState,
899 &blendState,
900 (const VkPipelineDynamicStateCreateInfo*)DE_NULL,
901 pipelineLayout,
902
903 renderPass,
904 0u,
905 DE_NULL,
906 0u
907 };
908
909 return createGraphicsPipeline(vkd, device, DE_NULL, &createInfo);
910 }
911
createSplitDescriptorSetLayout(const DeviceInterface & vkd,VkDevice device,VkFormat vkFormat)912 Move<VkDescriptorSetLayout> createSplitDescriptorSetLayout (const DeviceInterface& vkd,
913 VkDevice device,
914 VkFormat vkFormat)
915 {
916 const tcu::TextureFormat format (mapVkFormat(vkFormat));
917 const bool hasDepth (tcu::hasDepthComponent(format.order));
918 const bool hasStencil (tcu::hasStencilComponent(format.order));
919 const VkDescriptorSetLayoutBinding bindings[] =
920 {
921 {
922 0u,
923 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
924 1u,
925 VK_SHADER_STAGE_FRAGMENT_BIT,
926 DE_NULL
927 },
928 {
929 1u,
930 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
931 1u,
932 VK_SHADER_STAGE_FRAGMENT_BIT,
933 DE_NULL
934 }
935 };
936 const VkDescriptorSetLayoutCreateInfo createInfo =
937 {
938 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
939 DE_NULL,
940 0u,
941
942 hasDepth && hasStencil ? 2u : 1u,
943 bindings
944 };
945
946 return createDescriptorSetLayout(vkd, device, &createInfo);
947 }
948
createSplitPipelineLayout(const DeviceInterface & vkd,VkDevice device,VkDescriptorSetLayout descriptorSetLayout)949 Move<VkPipelineLayout> createSplitPipelineLayout (const DeviceInterface& vkd,
950 VkDevice device,
951 VkDescriptorSetLayout descriptorSetLayout)
952 {
953 const VkPushConstantRange pushConstant =
954 {
955 VK_SHADER_STAGE_FRAGMENT_BIT,
956 0u,
957 4u
958 };
959 const VkPipelineLayoutCreateInfo createInfo =
960 {
961 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
962 DE_NULL,
963 (vk::VkPipelineLayoutCreateFlags)0,
964
965 1u,
966 &descriptorSetLayout,
967
968 1u,
969 &pushConstant
970 };
971
972 return createPipelineLayout(vkd, device, &createInfo);
973 }
974
createSplitPipeline(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,deUint32 subpassIndex,VkPipelineLayout pipelineLayout,const vk::ProgramCollection<vk::ProgramBinary> & binaryCollection,deUint32 width,deUint32 height,deUint32 sampleCount)975 Move<VkPipeline> createSplitPipeline (const DeviceInterface& vkd,
976 VkDevice device,
977 VkRenderPass renderPass,
978 deUint32 subpassIndex,
979 VkPipelineLayout pipelineLayout,
980 const vk::ProgramCollection<vk::ProgramBinary>& binaryCollection,
981 deUint32 width,
982 deUint32 height,
983 deUint32 sampleCount)
984 {
985 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
986 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-split-frag"), 0u));
987 const VkSpecializationInfo emptyShaderSpecializations =
988 {
989 0u,
990 DE_NULL,
991
992 0u,
993 DE_NULL
994 };
995 // Disable blending
996 const VkPipelineColorBlendAttachmentState attachmentBlendState =
997 {
998 VK_FALSE,
999 VK_BLEND_FACTOR_SRC_ALPHA,
1000 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
1001 VK_BLEND_OP_ADD,
1002 VK_BLEND_FACTOR_ONE,
1003 VK_BLEND_FACTOR_ONE,
1004 VK_BLEND_OP_ADD,
1005 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
1006 };
1007 const std::vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates (de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, sampleCount), attachmentBlendState);
1008 const VkPipelineShaderStageCreateInfo shaderStages[2] =
1009 {
1010 {
1011 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1012 DE_NULL,
1013 (VkPipelineShaderStageCreateFlags)0u,
1014 VK_SHADER_STAGE_VERTEX_BIT,
1015 *vertexShaderModule,
1016 "main",
1017 &emptyShaderSpecializations
1018 },
1019 {
1020 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1021 DE_NULL,
1022 (VkPipelineShaderStageCreateFlags)0u,
1023 VK_SHADER_STAGE_FRAGMENT_BIT,
1024 *fragmentShaderModule,
1025 "main",
1026 &emptyShaderSpecializations
1027 }
1028 };
1029 const VkPipelineVertexInputStateCreateInfo vertexInputState =
1030 {
1031 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1032 DE_NULL,
1033 (VkPipelineVertexInputStateCreateFlags)0u,
1034
1035 0u,
1036 DE_NULL,
1037
1038 0u,
1039 DE_NULL
1040 };
1041 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
1042 {
1043 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
1044 DE_NULL,
1045
1046 (VkPipelineInputAssemblyStateCreateFlags)0u,
1047 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
1048 VK_FALSE
1049 };
1050 const VkViewport viewport =
1051 {
1052 0.0f, 0.0f,
1053 (float)width, (float)height,
1054
1055 0.0f, 1.0f
1056 };
1057 const VkRect2D scissor =
1058 {
1059 { 0u, 0u },
1060 { width, height }
1061 };
1062 const VkPipelineViewportStateCreateInfo viewportState =
1063 {
1064 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1065 DE_NULL,
1066 (VkPipelineViewportStateCreateFlags)0u,
1067
1068 1u,
1069 &viewport,
1070
1071 1u,
1072 &scissor
1073 };
1074 const VkPipelineRasterizationStateCreateInfo rasterState =
1075 {
1076 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
1077 DE_NULL,
1078 (VkPipelineRasterizationStateCreateFlags)0u,
1079 VK_TRUE,
1080 VK_FALSE,
1081 VK_POLYGON_MODE_FILL,
1082 VK_CULL_MODE_NONE,
1083 VK_FRONT_FACE_COUNTER_CLOCKWISE,
1084 VK_FALSE,
1085 0.0f,
1086 0.0f,
1087 0.0f,
1088 1.0f
1089 };
1090 const VkPipelineMultisampleStateCreateInfo multisampleState =
1091 {
1092 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1093 DE_NULL,
1094 (VkPipelineMultisampleStateCreateFlags)0u,
1095
1096 sampleCountBitFromomSampleCount(sampleCount),
1097 VK_FALSE,
1098 0.0f,
1099 DE_NULL,
1100 VK_FALSE,
1101 VK_FALSE,
1102 };
1103 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
1104 {
1105 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1106 DE_NULL,
1107 (VkPipelineDepthStencilStateCreateFlags)0u,
1108
1109 VK_FALSE,
1110 VK_FALSE,
1111 VK_COMPARE_OP_ALWAYS,
1112 VK_FALSE,
1113 VK_FALSE,
1114 {
1115 VK_STENCIL_OP_REPLACE,
1116 VK_STENCIL_OP_REPLACE,
1117 VK_STENCIL_OP_REPLACE,
1118 VK_COMPARE_OP_ALWAYS,
1119 ~0u,
1120 ~0u,
1121 0x0u
1122 },
1123 {
1124 VK_STENCIL_OP_REPLACE,
1125 VK_STENCIL_OP_REPLACE,
1126 VK_STENCIL_OP_REPLACE,
1127 VK_COMPARE_OP_ALWAYS,
1128 ~0u,
1129 ~0u,
1130 0x0u
1131 },
1132
1133 0.0f,
1134 1.0f
1135 };
1136 const VkPipelineColorBlendStateCreateInfo blendState =
1137 {
1138 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1139 DE_NULL,
1140 (VkPipelineColorBlendStateCreateFlags)0u,
1141
1142 VK_FALSE,
1143 VK_LOGIC_OP_COPY,
1144
1145 (deUint32)attachmentBlendStates.size(),
1146 &attachmentBlendStates[0],
1147
1148 { 0.0f, 0.0f, 0.0f, 0.0f }
1149 };
1150 const VkGraphicsPipelineCreateInfo createInfo =
1151 {
1152 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1153 DE_NULL,
1154 (VkPipelineCreateFlags)0u,
1155
1156 2,
1157 shaderStages,
1158
1159 &vertexInputState,
1160 &inputAssemblyState,
1161 DE_NULL,
1162 &viewportState,
1163 &rasterState,
1164 &multisampleState,
1165 &depthStencilState,
1166 &blendState,
1167 (const VkPipelineDynamicStateCreateInfo*)DE_NULL,
1168 pipelineLayout,
1169
1170 renderPass,
1171 subpassIndex,
1172 DE_NULL,
1173 0u
1174 };
1175
1176 return createGraphicsPipeline(vkd, device, DE_NULL, &createInfo);
1177 }
1178
createSplitPipelines(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkPipelineLayout pipelineLayout,const vk::ProgramCollection<vk::ProgramBinary> & binaryCollection,deUint32 width,deUint32 height,deUint32 sampleCount)1179 vector<VkPipeline> createSplitPipelines (const DeviceInterface& vkd,
1180 VkDevice device,
1181 VkRenderPass renderPass,
1182 VkPipelineLayout pipelineLayout,
1183 const vk::ProgramCollection<vk::ProgramBinary>& binaryCollection,
1184 deUint32 width,
1185 deUint32 height,
1186 deUint32 sampleCount)
1187 {
1188 vector<VkPipeline> pipelines (deDivRoundUp32(sampleCount, MAX_COLOR_ATTACHMENT_COUNT), (VkPipeline)0u);
1189
1190 try
1191 {
1192 for (size_t ndx = 0; ndx < pipelines.size(); ndx++)
1193 pipelines[ndx] = createSplitPipeline(vkd, device, renderPass, (deUint32)(ndx + 1), pipelineLayout, binaryCollection, width, height, sampleCount).disown();
1194 }
1195 catch (...)
1196 {
1197 for (size_t ndx = 0; ndx < pipelines.size(); ndx++)
1198 vkd.destroyPipeline(device, pipelines[ndx], DE_NULL);
1199
1200 throw;
1201 }
1202
1203 return pipelines;
1204 }
1205
createSplitDescriptorPool(const DeviceInterface & vkd,VkDevice device)1206 Move<VkDescriptorPool> createSplitDescriptorPool (const DeviceInterface& vkd,
1207 VkDevice device)
1208 {
1209 const VkDescriptorPoolSize size =
1210 {
1211 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2u
1212 };
1213 const VkDescriptorPoolCreateInfo createInfo =
1214 {
1215 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1216 DE_NULL,
1217 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1218
1219
1220 2u,
1221 1u,
1222 &size
1223 };
1224
1225 return createDescriptorPool(vkd, device, &createInfo);
1226 }
1227
createSplitDescriptorSet(const DeviceInterface & vkd,VkDevice device,VkDescriptorPool pool,VkDescriptorSetLayout layout,VkImageView primaryImageView,VkImageView secondaryImageView)1228 Move<VkDescriptorSet> createSplitDescriptorSet (const DeviceInterface& vkd,
1229 VkDevice device,
1230 VkDescriptorPool pool,
1231 VkDescriptorSetLayout layout,
1232 VkImageView primaryImageView,
1233 VkImageView secondaryImageView)
1234 {
1235 const VkDescriptorSetAllocateInfo allocateInfo =
1236 {
1237 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1238 DE_NULL,
1239
1240 pool,
1241 1u,
1242 &layout
1243 };
1244 Move<VkDescriptorSet> set (allocateDescriptorSet(vkd, device, &allocateInfo));
1245
1246 {
1247 const VkDescriptorImageInfo imageInfos[] =
1248 {
1249 {
1250 (VkSampler)0u,
1251 primaryImageView,
1252 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1253 },
1254 {
1255 (VkSampler)0u,
1256 secondaryImageView,
1257 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1258 }
1259 };
1260 const VkWriteDescriptorSet writes[] =
1261 {
1262 {
1263 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1264 DE_NULL,
1265
1266 *set,
1267 0u,
1268 0u,
1269 1u,
1270 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1271 &imageInfos[0],
1272 DE_NULL,
1273 DE_NULL
1274 },
1275 {
1276 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1277 DE_NULL,
1278
1279 *set,
1280 1u,
1281 0u,
1282 1u,
1283 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1284 &imageInfos[1],
1285 DE_NULL,
1286 DE_NULL
1287 }
1288 };
1289 const deUint32 count = secondaryImageView != (VkImageView)0
1290 ? 2u
1291 : 1u;
1292
1293 vkd.updateDescriptorSets(device, count, writes, 0u, DE_NULL);
1294 }
1295 return set;
1296 }
1297
1298 struct TestConfig
1299 {
TestConfigvkt::__anon7e6592500111::TestConfig1300 TestConfig (VkFormat format_,
1301 deUint32 sampleCount_)
1302 : format (format_)
1303 , sampleCount (sampleCount_)
1304 {
1305 }
1306
1307 VkFormat format;
1308 deUint32 sampleCount;
1309 };
1310
getSrcImageUsage(VkFormat vkFormat)1311 VkImageUsageFlags getSrcImageUsage (VkFormat vkFormat)
1312 {
1313 const tcu::TextureFormat format (mapVkFormat(vkFormat));
1314 const bool hasDepth (tcu::hasDepthComponent(format.order));
1315 const bool hasStencil (tcu::hasStencilComponent(format.order));
1316
1317 if (hasDepth || hasStencil)
1318 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1319 else
1320 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1321 }
1322
getDstFormat(VkFormat vkFormat)1323 VkFormat getDstFormat (VkFormat vkFormat)
1324 {
1325 const tcu::TextureFormat format (mapVkFormat(vkFormat));
1326 const bool hasDepth (tcu::hasDepthComponent(format.order));
1327 const bool hasStencil (tcu::hasStencilComponent(format.order));
1328
1329 if (hasDepth && hasStencil)
1330 return VK_FORMAT_R32G32_SFLOAT;
1331 else if (hasDepth || hasStencil)
1332 return VK_FORMAT_R32_SFLOAT;
1333 else
1334 return vkFormat;
1335 }
1336
1337
1338 class MultisampleRenderPassTestInstance : public TestInstance
1339 {
1340 public:
1341 MultisampleRenderPassTestInstance (Context& context, TestConfig config);
1342 ~MultisampleRenderPassTestInstance (void);
1343
1344 tcu::TestStatus iterate (void);
1345
1346 private:
1347 const VkFormat m_srcFormat;
1348 const VkFormat m_dstFormat;
1349 const deUint32 m_sampleCount;
1350 const deUint32 m_width;
1351 const deUint32 m_height;
1352
1353 const VkImageAspectFlags m_srcImageAspect;
1354 const VkImageUsageFlags m_srcImageUsage;
1355 const Unique<VkImage> m_srcImage;
1356 const de::UniquePtr<Allocation> m_srcImageMemory;
1357 const Unique<VkImageView> m_srcImageView;
1358 const Unique<VkImageView> m_srcPrimaryInputImageView;
1359 const Unique<VkImageView> m_srcSecondaryInputImageView;
1360
1361 const std::vector<VkImageSp> m_dstMultisampleImages;
1362 const std::vector<de::SharedPtr<Allocation> > m_dstMultisampleImageMemory;
1363 const std::vector<VkImageViewSp> m_dstMultisampleImageViews;
1364
1365 const std::vector<VkImageSp> m_dstSinglesampleImages;
1366 const std::vector<de::SharedPtr<Allocation> > m_dstSinglesampleImageMemory;
1367 const std::vector<VkImageViewSp> m_dstSinglesampleImageViews;
1368
1369 const std::vector<VkBufferSp> m_dstBuffers;
1370 const std::vector<de::SharedPtr<Allocation> > m_dstBufferMemory;
1371
1372 const Unique<VkRenderPass> m_renderPass;
1373 const Unique<VkFramebuffer> m_framebuffer;
1374
1375 const Unique<VkPipelineLayout> m_renderPipelineLayout;
1376 const Unique<VkPipeline> m_renderPipeline;
1377
1378 const Unique<VkDescriptorSetLayout> m_splitDescriptorSetLayout;
1379 const Unique<VkPipelineLayout> m_splitPipelineLayout;
1380 const vector<VkPipeline> m_splitPipelines;
1381 const Unique<VkDescriptorPool> m_splitDescriptorPool;
1382 const Unique<VkDescriptorSet> m_splitDescriptorSet;
1383
1384 const Unique<VkCommandPool> m_commandPool;
1385 tcu::ResultCollector m_resultCollector;
1386 };
1387
MultisampleRenderPassTestInstance(Context & context,TestConfig config)1388 MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
1389 : TestInstance (context)
1390 , m_srcFormat (config.format)
1391 , m_dstFormat (getDstFormat(config.format))
1392 , m_sampleCount (config.sampleCount)
1393 , m_width (32u)
1394 , m_height (32u)
1395
1396 , m_srcImageAspect (getImageAspectFlags(m_srcFormat))
1397 , m_srcImageUsage (getSrcImageUsage(m_srcFormat))
1398 , m_srcImage (createImage(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_srcFormat, sampleCountBitFromomSampleCount(m_sampleCount), m_srcImageUsage, m_width, m_height))
1399 , m_srcImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_srcImage))
1400 , m_srcImageView (createImageAttachmentView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect))
1401 , m_srcPrimaryInputImageView (createSrcPrimaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect))
1402 , m_srcSecondaryInputImageView (createSrcSecondaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect))
1403
1404 , m_dstMultisampleImages (createMultisampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1405 , m_dstMultisampleImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstMultisampleImages))
1406 , m_dstMultisampleImageViews (createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstMultisampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))
1407
1408 , m_dstSinglesampleImages (createSingleSampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1409 , m_dstSinglesampleImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstSinglesampleImages))
1410 , m_dstSinglesampleImageViews (createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstSinglesampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))
1411
1412 , m_dstBuffers (createBuffers(context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1413 , m_dstBufferMemory (createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstBuffers))
1414
1415 , m_renderPass (createRenderPass(context.getDeviceInterface(), context.getDevice(), m_srcFormat, m_dstFormat, m_sampleCount))
1416 , m_framebuffer (createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_srcImageView, m_dstMultisampleImageViews, m_dstSinglesampleImageViews, m_width, m_height))
1417
1418 , m_renderPipelineLayout (createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
1419 , m_renderPipeline (createRenderPipeline(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
1420
1421 , m_splitDescriptorSetLayout (createSplitDescriptorSetLayout(context.getDeviceInterface(), context.getDevice(), m_srcFormat))
1422 , m_splitPipelineLayout (createSplitPipelineLayout(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorSetLayout))
1423 , m_splitPipelines (createSplitPipelines(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_splitPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
1424 , m_splitDescriptorPool (createSplitDescriptorPool(context.getDeviceInterface(), context.getDevice()))
1425 , m_splitDescriptorSet (createSplitDescriptorSet(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorPool, *m_splitDescriptorSetLayout, *m_srcPrimaryInputImageView, *m_srcSecondaryInputImageView))
1426 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
1427 {
1428 }
1429
~MultisampleRenderPassTestInstance(void)1430 MultisampleRenderPassTestInstance::~MultisampleRenderPassTestInstance (void)
1431 {
1432 }
1433
iterate(void)1434 tcu::TestStatus MultisampleRenderPassTestInstance::iterate (void)
1435 {
1436 const DeviceInterface& vkd (m_context.getDeviceInterface());
1437 const VkDevice device (m_context.getDevice());
1438 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1439
1440 {
1441 const VkCommandBufferBeginInfo beginInfo =
1442 {
1443 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1444 DE_NULL,
1445
1446 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
1447 DE_NULL
1448 };
1449
1450 VK_CHECK(vkd.beginCommandBuffer(*commandBuffer, &beginInfo));
1451 }
1452
1453 {
1454 const VkRenderPassBeginInfo beginInfo =
1455 {
1456 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1457 DE_NULL,
1458
1459 *m_renderPass,
1460 *m_framebuffer,
1461
1462 {
1463 { 0u, 0u },
1464 { m_width, m_height }
1465 },
1466
1467 0u,
1468 DE_NULL
1469 };
1470 vkd.cmdBeginRenderPass(*commandBuffer, &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
1471 }
1472
1473 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
1474
1475 for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
1476 {
1477 vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(sampleNdx), &sampleNdx);
1478 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1479 }
1480
1481 for (deUint32 splitPipelineNdx = 0; splitPipelineNdx < m_splitPipelines.size(); splitPipelineNdx++)
1482 {
1483 vkd.cmdNextSubpass(*commandBuffer, VK_SUBPASS_CONTENTS_INLINE);
1484
1485 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_splitPipelines[splitPipelineNdx]);
1486 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_splitPipelineLayout, 0u, 1u, &*m_splitDescriptorSet, 0u, DE_NULL);
1487 vkd.cmdPushConstants(*commandBuffer, *m_splitPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(splitPipelineNdx), &splitPipelineNdx);
1488 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1489 }
1490
1491 vkd.cmdEndRenderPass(*commandBuffer);
1492
1493 // Memory barriers between rendering and copies
1494 {
1495 std::vector<VkImageMemoryBarrier> barriers;
1496
1497 for (size_t dstNdx = 0; dstNdx < m_dstSinglesampleImages.size(); dstNdx++)
1498 {
1499 const VkImageMemoryBarrier barrier =
1500 {
1501 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
1502 DE_NULL,
1503
1504 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1505 VK_ACCESS_TRANSFER_READ_BIT,
1506
1507 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1508 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1509
1510 VK_QUEUE_FAMILY_IGNORED,
1511 VK_QUEUE_FAMILY_IGNORED,
1512
1513 **m_dstSinglesampleImages[dstNdx],
1514 {
1515 VK_IMAGE_ASPECT_COLOR_BIT,
1516 0u,
1517 1u,
1518 0u,
1519 1u
1520 }
1521 };
1522
1523 barriers.push_back(barrier);
1524 }
1525
1526 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, (deUint32)barriers.size(), &barriers[0]);
1527 }
1528
1529 // Copy image memory to buffers
1530 for (size_t dstNdx = 0; dstNdx < m_dstSinglesampleImages.size(); dstNdx++)
1531 {
1532 const VkBufferImageCopy region =
1533 {
1534 0u,
1535 0u,
1536 0u,
1537 {
1538 VK_IMAGE_ASPECT_COLOR_BIT,
1539 0u,
1540 0u,
1541 1u,
1542 },
1543 { 0u, 0u, 0u },
1544 { m_width, m_height, 1u }
1545 };
1546
1547 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_dstSinglesampleImages[dstNdx], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_dstBuffers[dstNdx], 1u, ®ion);
1548 }
1549
1550 // Memory barriers between copies and host access
1551 {
1552 std::vector<VkBufferMemoryBarrier> barriers;
1553
1554 for (size_t dstNdx = 0; dstNdx < m_dstBuffers.size(); dstNdx++)
1555 {
1556 const VkBufferMemoryBarrier barrier =
1557 {
1558 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1559 DE_NULL,
1560
1561 VK_ACCESS_TRANSFER_WRITE_BIT,
1562 VK_ACCESS_HOST_READ_BIT,
1563
1564 VK_QUEUE_FAMILY_IGNORED,
1565 VK_QUEUE_FAMILY_IGNORED,
1566
1567 **m_dstBuffers[dstNdx],
1568 0u,
1569 VK_WHOLE_SIZE
1570 };
1571
1572 barriers.push_back(barrier);
1573 }
1574
1575 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, (deUint32)barriers.size(), &barriers[0], 0u, DE_NULL);
1576 }
1577
1578 VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
1579
1580 {
1581 const VkSubmitInfo submitInfo =
1582 {
1583 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1584 DE_NULL,
1585
1586 0u,
1587 DE_NULL,
1588 DE_NULL,
1589
1590 1u,
1591 &*commandBuffer,
1592
1593 0u,
1594 DE_NULL
1595 };
1596
1597 VK_CHECK(vkd.queueSubmit(m_context.getUniversalQueue(), 1u, &submitInfo, (VkFence)0u));
1598
1599 VK_CHECK(vkd.queueWaitIdle(m_context.getUniversalQueue()));
1600 }
1601
1602 {
1603 const tcu::TextureFormat format (mapVkFormat(m_dstFormat));
1604 const tcu::TextureFormat srcFormat (mapVkFormat(m_srcFormat));
1605 const bool hasDepth (tcu::hasDepthComponent(srcFormat.order));
1606 const bool hasStencil (tcu::hasStencilComponent(srcFormat.order));
1607
1608 for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
1609 {
1610 const std::string name ("Sample" + de::toString(sampleNdx));
1611 const void* const ptr (m_dstBufferMemory[sampleNdx]->getHostPtr());
1612 const tcu::ConstPixelBufferAccess access (format, m_width, m_height, 1, ptr);
1613 tcu::TextureLevel reference (format, m_width, m_height);
1614
1615 if (hasDepth || hasStencil)
1616 {
1617 if (hasDepth)
1618 {
1619 for (deUint32 y = 0; y < m_height; y++)
1620 for (deUint32 x = 0; x < m_width; x++)
1621 {
1622 const deUint32 x1 = x ^ sampleNdx;
1623 const deUint32 y1 = y ^ sampleNdx;
1624 const float range = 1.0f;
1625 float depth = 0.0f;
1626 deUint32 divider = 2;
1627
1628 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1629 for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
1630 {
1631 depth += (range / (float)divider)
1632 * (((bitNdx % 2 == 0 ? x1 : y1) & (0x1u << (bitNdx / 2u))) == 0u ? 0u : 1u);
1633 divider *= 2;
1634 }
1635
1636 reference.getAccess().setPixel(Vec4(depth, 0.0f, 0.0f, 0.0f), x, y);
1637 }
1638 }
1639 if (hasStencil)
1640 {
1641 for (deUint32 y = 0; y < m_height; y++)
1642 for (deUint32 x = 0; x < m_width; x++)
1643 {
1644 const deUint32 stencil = sampleNdx + 1u;
1645
1646 if (hasDepth)
1647 {
1648 const Vec4 src (reference.getAccess().getPixel(x, y));
1649
1650 reference.getAccess().setPixel(Vec4(src.x(), (float)stencil, 0.0f, 0.0f), x, y);
1651 }
1652 else
1653 reference.getAccess().setPixel(Vec4((float)stencil, 0.0f, 0.0f, 0.0f), x, y);
1654 }
1655 }
1656 {
1657 const Vec4 threshold (hasDepth ? (1.0f / 1024.0f) : 0.0f, 0.0f, 0.0f, 0.0f);
1658
1659 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1660 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1661 }
1662 }
1663 else
1664 {
1665 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1666
1667 switch (channelClass)
1668 {
1669 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1670 {
1671 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1672 const UVec4 minValue (0);
1673 const UVec4 range (UVec4(1u) << tcu::min(bits, UVec4(31)));
1674 const int componentCount (tcu::getNumUsedChannels(format.order));
1675 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1676
1677 for (deUint32 y = 0; y < m_height; y++)
1678 for (deUint32 x = 0; x < m_width; x++)
1679 {
1680 const deUint32 x1 = x ^ sampleNdx;
1681 const deUint32 y1 = y ^ sampleNdx;
1682 UVec4 color (minValue);
1683 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1684 deUint32 nextSrcBit = 0;
1685 deUint32 divider = 2;
1686
1687 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1688 while (nextSrcBit < de::min(bitSize, 10u))
1689 {
1690 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1691 {
1692 if (dstBitsUsed[compNdx] > bits[compNdx])
1693 continue;
1694
1695 color[compNdx] += (range[compNdx] / divider)
1696 * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1697
1698 nextSrcBit++;
1699 dstBitsUsed[compNdx]++;
1700 }
1701
1702 divider *= 2;
1703 }
1704
1705 reference.getAccess().setPixel(color, x, y);
1706 }
1707
1708 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
1709 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1710
1711 break;
1712 }
1713
1714 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1715 {
1716 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1717 const IVec4 minValue (0);
1718 const IVec4 range ((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
1719 const int componentCount (tcu::getNumUsedChannels(format.order));
1720 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1721
1722 for (deUint32 y = 0; y < m_height; y++)
1723 for (deUint32 x = 0; x < m_width; x++)
1724 {
1725 const deUint32 x1 = x ^ sampleNdx;
1726 const deUint32 y1 = y ^ sampleNdx;
1727 IVec4 color (minValue);
1728 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1729 deUint32 nextSrcBit = 0;
1730 deUint32 divider = 2;
1731
1732 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1733 while (nextSrcBit < de::min(bitSize, 10u))
1734 {
1735 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1736 {
1737 if (dstBitsUsed[compNdx] > bits[compNdx])
1738 continue;
1739
1740 color[compNdx] += (range[compNdx] / divider)
1741 * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1742
1743 nextSrcBit++;
1744 dstBitsUsed[compNdx]++;
1745 }
1746
1747 divider *= 2;
1748 }
1749
1750 reference.getAccess().setPixel(color, x, y);
1751 }
1752
1753 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
1754 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1755
1756 break;
1757 }
1758
1759 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1760 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1761 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1762 {
1763 const tcu::TextureFormatInfo info (tcu::getTextureFormatInfo(format));
1764 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1765 const Vec4 minLimit (-65536.0);
1766 const Vec4 maxLimit (65536.0);
1767 const Vec4 minValue (tcu::max(info.valueMin, minLimit));
1768 const Vec4 range (tcu::min(info.valueMax, maxLimit) - minValue);
1769 const int componentCount (tcu::getNumUsedChannels(format.order));
1770 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1771
1772 for (deUint32 y = 0; y < m_height; y++)
1773 for (deUint32 x = 0; x < m_width; x++)
1774 {
1775 const deUint32 x1 = x ^ sampleNdx;
1776 const deUint32 y1 = y ^ sampleNdx;
1777 Vec4 color (minValue);
1778 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1779 deUint32 nextSrcBit = 0;
1780 deUint32 divider = 2;
1781
1782 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1783 while (nextSrcBit < de::min(bitSize, 10u))
1784 {
1785 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1786 {
1787 if (dstBitsUsed[compNdx] > bits[compNdx])
1788 continue;
1789
1790 color[compNdx] += (range[compNdx] / (float)divider)
1791 * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1792
1793 nextSrcBit++;
1794 dstBitsUsed[compNdx]++;
1795 }
1796
1797 divider *= 2;
1798 }
1799
1800 if (tcu::isSRGB(format))
1801 reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
1802 else
1803 reference.getAccess().setPixel(color, x, y);
1804 }
1805
1806 if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
1807 {
1808 // Convert target format ulps to float ulps and allow 64ulp differences
1809 const UVec4 threshold (64u * (UVec4(1u) << (UVec4(23) - tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>())));
1810
1811 if (!tcu::floatUlpThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1812 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1813 }
1814 else
1815 {
1816 // Allow error of 4 times the minimum presentable difference
1817 const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());
1818
1819 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1820 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1821 }
1822
1823 break;
1824 }
1825
1826 default:
1827 DE_FATAL("Unknown channel class");
1828 }
1829 }
1830 }
1831 }
1832
1833 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1834 }
1835
1836 struct Programs
1837 {
initvkt::__anon7e6592500111::Programs1838 void init (vk::SourceCollections& dst, TestConfig config) const
1839 {
1840 const tcu::TextureFormat format (mapVkFormat(config.format));
1841 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1842
1843 dst.glslSources.add("quad-vert") << glu::VertexSource(
1844 "#version 450\n"
1845 "out gl_PerVertex {\n"
1846 "\tvec4 gl_Position;\n"
1847 "};\n"
1848 "highp float;\n"
1849 "void main (void) {\n"
1850 "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1851 "\t ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1852 "}\n");
1853
1854 if (tcu::hasDepthComponent(format.order))
1855 {
1856 const Vec4 minValue (0.0f);
1857 const Vec4 range (1.0f);
1858 std::ostringstream fragmentShader;
1859
1860 fragmentShader <<
1861 "#version 450\n"
1862 "layout(push_constant) uniform PushConstant {\n"
1863 "\thighp uint sampleIndex;\n"
1864 "} pushConstants;\n"
1865 "void main (void)\n"
1866 "{\n"
1867 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1868 "\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
1869 "\thighp float depth;\n"
1870 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1871 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1872
1873 fragmentShader << "\tdepth = " << minValue[0] << ";\n";
1874
1875 {
1876 deUint32 divider = 2;
1877
1878 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1879 for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
1880 {
1881 fragmentShader <<
1882 "\tdepth += " << (range[0] / (float)divider)
1883 << " * float(bitfieldExtract(" << (bitNdx % 2 == 0 ? "x" : "y") << ", " << (bitNdx / 2) << ", 1));\n";
1884
1885 divider *= 2;
1886 }
1887 }
1888
1889 fragmentShader <<
1890 "\tgl_FragDepth = depth;\n"
1891 "}\n";
1892
1893 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1894 }
1895 else if (tcu::hasStencilComponent(format.order))
1896 {
1897 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1898 "#version 450\n"
1899 "layout(push_constant) uniform PushConstant {\n"
1900 "\thighp uint sampleIndex;\n"
1901 "} pushConstants;\n"
1902 "void main (void)\n"
1903 "{\n"
1904 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1905 "\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
1906 "}\n");
1907 }
1908 else
1909 {
1910 switch (channelClass)
1911 {
1912 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1913 {
1914 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1915 const UVec4 minValue (0);
1916 const UVec4 range (UVec4(1u) << tcu::min(bits, UVec4(31)));
1917 std::ostringstream fragmentShader;
1918
1919 fragmentShader <<
1920 "#version 450\n"
1921 "layout(location = 0) out highp uvec4 o_color;\n"
1922 "layout(push_constant) uniform PushConstant {\n"
1923 "\thighp uint sampleIndex;\n"
1924 "} pushConstants;\n"
1925 "void main (void)\n"
1926 "{\n"
1927 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1928 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1929 "\thighp uint color[4];\n"
1930 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1931 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1932
1933 for (int ndx = 0; ndx < 4; ndx++)
1934 fragmentShader << "\tcolor[" << ndx << "] = " << minValue[ndx] << ";\n";
1935
1936 {
1937 const int componentCount = tcu::getNumUsedChannels(format.order);
1938 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1939 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1940 deUint32 nextSrcBit = 0;
1941 deUint32 divider = 2;
1942
1943 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1944 while (nextSrcBit < de::min(bitSize, 10u))
1945 {
1946 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1947 {
1948 if (dstBitsUsed[compNdx] > bits[compNdx])
1949 continue;
1950
1951 fragmentShader <<
1952 "\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
1953 << " * bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1);\n";
1954
1955 nextSrcBit++;
1956 dstBitsUsed[compNdx]++;
1957 }
1958
1959 divider *= 2;
1960 }
1961 }
1962
1963 fragmentShader <<
1964 "\to_color = uvec4(color[0], color[1], color[2], color[3]);\n"
1965 "}\n";
1966
1967 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1968 break;
1969 }
1970
1971 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1972 {
1973 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1974 const IVec4 minValue (0);
1975 const IVec4 range ((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
1976 std::ostringstream fragmentShader;
1977
1978 fragmentShader <<
1979 "#version 450\n"
1980 "layout(location = 0) out highp ivec4 o_color;\n"
1981 "layout(push_constant) uniform PushConstant {\n"
1982 "\thighp uint sampleIndex;\n"
1983 "} pushConstants;\n"
1984 "void main (void)\n"
1985 "{\n"
1986 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1987 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1988 "\thighp int color[4];\n"
1989 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1990 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1991
1992 for (int ndx = 0; ndx < 4; ndx++)
1993 fragmentShader << "\tcolor[" << ndx << "] = " << minValue[ndx] << ";\n";
1994
1995 {
1996 const int componentCount = tcu::getNumUsedChannels(format.order);
1997 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1998 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1999 deUint32 nextSrcBit = 0;
2000 deUint32 divider = 2;
2001
2002 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
2003 while (nextSrcBit < de::min(bitSize, 10u))
2004 {
2005 for (int compNdx = 0; compNdx < componentCount; compNdx++)
2006 {
2007 if (dstBitsUsed[compNdx] > bits[compNdx])
2008 continue;
2009
2010 fragmentShader <<
2011 "\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
2012 << " * int(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";
2013
2014 nextSrcBit++;
2015 dstBitsUsed[compNdx]++;
2016 }
2017
2018 divider *= 2;
2019 }
2020 }
2021
2022 fragmentShader <<
2023 "\to_color = ivec4(color[0], color[1], color[2], color[3]);\n"
2024 "}\n";
2025
2026 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
2027 break;
2028 }
2029
2030 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2031 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2032 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2033 {
2034 const tcu::TextureFormatInfo info (tcu::getTextureFormatInfo(format));
2035 const UVec4 bits (tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>());
2036 const Vec4 minLimit (-65536.0);
2037 const Vec4 maxLimit (65536.0);
2038 const Vec4 minValue (tcu::max(info.valueMin, minLimit));
2039 const Vec4 range (tcu::min(info.valueMax, maxLimit) - minValue);
2040 std::ostringstream fragmentShader;
2041
2042 fragmentShader <<
2043 "#version 450\n"
2044 "layout(location = 0) out highp vec4 o_color;\n"
2045 "layout(push_constant) uniform PushConstant {\n"
2046 "\thighp uint sampleIndex;\n"
2047 "} pushConstants;\n"
2048 "void main (void)\n"
2049 "{\n"
2050 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
2051 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
2052 "\thighp float color[4];\n"
2053 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
2054 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
2055
2056 for (int ndx = 0; ndx < 4; ndx++)
2057 fragmentShader << "\tcolor[" << ndx << "] = " << minValue[ndx] << ";\n";
2058
2059 {
2060 const int componentCount = tcu::getNumUsedChannels(format.order);
2061 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
2062 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
2063 deUint32 nextSrcBit = 0;
2064 deUint32 divider = 2;
2065
2066 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
2067 while (nextSrcBit < de::min(bitSize, 10u))
2068 {
2069 for (int compNdx = 0; compNdx < componentCount; compNdx++)
2070 {
2071 if (dstBitsUsed[compNdx] > bits[compNdx])
2072 continue;
2073
2074 fragmentShader <<
2075 "\tcolor[" << compNdx << "] += " << (range[compNdx] / (float)divider)
2076 << " * float(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";
2077
2078 nextSrcBit++;
2079 dstBitsUsed[compNdx]++;
2080 }
2081
2082 divider *= 2;
2083 }
2084 }
2085
2086 fragmentShader <<
2087 "\to_color = vec4(color[0], color[1], color[2], color[3]);\n"
2088 "}\n";
2089
2090 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
2091 break;
2092 }
2093
2094 default:
2095 DE_FATAL("Unknown channel class");
2096 }
2097 }
2098
2099 if (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
2100 {
2101 std::ostringstream splitShader;
2102
2103 splitShader <<
2104 "#version 450\n";
2105
2106 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
2107 {
2108 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n"
2109 << "layout(input_attachment_index = 0, set = 0, binding = 1) uniform highp usubpassInputMS i_stencil;\n";
2110 }
2111 else if (tcu::hasDepthComponent(format.order))
2112 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n";
2113 else if (tcu::hasStencilComponent(format.order))
2114 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp usubpassInputMS i_stencil;\n";
2115
2116 splitShader <<
2117 "layout(push_constant) uniform PushConstant {\n"
2118 "\thighp uint splitSubpassIndex;\n"
2119 "} pushConstants;\n";
2120
2121 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2122 {
2123 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
2124 splitShader << "layout(location = " << attachmentNdx << ") out highp vec2 o_color" << attachmentNdx << ";\n";
2125 else
2126 splitShader << "layout(location = " << attachmentNdx << ") out highp float o_color" << attachmentNdx << ";\n";
2127 }
2128
2129 splitShader <<
2130 "void main (void)\n"
2131 "{\n";
2132
2133 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2134 {
2135 if (tcu::hasDepthComponent(format.order))
2136 splitShader << "\thighp float depth" << attachmentNdx << " = subpassLoad(i_depth, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";
2137
2138 if (tcu::hasStencilComponent(format.order))
2139 splitShader << "\thighp uint stencil" << attachmentNdx << " = subpassLoad(i_stencil, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";
2140
2141 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
2142 splitShader << "\to_color" << attachmentNdx << " = vec2(depth" << attachmentNdx << ", float(stencil" << attachmentNdx << "));\n";
2143 else if (tcu::hasDepthComponent(format.order))
2144 splitShader << "\to_color" << attachmentNdx << " = float(depth" << attachmentNdx << ");\n";
2145 else if (tcu::hasStencilComponent(format.order))
2146 splitShader << "\to_color" << attachmentNdx << " = float(stencil" << attachmentNdx << ");\n";
2147 }
2148
2149 splitShader <<
2150 "}\n";
2151
2152 dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
2153 }
2154 else
2155 {
2156 std::string subpassType;
2157 std::string outputType;
2158
2159 switch (channelClass)
2160 {
2161 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2162 subpassType = "usubpassInputMS";
2163 outputType = "uvec4";
2164 break;
2165
2166 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2167 subpassType = "isubpassInputMS";
2168 outputType = "ivec4";
2169 break;
2170
2171 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2172 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2173 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2174 subpassType = "subpassInputMS";
2175 outputType = "vec4";
2176 break;
2177
2178 default:
2179 DE_FATAL("Unknown channel class");
2180 }
2181
2182 std::ostringstream splitShader;
2183 splitShader <<
2184 "#version 450\n"
2185 "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp " << subpassType << " i_color;\n"
2186 "layout(push_constant) uniform PushConstant {\n"
2187 "\thighp uint splitSubpassIndex;\n"
2188 "} pushConstants;\n";
2189
2190 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2191 splitShader << "layout(location = " << attachmentNdx << ") out highp " << outputType << " o_color" << attachmentNdx << ";\n";
2192
2193 splitShader <<
2194 "void main (void)\n"
2195 "{\n";
2196
2197 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2198 splitShader << "\to_color" << attachmentNdx << " = subpassLoad(i_color, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u));\n";
2199
2200 splitShader <<
2201 "}\n";
2202
2203 dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
2204 }
2205 }
2206 };
2207
formatToName(VkFormat format)2208 std::string formatToName (VkFormat format)
2209 {
2210 const std::string formatStr = de::toString(format);
2211 const std::string prefix = "VK_FORMAT_";
2212
2213 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
2214
2215 return de::toLower(formatStr.substr(prefix.length()));
2216 }
2217
initTests(tcu::TestCaseGroup * group)2218 void initTests (tcu::TestCaseGroup* group)
2219 {
2220 static const VkFormat formats[] =
2221 {
2222 VK_FORMAT_R5G6B5_UNORM_PACK16,
2223 VK_FORMAT_R8_UNORM,
2224 VK_FORMAT_R8_SNORM,
2225 VK_FORMAT_R8_UINT,
2226 VK_FORMAT_R8_SINT,
2227 VK_FORMAT_R8G8_UNORM,
2228 VK_FORMAT_R8G8_SNORM,
2229 VK_FORMAT_R8G8_UINT,
2230 VK_FORMAT_R8G8_SINT,
2231 VK_FORMAT_R8G8B8A8_UNORM,
2232 VK_FORMAT_R8G8B8A8_SNORM,
2233 VK_FORMAT_R8G8B8A8_UINT,
2234 VK_FORMAT_R8G8B8A8_SINT,
2235 VK_FORMAT_R8G8B8A8_SRGB,
2236 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
2237 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
2238 VK_FORMAT_A8B8G8R8_UINT_PACK32,
2239 VK_FORMAT_A8B8G8R8_SINT_PACK32,
2240 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
2241 VK_FORMAT_B8G8R8A8_UNORM,
2242 VK_FORMAT_B8G8R8A8_SRGB,
2243 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
2244 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
2245 VK_FORMAT_A2B10G10R10_UINT_PACK32,
2246 VK_FORMAT_R16_UNORM,
2247 VK_FORMAT_R16_SNORM,
2248 VK_FORMAT_R16_UINT,
2249 VK_FORMAT_R16_SINT,
2250 VK_FORMAT_R16_SFLOAT,
2251 VK_FORMAT_R16G16_UNORM,
2252 VK_FORMAT_R16G16_SNORM,
2253 VK_FORMAT_R16G16_UINT,
2254 VK_FORMAT_R16G16_SINT,
2255 VK_FORMAT_R16G16_SFLOAT,
2256 VK_FORMAT_R16G16B16A16_UNORM,
2257 VK_FORMAT_R16G16B16A16_SNORM,
2258 VK_FORMAT_R16G16B16A16_UINT,
2259 VK_FORMAT_R16G16B16A16_SINT,
2260 VK_FORMAT_R16G16B16A16_SFLOAT,
2261 VK_FORMAT_R32_UINT,
2262 VK_FORMAT_R32_SINT,
2263 VK_FORMAT_R32_SFLOAT,
2264 VK_FORMAT_R32G32_UINT,
2265 VK_FORMAT_R32G32_SINT,
2266 VK_FORMAT_R32G32_SFLOAT,
2267 VK_FORMAT_R32G32B32A32_UINT,
2268 VK_FORMAT_R32G32B32A32_SINT,
2269 VK_FORMAT_R32G32B32A32_SFLOAT,
2270
2271 VK_FORMAT_D16_UNORM,
2272 VK_FORMAT_X8_D24_UNORM_PACK32,
2273 VK_FORMAT_D32_SFLOAT,
2274 VK_FORMAT_S8_UINT,
2275 VK_FORMAT_D16_UNORM_S8_UINT,
2276 VK_FORMAT_D24_UNORM_S8_UINT,
2277 VK_FORMAT_D32_SFLOAT_S8_UINT
2278 };
2279 const deUint32 sampleCounts[] =
2280 {
2281 2u, 4u, 8u, 16u, 32u
2282 };
2283 tcu::TestContext& testCtx (group->getTestContext());
2284
2285 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
2286 {
2287 const VkFormat format (formats[formatNdx]);
2288 const std::string formatName (formatToName(format));
2289 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));
2290
2291 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
2292 {
2293 const deUint32 sampleCount (sampleCounts[sampleCountNdx]);
2294 const std::string testName ("samples_" + de::toString(sampleCount));
2295
2296 formatGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), TestConfig(format, sampleCount)));
2297 }
2298
2299 group->addChild(formatGroup.release());
2300 }
2301 }
2302
2303 } // anonymous
2304
createRenderPassMultisampleTests(tcu::TestContext & testCtx)2305 tcu::TestCaseGroup* createRenderPassMultisampleTests (tcu::TestContext& testCtx)
2306 {
2307 return createTestGroup(testCtx, "multisample", "Multisample render pass tests", initTests);
2308 }
2309
2310 } // vkt
2311