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