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