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 Allocator& allocator = m_context.getDefaultAllocator();
252 const VkQueue queue = m_context.getUniversalQueue();
253 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
255 VkImageCreateInfo imageMSInfo;
256 VkImageCreateInfo imageRSInfo;
258 // Check if image size does not exceed device limits
259 validateImageSize(instance, physicalDevice, m_imageType, m_imageMSParams.imageSize);
261 // Check if device supports image format as color attachment
262 validateImageFeatureFlags(instance, physicalDevice, mapTextureFormat(m_imageFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
264 imageMSInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
265 imageMSInfo.pNext = DE_NULL;
266 imageMSInfo.flags = 0u;
267 imageMSInfo.imageType = mapImageType(m_imageType);
268 imageMSInfo.format = mapTextureFormat(m_imageFormat);
269 imageMSInfo.extent = makeExtent3D(getLayerSize(m_imageType, m_imageMSParams.imageSize));
270 imageMSInfo.arrayLayers = getNumLayers(m_imageType, m_imageMSParams.imageSize);
271 imageMSInfo.mipLevels = 1u;
272 imageMSInfo.samples = m_imageMSParams.numSamples;
273 imageMSInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
274 imageMSInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
275 imageMSInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
276 imageMSInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
277 imageMSInfo.queueFamilyIndexCount = 0u;
278 imageMSInfo.pQueueFamilyIndices = DE_NULL;
280 if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
282 imageMSInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
285 validateImageInfo(instance, physicalDevice, imageMSInfo);
287 const de::UniquePtr<Image> imageMS(new Image(deviceInterface, device, allocator, imageMSInfo, MemoryRequirement::Any));
289 imageRSInfo = imageMSInfo;
290 imageRSInfo.samples = VK_SAMPLE_COUNT_1_BIT;
292 validateImageInfo(instance, physicalDevice, imageRSInfo);
294 const de::UniquePtr<Image> imageRS(new Image(deviceInterface, device, allocator, imageRSInfo, MemoryRequirement::Any));
296 // Create render pass
297 const VkAttachmentDescription attachmentMSDesc =
299 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
300 imageMSInfo.format, // VkFormat format;
301 imageMSInfo.samples, // VkSampleCountFlagBits samples;
302 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
303 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
304 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
305 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
306 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
307 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
310 const VkAttachmentDescription attachmentRSDesc =
312 (VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags;
313 imageRSInfo.format, // VkFormat format;
314 imageRSInfo.samples, // VkSampleCountFlagBits samples;
315 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
316 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
317 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
318 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
319 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
320 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
323 const VkAttachmentDescription attachments[] = { attachmentMSDesc, attachmentRSDesc };
325 const VkAttachmentReference attachmentMSRef =
327 0u, // deUint32 attachment;
328 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
331 const VkAttachmentReference attachmentRSRef =
333 1u, // deUint32 attachment;
334 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
337 const VkAttachmentReference* resolveAttachment = m_imageMSParams.numSamples == VK_SAMPLE_COUNT_1_BIT ? DE_NULL : &attachmentRSRef;
339 const VkSubpassDescription subpassDescription =
341 (VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags;
342 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
343 0u, // deUint32 inputAttachmentCount;
344 DE_NULL, // const VkAttachmentReference* pInputAttachments;
345 1u, // deUint32 colorAttachmentCount;
346 &attachmentMSRef, // const VkAttachmentReference* pColorAttachments;
347 resolveAttachment, // const VkAttachmentReference* pResolveAttachments;
348 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
349 0u, // deUint32 preserveAttachmentCount;
350 DE_NULL // const deUint32* pPreserveAttachments;
353 const VkRenderPassCreateInfo renderPassInfo =
355 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
356 DE_NULL, // const void* pNext;
357 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags;
358 2u, // deUint32 attachmentCount;
359 attachments, // const VkAttachmentDescription* pAttachments;
360 1u, // deUint32 subpassCount;
361 &subpassDescription, // const VkSubpassDescription* pSubpasses;
362 0u, // deUint32 dependencyCount;
363 DE_NULL // const VkSubpassDependency* pDependencies;
366 const Unique<VkRenderPass> renderPass(createRenderPass(deviceInterface, device, &renderPassInfo));
368 const VkImageSubresourceRange fullImageRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageMSInfo.mipLevels, 0u, imageMSInfo.arrayLayers);
370 // Create color attachments image views
371 const Unique<VkImageView> imageMSView(makeImageView(deviceInterface, device, **imageMS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
372 const Unique<VkImageView> imageRSView(makeImageView(deviceInterface, device, **imageRS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
374 const VkImageView attachmentsViews[] = { *imageMSView, *imageRSView };
376 // Create framebuffer
377 const VkFramebufferCreateInfo framebufferInfo =
379 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
380 DE_NULL, // const void* pNext;
381 (VkFramebufferCreateFlags)0u, // VkFramebufferCreateFlags flags;
382 *renderPass, // VkRenderPass renderPass;
383 2u, // uint32_t attachmentCount;
384 attachmentsViews, // const VkImageView* pAttachments;
385 imageMSInfo.extent.width, // uint32_t width;
386 imageMSInfo.extent.height, // uint32_t height;
387 imageMSInfo.arrayLayers, // uint32_t layers;
390 const Unique<VkFramebuffer> framebuffer(createFramebuffer(deviceInterface, device, &framebufferInfo));
392 // Create pipeline layout
393 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
395 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
396 DE_NULL, // const void* pNext;
397 (VkPipelineLayoutCreateFlags)0u, // VkPipelineLayoutCreateFlags flags;
398 0u, // deUint32 setLayoutCount;
399 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
400 0u, // deUint32 pushConstantRangeCount;
401 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
404 const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(deviceInterface, device, &pipelineLayoutParams));
406 // Create vertex attributes data
407 const VertexDataDesc vertexDataDesc = getVertexDataDescripton();
409 de::SharedPtr<Buffer> vertexBuffer = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, makeBufferCreateInfo(vertexDataDesc.dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
410 const Allocation& vertexBufferAllocation = vertexBuffer->getAllocation();
412 uploadVertexData(vertexBufferAllocation, vertexDataDesc);
414 flushMappedMemoryRange(deviceInterface, device, vertexBufferAllocation.getMemory(), vertexBufferAllocation.getOffset(), vertexDataDesc.dataSize);
416 const VkVertexInputBindingDescription vertexBinding =
418 0u, // deUint32 binding;
419 vertexDataDesc.dataStride, // deUint32 stride;
420 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
423 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
425 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
426 DE_NULL, // const void* pNext;
427 (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags flags;
428 1u, // uint32_t vertexBindingDescriptionCount;
429 &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
430 static_cast<deUint32>(vertexDataDesc.vertexAttribDescVec.size()), // uint32_t vertexAttributeDescriptionCount;
431 dataPointer(vertexDataDesc.vertexAttribDescVec), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
434 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo =
436 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
437 DE_NULL, // const void* pNext;
438 (VkPipelineInputAssemblyStateCreateFlags)0u, // VkPipelineInputAssemblyStateCreateFlags flags;
439 vertexDataDesc.primitiveTopology, // VkPrimitiveTopology topology;
440 VK_FALSE, // VkBool32 primitiveRestartEnable;
443 const VkViewport viewport =
446 static_cast<float>(imageMSInfo.extent.width), static_cast<float>(imageMSInfo.extent.height),
450 const VkRect2D scissor =
453 makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
456 const VkPipelineViewportStateCreateInfo viewportStateInfo =
458 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
459 DE_NULL, // const void* pNext;
460 (VkPipelineViewportStateCreateFlags)0u, // VkPipelineViewportStateCreateFlags flags;
461 1u, // uint32_t viewportCount;
462 &viewport, // const VkViewport* pViewports;
463 1u, // uint32_t scissorCount;
464 &scissor, // const VkRect2D* pScissors;
467 const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo =
469 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
470 DE_NULL, // const void* pNext;
471 (VkPipelineRasterizationStateCreateFlags)0u, // VkPipelineRasterizationStateCreateFlags flags;
472 VK_FALSE, // VkBool32 depthClampEnable;
473 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
474 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
475 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
476 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
477 VK_FALSE, // VkBool32 depthBiasEnable;
478 0.0f, // float depthBiasConstantFactor;
479 0.0f, // float depthBiasClamp;
480 0.0f, // float depthBiasSlopeFactor;
481 1.0f, // float lineWidth;
484 const VkPipelineMultisampleStateCreateInfo multisampleStateInfo =
486 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
487 DE_NULL, // const void* pNext;
488 (VkPipelineMultisampleStateCreateFlags)0u, // VkPipelineMultisampleStateCreateFlags flags;
489 imageMSInfo.samples, // VkSampleCountFlagBits rasterizationSamples;
490 VK_TRUE, // VkBool32 sampleShadingEnable;
491 1.0f, // float minSampleShading;
492 DE_NULL, // const VkSampleMask* pSampleMask;
493 VK_FALSE, // VkBool32 alphaToCoverageEnable;
494 VK_FALSE, // VkBool32 alphaToOneEnable;
497 const VkStencilOpState stencilOpState = makeStencilOpState
499 VK_STENCIL_OP_KEEP, // stencil fail
500 VK_STENCIL_OP_KEEP, // depth & stencil pass
501 VK_STENCIL_OP_KEEP, // depth only fail
502 VK_COMPARE_OP_ALWAYS, // compare op
508 const VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo =
510 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
511 DE_NULL, // const void* pNext;
512 (VkPipelineDepthStencilStateCreateFlags)0u, // VkPipelineDepthStencilStateCreateFlags flags;
513 VK_FALSE, // VkBool32 depthTestEnable;
514 VK_FALSE, // VkBool32 depthWriteEnable;
515 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
516 VK_FALSE, // VkBool32 depthBoundsTestEnable;
517 VK_FALSE, // VkBool32 stencilTestEnable;
518 stencilOpState, // VkStencilOpState front;
519 stencilOpState, // VkStencilOpState back;
520 0.0f, // float minDepthBounds;
521 1.0f, // float maxDepthBounds;
524 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
526 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
528 VK_FALSE, // VkBool32 blendEnable;
529 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
530 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor;
531 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
532 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
533 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstAlphaBlendFactor;
534 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
535 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
538 const VkPipelineColorBlendStateCreateInfo colorBlendStateInfo =
540 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
541 DE_NULL, // const void* pNext;
542 (VkPipelineColorBlendStateCreateFlags)0u, // VkPipelineColorBlendStateCreateFlags flags;
543 VK_FALSE, // VkBool32 logicOpEnable;
544 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
545 1u, // deUint32 attachmentCount;
546 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
547 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
550 const Unique<VkShaderModule> vsModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0));
552 const VkPipelineShaderStageCreateInfo vsShaderStageInfo =
554 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
555 DE_NULL, // const void* pNext;
556 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
557 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
558 *vsModule, // VkShaderModule module;
559 "main", // const char* pName;
560 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
563 const Unique<VkShaderModule> fsModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0));
565 const VkPipelineShaderStageCreateInfo fsShaderStageInfo =
567 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
568 DE_NULL, // const void* pNext;
569 (VkPipelineShaderStageCreateFlags)0u, // VkPipelineShaderStageCreateFlags flags;
570 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
571 *fsModule, // VkShaderModule module;
572 "main", // const char* pName;
573 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
576 const VkPipelineShaderStageCreateInfo shaderStageInfos[] = { vsShaderStageInfo, fsShaderStageInfo };
578 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
580 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
581 DE_NULL, // const void* pNext;
582 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
583 2u, // deUint32 stageCount;
584 shaderStageInfos, // const VkPipelineShaderStageCreateInfo* pStages;
585 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
586 &inputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
587 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
588 &viewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState;
589 &rasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
590 &multisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
591 &depthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
592 &colorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
593 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
594 *pipelineLayout, // VkPipelineLayout layout;
595 *renderPass, // VkRenderPass renderPass;
596 0u, // deUint32 subpass;
597 DE_NULL, // VkPipeline basePipelineHandle;
598 0u, // deInt32 basePipelineIndex;
601 // Create graphics pipeline
602 const Unique<VkPipeline> graphicsPipeline(createGraphicsPipeline(deviceInterface, device, DE_NULL, &graphicsPipelineInfo));
604 // Create command buffer for compute and transfer oparations
605 const Unique<VkCommandPool> commandPool(createCommandPool(deviceInterface, device, (VkCommandPoolCreateFlags)VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
606 const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, device, *commandPool));
608 // Start recording commands
609 beginCommandBuffer(deviceInterface, *commandBuffer);
612 VkImageMemoryBarrier imageOutputAttachmentBarriers[2];
614 imageOutputAttachmentBarriers[0] = makeImageMemoryBarrier
617 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
618 VK_IMAGE_LAYOUT_UNDEFINED,
619 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
624 imageOutputAttachmentBarriers[1] = makeImageMemoryBarrier
627 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
628 VK_IMAGE_LAYOUT_UNDEFINED,
629 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
634 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);
638 const VkDeviceSize vertexStartOffset = 0u;
640 std::vector<VkClearValue> clearValues;
641 clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
642 clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
644 const vk::VkRect2D renderArea =
646 makeOffset2D(0u, 0u),
647 makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
651 const VkRenderPassBeginInfo renderPassBeginInfo =
653 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
654 DE_NULL, // const void* pNext;
655 *renderPass, // VkRenderPass renderPass;
656 *framebuffer, // VkFramebuffer framebuffer;
657 renderArea, // VkRect2D renderArea;
658 static_cast<deUint32>(clearValues.size()), // deUint32 clearValueCount;
659 &clearValues[0], // const VkClearValue* pClearValues;
662 deviceInterface.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
664 // Bind graphics pipeline
665 deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
667 // Bind vertex buffer
668 deviceInterface.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer->get(), &vertexStartOffset);
670 // Draw full screen quad
671 deviceInterface.cmdDraw(*commandBuffer, vertexDataDesc.verticesCount, 1u, 0u, 0u);
674 deviceInterface.cmdEndRenderPass(*commandBuffer);
677 const VkImage sourceImage = m_imageMSParams.numSamples == VK_SAMPLE_COUNT_1_BIT ? **imageMS : **imageRS;
680 const VkImageMemoryBarrier imageTransferSrcBarrier = makeImageMemoryBarrier
682 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
683 VK_ACCESS_TRANSFER_READ_BIT,
684 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
685 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
690 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageTransferSrcBarrier);
693 // Copy data from resolve image to buffer
694 const deUint32 imageRSSizeInBytes = getImageSizeInBytes(imageRSInfo.extent, imageRSInfo.arrayLayers, m_imageFormat, imageRSInfo.mipLevels);
696 const VkBufferCreateInfo bufferRSInfo = makeBufferCreateInfo(imageRSSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
697 const de::UniquePtr<Buffer> bufferRS(new Buffer(deviceInterface, device, allocator, bufferRSInfo, MemoryRequirement::HostVisible));
700 const VkBufferImageCopy bufferImageCopy =
702 0u, // VkDeviceSize bufferOffset;
703 0u, // deUint32 bufferRowLength;
704 0u, // deUint32 bufferImageHeight;
705 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageRSInfo.arrayLayers), // VkImageSubresourceLayers imageSubresource;
706 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
707 imageRSInfo.extent, // VkExtent3D imageExtent;
710 deviceInterface.cmdCopyImageToBuffer(*commandBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferRS->get(), 1u, &bufferImageCopy);
714 const VkBufferMemoryBarrier bufferRSHostReadBarrier = makeBufferMemoryBarrier
716 VK_ACCESS_TRANSFER_WRITE_BIT,
717 VK_ACCESS_HOST_READ_BIT,
723 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferRSHostReadBarrier, 0u, DE_NULL);
726 // End recording commands
727 VK_CHECK(deviceInterface.endCommandBuffer(*commandBuffer));
729 // Submit commands for execution and wait for completion
730 submitCommandsAndWait(deviceInterface, device, queue, *commandBuffer);
732 // Retrieve data from buffer to host memory
733 const Allocation& bufferRSAllocation = bufferRS->getAllocation();
735 invalidateMappedMemoryRange(deviceInterface, device, bufferRSAllocation.getMemory(), bufferRSAllocation.getOffset(), imageRSSizeInBytes);
737 const tcu::ConstPixelBufferAccess bufferRSData (m_imageFormat,
738 imageRSInfo.extent.width,
739 imageRSInfo.extent.height,
740 imageRSInfo.extent.depth * imageRSInfo.arrayLayers,
741 bufferRSAllocation.getHostPtr());
743 std::stringstream imageName;
744 imageName << getImageTypeName(m_imageType) << "_" << bufferRSData.getWidth() << "_" << bufferRSData.getHeight() << "_" << bufferRSData.getDepth() << std::endl;
746 m_context.getTestContext().getLog()
747 << tcu::TestLog::Section(imageName.str(), imageName.str())
748 << tcu::LogImage("image", "", bufferRSData)
749 << tcu::TestLog::EndSection;
751 return verifyResolvedImage(bufferRSData);
754 class MSInstanceDistinctValues : public MSInterpolationInstanceBase
757 MSInstanceDistinctValues(Context& context,
758 const ImageMSParams& imageMSParams)
759 : MSInterpolationInstanceBase(context, imageMSParams) {}
761 VertexDataDesc getVertexDataDescripton (void) const;
762 void uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const;
763 tcu::TestStatus verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const;
768 VertexData(const tcu::Vec4& posNdc) : positionNdc(posNdc) {}
770 tcu::Vec4 positionNdc;
774 MSInterpolationInstanceBase::VertexDataDesc MSInstanceDistinctValues::getVertexDataDescripton (void) const
776 VertexDataDesc vertexDataDesc;
778 vertexDataDesc.verticesCount = 3u;
779 vertexDataDesc.dataStride = sizeof(VertexData);
780 vertexDataDesc.dataSize = vertexDataDesc.verticesCount * vertexDataDesc.dataStride;
781 vertexDataDesc.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
783 const VkVertexInputAttributeDescription vertexAttribPositionNdc =
785 0u, // deUint32 location;
786 0u, // deUint32 binding;
787 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
788 DE_OFFSET_OF(VertexData, positionNdc), // deUint32 offset;
791 vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc);
793 return vertexDataDesc;
796 void MSInstanceDistinctValues::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
798 std::vector<VertexData> vertices;
800 vertices.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f)));
801 vertices.push_back(VertexData(tcu::Vec4(-1.0f, 4.0f, 0.0f, 1.0f)));
802 vertices.push_back(VertexData(tcu::Vec4( 4.0f,-1.0f, 0.0f, 1.0f)));
804 deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize));
807 tcu::TestStatus MSInstanceDistinctValues::verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const
809 const deUint32 distinctValuesExpected = static_cast<deUint32>(m_imageMSParams.numSamples) + 1u;
811 std::vector<tcu::IVec4> distinctValues;
813 for (deInt32 z = 0u; z < imageData.getDepth(); ++z)
814 for (deInt32 y = 0u; y < imageData.getHeight(); ++y)
815 for (deInt32 x = 0u; x < imageData.getWidth(); ++x)
817 const tcu::IVec4 pixel = imageData.getPixelInt(x, y, z);
819 if (std::find(distinctValues.begin(), distinctValues.end(), pixel) == distinctValues.end())
820 distinctValues.push_back(pixel);
823 if (distinctValues.size() >= distinctValuesExpected)
824 return tcu::TestStatus::pass("Passed");
826 return tcu::TestStatus::fail("Failed");
829 class MSCaseSampleQualifierDistinctValues : public MSInterpolationCaseBase
832 MSCaseSampleQualifierDistinctValues (tcu::TestContext& testCtx,
833 const std::string& name,
834 const ImageMSParams& imageMSParams)
835 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
838 void initPrograms (vk::SourceCollections& programCollection) const;
839 TestInstance* createInstance (Context& context) const;
842 MSInterpolationCaseBase* createMSCaseSampleQualifierDistinctValues (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
844 return new MSCaseSampleQualifierDistinctValues(testCtx, name, imageMSParams);
847 void MSCaseSampleQualifierDistinctValues::init (void)
850 << tcu::TestLog::Message
851 << "Verifying that a sample qualified varying is given different values for different samples.\n"
852 << " Render full screen traingle with quadratic function defining red/green color pattern division.\n"
853 << " => Resulting image should contain n+1 different colors, where n = sample count.\n"
854 << tcu::TestLog::EndMessage;
856 MSInterpolationCaseBase::init();
859 void MSCaseSampleQualifierDistinctValues::initPrograms (vk::SourceCollections& programCollection) const
861 // Create vertex shader
862 std::ostringstream vs;
864 vs << "#version 440\n"
865 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
867 << "layout(location = 0) out vec4 vs_out_position_ndc;\n"
869 << "out gl_PerVertex {\n"
870 << " vec4 gl_Position;\n"
872 << "void main (void)\n"
874 << " gl_Position = vs_in_position_ndc;\n"
875 << " vs_out_position_ndc = vs_in_position_ndc;\n"
878 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
880 // Create fragment shader
881 std::ostringstream fs;
883 fs << "#version 440\n"
884 << "layout(location = 0) sample in vec4 fs_in_position_ndc;\n"
886 << "layout(location = 0) out vec2 fs_out_color;\n"
888 << "void main (void)\n"
890 << " if(fs_in_position_ndc.y < -2.0*pow(0.5*(fs_in_position_ndc.x + 1.0), 2.0) + 1.0)\n"
891 << " fs_out_color = vec2(1.0, 0.0);\n"
893 << " fs_out_color = vec2(0.0, 1.0);\n"
896 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
899 TestInstance* MSCaseSampleQualifierDistinctValues::createInstance (Context& context) const
901 return new MSInstanceDistinctValues(context, m_imageMSParams);
904 class MSCaseInterpolateAtSampleDistinctValues : public MSInterpolationCaseBase
907 MSCaseInterpolateAtSampleDistinctValues (tcu::TestContext& testCtx,
908 const std::string& name,
909 const ImageMSParams& imageMSParams)
910 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
913 void initPrograms (vk::SourceCollections& programCollection) const;
914 TestInstance* createInstance (Context& context) const;
917 MSInterpolationCaseBase* createMSCaseInterpolateAtSampleDistinctValues (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
919 return new MSCaseInterpolateAtSampleDistinctValues(testCtx, name, imageMSParams);
922 void MSCaseInterpolateAtSampleDistinctValues::init (void)
925 << tcu::TestLog::Message
926 << "Verifying that a interpolateAtSample returns different values for different samples.\n"
927 << " Render full screen traingle with quadratic function defining red/green color pattern division.\n"
928 << " => Resulting image should contain n+1 different colors, where n = sample count.\n"
929 << tcu::TestLog::EndMessage;
931 MSInterpolationCaseBase::init();
934 void MSCaseInterpolateAtSampleDistinctValues::initPrograms (vk::SourceCollections& programCollection) const
936 // Create vertex shader
937 std::ostringstream vs;
939 vs << "#version 440\n"
940 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
942 << "layout(location = 0) out vec4 vs_out_position_ndc;\n"
944 << "out gl_PerVertex {\n"
945 << " vec4 gl_Position;\n"
947 << "void main (void)\n"
949 << " gl_Position = vs_in_position_ndc;\n"
950 << " vs_out_position_ndc = vs_in_position_ndc;\n"
953 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
955 // Create fragment shader
956 std::ostringstream fs;
958 fs << "#version 440\n"
959 << "layout(location = 0) in vec4 fs_in_position_ndc;\n"
961 << "layout(location = 0) out vec2 fs_out_color;\n"
963 << "void main (void)\n"
965 << " const vec4 position_ndc_at_sample = interpolateAtSample(fs_in_position_ndc, gl_SampleID);\n"
966 << " if(position_ndc_at_sample.y < -2.0*pow(0.5*(position_ndc_at_sample.x + 1.0), 2.0) + 1.0)\n"
967 << " fs_out_color = vec2(0.0, 1.0);\n"
969 << " fs_out_color = vec2(1.0, 0.0);\n"
972 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
975 TestInstance* MSCaseInterpolateAtSampleDistinctValues::createInstance (Context& context) const
977 return new MSInstanceDistinctValues(context, m_imageMSParams);
980 class MSInstanceInterpolateScreenPosition : public MSInterpolationInstanceBase
983 MSInstanceInterpolateScreenPosition (Context& context,
984 const ImageMSParams& imageMSParams)
985 : MSInterpolationInstanceBase(context, imageMSParams) {}
987 VertexDataDesc getVertexDataDescripton (void) const;
988 void uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const;
989 tcu::TestStatus verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const;
994 VertexData(const tcu::Vec4& posNdc, const tcu::Vec2& posScreen) : positionNdc(posNdc), positionScreen(posScreen) {}
996 tcu::Vec4 positionNdc;
997 tcu::Vec2 positionScreen;
1001 MSInterpolationInstanceBase::VertexDataDesc MSInstanceInterpolateScreenPosition::getVertexDataDescripton (void) const
1003 VertexDataDesc vertexDataDesc;
1005 vertexDataDesc.verticesCount = 4u;
1006 vertexDataDesc.dataStride = sizeof(VertexData);
1007 vertexDataDesc.dataSize = vertexDataDesc.verticesCount * vertexDataDesc.dataStride;
1008 vertexDataDesc.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
1010 const VkVertexInputAttributeDescription vertexAttribPositionNdc =
1012 0u, // deUint32 location;
1013 0u, // deUint32 binding;
1014 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1015 DE_OFFSET_OF(VertexData, positionNdc), // deUint32 offset;
1018 vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc);
1020 const VkVertexInputAttributeDescription vertexAttribPositionScreen =
1022 1u, // deUint32 location;
1023 0u, // deUint32 binding;
1024 VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
1025 DE_OFFSET_OF(VertexData, positionScreen), // deUint32 offset;
1028 vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionScreen);
1030 return vertexDataDesc;
1033 void MSInstanceInterpolateScreenPosition::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
1035 const tcu::UVec3 layerSize = getLayerSize(IMAGE_TYPE_2D, m_imageMSParams.imageSize);
1036 const float screenSizeX = static_cast<float>(layerSize.x());
1037 const float screenSizeY = static_cast<float>(layerSize.y());
1039 std::vector<VertexData> vertices;
1041 vertices.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec2(0.0f, 0.0f)));
1042 vertices.push_back(VertexData(tcu::Vec4( 1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec2(screenSizeX, 0.0f)));
1043 vertices.push_back(VertexData(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec2(0.0f, screenSizeY)));
1044 vertices.push_back(VertexData(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec2(screenSizeX, screenSizeY)));
1046 deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize));
1049 tcu::TestStatus MSInstanceInterpolateScreenPosition::verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const
1051 for (deInt32 z = 0u; z < imageData.getDepth(); ++z)
1052 for (deInt32 y = 0u; y < imageData.getHeight(); ++y)
1053 for (deInt32 x = 0u; x < imageData.getWidth(); ++x)
1055 const deInt32 firstComponent = imageData.getPixelInt(x, y, z).x();
1057 if (firstComponent > 0)
1058 return tcu::TestStatus::fail("Failed");
1060 return tcu::TestStatus::pass("Passed");
1063 class MSCaseInterpolateAtSampleSingleSample : public MSInterpolationCaseBase
1066 MSCaseInterpolateAtSampleSingleSample (tcu::TestContext& testCtx,
1067 const std::string& name,
1068 tcu::UVec3 imageSize)
1069 : MSInterpolationCaseBase(testCtx, name, ImageMSParams(VK_SAMPLE_COUNT_1_BIT, imageSize)) {}
1072 void initPrograms (vk::SourceCollections& programCollection) const;
1073 TestInstance* createInstance (Context& context) const;
1076 void MSCaseInterpolateAtSampleSingleSample::init (void)
1079 << tcu::TestLog::Message
1080 << "Verifying that using interpolateAtSample with multisample buffers not available returns sample evaluated at the center of the pixel.\n"
1081 << " Interpolate varying containing screen space location.\n"
1082 << " => fract(screen space location) should be (about) (0.5, 0.5)\n"
1083 << tcu::TestLog::EndMessage;
1085 MSInterpolationCaseBase::init();
1088 void MSCaseInterpolateAtSampleSingleSample::initPrograms (vk::SourceCollections& programCollection) const
1090 // Create vertex shader
1091 std::ostringstream vs;
1093 vs << "#version 440\n"
1094 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
1095 << "layout(location = 1) in vec2 vs_in_position_screen;\n"
1097 << "layout(location = 0) out vec2 vs_out_position_screen;\n"
1099 << "out gl_PerVertex {\n"
1100 << " vec4 gl_Position;\n"
1102 << "void main (void)\n"
1104 << " gl_Position = vs_in_position_ndc;\n"
1105 << " vs_out_position_screen = vs_in_position_screen;\n"
1108 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
1110 // Create fragment shader
1111 std::ostringstream fs;
1113 fs << "#version 440\n"
1114 << "layout(location = 0) in vec2 fs_in_position_screen;\n"
1116 << "layout(location = 0) out vec2 fs_out_color;\n"
1118 << "void main (void)\n"
1120 << " const float threshold = 0.15625;\n"
1121 << " const vec2 position_screen_at_sample = interpolateAtSample(fs_in_position_screen, 0);\n"
1122 << " const vec2 position_inside_pixel = fract(position_screen_at_sample);\n"
1124 << " if (abs(position_inside_pixel.x - 0.5) <= threshold && abs(position_inside_pixel.y - 0.5) <= threshold)\n"
1125 << " fs_out_color = vec2(0.0, 1.0);\n"
1127 << " fs_out_color = vec2(1.0, 0.0);\n"
1130 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
1133 TestInstance* MSCaseInterpolateAtSampleSingleSample::createInstance (Context& context) const
1135 return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
1138 class MSCaseInterpolateAtSampleIgnoresCentroid : public MSInterpolationCaseBase
1141 MSCaseInterpolateAtSampleIgnoresCentroid(tcu::TestContext& testCtx,
1142 const std::string& name,
1143 const ImageMSParams& imageMSParams)
1144 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
1147 void initPrograms (vk::SourceCollections& programCollection) const;
1148 TestInstance* createInstance (Context& context) const;
1151 MSInterpolationCaseBase* createMSCaseInterpolateAtSampleIgnoresCentroid (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
1153 return new MSCaseInterpolateAtSampleIgnoresCentroid(testCtx, name, imageMSParams);
1156 void MSCaseInterpolateAtSampleIgnoresCentroid::init (void)
1159 << tcu::TestLog::Message
1160 << "Verifying that interpolateAtSample ignores centroid qualifier.\n"
1161 << " Interpolate varying containing screen space location with centroid and sample qualifiers.\n"
1162 << " => interpolateAtSample(screenSample, n) ~= interpolateAtSample(screenCentroid, n)\n"
1163 << tcu::TestLog::EndMessage;
1165 MSInterpolationCaseBase::init();
1168 void MSCaseInterpolateAtSampleIgnoresCentroid::initPrograms (vk::SourceCollections& programCollection) const
1170 // Create vertex shader
1171 std::ostringstream vs;
1173 vs << "#version 440\n"
1174 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
1175 << "layout(location = 1) in vec2 vs_in_position_screen;\n"
1177 << "layout(location = 0) out vec2 vs_out_pos_screen_centroid;\n"
1178 << "layout(location = 1) out vec2 vs_out_pos_screen_fragment;\n"
1180 << "out gl_PerVertex {\n"
1181 << " vec4 gl_Position;\n"
1183 << "void main (void)\n"
1185 << " gl_Position = vs_in_position_ndc;\n"
1186 << " vs_out_pos_screen_centroid = vs_in_position_screen;\n"
1187 << " vs_out_pos_screen_fragment = vs_in_position_screen;\n"
1190 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
1192 // Create fragment shader
1193 std::ostringstream fs;
1195 fs << "#version 440\n"
1196 << "layout(location = 0) centroid in vec2 fs_in_pos_screen_centroid;\n"
1197 << "layout(location = 1) in vec2 fs_in_pos_screen_fragment;\n"
1199 << "layout(location = 0) out vec2 fs_out_color;\n"
1201 << "void main (void)\n"
1203 << " const float threshold = 0.0005;\n"
1205 << " const vec2 position_a = interpolateAtSample(fs_in_pos_screen_centroid, gl_SampleID);\n"
1206 << " const vec2 position_b = interpolateAtSample(fs_in_pos_screen_fragment, gl_SampleID);\n"
1207 << " const bool valuesEqual = all(lessThan(abs(position_a - position_b), vec2(threshold)));\n"
1209 << " if (valuesEqual)\n"
1210 << " fs_out_color = vec2(0.0, 1.0);\n"
1212 << " fs_out_color = vec2(1.0, 0.0);\n"
1215 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
1218 TestInstance* MSCaseInterpolateAtSampleIgnoresCentroid::createInstance (Context& context) const
1220 return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
1223 class MSCaseInterpolateAtSampleConsistency : public MSInterpolationCaseBase
1226 MSCaseInterpolateAtSampleConsistency (tcu::TestContext& testCtx,
1227 const std::string& name,
1228 const ImageMSParams& imageMSParams)
1229 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
1232 void initPrograms (vk::SourceCollections& programCollection) const;
1233 TestInstance* createInstance (Context& context) const;
1236 MSInterpolationCaseBase* createMSCaseInterpolateAtSampleConsistency (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
1238 return new MSCaseInterpolateAtSampleConsistency(testCtx, name, imageMSParams);
1241 void MSCaseInterpolateAtSampleConsistency::init (void)
1244 << tcu::TestLog::Message
1245 << "Verifying that interpolateAtSample with the sample set to the current sampleID returns consistent values.\n"
1246 << " Interpolate varying containing screen space location with centroid and sample qualifiers.\n"
1247 << " => interpolateAtSample(screenCentroid, sampleID) = screenSample\n"
1248 << tcu::TestLog::EndMessage;
1250 MSInterpolationCaseBase::init();
1253 void MSCaseInterpolateAtSampleConsistency::initPrograms (vk::SourceCollections& programCollection) const
1255 // Create vertex shader
1256 std::ostringstream vs;
1258 vs << "#version 440\n"
1259 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
1260 << "layout(location = 1) in vec2 vs_in_position_screen;\n"
1262 << "layout(location = 0) out vec2 vs_out_pos_screen_centroid;\n"
1263 << "layout(location = 1) out vec2 vs_out_pos_screen_sample;\n"
1265 << "out gl_PerVertex {\n"
1266 << " vec4 gl_Position;\n"
1268 << "void main (void)\n"
1270 << " gl_Position = vs_in_position_ndc;\n"
1271 << " vs_out_pos_screen_centroid = vs_in_position_screen;\n"
1272 << " vs_out_pos_screen_sample = vs_in_position_screen;\n"
1275 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
1277 // Create fragment shader
1278 std::ostringstream fs;
1280 fs << "#version 440\n"
1281 << "layout(location = 0) centroid in vec2 fs_in_pos_screen_centroid;\n"
1282 << "layout(location = 1) sample in vec2 fs_in_pos_screen_sample;\n"
1284 << "layout(location = 0) out vec2 fs_out_color;\n"
1286 << "void main (void)\n"
1288 << " const float threshold = 0.15625;\n"
1290 << " const vec2 pos_interpolated_at_sample = interpolateAtSample(fs_in_pos_screen_centroid, gl_SampleID);\n"
1291 << " const bool valuesEqual = all(lessThan(abs(pos_interpolated_at_sample - fs_in_pos_screen_sample), vec2(threshold)));\n"
1293 << " if (valuesEqual)\n"
1294 << " fs_out_color = vec2(0.0, 1.0);\n"
1296 << " fs_out_color = vec2(1.0, 0.0);\n"
1299 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
1302 TestInstance* MSCaseInterpolateAtSampleConsistency::createInstance (Context& context) const
1304 return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
1307 class MSCaseInterpolateAtCentroidConsistency : public MSInterpolationCaseBase
1310 MSCaseInterpolateAtCentroidConsistency (tcu::TestContext& testCtx,
1311 const std::string& name,
1312 const ImageMSParams& imageMSParams)
1313 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
1316 void initPrograms (vk::SourceCollections& programCollection) const;
1317 TestInstance* createInstance (Context& context) const;
1320 MSInterpolationCaseBase* createMSCaseInterpolateAtCentroidConsistency (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
1322 return new MSCaseInterpolateAtCentroidConsistency(testCtx, name, imageMSParams);
1325 void MSCaseInterpolateAtCentroidConsistency::init (void)
1328 << tcu::TestLog::Message
1329 << "Verifying that interpolateAtCentroid does not return different values than a corresponding centroid qualified varying.\n"
1330 << " Interpolate varying containing screen space location with sample and centroid qualifiers.\n"
1331 << " => interpolateAtCentroid(screenSample) = screenCentroid\n"
1332 << tcu::TestLog::EndMessage;
1334 MSInterpolationCaseBase::init();
1337 void MSCaseInterpolateAtCentroidConsistency::initPrograms (vk::SourceCollections& programCollection) const
1339 // Create vertex shader
1340 std::ostringstream vs;
1342 vs << "#version 440\n"
1343 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
1344 << "layout(location = 1) in vec2 vs_in_position_screen;\n"
1346 << "layout(location = 0) out vec2 vs_out_pos_screen_sample;\n"
1347 << "layout(location = 1) out vec2 vs_out_pos_screen_centroid;\n"
1349 << "out gl_PerVertex {\n"
1350 << " vec4 gl_Position;\n"
1352 << "void main (void)\n"
1354 << " gl_Position = vs_in_position_ndc;\n"
1355 << " vs_out_pos_screen_sample = vs_in_position_screen;\n"
1356 << " vs_out_pos_screen_centroid = vs_in_position_screen;\n"
1359 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
1361 // Create fragment shader
1362 std::ostringstream fs;
1364 fs << "#version 440\n"
1365 << "layout(location = 0) sample in vec2 fs_in_pos_screen_sample;\n"
1366 << "layout(location = 1) centroid in vec2 fs_in_pos_screen_centroid;\n"
1368 << "layout(location = 0) out vec2 fs_out_color;\n"
1370 << "void main (void)\n"
1372 << " const float threshold = 0.0005;\n"
1374 << " const vec2 pos_interpolated_at_centroid = interpolateAtCentroid(fs_in_pos_screen_sample);\n"
1375 << " const bool valuesEqual = all(lessThan(abs(pos_interpolated_at_centroid - fs_in_pos_screen_centroid), vec2(threshold)));\n"
1377 << " if (valuesEqual)\n"
1378 << " fs_out_color = vec2(0.0, 1.0);\n"
1380 << " fs_out_color = vec2(1.0, 0.0);\n"
1383 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
1386 TestInstance* MSCaseInterpolateAtCentroidConsistency::createInstance (Context& context) const
1388 return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
1391 class MSCaseInterpolateAtOffsetPixelCenter : public MSInterpolationCaseBase
1394 MSCaseInterpolateAtOffsetPixelCenter(tcu::TestContext& testCtx,
1395 const std::string& name,
1396 const ImageMSParams& imageMSParams)
1397 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
1400 void initPrograms (vk::SourceCollections& programCollection) const;
1401 TestInstance* createInstance (Context& context) const;
1404 MSInterpolationCaseBase* createMSCaseInterpolateAtOffsetPixelCenter (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
1406 return new MSCaseInterpolateAtOffsetPixelCenter(testCtx, name, imageMSParams);
1409 void MSCaseInterpolateAtOffsetPixelCenter::init (void)
1412 << tcu::TestLog::Message
1413 << "Verifying that interpolateAtOffset returns value sampled at an offset from the center of the pixel.\n"
1414 << " Interpolate varying containing screen space location.\n"
1415 << " => interpolateAtOffset(screen, offset) should be \"varying value at the pixel center\" + offset"
1416 << tcu::TestLog::EndMessage;
1418 MSInterpolationCaseBase::init();
1421 void MSCaseInterpolateAtOffsetPixelCenter::initPrograms (vk::SourceCollections& programCollection) const
1423 // Create vertex shader
1424 std::ostringstream vs;
1426 vs << "#version 440\n"
1427 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
1428 << "layout(location = 1) in vec2 vs_in_position_screen;\n"
1430 << "layout(location = 0) out vec2 vs_out_pos_screen;\n"
1431 << "layout(location = 1) out vec2 vs_out_offset;\n"
1433 << "out gl_PerVertex {\n"
1434 << " vec4 gl_Position;\n"
1436 << "void main (void)\n"
1438 << " gl_Position = vs_in_position_ndc;\n"
1439 << " vs_out_pos_screen = vs_in_position_screen;\n"
1440 << " vs_out_offset = vs_in_position_ndc.xy * 0.5;\n"
1443 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
1445 // Create fragment shader
1446 std::ostringstream fs;
1448 fs << "#version 440\n"
1449 << "layout(location = 0) in vec2 fs_in_pos_screen;\n"
1450 << "layout(location = 1) in vec2 fs_in_offset;\n"
1452 << "layout(location = 0) out vec2 fs_out_color;\n"
1454 << "void main (void)\n"
1456 << " const vec2 frag_center = interpolateAtOffset(fs_in_pos_screen, vec2(0.0));\n"
1457 << " const vec2 center_diff = abs(frag_center - fs_in_pos_screen);\n"
1458 << " const float threshold = 0.125;\n"
1459 << " bool valuesEqual = false;\n"
1461 << " if (all(lessThan(center_diff, vec2(0.5 + threshold)))) {\n"
1462 << " const vec2 pos_interpolated_at_offset = interpolateAtOffset(fs_in_pos_screen, fs_in_offset);\n"
1463 << " const vec2 reference_value = frag_center + fs_in_offset;\n"
1465 << " valuesEqual = all(lessThan(abs(pos_interpolated_at_offset - reference_value), vec2(threshold)));\n"
1468 << " if (valuesEqual)\n"
1469 << " fs_out_color = vec2(0.0, 1.0);\n"
1471 << " fs_out_color = vec2(1.0, 0.0);\n"
1474 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
1477 TestInstance* MSCaseInterpolateAtOffsetPixelCenter::createInstance (Context& context) const
1479 return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
1482 class MSCaseInterpolateAtOffsetSamplePosition : public MSInterpolationCaseBase
1485 MSCaseInterpolateAtOffsetSamplePosition (tcu::TestContext& testCtx,
1486 const std::string& name,
1487 const ImageMSParams& imageMSParams)
1488 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
1491 void initPrograms (vk::SourceCollections& programCollection) const;
1492 TestInstance* createInstance (Context& context) const;
1495 MSInterpolationCaseBase* createMSCaseInterpolateAtOffsetSamplePosition (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
1497 return new MSCaseInterpolateAtOffsetSamplePosition(testCtx, name, imageMSParams);
1500 void MSCaseInterpolateAtOffsetSamplePosition::init (void)
1503 << tcu::TestLog::Message
1504 << "Verifying that interpolateAtOffset of screen position with the offset of current sample position returns value "
1505 << "similar to screen position interpolated at sample.\n"
1506 << " Interpolate varying containing screen space location with and without sample qualifier.\n"
1507 << " => interpolateAtOffset(screenFragment, samplePosition - (0.5,0.5)) = screenSample"
1508 << tcu::TestLog::EndMessage;
1510 MSInterpolationCaseBase::init();
1513 void MSCaseInterpolateAtOffsetSamplePosition::initPrograms (vk::SourceCollections& programCollection) const
1515 // Create vertex shader
1516 std::ostringstream vs;
1518 vs << "#version 440\n"
1519 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
1520 << "layout(location = 1) in vec2 vs_in_position_screen;\n"
1522 << "layout(location = 0) out vec2 vs_out_pos_screen_fragment;\n"
1523 << "layout(location = 1) out vec2 vs_out_pos_screen_sample;\n"
1525 << "out gl_PerVertex {\n"
1526 << " vec4 gl_Position;\n"
1528 << "void main (void)\n"
1530 << " gl_Position = vs_in_position_ndc;\n"
1531 << " vs_out_pos_screen_fragment = vs_in_position_screen;\n"
1532 << " vs_out_pos_screen_sample = vs_in_position_screen;\n"
1535 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
1537 // Create fragment shader
1538 std::ostringstream fs;
1540 fs << "#version 440\n"
1541 << "layout(location = 0) in vec2 fs_in_pos_screen_fragment;\n"
1542 << "layout(location = 1) sample in vec2 fs_in_pos_screen_sample;\n"
1544 << "layout(location = 0) out vec2 fs_out_color;\n"
1546 << "void main (void)\n"
1548 << " const float threshold = 0.15625;\n"
1550 << " const vec2 offset = gl_SamplePosition - vec2(0.5, 0.5);\n"
1551 << " const vec2 pos_interpolated_at_offset = interpolateAtOffset(fs_in_pos_screen_fragment, offset);\n"
1552 << " const bool valuesEqual = all(lessThan(abs(pos_interpolated_at_offset - fs_in_pos_screen_sample), vec2(threshold)));\n"
1554 << " if (valuesEqual)\n"
1555 << " fs_out_color = vec2(0.0, 1.0);\n"
1557 << " fs_out_color = vec2(1.0, 0.0);\n"
1560 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
1563 TestInstance* MSCaseInterpolateAtOffsetSamplePosition::createInstance (Context& context) const
1565 return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
1568 class MSInstanceInterpolateBarycentricCoordinates : public MSInterpolationInstanceBase
1571 MSInstanceInterpolateBarycentricCoordinates (Context& context,
1572 const ImageMSParams& imageMSParams)
1573 : MSInterpolationInstanceBase(context, imageMSParams) {}
1575 VertexDataDesc getVertexDataDescripton (void) const;
1576 void uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const;
1577 tcu::TestStatus verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const;
1582 VertexData(const tcu::Vec4& posNdc, const tcu::Vec3& barCoord) : positionNdc(posNdc), barycentricCoord(barCoord) {}
1584 tcu::Vec4 positionNdc;
1585 tcu::Vec3 barycentricCoord;
1589 MSInterpolationInstanceBase::VertexDataDesc MSInstanceInterpolateBarycentricCoordinates::getVertexDataDescripton (void) const
1591 VertexDataDesc vertexDataDesc;
1593 vertexDataDesc.verticesCount = 3u;
1594 vertexDataDesc.dataStride = sizeof(VertexData);
1595 vertexDataDesc.dataSize = vertexDataDesc.verticesCount * vertexDataDesc.dataStride;
1596 vertexDataDesc.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1598 const VkVertexInputAttributeDescription vertexAttribPositionNdc =
1600 0u, // deUint32 location;
1601 0u, // deUint32 binding;
1602 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1603 DE_OFFSET_OF(VertexData, positionNdc), // deUint32 offset;
1606 vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc);
1608 const VkVertexInputAttributeDescription vertexAttrBarCoord =
1610 1u, // deUint32 location;
1611 0u, // deUint32 binding;
1612 VK_FORMAT_R32G32B32_SFLOAT, // VkFormat format;
1613 DE_OFFSET_OF(VertexData, barycentricCoord), // deUint32 offset;
1616 vertexDataDesc.vertexAttribDescVec.push_back(vertexAttrBarCoord);
1618 return vertexDataDesc;
1621 void MSInstanceInterpolateBarycentricCoordinates::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
1623 // Create buffer storing vertex data
1624 std::vector<VertexData> vertices;
1626 vertices.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec3(0.0f, 0.0f, 1.0f)));
1627 vertices.push_back(VertexData(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec3(1.0f, 0.0f, 0.0f)));
1628 vertices.push_back(VertexData(tcu::Vec4( 1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec3(0.0f, 1.0f, 0.0f)));
1630 deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize));
1633 tcu::TestStatus MSInstanceInterpolateBarycentricCoordinates::verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const
1635 for (deInt32 z = 0u; z < imageData.getDepth(); ++z)
1636 for (deInt32 y = 0u; y < imageData.getHeight(); ++y)
1637 for (deInt32 x = 0u; x < imageData.getWidth(); ++x)
1639 const deInt32 firstComponent = imageData.getPixelInt(x, y, z).x();
1641 if (firstComponent > 0)
1642 return tcu::TestStatus::fail("Failed");
1645 return tcu::TestStatus::pass("Passed");
1648 class MSCaseCentroidQualifierInsidePrimitive : public MSInterpolationCaseBase
1651 MSCaseCentroidQualifierInsidePrimitive (tcu::TestContext& testCtx,
1652 const std::string& name,
1653 const ImageMSParams& imageMSParams)
1654 : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
1657 void initPrograms (vk::SourceCollections& programCollection) const;
1658 TestInstance* createInstance (Context& context) const;
1661 MSInterpolationCaseBase* createMSCaseCentroidQualifierInsidePrimitive (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
1663 return new MSCaseCentroidQualifierInsidePrimitive(testCtx, name, imageMSParams);
1666 void MSCaseCentroidQualifierInsidePrimitive::init (void)
1669 << tcu::TestLog::Message
1670 << "Verifying that varying qualified with centroid is interpolated at location inside both the pixel and the primitive being processed.\n"
1671 << " Interpolate triangle's barycentric coordinates with centroid qualifier.\n"
1672 << " => After interpolation we expect barycentric.xyz >= 0.0 && barycentric.xyz <= 1.0\n"
1673 << tcu::TestLog::EndMessage;
1675 MSInterpolationCaseBase::init();
1678 void MSCaseCentroidQualifierInsidePrimitive::initPrograms (vk::SourceCollections& programCollection) const
1680 // Create vertex shader
1681 std::ostringstream vs;
1683 vs << "#version 440\n"
1684 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
1685 << "layout(location = 1) in vec3 vs_in_barCoord;\n"
1687 << "layout(location = 0) out vec3 vs_out_barCoord;\n"
1689 << "out gl_PerVertex {\n"
1690 << " vec4 gl_Position;\n"
1692 << "void main (void)\n"
1694 << " gl_Position = vs_in_position_ndc;\n"
1695 << " vs_out_barCoord = vs_in_barCoord;\n"
1698 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
1700 // Create fragment shader
1701 std::ostringstream fs;
1703 fs << "#version 440\n"
1704 << "layout(location = 0) centroid in vec3 fs_in_barCoord;\n"
1706 << "layout(location = 0) out vec2 fs_out_color;\n"
1708 << "void main (void)\n"
1710 << " if( all(greaterThanEqual(fs_in_barCoord, vec3(0.0))) && all(lessThanEqual(fs_in_barCoord, vec3(1.0))) )\n"
1711 << " fs_out_color = vec2(0.0, 1.0);\n"
1713 << " fs_out_color = vec2(1.0, 0.0);\n"
1716 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
1719 TestInstance* MSCaseCentroidQualifierInsidePrimitive::createInstance (Context& context) const
1721 return new MSInstanceInterpolateBarycentricCoordinates(context, m_imageMSParams);
1726 tcu::TestCaseGroup* makeGroup( multisample::MSInterpolationCaseFuncPtr createCaseFuncPtr,
1727 tcu::TestContext& testCtx,
1728 const std::string groupName,
1729 const tcu::UVec3 imageSizes[],
1730 const deUint32 imageSizesElemCount,
1731 const vk::VkSampleCountFlagBits imageSamples[],
1732 const deUint32 imageSamplesElemCount)
1734 de::MovePtr<tcu::TestCaseGroup> caseGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), ""));
1736 for (deUint32 imageSizeNdx = 0u; imageSizeNdx < imageSizesElemCount; ++imageSizeNdx)
1738 const tcu::UVec3 imageSize = imageSizes[imageSizeNdx];
1739 std::ostringstream imageSizeStream;
1741 imageSizeStream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
1743 de::MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(testCtx, imageSizeStream.str().c_str(), ""));
1745 for (deUint32 imageSamplesNdx = 0u; imageSamplesNdx < imageSamplesElemCount; ++imageSamplesNdx)
1747 const vk::VkSampleCountFlagBits samples = imageSamples[imageSamplesNdx];
1748 const multisample::ImageMSParams imageMSParams = multisample::ImageMSParams(samples, imageSize);
1750 sizeGroup->addChild(createCaseFuncPtr(testCtx, "samples_" + de::toString(samples), imageMSParams));
1753 caseGroup->addChild(sizeGroup.release());
1755 return caseGroup.release();
1758 tcu::TestCaseGroup* createMultisampleInterpolationTests (tcu::TestContext& testCtx)
1760 de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "multisample_interpolation", "Multisample Interpolation"));
1762 const tcu::UVec3 imageSizes[] =
1764 tcu::UVec3(128u, 128u, 1u),
1765 tcu::UVec3(137u, 191u, 1u),
1768 const deUint32 sizesElemCount = static_cast<deUint32>(sizeof(imageSizes) / sizeof(tcu::UVec3));
1770 const vk::VkSampleCountFlagBits imageSamples[] =
1772 vk::VK_SAMPLE_COUNT_2_BIT,
1773 vk::VK_SAMPLE_COUNT_4_BIT,
1774 vk::VK_SAMPLE_COUNT_8_BIT,
1775 vk::VK_SAMPLE_COUNT_16_BIT,
1776 vk::VK_SAMPLE_COUNT_32_BIT,
1777 vk::VK_SAMPLE_COUNT_64_BIT,
1780 const deUint32 samplesElemCount = static_cast<deUint32>(sizeof(imageSamples) / sizeof(vk::VkSampleCountFlagBits));
1782 de::MovePtr<tcu::TestCaseGroup> caseGroup(new tcu::TestCaseGroup(testCtx, "sample_interpolate_at_single_sample_", ""));
1784 for (deUint32 imageSizeNdx = 0u; imageSizeNdx < sizesElemCount; ++imageSizeNdx)
1786 const tcu::UVec3 imageSize = imageSizes[imageSizeNdx];
1787 std::ostringstream imageSizeStream;
1789 imageSizeStream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
1791 de::MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(testCtx, imageSizeStream.str().c_str(), ""));
1793 sizeGroup->addChild(new multisample::MSCaseInterpolateAtSampleSingleSample(testCtx, "samples_" + de::toString(1), imageSize));
1795 caseGroup->addChild(sizeGroup.release());
1798 testGroup->addChild(caseGroup.release());
1800 testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtSampleDistinctValues, testCtx, "sample_interpolate_at_distinct_values", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1801 testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtSampleIgnoresCentroid, testCtx, "sample_interpolate_at_ignores_centroid", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1802 testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtSampleConsistency, testCtx, "sample_interpolate_at_consistency", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1803 testGroup->addChild(makeGroup(multisample::createMSCaseSampleQualifierDistinctValues, testCtx, "sample_qualifier_distinct_values", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1804 testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtCentroidConsistency, testCtx, "centroid_interpolate_at_consistency", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1805 testGroup->addChild(makeGroup(multisample::createMSCaseCentroidQualifierInsidePrimitive, testCtx, "centroid_qualifier_inside_primitive", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1806 testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtOffsetPixelCenter, testCtx, "offset_interpolate_at_pixel_center", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1807 testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtOffsetSamplePosition, testCtx, "offset_interpolate_at_sample_position", imageSizes, sizesElemCount, imageSamples, samplesElemCount));
1809 return testGroup.release();