1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * \file vktPipelineMultisampleInterpolationTests.cpp
21 * \brief Multisample Interpolation Tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktPipelineMultisampleInterpolationTests.hpp"
25 #include "vktPipelineMultisampleTestsUtil.hpp"
26 #include "vktPipelineMakeUtil.hpp"
27 #include "vkQueryUtil.hpp"
28 #include "tcuTestLog.hpp"
43 ImageMSParams(const VkSampleCountFlagBits samples, const tcu::UVec3& size) : numSamples(samples), imageSize(size) {}
45 VkSampleCountFlagBits numSamples;
49 class MSInterpolationCaseBase : public TestCase
52 MSInterpolationCaseBase (tcu::TestContext& testCtx,
53 const std::string& name,
54 const ImageMSParams& imageMSParams)
55 : TestCase(testCtx, name, "")
56 , m_imageMSParams(imageMSParams)
60 const ImageMSParams m_imageMSParams;
63 typedef MSInterpolationCaseBase* (*MSInterpolationCaseFuncPtr)(tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams);
65 class MSInterpolationInstanceBase : public TestInstance
68 MSInterpolationInstanceBase (Context& context,
69 const ImageMSParams& imageMSParams)
70 : TestInstance (context)
71 , m_imageMSParams (imageMSParams)
72 , m_imageType (IMAGE_TYPE_2D)
73 , m_imageFormat (tcu::TextureFormat(tcu::TextureFormat::RG, tcu::TextureFormat::UNORM_INT8))
76 tcu::TestStatus iterate (void);
80 typedef std::vector<VkVertexInputAttributeDescription> VertexAttribDescVec;
84 VkPrimitiveTopology primitiveTopology;
85 deUint32 verticesCount;
87 VkDeviceSize dataSize;
88 VertexAttribDescVec vertexAttribDescVec;
91 void validateImageSize (const InstanceInterface& instance,
92 const VkPhysicalDevice physicalDevice,
93 const ImageType imageType,
94 const tcu::UVec3& imageSize) const;
96 void validateImageFeatureFlags (const InstanceInterface& instance,
97 const VkPhysicalDevice physicalDevice,
98 const VkFormat format,
99 const VkFormatFeatureFlags featureFlags) const;
101 void validateImageInfo (const InstanceInterface& instance,
102 const VkPhysicalDevice physicalDevice,
103 const VkImageCreateInfo& imageInfo) const;
105 virtual VertexDataDesc getVertexDataDescripton (void) const = 0;
107 virtual void uploadVertexData (const Allocation& vertexBufferAllocation,
108 const VertexDataDesc& vertexDataDescripton) const = 0;
110 virtual tcu::TestStatus verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const = 0;
112 const ImageMSParams m_imageMSParams;
113 const ImageType m_imageType;
114 const tcu::TextureFormat m_imageFormat;
117 void MSInterpolationInstanceBase::validateImageSize (const InstanceInterface& instance,
118 const VkPhysicalDevice physicalDevice,
119 const ImageType imageType,
120 const tcu::UVec3& imageSize) const
122 const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
124 bool isImageSizeValid = true;
129 isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension1D;
131 case IMAGE_TYPE_1D_ARRAY:
132 isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension1D &&
133 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
136 isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
137 imageSize.y() <= deviceProperties.limits.maxImageDimension2D;
139 case IMAGE_TYPE_2D_ARRAY:
140 isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
141 imageSize.y() <= deviceProperties.limits.maxImageDimension2D &&
142 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
144 case IMAGE_TYPE_CUBE:
145 isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
146 imageSize.y() <= deviceProperties.limits.maxImageDimensionCube;
148 case IMAGE_TYPE_CUBE_ARRAY:
149 isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
150 imageSize.y() <= deviceProperties.limits.maxImageDimensionCube &&
151 imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
154 isImageSizeValid = imageSize.x() <= deviceProperties.limits.maxImageDimension3D &&
155 imageSize.y() <= deviceProperties.limits.maxImageDimension3D &&
156 imageSize.z() <= deviceProperties.limits.maxImageDimension3D;
159 DE_FATAL("Unknown image type");
162 if (!isImageSizeValid)
164 std::ostringstream notSupportedStream;
166 notSupportedStream << "Image type (" << getImageTypeName(imageType) << ") with size (" << imageSize.x() << ", " << imageSize.y() << ", " << imageSize.z() << ") not supported by device" << std::endl;
168 const std::string notSupportedString = notSupportedStream.str();
170 TCU_THROW(NotSupportedError, notSupportedString.c_str());
174 void MSInterpolationInstanceBase::validateImageFeatureFlags (const InstanceInterface& instance,
175 const VkPhysicalDevice physicalDevice,
176 const VkFormat format,
177 const VkFormatFeatureFlags featureFlags) const
179 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
181 if ((formatProperties.optimalTilingFeatures & featureFlags) != featureFlags)
183 std::ostringstream notSupportedStream;
185 notSupportedStream << "Device does not support image format " << format << " for feature flags " << featureFlags << std::endl;
187 const std::string notSupportedString = notSupportedStream.str();
189 TCU_THROW(NotSupportedError, notSupportedString.c_str());
193 void MSInterpolationInstanceBase::validateImageInfo (const InstanceInterface& instance,
194 const VkPhysicalDevice physicalDevice,
195 const VkImageCreateInfo& imageInfo) const
197 VkImageFormatProperties imageFormatProps;
198 instance.getPhysicalDeviceImageFormatProperties(physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.tiling, imageInfo.usage, imageInfo.flags, &imageFormatProps);
200 if (imageFormatProps.maxExtent.width < imageInfo.extent.width ||
201 imageFormatProps.maxExtent.height < imageInfo.extent.height ||
202 imageFormatProps.maxExtent.depth < imageInfo.extent.depth)
204 std::ostringstream notSupportedStream;
206 notSupportedStream << "Image extent ("
207 << imageInfo.extent.width << ", "
208 << imageInfo.extent.height << ", "
209 << imageInfo.extent.depth
210 << ") exceeds allowed maximum ("
211 << imageFormatProps.maxExtent.width << ", "
212 << imageFormatProps.maxExtent.height << ", "
213 << imageFormatProps.maxExtent.depth
217 const std::string notSupportedString = notSupportedStream.str();
219 TCU_THROW(NotSupportedError, notSupportedString.c_str());
222 if (imageFormatProps.maxArrayLayers < imageInfo.arrayLayers)
224 std::ostringstream notSupportedStream;
226 notSupportedStream << "Image layers count of " << imageInfo.arrayLayers << " exceeds allowed maximum which is " << imageFormatProps.maxArrayLayers << std::endl;
228 const std::string notSupportedString = notSupportedStream.str();
230 TCU_THROW(NotSupportedError, notSupportedString.c_str());
233 if (!(imageFormatProps.sampleCounts & imageInfo.samples))
235 std::ostringstream notSupportedStream;
237 notSupportedStream << "Samples count of " << imageInfo.samples << " not supported for image" << std::endl;
239 const std::string notSupportedString = notSupportedStream.str();
241 TCU_THROW(NotSupportedError, notSupportedString.c_str());
245 tcu::TestStatus MSInterpolationInstanceBase::iterate (void)
247 const InstanceInterface& instance = m_context.getInstanceInterface();
248 const DeviceInterface& deviceInterface = m_context.getDeviceInterface();
249 const VkDevice device = m_context.getDevice();
250 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
251 const VkPhysicalDeviceFeatures& features = m_context.getDeviceFeatures();
252 Allocator& allocator = m_context.getDefaultAllocator();
253 const VkQueue queue = m_context.getUniversalQueue();
254 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
256 VkImageCreateInfo imageMSInfo;
257 VkImageCreateInfo imageRSInfo;
259 // Check if image size does not exceed device limits
260 validateImageSize(instance, physicalDevice, m_imageType, m_imageMSParams.imageSize);
262 // Check if device supports image format as color attachment
263 validateImageFeatureFlags(instance, physicalDevice, mapTextureFormat(m_imageFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
265 imageMSInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
266 imageMSInfo.pNext = DE_NULL;
267 imageMSInfo.flags = 0u;
268 imageMSInfo.imageType = mapImageType(m_imageType);
269 imageMSInfo.format = mapTextureFormat(m_imageFormat);
270 imageMSInfo.extent = makeExtent3D(getLayerSize(m_imageType, m_imageMSParams.imageSize));
271 imageMSInfo.arrayLayers = getNumLayers(m_imageType, m_imageMSParams.imageSize);
272 imageMSInfo.mipLevels = 1u;
273 imageMSInfo.samples = m_imageMSParams.numSamples;
274 imageMSInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
275 imageMSInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
276 imageMSInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
277 imageMSInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
278 imageMSInfo.queueFamilyIndexCount = 0u;
279 imageMSInfo.pQueueFamilyIndices = DE_NULL;
281 if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
283 imageMSInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
286 validateImageInfo(instance, physicalDevice, imageMSInfo);
288 const de::UniquePtr<Image> imageMS(new Image(deviceInterface, device, allocator, imageMSInfo, MemoryRequirement::Any));
290 imageRSInfo = imageMSInfo;
291 imageRSInfo.samples = VK_SAMPLE_COUNT_1_BIT;
293 validateImageInfo(instance, physicalDevice, imageRSInfo);
295 const de::UniquePtr<Image> imageRS(new Image(deviceInterface, device, allocator, imageRSInfo, MemoryRequirement::Any));
297 // Create render pass
298 const VkAttachmentDescription attachmentMSDesc =
300 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
301 imageMSInfo.format, // VkFormat format;
302 imageMSInfo.samples, // VkSampleCountFlagBits samples;
303 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
304 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
305 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
306 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
307 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
308 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
311 const VkAttachmentDescription attachmentRSDesc =
313 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
314 imageRSInfo.format, // VkFormat format;
315 imageRSInfo.samples, // VkSampleCountFlagBits samples;
316 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
317 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
318 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
319 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
320 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
321 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
324 const VkAttachmentDescription attachments[] = { attachmentMSDesc, attachmentRSDesc };
326 const VkAttachmentReference attachmentMSRef =
328 0u, // deUint32 attachment;
329 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
332 const VkAttachmentReference attachmentRSRef =
334 1u, // deUint32 attachment;
335 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
338 const VkAttachmentReference* resolveAttachment = m_imageMSParams.numSamples == VK_SAMPLE_COUNT_1_BIT ? DE_NULL : &attachmentRSRef;
340 const VkSubpassDescription subpassDescription =
342 (VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags;
343 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
344 0u, // deUint32 inputAttachmentCount;
345 DE_NULL, // const VkAttachmentReference* pInputAttachments;
346 1u, // deUint32 colorAttachmentCount;
347 &attachmentMSRef, // const VkAttachmentReference* pColorAttachments;
348 resolveAttachment, // const VkAttachmentReference* pResolveAttachments;
349 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
350 0u, // deUint32 preserveAttachmentCount;
351 DE_NULL // const deUint32* pPreserveAttachments;
354 const VkRenderPassCreateInfo renderPassInfo =
356 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
357 DE_NULL, // const void* pNext;
358 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags;
359 2u, // deUint32 attachmentCount;
360 attachments, // const VkAttachmentDescription* pAttachments;
361 1u, // deUint32 subpassCount;
362 &subpassDescription, // const VkSubpassDescription* pSubpasses;
363 0u, // deUint32 dependencyCount;
364 DE_NULL // const VkSubpassDependency* pDependencies;
367 const Unique<VkRenderPass> renderPass(createRenderPass(deviceInterface, device, &renderPassInfo));
369 const VkImageSubresourceRange fullImageRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageMSInfo.mipLevels, 0u, imageMSInfo.arrayLayers);
371 // Create color attachments image views
372 const Unique<VkImageView> imageMSView(makeImageView(deviceInterface, device, **imageMS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
373 const Unique<VkImageView> imageRSView(makeImageView(deviceInterface, device, **imageRS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
375 const VkImageView attachmentsViews[] = { *imageMSView, *imageRSView };
377 // Create framebuffer
378 const VkFramebufferCreateInfo framebufferInfo =
380 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
381 DE_NULL, // const void* pNext;
382 (VkFramebufferCreateFlags)0u, // VkFramebufferCreateFlags flags;
383 *renderPass, // VkRenderPass renderPass;
384 2u, // uint32_t attachmentCount;
385 attachmentsViews, // const VkImageView* pAttachments;
386 imageMSInfo.extent.width, // uint32_t width;
387 imageMSInfo.extent.height, // uint32_t height;
388 imageMSInfo.arrayLayers, // uint32_t layers;
391 const Unique<VkFramebuffer> framebuffer(createFramebuffer(deviceInterface, device, &framebufferInfo));
393 // Create pipeline layout
394 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
396 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
397 DE_NULL, // const void* pNext;
398 (VkPipelineLayoutCreateFlags)0u, // VkPipelineLayoutCreateFlags flags;
399 0u, // deUint32 setLayoutCount;
400 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
401 0u, // deUint32 pushConstantRangeCount;
402 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
405 const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(deviceInterface, device, &pipelineLayoutParams));
407 // Create vertex attributes data
408 const VertexDataDesc vertexDataDesc = getVertexDataDescripton();
410 de::SharedPtr<Buffer> vertexBuffer = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, makeBufferCreateInfo(vertexDataDesc.dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
411 const Allocation& vertexBufferAllocation = vertexBuffer->getAllocation();
413 uploadVertexData(vertexBufferAllocation, vertexDataDesc);
415 flushMappedMemoryRange(deviceInterface, device, vertexBufferAllocation.getMemory(), vertexBufferAllocation.getOffset(), vertexDataDesc.dataSize);
417 const VkVertexInputBindingDescription vertexBinding =
419 0u, // deUint32 binding;
420 vertexDataDesc.dataStride, // deUint32 stride;
421 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
424 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
426 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
427 DE_NULL, // const void* pNext;
428 (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags;
429 1u, // uint32_t vertexBindingDescriptionCount;
430 &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
431 static_cast<deUint32>(vertexDataDesc.vertexAttribDescVec.size()), // uint32_t vertexAttributeDescriptionCount;
432 dataPointer(vertexDataDesc.vertexAttribDescVec), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
435 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo =
437 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
438 DE_NULL, // const void* pNext;
439 (VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags flags;
440 vertexDataDesc.primitiveTopology, // VkPrimitiveTopology topology;
441 VK_FALSE, // VkBool32 primitiveRestartEnable;
444 const VkViewport viewport =
447 static_cast<float>(imageMSInfo.extent.width), static_cast<float>(imageMSInfo.extent.height),
451 const VkRect2D scissor =
454 makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
457 const VkPipelineViewportStateCreateInfo viewportStateInfo =
459 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
460 DE_NULL, // const void* pNext;
461 (VkPipelineViewportStateCreateFlags)0u, // VkPipelineViewportStateCreateFlags flags;
462 1u, // uint32_t viewportCount;
463 &viewport, // const VkViewport* pViewports;
464 1u, // uint32_t scissorCount;
465 &scissor, // const VkRect2D* pScissors;
468 const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo =
470 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
471 DE_NULL, // const void* pNext;
472 (VkPipelineRasterizationStateCreateFlags)0u, // VkPipelineRasterizationStateCreateFlags flags;
473 VK_FALSE, // VkBool32 depthClampEnable;
474 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
475 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
476 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
477 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
478 VK_FALSE, // VkBool32 depthBiasEnable;
479 0.0f, // float depthBiasConstantFactor;
480 0.0f, // float depthBiasClamp;
481 0.0f, // float depthBiasSlopeFactor;
482 1.0f, // float lineWidth;
485 const VkPipelineMultisampleStateCreateInfo multisampleStateInfo =
487 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
488 DE_NULL, // const void* pNext;
489 (VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags flags;
490 imageMSInfo.samples, // VkSampleCountFlagBits rasterizationSamples;
491 features.sampleRateShading, // VkBool32 sampleShadingEnable;
492 1.0f, // float minSampleShading;
493 DE_NULL, // const VkSampleMask* pSampleMask;
494 VK_FALSE, // VkBool32 alphaToCoverageEnable;
495 VK_FALSE, // VkBool32 alphaToOneEnable;
498 const VkStencilOpState stencilOpState = makeStencilOpState
500 VK_STENCIL_OP_KEEP, // stencil fail
501 VK_STENCIL_OP_KEEP, // depth & stencil pass
502 VK_STENCIL_OP_KEEP, // depth only fail
503 VK_COMPARE_OP_ALWAYS, // compare op
509 const VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo =
511 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
512 DE_NULL, // const void* pNext;
513 (VkPipelineDepthStencilStateCreateFlags)0u, // VkPipelineDepthStencilStateCreateFlags flags;
514 VK_FALSE, // VkBool32 depthTestEnable;
515 VK_FALSE, // VkBool32 depthWriteEnable;
516 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
517 VK_FALSE, // VkBool32 depthBoundsTestEnable;
518 VK_FALSE, // VkBool32 stencilTestEnable;
519 stencilOpState, // VkStencilOpState front;
520 stencilOpState, // VkStencilOpState back;
521 0.0f, // float minDepthBounds;
522 1.0f, // float maxDepthBounds;
525 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
527 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
529 VK_FALSE, // VkBool32 blendEnable;
530 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
531 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor;
532 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
533 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
534 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstAlphaBlendFactor;
535 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
536 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
539 const VkPipelineColorBlendStateCreateInfo colorBlendStateInfo =
541 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
542 DE_NULL, // const void* pNext;
543 (VkPipelineColorBlendStateCreateFlags)0u, // VkPipelineColorBlendStateCreateFlags flags;
544 VK_FALSE, // VkBool32 logicOpEnable;
545 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
546 1u, // deUint32 attachmentCount;
547 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
548 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
551 const Unique<VkShaderModule> vsModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0));
553 const VkPipelineShaderStageCreateInfo vsShaderStageInfo =
555 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
556 DE_NULL, // const void* pNext;
557 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
558 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
559 *vsModule, // VkShaderModule module;
560 "main", // const char* pName;
561 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
564 const Unique<VkShaderModule> fsModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0));
566 const VkPipelineShaderStageCreateInfo fsShaderStageInfo =
568 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
569 DE_NULL, // const void* pNext;
570 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
571 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
572 *fsModule, // VkShaderModule module;
573 "main", // const char* pName;
574 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
577 const VkPipelineShaderStageCreateInfo shaderStageInfos[] = { vsShaderStageInfo, fsShaderStageInfo };
579 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
581 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
582 DE_NULL, // const void* pNext;
583 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
584 2u, // deUint32 stageCount;
585 shaderStageInfos, // const VkPipelineShaderStageCreateInfo* pStages;
586 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
587 &inputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
588 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
589 &viewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
590 &rasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
591 &multisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
592 &depthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
593 &colorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
594 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
595 *pipelineLayout, // VkPipelineLayout layout;
596 *renderPass, // VkRenderPass renderPass;
597 0u, // deUint32 subpass;
598 DE_NULL, // VkPipeline basePipelineHandle;
599 0u, // deInt32 basePipelineIndex;
602 // Create graphics pipeline
603 const Unique<VkPipeline> graphicsPipeline(createGraphicsPipeline(deviceInterface, device, DE_NULL, &graphicsPipelineInfo));
605 // Create command buffer for compute and transfer oparations
606 const Unique<VkCommandPool> commandPool(createCommandPool(deviceInterface, device, (VkCommandPoolCreateFlags)VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
607 const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, device, *commandPool));
609 // Start recording commands
610 beginCommandBuffer(deviceInterface, *commandBuffer);
613 VkImageMemoryBarrier imageOutputAttachmentBarriers[2];
615 imageOutputAttachmentBarriers[0] = makeImageMemoryBarrier
618 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
619 VK_IMAGE_LAYOUT_UNDEFINED,
620 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
625 imageOutputAttachmentBarriers[1] = makeImageMemoryBarrier
628 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
629 VK_IMAGE_LAYOUT_UNDEFINED,
630 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
635 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageOutputAttachmentBarriers);
639 const VkDeviceSize vertexStartOffset = 0u;
641 std::vector<VkClearValue> clearValues;
642 clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
643 clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
645 const vk::VkRect2D renderArea =
647 makeOffset2D(0u, 0u),
648 makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
652 const VkRenderPassBeginInfo renderPassBeginInfo =
654 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
655 DE_NULL, // const void* pNext;
656 *renderPass, // VkRenderPass renderPass;
657 *framebuffer, // VkFramebuffer framebuffer;
658 renderArea, // VkRect2D renderArea;
659 static_cast<deUint32>(clearValues.size()), // deUint32 clearValueCount;
660 &clearValues[0], // const VkClearValue* pClearValues;
663 deviceInterface.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
665 // Bind graphics pipeline
666 deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
668 // Bind vertex buffer
669 deviceInterface.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer->get(), &vertexStartOffset);
671 // Draw full screen quad
672 deviceInterface.cmdDraw(*commandBuffer, vertexDataDesc.verticesCount, 1u, 0u, 0u);
675 deviceInterface.cmdEndRenderPass(*commandBuffer);
678 const VkImage sourceImage = m_imageMSParams.numSamples == VK_SAMPLE_COUNT_1_BIT ? **imageMS : **imageRS;
681 const VkImageMemoryBarrier imageTransferSrcBarrier = makeImageMemoryBarrier
683 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
684 VK_ACCESS_TRANSFER_READ_BIT,
685 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
686 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
691 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageTransferSrcBarrier);
694 // Copy data from resolve image to buffer
695 const deUint32 imageRSSizeInBytes = getImageSizeInBytes(imageRSInfo.extent, imageRSInfo.arrayLayers, m_imageFormat, imageRSInfo.mipLevels);
697 const VkBufferCreateInfo bufferRSInfo = makeBufferCreateInfo(imageRSSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
698 const de::UniquePtr<Buffer> bufferRS(new Buffer(deviceInterface, device, allocator, bufferRSInfo, MemoryRequirement::HostVisible));
701 const VkBufferImageCopy bufferImageCopy =
703 0u, // VkDeviceSize bufferOffset;
704 0u, // deUint32 bufferRowLength;
705 0u, // deUint32 bufferImageHeight;
706 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageRSInfo.arrayLayers), // VkImageSubresourceLayers imageSubresource;
707 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
708 imageRSInfo.extent, // VkExtent3D imageExtent;
711 deviceInterface.cmdCopyImageToBuffer(*commandBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferRS->get(), 1u, &bufferImageCopy);
715 const VkBufferMemoryBarrier bufferRSHostReadBarrier = makeBufferMemoryBarrier
717 VK_ACCESS_TRANSFER_WRITE_BIT,
718 VK_ACCESS_HOST_READ_BIT,
724 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferRSHostReadBarrier, 0u, DE_NULL);
727 // End recording commands
728 VK_CHECK(deviceInterface.endCommandBuffer(*commandBuffer));
730 // Submit commands for execution and wait for completion
731 submitCommandsAndWait(deviceInterface, device, queue, *commandBuffer);
733 // Retrieve data from buffer to host memory
734 const Allocation& bufferRSAllocation = bufferRS->getAllocation();
736 invalidateMappedMemoryRange(deviceInterface, device, bufferRSAllocation.getMemory(), bufferRSAllocation.getOffset(), imageRSSizeInBytes);
738 const tcu::ConstPixelBufferAccess bufferRSData (m_imageFormat,
739 imageRSInfo.extent.width,
740 imageRSInfo.extent.height,
741 imageRSInfo.extent.depth * imageRSInfo.arrayLayers,
742 bufferRSAllocation.getHostPtr());
744 std::stringstream imageName;
745 imageName << getImageTypeName(m_imageType) << "_" << bufferRSData.getWidth() << "_" << bufferRSData.getHeight() << "_" << bufferRSData.getDepth() << std::endl;
747 m_context.getTestContext().getLog()
748 << tcu::TestLog::Section(imageName.str(), imageName.str())
749 << tcu::LogImage("image", "", bufferRSData)
750 << tcu::TestLog::EndSection;
752 return verifyResolvedImage(bufferRSData);
755 class MSInstanceDistinctValues : public MSInterpolationInstanceBase
758 MSInstanceDistinctValues(Context& context,
759 const ImageMSParams& imageMSParams)
760 : MSInterpolationInstanceBase(context, imageMSParams) {}
762 VertexDataDesc getVertexDataDescripton (void) const;
763 void uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const;
764 tcu::TestStatus verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const;
769 VertexData(const tcu::Vec4& posNdc) : positionNdc(posNdc) {}
771 tcu::Vec4 positionNdc;
775 MSInterpolationInstanceBase::VertexDataDesc MSInstanceDistinctValues::getVertexDataDescripton (void) const
777 VertexDataDesc vertexDataDesc;
779 vertexDataDesc.verticesCount = 3u;
780 vertexDataDesc.dataStride = sizeof(VertexData);
781 vertexDataDesc.dataSize = vertexDataDesc.verticesCount * vertexDataDesc.dataStride;
782 vertexDataDesc.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
784 const VkVertexInputAttributeDescription vertexAttribPositionNdc =
786 0u, // deUint32 location;
787 0u, // deUint32 binding;
788 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
789 DE_OFFSET_OF(VertexData, positionNdc), // deUint32 offset;
792 vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc);
794 return vertexDataDesc;
797 void MSInstanceDistinctValues::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
799 std::vector<VertexData> vertices;
801 vertices.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f)));
802 vertices.push_back(VertexData(tcu::Vec4(-1.0f, 4.0f, 0.0f, 1.0f)));
803 vertices.push_back(VertexData(tcu::Vec4( 4.0f,-1.0f, 0.0f, 1.0f)));
805 deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize));
808 tcu::TestStatus MSInstanceDistinctValues::verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const
810 const deUint32 distinctValuesExpected = static_cast<deUint32>(m_imageMSParams.numSamples) + 1u;
812 std::vector<tcu::IVec4> distinctValues;
814 for (deInt32 z = 0u; z < imageData.getDepth(); ++z)
815 for (deInt32 y = 0u; y < imageData.getHeight(); ++y)
816 for (deInt32 x = 0u; x < imageData.getWidth(); ++x)
818 const tcu::IVec4 pixel = imageData.getPixelInt(x, y, z);
820 if (std::find(distinctValues.begin(), distinctValues.end(), pixel) == distinctValues.end())
821 distinctValues.push_back(pixel);
824 if (distinctValues.size() >= distinctValuesExpected)
825 return tcu::TestStatus::pass("Passed");
827 return tcu::TestStatus::fail("Failed");
830 class MSCaseSampleQualifierDistinctValues : public MSInterpolationCaseBase
833 MSCaseSampleQualifierDistinctValues (tcu::TestContext& testCtx,
834 const std::string& name,
835 const ImageMSParams& imageMSParams)
836 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
839 void initPrograms (vk::SourceCollections& programCollection) const;
840 TestInstance* createInstance (Context& context) const;
843 MSInterpolationCaseBase* createMSCaseSampleQualifierDistinctValues (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
845 return new MSCaseSampleQualifierDistinctValues(testCtx, name, imageMSParams);
848 void MSCaseSampleQualifierDistinctValues::init (void)
851 << tcu::TestLog::Message
852 << "Verifying that a sample qualified varying is given different values for different samples.\n"
853 << " Render full screen traingle with quadratic function defining red/green color pattern division.\n"
854 << " => Resulting image should contain n+1 different colors, where n = sample count.\n"
855 << tcu::TestLog::EndMessage;
857 MSInterpolationCaseBase::init();
860 void MSCaseSampleQualifierDistinctValues::initPrograms (vk::SourceCollections& programCollection) const
862 // Create vertex shader
863 std::ostringstream vs;
865 vs << "#version 440\n"
866 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
868 << "layout(location = 0) out vec4 vs_out_position_ndc;\n"
870 << "out gl_PerVertex {\n"
871 << " vec4 gl_Position;\n"
873 << "void main (void)\n"
875 << " gl_Position = vs_in_position_ndc;\n"
876 << " vs_out_position_ndc = vs_in_position_ndc;\n"
879 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
881 // Create fragment shader
882 std::ostringstream fs;
884 fs << "#version 440\n"
885 << "layout(location = 0) sample in vec4 fs_in_position_ndc;\n"
887 << "layout(location = 0) out vec2 fs_out_color;\n"
889 << "void main (void)\n"
891 << " if(fs_in_position_ndc.y < -2.0*pow(0.5*(fs_in_position_ndc.x + 1.0), 2.0) + 1.0)\n"
892 << " fs_out_color = vec2(1.0, 0.0);\n"
894 << " fs_out_color = vec2(0.0, 1.0);\n"
897 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
900 TestInstance* MSCaseSampleQualifierDistinctValues::createInstance (Context& context) const
902 return new MSInstanceDistinctValues(context, m_imageMSParams);
905 class MSCaseInterpolateAtSampleDistinctValues : public MSInterpolationCaseBase
908 MSCaseInterpolateAtSampleDistinctValues (tcu::TestContext& testCtx,
909 const std::string& name,
910 const ImageMSParams& imageMSParams)
911 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
914 void initPrograms (vk::SourceCollections& programCollection) const;
915 TestInstance* createInstance (Context& context) const;
918 MSInterpolationCaseBase* createMSCaseInterpolateAtSampleDistinctValues (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
920 return new MSCaseInterpolateAtSampleDistinctValues(testCtx, name, imageMSParams);
923 void MSCaseInterpolateAtSampleDistinctValues::init (void)
926 << tcu::TestLog::Message
927 << "Verifying that a interpolateAtSample returns different values for different samples.\n"
928 << " Render full screen traingle with quadratic function defining red/green color pattern division.\n"
929 << " => Resulting image should contain n+1 different colors, where n = sample count.\n"
930 << tcu::TestLog::EndMessage;
932 MSInterpolationCaseBase::init();
935 void MSCaseInterpolateAtSampleDistinctValues::initPrograms (vk::SourceCollections& programCollection) const
937 // Create vertex shader
938 std::ostringstream vs;
940 vs << "#version 440\n"
941 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
943 << "layout(location = 0) out vec4 vs_out_position_ndc;\n"
945 << "out gl_PerVertex {\n"
946 << " vec4 gl_Position;\n"
948 << "void main (void)\n"
950 << " gl_Position = vs_in_position_ndc;\n"
951 << " vs_out_position_ndc = vs_in_position_ndc;\n"
954 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
956 // Create fragment shader
957 std::ostringstream fs;
959 fs << "#version 440\n"
960 << "layout(location = 0) in vec4 fs_in_position_ndc;\n"
962 << "layout(location = 0) out vec2 fs_out_color;\n"
964 << "void main (void)\n"
966 << " const vec4 position_ndc_at_sample = interpolateAtSample(fs_in_position_ndc, gl_SampleID);\n"
967 << " if(position_ndc_at_sample.y < -2.0*pow(0.5*(position_ndc_at_sample.x + 1.0), 2.0) + 1.0)\n"
968 << " fs_out_color = vec2(0.0, 1.0);\n"
970 << " fs_out_color = vec2(1.0, 0.0);\n"
973 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
976 TestInstance* MSCaseInterpolateAtSampleDistinctValues::createInstance (Context& context) const
978 if (!context.getDeviceFeatures().sampleRateShading)
979 TCU_THROW(NotSupportedError, "sampleRateShading support required");
981 return new MSInstanceDistinctValues(context, m_imageMSParams);
984 class MSInstanceInterpolateScreenPosition : public MSInterpolationInstanceBase
987 MSInstanceInterpolateScreenPosition (Context& context,
988 const ImageMSParams& imageMSParams)
989 : MSInterpolationInstanceBase(context, imageMSParams) {}
991 VertexDataDesc getVertexDataDescripton (void) const;
992 void uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const;
993 tcu::TestStatus verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const;
998 VertexData(const tcu::Vec4& posNdc, const tcu::Vec2& posScreen) : positionNdc(posNdc), positionScreen(posScreen) {}
1000 tcu::Vec4 positionNdc;
1001 tcu::Vec2 positionScreen;
1005 MSInterpolationInstanceBase::VertexDataDesc MSInstanceInterpolateScreenPosition::getVertexDataDescripton (void) const
1007 VertexDataDesc vertexDataDesc;
1009 vertexDataDesc.verticesCount = 4u;
1010 vertexDataDesc.dataStride = sizeof(VertexData);
1011 vertexDataDesc.dataSize = vertexDataDesc.verticesCount * vertexDataDesc.dataStride;
1012 vertexDataDesc.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
1014 const VkVertexInputAttributeDescription vertexAttribPositionNdc =
1016 0u, // deUint32 location;
1017 0u, // deUint32 binding;
1018 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1019 DE_OFFSET_OF(VertexData, positionNdc), // deUint32 offset;
1022 vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc);
1024 const VkVertexInputAttributeDescription vertexAttribPositionScreen =
1026 1u, // deUint32 location;
1027 0u, // deUint32 binding;
1028 VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
1029 DE_OFFSET_OF(VertexData, positionScreen), // deUint32 offset;
1032 vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionScreen);
1034 return vertexDataDesc;
1037 void MSInstanceInterpolateScreenPosition::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
1039 const tcu::UVec3 layerSize = getLayerSize(IMAGE_TYPE_2D, m_imageMSParams.imageSize);
1040 const float screenSizeX = static_cast<float>(layerSize.x());
1041 const float screenSizeY = static_cast<float>(layerSize.y());
1043 std::vector<VertexData> vertices;
1045 vertices.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec2(0.0f, 0.0f)));
1046 vertices.push_back(VertexData(tcu::Vec4( 1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec2(screenSizeX, 0.0f)));
1047 vertices.push_back(VertexData(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec2(0.0f, screenSizeY)));
1048 vertices.push_back(VertexData(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec2(screenSizeX, screenSizeY)));
1050 deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize));
1053 tcu::TestStatus MSInstanceInterpolateScreenPosition::verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const
1055 for (deInt32 z = 0u; z < imageData.getDepth(); ++z)
1056 for (deInt32 y = 0u; y < imageData.getHeight(); ++y)
1057 for (deInt32 x = 0u; x < imageData.getWidth(); ++x)
1059 const deInt32 firstComponent = imageData.getPixelInt(x, y, z).x();
1061 if (firstComponent > 0)
1062 return tcu::TestStatus::fail("Failed");
1064 return tcu::TestStatus::pass("Passed");
1067 class MSCaseInterpolateAtSampleSingleSample : public MSInterpolationCaseBase
1070 MSCaseInterpolateAtSampleSingleSample (tcu::TestContext& testCtx,
1071 const std::string& name,
1072 tcu::UVec3 imageSize)
1073 : MSInterpolationCaseBase(testCtx, name, ImageMSParams(VK_SAMPLE_COUNT_1_BIT, imageSize)) {}
1076 void initPrograms (vk::SourceCollections& programCollection) const;
1077 TestInstance* createInstance (Context& context) const;
1080 void MSCaseInterpolateAtSampleSingleSample::init (void)
1083 << tcu::TestLog::Message
1084 << "Verifying that using interpolateAtSample with multisample buffers not available returns sample evaluated at the center of the pixel.\n"
1085 << " Interpolate varying containing screen space location.\n"
1086 << " => fract(screen space location) should be (about) (0.5, 0.5)\n"
1087 << tcu::TestLog::EndMessage;
1089 MSInterpolationCaseBase::init();
1092 void MSCaseInterpolateAtSampleSingleSample::initPrograms (vk::SourceCollections& programCollection) const
1094 // Create vertex shader
1095 std::ostringstream vs;
1097 vs << "#version 440\n"
1098 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
1099 << "layout(location = 1) in vec2 vs_in_position_screen;\n"
1101 << "layout(location = 0) out vec2 vs_out_position_screen;\n"
1103 << "out gl_PerVertex {\n"
1104 << " vec4 gl_Position;\n"
1106 << "void main (void)\n"
1108 << " gl_Position = vs_in_position_ndc;\n"
1109 << " vs_out_position_screen = vs_in_position_screen;\n"
1112 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
1114 // Create fragment shader
1115 std::ostringstream fs;
1117 fs << "#version 440\n"
1118 << "layout(location = 0) in vec2 fs_in_position_screen;\n"
1120 << "layout(location = 0) out vec2 fs_out_color;\n"
1122 << "void main (void)\n"
1124 << " const float threshold = 0.15625;\n"
1125 << " const vec2 position_screen_at_sample = interpolateAtSample(fs_in_position_screen, 0);\n"
1126 << " const vec2 position_inside_pixel = fract(position_screen_at_sample);\n"
1128 << " if (abs(position_inside_pixel.x - 0.5) <= threshold && abs(position_inside_pixel.y - 0.5) <= threshold)\n"
1129 << " fs_out_color = vec2(0.0, 1.0);\n"
1131 << " fs_out_color = vec2(1.0, 0.0);\n"
1134 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
1137 TestInstance* MSCaseInterpolateAtSampleSingleSample::createInstance (Context& context) const
1139 if (!context.getDeviceFeatures().sampleRateShading)
1140 TCU_THROW(NotSupportedError, "sampleRateShading support required");
1142 return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
1145 class MSCaseInterpolateAtSampleIgnoresCentroid : public MSInterpolationCaseBase
1148 MSCaseInterpolateAtSampleIgnoresCentroid(tcu::TestContext& testCtx,
1149 const std::string& name,
1150 const ImageMSParams& imageMSParams)
1151 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
1154 void initPrograms (vk::SourceCollections& programCollection) const;
1155 TestInstance* createInstance (Context& context) const;
1158 MSInterpolationCaseBase* createMSCaseInterpolateAtSampleIgnoresCentroid (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
1160 return new MSCaseInterpolateAtSampleIgnoresCentroid(testCtx, name, imageMSParams);
1163 void MSCaseInterpolateAtSampleIgnoresCentroid::init (void)
1166 << tcu::TestLog::Message
1167 << "Verifying that interpolateAtSample ignores centroid qualifier.\n"
1168 << " Interpolate varying containing screen space location with centroid and sample qualifiers.\n"
1169 << " => interpolateAtSample(screenSample, n) ~= interpolateAtSample(screenCentroid, n)\n"
1170 << tcu::TestLog::EndMessage;
1172 MSInterpolationCaseBase::init();
1175 void MSCaseInterpolateAtSampleIgnoresCentroid::initPrograms (vk::SourceCollections& programCollection) const
1177 // Create vertex shader
1178 std::ostringstream vs;
1180 vs << "#version 440\n"
1181 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
1182 << "layout(location = 1) in vec2 vs_in_position_screen;\n"
1184 << "layout(location = 0) out vec2 vs_out_pos_screen_centroid;\n"
1185 << "layout(location = 1) out vec2 vs_out_pos_screen_fragment;\n"
1187 << "out gl_PerVertex {\n"
1188 << " vec4 gl_Position;\n"
1190 << "void main (void)\n"
1192 << " gl_Position = vs_in_position_ndc;\n"
1193 << " vs_out_pos_screen_centroid = vs_in_position_screen;\n"
1194 << " vs_out_pos_screen_fragment = vs_in_position_screen;\n"
1197 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
1199 // Create fragment shader
1200 std::ostringstream fs;
1202 fs << "#version 440\n"
1203 << "layout(location = 0) centroid in vec2 fs_in_pos_screen_centroid;\n"
1204 << "layout(location = 1) in vec2 fs_in_pos_screen_fragment;\n"
1206 << "layout(location = 0) out vec2 fs_out_color;\n"
1208 << "void main (void)\n"
1210 << " const float threshold = 0.0005;\n"
1212 << " const vec2 position_a = interpolateAtSample(fs_in_pos_screen_centroid, gl_SampleID);\n"
1213 << " const vec2 position_b = interpolateAtSample(fs_in_pos_screen_fragment, gl_SampleID);\n"
1214 << " const bool valuesEqual = all(lessThan(abs(position_a - position_b), vec2(threshold)));\n"
1216 << " if (valuesEqual)\n"
1217 << " fs_out_color = vec2(0.0, 1.0);\n"
1219 << " fs_out_color = vec2(1.0, 0.0);\n"
1222 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
1225 TestInstance* MSCaseInterpolateAtSampleIgnoresCentroid::createInstance (Context& context) const
1227 if (!context.getDeviceFeatures().sampleRateShading)
1228 TCU_THROW(NotSupportedError, "sampleRateShading support required");
1230 return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
1233 class MSCaseInterpolateAtSampleConsistency : public MSInterpolationCaseBase
1236 MSCaseInterpolateAtSampleConsistency (tcu::TestContext& testCtx,
1237 const std::string& name,
1238 const ImageMSParams& imageMSParams)
1239 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
1242 void initPrograms (vk::SourceCollections& programCollection) const;
1243 TestInstance* createInstance (Context& context) const;
1246 MSInterpolationCaseBase* createMSCaseInterpolateAtSampleConsistency (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
1248 return new MSCaseInterpolateAtSampleConsistency(testCtx, name, imageMSParams);
1251 void MSCaseInterpolateAtSampleConsistency::init (void)
1254 << tcu::TestLog::Message
1255 << "Verifying that interpolateAtSample with the sample set to the current sampleID returns consistent values.\n"
1256 << " Interpolate varying containing screen space location with centroid and sample qualifiers.\n"
1257 << " => interpolateAtSample(screenCentroid, sampleID) = screenSample\n"
1258 << tcu::TestLog::EndMessage;
1260 MSInterpolationCaseBase::init();
1263 void MSCaseInterpolateAtSampleConsistency::initPrograms (vk::SourceCollections& programCollection) const
1265 // Create vertex shader
1266 std::ostringstream vs;
1268 vs << "#version 440\n"
1269 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
1270 << "layout(location = 1) in vec2 vs_in_position_screen;\n"
1272 << "layout(location = 0) out vec2 vs_out_pos_screen_centroid;\n"
1273 << "layout(location = 1) out vec2 vs_out_pos_screen_sample;\n"
1275 << "out gl_PerVertex {\n"
1276 << " vec4 gl_Position;\n"
1278 << "void main (void)\n"
1280 << " gl_Position = vs_in_position_ndc;\n"
1281 << " vs_out_pos_screen_centroid = vs_in_position_screen;\n"
1282 << " vs_out_pos_screen_sample = vs_in_position_screen;\n"
1285 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
1287 // Create fragment shader
1288 std::ostringstream fs;
1290 fs << "#version 440\n"
1291 << "layout(location = 0) centroid in vec2 fs_in_pos_screen_centroid;\n"
1292 << "layout(location = 1) sample in vec2 fs_in_pos_screen_sample;\n"
1294 << "layout(location = 0) out vec2 fs_out_color;\n"
1296 << "void main (void)\n"
1298 << " const float threshold = 0.15625;\n"
1300 << " const vec2 pos_interpolated_at_sample = interpolateAtSample(fs_in_pos_screen_centroid, gl_SampleID);\n"
1301 << " const bool valuesEqual = all(lessThan(abs(pos_interpolated_at_sample - fs_in_pos_screen_sample), vec2(threshold)));\n"
1303 << " if (valuesEqual)\n"
1304 << " fs_out_color = vec2(0.0, 1.0);\n"
1306 << " fs_out_color = vec2(1.0, 0.0);\n"
1309 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
1312 TestInstance* MSCaseInterpolateAtSampleConsistency::createInstance (Context& context) const
1314 if (!context.getDeviceFeatures().sampleRateShading)
1315 TCU_THROW(NotSupportedError, "sampleRateShading support required");
1317 return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
1320 class MSCaseInterpolateAtCentroidConsistency : public MSInterpolationCaseBase
1323 MSCaseInterpolateAtCentroidConsistency (tcu::TestContext& testCtx,
1324 const std::string& name,
1325 const ImageMSParams& imageMSParams)
1326 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
1329 void initPrograms (vk::SourceCollections& programCollection) const;
1330 TestInstance* createInstance (Context& context) const;
1333 MSInterpolationCaseBase* createMSCaseInterpolateAtCentroidConsistency (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
1335 return new MSCaseInterpolateAtCentroidConsistency(testCtx, name, imageMSParams);
1338 void MSCaseInterpolateAtCentroidConsistency::init (void)
1341 << tcu::TestLog::Message
1342 << "Verifying that interpolateAtCentroid does not return different values than a corresponding centroid qualified varying.\n"
1343 << " Interpolate varying containing screen space location with sample and centroid qualifiers.\n"
1344 << " => interpolateAtCentroid(screenSample) = screenCentroid\n"
1345 << tcu::TestLog::EndMessage;
1347 MSInterpolationCaseBase::init();
1350 void MSCaseInterpolateAtCentroidConsistency::initPrograms (vk::SourceCollections& programCollection) const
1352 // Create vertex shader
1353 std::ostringstream vs;
1355 vs << "#version 440\n"
1356 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
1357 << "layout(location = 1) in vec2 vs_in_position_screen;\n"
1359 << "layout(location = 0) out vec2 vs_out_pos_screen_sample;\n"
1360 << "layout(location = 1) out vec2 vs_out_pos_screen_centroid;\n"
1362 << "out gl_PerVertex {\n"
1363 << " vec4 gl_Position;\n"
1365 << "void main (void)\n"
1367 << " gl_Position = vs_in_position_ndc;\n"
1368 << " vs_out_pos_screen_sample = vs_in_position_screen;\n"
1369 << " vs_out_pos_screen_centroid = vs_in_position_screen;\n"
1372 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
1374 // Create fragment shader
1375 std::ostringstream fs;
1377 fs << "#version 440\n"
1378 << "layout(location = 0) sample in vec2 fs_in_pos_screen_sample;\n"
1379 << "layout(location = 1) centroid in vec2 fs_in_pos_screen_centroid;\n"
1381 << "layout(location = 0) out vec2 fs_out_color;\n"
1383 << "void main (void)\n"
1385 << " const float threshold = 0.0005;\n"
1387 << " const vec2 pos_interpolated_at_centroid = interpolateAtCentroid(fs_in_pos_screen_sample);\n"
1388 << " const bool valuesEqual = all(lessThan(abs(pos_interpolated_at_centroid - fs_in_pos_screen_centroid), vec2(threshold)));\n"
1390 << " if (valuesEqual)\n"
1391 << " fs_out_color = vec2(0.0, 1.0);\n"
1393 << " fs_out_color = vec2(1.0, 0.0);\n"
1396 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
1399 TestInstance* MSCaseInterpolateAtCentroidConsistency::createInstance (Context& context) const
1401 if (!context.getDeviceFeatures().sampleRateShading)
1402 TCU_THROW(NotSupportedError, "sampleRateShading support required");
1404 return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
1407 class MSCaseInterpolateAtOffsetPixelCenter : public MSInterpolationCaseBase
1410 MSCaseInterpolateAtOffsetPixelCenter(tcu::TestContext& testCtx,
1411 const std::string& name,
1412 const ImageMSParams& imageMSParams)
1413 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
1416 void initPrograms (vk::SourceCollections& programCollection) const;
1417 TestInstance* createInstance (Context& context) const;
1420 MSInterpolationCaseBase* createMSCaseInterpolateAtOffsetPixelCenter (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
1422 return new MSCaseInterpolateAtOffsetPixelCenter(testCtx, name, imageMSParams);
1425 void MSCaseInterpolateAtOffsetPixelCenter::init (void)
1428 << tcu::TestLog::Message
1429 << "Verifying that interpolateAtOffset returns value sampled at an offset from the center of the pixel.\n"
1430 << " Interpolate varying containing screen space location.\n"
1431 << " => interpolateAtOffset(screen, offset) should be \"varying value at the pixel center\" + offset"
1432 << tcu::TestLog::EndMessage;
1434 MSInterpolationCaseBase::init();
1437 void MSCaseInterpolateAtOffsetPixelCenter::initPrograms (vk::SourceCollections& programCollection) const
1439 // Create vertex shader
1440 std::ostringstream vs;
1442 vs << "#version 440\n"
1443 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
1444 << "layout(location = 1) in vec2 vs_in_position_screen;\n"
1446 << "layout(location = 0) out vec2 vs_out_pos_screen;\n"
1447 << "layout(location = 1) out vec2 vs_out_offset;\n"
1449 << "out gl_PerVertex {\n"
1450 << " vec4 gl_Position;\n"
1452 << "void main (void)\n"
1454 << " gl_Position = vs_in_position_ndc;\n"
1455 << " vs_out_pos_screen = vs_in_position_screen;\n"
1456 << " vs_out_offset = vs_in_position_ndc.xy * 0.5;\n"
1459 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
1461 // Create fragment shader
1462 std::ostringstream fs;
1464 fs << "#version 440\n"
1465 << "layout(location = 0) in vec2 fs_in_pos_screen;\n"
1466 << "layout(location = 1) in vec2 fs_in_offset;\n"
1468 << "layout(location = 0) out vec2 fs_out_color;\n"
1470 << "void main (void)\n"
1472 << " const vec2 frag_center = interpolateAtOffset(fs_in_pos_screen, vec2(0.0));\n"
1473 << " const vec2 center_diff = abs(frag_center - fs_in_pos_screen);\n"
1474 << " const float threshold = 0.125;\n"
1475 << " bool valuesEqual = false;\n"
1477 << " if (all(lessThan(center_diff, vec2(0.5 + threshold)))) {\n"
1478 << " const vec2 pos_interpolated_at_offset = interpolateAtOffset(fs_in_pos_screen, fs_in_offset);\n"
1479 << " const vec2 reference_value = frag_center + fs_in_offset;\n"
1481 << " valuesEqual = all(lessThan(abs(pos_interpolated_at_offset - reference_value), vec2(threshold)));\n"
1484 << " if (valuesEqual)\n"
1485 << " fs_out_color = vec2(0.0, 1.0);\n"
1487 << " fs_out_color = vec2(1.0, 0.0);\n"
1490 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
1493 TestInstance* MSCaseInterpolateAtOffsetPixelCenter::createInstance (Context& context) const
1495 if (!context.getDeviceFeatures().sampleRateShading)
1496 TCU_THROW(NotSupportedError, "sampleRateShading support required");
1498 return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
1501 class MSCaseInterpolateAtOffsetSamplePosition : public MSInterpolationCaseBase
1504 MSCaseInterpolateAtOffsetSamplePosition (tcu::TestContext& testCtx,
1505 const std::string& name,
1506 const ImageMSParams& imageMSParams)
1507 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
1510 void initPrograms (vk::SourceCollections& programCollection) const;
1511 TestInstance* createInstance (Context& context) const;
1514 MSInterpolationCaseBase* createMSCaseInterpolateAtOffsetSamplePosition (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
1516 return new MSCaseInterpolateAtOffsetSamplePosition(testCtx, name, imageMSParams);
1519 void MSCaseInterpolateAtOffsetSamplePosition::init (void)
1522 << tcu::TestLog::Message
1523 << "Verifying that interpolateAtOffset of screen position with the offset of current sample position returns value "
1524 << "similar to screen position interpolated at sample.\n"
1525 << " Interpolate varying containing screen space location with and without sample qualifier.\n"
1526 << " => interpolateAtOffset(screenFragment, samplePosition - (0.5,0.5)) = screenSample"
1527 << tcu::TestLog::EndMessage;
1529 MSInterpolationCaseBase::init();
1532 void MSCaseInterpolateAtOffsetSamplePosition::initPrograms (vk::SourceCollections& programCollection) const
1534 // Create vertex shader
1535 std::ostringstream vs;
1537 vs << "#version 440\n"
1538 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
1539 << "layout(location = 1) in vec2 vs_in_position_screen;\n"
1541 << "layout(location = 0) out vec2 vs_out_pos_screen_fragment;\n"
1542 << "layout(location = 1) out vec2 vs_out_pos_screen_sample;\n"
1544 << "out gl_PerVertex {\n"
1545 << " vec4 gl_Position;\n"
1547 << "void main (void)\n"
1549 << " gl_Position = vs_in_position_ndc;\n"
1550 << " vs_out_pos_screen_fragment = vs_in_position_screen;\n"
1551 << " vs_out_pos_screen_sample = vs_in_position_screen;\n"
1554 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
1556 // Create fragment shader
1557 std::ostringstream fs;
1559 fs << "#version 440\n"
1560 << "layout(location = 0) in vec2 fs_in_pos_screen_fragment;\n"
1561 << "layout(location = 1) sample in vec2 fs_in_pos_screen_sample;\n"
1563 << "layout(location = 0) out vec2 fs_out_color;\n"
1565 << "void main (void)\n"
1567 << " const float threshold = 0.15625;\n"
1569 << " const vec2 offset = gl_SamplePosition - vec2(0.5, 0.5);\n"
1570 << " const vec2 pos_interpolated_at_offset = interpolateAtOffset(fs_in_pos_screen_fragment, offset);\n"
1571 << " const bool valuesEqual = all(lessThan(abs(pos_interpolated_at_offset - fs_in_pos_screen_sample), vec2(threshold)));\n"
1573 << " if (valuesEqual)\n"
1574 << " fs_out_color = vec2(0.0, 1.0);\n"
1576 << " fs_out_color = vec2(1.0, 0.0);\n"
1579 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
1582 TestInstance* MSCaseInterpolateAtOffsetSamplePosition::createInstance (Context& context) const
1584 if (!context.getDeviceFeatures().sampleRateShading)
1585 TCU_THROW(NotSupportedError, "sampleRateShading support required");
1587 return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
1590 class MSInstanceInterpolateBarycentricCoordinates : public MSInterpolationInstanceBase
1593 MSInstanceInterpolateBarycentricCoordinates (Context& context,
1594 const ImageMSParams& imageMSParams)
1595 : MSInterpolationInstanceBase(context, imageMSParams) {}
1597 VertexDataDesc getVertexDataDescripton (void) const;
1598 void uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const;
1599 tcu::TestStatus verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const;
1604 VertexData(const tcu::Vec4& posNdc, const tcu::Vec3& barCoord) : positionNdc(posNdc), barycentricCoord(barCoord) {}
1606 tcu::Vec4 positionNdc;
1607 tcu::Vec3 barycentricCoord;
1611 MSInterpolationInstanceBase::VertexDataDesc MSInstanceInterpolateBarycentricCoordinates::getVertexDataDescripton (void) const
1613 VertexDataDesc vertexDataDesc;
1615 vertexDataDesc.verticesCount = 3u;
1616 vertexDataDesc.dataStride = sizeof(VertexData);
1617 vertexDataDesc.dataSize = vertexDataDesc.verticesCount * vertexDataDesc.dataStride;
1618 vertexDataDesc.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1620 const VkVertexInputAttributeDescription vertexAttribPositionNdc =
1622 0u, // deUint32 location;
1623 0u, // deUint32 binding;
1624 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1625 DE_OFFSET_OF(VertexData, positionNdc), // deUint32 offset;
1628 vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc);
1630 const VkVertexInputAttributeDescription vertexAttrBarCoord =
1632 1u, // deUint32 location;
1633 0u, // deUint32 binding;
1634 VK_FORMAT_R32G32B32_SFLOAT, // VkFormat format;
1635 DE_OFFSET_OF(VertexData, barycentricCoord), // deUint32 offset;
1638 vertexDataDesc.vertexAttribDescVec.push_back(vertexAttrBarCoord);
1640 return vertexDataDesc;
1643 void MSInstanceInterpolateBarycentricCoordinates::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
1645 // Create buffer storing vertex data
1646 std::vector<VertexData> vertices;
1648 vertices.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec3(0.0f, 0.0f, 1.0f)));
1649 vertices.push_back(VertexData(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec3(1.0f, 0.0f, 0.0f)));
1650 vertices.push_back(VertexData(tcu::Vec4( 1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec3(0.0f, 1.0f, 0.0f)));
1652 deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize));
1655 tcu::TestStatus MSInstanceInterpolateBarycentricCoordinates::verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const
1657 for (deInt32 z = 0u; z < imageData.getDepth(); ++z)
1658 for (deInt32 y = 0u; y < imageData.getHeight(); ++y)
1659 for (deInt32 x = 0u; x < imageData.getWidth(); ++x)
1661 const deInt32 firstComponent = imageData.getPixelInt(x, y, z).x();
1663 if (firstComponent > 0)
1664 return tcu::TestStatus::fail("Failed");
1667 return tcu::TestStatus::pass("Passed");
1670 class MSCaseCentroidQualifierInsidePrimitive : public MSInterpolationCaseBase
1673 MSCaseCentroidQualifierInsidePrimitive (tcu::TestContext& testCtx,
1674 const std::string& name,
1675 const ImageMSParams& imageMSParams)
1676 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
1679 void initPrograms (vk::SourceCollections& programCollection) const;
1680 TestInstance* createInstance (Context& context) const;
1683 MSInterpolationCaseBase* createMSCaseCentroidQualifierInsidePrimitive (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
1685 return new MSCaseCentroidQualifierInsidePrimitive(testCtx, name, imageMSParams);
1688 void MSCaseCentroidQualifierInsidePrimitive::init (void)
1691 << tcu::TestLog::Message
1692 << "Verifying that varying qualified with centroid is interpolated at location inside both the pixel and the primitive being processed.\n"
1693 << " Interpolate triangle's barycentric coordinates with centroid qualifier.\n"
1694 << " => After interpolation we expect barycentric.xyz >= 0.0 && barycentric.xyz <= 1.0\n"
1695 << tcu::TestLog::EndMessage;
1697 MSInterpolationCaseBase::init();
1700 void MSCaseCentroidQualifierInsidePrimitive::initPrograms (vk::SourceCollections& programCollection) const
1702 // Create vertex shader
1703 std::ostringstream vs;
1705 vs << "#version 440\n"
1706 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
1707 << "layout(location = 1) in vec3 vs_in_barCoord;\n"
1709 << "layout(location = 0) out vec3 vs_out_barCoord;\n"
1711 << "out gl_PerVertex {\n"
1712 << " vec4 gl_Position;\n"
1714 << "void main (void)\n"
1716 << " gl_Position = vs_in_position_ndc;\n"
1717 << " vs_out_barCoord = vs_in_barCoord;\n"
1720 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
1722 // Create fragment shader
1723 std::ostringstream fs;
1725 fs << "#version 440\n"
1726 << "layout(location = 0) centroid in vec3 fs_in_barCoord;\n"
1728 << "layout(location = 0) out vec2 fs_out_color;\n"
1730 << "void main (void)\n"
1732 << " if( all(greaterThanEqual(fs_in_barCoord, vec3(0.0))) && all(lessThanEqual(fs_in_barCoord, vec3(1.0))) )\n"
1733 << " fs_out_color = vec2(0.0, 1.0);\n"
1735 << " fs_out_color = vec2(1.0, 0.0);\n"
1738 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
1741 TestInstance* MSCaseCentroidQualifierInsidePrimitive::createInstance (Context& context) const
1743 return new MSInstanceInterpolateBarycentricCoordinates(context, m_imageMSParams);
1748 tcu::TestCaseGroup* makeGroup( multisample::MSInterpolationCaseFuncPtr createCaseFuncPtr,
1749 tcu::TestContext& testCtx,
1750 const std::string groupName,
1751 const tcu::UVec3 imageSizes[],
1752 const deUint32 imageSizesElemCount,
1753 const vk::VkSampleCountFlagBits imageSamples[],
1754 const deUint32 imageSamplesElemCount)
1756 de::MovePtr<tcu::TestCaseGroup> caseGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), ""));
1758 for (deUint32 imageSizeNdx = 0u; imageSizeNdx < imageSizesElemCount; ++imageSizeNdx)
1760 const tcu::UVec3 imageSize = imageSizes[imageSizeNdx];
1761 std::ostringstream imageSizeStream;
1763 imageSizeStream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
1765 de::MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(testCtx, imageSizeStream.str().c_str(), ""));
1767 for (deUint32 imageSamplesNdx = 0u; imageSamplesNdx < imageSamplesElemCount; ++imageSamplesNdx)
1769 const vk::VkSampleCountFlagBits samples = imageSamples[imageSamplesNdx];
1770 const multisample::ImageMSParams imageMSParams = multisample::ImageMSParams(samples, imageSize);
1772 sizeGroup->addChild(createCaseFuncPtr(testCtx, "samples_" + de::toString(samples), imageMSParams));
1775 caseGroup->addChild(sizeGroup.release());
1777 return caseGroup.release();
1780 tcu::TestCaseGroup* createMultisampleInterpolationTests (tcu::TestContext& testCtx)
1782 de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "multisample_interpolation", "Multisample Interpolation"));
1784 const tcu::UVec3 imageSizes[] =
1786 tcu::UVec3(128u, 128u, 1u),
1787 tcu::UVec3(137u, 191u, 1u),
1790 const deUint32 sizesElemCount = static_cast<deUint32>(sizeof(imageSizes) / sizeof(tcu::UVec3));
1792 const vk::VkSampleCountFlagBits imageSamples[] =
1794 vk::VK_SAMPLE_COUNT_2_BIT,
1795 vk::VK_SAMPLE_COUNT_4_BIT,
1796 vk::VK_SAMPLE_COUNT_8_BIT,
1797 vk::VK_SAMPLE_COUNT_16_BIT,
1798 vk::VK_SAMPLE_COUNT_32_BIT,
1799 vk::VK_SAMPLE_COUNT_64_BIT,
1802 const deUint32 samplesElemCount = static_cast<deUint32>(sizeof(imageSamples) / sizeof(vk::VkSampleCountFlagBits));
1804 de::MovePtr<tcu::TestCaseGroup> caseGroup(new tcu::TestCaseGroup(testCtx, "sample_interpolate_at_single_sample_", ""));
1806 for (deUint32 imageSizeNdx = 0u; imageSizeNdx < sizesElemCount; ++imageSizeNdx)
1808 const tcu::UVec3 imageSize = imageSizes[imageSizeNdx];
1809 std::ostringstream imageSizeStream;
1811 imageSizeStream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
1813 de::MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(testCtx, imageSizeStream.str().c_str(), ""));
1815 sizeGroup->addChild(new multisample::MSCaseInterpolateAtSampleSingleSample(testCtx, "samples_" + de::toString(1), imageSize));
1817 caseGroup->addChild(sizeGroup.release());
1820 testGroup->addChild(caseGroup.release());
1822 testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtSampleDistinctValues, testCtx, "sample_interpolate_at_distinct_values", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1823 testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtSampleIgnoresCentroid, testCtx, "sample_interpolate_at_ignores_centroid", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1824 testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtSampleConsistency, testCtx, "sample_interpolate_at_consistency", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1825 testGroup->addChild(makeGroup(multisample::createMSCaseSampleQualifierDistinctValues, testCtx, "sample_qualifier_distinct_values", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1826 testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtCentroidConsistency, testCtx, "centroid_interpolate_at_consistency", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1827 testGroup->addChild(makeGroup(multisample::createMSCaseCentroidQualifierInsidePrimitive, testCtx, "centroid_qualifier_inside_primitive", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1828 testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtOffsetPixelCenter, testCtx, "offset_interpolate_at_pixel_center", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1829 testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtOffsetSamplePosition, testCtx, "offset_interpolate_at_sample_position", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1831 return testGroup.release();