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