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 pass multisample resolve
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktRenderPassMultisampleResolveTests.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::Vec3;
64 using tcu::Vec4;
65
66 using tcu::Maybe;
67 using tcu::just;
68 using tcu::nothing;
69
70 using tcu::ConstPixelBufferAccess;
71 using tcu::PixelBufferAccess;
72
73 using tcu::TestLog;
74
75 using std::pair;
76 using std::string;
77 using std::vector;
78
79 typedef de::SharedPtr<vk::Unique<VkImage> > VkImageSp;
80 typedef de::SharedPtr<vk::Unique<VkImageView> > VkImageViewSp;
81 typedef de::SharedPtr<vk::Unique<VkBuffer> > VkBufferSp;
82 typedef de::SharedPtr<vk::Unique<VkPipeline> > VkPipelineSp;
83
84 namespace vkt
85 {
86 namespace
87 {
88
89 using namespace renderpass;
90
91 enum
92 {
93 MAX_COLOR_ATTACHMENT_COUNT = 4u
94 };
95
96 template<typename T>
safeSharedPtr(T * ptr)97 de::SharedPtr<T> safeSharedPtr (T* ptr)
98 {
99 try
100 {
101 return de::SharedPtr<T>(ptr);
102 }
103 catch (...)
104 {
105 delete ptr;
106 throw;
107 }
108 }
109
getFormatThreshold(VkFormat format)110 tcu::Vec4 getFormatThreshold (VkFormat format)
111 {
112 const tcu::TextureFormat tcuFormat (mapVkFormat(format));
113 const deUint32 componentCount (tcu::getNumUsedChannels(tcuFormat.order));
114
115 if (isSnormFormat(format))
116 {
117 return Vec4((componentCount >= 1) ? 1.5f * getRepresentableDiffSnorm(format, 0) : 0.0f,
118 (componentCount >= 2) ? 1.5f * getRepresentableDiffSnorm(format, 1) : 0.0f,
119 (componentCount >= 3) ? 1.5f * getRepresentableDiffSnorm(format, 2) : 0.0f,
120 (componentCount == 4) ? 1.5f * getRepresentableDiffSnorm(format, 3) : 0.0f);
121 }
122 else if (isUnormFormat(format))
123 {
124 return Vec4((componentCount >= 1) ? 1.5f * getRepresentableDiffUnorm(format, 0) : 0.0f,
125 (componentCount >= 2) ? 1.5f * getRepresentableDiffUnorm(format, 1) : 0.0f,
126 (componentCount >= 3) ? 1.5f * getRepresentableDiffUnorm(format, 2) : 0.0f,
127 (componentCount == 4) ? 1.5f * getRepresentableDiffUnorm(format, 3) : 0.0f);
128 }
129 else if (isFloatFormat(format))
130 return Vec4(0.00001f);
131 else
132 return Vec4(0.001f);
133 }
134
bindBufferMemory(const DeviceInterface & vk,VkDevice device,VkBuffer buffer,VkDeviceMemory mem,VkDeviceSize memOffset)135 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
136 {
137 VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
138 }
139
bindImageMemory(const DeviceInterface & vk,VkDevice device,VkImage image,VkDeviceMemory mem,VkDeviceSize memOffset)140 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
141 {
142 VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
143 }
144
createBufferMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkBuffer buffer)145 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface& vk,
146 VkDevice device,
147 Allocator& allocator,
148 VkBuffer buffer)
149 {
150 de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
151 bindBufferMemory(vk, device, buffer, allocation->getMemory(), allocation->getOffset());
152 return allocation;
153 }
154
createImageMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkImage image)155 de::MovePtr<Allocation> createImageMemory (const DeviceInterface& vk,
156 VkDevice device,
157 Allocator& allocator,
158 VkImage image)
159 {
160 de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), MemoryRequirement::Any));
161 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
162 return allocation;
163 }
164
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)165 Move<VkImage> createImage (const DeviceInterface& vk,
166 VkDevice device,
167 VkImageCreateFlags flags,
168 VkImageType imageType,
169 VkFormat format,
170 VkExtent3D extent,
171 deUint32 mipLevels,
172 deUint32 arrayLayers,
173 VkSampleCountFlagBits samples,
174 VkImageTiling tiling,
175 VkImageUsageFlags usage,
176 VkSharingMode sharingMode,
177 deUint32 queueFamilyCount,
178 const deUint32* pQueueFamilyIndices,
179 VkImageLayout initialLayout)
180 {
181 const VkImageCreateInfo pCreateInfo =
182 {
183 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
184 DE_NULL,
185 flags,
186 imageType,
187 format,
188 extent,
189 mipLevels,
190 arrayLayers,
191 samples,
192 tiling,
193 usage,
194 sharingMode,
195 queueFamilyCount,
196 pQueueFamilyIndices,
197 initialLayout
198 };
199 return createImage(vk, device, &pCreateInfo);
200 }
201
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags flags,VkImage image,VkImageViewType viewType,VkFormat format,VkComponentMapping components,VkImageSubresourceRange subresourceRange)202 Move<VkImageView> createImageView (const DeviceInterface& vk,
203 VkDevice device,
204 VkImageViewCreateFlags flags,
205 VkImage image,
206 VkImageViewType viewType,
207 VkFormat format,
208 VkComponentMapping components,
209 VkImageSubresourceRange subresourceRange)
210 {
211 const VkImageViewCreateInfo pCreateInfo =
212 {
213 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
214 DE_NULL,
215 flags,
216 image,
217 viewType,
218 format,
219 components,
220 subresourceRange,
221 };
222 return createImageView(vk, device, &pCreateInfo);
223 }
224
createImage(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const DeviceInterface & vkd,VkDevice device,VkFormat vkFormat,VkSampleCountFlagBits sampleCountBit,VkImageUsageFlags usage,deUint32 width,deUint32 height,deUint32 layerCount)225 Move<VkImage> createImage (const InstanceInterface& vki,
226 VkPhysicalDevice physicalDevice,
227 const DeviceInterface& vkd,
228 VkDevice device,
229 VkFormat vkFormat,
230 VkSampleCountFlagBits sampleCountBit,
231 VkImageUsageFlags usage,
232 deUint32 width,
233 deUint32 height,
234 deUint32 layerCount)
235 {
236 try
237 {
238 const tcu::TextureFormat format (mapVkFormat(vkFormat));
239 const VkImageType imageType (VK_IMAGE_TYPE_2D);
240 const VkImageTiling imageTiling (VK_IMAGE_TILING_OPTIMAL);
241 const VkFormatProperties formatProperties (getPhysicalDeviceFormatProperties(vki, physicalDevice, vkFormat));
242 const VkImageFormatProperties imageFormatProperties (getPhysicalDeviceImageFormatProperties(vki, physicalDevice, vkFormat, imageType, imageTiling, usage, 0u));
243 const VkExtent3D imageExtent =
244 {
245 width,
246 height,
247 1u
248 };
249
250 if ((tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
251 && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)
252 TCU_THROW(NotSupportedError, "Format can't be used as depth stencil attachment");
253
254 if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
255 && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
256 TCU_THROW(NotSupportedError, "Format can't be used as color attachment");
257
258 if (imageFormatProperties.maxExtent.width < imageExtent.width
259 || imageFormatProperties.maxExtent.height < imageExtent.height
260 || ((imageFormatProperties.sampleCounts & sampleCountBit) == 0)
261 || imageFormatProperties.maxArrayLayers < layerCount)
262 {
263 TCU_THROW(NotSupportedError, "Image type not supported");
264 }
265
266 return createImage(vkd, device, 0u, imageType, vkFormat, imageExtent, 1u, layerCount, sampleCountBit, imageTiling, usage, VK_SHARING_MODE_EXCLUSIVE, 0u, DE_NULL, VK_IMAGE_LAYOUT_UNDEFINED);
267 }
268 catch (const vk::Error& error)
269 {
270 if (error.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
271 TCU_THROW(NotSupportedError, "Image format not supported");
272
273 throw;
274 }
275 }
276
createImageView(const DeviceInterface & vkd,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect,deUint32 layerCount)277 Move<VkImageView> createImageView (const DeviceInterface& vkd,
278 VkDevice device,
279 VkImage image,
280 VkFormat format,
281 VkImageAspectFlags aspect,
282 deUint32 layerCount)
283 {
284 const VkImageSubresourceRange range =
285 {
286 aspect,
287 0u,
288 1u,
289 0u,
290 layerCount
291 };
292
293 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, format, makeComponentMappingRGBA(), range);
294 }
295
getPixelSize(VkFormat vkFormat)296 VkDeviceSize getPixelSize (VkFormat vkFormat)
297 {
298 const tcu::TextureFormat format (mapVkFormat(vkFormat));
299
300 return format.getPixelSize();
301 }
302
createBuffer(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 width,deUint32 height,deUint32 layerCount)303 Move<VkBuffer> createBuffer (const DeviceInterface& vkd,
304 VkDevice device,
305 VkFormat format,
306 deUint32 width,
307 deUint32 height,
308 deUint32 layerCount)
309 {
310 const VkBufferUsageFlags bufferUsage (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
311 const VkDeviceSize pixelSize (getPixelSize(format));
312 const VkBufferCreateInfo createInfo =
313 {
314 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
315 DE_NULL,
316 0u,
317
318 width * height * layerCount * pixelSize,
319 bufferUsage,
320
321 VK_SHARING_MODE_EXCLUSIVE,
322 0u,
323 DE_NULL
324 };
325 return createBuffer(vkd, device, &createInfo);
326 }
327
sampleCountBitFromSampleCount(deUint32 count)328 VkSampleCountFlagBits sampleCountBitFromSampleCount (deUint32 count)
329 {
330 switch (count)
331 {
332 case 1: return VK_SAMPLE_COUNT_1_BIT;
333 case 2: return VK_SAMPLE_COUNT_2_BIT;
334 case 4: return VK_SAMPLE_COUNT_4_BIT;
335 case 8: return VK_SAMPLE_COUNT_8_BIT;
336 case 16: return VK_SAMPLE_COUNT_16_BIT;
337 case 32: return VK_SAMPLE_COUNT_32_BIT;
338 case 64: return VK_SAMPLE_COUNT_64_BIT;
339
340 default:
341 DE_FATAL("Invalid sample count");
342 return (VkSampleCountFlagBits)0x0;
343 }
344 }
345
createMultisampleImages(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 sampleCount,deUint32 width,deUint32 height,deUint32 layerCount)346 std::vector<VkImageSp> createMultisampleImages (const InstanceInterface& vki,
347 VkPhysicalDevice physicalDevice,
348 const DeviceInterface& vkd,
349 VkDevice device,
350 VkFormat format,
351 deUint32 sampleCount,
352 deUint32 width,
353 deUint32 height,
354 deUint32 layerCount)
355 {
356 std::vector<VkImageSp> images (MAX_COLOR_ATTACHMENT_COUNT);
357
358 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
359 images[imageNdx] = safeSharedPtr(new Unique<VkImage>(createImage(vki, physicalDevice, vkd, device, format, sampleCountBitFromSampleCount(sampleCount), VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, width, height, layerCount)));
360
361 return images;
362 }
363
createSingleSampleImages(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 width,deUint32 height,deUint32 layerCount)364 std::vector<VkImageSp> createSingleSampleImages (const InstanceInterface& vki,
365 VkPhysicalDevice physicalDevice,
366 const DeviceInterface& vkd,
367 VkDevice device,
368 VkFormat format,
369 deUint32 width,
370 deUint32 height,
371 deUint32 layerCount)
372 {
373 std::vector<VkImageSp> images (MAX_COLOR_ATTACHMENT_COUNT);
374
375 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
376 images[imageNdx] = safeSharedPtr(new 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, layerCount)));
377
378 return images;
379 }
380
createImageMemory(const DeviceInterface & vkd,VkDevice device,Allocator & allocator,const std::vector<VkImageSp> images)381 std::vector<de::SharedPtr<Allocation> > createImageMemory (const DeviceInterface& vkd,
382 VkDevice device,
383 Allocator& allocator,
384 const std::vector<VkImageSp> images)
385 {
386 std::vector<de::SharedPtr<Allocation> > memory (images.size());
387
388 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
389 memory[memoryNdx] = safeSharedPtr(createImageMemory(vkd, device, allocator, **images[memoryNdx]).release());
390
391 return memory;
392 }
393
createImageViews(const DeviceInterface & vkd,VkDevice device,const std::vector<VkImageSp> & images,VkFormat format,VkImageAspectFlagBits aspect,deUint32 layerCount)394 std::vector<VkImageViewSp> createImageViews (const DeviceInterface& vkd,
395 VkDevice device,
396 const std::vector<VkImageSp>& images,
397 VkFormat format,
398 VkImageAspectFlagBits aspect,
399 deUint32 layerCount)
400 {
401 std::vector<VkImageViewSp> views (images.size());
402
403 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
404 views[imageNdx] = safeSharedPtr(new Unique<VkImageView>(createImageView(vkd, device, **images[imageNdx], format, aspect, layerCount)));
405
406 return views;
407 }
408
createBuffers(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 width,deUint32 height,deUint32 layerCount)409 std::vector<VkBufferSp> createBuffers (const DeviceInterface& vkd,
410 VkDevice device,
411 VkFormat format,
412 deUint32 width,
413 deUint32 height,
414 deUint32 layerCount)
415 {
416 std::vector<VkBufferSp> buffers (MAX_COLOR_ATTACHMENT_COUNT);
417
418 for (size_t bufferNdx = 0; bufferNdx < buffers.size(); bufferNdx++)
419 buffers[bufferNdx] = safeSharedPtr(new Unique<VkBuffer>(createBuffer(vkd, device, format, width, height, layerCount)));
420
421 return buffers;
422 }
423
createBufferMemory(const DeviceInterface & vkd,VkDevice device,Allocator & allocator,const std::vector<VkBufferSp> buffers)424 std::vector<de::SharedPtr<Allocation> > createBufferMemory (const DeviceInterface& vkd,
425 VkDevice device,
426 Allocator& allocator,
427 const std::vector<VkBufferSp> buffers)
428 {
429 std::vector<de::SharedPtr<Allocation> > memory (buffers.size());
430
431 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
432 memory[memoryNdx] = safeSharedPtr(createBufferMemory(vkd, device, allocator, **buffers[memoryNdx]).release());
433
434 return memory;
435 }
436
437 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 sampleCount)438 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
439 VkDevice device,
440 VkFormat format,
441 deUint32 sampleCount)
442 {
443 const VkSampleCountFlagBits samples (sampleCountBitFromSampleCount(sampleCount));
444 std::vector<AttachmentDesc> attachments;
445 std::vector<AttachmentRef> colorAttachmentRefs;
446 std::vector<AttachmentRef> resolveAttachmentRefs;
447
448 for (size_t attachmentNdx = 0; attachmentNdx < 4; attachmentNdx++)
449 {
450 {
451 const AttachmentDesc multisampleAttachment // VkAttachmentDescription || VkAttachmentDescription2KHR
452 (
453 // || VkStructureType sType;
454 DE_NULL, // || const void* pNext;
455 0u, // VkAttachmentDescriptionFlags flags; || VkAttachmentDescriptionFlags flags;
456 format, // VkFormat format; || VkFormat format;
457 samples, // VkSampleCountFlagBits samples; || VkSampleCountFlagBits samples;
458 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; || VkAttachmentLoadOp loadOp;
459 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp; || VkAttachmentStoreOp storeOp;
460 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; || VkAttachmentLoadOp stencilLoadOp;
461 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; || VkAttachmentStoreOp stencilStoreOp;
462 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; || VkImageLayout initialLayout;
463 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; || VkImageLayout finalLayout;
464 );
465 const AttachmentRef attachmentRef // VkAttachmentReference || VkAttachmentReference2KHR
466 (
467 // || VkStructureType sType;
468 DE_NULL, // || const void* pNext;
469 (deUint32)attachments.size(), // deUint32 attachment; || deUint32 attachment;
470 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout; || VkImageLayout layout;
471 0u // || VkImageAspectFlags aspectMask;
472 );
473 colorAttachmentRefs.push_back(attachmentRef);
474 attachments.push_back(multisampleAttachment);
475 }
476 {
477 const AttachmentDesc singlesampleAttachment // VkAttachmentDescription || VkAttachmentDescription2KHR
478 (
479 // || VkStructureType sType;
480 DE_NULL, // || const void* pNext;
481 0u, // VkAttachmentDescriptionFlags flags; || VkAttachmentDescriptionFlags flags;
482 format, // VkFormat format; || VkFormat format;
483 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; || VkSampleCountFlagBits samples;
484 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; || VkAttachmentLoadOp loadOp;
485 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; || VkAttachmentStoreOp storeOp;
486 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; || VkAttachmentLoadOp stencilLoadOp;
487 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; || VkAttachmentStoreOp stencilStoreOp;
488 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; || VkImageLayout initialLayout;
489 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL // VkImageLayout finalLayout; || VkImageLayout finalLayout;
490 );
491 const AttachmentRef attachmentRef // VkAttachmentReference || VkAttachmentReference2KHR
492 (
493 // || VkStructureType sType;
494 DE_NULL, // || const void* pNext;
495 (deUint32)attachments.size(), // deUint32 attachment; || deUint32 attachment;
496 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout; || VkImageLayout layout;
497 0u // || VkImageAspectFlags aspectMask;
498 );
499 resolveAttachmentRefs.push_back(attachmentRef);
500 attachments.push_back(singlesampleAttachment);
501 }
502 }
503
504 DE_ASSERT(colorAttachmentRefs.size() == resolveAttachmentRefs.size());
505 DE_ASSERT(attachments.size() == colorAttachmentRefs.size() + resolveAttachmentRefs.size());
506
507 {
508 const SubpassDesc subpass // VkSubpassDescription || VkSubpassDescription2KHR
509 (
510 // || VkStructureType sType;
511 DE_NULL, // || const void* pNext;
512 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; || VkSubpassDescriptionFlags flags;
513 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; || VkPipelineBindPoint pipelineBindPoint;
514 0u, // || deUint32 viewMask;
515 0u, // deUint32 inputAttachmentCount; || deUint32 inputAttachmentCount;
516 DE_NULL, // const VkAttachmentReference* pInputAttachments; || const VkAttachmentReference2KHR* pInputAttachments;
517 (deUint32)colorAttachmentRefs.size(), // deUint32 colorAttachmentCount; || deUint32 colorAttachmentCount;
518 &colorAttachmentRefs[0], // const VkAttachmentReference* pColorAttachments; || const VkAttachmentReference2KHR* pColorAttachments;
519 &resolveAttachmentRefs[0], // const VkAttachmentReference* pResolveAttachments; || const VkAttachmentReference2KHR* pResolveAttachments;
520 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; || const VkAttachmentReference2KHR* pDepthStencilAttachment;
521 0u, // deUint32 preserveAttachmentCount; || deUint32 preserveAttachmentCount;
522 DE_NULL // const deUint32* pPreserveAttachments; || const deUint32* pPreserveAttachments;
523 );
524 const RenderPassCreateInfo renderPassCreator // VkRenderPassCreateInfo || VkRenderPassCreateInfo2KHR
525 (
526 // VkStructureType sType; || VkStructureType sType;
527 DE_NULL, // const void* pNext; || const void* pNext;
528 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags; || VkRenderPassCreateFlags flags;
529 (deUint32)attachments.size(), // deUint32 attachmentCount; || deUint32 attachmentCount;
530 &attachments[0], // const VkAttachmentDescription* pAttachments; || const VkAttachmentDescription2KHR* pAttachments;
531 1u, // deUint32 subpassCount; || deUint32 subpassCount;
532 &subpass, // const VkSubpassDescription* pSubpasses; || const VkSubpassDescription2KHR* pSubpasses;
533 0u, // deUint32 dependencyCount; || deUint32 dependencyCount;
534 DE_NULL, // const VkSubpassDependency* pDependencies; || const VkSubpassDependency2KHR* pDependencies;
535 0u, // || deUint32 correlatedViewMaskCount;
536 DE_NULL // || const deUint32* pCorrelatedViewMasks;
537 );
538
539 return renderPassCreator.createRenderPass(vkd, device);
540 }
541 }
542
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 sampleCount,const RenderPassType renderPassType)543 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
544 VkDevice device,
545 VkFormat format,
546 deUint32 sampleCount,
547 const RenderPassType renderPassType)
548 {
549 switch (renderPassType)
550 {
551 case RENDERPASS_TYPE_LEGACY:
552 return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vkd, device, format, sampleCount);
553 case RENDERPASS_TYPE_RENDERPASS2:
554 return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vkd, device, format, sampleCount);
555 default:
556 TCU_THROW(InternalError, "Impossible");
557 }
558 }
559
createFramebuffer(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,const std::vector<VkImageViewSp> & multisampleImageViews,const std::vector<VkImageViewSp> & singlesampleImageViews,deUint32 width,deUint32 height,deUint32 layerCount)560 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vkd,
561 VkDevice device,
562 VkRenderPass renderPass,
563 const std::vector<VkImageViewSp>& multisampleImageViews,
564 const std::vector<VkImageViewSp>& singlesampleImageViews,
565 deUint32 width,
566 deUint32 height,
567 deUint32 layerCount)
568 {
569 std::vector<VkImageView> attachments;
570
571 attachments.reserve(multisampleImageViews.size() + singlesampleImageViews.size());
572
573 DE_ASSERT(multisampleImageViews.size() == singlesampleImageViews.size());
574
575 for (size_t ndx = 0; ndx < multisampleImageViews.size(); ndx++)
576 {
577 attachments.push_back(**multisampleImageViews[ndx]);
578 attachments.push_back(**singlesampleImageViews[ndx]);
579 }
580
581 const VkFramebufferCreateInfo createInfo =
582 {
583 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
584 DE_NULL,
585 0u,
586
587 renderPass,
588 (deUint32)attachments.size(),
589 &attachments[0],
590
591 width,
592 height,
593 layerCount
594 };
595
596 return createFramebuffer(vkd, device, &createInfo);
597 }
598
createRenderPipelineLayout(const DeviceInterface & vkd,VkDevice device)599 Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface& vkd,
600 VkDevice device)
601 {
602 const VkPushConstantRange pushConstant =
603 {
604 VK_SHADER_STAGE_FRAGMENT_BIT,
605 0u,
606 4u
607 };
608 const VkPipelineLayoutCreateInfo createInfo =
609 {
610 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
611 DE_NULL,
612 (vk::VkPipelineLayoutCreateFlags)0,
613
614 0u,
615 DE_NULL,
616
617 1u,
618 &pushConstant
619 };
620
621 return createPipelineLayout(vkd, device, &createInfo);
622 }
623
createRenderPipeline(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkPipelineLayout pipelineLayout,const vk::BinaryCollection & binaryCollection,deUint32 width,deUint32 height,deUint32 sampleCount,deUint32 layerCount)624 Move<VkPipeline> createRenderPipeline (const DeviceInterface& vkd,
625 VkDevice device,
626 VkRenderPass renderPass,
627 VkPipelineLayout pipelineLayout,
628 const vk::BinaryCollection& binaryCollection,
629 deUint32 width,
630 deUint32 height,
631 deUint32 sampleCount,
632 deUint32 layerCount)
633 {
634 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
635 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
636 const Move<VkShaderModule> geometryShaderModule (layerCount == 1 ? Move<VkShaderModule>() : createShaderModule(vkd, device, binaryCollection.get("geom"), 0u));
637 // Disable blending
638 const VkPipelineColorBlendAttachmentState attachmentBlendState =
639 {
640 VK_FALSE,
641 VK_BLEND_FACTOR_SRC_ALPHA,
642 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
643 VK_BLEND_OP_ADD,
644 VK_BLEND_FACTOR_ONE,
645 VK_BLEND_FACTOR_ONE,
646 VK_BLEND_OP_ADD,
647 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
648 };
649 const VkPipelineColorBlendAttachmentState attachmentBlendStates[] =
650 {
651 attachmentBlendState,
652 attachmentBlendState,
653 attachmentBlendState,
654 attachmentBlendState,
655 };
656 const VkPipelineVertexInputStateCreateInfo vertexInputState =
657 {
658 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
659 DE_NULL,
660 (VkPipelineVertexInputStateCreateFlags)0u,
661
662 0u,
663 DE_NULL,
664
665 0u,
666 DE_NULL
667 };
668 const tcu::UVec2 renderArea (width, height);
669 const std::vector<VkViewport> viewports (1, makeViewport(renderArea));
670 const std::vector<VkRect2D> scissors (1, makeRect2D(renderArea));
671
672 const VkPipelineMultisampleStateCreateInfo multisampleState =
673 {
674 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
675 DE_NULL,
676 (VkPipelineMultisampleStateCreateFlags)0u,
677
678 sampleCountBitFromSampleCount(sampleCount),
679 VK_FALSE,
680 0.0f,
681 DE_NULL,
682 VK_FALSE,
683 VK_FALSE,
684 };
685 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
686 {
687 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
688 DE_NULL,
689 (VkPipelineDepthStencilStateCreateFlags)0u,
690
691 VK_FALSE,
692 VK_TRUE,
693 VK_COMPARE_OP_ALWAYS,
694 VK_FALSE,
695 VK_TRUE,
696 {
697 VK_STENCIL_OP_KEEP,
698 VK_STENCIL_OP_INCREMENT_AND_WRAP,
699 VK_STENCIL_OP_KEEP,
700 VK_COMPARE_OP_ALWAYS,
701 ~0u,
702 ~0u,
703 0xFFu / (sampleCount + 1)
704 },
705 {
706 VK_STENCIL_OP_KEEP,
707 VK_STENCIL_OP_INCREMENT_AND_WRAP,
708 VK_STENCIL_OP_KEEP,
709 VK_COMPARE_OP_ALWAYS,
710 ~0u,
711 ~0u,
712 0xFFu / (sampleCount + 1)
713 },
714
715 0.0f,
716 1.0f
717 };
718 const VkPipelineColorBlendStateCreateInfo blendState =
719 {
720 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
721 DE_NULL,
722 (VkPipelineColorBlendStateCreateFlags)0u,
723
724 VK_FALSE,
725 VK_LOGIC_OP_COPY,
726 DE_LENGTH_OF_ARRAY(attachmentBlendStates),
727 attachmentBlendStates,
728 { 0.0f, 0.0f, 0.0f, 0.0f }
729 };
730
731 return makeGraphicsPipeline(vkd, // const DeviceInterface& vk
732 device, // const VkDevice device
733 pipelineLayout, // const VkPipelineLayout pipelineLayout
734 *vertexShaderModule, // const VkShaderModule vertexShaderModule
735 DE_NULL, // const VkShaderModule tessellationControlShaderModule
736 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
737 layerCount != 1 ? *geometryShaderModule : DE_NULL, // const VkShaderModule geometryShaderModule
738 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
739 renderPass, // const VkRenderPass renderPass
740 viewports, // const std::vector<VkViewport>& viewports
741 scissors, // const std::vector<VkRect2D>& scissors
742 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
743 0u, // const deUint32 subpass
744 0u, // const deUint32 patchControlPoints
745 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
746 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
747 &multisampleState, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
748 &depthStencilState, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
749 &blendState); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
750 }
751
752 struct TestConfig
753 {
TestConfigvkt::__anon156ab5910111::TestConfig754 TestConfig (VkFormat format_,
755 deUint32 sampleCount_,
756 deUint32 layerCount_,
757 RenderPassType renderPassType_)
758 : format (format_)
759 , sampleCount (sampleCount_)
760 , layerCount (layerCount_)
761 , renderPassType (renderPassType_)
762 {
763 }
764
765 VkFormat format;
766 deUint32 sampleCount;
767 deUint32 layerCount;
768 RenderPassType renderPassType;
769 };
770
771 class MultisampleRenderPassTestInstance : public TestInstance
772 {
773 public:
774 MultisampleRenderPassTestInstance (Context& context, TestConfig config);
775 ~MultisampleRenderPassTestInstance (void);
776
777 tcu::TestStatus iterate (void);
778
779 private:
780 template<typename RenderpassSubpass>
781 void submit (void);
782 void submitSwitch (RenderPassType renderPassType);
783 void verify (void);
784 void logImage (const std::string& name,
785 const tcu::ConstPixelBufferAccess& image);
786
787 const bool m_featuresSupported;
788 const bool m_extensionSupported;
789 const RenderPassType m_renderPassType;
790
791 const VkFormat m_format;
792 const deUint32 m_sampleCount;
793 const deUint32 m_layerCount;
794 const deUint32 m_width;
795 const deUint32 m_height;
796
797 const std::vector<VkImageSp> m_multisampleImages;
798 const std::vector<de::SharedPtr<Allocation> > m_multisampleImageMemory;
799 const std::vector<VkImageViewSp> m_multisampleImageViews;
800
801 const std::vector<VkImageSp> m_singlesampleImages;
802 const std::vector<de::SharedPtr<Allocation> > m_singlesampleImageMemory;
803 const std::vector<VkImageViewSp> m_singlesampleImageViews;
804
805 const Unique<VkRenderPass> m_renderPass;
806 const Unique<VkFramebuffer> m_framebuffer;
807
808 const Unique<VkPipelineLayout> m_renderPipelineLayout;
809 const Unique<VkPipeline> m_renderPipeline;
810
811 const std::vector<VkBufferSp> m_buffers;
812 const std::vector<de::SharedPtr<Allocation> > m_bufferMemory;
813
814 const Unique<VkCommandPool> m_commandPool;
815 tcu::TextureLevel m_sum;
816 deUint32 m_sampleMask;
817 tcu::ResultCollector m_resultCollector;
818 };
819
MultisampleRenderPassTestInstance(Context & context,TestConfig config)820 MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
821 : TestInstance (context)
822 , m_featuresSupported ((config.layerCount > 1) && context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER))
823 , m_extensionSupported ((config.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceExtension("VK_KHR_create_renderpass2"))
824 , m_renderPassType (config.renderPassType)
825 , m_format (config.format)
826 , m_sampleCount (config.sampleCount)
827 , m_layerCount (config.layerCount)
828 , m_width (32u)
829 , m_height (32u)
830
831 , m_multisampleImages (createMultisampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_format, m_sampleCount, m_width, m_height, m_layerCount))
832 , m_multisampleImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_multisampleImages))
833 , m_multisampleImageViews (createImageViews(context.getDeviceInterface(), context.getDevice(), m_multisampleImages, m_format, VK_IMAGE_ASPECT_COLOR_BIT, m_layerCount))
834
835 , m_singlesampleImages (createSingleSampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height, m_layerCount))
836 , m_singlesampleImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_singlesampleImages))
837 , m_singlesampleImageViews (createImageViews(context.getDeviceInterface(), context.getDevice(), m_singlesampleImages, m_format, VK_IMAGE_ASPECT_COLOR_BIT, m_layerCount))
838
839 , m_renderPass (createRenderPass(context.getDeviceInterface(), context.getDevice(), m_format, m_sampleCount, config.renderPassType))
840 , m_framebuffer (createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, m_multisampleImageViews, m_singlesampleImageViews, m_width, m_height, m_layerCount))
841
842 , m_renderPipelineLayout (createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
843 , m_renderPipeline (createRenderPipeline(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount, m_layerCount))
844
845 , m_buffers (createBuffers(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height, m_layerCount))
846 , m_bufferMemory (createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_buffers))
847
848 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
849 , m_sum (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), m_width, m_height, m_layerCount)
850 , m_sampleMask (0x0u)
851 {
852 tcu::clear(m_sum.getAccess(), Vec4(0.0f, 0.0f, 0.0f, 0.0f));
853 }
854
~MultisampleRenderPassTestInstance(void)855 MultisampleRenderPassTestInstance::~MultisampleRenderPassTestInstance (void)
856 {
857 }
858
logImage(const std::string & name,const tcu::ConstPixelBufferAccess & image)859 void MultisampleRenderPassTestInstance::logImage (const std::string& name, const tcu::ConstPixelBufferAccess& image)
860 {
861 m_context.getTestContext().getLog() << tcu::LogImage(name.c_str(), name.c_str(), image);
862
863 for (deUint32 layerNdx = 0; layerNdx < m_layerCount; ++layerNdx)
864 {
865 const std::string layerName (name + " Layer:" + de::toString(layerNdx));
866 tcu::ConstPixelBufferAccess layerImage (image.getFormat(), m_width, m_height, 1, image.getPixelPtr(0, 0, layerNdx));
867
868 m_context.getTestContext().getLog() << tcu::LogImage(layerName.c_str(), layerName.c_str(), layerImage);
869 }
870 }
871
872 template<typename RenderpassSubpass>
submit(void)873 void MultisampleRenderPassTestInstance::submit (void)
874 {
875 const DeviceInterface& vkd (m_context.getDeviceInterface());
876 const VkDevice device (m_context.getDevice());
877 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
878 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
879 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL);
880
881 beginCommandBuffer(vkd, *commandBuffer);
882
883 // Memory barriers between previous copies and rendering
884 {
885 std::vector<VkImageMemoryBarrier> barriers;
886
887 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
888 {
889 const VkImageMemoryBarrier barrier =
890 {
891 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
892 DE_NULL,
893
894 VK_ACCESS_TRANSFER_READ_BIT,
895 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
896
897 VK_IMAGE_LAYOUT_UNDEFINED,
898 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
899
900 VK_QUEUE_FAMILY_IGNORED,
901 VK_QUEUE_FAMILY_IGNORED,
902
903 **m_singlesampleImages[dstNdx],
904 {
905 VK_IMAGE_ASPECT_COLOR_BIT,
906 0u,
907 1u,
908 0u,
909 m_layerCount
910 }
911 };
912
913 barriers.push_back(barrier);
914 }
915
916 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, (deUint32)barriers.size(), &barriers[0]);
917 }
918
919 {
920 const VkRenderPassBeginInfo beginInfo =
921 {
922 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
923 DE_NULL,
924
925 *m_renderPass,
926 *m_framebuffer,
927
928 {
929 { 0u, 0u },
930 { m_width, m_height }
931 },
932
933 0u,
934 DE_NULL
935 };
936 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
937 }
938
939 // Clear everything to black
940 {
941 const tcu::TextureFormat format (mapVkFormat(m_format));
942 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
943 VkClearValue value;
944
945 switch (channelClass)
946 {
947 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
948 value = makeClearValueColorF32(-1.0f, -1.0f, -1.0f, -1.0f);
949 break;
950
951 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
952 value = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 0.0f);
953 break;
954
955 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
956 value = makeClearValueColorF32(-1.0f, -1.0f, -1.0f, -1.0f);
957 break;
958
959 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
960 value = makeClearValueColorI32(-128, -128, -128, -128);
961 break;
962
963 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
964 value = makeClearValueColorU32(0u, 0u, 0u, 0u);
965 break;
966
967 default:
968 DE_FATAL("Unknown channel class");
969 }
970 const VkClearAttachment colors[] =
971 {
972 {
973 VK_IMAGE_ASPECT_COLOR_BIT,
974 0u,
975 value
976 },
977 {
978 VK_IMAGE_ASPECT_COLOR_BIT,
979 1u,
980 value
981 },
982 {
983 VK_IMAGE_ASPECT_COLOR_BIT,
984 2u,
985 value
986 },
987 {
988 VK_IMAGE_ASPECT_COLOR_BIT,
989 3u,
990 value
991 }
992 };
993 const VkClearRect rect =
994 {
995 {
996 { 0u, 0u },
997 { m_width, m_height }
998 },
999 0u,
1000 m_layerCount,
1001 };
1002 vkd.cmdClearAttachments(*commandBuffer, DE_LENGTH_OF_ARRAY(colors), colors, 1u, &rect);
1003 }
1004
1005 // Render black samples
1006 {
1007 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
1008 vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(m_sampleMask), &m_sampleMask);
1009 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1010 }
1011
1012 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
1013
1014 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
1015 copyImageToBuffer(vkd, *commandBuffer, **m_singlesampleImages[dstNdx], **m_buffers[dstNdx], tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_layerCount);
1016
1017 endCommandBuffer(vkd, *commandBuffer);
1018
1019 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
1020
1021 for (size_t memoryBufferNdx = 0; memoryBufferNdx < m_bufferMemory.size(); memoryBufferNdx++)
1022 invalidateMappedMemoryRange(vkd, device, m_bufferMemory[memoryBufferNdx]->getMemory(), 0u, VK_WHOLE_SIZE);
1023 }
1024
submitSwitch(RenderPassType renderPassType)1025 void MultisampleRenderPassTestInstance::submitSwitch (RenderPassType renderPassType)
1026 {
1027 switch (renderPassType)
1028 {
1029 case RENDERPASS_TYPE_LEGACY:
1030 submit<RenderpassSubpass1>();
1031 break;
1032 case RENDERPASS_TYPE_RENDERPASS2:
1033 submit<RenderpassSubpass2>();
1034 break;
1035 default:
1036 TCU_THROW(InternalError, "Impossible");
1037 }
1038 }
1039
verify(void)1040 void MultisampleRenderPassTestInstance::verify (void)
1041 {
1042 const Vec4 errorColor (1.0f, 0.0f, 0.0f, 1.0f);
1043 const Vec4 okColor (0.0f, 1.0f, 0.0f, 1.0f);
1044 const tcu::TextureFormat format (mapVkFormat(m_format));
1045 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1046 const void* const ptrs[] =
1047 {
1048 m_bufferMemory[0]->getHostPtr(),
1049 m_bufferMemory[1]->getHostPtr(),
1050 m_bufferMemory[2]->getHostPtr(),
1051 m_bufferMemory[3]->getHostPtr()
1052 };
1053 const tcu::ConstPixelBufferAccess accesses[] =
1054 {
1055 tcu::ConstPixelBufferAccess(format, m_width, m_height, m_layerCount, ptrs[0]),
1056 tcu::ConstPixelBufferAccess(format, m_width, m_height, m_layerCount, ptrs[1]),
1057 tcu::ConstPixelBufferAccess(format, m_width, m_height, m_layerCount, ptrs[2]),
1058 tcu::ConstPixelBufferAccess(format, m_width, m_height, m_layerCount, ptrs[3])
1059 };
1060 tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height, m_layerCount);
1061 tcu::TestLog& log (m_context.getTestContext().getLog());
1062
1063 switch (channelClass)
1064 {
1065 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1066 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1067 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1068 {
1069 const int componentCount (tcu::getNumUsedChannels(format.order));
1070 bool isOk = true;
1071 float clearValue;
1072 float renderValue;
1073
1074 switch (channelClass)
1075 {
1076 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1077 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1078 clearValue = -1.0f;
1079 renderValue = 1.0f;
1080 break;
1081
1082 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1083 clearValue = 0.0f;
1084 renderValue = 1.0f;
1085 break;
1086
1087 default:
1088 clearValue = 0.0f;
1089 renderValue = 0.0f;
1090 DE_FATAL("Unknown channel class");
1091 }
1092
1093 for (deUint32 z = 0; z < m_layerCount; z++)
1094 for (deUint32 y = 0; y < m_height; y++)
1095 for (deUint32 x = 0; x < m_width; x++)
1096 {
1097 // Color has to be black if no samples were covered, white if all samples were covered or same in every attachment
1098 const Vec4 firstColor (accesses[0].getPixel(x, y, z));
1099 const Vec4 refColor (m_sampleMask == 0x0u
1100 ? Vec4(clearValue,
1101 componentCount > 1 ? clearValue : 0.0f,
1102 componentCount > 2 ? clearValue : 0.0f,
1103 componentCount > 3 ? clearValue : 1.0f)
1104 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1105 ? Vec4(renderValue,
1106 componentCount > 1 ? renderValue : 0.0f,
1107 componentCount > 2 ? renderValue : 0.0f,
1108 componentCount > 3 ? renderValue : 1.0f)
1109 : firstColor);
1110
1111 errorMask.getAccess().setPixel(okColor, x, y, z);
1112
1113 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1114 {
1115 const Vec4 color (accesses[attachmentNdx].getPixel(x, y, z));
1116
1117 if (refColor != color)
1118 {
1119 isOk = false;
1120 errorMask.getAccess().setPixel(errorColor, x, y, z);
1121 break;
1122 }
1123 }
1124
1125 {
1126 const Vec4 old = m_sum.getAccess().getPixel(x, y, z);
1127 m_sum.getAccess().setPixel(old + (tcu::isSRGB(format) ? tcu::sRGBToLinear(firstColor) : firstColor), x, y, z);
1128 }
1129 }
1130
1131 if (!isOk)
1132 {
1133 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1134 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1135
1136 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1137 logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);
1138
1139 logImage("ErrorMask", errorMask.getAccess());
1140
1141 if (m_sampleMask == 0x0u)
1142 {
1143 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1144 m_resultCollector.fail("Empty sample mask didn't produce correct pixel values");
1145 }
1146 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1147 {
1148 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1149 m_resultCollector.fail("Full sample mask didn't produce correct pixel values");
1150 }
1151 else
1152 {
1153 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve is inconsistent between attachments" << tcu::TestLog::EndMessage;
1154 m_resultCollector.fail("Resolve is inconsistent between attachments");
1155 }
1156 }
1157 break;
1158 }
1159
1160 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1161 {
1162 const int componentCount (tcu::getNumUsedChannels(format.order));
1163 const UVec4 bitDepth (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1164 const UVec4 renderValue (tcu::select((UVec4(1u) << tcu::min(UVec4(8u), bitDepth)) - UVec4(1u),
1165 UVec4(0u, 0u, 0u, 1u),
1166 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1167 const UVec4 clearValue (tcu::select(UVec4(0u),
1168 UVec4(0u, 0u, 0u, 1u),
1169 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1170 bool unexpectedValues = false;
1171 bool inconsistentComponents = false;
1172 bool inconsistentAttachments = false;
1173
1174 for (deUint32 z = 0; z < m_layerCount; z++)
1175 for (deUint32 y = 0; y < m_height; y++)
1176 for (deUint32 x = 0; x < m_width; x++)
1177 {
1178 // Color has to be all zeros if no samples were covered, all 255 if all samples were covered or consistent across all attachments
1179 const UVec4 refColor (m_sampleMask == 0x0u
1180 ? clearValue
1181 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1182 ? renderValue
1183 : accesses[0].getPixelUint(x, y, z));
1184 bool isOk = true;
1185
1186 // If reference value was taken from first attachment, check that it is valid value i.e. clear or render value
1187 if (m_sampleMask != 0x0u && m_sampleMask != ((0x1u << m_sampleCount) - 1u))
1188 {
1189 // Each component must be resolved same way
1190 const BVec4 isRenderValue (refColor == renderValue);
1191 const BVec4 isClearValue (refColor == clearValue);
1192 const bool unexpectedValue (tcu::anyNotEqual(tcu::logicalOr(isRenderValue, isClearValue), BVec4(true)));
1193 const bool inconsistentComponent (!(tcu::allEqual(isRenderValue, BVec4(true)) || tcu::allEqual(isClearValue, BVec4(true))));
1194
1195 unexpectedValues |= unexpectedValue;
1196 inconsistentComponents |= inconsistentComponent;
1197
1198 if (unexpectedValue || inconsistentComponent)
1199 isOk = false;
1200 }
1201
1202 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1203 {
1204 const UVec4 color (accesses[attachmentNdx].getPixelUint(x, y, z));
1205
1206 if (refColor != color)
1207 {
1208 isOk = false;
1209 inconsistentAttachments = true;
1210 break;
1211 }
1212 }
1213
1214 errorMask.getAccess().setPixel((isOk ? okColor : errorColor), x, y, z);
1215 }
1216
1217 if (unexpectedValues || inconsistentComponents || inconsistentAttachments)
1218 {
1219 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1220 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1221
1222 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1223 logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);
1224
1225 logImage("ErrorMask", errorMask.getAccess());
1226
1227 if (m_sampleMask == 0x0u)
1228 {
1229 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1230 m_resultCollector.fail("Empty sample mask didn't produce correct pixels");
1231 }
1232 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1233 {
1234 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1235 m_resultCollector.fail("Full sample mask didn't produce correct pixels");
1236 }
1237 else
1238 {
1239 if (unexpectedValues)
1240 {
1241 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve produced unexpected values i.e. not " << clearValue << " or " << renderValue << tcu::TestLog::EndMessage;
1242 m_resultCollector.fail("Resolve produced unexpected values");
1243 }
1244
1245 if (inconsistentComponents)
1246 {
1247 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different components of attachment were resolved to different values." << tcu::TestLog::EndMessage;
1248 m_resultCollector.fail("Different components of attachment were resolved to different values.");
1249 }
1250
1251 if (inconsistentAttachments)
1252 {
1253 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different attachments were resolved to different values." << tcu::TestLog::EndMessage;
1254 m_resultCollector.fail("Different attachments were resolved to different values.");
1255 }
1256 }
1257 }
1258 break;
1259 }
1260
1261 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1262 {
1263 const int componentCount (tcu::getNumUsedChannels(format.order));
1264 const IVec4 bitDepth (tcu::getTextureFormatBitDepth(format));
1265 const IVec4 renderValue (tcu::select((IVec4(1) << (tcu::min(IVec4(8), bitDepth) - IVec4(1))) - IVec4(1),
1266 IVec4(0, 0, 0, 1),
1267 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1268 const IVec4 clearValue (tcu::select(-(IVec4(1) << (tcu::min(IVec4(8), bitDepth) - IVec4(1))),
1269 IVec4(0, 0, 0, 1),
1270 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1271 bool unexpectedValues = false;
1272 bool inconsistentComponents = false;
1273 bool inconsistentAttachments = false;
1274
1275 for (deUint32 z = 0; z < m_layerCount; z++)
1276 for (deUint32 y = 0; y < m_height; y++)
1277 for (deUint32 x = 0; x < m_width; x++)
1278 {
1279 // Color has to be all zeros if no samples were covered, all 255 if all samples were covered or consistent across all attachments
1280 const IVec4 refColor (m_sampleMask == 0x0u
1281 ? clearValue
1282 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1283 ? renderValue
1284 : accesses[0].getPixelInt(x, y, z));
1285 bool isOk = true;
1286
1287 // If reference value was taken from first attachment, check that it is valid value i.e. clear or render value
1288 if (m_sampleMask != 0x0u && m_sampleMask != ((0x1u << m_sampleCount) - 1u))
1289 {
1290 // Each component must be resolved same way
1291 const BVec4 isRenderValue (refColor == renderValue);
1292 const BVec4 isClearValue (refColor == clearValue);
1293 const bool unexpectedValue (tcu::anyNotEqual(tcu::logicalOr(isRenderValue, isClearValue), BVec4(true)));
1294 const bool inconsistentComponent (!(tcu::allEqual(isRenderValue, BVec4(true)) || tcu::allEqual(isClearValue, BVec4(true))));
1295
1296 unexpectedValues |= unexpectedValue;
1297 inconsistentComponents |= inconsistentComponent;
1298
1299 if (unexpectedValue || inconsistentComponent)
1300 isOk = false;
1301 }
1302
1303 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1304 {
1305 const IVec4 color (accesses[attachmentNdx].getPixelInt(x, y, z));
1306
1307 if (refColor != color)
1308 {
1309 isOk = false;
1310 inconsistentAttachments = true;
1311 break;
1312 }
1313 }
1314
1315 errorMask.getAccess().setPixel((isOk ? okColor : errorColor), x, y, z);
1316 }
1317
1318 if (unexpectedValues || inconsistentComponents || inconsistentAttachments)
1319 {
1320 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1321 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1322
1323 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1324 logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);
1325
1326 logImage("ErrorMask", errorMask.getAccess());
1327
1328 if (m_sampleMask == 0x0u)
1329 {
1330 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1331 m_resultCollector.fail("Empty sample mask didn't produce correct pixels");
1332 }
1333 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1334 {
1335 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1336 m_resultCollector.fail("Full sample mask didn't produce correct pixels");
1337 }
1338 else
1339 {
1340 if (unexpectedValues)
1341 {
1342 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve produced unexpected values i.e. not " << clearValue << " or " << renderValue << tcu::TestLog::EndMessage;
1343 m_resultCollector.fail("Resolve produced unexpected values");
1344 }
1345
1346 if (inconsistentComponents)
1347 {
1348 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different components of attachment were resolved to different values." << tcu::TestLog::EndMessage;
1349 m_resultCollector.fail("Different components of attachment were resolved to different values.");
1350 }
1351
1352 if (inconsistentAttachments)
1353 {
1354 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different attachments were resolved to different values." << tcu::TestLog::EndMessage;
1355 m_resultCollector.fail("Different attachments were resolved to different values.");
1356 }
1357 }
1358 }
1359 break;
1360 }
1361
1362 default:
1363 DE_FATAL("Unknown channel class");
1364 }
1365 }
1366
iterate(void)1367 tcu::TestStatus MultisampleRenderPassTestInstance::iterate (void)
1368 {
1369 if (m_sampleMask == 0u)
1370 {
1371 const tcu::TextureFormat format (mapVkFormat(m_format));
1372 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1373 tcu::TestLog& log (m_context.getTestContext().getLog());
1374
1375 switch (channelClass)
1376 {
1377 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1378 log << TestLog::Message << "Clearing target to zero and rendering 255 pixels with every possible sample mask" << TestLog::EndMessage;
1379 break;
1380
1381 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1382 log << TestLog::Message << "Clearing target to -128 and rendering 127 pixels with every possible sample mask" << TestLog::EndMessage;
1383 break;
1384
1385 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1386 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1387 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1388 log << TestLog::Message << "Clearing target to black and rendering white pixels with every possible sample mask" << TestLog::EndMessage;
1389 break;
1390
1391 default:
1392 DE_FATAL("Unknown channel class");
1393 }
1394 }
1395
1396 submitSwitch(m_renderPassType);
1397 verify();
1398
1399 if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1400 {
1401 const tcu::TextureFormat format (mapVkFormat(m_format));
1402 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1403 const Vec4 threshold (getFormatThreshold(m_format));
1404 tcu::TestLog& log (m_context.getTestContext().getLog());
1405
1406 if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT
1407 || channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT
1408 || channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
1409 {
1410 const int componentCount (tcu::getNumUsedChannels(format.order));
1411 const Vec4 errorColor (1.0f, 0.0f, 0.0f, 1.0f);
1412 const Vec4 okColor (0.0f, 1.0f, 0.0f, 1.0f);
1413 tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height, m_layerCount);
1414 bool isOk = true;
1415 Vec4 maxDiff (0.0f);
1416 Vec4 expectedAverage;
1417
1418 switch (channelClass)
1419 {
1420 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1421 {
1422 expectedAverage = Vec4(0.5f, componentCount > 1 ? 0.5f : 0.0f, componentCount > 2 ? 0.5f : 0.0f, componentCount > 3 ? 0.5f : 1.0f);
1423 break;
1424 }
1425
1426 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1427 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1428 {
1429 expectedAverage = Vec4(0.0f, 0.0f, 0.0f, componentCount > 3 ? 0.0f : 1.0f);
1430 break;
1431 }
1432
1433 default:
1434 DE_FATAL("Unknown channel class");
1435 }
1436
1437 for (deUint32 z = 0; z < m_layerCount; z++)
1438 for (deUint32 y = 0; y < m_height; y++)
1439 for (deUint32 x = 0; x < m_width; x++)
1440 {
1441 const Vec4 sum (m_sum.getAccess().getPixel(x, y, z));
1442 const Vec4 average (sum / Vec4((float)(0x1u << m_sampleCount)));
1443 const Vec4 diff (tcu::abs(average - expectedAverage));
1444
1445 m_sum.getAccess().setPixel(average, x, y, z);
1446 errorMask.getAccess().setPixel(okColor, x, y, z);
1447
1448 if (diff[0] > threshold.x()
1449 || diff[1] > threshold.y()
1450 || diff[2] > threshold.z()
1451 || diff[3] > threshold.w())
1452 {
1453 isOk = false;
1454 maxDiff = tcu::max(maxDiff, diff);
1455 errorMask.getAccess().setPixel(errorColor, x, y, z);
1456 }
1457 }
1458
1459 log << TestLog::Image("Average resolved values in attachment 0", "Average resolved values in attachment 0", m_sum);
1460
1461 if (!isOk)
1462 {
1463 std::stringstream message;
1464
1465 m_context.getTestContext().getLog() << tcu::LogImage("ErrorMask", "ErrorMask", errorMask.getAccess());
1466
1467 message << "Average resolved values differ from expected average values by more than ";
1468
1469 switch (componentCount)
1470 {
1471 case 1:
1472 message << threshold.x();
1473 break;
1474 case 2:
1475 message << "vec2" << Vec2(threshold.x(), threshold.y());
1476 break;
1477 case 3:
1478 message << "vec3" << Vec3(threshold.x(), threshold.y(), threshold.z());
1479 break;
1480 default:
1481 message << "vec4" << threshold;
1482 }
1483
1484 message << ". Max diff " << maxDiff;
1485 log << TestLog::Message << message.str() << TestLog::EndMessage;
1486
1487 m_resultCollector.fail("Average resolved values differ from expected average values");
1488 }
1489 }
1490
1491 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1492 }
1493 else
1494 {
1495 m_sampleMask++;
1496 return tcu::TestStatus::incomplete();
1497 }
1498 }
1499
1500 struct Programs
1501 {
initvkt::__anon156ab5910111::Programs1502 void init (vk::SourceCollections& dst, TestConfig config) const
1503 {
1504 const tcu::TextureFormat format (mapVkFormat(config.format));
1505 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1506
1507 dst.glslSources.add("quad-vert") << glu::VertexSource(
1508 "#version 450\n"
1509 "out gl_PerVertex {\n"
1510 "\tvec4 gl_Position;\n"
1511 "};\n"
1512 "highp float;\n"
1513 "void main (void) {\n"
1514 "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1515 "\t ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1516 "}\n");
1517
1518 if (config.layerCount > 1)
1519 {
1520 std::ostringstream src;
1521
1522 src << "#version 450\n"
1523 << "highp float;\n"
1524 << "\n"
1525 << "layout(triangles) in;\n"
1526 << "layout(triangle_strip, max_vertices = " << 3 * 2 * config.layerCount << ") out;\n"
1527 << "\n"
1528 << "in gl_PerVertex {\n"
1529 << " vec4 gl_Position;\n"
1530 << "} gl_in[];\n"
1531 << "\n"
1532 << "out gl_PerVertex {\n"
1533 << " vec4 gl_Position;\n"
1534 << "};\n"
1535 << "\n"
1536 << "void main (void) {\n"
1537 << " for (int layerNdx = 0; layerNdx < " << config.layerCount << "; ++layerNdx) {\n"
1538 << " for(int vertexNdx = 0; vertexNdx < gl_in.length(); vertexNdx++) {\n"
1539 << " gl_Position = gl_in[vertexNdx].gl_Position;\n"
1540 << " gl_Layer = layerNdx;\n"
1541 << " EmitVertex();\n"
1542 << " };\n"
1543 << " EndPrimitive();\n"
1544 << " };\n"
1545 << "}\n";
1546
1547 dst.glslSources.add("geom") << glu::GeometrySource(src.str());
1548 }
1549
1550 switch (channelClass)
1551 {
1552 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1553 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1554 "#version 450\n"
1555 "layout(push_constant) uniform PushConstant {\n"
1556 "\thighp uint sampleMask;\n"
1557 "} pushConstants;\n"
1558 "layout(location = 0) out highp uvec4 o_color0;\n"
1559 "layout(location = 1) out highp uvec4 o_color1;\n"
1560 "layout(location = 2) out highp uvec4 o_color2;\n"
1561 "layout(location = 3) out highp uvec4 o_color3;\n"
1562 "void main (void)\n"
1563 "{\n"
1564 "\tgl_SampleMask[0] = int(pushConstants.sampleMask);\n"
1565 "\to_color0 = uvec4(255);\n"
1566 "\to_color1 = uvec4(255);\n"
1567 "\to_color2 = uvec4(255);\n"
1568 "\to_color3 = uvec4(255);\n"
1569 "}\n");
1570 break;
1571
1572 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1573 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1574 "#version 450\n"
1575 "layout(push_constant) uniform PushConstant {\n"
1576 "\thighp uint sampleMask;\n"
1577 "} pushConstants;\n"
1578 "layout(location = 0) out highp ivec4 o_color0;\n"
1579 "layout(location = 1) out highp ivec4 o_color1;\n"
1580 "layout(location = 2) out highp ivec4 o_color2;\n"
1581 "layout(location = 3) out highp ivec4 o_color3;\n"
1582 "void main (void)\n"
1583 "{\n"
1584 "\tgl_SampleMask[0] = int(pushConstants.sampleMask);\n"
1585 "\to_color0 = ivec4(127);\n"
1586 "\to_color1 = ivec4(127);\n"
1587 "\to_color2 = ivec4(127);\n"
1588 "\to_color3 = ivec4(127);\n"
1589 "}\n");
1590 break;
1591
1592 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1593 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1594 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1595 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1596 "#version 450\n"
1597 "layout(push_constant) uniform PushConstant {\n"
1598 "\thighp uint sampleMask;\n"
1599 "} pushConstants;\n"
1600 "layout(location = 0) out highp vec4 o_color0;\n"
1601 "layout(location = 1) out highp vec4 o_color1;\n"
1602 "layout(location = 2) out highp vec4 o_color2;\n"
1603 "layout(location = 3) out highp vec4 o_color3;\n"
1604 "void main (void)\n"
1605 "{\n"
1606 "\tgl_SampleMask[0] = int(pushConstants.sampleMask);\n"
1607 "\to_color0 = vec4(1.0);\n"
1608 "\to_color1 = vec4(1.0);\n"
1609 "\to_color2 = vec4(1.0);\n"
1610 "\to_color3 = vec4(1.0);\n"
1611 "}\n");
1612 break;
1613
1614 default:
1615 DE_FATAL("Unknown channel class");
1616 }
1617 }
1618 };
1619
formatToName(VkFormat format)1620 std::string formatToName (VkFormat format)
1621 {
1622 const std::string formatStr = de::toString(format);
1623 const std::string prefix = "VK_FORMAT_";
1624
1625 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
1626
1627 return de::toLower(formatStr.substr(prefix.length()));
1628 }
1629
initTests(tcu::TestCaseGroup * group,RenderPassType renderPassType)1630 void initTests (tcu::TestCaseGroup* group, RenderPassType renderPassType)
1631 {
1632 static const VkFormat formats[] =
1633 {
1634 VK_FORMAT_R5G6B5_UNORM_PACK16,
1635 VK_FORMAT_R8_UNORM,
1636 VK_FORMAT_R8_SNORM,
1637 VK_FORMAT_R8_UINT,
1638 VK_FORMAT_R8_SINT,
1639 VK_FORMAT_R8G8_UNORM,
1640 VK_FORMAT_R8G8_SNORM,
1641 VK_FORMAT_R8G8_UINT,
1642 VK_FORMAT_R8G8_SINT,
1643 VK_FORMAT_R8G8B8A8_UNORM,
1644 VK_FORMAT_R8G8B8A8_SNORM,
1645 VK_FORMAT_R8G8B8A8_UINT,
1646 VK_FORMAT_R8G8B8A8_SINT,
1647 VK_FORMAT_R8G8B8A8_SRGB,
1648 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1649 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1650 VK_FORMAT_A8B8G8R8_UINT_PACK32,
1651 VK_FORMAT_A8B8G8R8_SINT_PACK32,
1652 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1653 VK_FORMAT_B8G8R8A8_UNORM,
1654 VK_FORMAT_B8G8R8A8_SRGB,
1655 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1656 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1657 VK_FORMAT_A2B10G10R10_UINT_PACK32,
1658 VK_FORMAT_R16_UNORM,
1659 VK_FORMAT_R16_SNORM,
1660 VK_FORMAT_R16_UINT,
1661 VK_FORMAT_R16_SINT,
1662 VK_FORMAT_R16_SFLOAT,
1663 VK_FORMAT_R16G16_UNORM,
1664 VK_FORMAT_R16G16_SNORM,
1665 VK_FORMAT_R16G16_UINT,
1666 VK_FORMAT_R16G16_SINT,
1667 VK_FORMAT_R16G16_SFLOAT,
1668 VK_FORMAT_R16G16B16A16_UNORM,
1669 VK_FORMAT_R16G16B16A16_SNORM,
1670 VK_FORMAT_R16G16B16A16_UINT,
1671 VK_FORMAT_R16G16B16A16_SINT,
1672 VK_FORMAT_R16G16B16A16_SFLOAT,
1673 VK_FORMAT_R32_UINT,
1674 VK_FORMAT_R32_SINT,
1675 VK_FORMAT_R32_SFLOAT,
1676 VK_FORMAT_R32G32_UINT,
1677 VK_FORMAT_R32G32_SINT,
1678 VK_FORMAT_R32G32_SFLOAT,
1679 VK_FORMAT_R32G32B32A32_UINT,
1680 VK_FORMAT_R32G32B32A32_SINT,
1681 VK_FORMAT_R32G32B32A32_SFLOAT,
1682 };
1683 const deUint32 sampleCounts[] =
1684 {
1685 2u, 4u, 8u
1686 };
1687 const deUint32 layerCounts[] =
1688 {
1689 1u, 3u, 6u
1690 };
1691 tcu::TestContext& testCtx (group->getTestContext());
1692
1693 for (size_t layerCountNdx = 0; layerCountNdx < DE_LENGTH_OF_ARRAY(layerCounts); layerCountNdx++)
1694 {
1695 const deUint32 layerCount (layerCounts[layerCountNdx]);
1696 const std::string layerGroupName ("layers_" + de::toString(layerCount));
1697 de::MovePtr<tcu::TestCaseGroup> layerGroup (new tcu::TestCaseGroup(testCtx, layerGroupName.c_str(), layerGroupName.c_str()));
1698
1699 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1700 {
1701 const VkFormat format (formats[formatNdx]);
1702 const std::string formatName (formatToName(format));
1703 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));
1704
1705 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
1706 {
1707 const deUint32 sampleCount (sampleCounts[sampleCountNdx]);
1708 const std::string testName ("samples_" + de::toString(sampleCount));
1709 const TestConfig testConfig (format, sampleCount, layerCount, renderPassType);
1710
1711 // Skip this test as it is rather slow
1712 if (layerCount == 6 && sampleCount == 8)
1713 continue;
1714
1715 formatGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
1716 }
1717
1718 if (layerCount == 1)
1719 group->addChild(formatGroup.release());
1720 else
1721 layerGroup->addChild(formatGroup.release());
1722 }
1723
1724 if (layerCount != 1)
1725 group->addChild(layerGroup.release());
1726 }
1727 }
1728
1729 } // anonymous
1730
createRenderPassMultisampleResolveTests(tcu::TestContext & testCtx)1731 tcu::TestCaseGroup* createRenderPassMultisampleResolveTests (tcu::TestContext& testCtx)
1732 {
1733 return createTestGroup(testCtx, "multisample_resolve", "Multisample render pass resolve tests", initTests, RENDERPASS_TYPE_LEGACY);
1734 }
1735
createRenderPass2MultisampleResolveTests(tcu::TestContext & testCtx)1736 tcu::TestCaseGroup* createRenderPass2MultisampleResolveTests (tcu::TestContext& testCtx)
1737 {
1738 return createTestGroup(testCtx, "multisample_resolve", "Multisample render pass resolve tests", initTests, RENDERPASS_TYPE_RENDERPASS2);
1739 }
1740
1741 } // vkt
1742