1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2014 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Functional rasterization tests.
24 *//*--------------------------------------------------------------------*/
26 #include "vktTestGroupUtil.hpp"
27 #include "vktAmberTestCase.hpp"
28 #include "vktRasterizationTests.hpp"
29 #include "vktRasterizationFragShaderSideEffectsTests.hpp"
30 #include "vktRasterizationProvokingVertexTests.hpp"
31 #include "tcuRasterizationVerifier.hpp"
32 #include "tcuSurface.hpp"
33 #include "tcuRenderTarget.hpp"
34 #include "tcuVectorUtil.hpp"
35 #include "tcuStringTemplate.hpp"
36 #include "tcuTextureUtil.hpp"
37 #include "tcuResultCollector.hpp"
38 #include "tcuFloatFormat.hpp"
39 #include "vkImageUtil.hpp"
40 #include "deStringUtil.hpp"
41 #include "deRandom.hpp"
42 #include "vktTestCase.hpp"
43 #include "vktTestCaseUtil.hpp"
44 #include "vkPrograms.hpp"
45 #include "vkMemUtil.hpp"
46 #include "vkRefUtil.hpp"
47 #include "vkQueryUtil.hpp"
48 #include "vkBuilderUtil.hpp"
49 #include "vkTypeUtil.hpp"
50 #include "vkCmdUtil.hpp"
51 #include "vkObjUtil.hpp"
52 #include "vkBufferWithMemory.hpp"
53 #include "vkImageWithMemory.hpp"
54 #include "vkBarrierUtil.hpp"
63 namespace rasterization
68 using tcu::RasterizationArguments;
69 using tcu::TriangleSceneSpec;
70 using tcu::PointSceneSpec;
71 using tcu::LineSceneSpec;
72 using tcu::LineInterpolationMethod;
74 static const char* const s_shaderVertexTemplate = "#version 310 es\n"
75 "layout(location = 0) in highp vec4 a_position;\n"
76 "layout(location = 1) in highp vec4 a_color;\n"
77 "layout(location = 0) ${INTERPOLATION}out highp vec4 v_color;\n"
78 "layout (set=0, binding=0) uniform PointSize {\n"
79 " highp float u_pointSize;\n"
83 " gl_Position = a_position;\n"
84 " gl_PointSize = u_pointSize;\n"
85 " v_color = a_color;\n"
88 static const char* const s_shaderFragmentTemplate = "#version 310 es\n"
89 "layout(location = 0) out highp vec4 fragColor;\n"
90 "layout(location = 0) ${INTERPOLATION}in highp vec4 v_color;\n"
93 " fragColor = v_color;\n"
96 enum InterpolationCaseFlags
98 INTERPOLATIONFLAGS_NONE = 0,
99 INTERPOLATIONFLAGS_PROJECTED = (1 << 1),
100 INTERPOLATIONFLAGS_FLATSHADE = (1 << 2),
103 enum ResolutionValues
105 RESOLUTION_POT = 256,
106 RESOLUTION_NPOT = 258
109 enum PrimitiveWideness
111 PRIMITIVEWIDENESS_NARROW = 0,
112 PRIMITIVEWIDENESS_WIDE,
114 PRIMITIVEWIDENESS_LAST
119 LINESTIPPLE_DISABLED = 0,
126 static const deUint32 lineStippleFactor = 2;
127 static const deUint32 lineStipplePattern = 0x0F0F;
129 enum class LineStippleFactorCase
136 enum PrimitiveStrictness
138 PRIMITIVESTRICTNESS_STRICT = 0,
139 PRIMITIVESTRICTNESS_NONSTRICT,
140 PRIMITIVESTRICTNESS_IGNORE,
142 PRIMITIVESTRICTNESS_LAST
146 class BaseRenderingTestCase : public TestCase
149 BaseRenderingTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deBool flatshade = DE_FALSE);
150 virtual ~BaseRenderingTestCase (void);
152 virtual void initPrograms (vk::SourceCollections& programCollection) const;
155 const VkSampleCountFlagBits m_sampleCount;
156 const deBool m_flatshade;
159 BaseRenderingTestCase::BaseRenderingTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount, deBool flatshade)
160 : TestCase(context, name, description)
161 , m_sampleCount (sampleCount)
162 , m_flatshade (flatshade)
166 void BaseRenderingTestCase::initPrograms (vk::SourceCollections& programCollection) const
168 tcu::StringTemplate vertexSource (s_shaderVertexTemplate);
169 tcu::StringTemplate fragmentSource (s_shaderFragmentTemplate);
170 std::map<std::string, std::string> params;
172 params["INTERPOLATION"] = (m_flatshade) ? ("flat ") : ("");
174 programCollection.glslSources.add("vertext_shader") << glu::VertexSource(vertexSource.specialize(params));
175 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fragmentSource.specialize(params));
178 BaseRenderingTestCase::~BaseRenderingTestCase (void)
182 class BaseRenderingTestInstance : public TestInstance
185 BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deUint32 renderSize = RESOLUTION_POT, VkFormat imageFormat = VK_FORMAT_R8G8B8A8_UNORM, deUint32 additionalRenderSize = 0);
186 ~BaseRenderingTestInstance (void);
189 void addImageTransitionBarrier (VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const;
190 virtual void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology);
191 void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, const std::vector<tcu::Vec4>& coloDrata, VkPrimitiveTopology primitiveTopology);
192 void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology,
193 VkImage image, VkImage resolvedImage, VkFramebuffer frameBuffer, const deUint32 renderSize, VkBuffer resultBuffer, const Allocation& resultBufferMemory);
194 virtual float getLineWidth (void) const;
195 virtual float getPointSize (void) const;
196 virtual bool getLineStippleDynamic (void) const { return false; };
199 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
202 VkPipelineRasterizationLineStateCreateInfoEXT initLineRasterizationStateCreateInfo (void) const;
205 const VkPipelineRasterizationLineStateCreateInfoEXT* getLineRasterizationStateCreateInfo (void);
208 const VkPipelineColorBlendStateCreateInfo* getColorBlendStateCreateInfo (void) const;
210 const tcu::TextureFormat& getTextureFormat (void) const;
212 const deUint32 m_renderSize;
213 const VkSampleCountFlagBits m_sampleCount;
214 deUint32 m_subpixelBits;
215 const deBool m_multisampling;
217 const VkFormat m_imageFormat;
218 const tcu::TextureFormat m_textureFormat;
219 Move<VkCommandPool> m_commandPool;
221 Move<VkImage> m_image;
222 de::MovePtr<Allocation> m_imageMemory;
223 Move<VkImageView> m_imageView;
225 Move<VkImage> m_resolvedImage;
226 de::MovePtr<Allocation> m_resolvedImageMemory;
227 Move<VkImageView> m_resolvedImageView;
229 Move<VkRenderPass> m_renderPass;
230 Move<VkFramebuffer> m_frameBuffer;
232 Move<VkDescriptorPool> m_descriptorPool;
233 Move<VkDescriptorSet> m_descriptorSet;
234 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
236 Move<VkBuffer> m_uniformBuffer;
237 de::MovePtr<Allocation> m_uniformBufferMemory;
238 const VkDeviceSize m_uniformBufferSize;
240 Move<VkPipelineLayout> m_pipelineLayout;
242 Move<VkShaderModule> m_vertexShaderModule;
243 Move<VkShaderModule> m_fragmentShaderModule;
245 Move<VkBuffer> m_resultBuffer;
246 de::MovePtr<Allocation> m_resultBufferMemory;
247 const VkDeviceSize m_resultBufferSize;
249 const deUint32 m_additionalRenderSize;
250 const VkDeviceSize m_additionalResultBufferSize;
252 VkPipelineRasterizationLineStateCreateInfoEXT m_lineRasterizationStateInfo;
255 virtual int getIteration (void) const { TCU_THROW(InternalError, "Iteration undefined in the base class"); }
258 BaseRenderingTestInstance::BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount, deUint32 renderSize, VkFormat imageFormat, deUint32 additionalRenderSize)
259 : TestInstance (context)
260 , m_renderSize (renderSize)
261 , m_sampleCount (sampleCount)
262 , m_subpixelBits (context.getDeviceProperties().limits.subPixelPrecisionBits)
263 , m_multisampling (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
264 , m_imageFormat (imageFormat)
265 , m_textureFormat (vk::mapVkFormat(m_imageFormat))
266 , m_uniformBufferSize (sizeof(float))
267 , m_resultBufferSize (renderSize * renderSize * m_textureFormat.getPixelSize())
268 , m_additionalRenderSize(additionalRenderSize)
269 , m_additionalResultBufferSize(additionalRenderSize * additionalRenderSize * m_textureFormat.getPixelSize())
270 , m_lineRasterizationStateInfo ()
272 const DeviceInterface& vkd = m_context.getDeviceInterface();
273 const VkDevice vkDevice = m_context.getDevice();
274 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
275 Allocator& allocator = m_context.getDefaultAllocator();
276 DescriptorPoolBuilder descriptorPoolBuilder;
277 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
280 m_commandPool = createCommandPool(vkd, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
284 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
285 VkImageFormatProperties properties;
287 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
290 VK_IMAGE_TILING_OPTIMAL,
293 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
295 TCU_THROW(NotSupportedError, "Format not supported");
298 if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
300 TCU_THROW(NotSupportedError, "Format not supported");
303 const VkImageCreateInfo imageCreateInfo =
305 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
306 DE_NULL, // const void* pNext;
307 0u, // VkImageCreateFlags flags;
308 VK_IMAGE_TYPE_2D, // VkImageType imageType;
309 m_imageFormat, // VkFormat format;
310 { m_renderSize, m_renderSize, 1u }, // VkExtent3D extent;
311 1u, // deUint32 mipLevels;
312 1u, // deUint32 arrayLayers;
313 m_sampleCount, // VkSampleCountFlagBits samples;
314 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
315 imageUsage, // VkImageUsageFlags usage;
316 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
317 1u, // deUint32 queueFamilyIndexCount;
318 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
319 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
322 m_image = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
324 m_imageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_image), MemoryRequirement::Any);
325 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_image, m_imageMemory->getMemory(), m_imageMemory->getOffset()));
330 const VkImageViewCreateInfo imageViewCreateInfo =
332 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
333 DE_NULL, // const void* pNext;
334 0u, // VkImageViewCreateFlags flags;
335 *m_image, // VkImage image;
336 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
337 m_imageFormat, // VkFormat format;
338 makeComponentMappingRGBA(), // VkComponentMapping components;
340 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
341 0u, // deUint32 baseMipLevel;
342 1u, // deUint32 mipLevels;
343 0u, // deUint32 baseArrayLayer;
344 1u, // deUint32 arraySize;
345 }, // VkImageSubresourceRange subresourceRange;
348 m_imageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
355 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
356 VkImageFormatProperties properties;
358 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
361 VK_IMAGE_TILING_OPTIMAL,
364 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
366 TCU_THROW(NotSupportedError, "Format not supported");
369 const VkImageCreateInfo imageCreateInfo =
371 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
372 DE_NULL, // const void* pNext;
373 0u, // VkImageCreateFlags flags;
374 VK_IMAGE_TYPE_2D, // VkImageType imageType;
375 m_imageFormat, // VkFormat format;
376 { m_renderSize, m_renderSize, 1u }, // VkExtent3D extent;
377 1u, // deUint32 mipLevels;
378 1u, // deUint32 arrayLayers;
379 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
380 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
381 imageUsage, // VkImageUsageFlags usage;
382 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
383 1u, // deUint32 queueFamilyIndexCount;
384 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
385 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
388 m_resolvedImage = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
389 m_resolvedImageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_resolvedImage), MemoryRequirement::Any);
390 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_resolvedImage, m_resolvedImageMemory->getMemory(), m_resolvedImageMemory->getOffset()));
393 // Resolved Image View
395 const VkImageViewCreateInfo imageViewCreateInfo =
397 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
398 DE_NULL, // const void* pNext;
399 0u, // VkImageViewCreateFlags flags;
400 *m_resolvedImage, // VkImage image;
401 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
402 m_imageFormat, // VkFormat format;
403 makeComponentMappingRGBA(), // VkComponentMapping components;
405 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
406 0u, // deUint32 baseMipLevel;
407 1u, // deUint32 mipLevels;
408 0u, // deUint32 baseArrayLayer;
409 1u, // deUint32 arraySize;
410 }, // VkImageSubresourceRange subresourceRange;
413 m_resolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
420 const VkImageLayout imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
421 const VkAttachmentDescription attachmentDesc[] =
424 0u, // VkAttachmentDescriptionFlags flags;
425 m_imageFormat, // VkFormat format;
426 m_sampleCount, // VkSampleCountFlagBits samples;
427 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
428 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
429 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
430 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
431 imageLayout, // VkImageLayout initialLayout;
432 imageLayout, // VkImageLayout finalLayout;
435 0u, // VkAttachmentDescriptionFlags flags;
436 m_imageFormat, // VkFormat format;
437 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
438 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
439 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
440 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
441 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
442 imageLayout, // VkImageLayout initialLayout;
443 imageLayout, // VkImageLayout finalLayout;
447 const VkAttachmentReference attachmentRef =
449 0u, // deUint32 attachment;
450 imageLayout, // VkImageLayout layout;
453 const VkAttachmentReference resolveAttachmentRef =
455 1u, // deUint32 attachment;
456 imageLayout, // VkImageLayout layout;
459 const VkSubpassDescription subpassDesc =
461 0u, // VkSubpassDescriptionFlags flags;
462 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
463 0u, // deUint32 inputAttachmentCount;
464 DE_NULL, // const VkAttachmentReference* pInputAttachments;
465 1u, // deUint32 colorAttachmentCount;
466 &attachmentRef, // const VkAttachmentReference* pColorAttachments;
467 m_multisampling ? &resolveAttachmentRef : DE_NULL, // const VkAttachmentReference* pResolveAttachments;
468 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
469 0u, // deUint32 preserveAttachmentCount;
470 DE_NULL, // const VkAttachmentReference* pPreserveAttachments;
473 const VkRenderPassCreateInfo renderPassCreateInfo =
475 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
476 DE_NULL, // const void* pNext;
477 0u, // VkRenderPassCreateFlags flags;
478 m_multisampling ? 2u : 1u, // deUint32 attachmentCount;
479 attachmentDesc, // const VkAttachmentDescription* pAttachments;
480 1u, // deUint32 subpassCount;
481 &subpassDesc, // const VkSubpassDescription* pSubpasses;
482 0u, // deUint32 dependencyCount;
483 DE_NULL, // const VkSubpassDependency* pDependencies;
486 m_renderPass = createRenderPass(vkd, vkDevice, &renderPassCreateInfo, DE_NULL);
491 const VkImageView attachments[] =
497 const VkFramebufferCreateInfo framebufferCreateInfo =
499 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
500 DE_NULL, // const void* pNext;
501 0u, // VkFramebufferCreateFlags flags;
502 *m_renderPass, // VkRenderPass renderPass;
503 m_multisampling ? 2u : 1u, // deUint32 attachmentCount;
504 attachments, // const VkImageView* pAttachments;
505 m_renderSize, // deUint32 width;
506 m_renderSize, // deUint32 height;
507 1u, // deUint32 layers;
510 m_frameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL);
515 const VkBufferCreateInfo bufferCreateInfo =
517 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
518 DE_NULL, // const void* pNext;
519 0u, // VkBufferCreateFlags flags;
520 m_uniformBufferSize, // VkDeviceSize size;
521 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage;
522 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
523 1u, // deUint32 queueFamilyIndexCount;
524 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
527 m_uniformBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo);
528 m_uniformBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_uniformBuffer), MemoryRequirement::HostVisible);
530 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_uniformBuffer, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset()));
535 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
536 m_descriptorPool = descriptorPoolBuilder.build(vkd, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
538 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_ALL);
539 m_descriptorSetLayout = descriptorSetLayoutBuilder.build(vkd, vkDevice);
541 const VkDescriptorSetAllocateInfo descriptorSetParams =
543 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
547 &m_descriptorSetLayout.get(),
550 m_descriptorSet = allocateDescriptorSet(vkd, vkDevice, &descriptorSetParams);
552 const VkDescriptorBufferInfo descriptorBufferInfo =
554 *m_uniformBuffer, // VkBuffer buffer;
555 0u, // VkDeviceSize offset;
556 VK_WHOLE_SIZE // VkDeviceSize range;
559 const VkWriteDescriptorSet writeDescritporSet =
561 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
562 DE_NULL, // const void* pNext;
563 *m_descriptorSet, // VkDescriptorSet destSet;
564 0, // deUint32 destBinding;
565 0, // deUint32 destArrayElement;
566 1u, // deUint32 count;
567 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType descriptorType;
568 DE_NULL, // const VkDescriptorImageInfo* pImageInfo;
569 &descriptorBufferInfo, // const VkDescriptorBufferInfo* pBufferInfo;
570 DE_NULL // const VkBufferView* pTexelBufferView;
573 vkd.updateDescriptorSets(vkDevice, 1u, &writeDescritporSet, 0u, DE_NULL);
578 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
580 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
581 DE_NULL, // const void* pNext;
582 0u, // VkPipelineLayoutCreateFlags flags;
583 1u, // deUint32 descriptorSetCount;
584 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
585 0u, // deUint32 pushConstantRangeCount;
586 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
589 m_pipelineLayout = createPipelineLayout(vkd, vkDevice, &pipelineLayoutCreateInfo);
594 m_vertexShaderModule = createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("vertext_shader"), 0);
595 m_fragmentShaderModule = createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("fragment_shader"), 0);
600 const VkBufferCreateInfo bufferCreateInfo =
602 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
603 DE_NULL, // const void* pNext;
604 0u, // VkBufferCreateFlags flags;
605 m_resultBufferSize, // VkDeviceSize size;
606 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
607 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
608 1u, // deUint32 queueFamilyIndexCount;
609 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
612 m_resultBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo);
613 m_resultBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_resultBuffer), MemoryRequirement::HostVisible);
615 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));
618 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Sample count = " << getSampleCountFlagsStr(m_sampleCount) << tcu::TestLog::EndMessage;
619 m_context.getTestContext().getLog() << tcu::TestLog::Message << "SUBPIXEL_BITS = " << m_subpixelBits << tcu::TestLog::EndMessage;
622 BaseRenderingTestInstance::~BaseRenderingTestInstance (void)
627 void BaseRenderingTestInstance::addImageTransitionBarrier(VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const
630 const DeviceInterface& vkd = m_context.getDeviceInterface();
632 const VkImageSubresourceRange subResourcerange =
634 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
635 0, // deUint32 baseMipLevel;
636 1, // deUint32 levelCount;
637 0, // deUint32 baseArrayLayer;
638 1 // deUint32 layerCount;
641 const VkImageMemoryBarrier imageBarrier =
643 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
644 DE_NULL, // const void* pNext;
645 srcAccessMask, // VkAccessFlags srcAccessMask;
646 dstAccessMask, // VkAccessFlags dstAccessMask;
647 oldLayout, // VkImageLayout oldLayout;
648 newLayout, // VkImageLayout newLayout;
649 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
650 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
651 image, // VkImage image;
652 subResourcerange // VkImageSubresourceRange subresourceRange;
655 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier);
658 void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology)
660 // default to color white
661 const std::vector<tcu::Vec4> colorData(vertexData.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
663 drawPrimitives(result, vertexData, colorData, primitiveTopology);
666 void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology)
668 drawPrimitives(result, positionData, colorData, primitiveTopology, *m_image, *m_resolvedImage, *m_frameBuffer, m_renderSize, *m_resultBuffer, *m_resultBufferMemory);
670 void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology,
671 VkImage image, VkImage resolvedImage, VkFramebuffer frameBuffer, const deUint32 renderSize, VkBuffer resultBuffer, const Allocation& resultBufferMemory)
673 const DeviceInterface& vkd = m_context.getDeviceInterface();
674 const VkDevice vkDevice = m_context.getDevice();
675 const VkQueue queue = m_context.getUniversalQueue();
676 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
677 Allocator& allocator = m_context.getDefaultAllocator();
678 const size_t attributeBatchSize = positionData.size() * sizeof(tcu::Vec4);
680 Move<VkCommandBuffer> commandBuffer;
681 Move<VkPipeline> graphicsPipeline;
682 Move<VkBuffer> vertexBuffer;
683 de::MovePtr<Allocation> vertexBufferMemory;
684 const VkPhysicalDeviceProperties properties = m_context.getDeviceProperties();
686 if (attributeBatchSize > properties.limits.maxVertexInputAttributeOffset)
688 std::stringstream message;
689 message << "Larger vertex input attribute offset is needed (" << attributeBatchSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
690 TCU_THROW(NotSupportedError, message.str().c_str());
693 // Create Graphics Pipeline
695 const VkVertexInputBindingDescription vertexInputBindingDescription =
697 0u, // deUint32 binding;
698 sizeof(tcu::Vec4), // deUint32 strideInBytes;
699 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
702 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
705 0u, // deUint32 location;
706 0u, // deUint32 binding;
707 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
708 0u // deUint32 offsetInBytes;
711 1u, // deUint32 location;
712 0u, // deUint32 binding;
713 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
714 (deUint32)attributeBatchSize // deUint32 offsetInBytes;
718 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
720 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
721 DE_NULL, // const void* pNext;
722 0, // VkPipelineVertexInputStateCreateFlags flags;
723 1u, // deUint32 bindingCount;
724 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
725 2u, // deUint32 attributeCount;
726 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
729 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(renderSize)));
730 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(renderSize)));
732 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
734 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
735 DE_NULL, // const void* pNext;
736 0u, // VkPipelineMultisampleStateCreateFlags flags;
737 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
738 VK_FALSE, // VkBool32 sampleShadingEnable;
739 0.0f, // float minSampleShading;
740 DE_NULL, // const VkSampleMask* pSampleMask;
741 VK_FALSE, // VkBool32 alphaToCoverageEnable;
742 VK_FALSE // VkBool32 alphaToOneEnable;
746 VkPipelineRasterizationStateCreateInfo rasterizationStateInfo = *getRasterizationStateCreateInfo();
748 const VkPipelineRasterizationLineStateCreateInfoEXT* lineRasterizationStateInfo = getLineRasterizationStateCreateInfo();
750 if (lineRasterizationStateInfo != DE_NULL)
751 appendStructurePtrToVulkanChain(&rasterizationStateInfo.pNext, lineRasterizationStateInfo);
753 VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
755 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType
756 DE_NULL, // const void* pNext
757 0u, // VkPipelineDynamicStateCreateFlags flags
758 0u, // deUint32 dynamicStateCount
759 DE_NULL // const VkDynamicState* pDynamicStates
762 VkDynamicState dynamicState = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
763 if (getLineStippleDynamic())
765 dynamicStateCreateInfo.dynamicStateCount = 1;
766 dynamicStateCreateInfo.pDynamicStates = &dynamicState;
769 graphicsPipeline = makeGraphicsPipeline(vkd, // const DeviceInterface& vk
770 vkDevice, // const VkDevice device
771 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
772 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
773 DE_NULL, // const VkShaderModule tessellationControlShaderModule
774 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
775 DE_NULL, // const VkShaderModule geometryShaderModule
776 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
777 *m_renderPass, // const VkRenderPass renderPass
778 viewports, // const std::vector<VkViewport>& viewports
779 scissors, // const std::vector<VkRect2D>& scissors
780 primitiveTopology, // const VkPrimitiveTopology topology
781 0u, // const deUint32 subpass
782 0u, // const deUint32 patchControlPoints
783 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
784 &rasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
785 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
786 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo,
787 getColorBlendStateCreateInfo(), // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo,
788 &dynamicStateCreateInfo); // const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo
791 // Create Vertex Buffer
793 const VkBufferCreateInfo vertexBufferParams =
795 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
796 DE_NULL, // const void* pNext;
797 0u, // VkBufferCreateFlags flags;
798 attributeBatchSize * 2, // VkDeviceSize size;
799 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
800 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
801 1u, // deUint32 queueFamilyCount;
802 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
805 vertexBuffer = createBuffer(vkd, vkDevice, &vertexBufferParams);
806 vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
808 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
810 // Load vertices into vertex buffer
811 deMemcpy(vertexBufferMemory->getHostPtr(), positionData.data(), attributeBatchSize);
812 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) + attributeBatchSize, colorData.data(), attributeBatchSize);
813 flushAlloc(vkd, vkDevice, *vertexBufferMemory);
816 // Create Command Buffer
817 commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
819 // Begin Command Buffer
820 beginCommandBuffer(vkd, *commandBuffer);
822 addImageTransitionBarrier(*commandBuffer, image,
823 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
824 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
825 0, // VkAccessFlags srcAccessMask
826 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
827 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
828 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
830 if (m_multisampling) {
831 addImageTransitionBarrier(*commandBuffer, resolvedImage,
832 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
833 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
834 0, // VkAccessFlags srcAccessMask
835 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
836 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
837 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
841 beginRenderPass(vkd, *commandBuffer, *m_renderPass, frameBuffer, vk::makeRect2D(0, 0, renderSize, renderSize), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
843 const VkDeviceSize vertexBufferOffset = 0;
845 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
846 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL);
847 vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
848 if (getLineStippleDynamic())
849 vkd.cmdSetLineStippleEXT(*commandBuffer, lineStippleFactor, lineStipplePattern);
850 vkd.cmdDraw(*commandBuffer, (deUint32)positionData.size(), 1, 0, 0);
851 endRenderPass(vkd, *commandBuffer);
854 copyImageToBuffer(vkd, *commandBuffer, m_multisampling ? resolvedImage : image, resultBuffer, tcu::IVec2(renderSize, renderSize));
856 endCommandBuffer(vkd, *commandBuffer);
860 float pointSize = getPointSize();
861 deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize);
862 flushAlloc(vkd, vkDevice, *m_uniformBufferMemory);
866 submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());
868 invalidateAlloc(vkd, vkDevice, resultBufferMemory);
869 tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(renderSize, renderSize, 1), resultBufferMemory.getHostPtr()));
872 float BaseRenderingTestInstance::getLineWidth (void) const
877 float BaseRenderingTestInstance::getPointSize (void) const
882 const VkPipelineRasterizationStateCreateInfo* BaseRenderingTestInstance::getRasterizationStateCreateInfo (void) const
884 static VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
886 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
887 DE_NULL, // const void* pNext;
888 0, // VkPipelineRasterizationStateCreateFlags flags;
889 false, // VkBool32 depthClipEnable;
890 false, // VkBool32 rasterizerDiscardEnable;
891 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
892 VK_CULL_MODE_NONE, // VkCullMode cullMode;
893 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
894 VK_FALSE, // VkBool32 depthBiasEnable;
895 0.0f, // float depthBias;
896 0.0f, // float depthBiasClamp;
897 0.0f, // float slopeScaledDepthBias;
898 getLineWidth(), // float lineWidth;
901 rasterizationStateCreateInfo.lineWidth = getLineWidth();
902 return &rasterizationStateCreateInfo;
905 VkPipelineRasterizationLineStateCreateInfoEXT BaseRenderingTestInstance::initLineRasterizationStateCreateInfo (void) const
907 VkPipelineRasterizationLineStateCreateInfoEXT lineRasterizationStateInfo =
909 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
910 DE_NULL, // const void* pNext;
911 VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, // VkLineRasterizationModeEXT lineRasterizationMode;
912 VK_FALSE, // VkBool32 stippledLineEnable;
913 1, // uint32_t lineStippleFactor;
914 0xFFFF, // uint16_t lineStipplePattern;
917 return lineRasterizationStateInfo;
920 const VkPipelineRasterizationLineStateCreateInfoEXT* BaseRenderingTestInstance::getLineRasterizationStateCreateInfo (void)
922 if (m_lineRasterizationStateInfo.sType != VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT)
923 m_lineRasterizationStateInfo = initLineRasterizationStateCreateInfo();
925 return &m_lineRasterizationStateInfo;
928 const VkPipelineColorBlendStateCreateInfo* BaseRenderingTestInstance::getColorBlendStateCreateInfo (void) const
930 static const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
932 false, // VkBool32 blendEnable;
933 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
934 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor;
935 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
936 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
937 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha;
938 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
939 (VK_COLOR_COMPONENT_R_BIT |
940 VK_COLOR_COMPONENT_G_BIT |
941 VK_COLOR_COMPONENT_B_BIT |
942 VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask;
945 static const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
947 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
948 DE_NULL, // const void* pNext;
949 0, // VkPipelineColorBlendStateCreateFlags flags;
950 false, // VkBool32 logicOpEnable;
951 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
952 1u, // deUint32 attachmentCount;
953 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
954 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
957 return &colorBlendStateParams;
960 const tcu::TextureFormat& BaseRenderingTestInstance::getTextureFormat (void) const
962 return m_textureFormat;
965 class BaseTriangleTestInstance : public BaseRenderingTestInstance
968 BaseTriangleTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, VkSampleCountFlagBits sampleCount, deUint32 renderSize = RESOLUTION_POT);
969 virtual tcu::TestStatus iterate (void);
972 int getIteration (void) const { return m_iteration; }
973 int getIterationCount (void) const { return m_iterationCount; }
976 virtual void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles) = DE_NULL;
977 virtual bool compareAndVerify (std::vector<TriangleSceneSpec::SceneTriangle>& triangles,
978 tcu::Surface& resultImage,
979 std::vector<tcu::Vec4>& drawBuffer);
982 const int m_iterationCount;
983 VkPrimitiveTopology m_primitiveTopology;
984 bool m_allIterationsPassed;
987 BaseTriangleTestInstance::BaseTriangleTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, VkSampleCountFlagBits sampleCount, deUint32 renderSize)
988 : BaseRenderingTestInstance (context, sampleCount, renderSize)
990 , m_iterationCount (3)
991 , m_primitiveTopology (primitiveTopology)
992 , m_allIterationsPassed (true)
996 tcu::TestStatus BaseTriangleTestInstance::iterate (void)
998 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
999 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1000 tcu::Surface resultImage (m_renderSize, m_renderSize);
1001 std::vector<tcu::Vec4> drawBuffer;
1002 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
1004 generateTriangles(m_iteration, drawBuffer, triangles);
1007 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
1011 const bool compareOk = compareAndVerify(triangles, resultImage, drawBuffer);
1014 m_allIterationsPassed = false;
1018 if (++m_iteration == m_iterationCount)
1020 if (m_allIterationsPassed)
1021 return tcu::TestStatus::pass("Pass");
1023 return tcu::TestStatus::fail("Incorrect rasterization");
1026 return tcu::TestStatus::incomplete();
1029 bool BaseTriangleTestInstance::compareAndVerify (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage, std::vector<tcu::Vec4>&)
1031 RasterizationArguments args;
1032 TriangleSceneSpec scene;
1034 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1036 args.numSamples = m_multisampling ? 1 : 0;
1037 args.subpixelBits = m_subpixelBits;
1038 args.redBits = colorBits[0];
1039 args.greenBits = colorBits[1];
1040 args.blueBits = colorBits[2];
1042 scene.triangles.swap(triangles);
1044 return verifyTriangleGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
1047 class BaseLineTestInstance : public BaseRenderingTestInstance
1050 BaseLineTestInstance (Context& context,
1051 VkPrimitiveTopology primitiveTopology,
1052 PrimitiveWideness wideness,
1053 PrimitiveStrictness strictness,
1054 VkSampleCountFlagBits sampleCount,
1055 LineStipple stipple,
1056 VkLineRasterizationModeEXT lineRasterizationMode,
1057 LineStippleFactorCase stippleFactor,
1058 const deUint32 additionalRenderSize = 0,
1059 const deUint32 renderSize = RESOLUTION_POT,
1060 const float narrowLineWidth = 1.0f);
1061 virtual tcu::TestStatus iterate (void);
1062 virtual float getLineWidth (void) const;
1063 bool getLineStippleEnable (void) const { return m_stipple != LINESTIPPLE_DISABLED; }
1064 virtual bool getLineStippleDynamic (void) const { return m_stipple == LINESTIPPLE_DYNAMIC; };
1067 VkPipelineRasterizationLineStateCreateInfoEXT initLineRasterizationStateCreateInfo (void) const;
1070 const VkPipelineRasterizationLineStateCreateInfoEXT* getLineRasterizationStateCreateInfo (void);
1073 int getIteration (void) const { return m_iteration; }
1074 int getIterationCount (void) const { return m_iterationCount; }
1077 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines) = DE_NULL;
1078 virtual bool compareAndVerify (std::vector<LineSceneSpec::SceneLine>& lines,
1079 tcu::Surface& resultImage,
1080 std::vector<tcu::Vec4>& drawBuffer);
1082 bool resultHasAlpha (tcu::Surface& result);
1085 const int m_iterationCount;
1086 VkPrimitiveTopology m_primitiveTopology;
1087 const PrimitiveWideness m_primitiveWideness;
1088 const PrimitiveStrictness m_primitiveStrictness;
1089 bool m_allIterationsPassed;
1090 bool m_qualityWarning;
1091 float m_maxLineWidth;
1092 std::vector<float> m_lineWidths;
1093 LineStipple m_stipple;
1094 VkLineRasterizationModeEXT m_lineRasterizationMode;
1095 LineStippleFactorCase m_stippleFactor;
1096 Move<VkImage> m_additionalImage;
1097 de::MovePtr<Allocation> m_additionalImageMemory;
1098 Move<VkImageView> m_additionalImageView;
1099 Move<VkImage> m_additionalResolvedImage;
1100 de::MovePtr<Allocation> m_additionalResolvedImageMemory;
1101 Move<VkImageView> m_additionalResolvedImageView;
1102 Move<VkFramebuffer> m_additionalFrameBuffer;
1103 Move<VkBuffer> m_additionalResultBuffer;
1104 de::MovePtr<Allocation> m_additionalResultBufferMemory;
1107 BaseLineTestInstance::BaseLineTestInstance (Context& context,
1108 VkPrimitiveTopology primitiveTopology,
1109 PrimitiveWideness wideness,
1110 PrimitiveStrictness strictness,
1111 VkSampleCountFlagBits sampleCount,
1112 LineStipple stipple,
1113 VkLineRasterizationModeEXT lineRasterizationMode,
1114 LineStippleFactorCase stippleFactor,
1115 const deUint32 additionalRenderSize,
1116 const deUint32 renderSize,
1117 const float narrowLineWidth)
1118 : BaseRenderingTestInstance (context, sampleCount, renderSize, VK_FORMAT_R8G8B8A8_UNORM, additionalRenderSize)
1120 , m_iterationCount (3)
1121 , m_primitiveTopology (primitiveTopology)
1122 , m_primitiveWideness (wideness)
1123 , m_primitiveStrictness (strictness)
1124 , m_allIterationsPassed (true)
1125 , m_qualityWarning (false)
1126 , m_maxLineWidth (1.0f)
1127 , m_stipple (stipple)
1128 , m_lineRasterizationMode (lineRasterizationMode)
1129 , m_stippleFactor (stippleFactor)
1131 DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
1133 if (m_lineRasterizationMode != VK_LINE_RASTERIZATION_MODE_EXT_LAST)
1135 if (context.isDeviceFunctionalitySupported("VK_EXT_line_rasterization"))
1137 VkPhysicalDeviceLineRasterizationPropertiesEXT lineRasterizationProperties =
1139 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT, // VkStructureType sType;
1140 DE_NULL, // void* pNext;
1141 0u, // deUint32 lineSubPixelPrecisionBits;
1144 VkPhysicalDeviceProperties2 deviceProperties2;
1145 deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1146 deviceProperties2.pNext = &lineRasterizationProperties;
1148 context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &deviceProperties2);
1150 m_subpixelBits = lineRasterizationProperties.lineSubPixelPrecisionBits;
1154 // create line widths
1155 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
1157 m_lineWidths.resize(m_iterationCount, narrowLineWidth);
1159 // Bump up m_maxLineWidth for conservative rasterization
1160 if (narrowLineWidth > m_maxLineWidth)
1161 m_maxLineWidth = narrowLineWidth;
1163 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
1165 const float* range = context.getDeviceProperties().limits.lineWidthRange;
1167 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
1169 DE_ASSERT(range[1] > 1.0f);
1171 // set hand picked sizes
1172 m_lineWidths.push_back(5.0f);
1173 m_lineWidths.push_back(10.0f);
1175 // Do not pick line width with 0.5 fractional value as rounding direction is not defined.
1176 if (deFloatFrac(range[1]) == 0.5f)
1178 m_lineWidths.push_back(range[1] - context.getDeviceProperties().limits.lineWidthGranularity);
1182 m_lineWidths.push_back(range[1]);
1185 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
1187 m_maxLineWidth = range[1];
1192 // Create image, image view and frame buffer for testing at an additional resolution if required.
1193 if (m_additionalRenderSize != 0)
1195 const DeviceInterface& vkd = m_context.getDeviceInterface();
1196 const VkDevice vkDevice = m_context.getDevice();
1197 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1198 Allocator& allocator = m_context.getDefaultAllocator();
1199 DescriptorPoolBuilder descriptorPoolBuilder;
1200 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
1202 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1203 const VkImageCreateInfo imageCreateInfo =
1205 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1206 DE_NULL, // const void* pNext;
1207 0u, // VkImageCreateFlags flags;
1208 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1209 m_imageFormat, // VkFormat format;
1210 { m_additionalRenderSize, m_additionalRenderSize, 1u }, // VkExtent3D extent;
1211 1u, // deUint32 mipLevels;
1212 1u, // deUint32 arrayLayers;
1213 m_sampleCount, // VkSampleCountFlagBits samples;
1214 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1215 imageUsage, // VkImageUsageFlags usage;
1216 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1217 1u, // deUint32 queueFamilyIndexCount;
1218 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1219 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1222 m_additionalImage = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
1224 m_additionalImageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_additionalImage), MemoryRequirement::Any);
1225 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_additionalImage, m_additionalImageMemory->getMemory(), m_additionalImageMemory->getOffset()));
1230 const VkImageViewCreateInfo imageViewCreateInfo =
1232 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1233 DE_NULL, // const void* pNext;
1234 0u, // VkImageViewCreateFlags flags;
1235 *m_additionalImage, // VkImage image;
1236 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1237 m_imageFormat, // VkFormat format;
1238 makeComponentMappingRGBA(), // VkComponentMapping components;
1240 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1241 0u, // deUint32 baseMipLevel;
1242 1u, // deUint32 mipLevels;
1243 0u, // deUint32 baseArrayLayer;
1244 1u, // deUint32 arraySize;
1245 }, // VkImageSubresourceRange subresourceRange;
1248 m_additionalImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
1251 if (m_multisampling)
1254 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1255 const VkImageCreateInfo imageCreateInfo =
1257 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1258 DE_NULL, // const void* pNext;
1259 0u, // VkImageCreateFlags flags;
1260 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1261 m_imageFormat, // VkFormat format;
1262 { m_additionalRenderSize, m_additionalRenderSize, 1u }, // VkExtent3D extent;
1263 1u, // deUint32 mipLevels;
1264 1u, // deUint32 arrayLayers;
1265 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1266 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1267 imageUsage, // VkImageUsageFlags usage;
1268 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1269 1u, // deUint32 queueFamilyIndexCount;
1270 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1271 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1274 m_additionalResolvedImage = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
1275 m_additionalResolvedImageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_additionalResolvedImage), MemoryRequirement::Any);
1276 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_additionalResolvedImage, m_additionalResolvedImageMemory->getMemory(), m_additionalResolvedImageMemory->getOffset()));
1281 const VkImageViewCreateInfo imageViewCreateInfo =
1283 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1284 DE_NULL, // const void* pNext;
1285 0u, // VkImageViewCreateFlags flags;
1286 *m_additionalResolvedImage, // VkImage image;
1287 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1288 m_imageFormat, // VkFormat format;
1289 makeComponentMappingRGBA(), // VkComponentMapping components;
1291 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1292 0u, // deUint32 baseMipLevel;
1293 1u, // deUint32 mipLevels;
1294 0u, // deUint32 baseArrayLayer;
1295 1u, // deUint32 arraySize;
1296 }, // VkImageSubresourceRange subresourceRange;
1298 m_additionalResolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
1303 const VkImageView attachments[] =
1305 *m_additionalImageView,
1306 *m_additionalResolvedImageView
1309 const VkFramebufferCreateInfo framebufferCreateInfo =
1311 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1312 DE_NULL, // const void* pNext;
1313 0u, // VkFramebufferCreateFlags flags;
1314 *m_renderPass, // VkRenderPass renderPass;
1315 m_multisampling ? 2u : 1u, // deUint32 attachmentCount;
1316 attachments, // const VkImageView* pAttachments;
1317 m_additionalRenderSize, // deUint32 width;
1318 m_additionalRenderSize, // deUint32 height;
1319 1u, // deUint32 layers;
1321 m_additionalFrameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL);
1326 const VkBufferCreateInfo bufferCreateInfo =
1328 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1329 DE_NULL, // const void* pNext;
1330 0u, // VkBufferCreateFlags flags;
1331 m_additionalResultBufferSize, // VkDeviceSize size;
1332 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1333 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1334 1u, // deUint32 queueFamilyIndexCount;
1335 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1338 m_additionalResultBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo);
1339 m_additionalResultBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_additionalResultBuffer), MemoryRequirement::HostVisible);
1341 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_additionalResultBuffer, m_additionalResultBufferMemory->getMemory(), m_additionalResultBufferMemory->getOffset()));
1346 bool BaseLineTestInstance::resultHasAlpha(tcu::Surface& resultImage)
1348 bool hasAlpha = false;
1349 for (int y = 0; y < resultImage.getHeight() && !hasAlpha; ++y)
1350 for (int x = 0; x < resultImage.getWidth(); ++x)
1352 const tcu::RGBA color = resultImage.getPixel(x, y);
1353 if (color.getAlpha() > 0 && color.getAlpha() < 0xFF)
1362 tcu::TestStatus BaseLineTestInstance::iterate (void)
1364 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1365 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1366 const float lineWidth = getLineWidth();
1367 tcu::Surface resultImage (m_renderSize, m_renderSize);
1368 std::vector<tcu::Vec4> drawBuffer;
1369 std::vector<LineSceneSpec::SceneLine> lines;
1372 if (lineWidth <= m_maxLineWidth)
1375 generateLines(m_iteration, drawBuffer, lines);
1378 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
1382 const bool compareOk = compareAndVerify(lines, resultImage, drawBuffer);
1385 m_allIterationsPassed = false;
1389 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
1392 if (++m_iteration == m_iterationCount)
1394 if (!m_allIterationsPassed)
1395 return tcu::TestStatus::fail("Incorrect rasterization");
1396 else if (m_qualityWarning)
1397 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality line rasterization");
1399 return tcu::TestStatus::pass("Pass");
1402 return tcu::TestStatus::incomplete();
1405 bool BaseLineTestInstance::compareAndVerify (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage, std::vector<tcu::Vec4>& drawBuffer)
1407 const float lineWidth = getLineWidth();
1409 tcu::Surface additionalResultImage (m_additionalRenderSize, m_additionalRenderSize);
1410 RasterizationArguments args;
1411 LineSceneSpec scene;
1412 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1413 bool strict = m_primitiveStrictness == PRIMITIVESTRICTNESS_STRICT;
1415 args.numSamples = m_multisampling ? 1 : 0;
1416 args.subpixelBits = m_subpixelBits;
1417 args.redBits = colorBits[0];
1418 args.greenBits = colorBits[1];
1419 args.blueBits = colorBits[2];
1421 scene.lines.swap(lines);
1422 scene.lineWidth = lineWidth;
1423 scene.stippleEnable = getLineStippleEnable();
1424 scene.stippleFactor = getLineStippleEnable() ? lineStippleFactor : 1;
1425 scene.stipplePattern = getLineStippleEnable() ? lineStipplePattern : 0xFFFF;
1426 scene.isStrip = m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
1427 scene.isSmooth = m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
1429 // Choose verification mode. Smooth lines assume mostly over-rasterization (bloated lines with a falloff).
1430 // Stippled lines lose some precision across segments in a strip, so need a weaker threshold than normal
1431 // lines. For simple cases, check for an exact match (STRICT).
1433 scene.verificationMode = tcu::VERIFICATIONMODE_SMOOTH;
1434 else if (scene.stippleEnable)
1435 scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
1437 scene.verificationMode = tcu::VERIFICATIONMODE_STRICT;
1439 if (m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT)
1441 // bresenham is "no AA" in GL, so set numSamples to zero.
1442 args.numSamples = 0;
1443 if (!verifyLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog()))
1450 // Smooth lines get the fractional coverage multiplied into the alpha component,
1451 // so do a sanity check to validate that there is at least one pixel in the image
1452 // with a fractional opacity.
1453 bool hasAlpha = resultHasAlpha(resultImage);
1456 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Missing alpha transparency (failed)." << tcu::TestLog::EndMessage;
1461 if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), (0 == m_multisampling), strict))
1463 // Retry with weaker verification. If it passes, consider it a quality warning.
1464 scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
1465 if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), false, strict))
1468 m_qualityWarning = true;
1471 if (m_additionalRenderSize != 0)
1473 const std::vector<tcu::Vec4> colorData(drawBuffer.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
1476 scene.verificationMode = tcu::VERIFICATIONMODE_SMOOTH;
1477 else if (scene.stippleEnable)
1478 scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
1480 scene.verificationMode = tcu::VERIFICATIONMODE_STRICT;
1482 drawPrimitives(additionalResultImage, drawBuffer, colorData, m_primitiveTopology, *m_additionalImage, *m_additionalResolvedImage, *m_additionalFrameBuffer, m_additionalRenderSize, *m_additionalResultBuffer, *m_additionalResultBufferMemory);
1485 if (!verifyRelaxedLineGroupRasterization(additionalResultImage, scene, args, m_context.getTestContext().getLog(), (0 == m_multisampling), strict))
1493 // Retry with weaker verification. If it passes, consider it a quality warning.
1494 scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
1495 if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), (0 == m_multisampling), strict))
1498 m_qualityWarning = true;
1507 float BaseLineTestInstance::getLineWidth (void) const
1509 return m_lineWidths[m_iteration];
1512 VkPipelineRasterizationLineStateCreateInfoEXT BaseLineTestInstance::initLineRasterizationStateCreateInfo (void) const
1514 VkPipelineRasterizationLineStateCreateInfoEXT lineRasterizationStateInfo =
1516 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
1517 DE_NULL, // const void* pNext;
1518 m_lineRasterizationMode, // VkLineRasterizationModeEXT lineRasterizationMode;
1519 getLineStippleEnable() ? VK_TRUE : VK_FALSE, // VkBool32 stippledLineEnable;
1520 1, // uint32_t lineStippleFactor;
1521 0xFFFF, // uint16_t lineStipplePattern;
1524 if (m_stipple == LINESTIPPLE_STATIC)
1526 lineRasterizationStateInfo.lineStippleFactor = lineStippleFactor;
1527 lineRasterizationStateInfo.lineStipplePattern = lineStipplePattern;
1529 else if (m_stipple == LINESTIPPLE_DISABLED)
1531 if (m_stippleFactor == LineStippleFactorCase::ZERO)
1532 lineRasterizationStateInfo.lineStippleFactor = 0u;
1533 else if (m_stippleFactor == LineStippleFactorCase::LARGE)
1534 lineRasterizationStateInfo.lineStippleFactor = 0xFEDCBA98u;
1537 return lineRasterizationStateInfo;
1540 const VkPipelineRasterizationLineStateCreateInfoEXT* BaseLineTestInstance::getLineRasterizationStateCreateInfo (void)
1542 if (m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_EXT_LAST)
1545 if (m_lineRasterizationStateInfo.sType != VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT)
1546 m_lineRasterizationStateInfo = initLineRasterizationStateCreateInfo();
1548 return &m_lineRasterizationStateInfo;
1551 class PointTestInstance : public BaseRenderingTestInstance
1554 PointTestInstance (Context& context,
1555 PrimitiveWideness wideness,
1556 PrimitiveStrictness strictness, // ignored
1557 VkSampleCountFlagBits sampleCount,
1558 LineStipple stipple, // ignored
1559 VkLineRasterizationModeEXT lineRasterizationMode, // ignored
1560 LineStippleFactorCase stippleFactor, // ignored
1561 deUint32 additionalRenderSize, // ignored
1562 deUint32 renderSize = RESOLUTION_POT,
1563 float pointSizeNarrow = 1.0f);
1564 virtual tcu::TestStatus iterate (void);
1565 virtual float getPointSize (void) const;
1568 int getIteration (void) const { return m_iteration; }
1569 int getIterationCount (void) const { return m_iterationCount; }
1572 virtual void generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints);
1573 virtual bool compareAndVerify (std::vector<PointSceneSpec::ScenePoint>& points,
1574 tcu::Surface& resultImage,
1575 std::vector<tcu::Vec4>& drawBuffer);
1578 const int m_iterationCount;
1579 const PrimitiveWideness m_primitiveWideness;
1580 bool m_allIterationsPassed;
1581 float m_maxPointSize;
1582 std::vector<float> m_pointSizes;
1585 PointTestInstance::PointTestInstance (Context& context,
1586 PrimitiveWideness wideness,
1587 PrimitiveStrictness strictness,
1588 VkSampleCountFlagBits sampleCount,
1589 LineStipple stipple,
1590 VkLineRasterizationModeEXT lineRasterizationMode,
1591 LineStippleFactorCase stippleFactor,
1592 deUint32 additionalRenderSize,
1593 deUint32 renderSize,
1594 float pointSizeNarrow)
1595 : BaseRenderingTestInstance (context, sampleCount, renderSize)
1597 , m_iterationCount (3)
1598 , m_primitiveWideness (wideness)
1599 , m_allIterationsPassed (true)
1600 , m_maxPointSize (pointSizeNarrow)
1602 DE_UNREF(strictness);
1604 DE_UNREF(lineRasterizationMode);
1605 DE_UNREF(stippleFactor);
1606 DE_UNREF(additionalRenderSize);
1608 // create point sizes
1609 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
1611 m_pointSizes.resize(m_iterationCount, pointSizeNarrow);
1613 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
1615 const float* range = context.getDeviceProperties().limits.pointSizeRange;
1617 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_ALIASED_POINT_SIZE_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
1619 DE_ASSERT(range[1] > 1.0f);
1621 // set hand picked sizes
1622 m_pointSizes.push_back(10.0f);
1623 m_pointSizes.push_back(25.0f);
1624 m_pointSizes.push_back(range[1]);
1625 DE_ASSERT((int)m_pointSizes.size() == m_iterationCount);
1627 m_maxPointSize = range[1];
1633 tcu::TestStatus PointTestInstance::iterate (void)
1635 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1636 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1637 const float pointSize = getPointSize();
1638 tcu::Surface resultImage (m_renderSize, m_renderSize);
1639 std::vector<tcu::Vec4> drawBuffer;
1640 std::vector<PointSceneSpec::ScenePoint> points;
1643 if (pointSize <= m_maxPointSize)
1646 generatePoints(m_iteration, drawBuffer, points);
1649 drawPrimitives(resultImage, drawBuffer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
1653 const bool compareOk = compareAndVerify(points, resultImage, drawBuffer);
1656 m_allIterationsPassed = false;
1660 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point size " << pointSize << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
1663 if (++m_iteration == m_iterationCount)
1665 if (m_allIterationsPassed)
1666 return tcu::TestStatus::pass("Pass");
1668 return tcu::TestStatus::fail("Incorrect rasterization");
1671 return tcu::TestStatus::incomplete();
1674 bool PointTestInstance::compareAndVerify (std::vector<PointSceneSpec::ScenePoint>& points,
1675 tcu::Surface& resultImage,
1676 std::vector<tcu::Vec4>& drawBuffer)
1678 RasterizationArguments args;
1679 PointSceneSpec scene;
1681 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1683 args.numSamples = m_multisampling ? 1 : 0;
1684 args.subpixelBits = m_subpixelBits;
1685 args.redBits = colorBits[0];
1686 args.greenBits = colorBits[1];
1687 args.blueBits = colorBits[2];
1689 scene.points.swap(points);
1691 DE_UNREF(drawBuffer);
1693 return verifyPointGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
1696 float PointTestInstance::getPointSize (void) const
1698 return m_pointSizes[m_iteration];
1701 void PointTestInstance::generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints)
1708 // \note: these values are chosen arbitrarily
1709 outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f);
1710 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1711 outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f);
1712 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1713 outData[4] = tcu::Vec4(-0.2f, -0.4f, 0.0f, 1.0f);
1714 outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f);
1718 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1719 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1720 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1721 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1722 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1723 outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f);
1727 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1728 outData[1] = tcu::Vec4( 0.3f, -0.9f, 0.0f, 1.0f);
1729 outData[2] = tcu::Vec4( -0.4f, -0.1f, 0.0f, 1.0f);
1730 outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f);
1731 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1732 outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f);
1736 outPoints.resize(outData.size());
1737 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
1739 outPoints[pointNdx].position = outData[pointNdx];
1740 outPoints[pointNdx].pointSize = getPointSize();
1744 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outPoints.size() << " point(s): (point size = " << getPointSize() << ")" << tcu::TestLog::EndMessage;
1745 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
1746 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point " << (pointNdx+1) << ":\t" << outPoints[pointNdx].position << tcu::TestLog::EndMessage;
1749 template <typename ConcreteTestInstance>
1750 class PointSizeTestCase : public BaseRenderingTestCase
1753 PointSizeTestCase (tcu::TestContext& context,
1755 std::string& description,
1756 deUint32 renderSize,
1758 VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
1759 : BaseRenderingTestCase (context, name, description, sampleCount)
1760 , m_pointSize (pointSize)
1761 , m_renderSize (renderSize)
1764 virtual TestInstance* createInstance (Context& context) const
1766 VkPhysicalDeviceProperties properties (context.getDeviceProperties());
1768 if (m_renderSize > properties.limits.maxViewportDimensions[0] || m_renderSize > properties.limits.maxViewportDimensions[1])
1769 TCU_THROW(NotSupportedError , "Viewport dimensions not supported");
1771 if (m_renderSize > properties.limits.maxFramebufferWidth || m_renderSize > properties.limits.maxFramebufferHeight)
1772 TCU_THROW(NotSupportedError , "Framebuffer width/height not supported");
1774 return new ConcreteTestInstance(context, m_renderSize, m_pointSize);
1777 virtual void checkSupport (Context& context) const
1779 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);
1782 const float m_pointSize;
1783 const deUint32 m_renderSize;
1786 class PointSizeTestInstance : public BaseRenderingTestInstance
1789 PointSizeTestInstance (Context& context, deUint32 renderSize, float pointSize);
1790 virtual tcu::TestStatus iterate (void);
1791 virtual float getPointSize (void) const;
1794 void generatePointData (PointSceneSpec::ScenePoint& outPoint);
1795 void drawPoint (tcu::PixelBufferAccess& result, tcu::PointSceneSpec::ScenePoint& point);
1796 bool verifyPoint (tcu::TestLog& log, tcu::PixelBufferAccess& access, float pointSize);
1797 bool isPointSizeClamped (float pointSize, float maxPointSizeLimit);
1799 const float m_pointSize;
1800 const float m_maxPointSize;
1801 const deUint32 m_renderSize;
1802 const VkFormat m_format;
1805 PointSizeTestInstance::PointSizeTestInstance (Context& context, deUint32 renderSize, float pointSize)
1806 : BaseRenderingTestInstance (context, vk::VK_SAMPLE_COUNT_1_BIT, renderSize, VK_FORMAT_R8_UNORM)
1807 , m_pointSize (pointSize)
1808 , m_maxPointSize (context.getDeviceProperties().limits.pointSizeRange[1])
1809 , m_renderSize (renderSize)
1810 , m_format (VK_FORMAT_R8_UNORM) // Use single-channel format to minimize memory allocation when using large render targets
1814 tcu::TestStatus PointSizeTestInstance::iterate (void)
1816 tcu::TextureLevel resultBuffer (mapVkFormat(m_format), m_renderSize, m_renderSize);
1817 tcu::PixelBufferAccess access (resultBuffer.getAccess());
1818 PointSceneSpec::ScenePoint point;
1821 generatePointData(point);
1824 drawPoint(access, point);
1828 // pointSize must either be specified pointSize or clamped to device limit pointSizeRange[1]
1829 const float pointSize (deFloatMin(m_pointSize, m_maxPointSize));
1830 const bool compareOk (verifyPoint(m_context.getTestContext().getLog(), access, pointSize));
1834 return isPointSizeClamped(pointSize, m_maxPointSize) ? tcu::TestStatus::pass("Pass, pointSize clamped to pointSizeRange[1]") : tcu::TestStatus::pass("Pass");
1836 return tcu::TestStatus::fail("Incorrect rasterization");
1840 float PointSizeTestInstance::getPointSize (void) const
1845 void PointSizeTestInstance::generatePointData (PointSceneSpec::ScenePoint& outPoint)
1847 const tcu::PointSceneSpec::ScenePoint point =
1849 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), // position
1850 tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), // color
1851 m_pointSize // pointSize
1858 tcu::TestLog& log = m_context.getTestContext().getLog();
1860 log << tcu::TestLog::Message << "Point position: " << de::toString(point.position) << tcu::TestLog::EndMessage;
1861 log << tcu::TestLog::Message << "Point color: " << de::toString(point.color) << tcu::TestLog::EndMessage;
1862 log << tcu::TestLog::Message << "Point size: " << de::toString(point.pointSize) << tcu::TestLog::EndMessage;
1863 log << tcu::TestLog::Message << "Render size: " << de::toString(m_renderSize) << tcu::TestLog::EndMessage;
1864 log << tcu::TestLog::Message << "Format: " << de::toString(m_format) << tcu::TestLog::EndMessage;
1868 void PointSizeTestInstance::drawPoint (tcu::PixelBufferAccess& result, PointSceneSpec::ScenePoint& point)
1870 const tcu::Vec4 positionData (point.position);
1871 const tcu::Vec4 colorData (point.color);
1873 const DeviceInterface& vkd (m_context.getDeviceInterface());
1874 const VkDevice vkDevice (m_context.getDevice());
1875 const VkQueue queue (m_context.getUniversalQueue());
1876 const deUint32 queueFamilyIndex (m_context.getUniversalQueueFamilyIndex());
1877 const size_t attributeBatchSize (sizeof(tcu::Vec4));
1878 Allocator& allocator (m_context.getDefaultAllocator());
1880 Move<VkCommandBuffer> commandBuffer;
1881 Move<VkPipeline> graphicsPipeline;
1882 Move<VkBuffer> vertexBuffer;
1883 de::MovePtr<Allocation> vertexBufferMemory;
1885 // Create Graphics Pipeline
1887 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(m_renderSize)));
1888 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(m_renderSize)));
1890 const VkVertexInputBindingDescription vertexInputBindingDescription =
1892 0u, // deUint32 binding;
1893 (deUint32)(2 * sizeof(tcu::Vec4)), // deUint32 strideInBytes;
1894 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
1897 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
1900 0u, // deUint32 location;
1901 0u, // deUint32 binding;
1902 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1903 0u // deUint32 offsetInBytes;
1906 1u, // deUint32 location;
1907 0u, // deUint32 binding;
1908 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1909 (deUint32)sizeof(tcu::Vec4) // deUint32 offsetInBytes;
1913 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1915 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1916 DE_NULL, // const void* pNext;
1917 0, // VkPipelineVertexInputStateCreateFlags flags;
1918 1u, // deUint32 bindingCount;
1919 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1920 2u, // deUint32 attributeCount;
1921 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1924 graphicsPipeline = makeGraphicsPipeline(vkd, // const DeviceInterface& vk
1925 vkDevice, // const VkDevice device
1926 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
1927 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
1928 DE_NULL, // const VkShaderModule tessellationControlShaderModule
1929 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
1930 DE_NULL, // const VkShaderModule geometryShaderModule
1931 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
1932 *m_renderPass, // const VkRenderPass renderPass
1933 viewports, // const std::vector<VkViewport>& viewports
1934 scissors, // const std::vector<VkRect2D>& scissors
1935 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // const VkPrimitiveTopology topology
1936 0u, // const deUint32 subpass
1937 0u, // const deUint32 patchControlPoints
1938 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
1939 getRasterizationStateCreateInfo(), // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
1940 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
1941 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo,
1942 getColorBlendStateCreateInfo()); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
1945 // Create Vertex Buffer
1947 const VkBufferCreateInfo vertexBufferParams =
1949 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1950 DE_NULL, // const void* pNext;
1951 0u, // VkBufferCreateFlags flags;
1952 attributeBatchSize * 2, // VkDeviceSize size;
1953 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1954 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1955 1u, // deUint32 queueFamilyCount;
1956 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1959 vertexBuffer = createBuffer(vkd, vkDevice, &vertexBufferParams);
1960 vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
1962 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
1964 // Load vertices into vertex buffer
1965 deMemcpy(vertexBufferMemory->getHostPtr(), &positionData, attributeBatchSize);
1966 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) + attributeBatchSize, &colorData, attributeBatchSize);
1967 flushAlloc(vkd, vkDevice, *vertexBufferMemory);
1970 // Create Command Buffer
1971 commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1973 // Begin Command Buffer
1974 beginCommandBuffer(vkd, *commandBuffer);
1976 addImageTransitionBarrier(*commandBuffer, *m_image,
1977 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
1978 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
1979 0, // VkAccessFlags srcAccessMask
1980 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
1981 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1982 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
1984 // Begin Render Pass
1985 beginRenderPass(vkd, *commandBuffer, *m_renderPass, *m_frameBuffer, vk::makeRect2D(0, 0, m_renderSize, m_renderSize), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
1987 const VkDeviceSize vertexBufferOffset = 0;
1989 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1990 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL);
1991 vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
1992 vkd.cmdDraw(*commandBuffer, 1, 1, 0, 0);
1993 endRenderPass(vkd, *commandBuffer);
1996 copyImageToBuffer(vkd, *commandBuffer, *m_image, *m_resultBuffer, tcu::IVec2(m_renderSize, m_renderSize));
1998 endCommandBuffer(vkd, *commandBuffer);
2002 float pointSize = getPointSize();
2004 deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize);
2005 flushAlloc(vkd, vkDevice, *m_uniformBufferMemory);
2009 submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());
2011 invalidateAlloc(vkd, vkDevice, *m_resultBufferMemory);
2012 tcu::copy(result, tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderSize, m_renderSize, 1), m_resultBufferMemory->getHostPtr()));
2015 bool PointSizeTestInstance::verifyPoint (tcu::TestLog& log, tcu::PixelBufferAccess& image, float pointSize)
2017 const float expectedPointColor (1.0f);
2018 const float expectedBackgroundColor (0.0f);
2019 deUint32 pointWidth (0u);
2020 deUint32 pointHeight (0u);
2021 bool incorrectlyColoredPixelsFound (false);
2024 // Verify rasterized point width and color
2025 for (size_t x = 0; x < (deUint32)image.getWidth(); x++)
2027 float pixelColor = image.getPixel((deUint32)x, image.getHeight() / 2).x();
2029 if (pixelColor == expectedPointColor)
2032 if ((pixelColor != expectedPointColor) && (pixelColor != expectedBackgroundColor))
2033 incorrectlyColoredPixelsFound = true;
2036 // Verify rasterized point height and color
2037 for (size_t y = 0; y < (deUint32)image.getHeight(); y++)
2039 float pixelColor = image.getPixel((deUint32)y, image.getWidth() / 2).x();
2041 if (pixelColor == expectedPointColor)
2044 if ((pixelColor != expectedPointColor) && (pixelColor != expectedBackgroundColor))
2045 incorrectlyColoredPixelsFound = true;
2048 // Compare amount of rasterized point pixels to expected pointSize.
2049 if ((pointWidth != (deUint32)deRoundFloatToInt32(pointSize)) || (pointHeight != (deUint32)deRoundFloatToInt32(pointSize)))
2051 log << tcu::TestLog::Message << "Incorrect point size. Expected pointSize: " << de::toString(pointSize)
2052 << ". Rasterized point width: " << pointWidth << " pixels, height: "
2053 << pointHeight << " pixels." << tcu::TestLog::EndMessage;
2058 // Check incorrectly colored pixels
2059 if (incorrectlyColoredPixelsFound)
2061 log << tcu::TestLog::Message << "Incorrectly colored pixels found." << tcu::TestLog::EndMessage;
2068 bool PointSizeTestInstance::isPointSizeClamped (float pointSize, float maxPointSizeLimit)
2070 return (pointSize == maxPointSizeLimit);
2073 template <typename ConcreteTestInstance>
2074 class BaseTestCase : public BaseRenderingTestCase
2077 BaseTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2078 : BaseRenderingTestCase(context, name, description, sampleCount)
2081 virtual TestInstance* createInstance (Context& context) const
2083 return new ConcreteTestInstance(context, m_sampleCount);
2087 class TrianglesTestInstance : public BaseTriangleTestInstance
2090 TrianglesTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
2091 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, sampleCount)
2094 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
2097 void TrianglesTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
2104 // \note: these values are chosen arbitrarily
2105 outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f);
2106 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
2107 outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f);
2108 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
2109 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
2110 outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f);
2114 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
2115 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
2116 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
2117 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
2118 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
2119 outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f);
2123 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
2124 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
2125 outData[2] = tcu::Vec4( -1.1f, -0.1f, 0.0f, 1.0f);
2126 outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f);
2127 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
2128 outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f);
2132 outTriangles.resize(2);
2133 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
2134 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false;
2135 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false;
2137 outTriangles[1].positions[0] = outData[3]; outTriangles[1].sharedEdge[0] = false;
2138 outTriangles[1].positions[1] = outData[4]; outTriangles[1].sharedEdge[1] = false;
2139 outTriangles[1].positions[2] = outData[5]; outTriangles[1].sharedEdge[2] = false;
2142 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outTriangles.size() << " triangle(s):" << tcu::TestLog::EndMessage;
2143 for (int triangleNdx = 0; triangleNdx < (int)outTriangles.size(); ++triangleNdx)
2145 m_context.getTestContext().getLog()
2146 << tcu::TestLog::Message
2147 << "Triangle " << (triangleNdx+1) << ":"
2148 << "\n\t" << outTriangles[triangleNdx].positions[0]
2149 << "\n\t" << outTriangles[triangleNdx].positions[1]
2150 << "\n\t" << outTriangles[triangleNdx].positions[2]
2151 << tcu::TestLog::EndMessage;
2155 class TriangleStripTestInstance : public BaseTriangleTestInstance
2158 TriangleStripTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
2159 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, sampleCount)
2162 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
2165 void TriangleStripTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
2172 // \note: these values are chosen arbitrarily
2173 outData[0] = tcu::Vec4(-0.504f, 0.8f, 0.0f, 1.0f);
2174 outData[1] = tcu::Vec4(-0.2f, -0.2f, 0.0f, 1.0f);
2175 outData[2] = tcu::Vec4(-0.2f, 0.199f, 0.0f, 1.0f);
2176 outData[3] = tcu::Vec4( 0.5f, 0.201f, 0.0f, 1.0f);
2177 outData[4] = tcu::Vec4( 1.5f, 0.4f, 0.0f, 1.0f);
2181 outData[0] = tcu::Vec4(-0.499f, 0.129f, 0.0f, 1.0f);
2182 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
2183 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
2184 outData[3] = tcu::Vec4( 0.11f, -0.31f, 0.0f, 1.0f);
2185 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
2189 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
2190 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
2191 outData[2] = tcu::Vec4(-0.87f, -0.1f, 0.0f, 1.0f);
2192 outData[3] = tcu::Vec4(-0.11f, 0.19f, 0.0f, 1.0f);
2193 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
2197 outTriangles.resize(3);
2198 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
2199 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = true;
2200 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false;
2202 outTriangles[1].positions[0] = outData[2]; outTriangles[1].sharedEdge[0] = true;
2203 outTriangles[1].positions[1] = outData[1]; outTriangles[1].sharedEdge[1] = false;
2204 outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true;
2206 outTriangles[2].positions[0] = outData[2]; outTriangles[2].sharedEdge[0] = true;
2207 outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false;
2208 outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false;
2211 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering triangle strip, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
2212 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
2214 m_context.getTestContext().getLog()
2215 << tcu::TestLog::Message
2216 << "\t" << outData[vtxNdx]
2217 << tcu::TestLog::EndMessage;
2221 class TriangleFanTestInstance : public BaseTriangleTestInstance
2224 TriangleFanTestInstance (Context& context, VkSampleCountFlagBits sampleCount);
2227 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
2230 TriangleFanTestInstance::TriangleFanTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
2231 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, sampleCount)
2233 if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
2234 !context.getPortabilitySubsetFeatures().triangleFans)
2236 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
2240 void TriangleFanTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
2247 // \note: these values are chosen arbitrarily
2248 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
2249 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
2250 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
2251 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
2252 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
2256 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
2257 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
2258 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
2259 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
2260 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
2264 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
2265 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
2266 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
2267 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
2268 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
2272 outTriangles.resize(3);
2273 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
2274 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false;
2275 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = true;
2277 outTriangles[1].positions[0] = outData[0]; outTriangles[1].sharedEdge[0] = true;
2278 outTriangles[1].positions[1] = outData[2]; outTriangles[1].sharedEdge[1] = false;
2279 outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true;
2281 outTriangles[2].positions[0] = outData[0]; outTriangles[2].sharedEdge[0] = true;
2282 outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false;
2283 outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false;
2286 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering triangle fan, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
2287 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
2289 m_context.getTestContext().getLog()
2290 << tcu::TestLog::Message
2291 << "\t" << outData[vtxNdx]
2292 << tcu::TestLog::EndMessage;
2296 struct ConservativeTestConfig
2298 VkConservativeRasterizationModeEXT conservativeRasterizationMode;
2299 float extraOverestimationSize;
2300 VkPrimitiveTopology primitiveTopology;
2301 bool degeneratePrimitives;
2303 deUint32 resolution;
2306 float getExtraOverestimationSize (const float overestimationSizeDesired, const VkPhysicalDeviceConservativeRasterizationPropertiesEXT& conservativeRasterizationProperties)
2308 const float extraOverestimationSize = overestimationSizeDesired == TCU_INFINITY ? conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize
2309 : overestimationSizeDesired == -TCU_INFINITY ? conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity
2310 : overestimationSizeDesired;
2312 return extraOverestimationSize;
2315 template <typename ConcreteTestInstance>
2316 class ConservativeTestCase : public BaseRenderingTestCase
2319 ConservativeTestCase (tcu::TestContext& context,
2320 const std::string& name,
2321 const std::string& description,
2322 const ConservativeTestConfig& conservativeTestConfig,
2323 VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2324 : BaseRenderingTestCase (context, name, description, sampleCount)
2325 , m_conservativeTestConfig (conservativeTestConfig)
2328 virtual void checkSupport (Context& context) const;
2330 virtual TestInstance* createInstance (Context& context) const
2332 return new ConcreteTestInstance(context, m_conservativeTestConfig, m_sampleCount);
2336 bool isUseLineSubPixel (Context& context) const;
2337 deUint32 getSubPixelResolution (Context& context) const;
2339 const ConservativeTestConfig m_conservativeTestConfig;
2342 template <typename ConcreteTestInstance>
2343 bool ConservativeTestCase<ConcreteTestInstance>::isUseLineSubPixel (Context& context) const
2345 return (isPrimitiveTopologyLine(m_conservativeTestConfig.primitiveTopology) && context.isDeviceFunctionalitySupported("VK_EXT_line_rasterization"));
2348 template <typename ConcreteTestInstance>
2349 deUint32 ConservativeTestCase<ConcreteTestInstance>::getSubPixelResolution (Context& context) const
2351 if (isUseLineSubPixel(context))
2353 const VkPhysicalDeviceLineRasterizationPropertiesEXT lineRasterizationPropertiesEXT = context.getLineRasterizationPropertiesEXT();
2355 return lineRasterizationPropertiesEXT.lineSubPixelPrecisionBits;
2359 return context.getDeviceProperties().limits.subPixelPrecisionBits;
2363 template <typename ConcreteTestInstance>
2364 void ConservativeTestCase<ConcreteTestInstance>::checkSupport (Context& context) const
2366 context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");
2368 const VkPhysicalDeviceConservativeRasterizationPropertiesEXT conservativeRasterizationProperties = context.getConservativeRasterizationPropertiesEXT();
2369 const deUint32 subPixelPrecisionBits = getSubPixelResolution(context);
2370 const deUint32 subPixelPrecision = 1<<subPixelPrecisionBits;
2371 const bool linesPrecision = isUseLineSubPixel(context);
2372 const float primitiveOverestimationSizeMult = float(subPixelPrecision) * conservativeRasterizationProperties.primitiveOverestimationSize;
2373 const bool topologyLineOrPoint = isPrimitiveTopologyLine(m_conservativeTestConfig.primitiveTopology) || isPrimitiveTopologyPoint(m_conservativeTestConfig.primitiveTopology);
2375 DE_ASSERT(subPixelPrecisionBits < sizeof(deUint32) * 8);
2377 context.getTestContext().getLog()
2378 << tcu::TestLog::Message
2379 << "maxExtraPrimitiveOverestimationSize=" << conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize << '\n'
2380 << "extraPrimitiveOverestimationSizeGranularity=" << conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity << '\n'
2381 << "degenerateLinesRasterized=" << conservativeRasterizationProperties.degenerateLinesRasterized << '\n'
2382 << "degenerateTrianglesRasterized=" << conservativeRasterizationProperties.degenerateTrianglesRasterized << '\n'
2383 << "primitiveOverestimationSize=" << conservativeRasterizationProperties.primitiveOverestimationSize << " (==" << primitiveOverestimationSizeMult << '/' << subPixelPrecision << ")\n"
2384 << "subPixelPrecisionBits=" << subPixelPrecisionBits << (linesPrecision ? " (using VK_EXT_line_rasterization)" : " (using limits)") << '\n'
2385 << tcu::TestLog::EndMessage;
2387 if (conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity > conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize)
2388 TCU_FAIL("Granularity cannot be greater than maximum extra size");
2390 if (topologyLineOrPoint)
2392 if (!conservativeRasterizationProperties.conservativePointAndLineRasterization)
2393 TCU_THROW(NotSupportedError, "Conservative line and point rasterization is not supported");
2396 if (m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT)
2398 if (conservativeRasterizationProperties.primitiveUnderestimation == DE_FALSE)
2399 TCU_THROW(NotSupportedError, "Underestimation is not supported");
2401 if (isPrimitiveTopologyLine(m_conservativeTestConfig.primitiveTopology))
2403 const float testLineWidth = m_conservativeTestConfig.lineWidth;
2405 if (testLineWidth != 1.0f)
2407 const VkPhysicalDeviceLimits& limits = context.getDeviceProperties().limits;
2408 const float lineWidthRange[2] = { limits.lineWidthRange[0], limits.lineWidthRange[1] };
2409 const float lineWidthGranularity = limits.lineWidthGranularity;
2411 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_WIDE_LINES);
2413 if (lineWidthGranularity == 0.0f)
2414 TCU_THROW(NotSupportedError, "Wide lines required for test, but are not supported");
2416 DE_ASSERT(lineWidthGranularity > 0.0f && lineWidthRange[0] > 0.0f && lineWidthRange[1] >= lineWidthRange[0]);
2418 if (!de::inBounds(testLineWidth, lineWidthRange[0], lineWidthRange[1]))
2419 TCU_THROW(NotSupportedError, "Tested line width is not supported");
2421 const float n = (testLineWidth - lineWidthRange[0]) / lineWidthGranularity;
2423 if (deFloatFrac(n) != 0.0f || n * lineWidthGranularity + lineWidthRange[0] != testLineWidth)
2424 TCU_THROW(NotSupportedError, "Exact match of line width is required for the test");
2427 else if (isPrimitiveTopologyPoint(m_conservativeTestConfig.primitiveTopology))
2429 const float testPointSize = m_conservativeTestConfig.lineWidth;
2431 if (testPointSize != 1.0f)
2433 const VkPhysicalDeviceLimits& limits = context.getDeviceProperties().limits;
2434 const float pointSizeRange[2] = { limits.pointSizeRange[0], limits.pointSizeRange[1] };
2435 const float pointSizeGranularity = limits.pointSizeGranularity;
2437 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);
2439 if (pointSizeGranularity == 0.0f)
2440 TCU_THROW(NotSupportedError, "Large points required for test, but are not supported");
2442 DE_ASSERT(pointSizeGranularity > 0.0f && pointSizeRange[0] > 0.0f && pointSizeRange[1] >= pointSizeRange[0]);
2444 if (!de::inBounds(testPointSize, pointSizeRange[0], pointSizeRange[1]))
2445 TCU_THROW(NotSupportedError, "Tested point size is not supported");
2447 const float n = (testPointSize - pointSizeRange[0]) / pointSizeGranularity;
2449 if (deFloatFrac(n) != 0.0f || n * pointSizeGranularity + pointSizeRange[0] != testPointSize)
2450 TCU_THROW(NotSupportedError, "Exact match of point size is required for the test");
2454 else if (m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT)
2456 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, conservativeRasterizationProperties);
2458 if (extraOverestimationSize > conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize)
2459 TCU_THROW(NotSupportedError, "Specified overestimation size is not supported");
2461 if (topologyLineOrPoint)
2463 if (!conservativeRasterizationProperties.conservativePointAndLineRasterization)
2464 TCU_THROW(NotSupportedError, "Conservative line and point rasterization is not supported");
2467 if (isPrimitiveTopologyTriangle(m_conservativeTestConfig.primitiveTopology))
2469 if (m_conservativeTestConfig.degeneratePrimitives)
2471 // Enforce specification minimum required limit to avoid division by zero
2472 DE_ASSERT(subPixelPrecisionBits >= 4);
2474 // Make sure float precision of 22 bits is enough, i.e. resoultion in subpixel quarters less than float precision
2475 if (m_conservativeTestConfig.resolution * (1<<(subPixelPrecisionBits + 2)) > (1<<21))
2476 TCU_THROW(NotSupportedError, "Subpixel resolution is too high to generate degenerate primitives");
2481 TCU_THROW(InternalError, "Non-conservative mode tests are not supported by this class");
2484 class ConservativeTraingleTestInstance : public BaseTriangleTestInstance
2487 ConservativeTraingleTestInstance (Context& context,
2488 ConservativeTestConfig conservativeTestConfig,
2489 VkSampleCountFlagBits sampleCount)
2490 : BaseTriangleTestInstance (context,
2491 conservativeTestConfig.primitiveTopology,
2493 conservativeTestConfig.resolution)
2494 , m_conservativeTestConfig (conservativeTestConfig)
2495 , m_conservativeRasterizationProperties (context.getConservativeRasterizationPropertiesEXT())
2496 , m_rasterizationConservativeStateCreateInfo (initRasterizationConservativeStateCreateInfo())
2497 , m_rasterizationStateCreateInfo (initRasterizationStateCreateInfo())
2500 void generateTriangles (int iteration,
2501 std::vector<tcu::Vec4>& outData,
2502 std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
2503 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
2506 virtual const VkPipelineRasterizationLineStateCreateInfoEXT* getLineRasterizationStateCreateInfo (void);
2508 virtual bool compareAndVerify (std::vector<TriangleSceneSpec::SceneTriangle>& triangles,
2509 tcu::Surface& resultImage,
2510 std::vector<tcu::Vec4>& drawBuffer);
2511 virtual bool compareAndVerifyOverestimatedNormal (std::vector<TriangleSceneSpec::SceneTriangle>& triangles,
2512 tcu::Surface& resultImage);
2513 virtual bool compareAndVerifyOverestimatedDegenerate (std::vector<TriangleSceneSpec::SceneTriangle>& triangles,
2514 tcu::Surface& resultImage);
2515 virtual bool compareAndVerifyUnderestimatedNormal (std::vector<TriangleSceneSpec::SceneTriangle>& triangles,
2516 tcu::Surface& resultImage);
2517 virtual bool compareAndVerifyUnderestimatedDegenerate (std::vector<TriangleSceneSpec::SceneTriangle>& triangles,
2518 tcu::Surface& resultImage);
2519 void generateNormalTriangles (int iteration,
2520 std::vector<tcu::Vec4>& outData,
2521 std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
2522 void generateDegenerateTriangles (int iteration,
2523 std::vector<tcu::Vec4>& outData,
2524 std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
2525 void drawPrimitives (tcu::Surface& result,
2526 const std::vector<tcu::Vec4>& vertexData,
2527 VkPrimitiveTopology primitiveTopology);
2530 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> initRasterizationConservativeStateCreateInfo (void);
2531 const std::vector<VkPipelineRasterizationStateCreateInfo> initRasterizationStateCreateInfo (void);
2533 const ConservativeTestConfig m_conservativeTestConfig;
2534 const VkPhysicalDeviceConservativeRasterizationPropertiesEXT m_conservativeRasterizationProperties;
2535 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> m_rasterizationConservativeStateCreateInfo;
2536 const std::vector<VkPipelineRasterizationStateCreateInfo> m_rasterizationStateCreateInfo;
2539 void ConservativeTraingleTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
2541 if (m_conservativeTestConfig.degeneratePrimitives)
2542 generateDegenerateTriangles(iteration, outData, outTriangles);
2544 generateNormalTriangles(iteration, outData, outTriangles);
2547 void ConservativeTraingleTestInstance::generateNormalTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
2549 const float halfPixel = 1.0f / float(m_renderSize);
2550 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
2551 const float overestimate = 2.0f * halfPixel * (m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize);
2552 const float overestimateMargin = overestimate;
2553 const float underestimateMargin = 0.0f;
2554 const bool isOverestimate = m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
2555 const float margin = isOverestimate ? overestimateMargin : underestimateMargin;
2556 const char* overestimateIterationComments[] = { "Corner touch", "Any portion pixel coverage", "Edge touch" };
2565 const float edge = 2 * halfPixel + margin;
2566 const float left = -1.0f + edge;
2567 const float right = +1.0f - edge;
2568 const float up = -1.0f + edge;
2569 const float down = +1.0f - edge;
2571 outData[0] = tcu::Vec4( left, down, 0.0f, 1.0f);
2572 outData[1] = tcu::Vec4( left, up, 0.0f, 1.0f);
2573 outData[2] = tcu::Vec4(right, down, 0.0f, 1.0f);
2575 outData[3] = tcu::Vec4( left, up, 0.0f, 1.0f);
2576 outData[4] = tcu::Vec4(right, down, 0.0f, 1.0f);
2577 outData[5] = tcu::Vec4(right, up, 0.0f, 1.0f);
2585 const float eps = halfPixel / 32.0f;
2586 const float edge = 4.0f * halfPixel + margin - eps;
2587 const float left = -1.0f + edge;
2588 const float right = +1.0f - edge;
2589 const float up = -1.0f + edge;
2590 const float down = +1.0f - edge;
2592 outData[0] = tcu::Vec4( left, down, 0.0f, 1.0f);
2593 outData[1] = tcu::Vec4( left, up, 0.0f, 1.0f);
2594 outData[2] = tcu::Vec4(right, down, 0.0f, 1.0f);
2596 outData[3] = tcu::Vec4( left, up, 0.0f, 1.0f);
2597 outData[4] = tcu::Vec4(right, down, 0.0f, 1.0f);
2598 outData[5] = tcu::Vec4(right, up, 0.0f, 1.0f);
2606 const float edge = 6.0f * halfPixel + margin;
2607 const float left = -1.0f + edge;
2608 const float right = +1.0f - edge;
2609 const float up = -1.0f + edge;
2610 const float down = +1.0f - edge;
2612 outData[0] = tcu::Vec4( left, down, 0.0f, 1.0f);
2613 outData[1] = tcu::Vec4( left, up, 0.0f, 1.0f);
2614 outData[2] = tcu::Vec4(right, down, 0.0f, 1.0f);
2616 outData[3] = tcu::Vec4( left, up, 0.0f, 1.0f);
2617 outData[4] = tcu::Vec4(right, down, 0.0f, 1.0f);
2618 outData[5] = tcu::Vec4(right, up, 0.0f, 1.0f);
2624 TCU_THROW(InternalError, "Unexpected iteration");
2627 outTriangles.resize(outData.size() / 3);
2629 for (size_t ndx = 0; ndx < outTriangles.size(); ++ndx)
2631 outTriangles[ndx].positions[0] = outData[3 * ndx + 0]; outTriangles[ndx].sharedEdge[0] = false;
2632 outTriangles[ndx].positions[1] = outData[3 * ndx + 1]; outTriangles[ndx].sharedEdge[1] = false;
2633 outTriangles[ndx].positions[2] = outData[3 * ndx + 2]; outTriangles[ndx].sharedEdge[2] = false;
2639 m_context.getTestContext().getLog()
2640 << tcu::TestLog::Message
2641 << "Testing " << overestimateIterationComments[iteration] << " "
2642 << "with rendering " << outTriangles.size() << " triangle(s):"
2643 << tcu::TestLog::EndMessage;
2647 m_context.getTestContext().getLog()
2648 << tcu::TestLog::Message
2649 << "Rendering " << outTriangles.size() << " triangle(s):"
2650 << tcu::TestLog::EndMessage;
2653 for (size_t ndx = 0; ndx < outTriangles.size(); ++ndx)
2655 const deUint32 multiplier = m_renderSize / 2;
2657 m_context.getTestContext().getLog()
2658 << tcu::TestLog::Message
2659 << "Triangle " << (ndx + 1) << ":"
2660 << "\n\t" << outTriangles[ndx].positions[0] << " == " << (float(multiplier) * outTriangles[ndx].positions[0]) << "/" << multiplier
2661 << "\n\t" << outTriangles[ndx].positions[1] << " == " << (float(multiplier) * outTriangles[ndx].positions[1]) << "/" << multiplier
2662 << "\n\t" << outTriangles[ndx].positions[2] << " == " << (float(multiplier) * outTriangles[ndx].positions[2]) << "/" << multiplier
2663 << tcu::TestLog::EndMessage;
2667 void ConservativeTraingleTestInstance::generateDegenerateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
2669 tcu::TestLog& log = m_context.getTestContext().getLog();
2670 const float pixelSize = 2.0f / float(m_renderSize);
2671 const deUint32 subPixels = 1u << m_context.getDeviceProperties().limits.subPixelPrecisionBits;
2672 const float subPixelSize = pixelSize / float(subPixels);
2673 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
2674 const float totalOverestimate = m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize;
2675 const float totalOverestimateInSubPixels = deFloatCeil(totalOverestimate * float(subPixels));
2676 const float overestimate = subPixelSize * totalOverestimateInSubPixels;
2677 const float overestimateSafetyMargin = subPixelSize * 0.125f;
2678 const float overestimateMargin = overestimate + overestimateSafetyMargin;
2679 const float underestimateMargin = 0.0f;
2680 const bool isOverestimate = m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
2681 const float margin = isOverestimate ? overestimateMargin : underestimateMargin;
2682 const char* overestimateIterationComments[] = { "Backfacing", "Generate pixels", "Use provoking vertex" };
2684 if (pixelSize < 2 * overestimateMargin)
2685 TCU_THROW(NotSupportedError, "Could not generate degenerate triangle for such overestimate parameters");
2695 for (int rowNdx = 0; rowNdx < 3; ++rowNdx)
2696 for (int colNdx = 0; colNdx < 4; ++colNdx)
2698 const float offsetX = -1.0f + float(4 * (colNdx + 1)) * pixelSize;
2699 const float offsetY = -1.0f + float(4 * (rowNdx + 1)) * pixelSize;
2700 const float left = offsetX + margin;
2701 const float right = offsetX + margin + 0.25f * subPixelSize;
2702 const float up = offsetY + margin;
2703 const float down = offsetY + margin + 0.25f * subPixelSize;
2704 const bool luPresent = (rowNdx & 1) == 0;
2705 const bool rdPresent = (rowNdx & 2) == 0;
2706 const bool luCW = (colNdx & 1) == 0;
2707 const bool rdCW = (colNdx & 2) == 0;
2709 DE_ASSERT(left < right);
2710 DE_ASSERT(up < down);
2716 // CW triangle left up
2717 outData.push_back(tcu::Vec4( left, down, 0.0f, 1.0f));
2718 outData.push_back(tcu::Vec4( left, up, 0.0f, 1.0f));
2719 outData.push_back(tcu::Vec4(right, up, 0.0f, 1.0f));
2723 // CCW triangle left up
2724 outData.push_back(tcu::Vec4(right, up, 0.0f, 1.0f));
2725 outData.push_back(tcu::Vec4( left, up, 0.0f, 1.0f));
2726 outData.push_back(tcu::Vec4( left, down, 0.0f, 1.0f));
2734 // CW triangle right down
2735 outData.push_back(tcu::Vec4(right, up, 0.0f, 1.0f));
2736 outData.push_back(tcu::Vec4(right, down, 0.0f, 1.0f));
2737 outData.push_back(tcu::Vec4( left, down, 0.0f, 1.0f));
2741 // CCW triangle right down
2742 outData.push_back(tcu::Vec4( left, down, 0.0f, 1.0f));
2743 outData.push_back(tcu::Vec4(right, down, 0.0f, 1.0f));
2744 outData.push_back(tcu::Vec4(right, up, 0.0f, 1.0f));
2753 TCU_THROW(InternalError, "Unexpected iteration");
2756 outTriangles.resize(outData.size() / 3);
2758 for (size_t ndx = 0; ndx < outTriangles.size(); ++ndx)
2760 outTriangles[ndx].positions[0] = outData[3 * ndx + 0]; outTriangles[ndx].sharedEdge[0] = false;
2761 outTriangles[ndx].positions[1] = outData[3 * ndx + 1]; outTriangles[ndx].sharedEdge[1] = false;
2762 outTriangles[ndx].positions[2] = outData[3 * ndx + 2]; outTriangles[ndx].sharedEdge[2] = false;
2768 m_context.getTestContext().getLog()
2769 << tcu::TestLog::Message
2770 << "Testing " << overestimateIterationComments[iteration] << " "
2771 << "with rendering " << outTriangles.size() << " triangle(s):"
2772 << tcu::TestLog::EndMessage;
2776 m_context.getTestContext().getLog()
2777 << tcu::TestLog::Message
2778 << "Rendering " << outTriangles.size() << " triangle(s):"
2779 << tcu::TestLog::EndMessage;
2782 for (int ndx = 0; ndx < (int)outTriangles.size(); ++ndx)
2784 const deUint32 multiplierInt = m_renderSize / 2;
2785 const deUint32 multiplierFrac = subPixels;
2786 std::string coordsString;
2788 for (size_t vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
2790 const tcu::Vec4& pos = outTriangles[ndx].positions[vertexNdx];
2791 std::ostringstream coordsFloat;
2792 std::ostringstream coordsNatural;
2794 for (int coordNdx = 0; coordNdx < 2; ++coordNdx)
2796 const char* sep = (coordNdx < 1) ? "," : "";
2797 const float coord = pos[coordNdx];
2798 const char sign = deSign(coord) < 0 ? '-' : '+';
2799 const float m = deFloatFloor(float(multiplierInt) * deFloatAbs(coord));
2800 const float r = deFloatFrac(float(multiplierInt) * deFloatAbs(coord)) * float(multiplierFrac);
2802 coordsFloat << std::fixed << std::setw(13) << std::setprecision(10) << coord << sep;
2803 coordsNatural << sign << '(' << m << '+' << r << '/' << multiplierFrac << ')' << sep;
2806 coordsString += "\n\t[" + coordsFloat.str() + "] == [" + coordsNatural.str() + "] / " + de::toString(multiplierInt);
2809 log << tcu::TestLog::Message
2810 << "Triangle " << (ndx + 1) << ':'
2812 << tcu::TestLog::EndMessage;
2816 void ConservativeTraingleTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology)
2818 if (m_conservativeTestConfig.degeneratePrimitives && getIteration() == 2)
2820 // Set provoking vertex color to white
2821 tcu::Vec4 colorProvoking (1.0f, 1.0f, 1.0f, 1.0f);
2822 tcu::Vec4 colorOther (0.0f, 1.0f, 1.0f, 1.0f);
2823 std::vector<tcu::Vec4> colorData;
2825 colorData.reserve(vertexData.size());
2827 for (size_t vertexNdx = 0; vertexNdx < vertexData.size(); ++vertexNdx)
2828 if (vertexNdx % 3 == 0)
2829 colorData.push_back(colorProvoking);
2831 colorData.push_back(colorOther);
2833 BaseRenderingTestInstance::drawPrimitives(result, vertexData, colorData, primitiveTopology);
2836 BaseRenderingTestInstance::drawPrimitives(result, vertexData, primitiveTopology);
2839 bool ConservativeTraingleTestInstance::compareAndVerify (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage, std::vector<tcu::Vec4>& drawBuffer)
2841 DE_UNREF(drawBuffer);
2843 switch (m_conservativeTestConfig.conservativeRasterizationMode)
2845 case VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT:
2847 if (m_conservativeTestConfig.degeneratePrimitives)
2848 return compareAndVerifyOverestimatedDegenerate(triangles, resultImage);
2850 return compareAndVerifyOverestimatedNormal(triangles, resultImage);
2855 case VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT:
2857 if (m_conservativeTestConfig.degeneratePrimitives)
2858 return compareAndVerifyUnderestimatedDegenerate(triangles, resultImage);
2860 return compareAndVerifyUnderestimatedNormal(triangles, resultImage);
2866 TCU_THROW(InternalError, "Unknown conservative rasterization mode");
2870 bool ConservativeTraingleTestInstance::compareAndVerifyOverestimatedNormal (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage)
2872 DE_UNREF(triangles);
2874 const int start = getIteration() + 1;
2875 const int end = resultImage.getHeight() - start;
2876 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
2877 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
2878 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
2879 tcu::TestLog& log = m_context.getTestContext().getLog();
2882 deUint32 errValue = 0;
2885 DE_ASSERT(resultImage.getHeight() == resultImage.getWidth());
2887 for (int y = start; result && y < end; ++y)
2888 for (int x = start; result && x < end; ++x)
2890 if (resultImage.getPixel(x,y).getPacked() != foregroundColor.getPacked())
2895 errValue = resultImage.getPixel(x,y).getPacked();
2903 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
2904 tcu::Surface expectedImage (resultImage.getWidth(), resultImage.getHeight());
2906 for (int y = 0; y < errorMask.getHeight(); ++y)
2907 for (int x = 0; x < errorMask.getWidth(); ++x)
2909 errorMask.setPixel(x, y, backgroundColor);
2910 expectedImage.setPixel(x, y, backgroundColor);
2913 for (int y = start; y < end; ++y)
2914 for (int x = start; x < end; ++x)
2916 expectedImage.setPixel(x, y, foregroundColor);
2918 if (resultImage.getPixel(x, y).getPacked() != foregroundColor.getPacked())
2919 errorMask.setPixel(x, y, unexpectedPixelColor);
2922 log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
2923 << tcu::TestLog::EndMessage;
2924 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
2925 << tcu::TestLog::Image("Result", "Result", resultImage)
2926 << tcu::TestLog::Image("Expected", "Expected", expectedImage)
2927 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
2928 << tcu::TestLog::EndImageSet;
2932 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
2933 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
2934 << tcu::TestLog::Image("Result", "Result", resultImage)
2935 << tcu::TestLog::EndImageSet;
2941 bool ConservativeTraingleTestInstance::compareAndVerifyOverestimatedDegenerate (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage)
2943 DE_UNREF(triangles);
2945 const char* iterationComments[] = { "Cull back face triangles", "Cull front face triangles", "Cull none" };
2946 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
2947 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
2948 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
2949 tcu::TestLog& log = m_context.getTestContext().getLog();
2951 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
2953 for (int y = 0; y < resultImage.getHeight(); ++y)
2954 for (int x = 0; x < resultImage.getWidth(); ++x)
2955 referenceImage.setPixel(x, y, backgroundColor);
2957 if (m_conservativeRasterizationProperties.degenerateTrianglesRasterized)
2959 if (getIteration() != 0)
2961 log << tcu::TestLog::Message << "Triangles expected to be rasterized with at least one pixel of white color each" << tcu::TestLog::EndMessage;
2963 for (int rowNdx = 0; rowNdx < 3; ++rowNdx)
2964 for (int colNdx = 0; colNdx < 4; ++colNdx)
2966 referenceImage.setPixel(4 * (colNdx + 1), 4 * (rowNdx + 1), foregroundColor);
2968 // Allow implementations that need to be extra conservative with degenerate triangles,
2969 // which may cause extra coverage.
2970 if (resultImage.getPixel(4 * (colNdx + 1) - 1, 4 * (rowNdx + 1) - 1) == foregroundColor)
2971 referenceImage.setPixel(4 * (colNdx + 1) - 1, 4 * (rowNdx + 1) - 1, foregroundColor);
2972 if (resultImage.getPixel(4 * (colNdx + 1) - 1, 4 * (rowNdx + 1)) == foregroundColor)
2973 referenceImage.setPixel(4 * (colNdx + 1) - 1, 4 * (rowNdx + 1), foregroundColor);
2974 if (resultImage.getPixel(4 * (colNdx + 1), 4 * (rowNdx + 1) - 1) == foregroundColor)
2975 referenceImage.setPixel(4 * (colNdx + 1), 4 * (rowNdx + 1) - 1, foregroundColor);
2979 log << tcu::TestLog::Message << "Triangles expected to be culled due to backfacing culling and all degenerate triangles assumed to be backfacing" << tcu::TestLog::EndMessage;
2982 log << tcu::TestLog::Message << "Triangles expected to be culled due to degenerateTrianglesRasterized=false" << tcu::TestLog::EndMessage;
2984 for (int y = 0; result && y < resultImage.getHeight(); ++y)
2985 for (int x = 0; result && x < resultImage.getWidth(); ++x)
2987 if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
2997 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
2999 for (int y = 0; y < errorMask.getHeight(); ++y)
3000 for (int x = 0; x < errorMask.getWidth(); ++x)
3002 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
3003 errorMask.setPixel(x, y, unexpectedPixelColor);
3005 errorMask.setPixel(x, y, backgroundColor);
3008 log << tcu::TestLog::Message << "Invalid pixels found for mode '" << iterationComments[getIteration()] << "'"
3009 << tcu::TestLog::EndMessage;
3010 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3011 << tcu::TestLog::Image("Result", "Result", resultImage)
3012 << tcu::TestLog::Image("Reference", "Reference", referenceImage)
3013 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
3014 << tcu::TestLog::EndImageSet;
3018 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
3019 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3020 << tcu::TestLog::Image("Result", "Result", resultImage)
3021 << tcu::TestLog::EndImageSet;
3027 bool ConservativeTraingleTestInstance::compareAndVerifyUnderestimatedNormal (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage)
3029 DE_UNREF(triangles);
3031 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
3032 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
3033 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
3034 const tcu::IVec2 viewportSize = tcu::IVec2(resultImage.getWidth(), resultImage.getHeight());
3035 tcu::TestLog& log = m_context.getTestContext().getLog();
3038 deUint32 errValue = 0;
3039 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
3042 DE_ASSERT(resultImage.getHeight() == resultImage.getWidth());
3044 for (int y = 0; y < resultImage.getHeight(); ++y)
3045 for (int x = 0; x < resultImage.getWidth(); ++x)
3046 referenceImage.setPixel(x, y, backgroundColor);
3048 for (size_t triangleNdx = 0; triangleNdx < triangles.size(); ++triangleNdx)
3050 const tcu::Vec4& p0 = triangles[triangleNdx].positions[0];
3051 const tcu::Vec4& p1 = triangles[triangleNdx].positions[1];
3052 const tcu::Vec4& p2 = triangles[triangleNdx].positions[2];
3054 for (int y = 0; y < resultImage.getHeight(); ++y)
3055 for (int x = 0; x < resultImage.getWidth(); ++x)
3057 if (calculateUnderestimateTriangleCoverage(p0, p1, p2, tcu::IVec2(x,y), m_subpixelBits, viewportSize) == tcu::COVERAGE_FULL)
3058 referenceImage.setPixel(x, y, foregroundColor);
3062 for (int y = 0; result && y < resultImage.getHeight(); ++y)
3063 for (int x = 0; result && x < resultImage.getWidth(); ++x)
3064 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
3069 errValue = resultImage.getPixel(x,y).getPacked();
3074 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
3076 for (int y = 0; y < errorMask.getHeight(); ++y)
3077 for (int x = 0; x < errorMask.getWidth(); ++x)
3079 if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
3080 errorMask.setPixel(x, y, unexpectedPixelColor);
3082 errorMask.setPixel(x, y, backgroundColor);
3085 log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
3086 << tcu::TestLog::EndMessage;
3087 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3088 << tcu::TestLog::Image("Result", "Result", resultImage)
3089 << tcu::TestLog::Image("Refernce", "Refernce", referenceImage)
3090 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
3091 << tcu::TestLog::EndImageSet;
3095 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
3096 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3097 << tcu::TestLog::Image("Result", "Result", resultImage)
3098 << tcu::TestLog::EndImageSet;
3104 bool ConservativeTraingleTestInstance::compareAndVerifyUnderestimatedDegenerate (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage)
3106 DE_UNREF(triangles);
3108 const char* iterationComments[] = { "Cull back face triangles", "Cull front face triangles", "Cull none" };
3109 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
3110 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
3111 tcu::TestLog& log = m_context.getTestContext().getLog();
3114 deUint32 errValue = 0;
3117 if (m_conservativeRasterizationProperties.degenerateTrianglesRasterized)
3119 if (getIteration() != 0)
3120 log << tcu::TestLog::Message << "Triangles expected to be not rendered due to no one triangle can fully cover fragment" << tcu::TestLog::EndMessage;
3122 log << tcu::TestLog::Message << "Triangles expected to be culled due to backfacing culling and all degenerate triangles assumed to be backfacing" << tcu::TestLog::EndMessage;
3125 log << tcu::TestLog::Message << "Triangles expected to be culled due to degenerateTrianglesRasterized=false" << tcu::TestLog::EndMessage;
3127 for (int y = 0; result && y < resultImage.getHeight(); ++y)
3128 for (int x = 0; result && x < resultImage.getWidth(); ++x)
3130 if (resultImage.getPixel(x, y).getPacked() != backgroundColor.getPacked())
3135 errValue = resultImage.getPixel(x,y).getPacked();
3143 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
3144 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
3146 for (int y = 0; y < resultImage.getHeight(); ++y)
3147 for (int x = 0; x < resultImage.getWidth(); ++x)
3148 referenceImage.setPixel(x, y, backgroundColor);
3150 for (int y = 0; y < errorMask.getHeight(); ++y)
3151 for (int x = 0; x < errorMask.getWidth(); ++x)
3153 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
3154 errorMask.setPixel(x, y, unexpectedPixelColor);
3156 errorMask.setPixel(x, y, backgroundColor);
3159 log << tcu::TestLog::Message << "Invalid pixels found for mode '" << iterationComments[getIteration()] << "' starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
3160 << tcu::TestLog::EndMessage;
3162 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3163 << tcu::TestLog::Image("Result", "Result", resultImage)
3164 << tcu::TestLog::Image("Reference", "Reference", referenceImage)
3165 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
3166 << tcu::TestLog::EndImageSet;
3170 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
3171 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3172 << tcu::TestLog::Image("Result", "Result", resultImage)
3173 << tcu::TestLog::EndImageSet;
3179 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> ConservativeTraingleTestInstance::initRasterizationConservativeStateCreateInfo (void)
3181 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
3182 std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> result;
3184 result.reserve(getIterationCount());
3186 for (int iteration = 0; iteration < getIterationCount(); ++iteration)
3188 const VkPipelineRasterizationConservativeStateCreateInfoEXT rasterizationConservativeStateCreateInfo =
3190 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
3191 DE_NULL, // const void* pNext;
3192 (VkPipelineRasterizationConservativeStateCreateFlagsEXT)0, // VkPipelineRasterizationConservativeStateCreateFlagsEXT flags;
3193 m_conservativeTestConfig.conservativeRasterizationMode, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
3194 extraOverestimationSize // float extraPrimitiveOverestimationSize;
3197 result.push_back(rasterizationConservativeStateCreateInfo);
3203 const std::vector<VkPipelineRasterizationStateCreateInfo> ConservativeTraingleTestInstance::initRasterizationStateCreateInfo (void)
3205 std::vector<VkPipelineRasterizationStateCreateInfo> result;
3207 result.reserve(getIterationCount());
3209 for (int iteration = 0; iteration < getIterationCount(); ++iteration)
3211 const VkCullModeFlags cullModeFlags = (!m_conservativeTestConfig.degeneratePrimitives) ? VK_CULL_MODE_NONE
3212 : (iteration == 0) ? VK_CULL_MODE_BACK_BIT
3213 : (iteration == 1) ? VK_CULL_MODE_FRONT_BIT
3214 : VK_CULL_MODE_NONE;
3216 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
3218 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
3219 &m_rasterizationConservativeStateCreateInfo[iteration], // const void* pNext;
3220 0, // VkPipelineRasterizationStateCreateFlags flags;
3221 false, // VkBool32 depthClampEnable;
3222 false, // VkBool32 rasterizerDiscardEnable;
3223 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
3224 cullModeFlags, // VkCullModeFlags cullMode;
3225 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
3226 VK_FALSE, // VkBool32 depthBiasEnable;
3227 0.0f, // float depthBiasConstantFactor;
3228 0.0f, // float depthBiasClamp;
3229 0.0f, // float depthBiasSlopeFactor;
3230 getLineWidth(), // float lineWidth;
3233 result.push_back(rasterizationStateCreateInfo);
3239 const VkPipelineRasterizationStateCreateInfo* ConservativeTraingleTestInstance::getRasterizationStateCreateInfo (void) const
3241 return &m_rasterizationStateCreateInfo[getIteration()];
3244 const VkPipelineRasterizationLineStateCreateInfoEXT* ConservativeTraingleTestInstance::getLineRasterizationStateCreateInfo (void)
3250 class ConservativeLineTestInstance : public BaseLineTestInstance
3253 ConservativeLineTestInstance (Context& context,
3254 ConservativeTestConfig conservativeTestConfig,
3255 VkSampleCountFlagBits sampleCount);
3257 void generateLines (int iteration,
3258 std::vector<tcu::Vec4>& outData,
3259 std::vector<LineSceneSpec::SceneLine>& outLines);
3260 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
3263 virtual const VkPipelineRasterizationLineStateCreateInfoEXT* getLineRasterizationStateCreateInfo (void);
3265 virtual bool compareAndVerify (std::vector<LineSceneSpec::SceneLine>& lines,
3266 tcu::Surface& resultImage,
3267 std::vector<tcu::Vec4>& drawBuffer);
3268 virtual bool compareAndVerifyOverestimatedNormal (std::vector<LineSceneSpec::SceneLine>& lines,
3269 tcu::Surface& resultImage);
3270 virtual bool compareAndVerifyOverestimatedDegenerate (std::vector<LineSceneSpec::SceneLine>& lines,
3271 tcu::Surface& resultImage);
3272 virtual bool compareAndVerifyUnderestimatedNormal (std::vector<LineSceneSpec::SceneLine>& lines,
3273 tcu::Surface& resultImage);
3274 virtual bool compareAndVerifyUnderestimatedDegenerate (std::vector<LineSceneSpec::SceneLine>& lines,
3275 tcu::Surface& resultImage);
3276 void generateNormalLines (int iteration,
3277 std::vector<tcu::Vec4>& outData,
3278 std::vector<LineSceneSpec::SceneLine>& outLines);
3279 void generateDegenerateLines (int iteration,
3280 std::vector<tcu::Vec4>& outData,
3281 std::vector<LineSceneSpec::SceneLine>& outLines);
3282 void drawPrimitives (tcu::Surface& result,
3283 const std::vector<tcu::Vec4>& vertexData,
3284 VkPrimitiveTopology primitiveTopology);
3287 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> initRasterizationConservativeStateCreateInfo (void);
3288 const std::vector<VkPipelineRasterizationStateCreateInfo> initRasterizationStateCreateInfo (void);
3290 const ConservativeTestConfig m_conservativeTestConfig;
3291 const VkPhysicalDeviceConservativeRasterizationPropertiesEXT m_conservativeRasterizationProperties;
3292 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> m_rasterizationConservativeStateCreateInfo;
3293 const std::vector<VkPipelineRasterizationStateCreateInfo> m_rasterizationStateCreateInfo;
3296 ConservativeLineTestInstance::ConservativeLineTestInstance (Context& context,
3297 ConservativeTestConfig conservativeTestConfig,
3298 VkSampleCountFlagBits sampleCount)
3299 : BaseLineTestInstance (
3301 conservativeTestConfig.primitiveTopology,
3302 PRIMITIVEWIDENESS_NARROW,
3303 PRIMITIVESTRICTNESS_IGNORE,
3305 LINESTIPPLE_DISABLED,
3306 VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT,
3307 LineStippleFactorCase::DEFAULT,
3309 conservativeTestConfig.resolution,
3310 conservativeTestConfig.lineWidth
3312 , m_conservativeTestConfig (conservativeTestConfig)
3313 , m_conservativeRasterizationProperties (context.getConservativeRasterizationPropertiesEXT())
3314 , m_rasterizationConservativeStateCreateInfo (initRasterizationConservativeStateCreateInfo())
3315 , m_rasterizationStateCreateInfo (initRasterizationStateCreateInfo())
3319 void ConservativeLineTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
3321 if (m_conservativeTestConfig.degeneratePrimitives)
3322 generateDegenerateLines(iteration, outData, outLines);
3324 generateNormalLines(iteration, outData, outLines);
3327 void ConservativeLineTestInstance::generateNormalLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
3329 const char* iterationComment = "";
3330 const float halfPixel = 1.0f / float(m_renderSize);
3331 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
3332 const float overestimate = 2.0f * halfPixel * (m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize);
3333 const float overestimateMargin = overestimate;
3334 const float underestimateMargin = 0.0f;
3335 const bool isOverestimate = m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
3336 const float margin = isOverestimate ? overestimateMargin : underestimateMargin;
3337 const float edge = 4 * halfPixel + margin;
3338 const float left = -1.0f + edge;
3339 const float right = +1.0f - edge;
3340 const float up = -1.0f + edge;
3341 const float down = +1.0f - edge;
3347 const char* iterationComments[] = { "Horizontal up line", "Vertical line", "Horizontal down line" };
3349 iterationComment = iterationComments[iteration];
3355 outData.push_back(tcu::Vec4( left, up + halfPixel, 0.0f, 1.0f));
3356 outData.push_back(tcu::Vec4( right, up + halfPixel, 0.0f, 1.0f));
3363 outData.push_back(tcu::Vec4( left + halfPixel, up, 0.0f, 1.0f));
3364 outData.push_back(tcu::Vec4( left + halfPixel, down, 0.0f, 1.0f));
3371 outData.push_back(tcu::Vec4( left, down - halfPixel, 0.0f, 1.0f));
3372 outData.push_back(tcu::Vec4( right, down - halfPixel, 0.0f, 1.0f));
3378 TCU_THROW(InternalError, "Unexpected iteration");
3383 const char* iterationComments[] = { "Horizontal lines", "Vertical lines", "Diagonal lines" };
3384 const deUint32 subPixels = 1u << m_subpixelBits;
3385 const float subPixelSize = 2.0f * halfPixel / float(subPixels);
3386 const float blockStep = 16.0f * 2.0f * halfPixel;
3387 const float lineWidth = 2.0f * halfPixel * getLineWidth();
3388 const float offsets[] =
3390 float(1) * blockStep,
3391 float(2) * blockStep + halfPixel,
3392 float(3) * blockStep + 0.5f * lineWidth + 2.0f * subPixelSize,
3393 float(4) * blockStep + 0.5f * lineWidth - 2.0f * subPixelSize,
3396 iterationComment = iterationComments[iteration];
3398 outData.reserve(DE_LENGTH_OF_ARRAY(offsets));
3404 for (size_t lineNdx = 0; lineNdx < DE_LENGTH_OF_ARRAY(offsets); ++lineNdx)
3406 outData.push_back(tcu::Vec4( left + halfPixel, up + offsets[lineNdx], 0.0f, 1.0f));
3407 outData.push_back(tcu::Vec4(right - halfPixel, up + offsets[lineNdx], 0.0f, 1.0f));
3415 for (size_t lineNdx = 0; lineNdx < DE_LENGTH_OF_ARRAY(offsets); ++lineNdx)
3417 outData.push_back(tcu::Vec4(left + offsets[lineNdx], up + halfPixel, 0.0f, 1.0f));
3418 outData.push_back(tcu::Vec4(left + offsets[lineNdx], down - halfPixel, 0.0f, 1.0f));
3426 for (size_t lineNdx = 0; lineNdx < DE_LENGTH_OF_ARRAY(offsets); ++lineNdx)
3428 outData.push_back(tcu::Vec4(left + offsets[lineNdx], up + halfPixel, 0.0f, 1.0f));
3429 outData.push_back(tcu::Vec4( right - halfPixel, down - offsets[lineNdx], 0.0f, 1.0f));
3436 TCU_THROW(InternalError, "Unexpected iteration");
3440 DE_ASSERT(outData.size() % 2 == 0);
3441 outLines.resize(outData.size() / 2);
3442 for(size_t lineNdx = 0; lineNdx < outLines.size(); ++lineNdx)
3444 outLines[lineNdx].positions[0] = outData[2 * lineNdx + 0];
3445 outLines[lineNdx].positions[1] = outData[2 * lineNdx + 1];
3449 m_context.getTestContext().getLog()
3450 << tcu::TestLog::Message
3451 << "Testing " << iterationComment << " "
3452 << "with rendering " << outLines.size() << " line(s):"
3453 << tcu::TestLog::EndMessage;
3455 for (int ndx = 0; ndx < (int)outLines.size(); ++ndx)
3457 const deUint32 multiplier = m_renderSize / 2;
3459 m_context.getTestContext().getLog()
3460 << tcu::TestLog::Message
3461 << "Line " << (ndx+1) << ":"
3462 << "\n\t" << outLines[ndx].positions[0] << " == " << (float(multiplier) * outLines[ndx].positions[0]) << "/" << multiplier
3463 << "\n\t" << outLines[ndx].positions[1] << " == " << (float(multiplier) * outLines[ndx].positions[1]) << "/" << multiplier
3464 << tcu::TestLog::EndMessage;
3468 void ConservativeLineTestInstance::generateDegenerateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
3470 const bool isOverestimate = m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
3471 const float pixelSize = 2.0f / float(m_renderSize);
3472 const deUint32 subPixels = 1u << m_context.getDeviceProperties().limits.subPixelPrecisionBits;
3473 const float subPixelSize = pixelSize / float(subPixels);
3474 const char* iterationComments[] = { "Horizontal line", "Vertical line", "Diagonal line" };
3480 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
3481 const float totalOverestimate = m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize;
3482 const float totalOverestimateInSubPixels = deFloatCeil(totalOverestimate * float(subPixels));
3483 const float overestimate = subPixelSize * totalOverestimateInSubPixels;
3484 const float overestimateSafetyMargin = subPixelSize * 0.125f;
3485 const float margin = overestimate + overestimateSafetyMargin;
3486 const float originOffset = -1.0f + 1 * pixelSize;
3487 const float originLeft = originOffset + margin;
3488 const float originRight = originOffset + margin + 0.25f * subPixelSize;
3489 const float originUp = originOffset + margin;
3490 const float originDown = originOffset + margin + 0.25f * subPixelSize;
3496 outData.push_back(tcu::Vec4( originLeft, originUp, 0.0f, 1.0f));
3497 outData.push_back(tcu::Vec4(originRight, originUp, 0.0f, 1.0f));
3504 outData.push_back(tcu::Vec4( originLeft, originUp, 0.0f, 1.0f));
3505 outData.push_back(tcu::Vec4( originLeft, originDown, 0.0f, 1.0f));
3512 outData.push_back(tcu::Vec4( originLeft, originUp, 0.0f, 1.0f));
3513 outData.push_back(tcu::Vec4(originRight, originDown, 0.0f, 1.0f));
3519 TCU_THROW(InternalError, "Unexpected iteration");
3524 size_t rowStart = 3 * getIteration();
3525 size_t rowEnd = 3 * (getIteration() + 1);
3527 for (size_t rowNdx = rowStart; rowNdx < rowEnd; ++rowNdx)
3528 for (size_t colNdx = 0; colNdx < 3 * 3; ++colNdx)
3530 const float originOffsetY = -1.0f + float(4 * (1 + rowNdx)) * pixelSize;
3531 const float originOffsetX = -1.0f + float(4 * (1 + colNdx)) * pixelSize;
3532 const float x0 = float(rowNdx % 3);
3533 const float y0 = float(rowNdx / 3);
3534 const float x1 = float(colNdx % 3);
3535 const float y1 = float(colNdx / 3);
3536 const tcu::Vec4 p0 = tcu::Vec4(originOffsetX + x0 * pixelSize / 2.0f, originOffsetY + y0 * pixelSize / 2.0f, 0.0f, 1.0f);
3537 const tcu::Vec4 p1 = tcu::Vec4(originOffsetX + x1 * pixelSize / 2.0f, originOffsetY + y1 * pixelSize / 2.0f, 0.0f, 1.0f);
3539 if (x0 == x1 && y0 == y1)
3542 outData.push_back(p0);
3543 outData.push_back(p1);
3547 outLines.resize(outData.size() / 2);
3549 for (size_t ndx = 0; ndx < outLines.size(); ++ndx)
3551 outLines[ndx].positions[0] = outData[2 * ndx + 0];
3552 outLines[ndx].positions[1] = outData[2 * ndx + 1];
3556 m_context.getTestContext().getLog()
3557 << tcu::TestLog::Message
3558 << "Testing " << iterationComments[iteration] << " "
3559 << "with rendering " << outLines.size() << " line(s):"
3560 << tcu::TestLog::EndMessage;
3562 for (int ndx = 0; ndx < (int)outLines.size(); ++ndx)
3564 const deUint32 multiplierInt = m_renderSize / 2;
3565 const deUint32 multiplierFrac = subPixels;
3566 std::string coordsString;
3568 for (size_t vertexNdx = 0; vertexNdx < 2; ++vertexNdx)
3570 const tcu::Vec4& pos = outLines[ndx].positions[vertexNdx];
3571 std::ostringstream coordsFloat;
3572 std::ostringstream coordsNatural;
3574 for (int coordNdx = 0; coordNdx < 2; ++coordNdx)
3576 const char* sep = (coordNdx < 1) ? "," : "";
3577 const float coord = pos[coordNdx];
3578 const char sign = deSign(coord) < 0 ? '-' : '+';
3579 const float m = deFloatFloor(float(multiplierInt) * deFloatAbs(coord));
3580 const float r = deFloatFrac(float(multiplierInt) * deFloatAbs(coord)) * float(multiplierFrac);
3582 coordsFloat << std::fixed << std::setw(13) << std::setprecision(10) << coord << sep;
3583 coordsNatural << sign << '(' << m << '+' << r << '/' << multiplierFrac << ')' << sep;
3586 coordsString += "\n\t[" + coordsFloat.str() + "] == [" + coordsNatural.str() + "] / " + de::toString(multiplierInt);
3589 m_context.getTestContext().getLog()
3590 << tcu::TestLog::Message
3591 << "Line " << (ndx + 1) << ':'
3593 << tcu::TestLog::EndMessage;
3597 void ConservativeLineTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology)
3599 if (m_conservativeTestConfig.degeneratePrimitives)
3601 // Set provoking vertex color to white
3602 tcu::Vec4 colorProvoking (1.0f, 1.0f, 1.0f, 1.0f);
3603 tcu::Vec4 colorOther (0.0f, 1.0f, 1.0f, 1.0f);
3604 std::vector<tcu::Vec4> colorData;
3606 colorData.reserve(vertexData.size());
3608 for (size_t vertexNdx = 0; vertexNdx < vertexData.size(); ++vertexNdx)
3609 if (vertexNdx % 2 == 0)
3610 colorData.push_back(colorProvoking);
3612 colorData.push_back(colorOther);
3614 BaseRenderingTestInstance::drawPrimitives(result, vertexData, colorData, primitiveTopology);
3617 BaseRenderingTestInstance::drawPrimitives(result, vertexData, primitiveTopology);
3620 bool ConservativeLineTestInstance::compareAndVerify (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage, std::vector<tcu::Vec4>& drawBuffer)
3622 DE_UNREF(drawBuffer);
3624 switch (m_conservativeTestConfig.conservativeRasterizationMode)
3626 case VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT:
3628 if (m_conservativeTestConfig.degeneratePrimitives)
3629 return compareAndVerifyOverestimatedDegenerate(lines, resultImage);
3631 return compareAndVerifyOverestimatedNormal(lines, resultImage);
3635 case VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT:
3637 if (m_conservativeTestConfig.degeneratePrimitives)
3638 return compareAndVerifyUnderestimatedDegenerate(lines, resultImage);
3640 return compareAndVerifyUnderestimatedNormal(lines, resultImage);
3646 TCU_THROW(InternalError, "Unknown conservative rasterization mode");
3650 bool ConservativeLineTestInstance::compareAndVerifyOverestimatedNormal (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage)
3654 const int b = 3; // bar width
3655 const int w = resultImage.getWidth() - 1;
3656 const int h = resultImage.getHeight() - 1;
3657 const int xStarts[] = { 1, 1, 1 };
3658 const int xEnds[] = { w - 1, b, w - 1 };
3659 const int yStarts[] = { 1, 1, h - b };
3660 const int yEnds[] = { b, h - 1, h - 1 };
3661 const int xStart = xStarts[getIteration()];
3662 const int xEnd = xEnds[getIteration()];
3663 const int yStart = yStarts[getIteration()];
3664 const int yEnd = yEnds[getIteration()];
3665 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
3666 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
3667 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
3668 tcu::TestLog& log = m_context.getTestContext().getLog();
3671 deUint32 errValue = 0;
3674 DE_ASSERT(resultImage.getHeight() == resultImage.getWidth());
3676 for (int y = yStart; result && y < yEnd; ++y)
3677 for (int x = xStart; result && x < xEnd; ++x)
3679 if (resultImage.getPixel(x,y).getPacked() != foregroundColor.getPacked())
3684 errValue = resultImage.getPixel(x,y).getPacked();
3692 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
3694 for (int y = 0; y < errorMask.getHeight(); ++y)
3695 for (int x = 0; x < errorMask.getWidth(); ++x)
3696 errorMask.setPixel(x, y, backgroundColor);
3698 for (int y = yStart; y < yEnd; ++y)
3699 for (int x = xStart; x < xEnd; ++x)
3701 if (resultImage.getPixel(x,y).getPacked() != foregroundColor.getPacked())
3702 errorMask.setPixel(x,y, unexpectedPixelColor);
3705 log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
3706 << tcu::TestLog::EndMessage;
3707 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3708 << tcu::TestLog::Image("Result", "Result", resultImage)
3709 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
3710 << tcu::TestLog::EndImageSet;
3714 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
3715 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3716 << tcu::TestLog::Image("Result", "Result", resultImage)
3717 << tcu::TestLog::EndImageSet;
3723 bool ConservativeLineTestInstance::compareAndVerifyOverestimatedDegenerate (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage)
3727 const char* iterationComments[] = { "Horizontal line", "Vertical line", "Diagonal line" };
3728 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
3729 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
3730 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
3731 tcu::TestLog& log = m_context.getTestContext().getLog();
3733 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
3735 for (int y = 0; y < resultImage.getHeight(); ++y)
3736 for (int x = 0; x < resultImage.getWidth(); ++x)
3737 referenceImage.setPixel(x, y, backgroundColor);
3739 if (m_conservativeRasterizationProperties.degenerateLinesRasterized)
3741 log << tcu::TestLog::Message << "Lines expected to be rasterized with white color" << tcu::TestLog::EndMessage;
3743 // This pixel will alway be covered due to the placement of the line.
3744 referenceImage.setPixel(1, 1, foregroundColor);
3746 // Additional pixels will be covered based on the extra bloat added to the primitive.
3747 const float extraOverestimation = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
3748 const int xExtent = 1 + int((extraOverestimation * 2.0f) + 0.5f);
3749 const int yExtent = xExtent;
3751 for (int y = 0; y <= yExtent; ++y)
3752 for (int x = 0; x <= xExtent; ++x)
3753 referenceImage.setPixel(x, y, foregroundColor);
3756 log << tcu::TestLog::Message << "Lines expected to be culled" << tcu::TestLog::EndMessage;
3758 for (int y = 0; result && y < resultImage.getHeight(); ++y)
3759 for (int x = 0; result && x < resultImage.getWidth(); ++x)
3761 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
3771 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
3773 for (int y = 0; y < errorMask.getHeight(); ++y)
3774 for (int x = 0; x < errorMask.getWidth(); ++x)
3776 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
3777 errorMask.setPixel(x, y, unexpectedPixelColor);
3779 errorMask.setPixel(x, y, backgroundColor);
3782 log << tcu::TestLog::Message << "Invalid pixels found for mode " << iterationComments[getIteration()]
3783 << tcu::TestLog::EndMessage;
3784 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3785 << tcu::TestLog::Image("Result", "Result", resultImage)
3786 << tcu::TestLog::Image("Reference", "Reference", referenceImage)
3787 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
3788 << tcu::TestLog::EndImageSet;
3792 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
3793 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3794 << tcu::TestLog::Image("Result", "Result", resultImage)
3795 << tcu::TestLog::EndImageSet;
3801 bool ConservativeLineTestInstance::compareAndVerifyUnderestimatedNormal (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage)
3805 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
3806 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
3807 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
3808 tcu::TestLog& log = m_context.getTestContext().getLog();
3813 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
3815 DE_ASSERT(resultImage.getHeight() == resultImage.getWidth());
3817 for (int y = 0; y < referenceImage.getHeight(); ++y)
3818 for (int x = 0; x < referenceImage.getWidth(); ++x)
3819 referenceImage.setPixel(x, y, backgroundColor);
3821 if (getLineWidth() > 1.0f)
3823 const tcu::IVec2 viewportSize(resultImage.getWidth(), resultImage.getHeight());
3825 for (size_t lineNdx = 0; lineNdx < lines.size(); ++lineNdx)
3826 for (int y = 0; y < resultImage.getHeight(); ++y)
3827 for (int x = 0; x < resultImage.getWidth(); ++x)
3829 if (calculateUnderestimateLineCoverage(lines[lineNdx].positions[0], lines[lineNdx].positions[1], getLineWidth(), tcu::IVec2(x,y), viewportSize) == tcu::COVERAGE_FULL)
3830 referenceImage.setPixel(x, y, foregroundColor);
3834 for (int y = 0; result && y < resultImage.getHeight(); ++y)
3835 for (int x = 0; result && x < resultImage.getWidth(); ++x)
3837 if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
3842 errValue = resultImage.getPixel(x,y);
3850 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
3852 for (int y = 0; y < errorMask.getHeight(); ++y)
3853 for (int x = 0; x < errorMask.getWidth(); ++x)
3854 errorMask.setPixel(x, y, backgroundColor);
3856 for (int y = 0; y < errorMask.getHeight(); ++y)
3857 for (int x = 0; x < errorMask.getWidth(); ++x)
3859 if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
3860 errorMask.setPixel(x, y, unexpectedPixelColor);
3863 log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " errValue=" << errValue
3864 << tcu::TestLog::EndMessage;
3865 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3866 << tcu::TestLog::Image("Result", "Result", resultImage)
3867 << tcu::TestLog::Image("Reference", "Reference", referenceImage)
3868 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
3869 << tcu::TestLog::EndImageSet;
3873 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
3874 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3875 << tcu::TestLog::Image("Result", "Result", resultImage)
3876 << tcu::TestLog::EndImageSet;
3882 bool ConservativeLineTestInstance::compareAndVerifyUnderestimatedDegenerate (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage)
3886 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
3887 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
3888 tcu::TestLog& log = m_context.getTestContext().getLog();
3890 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
3892 for (int y = 0; y < resultImage.getHeight(); ++y)
3893 for (int x = 0; x < resultImage.getWidth(); ++x)
3894 referenceImage.setPixel(x, y, backgroundColor);
3896 log << tcu::TestLog::Message << "No lines expected to be rasterized" << tcu::TestLog::EndMessage;
3898 for (int y = 0; result && y < resultImage.getHeight(); ++y)
3899 for (int x = 0; result && x < resultImage.getWidth(); ++x)
3901 if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
3911 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
3913 for (int y = 0; y < errorMask.getHeight(); ++y)
3914 for (int x = 0; x < errorMask.getWidth(); ++x)
3916 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
3917 errorMask.setPixel(x, y, unexpectedPixelColor);
3919 errorMask.setPixel(x, y, backgroundColor);
3922 log << tcu::TestLog::Message << "Invalid pixels found" << tcu::TestLog::EndMessage;
3923 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3924 << tcu::TestLog::Image("Result", "Result", resultImage)
3925 << tcu::TestLog::Image("Reference", "Reference", referenceImage)
3926 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
3927 << tcu::TestLog::EndImageSet;
3931 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
3932 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3933 << tcu::TestLog::Image("Result", "Result", resultImage)
3934 << tcu::TestLog::EndImageSet;
3940 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> ConservativeLineTestInstance::initRasterizationConservativeStateCreateInfo (void)
3942 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
3943 std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> result;
3945 result.reserve(getIterationCount());
3947 for (int iteration = 0; iteration < getIterationCount(); ++iteration)
3949 const VkPipelineRasterizationConservativeStateCreateInfoEXT rasterizationConservativeStateCreateInfo =
3951 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
3952 DE_NULL, // const void* pNext;
3953 (VkPipelineRasterizationConservativeStateCreateFlagsEXT)0, // VkPipelineRasterizationConservativeStateCreateFlagsEXT flags;
3954 m_conservativeTestConfig.conservativeRasterizationMode, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
3955 extraOverestimationSize // float extraPrimitiveOverestimationSize;
3958 result.push_back(rasterizationConservativeStateCreateInfo);
3964 const std::vector<VkPipelineRasterizationStateCreateInfo> ConservativeLineTestInstance::initRasterizationStateCreateInfo (void)
3966 std::vector<VkPipelineRasterizationStateCreateInfo> result;
3968 result.reserve(getIterationCount());
3970 for (int iteration = 0; iteration < getIterationCount(); ++iteration)
3972 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
3974 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
3975 &m_rasterizationConservativeStateCreateInfo[iteration], // const void* pNext;
3976 0, // VkPipelineRasterizationStateCreateFlags flags;
3977 false, // VkBool32 depthClampEnable;
3978 false, // VkBool32 rasterizerDiscardEnable;
3979 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
3980 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
3981 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
3982 VK_FALSE, // VkBool32 depthBiasEnable;
3983 0.0f, // float depthBiasConstantFactor;
3984 0.0f, // float depthBiasClamp;
3985 0.0f, // float depthBiasSlopeFactor;
3986 getLineWidth(), // float lineWidth;
3989 result.push_back(rasterizationStateCreateInfo);
3995 const VkPipelineRasterizationStateCreateInfo* ConservativeLineTestInstance::getRasterizationStateCreateInfo (void) const
3997 return &m_rasterizationStateCreateInfo[getIteration()];
4000 const VkPipelineRasterizationLineStateCreateInfoEXT* ConservativeLineTestInstance::getLineRasterizationStateCreateInfo (void)
4006 class ConservativePointTestInstance : public PointTestInstance
4009 ConservativePointTestInstance (Context& context,
4010 ConservativeTestConfig conservativeTestConfig,
4011 VkSampleCountFlagBits sampleCount)
4012 : PointTestInstance (
4014 PRIMITIVEWIDENESS_NARROW,
4015 PRIMITIVESTRICTNESS_IGNORE,
4017 LINESTIPPLE_DISABLED,
4018 VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT,
4019 LineStippleFactorCase::DEFAULT,
4021 conservativeTestConfig.resolution,
4022 conservativeTestConfig.lineWidth
4024 , m_conservativeTestConfig (conservativeTestConfig)
4025 , m_conservativeRasterizationProperties (context.getConservativeRasterizationPropertiesEXT())
4026 , m_rasterizationConservativeStateCreateInfo (initRasterizationConservativeStateCreateInfo())
4027 , m_rasterizationStateCreateInfo (initRasterizationStateCreateInfo())
4032 void generatePoints (int iteration,
4033 std::vector<tcu::Vec4>& outData,
4034 std::vector<PointSceneSpec::ScenePoint>& outPoints);
4035 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
4038 virtual const VkPipelineRasterizationLineStateCreateInfoEXT* getLineRasterizationStateCreateInfo (void);
4040 virtual bool compareAndVerify (std::vector<PointSceneSpec::ScenePoint>& points,
4041 tcu::Surface& resultImage,
4042 std::vector<tcu::Vec4>& drawBuffer);
4043 virtual bool compareAndVerifyOverestimated (std::vector<PointSceneSpec::ScenePoint>& points,
4044 tcu::Surface& resultImage);
4045 virtual bool compareAndVerifyUnderestimated (std::vector<PointSceneSpec::ScenePoint>& points,
4046 tcu::Surface& resultImage);
4049 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> initRasterizationConservativeStateCreateInfo (void);
4050 const std::vector<VkPipelineRasterizationStateCreateInfo> initRasterizationStateCreateInfo (void);
4052 const ConservativeTestConfig m_conservativeTestConfig;
4053 const VkPhysicalDeviceConservativeRasterizationPropertiesEXT m_conservativeRasterizationProperties;
4054 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> m_rasterizationConservativeStateCreateInfo;
4055 const std::vector<VkPipelineRasterizationStateCreateInfo> m_rasterizationStateCreateInfo;
4056 std::vector<int> m_renderStart;
4057 std::vector<int> m_renderEnd;
4060 void ConservativePointTestInstance::generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints)
4062 const float pixelSize = 2.0f / float(m_renderSize);
4063 const bool isOverestimate = m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
4065 m_renderStart.clear();
4066 m_renderEnd.clear();
4070 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
4071 const float overestimate = m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize;
4072 const float halfRenderAreaSize = overestimate + 0.5f;
4073 const float pointCenterOffset = 2.0f + 0.5f * float(iteration) + halfRenderAreaSize;
4074 const float pointEdgeStart = pointCenterOffset - halfRenderAreaSize;
4075 const float pointEdgeEnd = pointEdgeStart + 2 * halfRenderAreaSize;
4076 const int renderStart = int(deFloatFloor(pointEdgeStart)) + int((deFloatFrac(pointEdgeStart) > 0.0f) ? 0 : -1);
4077 const int renderEnd = int(deFloatCeil(pointEdgeEnd)) + int((deFloatFrac(pointEdgeEnd) > 0.0f) ? 0 : 1);
4079 outData.push_back(tcu::Vec4(-1.0f + pixelSize * pointCenterOffset, -1.0f + pixelSize * pointCenterOffset, 0.0f, 1.0f));
4081 m_renderStart.push_back(renderStart);
4082 m_renderEnd.push_back(renderEnd);
4086 const float pointSize = m_conservativeTestConfig.lineWidth;
4087 const float halfRenderAreaSize = pointSize / 2.0f;
4093 const float pointCenterOffset = (pointSize + 1.0f + deFloatFrac(pointSize)) / 2.0f;
4094 const float pointEdgeStart = pointCenterOffset - halfRenderAreaSize;
4095 const float pointEdgeEnd = pointEdgeStart + 2.0f * halfRenderAreaSize;
4096 const int renderStart = (m_renderSize / 2) + int(deFloatCeil(pointEdgeStart));
4097 const int renderEnd = (m_renderSize / 2) + int(deFloatFloor(pointEdgeEnd));
4099 outData.push_back(tcu::Vec4(pixelSize * pointCenterOffset, pixelSize * pointCenterOffset, 0.0f, 1.0f));
4101 m_renderStart.push_back(renderStart);
4102 m_renderEnd.push_back(renderEnd);
4109 const float subPixelSize = 1.0f / float(1u<<(m_subpixelBits - 1));
4110 const float pointBottomLeft = 1.0f - subPixelSize;
4111 const float pointCenterOffset = pointBottomLeft + pointSize / 2.0f;
4112 const float pointEdgeStart = pointCenterOffset - halfRenderAreaSize;
4113 const float pointEdgeEnd = pointEdgeStart + 2.0f * halfRenderAreaSize;
4114 const int renderStart = (m_renderSize / 2) + int(deFloatCeil(pointEdgeStart));
4115 const int renderEnd = (m_renderSize / 2) + int(deFloatFloor(pointEdgeEnd));
4117 outData.push_back(tcu::Vec4(pixelSize * pointCenterOffset, pixelSize * pointCenterOffset, 0.0f, 1.0f));
4119 m_renderStart.push_back(renderStart);
4120 m_renderEnd.push_back(renderEnd);
4127 // Edges of a point are considered not covered. Top-left coverage rule is not applicable for underestimate rasterization.
4128 const float pointCenterOffset = (pointSize + deFloatFrac(pointSize)) / 2.0f;
4129 const float pointEdgeStart = pointCenterOffset - halfRenderAreaSize;
4130 const float pointEdgeEnd = pointEdgeStart + 2.0f * halfRenderAreaSize;
4131 const int renderStart = (m_renderSize / 2) + int(deFloatCeil(pointEdgeStart)) + 1;
4132 const int renderEnd = (m_renderSize / 2) + int(deFloatFloor(pointEdgeEnd)) - 1;
4134 outData.push_back(tcu::Vec4(pixelSize * pointCenterOffset, pixelSize * pointCenterOffset, 0.0f, 1.0f));
4136 m_renderStart.push_back(renderStart);
4137 m_renderEnd.push_back(renderEnd);
4143 TCU_THROW(InternalError, "Unexpected iteration");
4147 outPoints.resize(outData.size());
4148 for (size_t ndx = 0; ndx < outPoints.size(); ++ndx)
4150 outPoints[ndx].position = outData[ndx];
4151 outPoints[ndx].pointSize = getPointSize();
4155 m_context.getTestContext().getLog()
4156 << tcu::TestLog::Message
4157 << "Testing conservative point rendering "
4158 << "with rendering " << outPoints.size() << " points(s):"
4159 << tcu::TestLog::EndMessage;
4160 for (int ndx = 0; ndx < (int)outPoints.size(); ++ndx)
4162 const deUint32 multiplier = m_renderSize / 2;
4164 m_context.getTestContext().getLog()
4165 << tcu::TestLog::Message
4166 << "Point " << (ndx+1) << ":"
4167 << "\n\t" << outPoints[ndx].position << " == " << (float(multiplier) * outPoints[ndx].position) << "/" << multiplier
4168 << tcu::TestLog::EndMessage;
4172 bool ConservativePointTestInstance::compareAndVerify (std::vector<PointSceneSpec::ScenePoint>& points, tcu::Surface& resultImage, std::vector<tcu::Vec4>& drawBuffer)
4174 DE_UNREF(drawBuffer);
4176 switch (m_conservativeTestConfig.conservativeRasterizationMode)
4178 case VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT:
4180 return compareAndVerifyOverestimated(points, resultImage);
4182 case VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT:
4184 return compareAndVerifyUnderestimated(points, resultImage);
4188 TCU_THROW(InternalError, "Unknown conservative rasterization mode");
4192 bool ConservativePointTestInstance::compareAndVerifyOverestimated (std::vector<PointSceneSpec::ScenePoint>& points, tcu::Surface& resultImage)
4196 const char* iterationComments[] = { "Edges and corners", "Partial coverage", "Edges and corners" };
4197 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
4198 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
4199 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
4200 tcu::TestLog& log = m_context.getTestContext().getLog();
4203 deUint32 errValue = 0;
4206 log << tcu::TestLog::Message << "Points expected to be rasterized with white color" << tcu::TestLog::EndMessage;
4207 log << tcu::TestLog::Message << "Testing " << iterationComments[getIteration()] << tcu::TestLog::EndMessage;
4209 for (size_t renderAreaNdx = 0; result && renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
4211 const int renderStart = m_renderStart[renderAreaNdx];
4212 const int renderEnd = m_renderEnd[renderAreaNdx];
4214 for (int y = renderStart; result && y < renderEnd; ++y)
4215 for (int x = renderStart; result && x < renderEnd; ++x)
4217 if (resultImage.getPixel(x,y).getPacked() != foregroundColor.getPacked())
4222 errValue = resultImage.getPixel(x, y).getPacked();
4231 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
4232 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
4233 std::ostringstream css;
4235 for (int y = 0; y < resultImage.getHeight(); ++y)
4236 for (int x = 0; x < resultImage.getWidth(); ++x)
4237 referenceImage.setPixel(x, y, backgroundColor);
4239 for (size_t renderAreaNdx = 0; renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
4241 const int renderStart = m_renderStart[renderAreaNdx];
4242 const int renderEnd = m_renderEnd[renderAreaNdx];
4244 for (int y = renderStart; y < renderEnd; ++y)
4245 for (int x = renderStart; x < renderEnd; ++x)
4246 referenceImage.setPixel(x, y, foregroundColor);
4249 for (int y = 0; y < errorMask.getHeight(); ++y)
4250 for (int x = 0; x < errorMask.getWidth(); ++x)
4252 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
4253 errorMask.setPixel(x, y, unexpectedPixelColor);
4255 errorMask.setPixel(x, y, backgroundColor);
4259 for (size_t renderAreaNdx = 0; renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
4261 const int renderStart = m_renderStart[renderAreaNdx];
4262 const int renderEnd = m_renderEnd[renderAreaNdx];
4264 css << "[" << renderStart << "," << renderEnd << ") x [" << renderStart << "," << renderEnd << ")" << std::endl;
4267 log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
4268 << tcu::TestLog::EndMessage;
4269 log << tcu::TestLog::Message << "Expected area(s) to be filled:" << css.str()
4270 << tcu::TestLog::EndMessage;
4271 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
4272 << tcu::TestLog::Image("Result", "Result", resultImage)
4273 << tcu::TestLog::Image("Reference", "Reference", referenceImage)
4274 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
4275 << tcu::TestLog::EndImageSet;
4279 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
4280 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
4281 << tcu::TestLog::Image("Result", "Result", resultImage)
4282 << tcu::TestLog::EndImageSet;
4288 bool ConservativePointTestInstance::compareAndVerifyUnderestimated (std::vector<PointSceneSpec::ScenePoint>& points, tcu::Surface& resultImage)
4292 const char* iterationComments[] = { "Full coverage", "Full coverage with subpixel", "Exact coverage" };
4293 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
4294 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
4295 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
4296 tcu::TestLog& log = m_context.getTestContext().getLog();
4299 deUint32 errValue = 0;
4301 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
4303 log << tcu::TestLog::Message << "Points expected to be rasterized with white color" << tcu::TestLog::EndMessage;
4304 log << tcu::TestLog::Message << "Testing " << iterationComments[getIteration()] << tcu::TestLog::EndMessage;
4306 for (int y = 0; y < resultImage.getHeight(); ++y)
4307 for (int x = 0; x < resultImage.getWidth(); ++x)
4308 referenceImage.setPixel(x, y, backgroundColor);
4310 for (size_t renderAreaNdx = 0; result && renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
4312 const int renderStart = m_renderStart[renderAreaNdx];
4313 const int renderEnd = m_renderEnd[renderAreaNdx];
4315 for (int y = renderStart; y < renderEnd; ++y)
4316 for (int x = renderStart; x < renderEnd; ++x)
4317 referenceImage.setPixel(x, y, foregroundColor);
4320 for (int y = 0; result && y < resultImage.getHeight(); ++y)
4321 for (int x = 0; result && x < resultImage.getWidth(); ++x)
4323 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
4328 errValue = resultImage.getPixel(x, y).getPacked();
4336 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
4337 std::ostringstream css;
4339 for (int y = 0; y < errorMask.getHeight(); ++y)
4340 for (int x = 0; x < errorMask.getWidth(); ++x)
4342 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
4343 errorMask.setPixel(x, y, unexpectedPixelColor);
4345 errorMask.setPixel(x, y, backgroundColor);
4349 for (size_t renderAreaNdx = 0; renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
4351 const int renderStart = m_renderStart[renderAreaNdx];
4352 const int renderEnd = m_renderEnd[renderAreaNdx];
4354 css << "[" << renderStart << "," << renderEnd << ") x [" << renderStart << "," << renderEnd << ")" << std::endl;
4357 log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
4358 << tcu::TestLog::EndMessage;
4359 log << tcu::TestLog::Message << "Expected area(s) to be filled:" << css.str()
4360 << tcu::TestLog::EndMessage;
4361 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
4362 << tcu::TestLog::Image("Result", "Result", resultImage)
4363 << tcu::TestLog::Image("Reference", "Reference", referenceImage)
4364 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
4365 << tcu::TestLog::EndImageSet;
4369 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
4370 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
4371 << tcu::TestLog::Image("Result", "Result", resultImage)
4372 << tcu::TestLog::EndImageSet;
4378 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> ConservativePointTestInstance::initRasterizationConservativeStateCreateInfo (void)
4380 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
4381 std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> result;
4383 result.reserve(getIterationCount());
4385 for (int iteration = 0; iteration < getIterationCount(); ++iteration)
4387 const VkPipelineRasterizationConservativeStateCreateInfoEXT rasterizationConservativeStateCreateInfo =
4389 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
4390 DE_NULL, // const void* pNext;
4391 (VkPipelineRasterizationConservativeStateCreateFlagsEXT)0, // VkPipelineRasterizationConservativeStateCreateFlagsEXT flags;
4392 m_conservativeTestConfig.conservativeRasterizationMode, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
4393 extraOverestimationSize // float extraPrimitiveOverestimationSize;
4396 result.push_back(rasterizationConservativeStateCreateInfo);
4402 const std::vector<VkPipelineRasterizationStateCreateInfo> ConservativePointTestInstance::initRasterizationStateCreateInfo (void)
4404 std::vector<VkPipelineRasterizationStateCreateInfo> result;
4406 result.reserve(getIterationCount());
4408 for (int iteration = 0; iteration < getIterationCount(); ++iteration)
4410 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
4412 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
4413 &m_rasterizationConservativeStateCreateInfo[iteration], // const void* pNext;
4414 0, // VkPipelineRasterizationStateCreateFlags flags;
4415 false, // VkBool32 depthClampEnable;
4416 false, // VkBool32 rasterizerDiscardEnable;
4417 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
4418 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
4419 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
4420 VK_FALSE, // VkBool32 depthBiasEnable;
4421 0.0f, // float depthBiasConstantFactor;
4422 0.0f, // float depthBiasClamp;
4423 0.0f, // float depthBiasSlopeFactor;
4424 0.0f, // float lineWidth;
4427 result.push_back(rasterizationStateCreateInfo);
4433 const VkPipelineRasterizationStateCreateInfo* ConservativePointTestInstance::getRasterizationStateCreateInfo (void) const
4435 return &m_rasterizationStateCreateInfo[getIteration()];
4438 const VkPipelineRasterizationLineStateCreateInfoEXT* ConservativePointTestInstance::getLineRasterizationStateCreateInfo (void)
4444 template <typename ConcreteTestInstance>
4445 class WidenessTestCase : public BaseRenderingTestCase
4448 WidenessTestCase (tcu::TestContext& context,
4449 const std::string& name,
4450 const std::string& description,
4451 PrimitiveWideness wideness,
4452 PrimitiveStrictness strictness,
4454 VkSampleCountFlagBits sampleCount,
4455 LineStipple stipple,
4456 VkLineRasterizationModeEXT lineRasterizationMode,
4457 LineStippleFactorCase stippleFactor = LineStippleFactorCase::DEFAULT,
4458 deUint32 additionalRenderSize = 0)
4459 : BaseRenderingTestCase (context, name, description, sampleCount)
4460 , m_wideness (wideness)
4461 , m_strictness (strictness)
4462 , m_isLineTest (isLineTest)
4463 , m_stipple (stipple)
4464 , m_lineRasterizationMode (lineRasterizationMode)
4465 , m_stippleFactor (stippleFactor)
4466 , m_additionalRenderSize (additionalRenderSize)
4469 virtual TestInstance* createInstance (Context& context) const
4471 return new ConcreteTestInstance(context, m_wideness, m_strictness, m_sampleCount, m_stipple, m_lineRasterizationMode, m_stippleFactor, m_additionalRenderSize);
4474 virtual void checkSupport (Context& context) const
4478 if (m_wideness == PRIMITIVEWIDENESS_WIDE)
4479 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_WIDE_LINES);
4481 switch (m_lineRasterizationMode)
4484 TCU_THROW(InternalError, "Unknown line rasterization mode");
4486 case VK_LINE_RASTERIZATION_MODE_EXT_LAST:
4488 if (m_strictness == PRIMITIVESTRICTNESS_STRICT)
4489 if (!context.getDeviceProperties().limits.strictLines)
4490 TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
4492 if (m_strictness == PRIMITIVESTRICTNESS_NONSTRICT)
4493 if (context.getDeviceProperties().limits.strictLines)
4494 TCU_THROW(NotSupportedError, "Nonstrict rasterization is not supported");
4499 case VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT:
4501 if (!context.getDeviceProperties().limits.strictLines)
4502 TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
4504 if (getLineStippleEnable() &&
4505 !context.getLineRasterizationFeaturesEXT().stippledRectangularLines)
4506 TCU_THROW(NotSupportedError, "Stippled rectangular lines not supported");
4510 case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT:
4512 if (!context.getLineRasterizationFeaturesEXT().rectangularLines)
4513 TCU_THROW(NotSupportedError, "Rectangular lines not supported");
4515 if (getLineStippleEnable() &&
4516 !context.getLineRasterizationFeaturesEXT().stippledRectangularLines)
4517 TCU_THROW(NotSupportedError, "Stippled rectangular lines not supported");
4521 case VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT:
4523 if (!context.getLineRasterizationFeaturesEXT().bresenhamLines)
4524 TCU_THROW(NotSupportedError, "Bresenham lines not supported");
4526 if (getLineStippleEnable() &&
4527 !context.getLineRasterizationFeaturesEXT().stippledBresenhamLines)
4528 TCU_THROW(NotSupportedError, "Stippled Bresenham lines not supported");
4532 case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT:
4534 if (!context.getLineRasterizationFeaturesEXT().smoothLines)
4535 TCU_THROW(NotSupportedError, "Smooth lines not supported");
4537 if (getLineStippleEnable() &&
4538 !context.getLineRasterizationFeaturesEXT().stippledSmoothLines)
4539 TCU_THROW(NotSupportedError, "Stippled smooth lines not supported");
4546 if (m_wideness == PRIMITIVEWIDENESS_WIDE)
4547 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);
4551 bool getLineStippleEnable (void) const { return m_stipple != LINESTIPPLE_DISABLED; }
4552 virtual bool getLineStippleDynamic (void) const { return m_stipple == LINESTIPPLE_DYNAMIC; };
4555 const PrimitiveWideness m_wideness;
4556 const PrimitiveStrictness m_strictness;
4557 const bool m_isLineTest;
4558 const LineStipple m_stipple;
4559 const VkLineRasterizationModeEXT m_lineRasterizationMode;
4560 const LineStippleFactorCase m_stippleFactor;
4561 const deUint32 m_additionalRenderSize;
4564 class LinesTestInstance : public BaseLineTestInstance
4567 LinesTestInstance (Context& context, PrimitiveWideness wideness, PrimitiveStrictness strictness, VkSampleCountFlagBits sampleCount, LineStipple stipple, VkLineRasterizationModeEXT lineRasterizationMode, LineStippleFactorCase stippleFactor, deUint32 additionalRenderSize = 0)
4568 : BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, wideness, strictness, sampleCount, stipple, lineRasterizationMode, stippleFactor, additionalRenderSize)
4571 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
4574 void LinesTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
4581 // \note: these values are chosen arbitrarily
4582 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
4583 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
4584 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
4585 outData[3] = tcu::Vec4( -0.3f, 0.2f, 0.0f, 1.0f);
4586 outData[4] = tcu::Vec4( -1.5f, -0.4f, 0.0f, 1.0f);
4587 outData[5] = tcu::Vec4( 0.1f, 0.5f, 0.0f, 1.0f);
4588 outData[6] = tcu::Vec4( 0.75f, -0.4f, 0.0f, 1.0f);
4589 outData[7] = tcu::Vec4( 0.3f, 0.8f, 0.0f, 1.0f);
4593 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
4594 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
4595 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
4596 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
4597 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
4598 outData[5] = tcu::Vec4( 0.18f, -0.2f, 0.0f, 1.0f);
4599 outData[6] = tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f);
4600 outData[7] = tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f);
4604 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
4605 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
4606 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
4607 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
4608 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
4609 outData[5] = tcu::Vec4( 0.8f, -0.7f, 0.0f, 1.0f);
4610 outData[6] = tcu::Vec4( 0.9f, 0.7f, 0.0f, 1.0f);
4611 outData[7] = tcu::Vec4( -0.9f, 0.7f, 0.0f, 1.0f);
4616 outLines[0].positions[0] = outData[0];
4617 outLines[0].positions[1] = outData[1];
4618 outLines[1].positions[0] = outData[2];
4619 outLines[1].positions[1] = outData[3];
4620 outLines[2].positions[0] = outData[4];
4621 outLines[2].positions[1] = outData[5];
4622 outLines[3].positions[0] = outData[6];
4623 outLines[3].positions[1] = outData[7];
4626 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outLines.size() << " lines(s): (width = " << getLineWidth() << ")" << tcu::TestLog::EndMessage;
4627 for (int lineNdx = 0; lineNdx < (int)outLines.size(); ++lineNdx)
4629 m_context.getTestContext().getLog()
4630 << tcu::TestLog::Message
4631 << "Line " << (lineNdx+1) << ":"
4632 << "\n\t" << outLines[lineNdx].positions[0]
4633 << "\n\t" << outLines[lineNdx].positions[1]
4634 << tcu::TestLog::EndMessage;
4638 class LineStripTestInstance : public BaseLineTestInstance
4641 LineStripTestInstance (Context& context, PrimitiveWideness wideness, PrimitiveStrictness strictness, VkSampleCountFlagBits sampleCount, LineStipple stipple, VkLineRasterizationModeEXT lineRasterizationMode, LineStippleFactorCase stippleFactor, deUint32)
4642 : BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, wideness, strictness, sampleCount, stipple, lineRasterizationMode, stippleFactor)
4645 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
4648 void LineStripTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
4655 // \note: these values are chosen arbitrarily
4656 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
4657 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
4658 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
4659 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
4663 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
4664 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
4665 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
4666 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
4670 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
4671 outData[1] = tcu::Vec4( 0.9f, -0.9f, 0.0f, 1.0f);
4672 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
4673 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
4678 outLines[0].positions[0] = outData[0];
4679 outLines[0].positions[1] = outData[1];
4680 outLines[1].positions[0] = outData[1];
4681 outLines[1].positions[1] = outData[2];
4682 outLines[2].positions[0] = outData[2];
4683 outLines[2].positions[1] = outData[3];
4686 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering line strip, width = " << getLineWidth() << ", " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
4687 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
4689 m_context.getTestContext().getLog()
4690 << tcu::TestLog::Message
4691 << "\t" << outData[vtxNdx]
4692 << tcu::TestLog::EndMessage;
4696 class FillRuleTestInstance : public BaseRenderingTestInstance
4699 enum FillRuleCaseType
4701 FILLRULECASE_BASIC = 0,
4702 FILLRULECASE_REVERSED,
4703 FILLRULECASE_CLIPPED_FULL,
4704 FILLRULECASE_CLIPPED_PARTIAL,
4705 FILLRULECASE_PROJECTED,
4709 FillRuleTestInstance (Context& context, FillRuleCaseType type, VkSampleCountFlagBits sampleCount);
4710 virtual tcu::TestStatus iterate (void);
4714 virtual const VkPipelineColorBlendStateCreateInfo* getColorBlendStateCreateInfo (void) const;
4715 int getRenderSize (FillRuleCaseType type) const;
4716 int getNumIterations (FillRuleCaseType type) const;
4717 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const;
4719 const FillRuleCaseType m_caseType;
4721 const int m_iterationCount;
4722 bool m_allIterationsPassed;
4726 FillRuleTestInstance::FillRuleTestInstance (Context& context, FillRuleCaseType type, VkSampleCountFlagBits sampleCount)
4727 : BaseRenderingTestInstance (context, sampleCount, getRenderSize(type))
4730 , m_iterationCount (getNumIterations(type))
4731 , m_allIterationsPassed (true)
4733 DE_ASSERT(type < FILLRULECASE_LAST);
4736 tcu::TestStatus FillRuleTestInstance::iterate (void)
4738 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
4739 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
4740 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
4741 const int thresholdRed = 1 << (8 - colorBits[0]);
4742 const int thresholdGreen = 1 << (8 - colorBits[1]);
4743 const int thresholdBlue = 1 << (8 - colorBits[2]);
4744 tcu::Surface resultImage (m_renderSize, m_renderSize);
4745 std::vector<tcu::Vec4> drawBuffer;
4747 generateTriangles(m_iteration, drawBuffer);
4751 const std::vector<tcu::Vec4> colorBuffer (drawBuffer.size(), tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
4753 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Drawing gray triangles with shared edges.\nEnabling additive blending to detect overlapping fragments." << tcu::TestLog::EndMessage;
4755 drawPrimitives(resultImage, drawBuffer, colorBuffer, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
4758 // verify no overdraw
4760 const tcu::RGBA triangleColor = tcu::RGBA(127, 127, 127, 255);
4761 bool overdraw = false;
4763 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Verifying result." << tcu::TestLog::EndMessage;
4765 for (int y = 0; y < resultImage.getHeight(); ++y)
4766 for (int x = 0; x < resultImage.getWidth(); ++x)
4768 const tcu::RGBA color = resultImage.getPixel(x, y);
4770 // color values are greater than triangle color? Allow lower values for multisampled edges and background.
4771 if ((color.getRed() - triangleColor.getRed()) > thresholdRed ||
4772 (color.getGreen() - triangleColor.getGreen()) > thresholdGreen ||
4773 (color.getBlue() - triangleColor.getBlue()) > thresholdBlue)
4779 m_context.getTestContext().getLog() << tcu::TestLog::Message << "No overlapping fragments detected." << tcu::TestLog::EndMessage;
4782 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Overlapping fragments detected, image is not valid." << tcu::TestLog::EndMessage;
4783 m_allIterationsPassed = false;
4787 // verify no missing fragments in the full viewport case
4788 if (m_caseType == FILLRULECASE_CLIPPED_FULL)
4790 bool missingFragments = false;
4792 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Searching missing fragments." << tcu::TestLog::EndMessage;
4794 for (int y = 0; y < resultImage.getHeight(); ++y)
4795 for (int x = 0; x < resultImage.getWidth(); ++x)
4797 const tcu::RGBA color = resultImage.getPixel(x, y);
4799 // black? (background)
4800 if (color.getRed() <= thresholdRed ||
4801 color.getGreen() <= thresholdGreen ||
4802 color.getBlue() <= thresholdBlue)
4803 missingFragments = true;
4807 if (!missingFragments)
4808 m_context.getTestContext().getLog() << tcu::TestLog::Message << "No missing fragments detected." << tcu::TestLog::EndMessage;
4811 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Missing fragments detected, image is not valid." << tcu::TestLog::EndMessage;
4813 m_allIterationsPassed = false;
4817 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result of rendering", "Result of rendering")
4818 << tcu::TestLog::Image("Result", "Result", resultImage)
4819 << tcu::TestLog::EndImageSet;
4822 if (++m_iteration == m_iterationCount)
4824 if (m_allIterationsPassed)
4825 return tcu::TestStatus::pass("Pass");
4827 return tcu::TestStatus::fail("Found invalid pixels");
4830 return tcu::TestStatus::incomplete();
4833 int FillRuleTestInstance::getRenderSize (FillRuleCaseType type) const
4835 if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
4836 return RESOLUTION_POT / 4;
4838 return RESOLUTION_POT;
4841 int FillRuleTestInstance::getNumIterations (FillRuleCaseType type) const
4843 if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
4849 void FillRuleTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const
4853 case FILLRULECASE_BASIC:
4854 case FILLRULECASE_REVERSED:
4855 case FILLRULECASE_PROJECTED:
4857 const int numRows = 4;
4858 const int numColumns = 4;
4859 const float quadSide = 0.15f;
4860 de::Random rnd (0xabcd);
4862 outData.resize(6 * numRows * numColumns);
4864 for (int col = 0; col < numColumns; ++col)
4865 for (int row = 0; row < numRows; ++row)
4867 const tcu::Vec2 center = tcu::Vec2(((float)row + 0.5f) / (float)numRows * 2.0f - 1.0f, ((float)col + 0.5f) / (float)numColumns * 2.0f - 1.0f);
4868 const float rotation = (float)(iteration * numColumns * numRows + col * numRows + row) / (float)(m_iterationCount * numColumns * numRows) * DE_PI / 2.0f;
4869 const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
4870 const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x());
4871 const tcu::Vec2 quad[4] =
4873 center + sideH + sideV,
4874 center + sideH - sideV,
4875 center - sideH - sideV,
4876 center - sideH + sideV,
4879 if (m_caseType == FILLRULECASE_BASIC)
4881 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
4882 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
4883 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
4884 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
4885 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
4886 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
4888 else if (m_caseType == FILLRULECASE_REVERSED)
4890 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
4891 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
4892 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
4893 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
4894 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
4895 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
4897 else if (m_caseType == FILLRULECASE_PROJECTED)
4899 const float w0 = rnd.getFloat(0.1f, 4.0f);
4900 const float w1 = rnd.getFloat(0.1f, 4.0f);
4901 const float w2 = rnd.getFloat(0.1f, 4.0f);
4902 const float w3 = rnd.getFloat(0.1f, 4.0f);
4904 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
4905 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x() * w1, quad[1].y() * w1, 0.0f, w1);
4906 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
4907 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
4908 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
4909 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x() * w3, quad[3].y() * w3, 0.0f, w3);
4912 DE_ASSERT(DE_FALSE);
4918 case FILLRULECASE_CLIPPED_PARTIAL:
4919 case FILLRULECASE_CLIPPED_FULL:
4921 const float quadSide = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (1.0f) : (2.0f);
4922 const tcu::Vec2 center = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (tcu::Vec2(0.5f, 0.5f)) : (tcu::Vec2(0.0f, 0.0f));
4923 const float rotation = (float)(iteration) / (float)(m_iterationCount - 1) * DE_PI / 2.0f;
4924 const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
4925 const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x());
4926 const tcu::Vec2 quad[4] =
4928 center + sideH + sideV,
4929 center + sideH - sideV,
4930 center - sideH - sideV,
4931 center - sideH + sideV,
4935 outData[0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
4936 outData[1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
4937 outData[2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
4938 outData[3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
4939 outData[4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
4940 outData[5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
4945 DE_ASSERT(DE_FALSE);
4949 const VkPipelineColorBlendStateCreateInfo* FillRuleTestInstance::getColorBlendStateCreateInfo (void) const
4951 static const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
4953 true, // VkBool32 blendEnable;
4954 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
4955 VK_BLEND_FACTOR_ONE, // VkBlend destBlendColor;
4956 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
4957 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
4958 VK_BLEND_FACTOR_ONE, // VkBlend destBlendAlpha;
4959 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
4960 (VK_COLOR_COMPONENT_R_BIT |
4961 VK_COLOR_COMPONENT_G_BIT |
4962 VK_COLOR_COMPONENT_B_BIT |
4963 VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask;
4966 static const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
4968 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
4969 DE_NULL, // const void* pNext;
4970 0, // VkPipelineColorBlendStateCreateFlags flags;
4971 false, // VkBool32 logicOpEnable;
4972 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
4973 1u, // deUint32 attachmentCount;
4974 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
4975 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
4978 return &colorBlendStateParams;
4982 class FillRuleTestCase : public BaseRenderingTestCase
4985 FillRuleTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, FillRuleTestInstance::FillRuleCaseType type, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
4986 : BaseRenderingTestCase (context, name, description, sampleCount)
4990 virtual TestInstance* createInstance (Context& context) const
4992 return new FillRuleTestInstance(context, m_type, m_sampleCount);
4995 const FillRuleTestInstance::FillRuleCaseType m_type;
4998 class CullingTestInstance : public BaseRenderingTestInstance
5001 CullingTestInstance (Context& context, VkCullModeFlags cullMode, VkPrimitiveTopology primitiveTopology, VkFrontFace frontFace, VkPolygonMode polygonMode)
5002 : BaseRenderingTestInstance (context, VK_SAMPLE_COUNT_1_BIT, RESOLUTION_POT)
5003 , m_cullMode (cullMode)
5004 , m_primitiveTopology (primitiveTopology)
5005 , m_frontFace (frontFace)
5006 , m_polygonMode (polygonMode)
5007 , m_multisampling (true)
5010 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
5012 tcu::TestStatus iterate (void);
5015 void generateVertices (std::vector<tcu::Vec4>& outData) const;
5016 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const;
5017 void extractLines (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, std::vector<LineSceneSpec::SceneLine>& outLines) const;
5018 void extractPoints (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, std::vector<PointSceneSpec::ScenePoint>& outPoints) const;
5019 bool triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const;
5021 const VkCullModeFlags m_cullMode;
5022 const VkPrimitiveTopology m_primitiveTopology;
5023 const VkFrontFace m_frontFace;
5024 const VkPolygonMode m_polygonMode;
5025 const bool m_multisampling;
5029 tcu::TestStatus CullingTestInstance::iterate (void)
5031 DE_ASSERT(m_polygonMode <= VK_POLYGON_MODE_POINT);
5033 tcu::Surface resultImage (m_renderSize, m_renderSize);
5034 std::vector<tcu::Vec4> drawBuffer;
5035 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
5036 std::vector<PointSceneSpec::ScenePoint> points;
5037 std::vector<LineSceneSpec::SceneLine> lines;
5039 const InstanceInterface& vk = m_context.getInstanceInterface();
5040 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
5041 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(vk, physicalDevice);
5043 if (!(deviceFeatures.fillModeNonSolid) && (m_polygonMode == VK_POLYGON_MODE_LINE || m_polygonMode == VK_POLYGON_MODE_POINT))
5044 TCU_THROW(NotSupportedError, "Wireframe fill modes are not supported");
5047 generateVertices(drawBuffer);
5048 extractTriangles(triangles, drawBuffer);
5050 if (m_polygonMode == VK_POLYGON_MODE_LINE)
5051 extractLines(triangles ,lines);
5052 else if (m_polygonMode == VK_POLYGON_MODE_POINT)
5053 extractPoints(triangles, points);
5057 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Setting front face to " << m_frontFace << tcu::TestLog::EndMessage;
5058 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Setting cull face to " << m_cullMode << tcu::TestLog::EndMessage;
5059 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Drawing test pattern (" << m_primitiveTopology << ")" << tcu::TestLog::EndMessage;
5061 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
5066 RasterizationArguments args;
5067 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
5068 bool isCompareOk = false;
5070 args.numSamples = m_multisampling ? 1 : 0;
5071 args.subpixelBits = m_subpixelBits;
5072 args.redBits = colorBits[0];
5073 args.greenBits = colorBits[1];
5074 args.blueBits = colorBits[2];
5076 switch (m_polygonMode)
5078 case VK_POLYGON_MODE_LINE:
5080 LineSceneSpec scene;
5081 scene.lineWidth = 0;
5082 scene.lines.swap(lines);
5083 isCompareOk = verifyLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
5086 case VK_POLYGON_MODE_POINT:
5088 PointSceneSpec scene;
5089 scene.points.swap(points);
5090 isCompareOk = verifyPointGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
5095 TriangleSceneSpec scene;
5096 scene.triangles.swap(triangles);
5097 isCompareOk = verifyTriangleGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), tcu::VERIFICATIONMODE_WEAK);
5103 return tcu::TestStatus::pass("Pass");
5105 return tcu::TestStatus::fail("Incorrect rendering");
5109 void CullingTestInstance::generateVertices (std::vector<tcu::Vec4>& outData) const
5111 de::Random rnd(543210);
5114 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
5116 outData[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
5117 outData[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
5118 outData[vtxNdx].z() = 0.0f;
5119 outData[vtxNdx].w() = 1.0f;
5123 void CullingTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const
5125 const bool cullDirection = (m_cullMode == VK_CULL_MODE_FRONT_BIT) ^ (m_frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE);
5128 if (m_cullMode == VK_CULL_MODE_FRONT_AND_BACK)
5131 switch (m_primitiveTopology)
5133 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
5135 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
5137 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
5138 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
5139 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
5141 if (triangleOrder(v0, v1, v2) != cullDirection)
5143 TriangleSceneSpec::SceneTriangle tri;
5144 tri.positions[0] = v0; tri.sharedEdge[0] = false;
5145 tri.positions[1] = v1; tri.sharedEdge[1] = false;
5146 tri.positions[2] = v2; tri.sharedEdge[2] = false;
5148 outTriangles.push_back(tri);
5154 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
5156 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
5158 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
5159 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
5160 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
5162 if (triangleOrder(v0, v1, v2) != (cullDirection ^ (vtxNdx % 2 != 0)))
5164 TriangleSceneSpec::SceneTriangle tri;
5165 tri.positions[0] = v0; tri.sharedEdge[0] = false;
5166 tri.positions[1] = v1; tri.sharedEdge[1] = false;
5167 tri.positions[2] = v2; tri.sharedEdge[2] = false;
5169 outTriangles.push_back(tri);
5175 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
5177 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
5179 const tcu::Vec4& v0 = vertices[0];
5180 const tcu::Vec4& v1 = vertices[vtxNdx + 0];
5181 const tcu::Vec4& v2 = vertices[vtxNdx + 1];
5183 if (triangleOrder(v0, v1, v2) != cullDirection)
5185 TriangleSceneSpec::SceneTriangle tri;
5186 tri.positions[0] = v0; tri.sharedEdge[0] = false;
5187 tri.positions[1] = v1; tri.sharedEdge[1] = false;
5188 tri.positions[2] = v2; tri.sharedEdge[2] = false;
5190 outTriangles.push_back(tri);
5201 void CullingTestInstance::extractLines (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles,
5202 std::vector<LineSceneSpec::SceneLine>& outLines) const
5204 for (int triNdx = 0; triNdx < (int)outTriangles.size(); ++triNdx)
5206 for (int vrtxNdx = 0; vrtxNdx < 2; ++vrtxNdx)
5208 LineSceneSpec::SceneLine line;
5209 line.positions[0] = outTriangles.at(triNdx).positions[vrtxNdx];
5210 line.positions[1] = outTriangles.at(triNdx).positions[vrtxNdx + 1];
5212 outLines.push_back(line);
5214 LineSceneSpec::SceneLine line;
5215 line.positions[0] = outTriangles.at(triNdx).positions[2];
5216 line.positions[1] = outTriangles.at(triNdx).positions[0];
5217 outLines.push_back(line);
5221 void CullingTestInstance::extractPoints (std::vector<TriangleSceneSpec::SceneTriangle> &outTriangles,
5222 std::vector<PointSceneSpec::ScenePoint> &outPoints) const
5224 for (int triNdx = 0; triNdx < (int)outTriangles.size(); ++triNdx)
5226 for (int vrtxNdx = 0; vrtxNdx < 3; ++vrtxNdx)
5228 PointSceneSpec::ScenePoint point;
5229 point.position = outTriangles.at(triNdx).positions[vrtxNdx];
5230 point.pointSize = 1.0f;
5232 outPoints.push_back(point);
5237 bool CullingTestInstance::triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const
5239 const tcu::Vec2 s0 = v0.swizzle(0, 1) / v0.w();
5240 const tcu::Vec2 s1 = v1.swizzle(0, 1) / v1.w();
5241 const tcu::Vec2 s2 = v2.swizzle(0, 1) / v2.w();
5244 return ((s1.x() - s0.x()) * (s2.y() - s0.y()) - (s2.x() - s0.x()) * (s1.y() - s0.y())) > 0;
5248 const VkPipelineRasterizationStateCreateInfo* CullingTestInstance::getRasterizationStateCreateInfo (void) const
5250 static VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
5252 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
5253 DE_NULL, // const void* pNext;
5254 0, // VkPipelineRasterizationStateCreateFlags flags;
5255 false, // VkBool32 depthClipEnable;
5256 false, // VkBool32 rasterizerDiscardEnable;
5257 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
5258 VK_CULL_MODE_NONE, // VkCullMode cullMode;
5259 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
5260 VK_FALSE, // VkBool32 depthBiasEnable;
5261 0.0f, // float depthBias;
5262 0.0f, // float depthBiasClamp;
5263 0.0f, // float slopeScaledDepthBias;
5264 getLineWidth(), // float lineWidth;
5267 rasterizationStateCreateInfo.lineWidth = getLineWidth();
5268 rasterizationStateCreateInfo.cullMode = m_cullMode;
5269 rasterizationStateCreateInfo.frontFace = m_frontFace;
5270 rasterizationStateCreateInfo.polygonMode = m_polygonMode;
5272 return &rasterizationStateCreateInfo;
5275 class CullingTestCase : public BaseRenderingTestCase
5278 CullingTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkCullModeFlags cullMode, VkPrimitiveTopology primitiveTopology, VkFrontFace frontFace, VkPolygonMode polygonMode, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
5279 : BaseRenderingTestCase (context, name, description, sampleCount)
5280 , m_cullMode (cullMode)
5281 , m_primitiveTopology (primitiveTopology)
5282 , m_frontFace (frontFace)
5283 , m_polygonMode (polygonMode)
5286 virtual TestInstance* createInstance (Context& context) const
5288 return new CullingTestInstance(context, m_cullMode, m_primitiveTopology, m_frontFace, m_polygonMode);
5290 void checkSupport (Context& context) const;
5292 const VkCullModeFlags m_cullMode;
5293 const VkPrimitiveTopology m_primitiveTopology;
5294 const VkFrontFace m_frontFace;
5295 const VkPolygonMode m_polygonMode;
5298 void CullingTestCase::checkSupport (Context& context) const
5300 if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset"))
5302 const VkPhysicalDevicePortabilitySubsetFeaturesKHR& subsetFeatures = context.getPortabilitySubsetFeatures();
5303 if (m_polygonMode == VK_POLYGON_MODE_POINT && !subsetFeatures.pointPolygons)
5304 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Point polygons are not supported by this implementation");
5305 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN && !subsetFeatures.triangleFans)
5306 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
5310 class DiscardTestInstance : public BaseRenderingTestInstance
5313 DiscardTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, deBool queryFragmentShaderInvocations)
5314 : BaseRenderingTestInstance (context, VK_SAMPLE_COUNT_1_BIT, RESOLUTION_POT)
5315 , m_primitiveTopology (primitiveTopology)
5316 , m_queryFragmentShaderInvocations (queryFragmentShaderInvocations)
5319 virtual const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
5320 tcu::TestStatus iterate (void);
5323 void generateVertices (std::vector<tcu::Vec4>& outData) const;
5324 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const;
5325 void extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices) const;
5326 void extractPoints (std::vector<PointSceneSpec::ScenePoint>& outPoints, const std::vector<tcu::Vec4>& vertices) const;
5327 void drawPrimitivesDiscard (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, VkPrimitiveTopology primitiveTopology, Move<VkQueryPool>& queryPool);
5329 const VkPrimitiveTopology m_primitiveTopology;
5330 const deBool m_queryFragmentShaderInvocations;
5333 tcu::TestStatus DiscardTestInstance::iterate (void)
5335 const DeviceInterface& vkd = m_context.getDeviceInterface();
5336 const VkDevice vkDevice = m_context.getDevice();
5337 deUint64 queryResult = 0u;
5338 tcu::Surface resultImage (m_renderSize, m_renderSize);
5339 std::vector<tcu::Vec4> drawBuffer;
5340 std::vector<PointSceneSpec::ScenePoint> points;
5341 std::vector<LineSceneSpec::SceneLine> lines;
5342 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
5344 generateVertices(drawBuffer);
5346 switch (m_primitiveTopology)
5348 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
5349 extractPoints(points, drawBuffer);
5352 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
5353 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
5354 extractLines(lines, drawBuffer);
5357 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
5358 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
5359 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
5360 extractTriangles(triangles, drawBuffer);
5367 const VkQueryPoolCreateInfo queryPoolCreateInfo =
5369 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // VkStructureType sType
5370 DE_NULL, // const void* pNext
5371 (VkQueryPoolCreateFlags)0, // VkQueryPoolCreateFlags flags
5372 VK_QUERY_TYPE_PIPELINE_STATISTICS , // VkQueryType queryType
5373 1u, // deUint32 entryCount
5374 VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT, // VkQueryPipelineStatisticFlags pipelineStatistics
5377 if (m_queryFragmentShaderInvocations)
5379 Move<VkQueryPool> queryPool = createQueryPool(vkd, vkDevice, &queryPoolCreateInfo);
5381 drawPrimitivesDiscard(resultImage, drawBuffer, m_primitiveTopology, queryPool);
5382 vkd.getQueryPoolResults(vkDevice, *queryPool, 0u, 1u, sizeof(deUint64), &queryResult, 0u, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
5385 BaseRenderingTestInstance::drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
5389 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
5391 const RasterizationArguments args =
5393 0, // int numSamples;
5394 (int)m_subpixelBits, // int subpixelBits;
5395 colorBits[0], // int redBits;
5396 colorBits[1], // int greenBits;
5397 colorBits[2] // int blueBits;
5400 // Empty scene to compare to, primitives should be discarded before rasterization
5401 TriangleSceneSpec scene;
5403 const bool isCompareOk = verifyTriangleGroupRasterization(resultImage,
5406 m_context.getTestContext().getLog(),
5407 tcu::VERIFICATIONMODE_STRICT);
5411 if (m_queryFragmentShaderInvocations && queryResult > 0u)
5412 return tcu::TestStatus::fail("Fragment shader invocations occured");
5414 return tcu::TestStatus::pass("Pass");
5417 return tcu::TestStatus::fail("Incorrect rendering");
5421 void DiscardTestInstance::generateVertices (std::vector<tcu::Vec4>& outData) const
5423 de::Random rnd(12345);
5427 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
5429 outData[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
5430 outData[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
5431 outData[vtxNdx].z() = 0.0f;
5432 outData[vtxNdx].w() = 1.0f;
5436 void DiscardTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const
5438 switch (m_primitiveTopology)
5440 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
5442 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
5444 TriangleSceneSpec::SceneTriangle tri;
5445 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
5446 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
5447 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
5449 tri.positions[0] = v0;
5450 tri.positions[1] = v1;
5451 tri.positions[2] = v2;
5453 outTriangles.push_back(tri);
5459 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
5461 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
5463 TriangleSceneSpec::SceneTriangle tri;
5464 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
5465 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
5466 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
5468 tri.positions[0] = v0;
5469 tri.positions[1] = v1;
5470 tri.positions[2] = v2;
5472 outTriangles.push_back(tri);
5478 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
5480 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
5482 TriangleSceneSpec::SceneTriangle tri;
5483 const tcu::Vec4& v0 = vertices[0];
5484 const tcu::Vec4& v1 = vertices[vtxNdx + 0];
5485 const tcu::Vec4& v2 = vertices[vtxNdx + 1];
5487 tri.positions[0] = v0;
5488 tri.positions[1] = v1;
5489 tri.positions[2] = v2;
5491 outTriangles.push_back(tri);
5502 void DiscardTestInstance::extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices) const
5504 switch (m_primitiveTopology)
5506 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
5508 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; vtxNdx += 2)
5510 LineSceneSpec::SceneLine line;
5512 line.positions[0] = vertices[vtxNdx + 0];
5513 line.positions[1] = vertices[vtxNdx + 1];
5515 outLines.push_back(line);
5521 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
5523 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
5525 LineSceneSpec::SceneLine line;
5527 line.positions[0] = vertices[vtxNdx + 0];
5528 line.positions[1] = vertices[vtxNdx + 1];
5530 outLines.push_back(line);
5541 void DiscardTestInstance::extractPoints (std::vector<PointSceneSpec::ScenePoint>& outPoints, const std::vector<tcu::Vec4>& vertices) const
5543 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
5545 for (int vrtxNdx = 0; vrtxNdx < 3; ++vrtxNdx)
5547 PointSceneSpec::ScenePoint point;
5549 point.position = vertices[vrtxNdx];
5550 point.pointSize = 1.0f;
5552 outPoints.push_back(point);
5557 const VkPipelineRasterizationStateCreateInfo* DiscardTestInstance::getRasterizationStateCreateInfo (void) const
5559 static const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
5561 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
5562 NULL, // const void* pNext;
5563 0, // VkPipelineRasterizationStateCreateFlags flags;
5564 VK_FALSE, // VkBool32 depthClipEnable;
5565 VK_TRUE, // VkBool32 rasterizerDiscardEnable;
5566 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
5567 VK_CULL_MODE_NONE, // VkCullMode cullMode;
5568 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
5569 VK_FALSE, // VkBool32 depthBiasEnable;
5570 0.0f, // float depthBias;
5571 0.0f, // float depthBiasClamp;
5572 0.0f, // float slopeScaledDepthBias;
5573 getLineWidth(), // float lineWidth;
5576 return &rasterizationStateCreateInfo;
5579 void DiscardTestInstance::drawPrimitivesDiscard (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, VkPrimitiveTopology primitiveTopology, Move<VkQueryPool>& queryPool)
5581 const DeviceInterface& vkd = m_context.getDeviceInterface();
5582 const VkDevice vkDevice = m_context.getDevice();
5583 const VkPhysicalDeviceProperties properties = m_context.getDeviceProperties();
5584 const VkQueue queue = m_context.getUniversalQueue();
5585 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
5586 Allocator& allocator = m_context.getDefaultAllocator();
5588 const size_t attributeBatchSize = positionData.size() * sizeof(tcu::Vec4);
5589 const VkDeviceSize vertexBufferOffset = 0;
5590 de::MovePtr<Allocation> vertexBufferMemory;
5591 Move<VkBuffer> vertexBuffer;
5592 Move<VkCommandBuffer> commandBuffer;
5593 Move<VkPipeline> graphicsPipeline;
5595 if (attributeBatchSize > properties.limits.maxVertexInputAttributeOffset)
5597 std::stringstream message;
5598 message << "Larger vertex input attribute offset is needed (" << attributeBatchSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
5599 TCU_THROW(NotSupportedError, message.str().c_str());
5602 // Create Graphics Pipeline
5604 const VkVertexInputBindingDescription vertexInputBindingDescription =
5606 0u, // deUint32 binding;
5607 sizeof(tcu::Vec4), // deUint32 strideInBytes;
5608 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
5611 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
5614 0u, // deUint32 location;
5615 0u, // deUint32 binding;
5616 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
5617 0u // deUint32 offsetInBytes;
5620 1u, // deUint32 location;
5621 0u, // deUint32 binding;
5622 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
5623 (deUint32)attributeBatchSize // deUint32 offsetInBytes;
5627 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
5629 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
5630 DE_NULL, // const void* pNext;
5631 0, // VkPipelineVertexInputStateCreateFlags flags;
5632 1u, // deUint32 bindingCount;
5633 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
5634 2u, // deUint32 attributeCount;
5635 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
5638 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(m_renderSize)));
5639 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(m_renderSize)));
5641 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
5643 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
5644 DE_NULL, // const void* pNext;
5645 0u, // VkPipelineMultisampleStateCreateFlags flags;
5646 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
5647 VK_FALSE, // VkBool32 sampleShadingEnable;
5648 0.0f, // float minSampleShading;
5649 DE_NULL, // const VkSampleMask* pSampleMask;
5650 VK_FALSE, // VkBool32 alphaToCoverageEnable;
5651 VK_FALSE // VkBool32 alphaToOneEnable;
5654 graphicsPipeline = makeGraphicsPipeline(vkd, // const DeviceInterface& vk
5655 vkDevice, // const VkDevice device
5656 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
5657 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
5658 DE_NULL, // const VkShaderModule tessellationControlShaderModule
5659 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
5660 DE_NULL, // const VkShaderModule geometryShaderModule
5661 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
5662 *m_renderPass, // const VkRenderPass renderPass
5663 viewports, // const std::vector<VkViewport>& viewports
5664 scissors, // const std::vector<VkRect2D>& scissors
5665 primitiveTopology, // const VkPrimitiveTopology topology
5666 0u, // const deUint32 subpass
5667 0u, // const deUint32 patchControlPoints
5668 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
5669 getRasterizationStateCreateInfo(), // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
5670 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
5671 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo,
5672 getColorBlendStateCreateInfo()); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
5675 // Create Vertex Buffer
5677 const VkBufferCreateInfo vertexBufferParams =
5679 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
5680 DE_NULL, // const void* pNext;
5681 0u, // VkBufferCreateFlags flags;
5682 attributeBatchSize * 2, // VkDeviceSize size;
5683 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
5684 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
5685 1u, // deUint32 queueFamilyCount;
5686 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
5689 const std::vector<tcu::Vec4> colorData (positionData.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
5691 vertexBuffer = createBuffer(vkd, vkDevice, &vertexBufferParams);
5692 vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
5694 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
5696 // Load vertices into vertex buffer
5697 deMemcpy(vertexBufferMemory->getHostPtr(), positionData.data(), attributeBatchSize);
5698 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) + attributeBatchSize, colorData.data(), attributeBatchSize);
5699 flushAlloc(vkd, vkDevice, *vertexBufferMemory);
5702 // Create Command Buffer
5703 commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5705 // Begin Command Buffer
5706 beginCommandBuffer(vkd, *commandBuffer);
5708 addImageTransitionBarrier(*commandBuffer, // VkCommandBuffer commandBuffer
5709 *m_image, // VkImage image
5710 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
5711 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
5712 0, // VkAccessFlags srcAccessMask
5713 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
5714 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
5715 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
5717 if (m_multisampling)
5719 addImageTransitionBarrier(*commandBuffer, // VkCommandBuffer commandBuffer
5720 *m_resolvedImage, // VkImage image
5721 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
5722 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
5723 0, // VkAccessFlags srcAccessMask
5724 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
5725 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
5726 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
5730 vkd.cmdResetQueryPool(*commandBuffer, *queryPool, 0u, 1u);
5732 // Begin render pass and start query
5733 beginRenderPass(vkd, *commandBuffer, *m_renderPass, *m_frameBuffer, vk::makeRect2D(0, 0, m_renderSize, m_renderSize), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
5734 vkd.cmdBeginQuery(*commandBuffer, *queryPool, 0u, (VkQueryControlFlags)0u);
5735 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
5736 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL);
5737 vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
5738 vkd.cmdDraw(*commandBuffer, (deUint32)positionData.size(), 1, 0, 0);
5739 endRenderPass(vkd, *commandBuffer);
5740 vkd.cmdEndQuery(*commandBuffer, *queryPool, 0u);
5743 copyImageToBuffer(vkd, *commandBuffer, m_multisampling ? *m_resolvedImage : *m_image, *m_resultBuffer, tcu::IVec2(m_renderSize, m_renderSize));
5745 endCommandBuffer(vkd, *commandBuffer);
5749 float pointSize = getPointSize();
5751 deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize);
5752 flushAlloc(vkd, vkDevice, *m_uniformBufferMemory);
5756 submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());
5758 invalidateAlloc(vkd, vkDevice, *m_resultBufferMemory);
5759 tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderSize, m_renderSize, 1), m_resultBufferMemory->getHostPtr()));
5762 class DiscardTestCase : public BaseRenderingTestCase
5765 DiscardTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkPrimitiveTopology primitiveTopology, deBool queryFragmentShaderInvocations, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
5766 : BaseRenderingTestCase (context, name, description, sampleCount)
5767 , m_primitiveTopology (primitiveTopology)
5768 , m_queryFragmentShaderInvocations (queryFragmentShaderInvocations)
5771 virtual TestInstance* createInstance (Context& context) const
5773 return new DiscardTestInstance (context, m_primitiveTopology, m_queryFragmentShaderInvocations);
5776 virtual void checkSupport (Context& context) const
5778 if (m_queryFragmentShaderInvocations)
5779 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY);
5781 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN &&
5782 context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
5783 !context.getPortabilitySubsetFeatures().triangleFans)
5784 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
5788 const VkPrimitiveTopology m_primitiveTopology;
5789 const deBool m_queryFragmentShaderInvocations;
5792 class TriangleInterpolationTestInstance : public BaseRenderingTestInstance
5796 TriangleInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount)
5797 : BaseRenderingTestInstance (context, sampleCount, RESOLUTION_POT)
5798 , m_primitiveTopology (primitiveTopology)
5799 , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
5800 , m_iterationCount (3)
5802 , m_allIterationsPassed (true)
5803 , m_flatshade ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
5806 tcu::TestStatus iterate (void);
5810 void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
5811 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
5814 VkPrimitiveTopology m_primitiveTopology;
5815 const bool m_projective;
5816 const int m_iterationCount;
5818 bool m_allIterationsPassed;
5819 const deBool m_flatshade;
5822 tcu::TestStatus TriangleInterpolationTestInstance::iterate (void)
5824 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
5825 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
5826 tcu::Surface resultImage (m_renderSize, m_renderSize);
5827 std::vector<tcu::Vec4> drawBuffer;
5828 std::vector<tcu::Vec4> colorBuffer;
5829 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
5832 generateVertices(m_iteration, drawBuffer, colorBuffer);
5833 extractTriangles(triangles, drawBuffer, colorBuffer);
5837 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
5838 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
5839 m_context.getTestContext().getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
5843 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitiveTopology);
5847 RasterizationArguments args;
5848 TriangleSceneSpec scene;
5849 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
5851 args.numSamples = m_multisampling ? 1 : 0;
5852 args.subpixelBits = m_subpixelBits;
5853 args.redBits = colorBits[0];
5854 args.greenBits = colorBits[1];
5855 args.blueBits = colorBits[2];
5857 scene.triangles.swap(triangles);
5859 if (!verifyTriangleGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog()))
5860 m_allIterationsPassed = false;
5864 if (++m_iteration == m_iterationCount)
5866 if (m_allIterationsPassed)
5867 return tcu::TestStatus::pass("Pass");
5869 return tcu::TestStatus::fail("Found invalid pixel values");
5872 return tcu::TestStatus::incomplete();
5875 void TriangleInterpolationTestInstance::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
5877 // use only red, green and blue
5878 const tcu::Vec4 colors[] =
5880 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
5881 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
5882 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
5885 de::Random rnd(123 + iteration * 1000 + (int)m_primitiveTopology);
5887 outVertices.resize(6);
5888 outColors.resize(6);
5890 for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
5892 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
5893 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
5894 outVertices[vtxNdx].z() = 0.0f;
5897 outVertices[vtxNdx].w() = 1.0f;
5900 const float w = rnd.getFloat(0.2f, 4.0f);
5902 outVertices[vtxNdx].x() *= w;
5903 outVertices[vtxNdx].y() *= w;
5904 outVertices[vtxNdx].z() *= w;
5905 outVertices[vtxNdx].w() = w;
5908 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
5912 void TriangleInterpolationTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
5914 switch (m_primitiveTopology)
5916 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
5918 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
5920 TriangleSceneSpec::SceneTriangle tri;
5921 tri.positions[0] = vertices[vtxNdx + 0];
5922 tri.positions[1] = vertices[vtxNdx + 1];
5923 tri.positions[2] = vertices[vtxNdx + 2];
5924 tri.sharedEdge[0] = false;
5925 tri.sharedEdge[1] = false;
5926 tri.sharedEdge[2] = false;
5930 tri.colors[0] = colors[vtxNdx];
5931 tri.colors[1] = colors[vtxNdx];
5932 tri.colors[2] = colors[vtxNdx];
5936 tri.colors[0] = colors[vtxNdx + 0];
5937 tri.colors[1] = colors[vtxNdx + 1];
5938 tri.colors[2] = colors[vtxNdx + 2];
5941 outTriangles.push_back(tri);
5946 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
5948 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
5950 TriangleSceneSpec::SceneTriangle tri;
5951 tri.positions[0] = vertices[vtxNdx + 0];
5952 tri.positions[1] = vertices[vtxNdx + 1];
5953 tri.positions[2] = vertices[vtxNdx + 2];
5954 tri.sharedEdge[0] = false;
5955 tri.sharedEdge[1] = false;
5956 tri.sharedEdge[2] = false;
5960 tri.colors[0] = colors[vtxNdx];
5961 tri.colors[1] = colors[vtxNdx];
5962 tri.colors[2] = colors[vtxNdx];
5966 tri.colors[0] = colors[vtxNdx + 0];
5967 tri.colors[1] = colors[vtxNdx + 1];
5968 tri.colors[2] = colors[vtxNdx + 2];
5971 outTriangles.push_back(tri);
5976 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
5978 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
5980 TriangleSceneSpec::SceneTriangle tri;
5981 tri.positions[0] = vertices[0];
5982 tri.positions[1] = vertices[vtxNdx + 0];
5983 tri.positions[2] = vertices[vtxNdx + 1];
5984 tri.sharedEdge[0] = false;
5985 tri.sharedEdge[1] = false;
5986 tri.sharedEdge[2] = false;
5990 tri.colors[0] = colors[vtxNdx];
5991 tri.colors[1] = colors[vtxNdx];
5992 tri.colors[2] = colors[vtxNdx];
5996 tri.colors[0] = colors[0];
5997 tri.colors[1] = colors[vtxNdx + 0];
5998 tri.colors[2] = colors[vtxNdx + 1];
6001 outTriangles.push_back(tri);
6011 class TriangleInterpolationTestCase : public BaseRenderingTestCase
6014 TriangleInterpolationTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
6015 : BaseRenderingTestCase (context, name, description, sampleCount, (flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
6016 , m_primitiveTopology (primitiveTopology)
6020 virtual TestInstance* createInstance (Context& context) const
6022 return new TriangleInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_sampleCount);
6025 virtual void checkSupport (Context& context) const
6027 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN &&
6028 context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
6029 !context.getPortabilitySubsetFeatures().triangleFans)
6031 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
6035 const VkPrimitiveTopology m_primitiveTopology;
6039 class LineInterpolationTestInstance : public BaseRenderingTestInstance
6042 LineInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, PrimitiveStrictness strictness, VkSampleCountFlagBits sampleCount);
6044 virtual tcu::TestStatus iterate (void);
6047 void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
6048 void extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
6049 virtual float getLineWidth (void) const;
6051 VkPrimitiveTopology m_primitiveTopology;
6052 const bool m_projective;
6053 const int m_iterationCount;
6054 const PrimitiveWideness m_primitiveWideness;
6057 bool m_allIterationsPassed;
6058 float m_maxLineWidth;
6059 std::vector<float> m_lineWidths;
6061 PrimitiveStrictness m_strictness;
6064 LineInterpolationTestInstance::LineInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, PrimitiveStrictness strictness, VkSampleCountFlagBits sampleCount)
6065 : BaseRenderingTestInstance (context, sampleCount)
6066 , m_primitiveTopology (primitiveTopology)
6067 , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
6068 , m_iterationCount (3)
6069 , m_primitiveWideness (wideness)
6071 , m_allIterationsPassed (true)
6072 , m_maxLineWidth (1.0f)
6073 , m_flatshade ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
6074 , m_strictness (strictness)
6076 DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
6078 // create line widths
6079 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
6081 m_lineWidths.resize(m_iterationCount, 1.0f);
6083 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
6085 const float* range = context.getDeviceProperties().limits.lineWidthRange;
6087 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
6089 DE_ASSERT(range[1] > 1.0f);
6091 // set hand picked sizes
6092 m_lineWidths.push_back(5.0f);
6093 m_lineWidths.push_back(10.0f);
6094 m_lineWidths.push_back(range[1]);
6095 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
6097 m_maxLineWidth = range[1];
6103 tcu::TestStatus LineInterpolationTestInstance::iterate (void)
6105 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
6106 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
6107 const float lineWidth = getLineWidth();
6108 tcu::Surface resultImage (m_renderSize, m_renderSize);
6109 std::vector<tcu::Vec4> drawBuffer;
6110 std::vector<tcu::Vec4> colorBuffer;
6111 std::vector<LineSceneSpec::SceneLine> lines;
6114 if (lineWidth <= m_maxLineWidth)
6117 generateVertices(m_iteration, drawBuffer, colorBuffer);
6118 extractLines(lines, drawBuffer, colorBuffer);
6122 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
6123 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
6124 m_context.getTestContext().getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
6128 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitiveTopology);
6132 RasterizationArguments args;
6133 LineSceneSpec scene;
6135 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
6137 args.numSamples = m_multisampling ? 1 : 0;
6138 args.subpixelBits = m_subpixelBits;
6139 args.redBits = colorBits[0];
6140 args.greenBits = colorBits[1];
6141 args.blueBits = colorBits[2];
6143 scene.lines.swap(lines);
6144 scene.lineWidth = getLineWidth();
6146 switch (m_strictness)
6148 case PRIMITIVESTRICTNESS_STRICT:
6150 if (!verifyTriangulatedLineGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog(), true))
6151 m_allIterationsPassed = false;
6156 case PRIMITIVESTRICTNESS_NONSTRICT:
6157 case PRIMITIVESTRICTNESS_IGNORE:
6159 if (!verifyTriangulatedLineGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog(), false, true))
6160 m_allIterationsPassed = false;
6166 TCU_THROW(InternalError, "Not implemented");
6171 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
6174 if (++m_iteration == m_iterationCount)
6176 if (m_allIterationsPassed)
6177 return tcu::TestStatus::pass("Pass");
6179 return tcu::TestStatus::fail("Incorrect rasterization");
6182 return tcu::TestStatus::incomplete();
6185 void LineInterpolationTestInstance::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
6187 // use only red, green and blue
6188 const tcu::Vec4 colors[] =
6190 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
6191 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
6192 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
6195 de::Random rnd(123 + iteration * 1000 + (int)m_primitiveTopology);
6197 outVertices.resize(6);
6198 outColors.resize(6);
6200 for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
6202 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
6203 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
6204 outVertices[vtxNdx].z() = 0.0f;
6207 outVertices[vtxNdx].w() = 1.0f;
6210 const float w = rnd.getFloat(0.2f, 4.0f);
6212 outVertices[vtxNdx].x() *= w;
6213 outVertices[vtxNdx].y() *= w;
6214 outVertices[vtxNdx].z() *= w;
6215 outVertices[vtxNdx].w() = w;
6218 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
6222 void LineInterpolationTestInstance::extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
6224 switch (m_primitiveTopology)
6226 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
6228 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; vtxNdx += 2)
6230 LineSceneSpec::SceneLine line;
6231 line.positions[0] = vertices[vtxNdx + 0];
6232 line.positions[1] = vertices[vtxNdx + 1];
6236 line.colors[0] = colors[vtxNdx];
6237 line.colors[1] = colors[vtxNdx];
6241 line.colors[0] = colors[vtxNdx + 0];
6242 line.colors[1] = colors[vtxNdx + 1];
6245 outLines.push_back(line);
6250 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
6252 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
6254 LineSceneSpec::SceneLine line;
6255 line.positions[0] = vertices[vtxNdx + 0];
6256 line.positions[1] = vertices[vtxNdx + 1];
6260 line.colors[0] = colors[vtxNdx];
6261 line.colors[1] = colors[vtxNdx];
6265 line.colors[0] = colors[vtxNdx + 0];
6266 line.colors[1] = colors[vtxNdx + 1];
6269 outLines.push_back(line);
6279 float LineInterpolationTestInstance::getLineWidth (void) const
6281 return m_lineWidths[m_iteration];
6284 class LineInterpolationTestCase : public BaseRenderingTestCase
6287 LineInterpolationTestCase (tcu::TestContext& context,
6288 const std::string& name,
6289 const std::string& description,
6290 VkPrimitiveTopology primitiveTopology,
6292 PrimitiveWideness wideness,
6293 PrimitiveStrictness strictness,
6294 VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
6295 : BaseRenderingTestCase (context, name, description, sampleCount, (flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
6296 , m_primitiveTopology (primitiveTopology)
6298 , m_wideness (wideness)
6299 , m_strictness (strictness)
6302 virtual TestInstance* createInstance (Context& context) const
6304 return new LineInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_wideness, m_strictness, m_sampleCount);
6307 virtual void checkSupport (Context& context) const
6309 if (m_strictness == PRIMITIVESTRICTNESS_STRICT &&
6310 !context.getDeviceProperties().limits.strictLines)
6311 TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
6313 if (m_wideness == PRIMITIVEWIDENESS_WIDE)
6314 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_WIDE_LINES);
6317 const VkPrimitiveTopology m_primitiveTopology;
6319 const PrimitiveWideness m_wideness;
6320 const PrimitiveStrictness m_strictness;
6323 class StrideZeroCase : public vkt::TestCase
6328 std::vector<tcu::Vec2> bufferData;
6329 deUint32 drawVertexCount;
6332 StrideZeroCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const Params& params)
6333 : vkt::TestCase (testCtx, name, description)
6337 virtual ~StrideZeroCase (void) {}
6339 virtual void initPrograms (vk::SourceCollections& programCollection) const;
6340 virtual TestInstance* createInstance (Context& context) const;
6341 virtual void checkSupport (Context& context) const;
6343 static constexpr vk::VkFormat kColorFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
6344 static constexpr vk::VkFormatFeatureFlags kColorFeatures = (vk::VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | vk::VK_FORMAT_FEATURE_TRANSFER_SRC_BIT);
6345 static constexpr vk::VkImageUsageFlags kColorUsage = (vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
6350 // | a | b | a = (-0.5, -0.5)
6351 // | | | b = ( 0.5, -0.5)
6352 // +-----------+ c = (-0.5, 0.5)
6353 // | | | d = ( 0.5, 0.5)
6358 static constexpr deUint32 kImageDim = 2u;
6359 static const float kCornerDelta; // 0.5f;
6361 static const tcu::Vec4 kClearColor;
6362 static const tcu::Vec4 kDrawColor;
6368 const float StrideZeroCase::kCornerDelta = 0.5f;
6369 const tcu::Vec4 StrideZeroCase::kClearColor (0.0f, 0.0f, 0.0f, 1.0f);
6370 const tcu::Vec4 StrideZeroCase::kDrawColor (1.0f, 1.0f, 1.0f, 1.0f);
6372 class StrideZeroInstance : public vkt::TestInstance
6375 StrideZeroInstance (Context& context, const StrideZeroCase::Params& params)
6376 : vkt::TestInstance (context)
6380 virtual ~StrideZeroInstance (void) {}
6382 virtual tcu::TestStatus iterate (void);
6385 StrideZeroCase::Params m_params;
6388 void StrideZeroCase::initPrograms (vk::SourceCollections& programCollection) const
6390 std::ostringstream vert;
6391 std::ostringstream frag;
6393 std::ostringstream drawColor;
6395 << std::setprecision(2) << std::fixed
6396 << "vec4(" << kDrawColor.x() << ", " << kDrawColor.y() << ", " << kDrawColor.z() << ", " << kDrawColor.w() << ")";
6400 << "layout (location=0) in vec2 inPos;\n"
6401 << "void main() {\n"
6402 << " gl_Position = vec4(inPos, 0.0, 1.0);\n"
6403 << " gl_PointSize = 1.0;\n"
6409 << "layout (location=0) out vec4 outColor;\n"
6410 << "void main() {\n"
6411 << " outColor = " << drawColor.str() << ";\n"
6415 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
6416 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
6419 TestInstance* StrideZeroCase::createInstance (Context& context) const
6421 return new StrideZeroInstance(context, m_params);
6424 void StrideZeroCase::checkSupport (Context& context) const
6426 const auto properties = vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), kColorFormat);
6427 if ((properties.optimalTilingFeatures & kColorFeatures) != kColorFeatures)
6428 TCU_THROW(NotSupportedError, "Required image format not supported");
6431 // Creates a vertex buffer with the given data but uses zero as the binding stride.
6432 // Then, tries to draw the requested number of points. Only the first point should ever be used.
6433 tcu::TestStatus StrideZeroInstance::iterate (void)
6435 const auto& vkd = m_context.getDeviceInterface();
6436 const auto device = m_context.getDevice();
6437 auto& alloc = m_context.getDefaultAllocator();
6438 const auto queue = m_context.getUniversalQueue();
6439 const auto queueIndex = m_context.getUniversalQueueFamilyIndex();
6440 constexpr auto kImageDim = StrideZeroCase::kImageDim;
6441 const auto colorExtent = vk::makeExtent3D(kImageDim, kImageDim, 1u);
6443 // Prepare vertex buffer.
6444 const auto vertexBufferSize = static_cast<vk::VkDeviceSize>(m_params.bufferData.size() * sizeof(decltype(m_params.bufferData)::value_type));
6445 const auto vertexBufferInfo = vk::makeBufferCreateInfo(vertexBufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
6446 const vk::BufferWithMemory vertexBuffer( vkd, device, alloc, vertexBufferInfo, vk::MemoryRequirement::HostVisible);
6447 auto& vertexBufferAlloc = vertexBuffer.getAllocation();
6448 const vk::VkDeviceSize vertexBufferOffset = 0ull;
6449 deMemcpy(vertexBufferAlloc.getHostPtr(), m_params.bufferData.data(), static_cast<size_t>(vertexBufferSize));
6450 flushAlloc(vkd, device, vertexBufferAlloc);
6452 // Prepare render image.
6453 const vk::VkImageCreateInfo colorAttachmentInfo =
6455 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
6456 nullptr, // const void* pNext;
6457 0u, // VkImageCreateFlags flags;
6458 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType;
6459 StrideZeroCase::kColorFormat, // VkFormat format;
6460 colorExtent, // VkExtent3D extent;
6461 1u, // deUint32 mipLevels;
6462 1u, // deUint32 arrayLayers;
6463 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
6464 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
6465 StrideZeroCase::kColorUsage, // VkImageUsageFlags usage;
6466 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
6467 1u, // deUint32 queueFamilyIndexCount;
6468 &queueIndex, // const deUint32* pQueueFamilyIndices;
6469 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
6471 const vk::ImageWithMemory colorAttachment(vkd, device, alloc, colorAttachmentInfo, vk::MemoryRequirement::Any);
6473 const auto colorSubresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
6474 const auto colorAttachmentView = vk::makeImageView(vkd, device, colorAttachment.get(), vk::VK_IMAGE_VIEW_TYPE_2D, StrideZeroCase::kColorFormat, colorSubresourceRange);
6476 const vk::VkVertexInputBindingDescription vertexBinding =
6478 0u, // deUint32 binding;
6479 0u, // deUint32 stride; [IMPORTANT]
6480 vk::VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
6483 const vk::VkVertexInputAttributeDescription vertexAttribute =
6485 0u, // deUint32 location;
6486 0u, // deUint32 binding;
6487 vk::VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
6488 0u, // deUint32 offset;
6491 const vk::VkPipelineVertexInputStateCreateInfo vertexInput =
6493 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
6494 nullptr, // const void* pNext;
6495 0u, // VkPipelineVertexInputStateCreateFlags flags;
6496 1u, // deUint32 vertexBindingDescriptionCount;
6497 &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
6498 1u, // deUint32 vertexAttributeDescriptionCount;
6499 &vertexAttribute, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
6502 const auto renderArea = vk::makeRect2D(kImageDim, kImageDim);
6503 const auto viewports = std::vector<vk::VkViewport>(1, vk::makeViewport(kImageDim, kImageDim));
6504 const auto scissors = std::vector<vk::VkRect2D>(1, renderArea);
6505 const auto pipelineLayout = vk::makePipelineLayout(vkd, device);
6506 const auto vertexShader = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
6507 const auto fragmentShader = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
6508 const auto renderPass = vk::makeRenderPass(vkd, device, StrideZeroCase::kColorFormat);
6509 const auto graphicsPipeline = vk::makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
6510 vertexShader.get(), DE_NULL, DE_NULL, DE_NULL, fragmentShader.get(), // Shaders.
6511 renderPass.get(), viewports, scissors, vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0u, 0u, // Render pass, viewports, scissors, topology.
6512 &vertexInput); // Vertex input state.
6513 const auto framebuffer = vk::makeFramebuffer(vkd, device, renderPass.get(), colorAttachmentView.get(), kImageDim, kImageDim);
6515 const auto cmdPool = vk::makeCommandPool(vkd, device, queueIndex);
6516 const auto cmdBufferPtr = vk::allocateCommandBuffer(vkd, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6517 const auto cmdBuffer = cmdBufferPtr.get();
6519 // Buffer used to verify results.
6520 const auto tcuFormat = vk::mapVkFormat(StrideZeroCase::kColorFormat);
6521 const auto colorBufferSize = static_cast<vk::VkDeviceSize>(tcu::getPixelSize(tcuFormat)) * kImageDim * kImageDim;
6522 const auto colorBufferInfo = vk::makeBufferCreateInfo(colorBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT);
6523 const vk::BufferWithMemory colorBuffer (vkd, device, alloc, colorBufferInfo, vk::MemoryRequirement::HostVisible);
6524 auto& colorBufferAlloc = colorBuffer.getAllocation();
6525 void* colorBufferPtr = colorBufferAlloc.getHostPtr();
6526 const auto colorLayers = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
6527 const auto copyRegion = vk::makeBufferImageCopy(colorExtent, colorLayers);
6529 // Barriers from attachment to buffer and buffer to host.
6530 const auto colorAttachmentBarrier = vk::makeImageMemoryBarrier (vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, colorAttachment.get(), colorSubresourceRange);
6531 const auto colorBufferBarrier = vk::makeBufferMemoryBarrier (vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT, colorBuffer.get(), 0ull, colorBufferSize);
6533 vk::beginCommandBuffer(vkd, cmdBuffer);
6534 vk::beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), renderArea, StrideZeroCase::kClearColor);
6535 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
6536 vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
6537 vkd.cmdDraw(cmdBuffer, m_params.drawVertexCount, 1u, 0u, 0u);
6538 vk::endRenderPass(vkd, cmdBuffer);
6539 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &colorAttachmentBarrier);
6540 vkd.cmdCopyImageToBuffer(cmdBuffer, colorAttachment.get(), vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, colorBuffer.get(), 1u, ©Region);
6541 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &colorBufferBarrier, 0u, nullptr);
6542 vk::endCommandBuffer(vkd, cmdBuffer);
6544 vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
6546 // Invalidate color buffer alloc.
6547 vk::invalidateAlloc(vkd, device, colorBufferAlloc);
6550 const int imageDimI = static_cast<int>(kImageDim);
6551 const tcu::ConstPixelBufferAccess colorPixels (tcuFormat, imageDimI, imageDimI, 1, colorBufferPtr);
6552 tcu::TestStatus testStatus = tcu::TestStatus::pass("Pass");
6553 auto& log = m_context.getTestContext().getLog();
6555 for (int x = 0; x < imageDimI; ++x)
6556 for (int y = 0; y < imageDimI; ++y)
6558 // Only the top-left corner should have draw data.
6559 const auto expectedColor = ((x == 0 && y == 0) ? StrideZeroCase::kDrawColor : StrideZeroCase::kClearColor);
6560 const auto imageColor = colorPixels.getPixel(x, y);
6562 if (expectedColor != imageColor)
6565 << tcu::TestLog::Message
6566 << "Unexpected color found in pixel (" << x << ", " << y << "): "
6567 << "expected (" << expectedColor.x() << ", " << expectedColor.y() << ", " << expectedColor.z() << ", " << expectedColor.w() << ") "
6568 << "and found (" << imageColor.x() << ", " << imageColor.y() << ", " << imageColor.z() << ", " << imageColor.w() << ")"
6569 << tcu::TestLog::EndMessage;
6571 testStatus = tcu::TestStatus::fail("Failed; Check log for details");
6578 void createRasterizationTests (tcu::TestCaseGroup* rasterizationTests)
6580 tcu::TestContext& testCtx = rasterizationTests->getTestContext();
6584 LineStippleFactorCase stippleFactor;
6585 const std::string nameSuffix;
6586 const std::string descSuffix;
6587 } stippleFactorCases[] =
6589 { LineStippleFactorCase::DEFAULT, "", "" },
6590 { LineStippleFactorCase::ZERO, "_factor_0", " and use zero as the line stipple factor" },
6591 { LineStippleFactorCase::LARGE, "_factor_large", " and use a large number as the line stipple factor" },
6596 tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(testCtx, "primitives", "Primitive rasterization");
6598 rasterizationTests->addChild(primitives);
6600 tcu::TestCaseGroup* const nostippleTests = new tcu::TestCaseGroup(testCtx, "no_stipple", "No stipple");
6601 tcu::TestCaseGroup* const stippleStaticTests = new tcu::TestCaseGroup(testCtx, "static_stipple", "Line stipple static");
6602 tcu::TestCaseGroup* const stippleDynamicTests = new tcu::TestCaseGroup(testCtx, "dynamic_stipple", "Line stipple dynamic");
6603 tcu::TestCaseGroup* const strideZeroTests = new tcu::TestCaseGroup(testCtx, "stride_zero", "Test input assembly with stride zero");
6605 primitives->addChild(nostippleTests);
6606 primitives->addChild(stippleStaticTests);
6607 primitives->addChild(stippleDynamicTests);
6608 primitives->addChild(strideZeroTests);
6613 StrideZeroCase::Params params;
6614 params.bufferData.emplace_back(-StrideZeroCase::kCornerDelta, -StrideZeroCase::kCornerDelta);
6615 params.drawVertexCount = 1u;
6616 strideZeroTests->addChild(new StrideZeroCase(testCtx, "single_point", "Attempt to draw 1 point with stride 0", params));
6619 StrideZeroCase::Params params;
6620 params.bufferData.emplace_back(-StrideZeroCase::kCornerDelta, -StrideZeroCase::kCornerDelta);
6621 params.bufferData.emplace_back( StrideZeroCase::kCornerDelta, -StrideZeroCase::kCornerDelta);
6622 params.bufferData.emplace_back(-StrideZeroCase::kCornerDelta, StrideZeroCase::kCornerDelta);
6623 params.bufferData.emplace_back( StrideZeroCase::kCornerDelta, StrideZeroCase::kCornerDelta);
6624 params.drawVertexCount = static_cast<deUint32>(params.bufferData.size());
6625 strideZeroTests->addChild(new StrideZeroCase(testCtx, "four_points", "Attempt to draw 4 points with stride 0 and 4 points in the buffer", params));
6628 StrideZeroCase::Params params;
6629 params.bufferData.emplace_back(-StrideZeroCase::kCornerDelta, -StrideZeroCase::kCornerDelta);
6630 params.drawVertexCount = 100000u;
6631 strideZeroTests->addChild(new StrideZeroCase(testCtx, "many_points", "Attempt to draw many points with stride 0 with one point in the buffer", params));
6635 nostippleTests->addChild(new BaseTestCase<TrianglesTestInstance> (testCtx, "triangles", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result"));
6636 nostippleTests->addChild(new BaseTestCase<TriangleStripTestInstance> (testCtx, "triangle_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, verify rasterization result"));
6637 nostippleTests->addChild(new BaseTestCase<TriangleFanTestInstance> (testCtx, "triangle_fan", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, verify rasterization result"));
6638 nostippleTests->addChild(new WidenessTestCase<PointTestInstance> (testCtx, "points", "Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, false, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
6640 nostippleTests->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "strict_lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in strict mode, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
6641 nostippleTests->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "strict_line_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP in strict mode, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
6642 nostippleTests->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "strict_lines_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in strict mode with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_STRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
6643 nostippleTests->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "strict_line_strip_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP in strict mode with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_STRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
6645 nostippleTests->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "non_strict_lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in nonstrict mode, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_NONSTRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
6646 nostippleTests->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "non_strict_line_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP in nonstrict mode, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_NONSTRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
6647 nostippleTests->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "non_strict_lines_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in nonstrict mode with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_NONSTRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
6648 nostippleTests->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "non_strict_line_strip_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP in nonstrict mode with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_NONSTRICT, true, VK_SAMPLE_COUNT_1_BIT, LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
6650 for (int i = 0; i < 3; ++i) {
6652 tcu::TestCaseGroup *g = i == 2 ? stippleDynamicTests : i == 1 ? stippleStaticTests : nostippleTests;
6654 LineStipple stipple = (LineStipple)i;
6656 for (const auto& sfCase : stippleFactorCases)
6658 if (sfCase.stippleFactor != LineStippleFactorCase::DEFAULT && stipple != LINESTIPPLE_DISABLED)
6661 const auto& factor = sfCase.stippleFactor;
6662 const auto& suffix = sfCase.nameSuffix;
6663 const auto& descSuffix = sfCase.descSuffix;
6665 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, factor, i == 0 ? RESOLUTION_NPOT : 0));
6666 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "line_strip" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, factor));
6667 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines_wide" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, factor));
6668 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "line_strip_wide" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, factor));
6670 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "rectangular_lines" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, factor));
6671 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "rectangular_line_strip" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, factor));
6672 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "rectangular_lines_wide" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, factor));
6673 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "rectangular_line_strip_wide" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT, factor));
6675 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "bresenham_lines" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT, factor));
6676 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "bresenham_line_strip" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT, factor));
6677 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "bresenham_lines_wide" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT, factor));
6678 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "bresenham_line_strip_wide" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT, factor));
6680 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "smooth_lines" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, factor));
6681 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "smooth_line_strip" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, factor));
6682 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "smooth_lines_wide" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, factor));
6683 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "smooth_line_strip_wide" + suffix, "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result" + descSuffix, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT, factor));
6690 tcu::TestCaseGroup* const primitiveSize = new tcu::TestCaseGroup(testCtx, "primitive_size", "Primitive size");
6691 rasterizationTests->addChild(primitiveSize);
6695 tcu::TestCaseGroup* const points = new tcu::TestCaseGroup(testCtx, "points", "Point size");
6697 static const struct TestCombinations
6699 const deUint32 renderSize;
6700 const float pointSize;
6701 } testCombinations[] =
6713 for (size_t testCombNdx = 0; testCombNdx < DE_LENGTH_OF_ARRAY(testCombinations); testCombNdx++)
6715 std::string testCaseName = "point_size_" + de::toString(testCombinations[testCombNdx].pointSize);
6716 deUint32 renderSize = testCombinations[testCombNdx].renderSize;
6717 float pointSize = testCombinations[testCombNdx].pointSize;
6719 points->addChild(new PointSizeTestCase<PointSizeTestInstance> (testCtx, testCaseName, testCaseName, renderSize, pointSize));
6722 primitiveSize->addChild(points);
6728 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(testCtx, "fill_rules", "Primitive fill rules");
6730 rasterizationTests->addChild(fillRules);
6732 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_BASIC));
6733 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad_reverse", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_REVERSED));
6734 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_full", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_FULL));
6735 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_partly", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_PARTIAL));
6736 fillRules->addChild(new FillRuleTestCase(testCtx, "projected", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_PROJECTED));
6741 static const struct CullMode
6743 VkCullModeFlags mode;
6747 { VK_CULL_MODE_FRONT_BIT, "front_" },
6748 { VK_CULL_MODE_BACK_BIT, "back_" },
6749 { VK_CULL_MODE_FRONT_AND_BACK, "both_" },
6751 static const struct PrimitiveType
6753 VkPrimitiveTopology type;
6755 } primitiveTypes[] =
6757 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangles" },
6758 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, "triangle_strip" },
6759 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, "triangle_fan" },
6761 static const struct FrontFaceOrder
6764 const char* postfix;
6767 { VK_FRONT_FACE_COUNTER_CLOCKWISE, "" },
6768 { VK_FRONT_FACE_CLOCKWISE, "_reverse" },
6771 static const struct PolygonMode
6777 { VK_POLYGON_MODE_FILL, "" },
6778 { VK_POLYGON_MODE_LINE, "_line" },
6779 { VK_POLYGON_MODE_POINT, "_point" }
6782 tcu::TestCaseGroup* const culling = new tcu::TestCaseGroup(testCtx, "culling", "Culling");
6784 rasterizationTests->addChild(culling);
6786 for (int cullModeNdx = 0; cullModeNdx < DE_LENGTH_OF_ARRAY(cullModes); ++cullModeNdx)
6787 for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveNdx)
6788 for (int frontOrderNdx = 0; frontOrderNdx < DE_LENGTH_OF_ARRAY(frontOrders); ++frontOrderNdx)
6789 for (int polygonModeNdx = 0; polygonModeNdx < DE_LENGTH_OF_ARRAY(polygonModes); ++polygonModeNdx)
6791 if (!(cullModes[cullModeNdx].mode == VK_CULL_MODE_FRONT_AND_BACK && polygonModes[polygonModeNdx].mode != VK_POLYGON_MODE_FILL))
6793 const std::string name = std::string(cullModes[cullModeNdx].prefix) + primitiveTypes[primitiveNdx].name + frontOrders[frontOrderNdx].postfix + polygonModes[polygonModeNdx].name;
6794 culling->addChild(new CullingTestCase(testCtx, name, "Test primitive culling.", cullModes[cullModeNdx].mode, primitiveTypes[primitiveNdx].type, frontOrders[frontOrderNdx].mode, polygonModes[polygonModeNdx].mode));
6801 static const struct PrimitiveType
6803 VkPrimitiveTopology type;
6805 } primitiveTypes[] =
6807 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangle_list" },
6808 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, "triangle_strip" },
6809 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, "triangle_fan" },
6810 { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, "line_list" },
6811 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, "line_strip" },
6812 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, "point_list" }
6815 static const struct queryPipeline
6821 { DE_FALSE, "query_pipeline_false" },
6822 { DE_TRUE, "query_pipeline_true" },
6825 tcu::TestCaseGroup* const discard = new tcu::TestCaseGroup(testCtx, "discard", "Rasterizer discard");
6827 for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveNdx)
6829 tcu::TestCaseGroup* const primitive = new tcu::TestCaseGroup(testCtx, primitiveTypes[primitiveNdx].name, "Rasterizer discard");
6831 for (int useQueryNdx = 0; useQueryNdx < DE_LENGTH_OF_ARRAY(queryPipeline); useQueryNdx++)
6833 const std::string name = std::string(queryPipeline[useQueryNdx].name);
6835 primitive->addChild(new DiscardTestCase(testCtx, name, "Test primitive discarding.", primitiveTypes[primitiveNdx].type, queryPipeline[useQueryNdx].useQuery));
6838 discard->addChild(primitive);
6841 rasterizationTests->addChild(discard);
6850 } overestimateSizes;
6852 const overestimateSizes overestimateNormalSizes[] =
6861 { -TCU_INFINITY, "min" },
6862 { TCU_INFINITY, "max" },
6864 const overestimateSizes overestimateDegenerate[] =
6868 { -TCU_INFINITY, "min" },
6869 { TCU_INFINITY, "max" },
6871 const overestimateSizes underestimateLineWidths[] =
6877 const overestimateSizes underestimatePointSizes[] =
6886 const struct PrimitiveType
6888 VkPrimitiveTopology type;
6893 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangles" },
6894 { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, "lines" },
6895 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, "points" }
6897 const VkSampleCountFlagBits samples[] =
6899 VK_SAMPLE_COUNT_1_BIT,
6900 VK_SAMPLE_COUNT_2_BIT,
6901 VK_SAMPLE_COUNT_4_BIT,
6902 VK_SAMPLE_COUNT_8_BIT,
6903 VK_SAMPLE_COUNT_16_BIT,
6904 VK_SAMPLE_COUNT_32_BIT,
6905 VK_SAMPLE_COUNT_64_BIT
6908 tcu::TestCaseGroup* const conservative = new tcu::TestCaseGroup(testCtx, "conservative", "Conservative rasterization tests");
6910 rasterizationTests->addChild(conservative);
6913 tcu::TestCaseGroup* const overestimate = new tcu::TestCaseGroup(testCtx, "overestimate", "Overestimate tests");
6915 conservative->addChild(overestimate);
6917 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); ++samplesNdx)
6919 const std::string samplesGroupName = "samples_" + de::toString(samples[samplesNdx]);
6921 tcu::TestCaseGroup* const samplesGroup = new tcu::TestCaseGroup(testCtx, samplesGroupName.c_str(), "Samples tests");
6923 overestimate->addChild(samplesGroup);
6925 for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveTypeNdx)
6927 tcu::TestCaseGroup* const primitiveGroup = new tcu::TestCaseGroup(testCtx, primitiveTypes[primitiveTypeNdx].name, "Primitive tests");
6929 samplesGroup->addChild(primitiveGroup);
6932 tcu::TestCaseGroup* const normal = new tcu::TestCaseGroup(testCtx, "normal", "Normal conservative rasterization tests");
6934 primitiveGroup->addChild(normal);
6936 for (int overestimateSizesNdx = 0; overestimateSizesNdx < DE_LENGTH_OF_ARRAY(overestimateNormalSizes); ++overestimateSizesNdx)
6938 const ConservativeTestConfig config =
6940 VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
6941 overestimateNormalSizes[overestimateSizesNdx].size, // float extraOverestimationSize;
6942 primitiveTypes[primitiveTypeNdx].type, // VkPrimitiveTopology primitiveTopology;
6943 false, // bool degeneratePrimitives;
6944 1.0f, // float lineWidth;
6945 RESOLUTION_POT, // deUint32 resolution;
6948 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
6949 normal->addChild(new ConservativeTestCase<ConservativeTraingleTestInstance> (testCtx,
6950 overestimateNormalSizes[overestimateSizesNdx].name,
6951 "Overestimate test, verify rasterization result",
6953 samples[samplesNdx]));
6955 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_LINE_LIST)
6956 normal->addChild(new ConservativeTestCase<ConservativeLineTestInstance> (testCtx,
6957 overestimateNormalSizes[overestimateSizesNdx].name,
6958 "Overestimate test, verify rasterization result",
6960 samples[samplesNdx]));
6962 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
6963 normal->addChild(new ConservativeTestCase<ConservativePointTestInstance> (testCtx,
6964 overestimateNormalSizes[overestimateSizesNdx].name,
6965 "Overestimate test, verify rasterization result",
6967 samples[samplesNdx]));
6972 tcu::TestCaseGroup* const degenerate = new tcu::TestCaseGroup(testCtx, "degenerate", "Degenerate primitives conservative rasterization tests");
6974 primitiveGroup->addChild(degenerate);
6976 for (int overestimateSizesNdx = 0; overestimateSizesNdx < DE_LENGTH_OF_ARRAY(overestimateDegenerate); ++overestimateSizesNdx)
6978 const ConservativeTestConfig config =
6980 VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
6981 overestimateDegenerate[overestimateSizesNdx].size, // float extraOverestimationSize;
6982 primitiveTypes[primitiveTypeNdx].type, // VkPrimitiveTopology primitiveTopology;
6983 true, // bool degeneratePrimitives;
6984 1.0f, // float lineWidth;
6985 64u, // deUint32 resolution;
6988 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
6989 degenerate->addChild(new ConservativeTestCase<ConservativeTraingleTestInstance> (testCtx,
6990 overestimateDegenerate[overestimateSizesNdx].name,
6991 "Overestimate triangle test, verify rasterization result",
6993 samples[samplesNdx]));
6995 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_LINE_LIST)
6996 degenerate->addChild(new ConservativeTestCase<ConservativeLineTestInstance> (testCtx,
6997 overestimateDegenerate[overestimateSizesNdx].name,
6998 "Overestimate line test, verify rasterization result",
7000 samples[samplesNdx]));
7008 tcu::TestCaseGroup* const underestimate = new tcu::TestCaseGroup(testCtx, "underestimate", "Underestimate tests");
7010 conservative->addChild(underestimate);
7012 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); ++samplesNdx)
7014 const std::string samplesGroupName = "samples_" + de::toString(samples[samplesNdx]);
7016 tcu::TestCaseGroup* const samplesGroup = new tcu::TestCaseGroup(testCtx, samplesGroupName.c_str(), "Samples tests");
7018 underestimate->addChild(samplesGroup);
7020 for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveTypeNdx)
7022 tcu::TestCaseGroup* const primitiveGroup = new tcu::TestCaseGroup(testCtx, primitiveTypes[primitiveTypeNdx].name, "Primitive tests");
7024 samplesGroup->addChild(primitiveGroup);
7027 tcu::TestCaseGroup* const normal = new tcu::TestCaseGroup(testCtx, "normal", "Normal conservative rasterization tests");
7029 primitiveGroup->addChild(normal);
7031 ConservativeTestConfig config =
7033 VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
7034 0.0f, // float extraOverestimationSize;
7035 primitiveTypes[primitiveTypeNdx].type, // VkPrimitiveTopology primitiveTopology;
7036 false, // bool degeneratePrimitives;
7037 1.0f, // float lineWidth;
7038 64u, // deUint32 resolution;
7041 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
7042 normal->addChild(new ConservativeTestCase<ConservativeTraingleTestInstance> (testCtx,
7044 "Underestimate test, verify rasterization result",
7046 samples[samplesNdx]));
7048 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_LINE_LIST)
7050 for (int underestimateWidthNdx = 0; underestimateWidthNdx < DE_LENGTH_OF_ARRAY(underestimateLineWidths); ++underestimateWidthNdx)
7052 config.lineWidth = underestimateLineWidths[underestimateWidthNdx].size;
7053 normal->addChild(new ConservativeTestCase<ConservativeLineTestInstance> (testCtx,
7054 underestimateLineWidths[underestimateWidthNdx].name,
7055 "Underestimate test, verify rasterization result",
7057 samples[samplesNdx]));
7061 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
7063 for (int underestimatePointSizeNdx = 0; underestimatePointSizeNdx < DE_LENGTH_OF_ARRAY(underestimatePointSizes); ++underestimatePointSizeNdx)
7065 config.lineWidth = underestimatePointSizes[underestimatePointSizeNdx].size;
7066 normal->addChild(new ConservativeTestCase<ConservativePointTestInstance> (testCtx,
7067 underestimatePointSizes[underestimatePointSizeNdx].name,
7068 "Underestimate test, verify rasterization result",
7070 samples[samplesNdx]));
7076 tcu::TestCaseGroup* const degenerate = new tcu::TestCaseGroup(testCtx, "degenerate", "Degenerate primitives conservative rasterization tests");
7078 primitiveGroup->addChild(degenerate);
7080 ConservativeTestConfig config =
7082 VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
7083 0.0f, // float extraOverestimationSize;
7084 primitiveTypes[primitiveTypeNdx].type, // VkPrimitiveTopology primitiveTopology;
7085 true, // bool degeneratePrimitives;
7086 1.0f, // float lineWidth;
7087 64u, // deUint32 resolution;
7090 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
7091 degenerate->addChild(new ConservativeTestCase<ConservativeTraingleTestInstance> (testCtx,
7093 "Underestimate triangle test, verify rasterization result",
7095 samples[samplesNdx]));
7097 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_LINE_LIST)
7099 for (int underestimateWidthNdx = 0; underestimateWidthNdx < DE_LENGTH_OF_ARRAY(underestimateLineWidths); ++underestimateWidthNdx)
7101 config.lineWidth = underestimateLineWidths[underestimateWidthNdx].size;
7102 degenerate->addChild(new ConservativeTestCase<ConservativeLineTestInstance> (testCtx,
7103 underestimateLineWidths[underestimateWidthNdx].name,
7104 "Underestimate line test, verify rasterization result",
7106 samples[samplesNdx]));
7117 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(testCtx, "interpolation", "Test interpolation");
7119 rasterizationTests->addChild(interpolation);
7123 tcu::TestCaseGroup* const basic = new tcu::TestCaseGroup(testCtx, "basic", "Non-projective interpolation");
7125 interpolation->addChild(basic);
7127 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_NONE));
7128 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_NONE));
7129 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_NONE));
7130 basic->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE));
7131 basic->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE));
7132 basic->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE));
7133 basic->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE));
7135 basic->addChild(new LineInterpolationTestCase (testCtx, "strict_lines", "Verify strict line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT));
7136 basic->addChild(new LineInterpolationTestCase (testCtx, "strict_line_strip", "Verify strict line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT));
7137 basic->addChild(new LineInterpolationTestCase (testCtx, "strict_lines_wide", "Verify strict wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_STRICT));
7138 basic->addChild(new LineInterpolationTestCase (testCtx, "strict_line_strip_wide", "Verify strict wide line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_STRICT));
7140 basic->addChild(new LineInterpolationTestCase (testCtx, "non_strict_lines", "Verify non-strict line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_NONSTRICT));
7141 basic->addChild(new LineInterpolationTestCase (testCtx, "non_strict_line_strip", "Verify non-strict line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_NONSTRICT));
7142 basic->addChild(new LineInterpolationTestCase (testCtx, "non_strict_lines_wide", "Verify non-strict wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_NONSTRICT));
7143 basic->addChild(new LineInterpolationTestCase (testCtx, "non_strict_line_strip_wide", "Verify non-strict wide line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_NONSTRICT));
7148 tcu::TestCaseGroup* const projected = new tcu::TestCaseGroup(testCtx, "projected", "Projective interpolation");
7150 interpolation->addChild(projected);
7152 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_PROJECTED));
7153 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_PROJECTED));
7154 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_PROJECTED));
7155 projected->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE));
7156 projected->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE));
7157 projected->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE));
7158 projected->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE));
7160 projected->addChild(new LineInterpolationTestCase (testCtx, "strict_lines", "Verify strict line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT));
7161 projected->addChild(new LineInterpolationTestCase (testCtx, "strict_line_strip", "Verify strict line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT));
7162 projected->addChild(new LineInterpolationTestCase (testCtx, "strict_lines_wide", "Verify strict wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_STRICT));
7163 projected->addChild(new LineInterpolationTestCase (testCtx, "strict_line_strip_wide", "Verify strict wide line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_STRICT));
7165 projected->addChild(new LineInterpolationTestCase (testCtx, "non_strict_lines", "Verify non-strict line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_NONSTRICT));
7166 projected->addChild(new LineInterpolationTestCase (testCtx, "non_strict_line_strip", "Verify non-strict line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_NONSTRICT));
7167 projected->addChild(new LineInterpolationTestCase (testCtx, "non_strict_lines_wide", "Verify non-strict wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_NONSTRICT));
7168 projected->addChild(new LineInterpolationTestCase (testCtx, "non_strict_line_strip_wide", "Verify non-strict wide line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_NONSTRICT));
7174 tcu::TestCaseGroup* const flatshading = new tcu::TestCaseGroup(testCtx, "flatshading", "Test flatshading");
7176 rasterizationTests->addChild(flatshading);
7178 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_FLATSHADE));
7179 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_FLATSHADE));
7180 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_FLATSHADE));
7181 flatshading->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE));
7182 flatshading->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE));
7183 flatshading->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE));
7184 flatshading->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE));
7186 flatshading->addChild(new LineInterpolationTestCase (testCtx, "strict_lines", "Verify strict line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT));
7187 flatshading->addChild(new LineInterpolationTestCase (testCtx, "strict_line_strip", "Verify strict line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT));
7188 flatshading->addChild(new LineInterpolationTestCase (testCtx, "strict_lines_wide", "Verify strict wide line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_STRICT));
7189 flatshading->addChild(new LineInterpolationTestCase (testCtx, "strict_line_strip_wide", "Verify strict wide line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_STRICT));
7191 flatshading->addChild(new LineInterpolationTestCase (testCtx, "non_strict_lines", "Verify non-strict line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_NONSTRICT));
7192 flatshading->addChild(new LineInterpolationTestCase (testCtx, "non_strict_line_strip", "Verify non-strict line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_NONSTRICT));
7193 flatshading->addChild(new LineInterpolationTestCase (testCtx, "non_strict_lines_wide", "Verify non-strict wide line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_NONSTRICT));
7194 flatshading->addChild(new LineInterpolationTestCase (testCtx, "non_strict_line_strip_wide", "Verify non-strict wide line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_NONSTRICT));
7197 const VkSampleCountFlagBits samples[] =
7199 VK_SAMPLE_COUNT_2_BIT,
7200 VK_SAMPLE_COUNT_4_BIT,
7201 VK_SAMPLE_COUNT_8_BIT,
7202 VK_SAMPLE_COUNT_16_BIT,
7203 VK_SAMPLE_COUNT_32_BIT,
7204 VK_SAMPLE_COUNT_64_BIT
7207 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
7209 std::ostringstream caseName;
7211 caseName << "_multisample_" << (2 << samplesNdx) << "_bit";
7215 tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(testCtx, ("primitives" + caseName.str()).c_str(), "Primitive rasterization");
7217 rasterizationTests->addChild(primitives);
7219 tcu::TestCaseGroup* const nostippleTests = new tcu::TestCaseGroup(testCtx, "no_stipple", "No stipple");
7220 tcu::TestCaseGroup* const stippleStaticTests = new tcu::TestCaseGroup(testCtx, "static_stipple", "Line stipple static");
7221 tcu::TestCaseGroup* const stippleDynamicTests = new tcu::TestCaseGroup(testCtx, "dynamic_stipple", "Line stipple dynamic");
7223 primitives->addChild(nostippleTests);
7224 primitives->addChild(stippleStaticTests);
7225 primitives->addChild(stippleDynamicTests);
7227 nostippleTests->addChild(new BaseTestCase<TrianglesTestInstance> (testCtx, "triangles", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result", samples[samplesNdx]));
7228 nostippleTests->addChild(new WidenessTestCase<PointTestInstance> (testCtx, "points", "Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, false, samples[samplesNdx], LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
7230 nostippleTests->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "strict_lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in strict mode, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT, true, samples[samplesNdx], LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
7231 nostippleTests->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "strict_lines_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in strict mode with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_STRICT, true, samples[samplesNdx], LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
7233 nostippleTests->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "non_strict_lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in nonstrict mode, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_NONSTRICT, true, samples[samplesNdx], LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
7234 nostippleTests->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "non_strict_lines_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST in nonstrict mode with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_NONSTRICT, true, samples[samplesNdx], LINESTIPPLE_DISABLED, VK_LINE_RASTERIZATION_MODE_EXT_LAST));
7236 for (int i = 0; i < 3; ++i) {
7238 tcu::TestCaseGroup *g = i == 2 ? stippleDynamicTests : i == 1 ? stippleStaticTests : nostippleTests;
7240 LineStipple stipple = (LineStipple)i;
7242 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, LineStippleFactorCase::DEFAULT, i == 0 ? RESOLUTION_NPOT : 0));
7243 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "line_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
7244 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
7245 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "line_strip_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
7247 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "rectangular_lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT));
7248 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "rectangular_line_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT));
7249 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "rectangular_lines_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT));
7250 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "rectangular_line_strip_wide","Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT));
7252 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "bresenham_lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT));
7253 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "bresenham_line_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT));
7254 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "bresenham_lines_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT));
7255 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "bresenham_line_strip_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT));
7257 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "smooth_lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT));
7258 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "smooth_line_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT));
7259 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "smooth_lines_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT));
7260 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "smooth_line_strip_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, true, samples[samplesNdx], stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT));
7266 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(testCtx, ("fill_rules" + caseName.str()).c_str(), "Primitive fill rules");
7268 rasterizationTests->addChild(fillRules);
7270 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_BASIC, samples[samplesNdx]));
7271 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad_reverse", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_REVERSED, samples[samplesNdx]));
7272 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_full", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_FULL, samples[samplesNdx]));
7273 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_partly", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_PARTIAL, samples[samplesNdx]));
7274 fillRules->addChild(new FillRuleTestCase(testCtx, "projected", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_PROJECTED, samples[samplesNdx]));
7279 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(testCtx, ("interpolation" + caseName.str()).c_str(), "Test interpolation");
7281 rasterizationTests->addChild(interpolation);
7283 interpolation->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_NONE, samples[samplesNdx]));
7284 interpolation->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, samples[samplesNdx]));
7285 interpolation->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, samples[samplesNdx]));
7287 interpolation->addChild(new LineInterpolationTestCase (testCtx, "strict_lines", "Verify strict line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT, samples[samplesNdx]));
7288 interpolation->addChild(new LineInterpolationTestCase (testCtx, "strict_lines_wide", "Verify strict wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_STRICT, samples[samplesNdx]));
7290 interpolation->addChild(new LineInterpolationTestCase (testCtx, "non_strict_lines", "Verify non-strict line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_NONSTRICT, samples[samplesNdx]));
7291 interpolation->addChild(new LineInterpolationTestCase (testCtx, "non_strict_lines_wide", "Verify non-strict wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_NONSTRICT, samples[samplesNdx]));
7295 // .provoking_vertex
7297 rasterizationTests->addChild(createProvokingVertexTests(testCtx));
7302 tcu::TestCaseGroup* const lineContinuity = new tcu::TestCaseGroup(testCtx, "line_continuity", "Test line continuity");
7303 static const char dataDir[] = "rasterization/line_continuity";
7309 bool requireFillModeNonSolid;
7312 static const Case cases[] =
7314 { "line-strip", "Test line strip drawing produces continuous lines", false },
7315 { "polygon-mode-lines", "Test triangles drawn with lines are continuous", true }
7318 rasterizationTests->addChild(lineContinuity);
7320 for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
7322 const std::string fileName = cases[i].name + ".amber";
7323 cts_amber::AmberTestCase* testCase = cts_amber::createAmberTestCase(testCtx, cases[i].name.c_str(), cases[i].desc.c_str(), dataDir, fileName);
7325 if (cases[i].requireFillModeNonSolid)
7327 testCase->addRequirement("Features.fillModeNonSolid");
7330 lineContinuity->addChild(testCase);
7336 tcu::TestCaseGroup* const depthBias = new tcu::TestCaseGroup(testCtx, "depth_bias", "Test depth bias");
7337 static const char dataDir[] = "rasterization/depth_bias";
7342 vk::VkFormat format;
7343 std::string description;
7346 {"d16_unorm", vk::VK_FORMAT_D16_UNORM, "Test depth bias with format D16_UNORM"},
7347 {"d32_sfloat", vk::VK_FORMAT_D32_SFLOAT, "Test depth bias with format D32_SFLOAT"},
7348 {"d24_unorm", vk::VK_FORMAT_D24_UNORM_S8_UINT, "Test depth bias with format D24_UNORM_S8_UINT"}
7351 for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
7353 const VkImageCreateInfo vkImageCreateInfo = {
7354 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType
7357 VK_IMAGE_TYPE_2D, // imageType
7358 cases[i].format, // format
7359 {250, 250, 1}, // extent
7362 VK_SAMPLE_COUNT_1_BIT, // samples
7363 VK_IMAGE_TILING_OPTIMAL, // tiling
7364 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // usage
7365 VK_SHARING_MODE_EXCLUSIVE, // sharingMode
7366 0, // queueFamilyIndexCount
7367 nullptr, // pQueueFamilyIndices
7368 VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
7371 std::vector<std::string> requirements = std::vector<std::string>(0);
7372 std::vector<VkImageCreateInfo> imageRequirements;
7373 imageRequirements.push_back(vkImageCreateInfo);
7374 const std::string fileName = cases[i].name + ".amber";
7375 cts_amber::AmberTestCase* testCase = cts_amber::createAmberTestCase(testCtx, cases[i].name.c_str(), cases[i].description.c_str(), dataDir, fileName, requirements, imageRequirements);
7377 depthBias->addChild(testCase);
7380 rasterizationTests->addChild(depthBias);
7383 // Fragment shader side effects.
7385 rasterizationTests->addChild(createFragSideEffectsTests(testCtx));
7391 tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
7393 return createTestGroup(testCtx, "rasterization", "Rasterization Tests", createRasterizationTests);