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::__anon72fea9d60111::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)1269 bool isExtensionSupported(Context& context, RenderingType renderingType, TestSeparateUsage separateStencilUsage)
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 return true;
1281 }
1282
1283
1284 class MultisampleRenderPassTestInstance : public TestInstance
1285 {
1286 public:
1287 MultisampleRenderPassTestInstance (Context& context, TestConfig config);
1288 ~MultisampleRenderPassTestInstance (void);
1289
1290 tcu::TestStatus iterate (void);
1291
1292 template<typename RenderpassSubpass>
1293 tcu::TestStatus iterateInternal (void);
1294
1295 private:
1296 const bool m_extensionSupported;
1297 const RenderingType m_renderingType;
1298 const TestSeparateUsage m_separateStencilUsage;
1299
1300 const VkFormat m_srcFormat;
1301 const VkFormat m_dstFormat;
1302 const deUint32 m_sampleCount;
1303 const deUint32 m_width;
1304 const deUint32 m_height;
1305
1306 const VkImageAspectFlags m_srcImageAspect;
1307 const VkImageUsageFlags m_srcImageUsage;
1308 const Unique<VkImage> m_srcImage;
1309 const de::UniquePtr<Allocation> m_srcImageMemory;
1310 const Unique<VkImageView> m_srcImageView;
1311 const Unique<VkImageView> m_srcPrimaryInputImageView;
1312 const Unique<VkImageView> m_srcSecondaryInputImageView;
1313
1314 const std::vector<VkImageSp> m_dstMultisampleImages;
1315 const std::vector<de::SharedPtr<Allocation> > m_dstMultisampleImageMemory;
1316 const std::vector<VkImageViewSp> m_dstMultisampleImageViews;
1317
1318 const std::vector<VkImageSp> m_dstSinglesampleImages;
1319 const std::vector<de::SharedPtr<Allocation> > m_dstSinglesampleImageMemory;
1320 const std::vector<VkImageViewSp> m_dstSinglesampleImageViews;
1321
1322 const std::vector<VkBufferSp> m_dstBuffers;
1323 const std::vector<de::SharedPtr<Allocation> > m_dstBufferMemory;
1324
1325 const Unique<VkRenderPass> m_renderPass;
1326 const Unique<VkFramebuffer> m_framebuffer;
1327
1328 const Unique<VkPipelineLayout> m_renderPipelineLayout;
1329 const Unique<VkPipeline> m_renderPipeline;
1330
1331 const Unique<VkDescriptorSetLayout> m_splitDescriptorSetLayout;
1332 const Unique<VkPipelineLayout> m_splitPipelineLayout;
1333 const std::vector<VkPipelineSp> m_splitPipelines;
1334 const Unique<VkDescriptorPool> m_splitDescriptorPool;
1335 const Unique<VkDescriptorSet> m_splitDescriptorSet;
1336
1337 const Unique<VkCommandPool> m_commandPool;
1338 tcu::ResultCollector m_resultCollector;
1339 };
1340
MultisampleRenderPassTestInstance(Context & context,TestConfig config)1341 MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
1342 : TestInstance (context)
1343 , m_extensionSupported (isExtensionSupported(context, config.renderingType, config.separateStencilUsage))
1344 , m_renderingType (config.renderingType)
1345 , m_separateStencilUsage (config.separateStencilUsage)
1346 , m_srcFormat (config.format)
1347 , m_dstFormat (getDstFormat(config.format, config.separateStencilUsage))
1348 , m_sampleCount (config.sampleCount)
1349 , m_width (32u)
1350 , m_height (32u)
1351
1352 , m_srcImageAspect (getImageAspectFlags(m_srcFormat))
1353 , m_srcImageUsage (getSrcImageUsage(m_srcFormat))
1354 , m_srcImage (createImage(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_srcFormat, sampleCountBitFromomSampleCount(m_sampleCount), m_srcImageUsage, m_width, m_height, m_separateStencilUsage))
1355 , m_srcImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_srcImage))
1356 , m_srcImageView (createImageAttachmentView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect))
1357 , m_srcPrimaryInputImageView (createSrcPrimaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect, m_separateStencilUsage))
1358 , m_srcSecondaryInputImageView (createSrcSecondaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect, m_separateStencilUsage))
1359
1360 , m_dstMultisampleImages (createMultisampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1361 , m_dstMultisampleImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstMultisampleImages))
1362 , m_dstMultisampleImageViews (createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstMultisampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))
1363
1364 , m_dstSinglesampleImages (createSingleSampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1365 , m_dstSinglesampleImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstSinglesampleImages))
1366 , m_dstSinglesampleImageViews (createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstSinglesampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))
1367
1368 , m_dstBuffers (createBuffers(context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1369 , m_dstBufferMemory (createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstBuffers))
1370
1371 , m_renderPass (createRenderPass(context.getDeviceInterface(), context.getDevice(), m_srcFormat, m_dstFormat, m_sampleCount, config.renderingType, m_separateStencilUsage))
1372 , m_framebuffer (createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_srcImageView, m_dstMultisampleImageViews, m_dstSinglesampleImageViews, m_width, m_height))
1373
1374 , m_renderPipelineLayout (createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
1375 , m_renderPipeline (createRenderPipeline(context.getDeviceInterface(), context.getDevice(), m_srcFormat, *m_renderPass, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
1376
1377 , m_splitDescriptorSetLayout (createSplitDescriptorSetLayout(context.getDeviceInterface(), context.getDevice(), m_srcFormat))
1378 , m_splitPipelineLayout (createSplitPipelineLayout(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorSetLayout))
1379 , m_splitPipelines (createSplitPipelines(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_splitPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
1380 , m_splitDescriptorPool (createSplitDescriptorPool(context.getDeviceInterface(), context.getDevice()))
1381 , m_splitDescriptorSet (createSplitDescriptorSet(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorPool, *m_splitDescriptorSetLayout, *m_srcPrimaryInputImageView, *m_srcSecondaryInputImageView))
1382 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
1383 {
1384 }
1385
~MultisampleRenderPassTestInstance(void)1386 MultisampleRenderPassTestInstance::~MultisampleRenderPassTestInstance (void)
1387 {
1388 }
1389
iterate(void)1390 tcu::TestStatus MultisampleRenderPassTestInstance::iterate (void)
1391 {
1392 switch (m_renderingType)
1393 {
1394 case RENDERING_TYPE_RENDERPASS_LEGACY:
1395 return iterateInternal<RenderpassSubpass1>();
1396 case RENDERING_TYPE_RENDERPASS2:
1397 return iterateInternal<RenderpassSubpass2>();
1398 default:
1399 TCU_THROW(InternalError, "Impossible");
1400 }
1401 }
1402
1403 template<typename RenderpassSubpass>
iterateInternal(void)1404 tcu::TestStatus MultisampleRenderPassTestInstance::iterateInternal (void)
1405 {
1406 const DeviceInterface& vkd (m_context.getDeviceInterface());
1407 const VkDevice device (m_context.getDevice());
1408 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1409 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1410 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL);
1411
1412 beginCommandBuffer(vkd, *commandBuffer);
1413
1414 {
1415 const VkRenderPassBeginInfo beginInfo =
1416 {
1417 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1418 DE_NULL,
1419
1420 *m_renderPass,
1421 *m_framebuffer,
1422
1423 {
1424 { 0u, 0u },
1425 { m_width, m_height }
1426 },
1427
1428 0u,
1429 DE_NULL
1430 };
1431 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
1432
1433 // Stencil needs to be cleared if it exists.
1434 if (tcu::hasStencilComponent(mapVkFormat(m_srcFormat).order))
1435 {
1436 const VkClearAttachment clearAttachment =
1437 {
1438 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
1439 0, // deUint32 colorAttachment;
1440 makeClearValueDepthStencil(0, 0) // VkClearValue clearValue;
1441 };
1442
1443 const VkClearRect clearRect =
1444 {
1445 {
1446 { 0u, 0u },
1447 { m_width, m_height }
1448 },
1449 0, // deUint32 baseArrayLayer;
1450 1 // deUint32 layerCount;
1451 };
1452
1453 vkd.cmdClearAttachments(*commandBuffer, 1, &clearAttachment, 1, &clearRect);
1454 }
1455 }
1456
1457 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
1458
1459 for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
1460 {
1461 vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(sampleNdx), &sampleNdx);
1462 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1463 }
1464
1465 for (deUint32 splitPipelineNdx = 0; splitPipelineNdx < m_splitPipelines.size(); splitPipelineNdx++)
1466 {
1467 RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
1468
1469 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_splitPipelines[splitPipelineNdx]);
1470 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_splitPipelineLayout, 0u, 1u, &*m_splitDescriptorSet, 0u, DE_NULL);
1471 vkd.cmdPushConstants(*commandBuffer, *m_splitPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(splitPipelineNdx), &splitPipelineNdx);
1472 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1473 }
1474
1475 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
1476
1477 for (size_t dstNdx = 0; dstNdx < m_dstSinglesampleImages.size(); dstNdx++)
1478 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);
1479
1480 endCommandBuffer(vkd, *commandBuffer);
1481
1482 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
1483
1484 {
1485 const tcu::TextureFormat format (mapVkFormat(m_dstFormat));
1486 const tcu::TextureFormat srcFormat (mapVkFormat(m_srcFormat));
1487 const bool verifyDepth (m_separateStencilUsage ? (m_separateStencilUsage == TEST_DEPTH) : tcu::hasDepthComponent(srcFormat.order));
1488 const bool verifyStencil (m_separateStencilUsage ? (m_separateStencilUsage == TEST_STENCIL) : tcu::hasStencilComponent(srcFormat.order));
1489
1490 for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
1491 {
1492 Allocation *dstBufMem = m_dstBufferMemory[sampleNdx].get();
1493 invalidateAlloc(vkd, device, *dstBufMem);
1494
1495 const std::string name ("Sample" + de::toString(sampleNdx));
1496 const void* const ptr (dstBufMem->getHostPtr());
1497 const tcu::ConstPixelBufferAccess access (format, m_width, m_height, 1, ptr);
1498 tcu::TextureLevel reference (format, m_width, m_height);
1499
1500 if (verifyDepth || verifyStencil)
1501 {
1502 if (verifyDepth)
1503 {
1504 for (deUint32 y = 0; y < m_height; y++)
1505 for (deUint32 x = 0; x < m_width; x++)
1506 {
1507 const deUint32 x1 = x ^ sampleNdx;
1508 const deUint32 y1 = y ^ sampleNdx;
1509 const float range = 1.0f;
1510 float depth = 0.0f;
1511 deUint32 divider = 2;
1512
1513 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1514 for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
1515 {
1516 depth += (range / (float)divider)
1517 * (((bitNdx % 2 == 0 ? x1 : y1) & (0x1u << (bitNdx / 2u))) == 0u ? 0u : 1u);
1518 divider *= 2;
1519 }
1520
1521 reference.getAccess().setPixel(Vec4(depth, 0.0f, 0.0f, 0.0f), x, y);
1522 }
1523 }
1524 if (verifyStencil)
1525 {
1526 for (deUint32 y = 0; y < m_height; y++)
1527 for (deUint32 x = 0; x < m_width; x++)
1528 {
1529 const deUint32 stencil = sampleNdx + 1u;
1530
1531 if (verifyDepth)
1532 {
1533 const Vec4 src (reference.getAccess().getPixel(x, y));
1534
1535 reference.getAccess().setPixel(Vec4(src.x(), (float)stencil, 0.0f, 0.0f), x, y);
1536 }
1537 else
1538 reference.getAccess().setPixel(Vec4((float)stencil, 0.0f, 0.0f, 0.0f), x, y);
1539 }
1540 }
1541 {
1542 const Vec4 threshold (verifyDepth ? (1.0f / 1024.0f) : 0.0f, 0.0f, 0.0f, 0.0f);
1543
1544 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1545 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1546 }
1547 }
1548 else
1549 {
1550 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1551
1552 switch (channelClass)
1553 {
1554 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1555 {
1556 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1557 const UVec4 minValue (0);
1558 const UVec4 range (UVec4(1u) << tcu::min(bits, UVec4(31)));
1559 const int componentCount (tcu::getNumUsedChannels(format.order));
1560 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1561
1562 for (deUint32 y = 0; y < m_height; y++)
1563 for (deUint32 x = 0; x < m_width; x++)
1564 {
1565 const deUint32 x1 = x ^ sampleNdx;
1566 const deUint32 y1 = y ^ sampleNdx;
1567 UVec4 color (minValue);
1568 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1569 deUint32 nextSrcBit = 0;
1570 deUint32 divider = 2;
1571
1572 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1573 while (nextSrcBit < de::min(bitSize, 10u))
1574 {
1575 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1576 {
1577 if (dstBitsUsed[compNdx] > bits[compNdx])
1578 continue;
1579
1580 color[compNdx] += (range[compNdx] / divider)
1581 * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1582
1583 nextSrcBit++;
1584 dstBitsUsed[compNdx]++;
1585 }
1586
1587 divider *= 2;
1588 }
1589
1590 reference.getAccess().setPixel(color, x, y);
1591 }
1592
1593 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
1594 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1595
1596 break;
1597 }
1598
1599 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1600 {
1601 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1602 const IVec4 minValue (0);
1603 const IVec4 range ((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
1604 const int componentCount (tcu::getNumUsedChannels(format.order));
1605 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1606
1607 for (deUint32 y = 0; y < m_height; y++)
1608 for (deUint32 x = 0; x < m_width; x++)
1609 {
1610 const deUint32 x1 = x ^ sampleNdx;
1611 const deUint32 y1 = y ^ sampleNdx;
1612 IVec4 color (minValue);
1613 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1614 deUint32 nextSrcBit = 0;
1615 deUint32 divider = 2;
1616
1617 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1618 while (nextSrcBit < de::min(bitSize, 10u))
1619 {
1620 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1621 {
1622 if (dstBitsUsed[compNdx] > bits[compNdx])
1623 continue;
1624
1625 color[compNdx] += (range[compNdx] / divider)
1626 * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1627
1628 nextSrcBit++;
1629 dstBitsUsed[compNdx]++;
1630 }
1631
1632 divider *= 2;
1633 }
1634
1635 reference.getAccess().setPixel(color, x, y);
1636 }
1637
1638 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
1639 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1640
1641 break;
1642 }
1643
1644 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1645 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1646 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1647 {
1648 const tcu::TextureFormatInfo info (tcu::getTextureFormatInfo(format));
1649 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1650 const Vec4 minLimit (-65536.0);
1651 const Vec4 maxLimit (65536.0);
1652 const Vec4 minValue (tcu::max(info.valueMin, minLimit));
1653 const Vec4 range (tcu::min(info.valueMax, maxLimit) - minValue);
1654 const int componentCount (tcu::getNumUsedChannels(format.order));
1655 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1656
1657 for (deUint32 y = 0; y < m_height; y++)
1658 for (deUint32 x = 0; x < m_width; x++)
1659 {
1660 const deUint32 x1 = x ^ sampleNdx;
1661 const deUint32 y1 = y ^ sampleNdx;
1662 Vec4 color (minValue);
1663 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1664 deUint32 nextSrcBit = 0;
1665 deUint32 divider = 2;
1666
1667 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1668 while (nextSrcBit < de::min(bitSize, 10u))
1669 {
1670 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1671 {
1672 if (dstBitsUsed[compNdx] > bits[compNdx])
1673 continue;
1674
1675 color[compNdx] += (range[compNdx] / (float)divider)
1676 * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1677
1678 nextSrcBit++;
1679 dstBitsUsed[compNdx]++;
1680 }
1681
1682 divider *= 2;
1683 }
1684
1685 if (tcu::isSRGB(format))
1686 reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
1687 else
1688 reference.getAccess().setPixel(color, x, y);
1689 }
1690
1691 if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
1692 {
1693 // Convert target format ulps to float ulps and allow 64ulp differences
1694 const UVec4 threshold (64u * (UVec4(1u) << (UVec4(23) - tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>())));
1695
1696 if (!tcu::floatUlpThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1697 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1698 }
1699 else
1700 {
1701 // Allow error of 4 times the minimum presentable difference
1702 const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());
1703
1704 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), 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
1708 break;
1709 }
1710
1711 default:
1712 DE_FATAL("Unknown channel class");
1713 }
1714 }
1715 }
1716 }
1717
1718 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1719 }
1720
1721 struct Programs
1722 {
initvkt::__anon72fea9d60111::Programs1723 void init (vk::SourceCollections& dst, TestConfig config) const
1724 {
1725 const tcu::TextureFormat format (mapVkFormat(config.format));
1726 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1727 const bool testDepth (config.separateStencilUsage ? (config.separateStencilUsage == TEST_DEPTH) : tcu::hasDepthComponent(format.order));
1728 const bool testStencil (config.separateStencilUsage ? (config.separateStencilUsage == TEST_STENCIL) : tcu::hasStencilComponent(format.order));
1729
1730 dst.glslSources.add("quad-vert") << glu::VertexSource(
1731 "#version 450\n"
1732 "out gl_PerVertex {\n"
1733 "\tvec4 gl_Position;\n"
1734 "};\n"
1735 "highp float;\n"
1736 "void main (void) {\n"
1737 "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1738 "\t ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1739 "}\n");
1740
1741 if (testDepth)
1742 {
1743 const Vec4 minValue (0.0f);
1744 const Vec4 range (1.0f);
1745 std::ostringstream fragmentShader;
1746
1747 fragmentShader <<
1748 "#version 450\n"
1749 "layout(push_constant) uniform PushConstant {\n"
1750 "\thighp uint sampleIndex;\n"
1751 "} pushConstants;\n"
1752 "void main (void)\n"
1753 "{\n"
1754 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1755 "\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
1756 "\thighp float depth;\n"
1757 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1758 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1759
1760 fragmentShader << "\tdepth = " << minValue[0] << ";\n";
1761
1762 {
1763 deUint32 divider = 2;
1764
1765 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1766 for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
1767 {
1768 fragmentShader <<
1769 "\tdepth += " << (range[0] / (float)divider)
1770 << " * float(bitfieldExtract(" << (bitNdx % 2 == 0 ? "x" : "y") << ", " << (bitNdx / 2) << ", 1));\n";
1771
1772 divider *= 2;
1773 }
1774 }
1775
1776 fragmentShader <<
1777 "\tgl_FragDepth = depth;\n"
1778 "}\n";
1779
1780 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1781 }
1782 else if (testStencil)
1783 {
1784 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1785 "#version 450\n"
1786 "layout(push_constant) uniform PushConstant {\n"
1787 "\thighp uint sampleIndex;\n"
1788 "} pushConstants;\n"
1789 "void main (void)\n"
1790 "{\n"
1791 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1792 "\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
1793 "}\n");
1794 }
1795 else
1796 {
1797 switch (channelClass)
1798 {
1799 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1800 {
1801 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1802 const UVec4 minValue (0);
1803 const UVec4 range (UVec4(1u) << tcu::min(bits, UVec4(31)));
1804 std::ostringstream fragmentShader;
1805
1806 fragmentShader <<
1807 "#version 450\n"
1808 "layout(location = 0) out highp uvec4 o_color;\n"
1809 "layout(push_constant) uniform PushConstant {\n"
1810 "\thighp uint sampleIndex;\n"
1811 "} pushConstants;\n"
1812 "void main (void)\n"
1813 "{\n"
1814 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1815 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1816 "\thighp uint color[4];\n"
1817 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1818 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1819
1820 for (int ndx = 0; ndx < 4; ndx++)
1821 fragmentShader << "\tcolor[" << ndx << "] = " << minValue[ndx] << ";\n";
1822
1823 {
1824 const int componentCount = tcu::getNumUsedChannels(format.order);
1825 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1826 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1827 deUint32 nextSrcBit = 0;
1828 deUint32 divider = 2;
1829
1830 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1831 while (nextSrcBit < de::min(bitSize, 10u))
1832 {
1833 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1834 {
1835 if (dstBitsUsed[compNdx] > bits[compNdx])
1836 continue;
1837
1838 fragmentShader <<
1839 "\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
1840 << " * bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1);\n";
1841
1842 nextSrcBit++;
1843 dstBitsUsed[compNdx]++;
1844 }
1845
1846 divider *= 2;
1847 }
1848 }
1849
1850 fragmentShader <<
1851 "\to_color = uvec4(color[0], color[1], color[2], color[3]);\n"
1852 "}\n";
1853
1854 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1855 break;
1856 }
1857
1858 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1859 {
1860 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1861 const IVec4 minValue (0);
1862 const IVec4 range ((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
1863 const IVec4 maxV ((UVec4(1u) << (bits - UVec4(1u))).cast<deInt32>());
1864 const IVec4 clampMax (maxV - 1);
1865 const IVec4 clampMin (-maxV);
1866 std::ostringstream fragmentShader;
1867
1868 fragmentShader <<
1869 "#version 450\n"
1870 "layout(location = 0) out highp ivec4 o_color;\n"
1871 "layout(push_constant) uniform PushConstant {\n"
1872 "\thighp uint sampleIndex;\n"
1873 "} pushConstants;\n"
1874 "void main (void)\n"
1875 "{\n"
1876 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1877 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1878 "\thighp int color[4];\n"
1879 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1880 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1881
1882 for (int ndx = 0; ndx < 4; ndx++)
1883 fragmentShader << "\tcolor[" << ndx << "] = " << minValue[ndx] << ";\n";
1884
1885 {
1886 const int componentCount = tcu::getNumUsedChannels(format.order);
1887 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1888 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1889 deUint32 nextSrcBit = 0;
1890 deUint32 divider = 2;
1891
1892 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1893 while (nextSrcBit < de::min(bitSize, 10u))
1894 {
1895 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1896 {
1897 if (dstBitsUsed[compNdx] > bits[compNdx])
1898 continue;
1899
1900 fragmentShader <<
1901 "\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
1902 << " * int(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";
1903
1904 nextSrcBit++;
1905 dstBitsUsed[compNdx]++;
1906 }
1907
1908 divider *= 2;
1909 }
1910 }
1911
1912 // The spec doesn't define whether signed-integers are clamped on output,
1913 // so we'll clamp them explicitly to have well-defined outputs.
1914 fragmentShader <<
1915 "\to_color = clamp(ivec4(color[0], color[1], color[2], color[3]), " <<
1916 "ivec4" << clampMin << ", ivec4" << clampMax << ");\n" <<
1917 "}\n";
1918
1919 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1920 break;
1921 }
1922
1923 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1924 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1925 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1926 {
1927 const tcu::TextureFormatInfo info (tcu::getTextureFormatInfo(format));
1928 const UVec4 bits (tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>());
1929 const Vec4 minLimit (-65536.0);
1930 const Vec4 maxLimit (65536.0);
1931 const Vec4 minValue (tcu::max(info.valueMin, minLimit));
1932 const Vec4 range (tcu::min(info.valueMax, maxLimit) - minValue);
1933 std::ostringstream fragmentShader;
1934
1935 fragmentShader <<
1936 "#version 450\n"
1937 "layout(location = 0) out highp vec4 o_color;\n"
1938 "layout(push_constant) uniform PushConstant {\n"
1939 "\thighp uint sampleIndex;\n"
1940 "} pushConstants;\n"
1941 "void main (void)\n"
1942 "{\n"
1943 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1944 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1945 "\thighp float color[4];\n"
1946 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1947 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1948
1949 for (int ndx = 0; ndx < 4; ndx++)
1950 fragmentShader << "\tcolor[" << ndx << "] = " << minValue[ndx] << ";\n";
1951
1952 {
1953 const int componentCount = tcu::getNumUsedChannels(format.order);
1954 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1955 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1956 deUint32 nextSrcBit = 0;
1957 deUint32 divider = 2;
1958
1959 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1960 while (nextSrcBit < de::min(bitSize, 10u))
1961 {
1962 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1963 {
1964 if (dstBitsUsed[compNdx] > bits[compNdx])
1965 continue;
1966
1967 fragmentShader <<
1968 "\tcolor[" << compNdx << "] += " << (range[compNdx] / (float)divider)
1969 << " * float(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";
1970
1971 nextSrcBit++;
1972 dstBitsUsed[compNdx]++;
1973 }
1974
1975 divider *= 2;
1976 }
1977 }
1978
1979 fragmentShader <<
1980 "\to_color = vec4(color[0], color[1], color[2], color[3]);\n"
1981 "}\n";
1982
1983 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1984 break;
1985 }
1986
1987 default:
1988 DE_FATAL("Unknown channel class");
1989 }
1990 }
1991
1992 if (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
1993 {
1994 std::ostringstream splitShader;
1995
1996 splitShader <<
1997 "#version 450\n";
1998
1999 if (testDepth && testStencil)
2000 {
2001 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n"
2002 << "layout(input_attachment_index = 0, set = 0, binding = 1) uniform highp usubpassInputMS i_stencil;\n";
2003 }
2004 else if (testDepth)
2005 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n";
2006 else if (testStencil)
2007 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp usubpassInputMS i_stencil;\n";
2008
2009 splitShader <<
2010 "layout(push_constant) uniform PushConstant {\n"
2011 "\thighp uint splitSubpassIndex;\n"
2012 "} pushConstants;\n";
2013
2014 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2015 {
2016 if (testDepth && testStencil)
2017 splitShader << "layout(location = " << attachmentNdx << ") out highp vec2 o_color" << attachmentNdx << ";\n";
2018 else
2019 splitShader << "layout(location = " << attachmentNdx << ") out highp float o_color" << attachmentNdx << ";\n";
2020 }
2021
2022 splitShader <<
2023 "void main (void)\n"
2024 "{\n";
2025
2026 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2027 {
2028 if (testDepth)
2029 splitShader << "\thighp float depth" << attachmentNdx << " = subpassLoad(i_depth, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";
2030
2031 if (testStencil)
2032 splitShader << "\thighp uint stencil" << attachmentNdx << " = subpassLoad(i_stencil, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";
2033
2034 if (testDepth && testStencil)
2035 splitShader << "\to_color" << attachmentNdx << " = vec2(depth" << attachmentNdx << ", float(stencil" << attachmentNdx << "));\n";
2036 else if (testDepth)
2037 splitShader << "\to_color" << attachmentNdx << " = float(depth" << attachmentNdx << ");\n";
2038 else if (testStencil)
2039 splitShader << "\to_color" << attachmentNdx << " = float(stencil" << attachmentNdx << ");\n";
2040 }
2041
2042 splitShader <<
2043 "}\n";
2044
2045 dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
2046 }
2047 else
2048 {
2049 std::string subpassType;
2050 std::string outputType;
2051
2052 switch (channelClass)
2053 {
2054 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2055 subpassType = "usubpassInputMS";
2056 outputType = "uvec4";
2057 break;
2058
2059 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2060 subpassType = "isubpassInputMS";
2061 outputType = "ivec4";
2062 break;
2063
2064 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2065 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2066 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2067 subpassType = "subpassInputMS";
2068 outputType = "vec4";
2069 break;
2070
2071 default:
2072 DE_FATAL("Unknown channel class");
2073 }
2074
2075 std::ostringstream splitShader;
2076 splitShader <<
2077 "#version 450\n"
2078 "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp " << subpassType << " i_color;\n"
2079 "layout(push_constant) uniform PushConstant {\n"
2080 "\thighp uint splitSubpassIndex;\n"
2081 "} pushConstants;\n";
2082
2083 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2084 splitShader << "layout(location = " << attachmentNdx << ") out highp " << outputType << " o_color" << attachmentNdx << ";\n";
2085
2086 splitShader <<
2087 "void main (void)\n"
2088 "{\n";
2089
2090 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2091 splitShader << "\to_color" << attachmentNdx << " = subpassLoad(i_color, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u));\n";
2092
2093 splitShader <<
2094 "}\n";
2095
2096 dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
2097 }
2098 }
2099 };
2100
formatToName(VkFormat format)2101 std::string formatToName (VkFormat format)
2102 {
2103 const std::string formatStr = de::toString(format);
2104 const std::string prefix = "VK_FORMAT_";
2105
2106 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
2107
2108 return de::toLower(formatStr.substr(prefix.length()));
2109 }
2110
initTests(tcu::TestCaseGroup * group,RenderingType renderingType)2111 void initTests (tcu::TestCaseGroup* group, RenderingType renderingType)
2112 {
2113 static const VkFormat formats[] =
2114 {
2115 VK_FORMAT_R5G6B5_UNORM_PACK16,
2116 VK_FORMAT_R8_UNORM,
2117 VK_FORMAT_R8_SNORM,
2118 VK_FORMAT_R8_UINT,
2119 VK_FORMAT_R8_SINT,
2120 VK_FORMAT_R8G8_UNORM,
2121 VK_FORMAT_R8G8_SNORM,
2122 VK_FORMAT_R8G8_UINT,
2123 VK_FORMAT_R8G8_SINT,
2124 VK_FORMAT_R8G8B8A8_UNORM,
2125 VK_FORMAT_R8G8B8A8_SNORM,
2126 VK_FORMAT_R8G8B8A8_UINT,
2127 VK_FORMAT_R8G8B8A8_SINT,
2128 VK_FORMAT_R8G8B8A8_SRGB,
2129 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
2130 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
2131 VK_FORMAT_A8B8G8R8_UINT_PACK32,
2132 VK_FORMAT_A8B8G8R8_SINT_PACK32,
2133 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
2134 VK_FORMAT_B8G8R8A8_UNORM,
2135 VK_FORMAT_B8G8R8A8_SRGB,
2136 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
2137 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
2138 VK_FORMAT_A2B10G10R10_UINT_PACK32,
2139 VK_FORMAT_R16_UNORM,
2140 VK_FORMAT_R16_SNORM,
2141 VK_FORMAT_R16_UINT,
2142 VK_FORMAT_R16_SINT,
2143 VK_FORMAT_R16_SFLOAT,
2144 VK_FORMAT_R16G16_UNORM,
2145 VK_FORMAT_R16G16_SNORM,
2146 VK_FORMAT_R16G16_UINT,
2147 VK_FORMAT_R16G16_SINT,
2148 VK_FORMAT_R16G16_SFLOAT,
2149 VK_FORMAT_R16G16B16A16_UNORM,
2150 VK_FORMAT_R16G16B16A16_SNORM,
2151 VK_FORMAT_R16G16B16A16_UINT,
2152 VK_FORMAT_R16G16B16A16_SINT,
2153 VK_FORMAT_R16G16B16A16_SFLOAT,
2154 VK_FORMAT_R32_UINT,
2155 VK_FORMAT_R32_SINT,
2156 VK_FORMAT_R32_SFLOAT,
2157 VK_FORMAT_R32G32_UINT,
2158 VK_FORMAT_R32G32_SINT,
2159 VK_FORMAT_R32G32_SFLOAT,
2160 VK_FORMAT_R32G32B32A32_UINT,
2161 VK_FORMAT_R32G32B32A32_SINT,
2162 VK_FORMAT_R32G32B32A32_SFLOAT,
2163 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
2164
2165 VK_FORMAT_D16_UNORM,
2166 VK_FORMAT_X8_D24_UNORM_PACK32,
2167 VK_FORMAT_D32_SFLOAT,
2168 VK_FORMAT_S8_UINT,
2169 VK_FORMAT_D16_UNORM_S8_UINT,
2170 VK_FORMAT_D24_UNORM_S8_UINT,
2171 VK_FORMAT_D32_SFLOAT_S8_UINT
2172 };
2173 const deUint32 sampleCounts[] =
2174 {
2175 2u, 4u, 8u, 16u, 32u
2176 };
2177 tcu::TestContext& testCtx (group->getTestContext());
2178 de::MovePtr<tcu::TestCaseGroup> extGroup (new tcu::TestCaseGroup(testCtx, "separate_stencil_usage", "test VK_EXT_separate_stencil_usage"));
2179
2180 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
2181 {
2182 const VkFormat format (formats[formatNdx]);
2183 const std::string formatName (formatToName(format));
2184 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));
2185 de::MovePtr<tcu::TestCaseGroup> extFormatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));
2186
2187 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
2188 {
2189 const deUint32 sampleCount (sampleCounts[sampleCountNdx]);
2190 const TestConfig testConfig (format, sampleCount, renderingType);
2191 const std::string testName ("samples_" + de::toString(sampleCount));
2192
2193 formatGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
2194
2195 // create tests for VK_EXT_separate_stencil_usage
2196 if (tcu::hasDepthComponent(mapVkFormat(format).order) && tcu::hasStencilComponent(mapVkFormat(format).order))
2197 {
2198 de::MovePtr<tcu::TestCaseGroup> sampleGroup (new tcu::TestCaseGroup(testCtx, testName.c_str(), testName.c_str()));
2199 {
2200 const TestConfig separateUsageDepthTestConfig (format, sampleCount, renderingType, TEST_DEPTH);
2201 sampleGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "test_depth", "depth with input attachment bit", separateUsageDepthTestConfig));
2202
2203 const TestConfig separateUsageStencilTestConfig (format, sampleCount, renderingType, TEST_STENCIL);
2204 sampleGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "test_stencil", "stencil with input attachment bit", separateUsageStencilTestConfig));
2205 }
2206
2207 extFormatGroup->addChild(sampleGroup.release());
2208 }
2209 }
2210
2211 group->addChild(formatGroup.release());
2212 extGroup->addChild(extFormatGroup.release());
2213 }
2214
2215 group->addChild(extGroup.release());
2216 }
2217
2218 } // anonymous
2219
createRenderPassMultisampleTests(tcu::TestContext & testCtx)2220 tcu::TestCaseGroup* createRenderPassMultisampleTests (tcu::TestContext& testCtx)
2221 {
2222 return createTestGroup(testCtx, "multisample", "Multisample render pass tests", initTests, RENDERING_TYPE_RENDERPASS_LEGACY);
2223 }
2224
createRenderPass2MultisampleTests(tcu::TestContext & testCtx)2225 tcu::TestCaseGroup* createRenderPass2MultisampleTests (tcu::TestContext& testCtx)
2226 {
2227 return createTestGroup(testCtx, "multisample", "Multisample render pass tests", initTests, RENDERING_TYPE_RENDERPASS2);
2228 }
2229
2230 } // vkt
2231