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 PrimitiveStrictness
131 PRIMITIVESTRICTNESS_STRICT = 0,
132 PRIMITIVESTRICTNESS_NONSTRICT,
133 PRIMITIVESTRICTNESS_IGNORE,
135 PRIMITIVESTRICTNESS_LAST
139 class BaseRenderingTestCase : public TestCase
142 BaseRenderingTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deBool flatshade = DE_FALSE);
143 virtual ~BaseRenderingTestCase (void);
145 virtual void initPrograms (vk::SourceCollections& programCollection) const;
148 const VkSampleCountFlagBits m_sampleCount;
149 const deBool m_flatshade;
152 BaseRenderingTestCase::BaseRenderingTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount, deBool flatshade)
153 : TestCase(context, name, description)
154 , m_sampleCount (sampleCount)
155 , m_flatshade (flatshade)
159 void BaseRenderingTestCase::initPrograms (vk::SourceCollections& programCollection) const
161 tcu::StringTemplate vertexSource (s_shaderVertexTemplate);
162 tcu::StringTemplate fragmentSource (s_shaderFragmentTemplate);
163 std::map<std::string, std::string> params;
165 params["INTERPOLATION"] = (m_flatshade) ? ("flat ") : ("");
167 programCollection.glslSources.add("vertext_shader") << glu::VertexSource(vertexSource.specialize(params));
168 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fragmentSource.specialize(params));
171 BaseRenderingTestCase::~BaseRenderingTestCase (void)
175 class BaseRenderingTestInstance : public TestInstance
178 BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deUint32 renderSize = RESOLUTION_POT, VkFormat imageFormat = VK_FORMAT_R8G8B8A8_UNORM, deUint32 additionalRenderSize = 0);
179 ~BaseRenderingTestInstance (void);
182 void addImageTransitionBarrier (VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const;
183 virtual void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology);
184 void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, const std::vector<tcu::Vec4>& coloDrata, VkPrimitiveTopology primitiveTopology);
185 void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology,
186 VkImage image, VkImage resolvedImage, VkFramebuffer frameBuffer, const deUint32 renderSize, VkBuffer resultBuffer, const Allocation& resultBufferMemory);
187 virtual float getLineWidth (void) const;
188 virtual float getPointSize (void) const;
189 virtual bool getLineStippleDynamic (void) const { return false; };
192 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
195 VkPipelineRasterizationLineStateCreateInfoEXT initLineRasterizationStateCreateInfo (void) const;
198 const VkPipelineRasterizationLineStateCreateInfoEXT* getLineRasterizationStateCreateInfo (void);
201 const VkPipelineColorBlendStateCreateInfo* getColorBlendStateCreateInfo (void) const;
203 const tcu::TextureFormat& getTextureFormat (void) const;
205 const deUint32 m_renderSize;
206 const VkSampleCountFlagBits m_sampleCount;
207 deUint32 m_subpixelBits;
208 const deBool m_multisampling;
210 const VkFormat m_imageFormat;
211 const tcu::TextureFormat m_textureFormat;
212 Move<VkCommandPool> m_commandPool;
214 Move<VkImage> m_image;
215 de::MovePtr<Allocation> m_imageMemory;
216 Move<VkImageView> m_imageView;
218 Move<VkImage> m_resolvedImage;
219 de::MovePtr<Allocation> m_resolvedImageMemory;
220 Move<VkImageView> m_resolvedImageView;
222 Move<VkRenderPass> m_renderPass;
223 Move<VkFramebuffer> m_frameBuffer;
225 Move<VkDescriptorPool> m_descriptorPool;
226 Move<VkDescriptorSet> m_descriptorSet;
227 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
229 Move<VkBuffer> m_uniformBuffer;
230 de::MovePtr<Allocation> m_uniformBufferMemory;
231 const VkDeviceSize m_uniformBufferSize;
233 Move<VkPipelineLayout> m_pipelineLayout;
235 Move<VkShaderModule> m_vertexShaderModule;
236 Move<VkShaderModule> m_fragmentShaderModule;
238 Move<VkBuffer> m_resultBuffer;
239 de::MovePtr<Allocation> m_resultBufferMemory;
240 const VkDeviceSize m_resultBufferSize;
242 const deUint32 m_additionalRenderSize;
243 const VkDeviceSize m_additionalResultBufferSize;
245 VkPipelineRasterizationLineStateCreateInfoEXT m_lineRasterizationStateInfo;
248 virtual int getIteration (void) const { TCU_THROW(InternalError, "Iteration undefined in the base class"); }
251 BaseRenderingTestInstance::BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount, deUint32 renderSize, VkFormat imageFormat, deUint32 additionalRenderSize)
252 : TestInstance (context)
253 , m_renderSize (renderSize)
254 , m_sampleCount (sampleCount)
255 , m_subpixelBits (context.getDeviceProperties().limits.subPixelPrecisionBits)
256 , m_multisampling (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
257 , m_imageFormat (imageFormat)
258 , m_textureFormat (vk::mapVkFormat(m_imageFormat))
259 , m_uniformBufferSize (sizeof(float))
260 , m_resultBufferSize (renderSize * renderSize * m_textureFormat.getPixelSize())
261 , m_additionalRenderSize(additionalRenderSize)
262 , m_additionalResultBufferSize(additionalRenderSize * additionalRenderSize * m_textureFormat.getPixelSize())
263 , m_lineRasterizationStateInfo ()
265 const DeviceInterface& vkd = m_context.getDeviceInterface();
266 const VkDevice vkDevice = m_context.getDevice();
267 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
268 Allocator& allocator = m_context.getDefaultAllocator();
269 DescriptorPoolBuilder descriptorPoolBuilder;
270 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
273 m_commandPool = createCommandPool(vkd, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
277 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
278 VkImageFormatProperties properties;
280 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
283 VK_IMAGE_TILING_OPTIMAL,
286 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
288 TCU_THROW(NotSupportedError, "Format not supported");
291 if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
293 TCU_THROW(NotSupportedError, "Format not supported");
296 const VkImageCreateInfo imageCreateInfo =
298 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
299 DE_NULL, // const void* pNext;
300 0u, // VkImageCreateFlags flags;
301 VK_IMAGE_TYPE_2D, // VkImageType imageType;
302 m_imageFormat, // VkFormat format;
303 { m_renderSize, m_renderSize, 1u }, // VkExtent3D extent;
304 1u, // deUint32 mipLevels;
305 1u, // deUint32 arrayLayers;
306 m_sampleCount, // VkSampleCountFlagBits samples;
307 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
308 imageUsage, // VkImageUsageFlags usage;
309 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
310 1u, // deUint32 queueFamilyIndexCount;
311 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
312 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
315 m_image = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
317 m_imageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_image), MemoryRequirement::Any);
318 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_image, m_imageMemory->getMemory(), m_imageMemory->getOffset()));
323 const VkImageViewCreateInfo imageViewCreateInfo =
325 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
326 DE_NULL, // const void* pNext;
327 0u, // VkImageViewCreateFlags flags;
328 *m_image, // VkImage image;
329 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
330 m_imageFormat, // VkFormat format;
331 makeComponentMappingRGBA(), // VkComponentMapping components;
333 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
334 0u, // deUint32 baseMipLevel;
335 1u, // deUint32 mipLevels;
336 0u, // deUint32 baseArrayLayer;
337 1u, // deUint32 arraySize;
338 }, // VkImageSubresourceRange subresourceRange;
341 m_imageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
348 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
349 VkImageFormatProperties properties;
351 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
354 VK_IMAGE_TILING_OPTIMAL,
357 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
359 TCU_THROW(NotSupportedError, "Format not supported");
362 const VkImageCreateInfo imageCreateInfo =
364 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
365 DE_NULL, // const void* pNext;
366 0u, // VkImageCreateFlags flags;
367 VK_IMAGE_TYPE_2D, // VkImageType imageType;
368 m_imageFormat, // VkFormat format;
369 { m_renderSize, m_renderSize, 1u }, // VkExtent3D extent;
370 1u, // deUint32 mipLevels;
371 1u, // deUint32 arrayLayers;
372 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
373 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
374 imageUsage, // VkImageUsageFlags usage;
375 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
376 1u, // deUint32 queueFamilyIndexCount;
377 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
378 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
381 m_resolvedImage = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
382 m_resolvedImageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_resolvedImage), MemoryRequirement::Any);
383 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_resolvedImage, m_resolvedImageMemory->getMemory(), m_resolvedImageMemory->getOffset()));
386 // Resolved Image View
388 const VkImageViewCreateInfo imageViewCreateInfo =
390 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
391 DE_NULL, // const void* pNext;
392 0u, // VkImageViewCreateFlags flags;
393 *m_resolvedImage, // VkImage image;
394 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
395 m_imageFormat, // VkFormat format;
396 makeComponentMappingRGBA(), // VkComponentMapping components;
398 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
399 0u, // deUint32 baseMipLevel;
400 1u, // deUint32 mipLevels;
401 0u, // deUint32 baseArrayLayer;
402 1u, // deUint32 arraySize;
403 }, // VkImageSubresourceRange subresourceRange;
406 m_resolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
413 const VkImageLayout imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
414 const VkAttachmentDescription attachmentDesc[] =
417 0u, // VkAttachmentDescriptionFlags flags;
418 m_imageFormat, // VkFormat format;
419 m_sampleCount, // VkSampleCountFlagBits samples;
420 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
421 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
422 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
423 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
424 imageLayout, // VkImageLayout initialLayout;
425 imageLayout, // VkImageLayout finalLayout;
428 0u, // VkAttachmentDescriptionFlags flags;
429 m_imageFormat, // VkFormat format;
430 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
431 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
432 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
433 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
434 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
435 imageLayout, // VkImageLayout initialLayout;
436 imageLayout, // VkImageLayout finalLayout;
440 const VkAttachmentReference attachmentRef =
442 0u, // deUint32 attachment;
443 imageLayout, // VkImageLayout layout;
446 const VkAttachmentReference resolveAttachmentRef =
448 1u, // deUint32 attachment;
449 imageLayout, // VkImageLayout layout;
452 const VkSubpassDescription subpassDesc =
454 0u, // VkSubpassDescriptionFlags flags;
455 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
456 0u, // deUint32 inputAttachmentCount;
457 DE_NULL, // const VkAttachmentReference* pInputAttachments;
458 1u, // deUint32 colorAttachmentCount;
459 &attachmentRef, // const VkAttachmentReference* pColorAttachments;
460 m_multisampling ? &resolveAttachmentRef : DE_NULL, // const VkAttachmentReference* pResolveAttachments;
461 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
462 0u, // deUint32 preserveAttachmentCount;
463 DE_NULL, // const VkAttachmentReference* pPreserveAttachments;
466 const VkRenderPassCreateInfo renderPassCreateInfo =
468 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
469 DE_NULL, // const void* pNext;
470 0u, // VkRenderPassCreateFlags flags;
471 m_multisampling ? 2u : 1u, // deUint32 attachmentCount;
472 attachmentDesc, // const VkAttachmentDescription* pAttachments;
473 1u, // deUint32 subpassCount;
474 &subpassDesc, // const VkSubpassDescription* pSubpasses;
475 0u, // deUint32 dependencyCount;
476 DE_NULL, // const VkSubpassDependency* pDependencies;
479 m_renderPass = createRenderPass(vkd, vkDevice, &renderPassCreateInfo, DE_NULL);
484 const VkImageView attachments[] =
490 const VkFramebufferCreateInfo framebufferCreateInfo =
492 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
493 DE_NULL, // const void* pNext;
494 0u, // VkFramebufferCreateFlags flags;
495 *m_renderPass, // VkRenderPass renderPass;
496 m_multisampling ? 2u : 1u, // deUint32 attachmentCount;
497 attachments, // const VkImageView* pAttachments;
498 m_renderSize, // deUint32 width;
499 m_renderSize, // deUint32 height;
500 1u, // deUint32 layers;
503 m_frameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL);
508 const VkBufferCreateInfo bufferCreateInfo =
510 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
511 DE_NULL, // const void* pNext;
512 0u, // VkBufferCreateFlags flags;
513 m_uniformBufferSize, // VkDeviceSize size;
514 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage;
515 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
516 1u, // deUint32 queueFamilyIndexCount;
517 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
520 m_uniformBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo);
521 m_uniformBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_uniformBuffer), MemoryRequirement::HostVisible);
523 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_uniformBuffer, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset()));
528 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
529 m_descriptorPool = descriptorPoolBuilder.build(vkd, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
531 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_ALL);
532 m_descriptorSetLayout = descriptorSetLayoutBuilder.build(vkd, vkDevice);
534 const VkDescriptorSetAllocateInfo descriptorSetParams =
536 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
540 &m_descriptorSetLayout.get(),
543 m_descriptorSet = allocateDescriptorSet(vkd, vkDevice, &descriptorSetParams);
545 const VkDescriptorBufferInfo descriptorBufferInfo =
547 *m_uniformBuffer, // VkBuffer buffer;
548 0u, // VkDeviceSize offset;
549 VK_WHOLE_SIZE // VkDeviceSize range;
552 const VkWriteDescriptorSet writeDescritporSet =
554 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
555 DE_NULL, // const void* pNext;
556 *m_descriptorSet, // VkDescriptorSet destSet;
557 0, // deUint32 destBinding;
558 0, // deUint32 destArrayElement;
559 1u, // deUint32 count;
560 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType descriptorType;
561 DE_NULL, // const VkDescriptorImageInfo* pImageInfo;
562 &descriptorBufferInfo, // const VkDescriptorBufferInfo* pBufferInfo;
563 DE_NULL // const VkBufferView* pTexelBufferView;
566 vkd.updateDescriptorSets(vkDevice, 1u, &writeDescritporSet, 0u, DE_NULL);
571 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
573 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
574 DE_NULL, // const void* pNext;
575 0u, // VkPipelineLayoutCreateFlags flags;
576 1u, // deUint32 descriptorSetCount;
577 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
578 0u, // deUint32 pushConstantRangeCount;
579 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
582 m_pipelineLayout = createPipelineLayout(vkd, vkDevice, &pipelineLayoutCreateInfo);
587 m_vertexShaderModule = createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("vertext_shader"), 0);
588 m_fragmentShaderModule = createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("fragment_shader"), 0);
593 const VkBufferCreateInfo bufferCreateInfo =
595 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
596 DE_NULL, // const void* pNext;
597 0u, // VkBufferCreateFlags flags;
598 m_resultBufferSize, // VkDeviceSize size;
599 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
600 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
601 1u, // deUint32 queueFamilyIndexCount;
602 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
605 m_resultBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo);
606 m_resultBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_resultBuffer), MemoryRequirement::HostVisible);
608 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));
611 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Sample count = " << getSampleCountFlagsStr(m_sampleCount) << tcu::TestLog::EndMessage;
612 m_context.getTestContext().getLog() << tcu::TestLog::Message << "SUBPIXEL_BITS = " << m_subpixelBits << tcu::TestLog::EndMessage;
615 BaseRenderingTestInstance::~BaseRenderingTestInstance (void)
620 void BaseRenderingTestInstance::addImageTransitionBarrier(VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const
623 const DeviceInterface& vkd = m_context.getDeviceInterface();
625 const VkImageSubresourceRange subResourcerange =
627 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
628 0, // deUint32 baseMipLevel;
629 1, // deUint32 levelCount;
630 0, // deUint32 baseArrayLayer;
631 1 // deUint32 layerCount;
634 const VkImageMemoryBarrier imageBarrier =
636 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
637 DE_NULL, // const void* pNext;
638 srcAccessMask, // VkAccessFlags srcAccessMask;
639 dstAccessMask, // VkAccessFlags dstAccessMask;
640 oldLayout, // VkImageLayout oldLayout;
641 newLayout, // VkImageLayout newLayout;
642 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
643 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
644 image, // VkImage image;
645 subResourcerange // VkImageSubresourceRange subresourceRange;
648 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier);
651 void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology)
653 // default to color white
654 const std::vector<tcu::Vec4> colorData(vertexData.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
656 drawPrimitives(result, vertexData, colorData, primitiveTopology);
659 void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology)
661 drawPrimitives(result, positionData, colorData, primitiveTopology, *m_image, *m_resolvedImage, *m_frameBuffer, m_renderSize, *m_resultBuffer, *m_resultBufferMemory);
663 void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology,
664 VkImage image, VkImage resolvedImage, VkFramebuffer frameBuffer, const deUint32 renderSize, VkBuffer resultBuffer, const Allocation& resultBufferMemory)
666 const DeviceInterface& vkd = m_context.getDeviceInterface();
667 const VkDevice vkDevice = m_context.getDevice();
668 const VkQueue queue = m_context.getUniversalQueue();
669 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
670 Allocator& allocator = m_context.getDefaultAllocator();
671 const size_t attributeBatchSize = positionData.size() * sizeof(tcu::Vec4);
673 Move<VkCommandBuffer> commandBuffer;
674 Move<VkPipeline> graphicsPipeline;
675 Move<VkBuffer> vertexBuffer;
676 de::MovePtr<Allocation> vertexBufferMemory;
677 const VkPhysicalDeviceProperties properties = m_context.getDeviceProperties();
679 if (attributeBatchSize > properties.limits.maxVertexInputAttributeOffset)
681 std::stringstream message;
682 message << "Larger vertex input attribute offset is needed (" << attributeBatchSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
683 TCU_THROW(NotSupportedError, message.str().c_str());
686 // Create Graphics Pipeline
688 const VkVertexInputBindingDescription vertexInputBindingDescription =
690 0u, // deUint32 binding;
691 sizeof(tcu::Vec4), // deUint32 strideInBytes;
692 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
695 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
698 0u, // deUint32 location;
699 0u, // deUint32 binding;
700 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
701 0u // deUint32 offsetInBytes;
704 1u, // deUint32 location;
705 0u, // deUint32 binding;
706 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
707 (deUint32)attributeBatchSize // deUint32 offsetInBytes;
711 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
713 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
714 DE_NULL, // const void* pNext;
715 0, // VkPipelineVertexInputStateCreateFlags flags;
716 1u, // deUint32 bindingCount;
717 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
718 2u, // deUint32 attributeCount;
719 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
722 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(renderSize)));
723 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(renderSize)));
725 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
727 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
728 DE_NULL, // const void* pNext;
729 0u, // VkPipelineMultisampleStateCreateFlags flags;
730 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
731 VK_FALSE, // VkBool32 sampleShadingEnable;
732 0.0f, // float minSampleShading;
733 DE_NULL, // const VkSampleMask* pSampleMask;
734 VK_FALSE, // VkBool32 alphaToCoverageEnable;
735 VK_FALSE // VkBool32 alphaToOneEnable;
739 VkPipelineRasterizationStateCreateInfo rasterizationStateInfo = *getRasterizationStateCreateInfo();
741 const VkPipelineRasterizationLineStateCreateInfoEXT* lineRasterizationStateInfo = getLineRasterizationStateCreateInfo();
743 if (lineRasterizationStateInfo != DE_NULL)
744 appendStructurePtrToVulkanChain(&rasterizationStateInfo.pNext, lineRasterizationStateInfo);
746 VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
748 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType
749 DE_NULL, // const void* pNext
750 0u, // VkPipelineDynamicStateCreateFlags flags
751 0u, // deUint32 dynamicStateCount
752 DE_NULL // const VkDynamicState* pDynamicStates
755 VkDynamicState dynamicState = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
756 if (getLineStippleDynamic())
758 dynamicStateCreateInfo.dynamicStateCount = 1;
759 dynamicStateCreateInfo.pDynamicStates = &dynamicState;
762 graphicsPipeline = makeGraphicsPipeline(vkd, // const DeviceInterface& vk
763 vkDevice, // const VkDevice device
764 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
765 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
766 DE_NULL, // const VkShaderModule tessellationControlShaderModule
767 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
768 DE_NULL, // const VkShaderModule geometryShaderModule
769 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
770 *m_renderPass, // const VkRenderPass renderPass
771 viewports, // const std::vector<VkViewport>& viewports
772 scissors, // const std::vector<VkRect2D>& scissors
773 primitiveTopology, // const VkPrimitiveTopology topology
774 0u, // const deUint32 subpass
775 0u, // const deUint32 patchControlPoints
776 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
777 &rasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
778 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
779 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo,
780 getColorBlendStateCreateInfo(), // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo,
781 &dynamicStateCreateInfo); // const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo
784 // Create Vertex Buffer
786 const VkBufferCreateInfo vertexBufferParams =
788 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
789 DE_NULL, // const void* pNext;
790 0u, // VkBufferCreateFlags flags;
791 attributeBatchSize * 2, // VkDeviceSize size;
792 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
793 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
794 1u, // deUint32 queueFamilyCount;
795 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
798 vertexBuffer = createBuffer(vkd, vkDevice, &vertexBufferParams);
799 vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
801 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
803 // Load vertices into vertex buffer
804 deMemcpy(vertexBufferMemory->getHostPtr(), positionData.data(), attributeBatchSize);
805 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) + attributeBatchSize, colorData.data(), attributeBatchSize);
806 flushAlloc(vkd, vkDevice, *vertexBufferMemory);
809 // Create Command Buffer
810 commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
812 // Begin Command Buffer
813 beginCommandBuffer(vkd, *commandBuffer);
815 addImageTransitionBarrier(*commandBuffer, image,
816 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
817 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
818 0, // VkAccessFlags srcAccessMask
819 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
820 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
821 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
823 if (m_multisampling) {
824 addImageTransitionBarrier(*commandBuffer, resolvedImage,
825 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
826 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
827 0, // VkAccessFlags srcAccessMask
828 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
829 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
830 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
834 beginRenderPass(vkd, *commandBuffer, *m_renderPass, frameBuffer, vk::makeRect2D(0, 0, renderSize, renderSize), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
836 const VkDeviceSize vertexBufferOffset = 0;
838 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
839 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL);
840 vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
841 if (getLineStippleDynamic())
842 vkd.cmdSetLineStippleEXT(*commandBuffer, lineStippleFactor, lineStipplePattern);
843 vkd.cmdDraw(*commandBuffer, (deUint32)positionData.size(), 1, 0, 0);
844 endRenderPass(vkd, *commandBuffer);
847 copyImageToBuffer(vkd, *commandBuffer, m_multisampling ? resolvedImage : image, resultBuffer, tcu::IVec2(renderSize, renderSize));
849 endCommandBuffer(vkd, *commandBuffer);
853 float pointSize = getPointSize();
854 deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize);
855 flushAlloc(vkd, vkDevice, *m_uniformBufferMemory);
859 submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());
861 invalidateAlloc(vkd, vkDevice, resultBufferMemory);
862 tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(renderSize, renderSize, 1), resultBufferMemory.getHostPtr()));
865 float BaseRenderingTestInstance::getLineWidth (void) const
870 float BaseRenderingTestInstance::getPointSize (void) const
875 const VkPipelineRasterizationStateCreateInfo* BaseRenderingTestInstance::getRasterizationStateCreateInfo (void) const
877 static VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
879 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
880 DE_NULL, // const void* pNext;
881 0, // VkPipelineRasterizationStateCreateFlags flags;
882 false, // VkBool32 depthClipEnable;
883 false, // VkBool32 rasterizerDiscardEnable;
884 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
885 VK_CULL_MODE_NONE, // VkCullMode cullMode;
886 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
887 VK_FALSE, // VkBool32 depthBiasEnable;
888 0.0f, // float depthBias;
889 0.0f, // float depthBiasClamp;
890 0.0f, // float slopeScaledDepthBias;
891 getLineWidth(), // float lineWidth;
894 rasterizationStateCreateInfo.lineWidth = getLineWidth();
895 return &rasterizationStateCreateInfo;
898 VkPipelineRasterizationLineStateCreateInfoEXT BaseRenderingTestInstance::initLineRasterizationStateCreateInfo (void) const
900 VkPipelineRasterizationLineStateCreateInfoEXT lineRasterizationStateInfo =
902 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
903 DE_NULL, // const void* pNext;
904 VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, // VkLineRasterizationModeEXT lineRasterizationMode;
905 VK_FALSE, // VkBool32 stippledLineEnable;
906 1, // uint32_t lineStippleFactor;
907 0xFFFF, // uint16_t lineStipplePattern;
910 return lineRasterizationStateInfo;
913 const VkPipelineRasterizationLineStateCreateInfoEXT* BaseRenderingTestInstance::getLineRasterizationStateCreateInfo (void)
915 if (m_lineRasterizationStateInfo.sType != VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT)
916 m_lineRasterizationStateInfo = initLineRasterizationStateCreateInfo();
918 return &m_lineRasterizationStateInfo;
921 const VkPipelineColorBlendStateCreateInfo* BaseRenderingTestInstance::getColorBlendStateCreateInfo (void) const
923 static const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
925 false, // VkBool32 blendEnable;
926 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
927 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor;
928 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
929 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
930 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha;
931 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
932 (VK_COLOR_COMPONENT_R_BIT |
933 VK_COLOR_COMPONENT_G_BIT |
934 VK_COLOR_COMPONENT_B_BIT |
935 VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask;
938 static const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
940 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
941 DE_NULL, // const void* pNext;
942 0, // VkPipelineColorBlendStateCreateFlags flags;
943 false, // VkBool32 logicOpEnable;
944 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
945 1u, // deUint32 attachmentCount;
946 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
947 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
950 return &colorBlendStateParams;
953 const tcu::TextureFormat& BaseRenderingTestInstance::getTextureFormat (void) const
955 return m_textureFormat;
958 class BaseTriangleTestInstance : public BaseRenderingTestInstance
961 BaseTriangleTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, VkSampleCountFlagBits sampleCount, deUint32 renderSize = RESOLUTION_POT);
962 virtual tcu::TestStatus iterate (void);
965 int getIteration (void) const { return m_iteration; }
966 int getIterationCount (void) const { return m_iterationCount; }
969 virtual void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles) = DE_NULL;
970 virtual bool compareAndVerify (std::vector<TriangleSceneSpec::SceneTriangle>& triangles,
971 tcu::Surface& resultImage,
972 std::vector<tcu::Vec4>& drawBuffer);
975 const int m_iterationCount;
976 VkPrimitiveTopology m_primitiveTopology;
977 bool m_allIterationsPassed;
980 BaseTriangleTestInstance::BaseTriangleTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, VkSampleCountFlagBits sampleCount, deUint32 renderSize)
981 : BaseRenderingTestInstance (context, sampleCount, renderSize)
983 , m_iterationCount (3)
984 , m_primitiveTopology (primitiveTopology)
985 , m_allIterationsPassed (true)
989 tcu::TestStatus BaseTriangleTestInstance::iterate (void)
991 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
992 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
993 tcu::Surface resultImage (m_renderSize, m_renderSize);
994 std::vector<tcu::Vec4> drawBuffer;
995 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
997 generateTriangles(m_iteration, drawBuffer, triangles);
1000 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
1004 const bool compareOk = compareAndVerify(triangles, resultImage, drawBuffer);
1007 m_allIterationsPassed = false;
1011 if (++m_iteration == m_iterationCount)
1013 if (m_allIterationsPassed)
1014 return tcu::TestStatus::pass("Pass");
1016 return tcu::TestStatus::fail("Incorrect rasterization");
1019 return tcu::TestStatus::incomplete();
1022 bool BaseTriangleTestInstance::compareAndVerify (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage, std::vector<tcu::Vec4>&)
1024 RasterizationArguments args;
1025 TriangleSceneSpec scene;
1027 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1029 args.numSamples = m_multisampling ? 1 : 0;
1030 args.subpixelBits = m_subpixelBits;
1031 args.redBits = colorBits[0];
1032 args.greenBits = colorBits[1];
1033 args.blueBits = colorBits[2];
1035 scene.triangles.swap(triangles);
1037 return verifyTriangleGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
1040 class BaseLineTestInstance : public BaseRenderingTestInstance
1043 BaseLineTestInstance (Context& context,
1044 VkPrimitiveTopology primitiveTopology,
1045 PrimitiveWideness wideness,
1046 PrimitiveStrictness strictness,
1047 VkSampleCountFlagBits sampleCount,
1048 LineStipple stipple,
1049 VkLineRasterizationModeEXT lineRasterizationMode,
1050 const deUint32 additionalRenderSize = 0,
1051 const deUint32 renderSize = RESOLUTION_POT,
1052 const float narrowLineWidth = 1.0f);
1053 virtual tcu::TestStatus iterate (void);
1054 virtual float getLineWidth (void) const;
1055 bool getLineStippleEnable (void) const { return m_stipple != LINESTIPPLE_DISABLED; }
1056 virtual bool getLineStippleDynamic (void) const { return m_stipple == LINESTIPPLE_DYNAMIC; };
1059 VkPipelineRasterizationLineStateCreateInfoEXT initLineRasterizationStateCreateInfo (void) const;
1062 const VkPipelineRasterizationLineStateCreateInfoEXT* getLineRasterizationStateCreateInfo (void);
1065 int getIteration (void) const { return m_iteration; }
1066 int getIterationCount (void) const { return m_iterationCount; }
1069 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines) = DE_NULL;
1070 virtual bool compareAndVerify (std::vector<LineSceneSpec::SceneLine>& lines,
1071 tcu::Surface& resultImage,
1072 std::vector<tcu::Vec4>& drawBuffer);
1074 bool resultHasAlpha (tcu::Surface& result);
1077 const int m_iterationCount;
1078 VkPrimitiveTopology m_primitiveTopology;
1079 const PrimitiveWideness m_primitiveWideness;
1080 const PrimitiveStrictness m_primitiveStrictness;
1081 bool m_allIterationsPassed;
1082 bool m_qualityWarning;
1083 float m_maxLineWidth;
1084 std::vector<float> m_lineWidths;
1085 LineStipple m_stipple;
1086 VkLineRasterizationModeEXT m_lineRasterizationMode;
1087 Move<VkImage> m_additionalImage;
1088 de::MovePtr<Allocation> m_additionalImageMemory;
1089 Move<VkImageView> m_additionalImageView;
1090 Move<VkImage> m_additionalResolvedImage;
1091 de::MovePtr<Allocation> m_additionalResolvedImageMemory;
1092 Move<VkImageView> m_additionalResolvedImageView;
1093 Move<VkFramebuffer> m_additionalFrameBuffer;
1094 Move<VkBuffer> m_additionalResultBuffer;
1095 de::MovePtr<Allocation> m_additionalResultBufferMemory;
1098 BaseLineTestInstance::BaseLineTestInstance (Context& context,
1099 VkPrimitiveTopology primitiveTopology,
1100 PrimitiveWideness wideness,
1101 PrimitiveStrictness strictness,
1102 VkSampleCountFlagBits sampleCount,
1103 LineStipple stipple,
1104 VkLineRasterizationModeEXT lineRasterizationMode,
1105 const deUint32 additionalRenderSize,
1106 const deUint32 renderSize,
1107 const float narrowLineWidth)
1108 : BaseRenderingTestInstance (context, sampleCount, renderSize, VK_FORMAT_R8G8B8A8_UNORM, additionalRenderSize)
1110 , m_iterationCount (3)
1111 , m_primitiveTopology (primitiveTopology)
1112 , m_primitiveWideness (wideness)
1113 , m_primitiveStrictness (strictness)
1114 , m_allIterationsPassed (true)
1115 , m_qualityWarning (false)
1116 , m_maxLineWidth (1.0f)
1117 , m_stipple (stipple)
1118 , m_lineRasterizationMode (lineRasterizationMode)
1120 DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
1122 if (m_lineRasterizationMode != VK_LINE_RASTERIZATION_MODE_EXT_LAST)
1124 if (context.isDeviceFunctionalitySupported("VK_EXT_line_rasterization"))
1126 VkPhysicalDeviceLineRasterizationPropertiesEXT lineRasterizationProperties =
1128 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT, // VkStructureType sType;
1129 DE_NULL, // void* pNext;
1130 0u, // deUint32 lineSubPixelPrecisionBits;
1133 VkPhysicalDeviceProperties2 deviceProperties2;
1134 deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1135 deviceProperties2.pNext = &lineRasterizationProperties;
1137 context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &deviceProperties2);
1139 m_subpixelBits = lineRasterizationProperties.lineSubPixelPrecisionBits;
1143 // create line widths
1144 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
1146 m_lineWidths.resize(m_iterationCount, narrowLineWidth);
1148 // Bump up m_maxLineWidth for conservative rasterization
1149 if (narrowLineWidth > m_maxLineWidth)
1150 m_maxLineWidth = narrowLineWidth;
1152 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
1154 const float* range = context.getDeviceProperties().limits.lineWidthRange;
1156 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
1158 DE_ASSERT(range[1] > 1.0f);
1160 // set hand picked sizes
1161 m_lineWidths.push_back(5.0f);
1162 m_lineWidths.push_back(10.0f);
1164 // Do not pick line width with 0.5 fractional value as rounding direction is not defined.
1165 if (deFloatFrac(range[1]) == 0.5f)
1167 m_lineWidths.push_back(range[1] - context.getDeviceProperties().limits.lineWidthGranularity);
1171 m_lineWidths.push_back(range[1]);
1174 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
1176 m_maxLineWidth = range[1];
1181 // Create image, image view and frame buffer for testing at an additional resolution if required.
1182 if (m_additionalRenderSize != 0)
1184 const DeviceInterface& vkd = m_context.getDeviceInterface();
1185 const VkDevice vkDevice = m_context.getDevice();
1186 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1187 Allocator& allocator = m_context.getDefaultAllocator();
1188 DescriptorPoolBuilder descriptorPoolBuilder;
1189 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
1191 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1192 const VkImageCreateInfo imageCreateInfo =
1194 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1195 DE_NULL, // const void* pNext;
1196 0u, // VkImageCreateFlags flags;
1197 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1198 m_imageFormat, // VkFormat format;
1199 { m_additionalRenderSize, m_additionalRenderSize, 1u }, // VkExtent3D extent;
1200 1u, // deUint32 mipLevels;
1201 1u, // deUint32 arrayLayers;
1202 m_sampleCount, // VkSampleCountFlagBits samples;
1203 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1204 imageUsage, // VkImageUsageFlags usage;
1205 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1206 1u, // deUint32 queueFamilyIndexCount;
1207 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1208 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1211 m_additionalImage = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
1213 m_additionalImageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_additionalImage), MemoryRequirement::Any);
1214 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_additionalImage, m_additionalImageMemory->getMemory(), m_additionalImageMemory->getOffset()));
1219 const VkImageViewCreateInfo imageViewCreateInfo =
1221 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1222 DE_NULL, // const void* pNext;
1223 0u, // VkImageViewCreateFlags flags;
1224 *m_additionalImage, // VkImage image;
1225 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1226 m_imageFormat, // VkFormat format;
1227 makeComponentMappingRGBA(), // VkComponentMapping components;
1229 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1230 0u, // deUint32 baseMipLevel;
1231 1u, // deUint32 mipLevels;
1232 0u, // deUint32 baseArrayLayer;
1233 1u, // deUint32 arraySize;
1234 }, // VkImageSubresourceRange subresourceRange;
1237 m_additionalImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
1240 if (m_multisampling)
1243 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1244 const VkImageCreateInfo imageCreateInfo =
1246 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1247 DE_NULL, // const void* pNext;
1248 0u, // VkImageCreateFlags flags;
1249 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1250 m_imageFormat, // VkFormat format;
1251 { m_additionalRenderSize, m_additionalRenderSize, 1u }, // VkExtent3D extent;
1252 1u, // deUint32 mipLevels;
1253 1u, // deUint32 arrayLayers;
1254 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1255 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1256 imageUsage, // VkImageUsageFlags usage;
1257 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1258 1u, // deUint32 queueFamilyIndexCount;
1259 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1260 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1263 m_additionalResolvedImage = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
1264 m_additionalResolvedImageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_additionalResolvedImage), MemoryRequirement::Any);
1265 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_additionalResolvedImage, m_additionalResolvedImageMemory->getMemory(), m_additionalResolvedImageMemory->getOffset()));
1270 const VkImageViewCreateInfo imageViewCreateInfo =
1272 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1273 DE_NULL, // const void* pNext;
1274 0u, // VkImageViewCreateFlags flags;
1275 *m_additionalResolvedImage, // VkImage image;
1276 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
1277 m_imageFormat, // VkFormat format;
1278 makeComponentMappingRGBA(), // VkComponentMapping components;
1280 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1281 0u, // deUint32 baseMipLevel;
1282 1u, // deUint32 mipLevels;
1283 0u, // deUint32 baseArrayLayer;
1284 1u, // deUint32 arraySize;
1285 }, // VkImageSubresourceRange subresourceRange;
1287 m_additionalResolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
1292 const VkImageView attachments[] =
1294 *m_additionalImageView,
1295 *m_additionalResolvedImageView
1298 const VkFramebufferCreateInfo framebufferCreateInfo =
1300 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1301 DE_NULL, // const void* pNext;
1302 0u, // VkFramebufferCreateFlags flags;
1303 *m_renderPass, // VkRenderPass renderPass;
1304 m_multisampling ? 2u : 1u, // deUint32 attachmentCount;
1305 attachments, // const VkImageView* pAttachments;
1306 m_additionalRenderSize, // deUint32 width;
1307 m_additionalRenderSize, // deUint32 height;
1308 1u, // deUint32 layers;
1310 m_additionalFrameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL);
1315 const VkBufferCreateInfo bufferCreateInfo =
1317 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1318 DE_NULL, // const void* pNext;
1319 0u, // VkBufferCreateFlags flags;
1320 m_additionalResultBufferSize, // VkDeviceSize size;
1321 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1322 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1323 1u, // deUint32 queueFamilyIndexCount;
1324 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1327 m_additionalResultBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo);
1328 m_additionalResultBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_additionalResultBuffer), MemoryRequirement::HostVisible);
1330 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_additionalResultBuffer, m_additionalResultBufferMemory->getMemory(), m_additionalResultBufferMemory->getOffset()));
1335 bool BaseLineTestInstance::resultHasAlpha(tcu::Surface& resultImage)
1337 bool hasAlpha = false;
1338 for (int y = 0; y < resultImage.getHeight() && !hasAlpha; ++y)
1339 for (int x = 0; x < resultImage.getWidth(); ++x)
1341 const tcu::RGBA color = resultImage.getPixel(x, y);
1342 if (color.getAlpha() > 0 && color.getAlpha() < 0xFF)
1351 tcu::TestStatus BaseLineTestInstance::iterate (void)
1353 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1354 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1355 const float lineWidth = getLineWidth();
1356 tcu::Surface resultImage (m_renderSize, m_renderSize);
1357 std::vector<tcu::Vec4> drawBuffer;
1358 std::vector<LineSceneSpec::SceneLine> lines;
1361 if (lineWidth <= m_maxLineWidth)
1364 generateLines(m_iteration, drawBuffer, lines);
1367 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
1371 const bool compareOk = compareAndVerify(lines, resultImage, drawBuffer);
1374 m_allIterationsPassed = false;
1378 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
1381 if (++m_iteration == m_iterationCount)
1383 if (!m_allIterationsPassed)
1384 return tcu::TestStatus::fail("Incorrect rasterization");
1385 else if (m_qualityWarning)
1386 return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality line rasterization");
1388 return tcu::TestStatus::pass("Pass");
1391 return tcu::TestStatus::incomplete();
1394 bool BaseLineTestInstance::compareAndVerify (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage, std::vector<tcu::Vec4>& drawBuffer)
1396 const float lineWidth = getLineWidth();
1398 tcu::Surface additionalResultImage (m_additionalRenderSize, m_additionalRenderSize);
1399 RasterizationArguments args;
1400 LineSceneSpec scene;
1401 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1402 bool strict = m_primitiveStrictness == PRIMITIVESTRICTNESS_STRICT;
1404 args.numSamples = m_multisampling ? 1 : 0;
1405 args.subpixelBits = m_subpixelBits;
1406 args.redBits = colorBits[0];
1407 args.greenBits = colorBits[1];
1408 args.blueBits = colorBits[2];
1410 scene.lines.swap(lines);
1411 scene.lineWidth = lineWidth;
1412 scene.stippleEnable = getLineStippleEnable();
1413 scene.stippleFactor = getLineStippleEnable() ? lineStippleFactor : 1;
1414 scene.stipplePattern = getLineStippleEnable() ? lineStipplePattern : 0xFFFF;
1415 scene.isStrip = m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
1416 scene.isSmooth = m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
1418 // Choose verification mode. Smooth lines assume mostly over-rasterization (bloated lines with a falloff).
1419 // Stippled lines lose some precision across segments in a strip, so need a weaker threshold than normal
1420 // lines. For simple cases, check for an exact match (STRICT).
1422 scene.verificationMode = tcu::VERIFICATIONMODE_SMOOTH;
1423 else if (scene.stippleEnable)
1424 scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
1426 scene.verificationMode = tcu::VERIFICATIONMODE_STRICT;
1428 if (m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT)
1430 // bresenham is "no AA" in GL, so set numSamples to zero.
1431 args.numSamples = 0;
1432 if (!verifyLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog()))
1439 // Smooth lines get the fractional coverage multiplied into the alpha component,
1440 // so do a sanity check to validate that there is at least one pixel in the image
1441 // with a fractional opacity.
1442 bool hasAlpha = resultHasAlpha(resultImage);
1445 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Missing alpha transparency (failed)." << tcu::TestLog::EndMessage;
1450 if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), (0 == m_multisampling), strict))
1452 // Retry with weaker verification. If it passes, consider it a quality warning.
1453 scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
1454 if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), false, strict))
1457 m_qualityWarning = true;
1460 if (m_additionalRenderSize != 0)
1462 const std::vector<tcu::Vec4> colorData(drawBuffer.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
1465 scene.verificationMode = tcu::VERIFICATIONMODE_SMOOTH;
1466 else if (scene.stippleEnable)
1467 scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
1469 scene.verificationMode = tcu::VERIFICATIONMODE_STRICT;
1471 drawPrimitives(additionalResultImage, drawBuffer, colorData, m_primitiveTopology, *m_additionalImage, *m_additionalResolvedImage, *m_additionalFrameBuffer, m_additionalRenderSize, *m_additionalResultBuffer, *m_additionalResultBufferMemory);
1474 if (!verifyRelaxedLineGroupRasterization(additionalResultImage, scene, args, m_context.getTestContext().getLog(), (0 == m_multisampling), strict))
1482 // Retry with weaker verification. If it passes, consider it a quality warning.
1483 scene.verificationMode = tcu::VERIFICATIONMODE_WEAKER;
1484 if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), (0 == m_multisampling), strict))
1487 m_qualityWarning = true;
1496 float BaseLineTestInstance::getLineWidth (void) const
1498 return m_lineWidths[m_iteration];
1501 VkPipelineRasterizationLineStateCreateInfoEXT BaseLineTestInstance::initLineRasterizationStateCreateInfo (void) const
1503 VkPipelineRasterizationLineStateCreateInfoEXT lineRasterizationStateInfo =
1505 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
1506 DE_NULL, // const void* pNext;
1507 m_lineRasterizationMode, // VkLineRasterizationModeEXT lineRasterizationMode;
1508 getLineStippleEnable() ? VK_TRUE : VK_FALSE, // VkBool32 stippledLineEnable;
1509 1, // uint32_t lineStippleFactor;
1510 0xFFFF, // uint16_t lineStipplePattern;
1513 if (m_stipple == LINESTIPPLE_STATIC)
1515 lineRasterizationStateInfo.lineStippleFactor = lineStippleFactor;
1516 lineRasterizationStateInfo.lineStipplePattern = lineStipplePattern;
1519 return lineRasterizationStateInfo;
1522 const VkPipelineRasterizationLineStateCreateInfoEXT* BaseLineTestInstance::getLineRasterizationStateCreateInfo (void)
1524 if (m_lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_EXT_LAST)
1527 if (m_lineRasterizationStateInfo.sType != VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT)
1528 m_lineRasterizationStateInfo = initLineRasterizationStateCreateInfo();
1530 return &m_lineRasterizationStateInfo;
1533 class PointTestInstance : public BaseRenderingTestInstance
1536 PointTestInstance (Context& context,
1537 PrimitiveWideness wideness,
1538 PrimitiveStrictness strictness, // ignored
1539 VkSampleCountFlagBits sampleCount,
1540 LineStipple stipple, // ignored
1541 VkLineRasterizationModeEXT lineRasterizationMode, // ignored
1542 deUint32 additionalRenderSize, // ignored
1543 deUint32 renderSize = RESOLUTION_POT,
1544 float pointSizeNarrow = 1.0f);
1545 virtual tcu::TestStatus iterate (void);
1546 virtual float getPointSize (void) const;
1549 int getIteration (void) const { return m_iteration; }
1550 int getIterationCount (void) const { return m_iterationCount; }
1553 virtual void generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints);
1554 virtual bool compareAndVerify (std::vector<PointSceneSpec::ScenePoint>& points,
1555 tcu::Surface& resultImage,
1556 std::vector<tcu::Vec4>& drawBuffer);
1559 const int m_iterationCount;
1560 const PrimitiveWideness m_primitiveWideness;
1561 bool m_allIterationsPassed;
1562 float m_maxPointSize;
1563 std::vector<float> m_pointSizes;
1566 PointTestInstance::PointTestInstance (Context& context,
1567 PrimitiveWideness wideness,
1568 PrimitiveStrictness strictness,
1569 VkSampleCountFlagBits sampleCount,
1570 LineStipple stipple,
1571 VkLineRasterizationModeEXT lineRasterizationMode,
1572 deUint32 additionalRenderSize,
1573 deUint32 renderSize,
1574 float pointSizeNarrow)
1575 : BaseRenderingTestInstance (context, sampleCount, renderSize)
1577 , m_iterationCount (3)
1578 , m_primitiveWideness (wideness)
1579 , m_allIterationsPassed (true)
1580 , m_maxPointSize (pointSizeNarrow)
1582 DE_UNREF(strictness);
1584 DE_UNREF(lineRasterizationMode);
1585 DE_UNREF(additionalRenderSize);
1587 // create point sizes
1588 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
1590 m_pointSizes.resize(m_iterationCount, pointSizeNarrow);
1592 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
1594 const float* range = context.getDeviceProperties().limits.pointSizeRange;
1596 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_ALIASED_POINT_SIZE_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
1598 DE_ASSERT(range[1] > 1.0f);
1600 // set hand picked sizes
1601 m_pointSizes.push_back(10.0f);
1602 m_pointSizes.push_back(25.0f);
1603 m_pointSizes.push_back(range[1]);
1604 DE_ASSERT((int)m_pointSizes.size() == m_iterationCount);
1606 m_maxPointSize = range[1];
1612 tcu::TestStatus PointTestInstance::iterate (void)
1614 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1615 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1616 const float pointSize = getPointSize();
1617 tcu::Surface resultImage (m_renderSize, m_renderSize);
1618 std::vector<tcu::Vec4> drawBuffer;
1619 std::vector<PointSceneSpec::ScenePoint> points;
1622 if (pointSize <= m_maxPointSize)
1625 generatePoints(m_iteration, drawBuffer, points);
1628 drawPrimitives(resultImage, drawBuffer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
1632 const bool compareOk = compareAndVerify(points, resultImage, drawBuffer);
1635 m_allIterationsPassed = false;
1639 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point size " << pointSize << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
1642 if (++m_iteration == m_iterationCount)
1644 if (m_allIterationsPassed)
1645 return tcu::TestStatus::pass("Pass");
1647 return tcu::TestStatus::fail("Incorrect rasterization");
1650 return tcu::TestStatus::incomplete();
1653 bool PointTestInstance::compareAndVerify (std::vector<PointSceneSpec::ScenePoint>& points,
1654 tcu::Surface& resultImage,
1655 std::vector<tcu::Vec4>& drawBuffer)
1657 RasterizationArguments args;
1658 PointSceneSpec scene;
1660 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1662 args.numSamples = m_multisampling ? 1 : 0;
1663 args.subpixelBits = m_subpixelBits;
1664 args.redBits = colorBits[0];
1665 args.greenBits = colorBits[1];
1666 args.blueBits = colorBits[2];
1668 scene.points.swap(points);
1670 DE_UNREF(drawBuffer);
1672 return verifyPointGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
1675 float PointTestInstance::getPointSize (void) const
1677 return m_pointSizes[m_iteration];
1680 void PointTestInstance::generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints)
1687 // \note: these values are chosen arbitrarily
1688 outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f);
1689 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1690 outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f);
1691 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1692 outData[4] = tcu::Vec4(-0.2f, -0.4f, 0.0f, 1.0f);
1693 outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f);
1697 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1698 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1699 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1700 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1701 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1702 outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f);
1706 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1707 outData[1] = tcu::Vec4( 0.3f, -0.9f, 0.0f, 1.0f);
1708 outData[2] = tcu::Vec4( -0.4f, -0.1f, 0.0f, 1.0f);
1709 outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f);
1710 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1711 outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f);
1715 outPoints.resize(outData.size());
1716 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
1718 outPoints[pointNdx].position = outData[pointNdx];
1719 outPoints[pointNdx].pointSize = getPointSize();
1723 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outPoints.size() << " point(s): (point size = " << getPointSize() << ")" << tcu::TestLog::EndMessage;
1724 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
1725 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point " << (pointNdx+1) << ":\t" << outPoints[pointNdx].position << tcu::TestLog::EndMessage;
1728 template <typename ConcreteTestInstance>
1729 class PointSizeTestCase : public BaseRenderingTestCase
1732 PointSizeTestCase (tcu::TestContext& context,
1734 std::string& description,
1735 deUint32 renderSize,
1737 VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
1738 : BaseRenderingTestCase (context, name, description, sampleCount)
1739 , m_pointSize (pointSize)
1740 , m_renderSize (renderSize)
1743 virtual TestInstance* createInstance (Context& context) const
1745 VkPhysicalDeviceProperties properties (context.getDeviceProperties());
1747 if (m_renderSize > properties.limits.maxViewportDimensions[0] || m_renderSize > properties.limits.maxViewportDimensions[1])
1748 TCU_THROW(NotSupportedError , "Viewport dimensions not supported");
1750 if (m_renderSize > properties.limits.maxFramebufferWidth || m_renderSize > properties.limits.maxFramebufferHeight)
1751 TCU_THROW(NotSupportedError , "Framebuffer width/height not supported");
1753 return new ConcreteTestInstance(context, m_renderSize, m_pointSize);
1756 virtual void checkSupport (Context& context) const
1758 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);
1761 const float m_pointSize;
1762 const deUint32 m_renderSize;
1765 class PointSizeTestInstance : public BaseRenderingTestInstance
1768 PointSizeTestInstance (Context& context, deUint32 renderSize, float pointSize);
1769 virtual tcu::TestStatus iterate (void);
1770 virtual float getPointSize (void) const;
1773 void generatePointData (PointSceneSpec::ScenePoint& outPoint);
1774 void drawPoint (tcu::PixelBufferAccess& result, tcu::PointSceneSpec::ScenePoint& point);
1775 bool verifyPoint (tcu::TestLog& log, tcu::PixelBufferAccess& access, float pointSize);
1776 bool isPointSizeClamped (float pointSize, float maxPointSizeLimit);
1778 const float m_pointSize;
1779 const float m_maxPointSize;
1780 const deUint32 m_renderSize;
1781 const VkFormat m_format;
1784 PointSizeTestInstance::PointSizeTestInstance (Context& context, deUint32 renderSize, float pointSize)
1785 : BaseRenderingTestInstance (context, vk::VK_SAMPLE_COUNT_1_BIT, renderSize, VK_FORMAT_R8_UNORM)
1786 , m_pointSize (pointSize)
1787 , m_maxPointSize (context.getDeviceProperties().limits.pointSizeRange[1])
1788 , m_renderSize (renderSize)
1789 , m_format (VK_FORMAT_R8_UNORM) // Use single-channel format to minimize memory allocation when using large render targets
1793 tcu::TestStatus PointSizeTestInstance::iterate (void)
1795 tcu::TextureLevel resultBuffer (mapVkFormat(m_format), m_renderSize, m_renderSize);
1796 tcu::PixelBufferAccess access (resultBuffer.getAccess());
1797 PointSceneSpec::ScenePoint point;
1800 generatePointData(point);
1803 drawPoint(access, point);
1807 // pointSize must either be specified pointSize or clamped to device limit pointSizeRange[1]
1808 const float pointSize (deFloatMin(m_pointSize, m_maxPointSize));
1809 const bool compareOk (verifyPoint(m_context.getTestContext().getLog(), access, pointSize));
1813 return isPointSizeClamped(pointSize, m_maxPointSize) ? tcu::TestStatus::pass("Pass, pointSize clamped to pointSizeRange[1]") : tcu::TestStatus::pass("Pass");
1815 return tcu::TestStatus::fail("Incorrect rasterization");
1819 float PointSizeTestInstance::getPointSize (void) const
1824 void PointSizeTestInstance::generatePointData (PointSceneSpec::ScenePoint& outPoint)
1826 const tcu::PointSceneSpec::ScenePoint point =
1828 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), // position
1829 tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), // color
1830 m_pointSize // pointSize
1837 tcu::TestLog& log = m_context.getTestContext().getLog();
1839 log << tcu::TestLog::Message << "Point position: " << de::toString(point.position) << tcu::TestLog::EndMessage;
1840 log << tcu::TestLog::Message << "Point color: " << de::toString(point.color) << tcu::TestLog::EndMessage;
1841 log << tcu::TestLog::Message << "Point size: " << de::toString(point.pointSize) << tcu::TestLog::EndMessage;
1842 log << tcu::TestLog::Message << "Render size: " << de::toString(m_renderSize) << tcu::TestLog::EndMessage;
1843 log << tcu::TestLog::Message << "Format: " << de::toString(m_format) << tcu::TestLog::EndMessage;
1847 void PointSizeTestInstance::drawPoint (tcu::PixelBufferAccess& result, PointSceneSpec::ScenePoint& point)
1849 const tcu::Vec4 positionData (point.position);
1850 const tcu::Vec4 colorData (point.color);
1852 const DeviceInterface& vkd (m_context.getDeviceInterface());
1853 const VkDevice vkDevice (m_context.getDevice());
1854 const VkQueue queue (m_context.getUniversalQueue());
1855 const deUint32 queueFamilyIndex (m_context.getUniversalQueueFamilyIndex());
1856 const size_t attributeBatchSize (sizeof(tcu::Vec4));
1857 Allocator& allocator (m_context.getDefaultAllocator());
1859 Move<VkCommandBuffer> commandBuffer;
1860 Move<VkPipeline> graphicsPipeline;
1861 Move<VkBuffer> vertexBuffer;
1862 de::MovePtr<Allocation> vertexBufferMemory;
1864 // Create Graphics Pipeline
1866 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(m_renderSize)));
1867 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(m_renderSize)));
1869 const VkVertexInputBindingDescription vertexInputBindingDescription =
1871 0u, // deUint32 binding;
1872 (deUint32)(2 * sizeof(tcu::Vec4)), // deUint32 strideInBytes;
1873 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
1876 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
1879 0u, // deUint32 location;
1880 0u, // deUint32 binding;
1881 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1882 0u // deUint32 offsetInBytes;
1885 1u, // deUint32 location;
1886 0u, // deUint32 binding;
1887 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1888 (deUint32)sizeof(tcu::Vec4) // deUint32 offsetInBytes;
1892 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1894 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1895 DE_NULL, // const void* pNext;
1896 0, // VkPipelineVertexInputStateCreateFlags flags;
1897 1u, // deUint32 bindingCount;
1898 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1899 2u, // deUint32 attributeCount;
1900 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1903 graphicsPipeline = makeGraphicsPipeline(vkd, // const DeviceInterface& vk
1904 vkDevice, // const VkDevice device
1905 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
1906 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
1907 DE_NULL, // const VkShaderModule tessellationControlShaderModule
1908 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
1909 DE_NULL, // const VkShaderModule geometryShaderModule
1910 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
1911 *m_renderPass, // const VkRenderPass renderPass
1912 viewports, // const std::vector<VkViewport>& viewports
1913 scissors, // const std::vector<VkRect2D>& scissors
1914 VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // const VkPrimitiveTopology topology
1915 0u, // const deUint32 subpass
1916 0u, // const deUint32 patchControlPoints
1917 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
1918 getRasterizationStateCreateInfo(), // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
1919 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
1920 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo,
1921 getColorBlendStateCreateInfo()); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
1924 // Create Vertex Buffer
1926 const VkBufferCreateInfo vertexBufferParams =
1928 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1929 DE_NULL, // const void* pNext;
1930 0u, // VkBufferCreateFlags flags;
1931 attributeBatchSize * 2, // VkDeviceSize size;
1932 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1933 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1934 1u, // deUint32 queueFamilyCount;
1935 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1938 vertexBuffer = createBuffer(vkd, vkDevice, &vertexBufferParams);
1939 vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
1941 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
1943 // Load vertices into vertex buffer
1944 deMemcpy(vertexBufferMemory->getHostPtr(), &positionData, attributeBatchSize);
1945 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) + attributeBatchSize, &colorData, attributeBatchSize);
1946 flushAlloc(vkd, vkDevice, *vertexBufferMemory);
1949 // Create Command Buffer
1950 commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1952 // Begin Command Buffer
1953 beginCommandBuffer(vkd, *commandBuffer);
1955 addImageTransitionBarrier(*commandBuffer, *m_image,
1956 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
1957 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
1958 0, // VkAccessFlags srcAccessMask
1959 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
1960 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1961 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
1963 // Begin Render Pass
1964 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));
1966 const VkDeviceSize vertexBufferOffset = 0;
1968 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
1969 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL);
1970 vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
1971 vkd.cmdDraw(*commandBuffer, 1, 1, 0, 0);
1972 endRenderPass(vkd, *commandBuffer);
1975 copyImageToBuffer(vkd, *commandBuffer, *m_image, *m_resultBuffer, tcu::IVec2(m_renderSize, m_renderSize));
1977 endCommandBuffer(vkd, *commandBuffer);
1981 float pointSize = getPointSize();
1983 deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize);
1984 flushAlloc(vkd, vkDevice, *m_uniformBufferMemory);
1988 submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());
1990 invalidateAlloc(vkd, vkDevice, *m_resultBufferMemory);
1991 tcu::copy(result, tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderSize, m_renderSize, 1), m_resultBufferMemory->getHostPtr()));
1994 bool PointSizeTestInstance::verifyPoint (tcu::TestLog& log, tcu::PixelBufferAccess& image, float pointSize)
1996 const float expectedPointColor (1.0f);
1997 const float expectedBackgroundColor (0.0f);
1998 deUint32 pointWidth (0u);
1999 deUint32 pointHeight (0u);
2000 bool incorrectlyColoredPixelsFound (false);
2003 // Verify rasterized point width and color
2004 for (size_t x = 0; x < (deUint32)image.getWidth(); x++)
2006 float pixelColor = image.getPixel((deUint32)x, image.getHeight() / 2).x();
2008 if (pixelColor == expectedPointColor)
2011 if ((pixelColor != expectedPointColor) && (pixelColor != expectedBackgroundColor))
2012 incorrectlyColoredPixelsFound = true;
2015 // Verify rasterized point height and color
2016 for (size_t y = 0; y < (deUint32)image.getHeight(); y++)
2018 float pixelColor = image.getPixel((deUint32)y, image.getWidth() / 2).x();
2020 if (pixelColor == expectedPointColor)
2023 if ((pixelColor != expectedPointColor) && (pixelColor != expectedBackgroundColor))
2024 incorrectlyColoredPixelsFound = true;
2027 // Compare amount of rasterized point pixels to expected pointSize.
2028 if ((pointWidth != (deUint32)deRoundFloatToInt32(pointSize)) || (pointHeight != (deUint32)deRoundFloatToInt32(pointSize)))
2030 log << tcu::TestLog::Message << "Incorrect point size. Expected pointSize: " << de::toString(pointSize)
2031 << ". Rasterized point width: " << pointWidth << " pixels, height: "
2032 << pointHeight << " pixels." << tcu::TestLog::EndMessage;
2037 // Check incorrectly colored pixels
2038 if (incorrectlyColoredPixelsFound)
2040 log << tcu::TestLog::Message << "Incorrectly colored pixels found." << tcu::TestLog::EndMessage;
2047 bool PointSizeTestInstance::isPointSizeClamped (float pointSize, float maxPointSizeLimit)
2049 return (pointSize == maxPointSizeLimit);
2052 template <typename ConcreteTestInstance>
2053 class BaseTestCase : public BaseRenderingTestCase
2056 BaseTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2057 : BaseRenderingTestCase(context, name, description, sampleCount)
2060 virtual TestInstance* createInstance (Context& context) const
2062 return new ConcreteTestInstance(context, m_sampleCount);
2066 class TrianglesTestInstance : public BaseTriangleTestInstance
2069 TrianglesTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
2070 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, sampleCount)
2073 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
2076 void TrianglesTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
2083 // \note: these values are chosen arbitrarily
2084 outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f);
2085 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
2086 outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f);
2087 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
2088 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
2089 outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f);
2093 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
2094 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
2095 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
2096 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
2097 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
2098 outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f);
2102 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
2103 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
2104 outData[2] = tcu::Vec4( -1.1f, -0.1f, 0.0f, 1.0f);
2105 outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f);
2106 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
2107 outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f);
2111 outTriangles.resize(2);
2112 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
2113 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false;
2114 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false;
2116 outTriangles[1].positions[0] = outData[3]; outTriangles[1].sharedEdge[0] = false;
2117 outTriangles[1].positions[1] = outData[4]; outTriangles[1].sharedEdge[1] = false;
2118 outTriangles[1].positions[2] = outData[5]; outTriangles[1].sharedEdge[2] = false;
2121 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outTriangles.size() << " triangle(s):" << tcu::TestLog::EndMessage;
2122 for (int triangleNdx = 0; triangleNdx < (int)outTriangles.size(); ++triangleNdx)
2124 m_context.getTestContext().getLog()
2125 << tcu::TestLog::Message
2126 << "Triangle " << (triangleNdx+1) << ":"
2127 << "\n\t" << outTriangles[triangleNdx].positions[0]
2128 << "\n\t" << outTriangles[triangleNdx].positions[1]
2129 << "\n\t" << outTriangles[triangleNdx].positions[2]
2130 << tcu::TestLog::EndMessage;
2134 class TriangleStripTestInstance : public BaseTriangleTestInstance
2137 TriangleStripTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
2138 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, sampleCount)
2141 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
2144 void TriangleStripTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
2151 // \note: these values are chosen arbitrarily
2152 outData[0] = tcu::Vec4(-0.504f, 0.8f, 0.0f, 1.0f);
2153 outData[1] = tcu::Vec4(-0.2f, -0.2f, 0.0f, 1.0f);
2154 outData[2] = tcu::Vec4(-0.2f, 0.199f, 0.0f, 1.0f);
2155 outData[3] = tcu::Vec4( 0.5f, 0.201f, 0.0f, 1.0f);
2156 outData[4] = tcu::Vec4( 1.5f, 0.4f, 0.0f, 1.0f);
2160 outData[0] = tcu::Vec4(-0.499f, 0.129f, 0.0f, 1.0f);
2161 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
2162 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
2163 outData[3] = tcu::Vec4( 0.11f, -0.31f, 0.0f, 1.0f);
2164 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
2168 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
2169 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
2170 outData[2] = tcu::Vec4(-0.87f, -0.1f, 0.0f, 1.0f);
2171 outData[3] = tcu::Vec4(-0.11f, 0.19f, 0.0f, 1.0f);
2172 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
2176 outTriangles.resize(3);
2177 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
2178 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = true;
2179 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false;
2181 outTriangles[1].positions[0] = outData[2]; outTriangles[1].sharedEdge[0] = true;
2182 outTriangles[1].positions[1] = outData[1]; outTriangles[1].sharedEdge[1] = false;
2183 outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true;
2185 outTriangles[2].positions[0] = outData[2]; outTriangles[2].sharedEdge[0] = true;
2186 outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false;
2187 outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false;
2190 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering triangle strip, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
2191 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
2193 m_context.getTestContext().getLog()
2194 << tcu::TestLog::Message
2195 << "\t" << outData[vtxNdx]
2196 << tcu::TestLog::EndMessage;
2200 class TriangleFanTestInstance : public BaseTriangleTestInstance
2203 TriangleFanTestInstance (Context& context, VkSampleCountFlagBits sampleCount);
2206 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
2209 TriangleFanTestInstance::TriangleFanTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
2210 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, sampleCount)
2212 if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
2213 !context.getPortabilitySubsetFeatures().triangleFans)
2215 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
2219 void TriangleFanTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
2226 // \note: these values are chosen arbitrarily
2227 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
2228 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
2229 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
2230 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
2231 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
2235 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
2236 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
2237 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
2238 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
2239 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
2243 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
2244 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
2245 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
2246 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
2247 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
2251 outTriangles.resize(3);
2252 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
2253 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false;
2254 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = true;
2256 outTriangles[1].positions[0] = outData[0]; outTriangles[1].sharedEdge[0] = true;
2257 outTriangles[1].positions[1] = outData[2]; outTriangles[1].sharedEdge[1] = false;
2258 outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true;
2260 outTriangles[2].positions[0] = outData[0]; outTriangles[2].sharedEdge[0] = true;
2261 outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false;
2262 outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false;
2265 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering triangle fan, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
2266 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
2268 m_context.getTestContext().getLog()
2269 << tcu::TestLog::Message
2270 << "\t" << outData[vtxNdx]
2271 << tcu::TestLog::EndMessage;
2275 struct ConservativeTestConfig
2277 VkConservativeRasterizationModeEXT conservativeRasterizationMode;
2278 float extraOverestimationSize;
2279 VkPrimitiveTopology primitiveTopology;
2280 bool degeneratePrimitives;
2282 deUint32 resolution;
2285 float getExtraOverestimationSize (const float overestimationSizeDesired, const VkPhysicalDeviceConservativeRasterizationPropertiesEXT& conservativeRasterizationProperties)
2287 const float extraOverestimationSize = overestimationSizeDesired == TCU_INFINITY ? conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize
2288 : overestimationSizeDesired == -TCU_INFINITY ? conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity
2289 : overestimationSizeDesired;
2291 return extraOverestimationSize;
2294 template <typename ConcreteTestInstance>
2295 class ConservativeTestCase : public BaseRenderingTestCase
2298 ConservativeTestCase (tcu::TestContext& context,
2299 const std::string& name,
2300 const std::string& description,
2301 const ConservativeTestConfig& conservativeTestConfig,
2302 VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2303 : BaseRenderingTestCase (context, name, description, sampleCount)
2304 , m_conservativeTestConfig (conservativeTestConfig)
2307 virtual void checkSupport (Context& context) const;
2309 virtual TestInstance* createInstance (Context& context) const
2311 return new ConcreteTestInstance(context, m_conservativeTestConfig, m_sampleCount);
2315 bool isUseLineSubPixel (Context& context) const;
2316 deUint32 getSubPixelResolution (Context& context) const;
2318 const ConservativeTestConfig m_conservativeTestConfig;
2321 template <typename ConcreteTestInstance>
2322 bool ConservativeTestCase<ConcreteTestInstance>::isUseLineSubPixel (Context& context) const
2324 return (isPrimitiveTopologyLine(m_conservativeTestConfig.primitiveTopology) && context.isDeviceFunctionalitySupported("VK_EXT_line_rasterization"));
2327 template <typename ConcreteTestInstance>
2328 deUint32 ConservativeTestCase<ConcreteTestInstance>::getSubPixelResolution (Context& context) const
2330 if (isUseLineSubPixel(context))
2332 const VkPhysicalDeviceLineRasterizationPropertiesEXT lineRasterizationPropertiesEXT = context.getLineRasterizationPropertiesEXT();
2334 return lineRasterizationPropertiesEXT.lineSubPixelPrecisionBits;
2338 return context.getDeviceProperties().limits.subPixelPrecisionBits;
2342 template <typename ConcreteTestInstance>
2343 void ConservativeTestCase<ConcreteTestInstance>::checkSupport (Context& context) const
2345 context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");
2347 const VkPhysicalDeviceConservativeRasterizationPropertiesEXT conservativeRasterizationProperties = context.getConservativeRasterizationPropertiesEXT();
2348 const deUint32 subPixelPrecisionBits = getSubPixelResolution(context);
2349 const deUint32 subPixelPrecision = 1<<subPixelPrecisionBits;
2350 const bool linesPrecision = isUseLineSubPixel(context);
2351 const float primitiveOverestimationSizeMult = float(subPixelPrecision) * conservativeRasterizationProperties.primitiveOverestimationSize;
2352 const bool topologyLineOrPoint = isPrimitiveTopologyLine(m_conservativeTestConfig.primitiveTopology) || isPrimitiveTopologyPoint(m_conservativeTestConfig.primitiveTopology);
2354 DE_ASSERT(subPixelPrecisionBits < sizeof(deUint32) * 8);
2356 context.getTestContext().getLog()
2357 << tcu::TestLog::Message
2358 << "maxExtraPrimitiveOverestimationSize=" << conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize << '\n'
2359 << "extraPrimitiveOverestimationSizeGranularity=" << conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity << '\n'
2360 << "degenerateLinesRasterized=" << conservativeRasterizationProperties.degenerateLinesRasterized << '\n'
2361 << "degenerateTrianglesRasterized=" << conservativeRasterizationProperties.degenerateTrianglesRasterized << '\n'
2362 << "primitiveOverestimationSize=" << conservativeRasterizationProperties.primitiveOverestimationSize << " (==" << primitiveOverestimationSizeMult << '/' << subPixelPrecision << ")\n"
2363 << "subPixelPrecisionBits=" << subPixelPrecisionBits << (linesPrecision ? " (using VK_EXT_line_rasterization)" : " (using limits)") << '\n'
2364 << tcu::TestLog::EndMessage;
2366 if (conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity > conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize)
2367 TCU_FAIL("Granularity cannot be greater than maximum extra size");
2369 if (topologyLineOrPoint)
2371 if (!conservativeRasterizationProperties.conservativePointAndLineRasterization)
2372 TCU_THROW(NotSupportedError, "Conservative line and point rasterization is not supported");
2375 if (m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT)
2377 if (conservativeRasterizationProperties.primitiveUnderestimation == DE_FALSE)
2378 TCU_THROW(NotSupportedError, "Underestimation is not supported");
2380 if (isPrimitiveTopologyLine(m_conservativeTestConfig.primitiveTopology))
2382 const float testLineWidth = m_conservativeTestConfig.lineWidth;
2384 if (testLineWidth != 1.0f)
2386 const VkPhysicalDeviceLimits& limits = context.getDeviceProperties().limits;
2387 const float lineWidthRange[2] = { limits.lineWidthRange[0], limits.lineWidthRange[1] };
2388 const float lineWidthGranularity = limits.lineWidthGranularity;
2390 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_WIDE_LINES);
2392 if (lineWidthGranularity == 0.0f)
2393 TCU_THROW(NotSupportedError, "Wide lines required for test, but are not supported");
2395 DE_ASSERT(lineWidthGranularity > 0.0f && lineWidthRange[0] > 0.0f && lineWidthRange[1] >= lineWidthRange[0]);
2397 if (!de::inBounds(testLineWidth, lineWidthRange[0], lineWidthRange[1]))
2398 TCU_THROW(NotSupportedError, "Tested line width is not supported");
2400 const float n = (testLineWidth - lineWidthRange[0]) / lineWidthGranularity;
2402 if (deFloatFrac(n) != 0.0f || n * lineWidthGranularity + lineWidthRange[0] != testLineWidth)
2403 TCU_THROW(NotSupportedError, "Exact match of line width is required for the test");
2406 else if (isPrimitiveTopologyPoint(m_conservativeTestConfig.primitiveTopology))
2408 const float testPointSize = m_conservativeTestConfig.lineWidth;
2410 if (testPointSize != 1.0f)
2412 const VkPhysicalDeviceLimits& limits = context.getDeviceProperties().limits;
2413 const float pointSizeRange[2] = { limits.pointSizeRange[0], limits.pointSizeRange[1] };
2414 const float pointSizeGranularity = limits.pointSizeGranularity;
2416 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);
2418 if (pointSizeGranularity == 0.0f)
2419 TCU_THROW(NotSupportedError, "Large points required for test, but are not supported");
2421 DE_ASSERT(pointSizeGranularity > 0.0f && pointSizeRange[0] > 0.0f && pointSizeRange[1] >= pointSizeRange[0]);
2423 if (!de::inBounds(testPointSize, pointSizeRange[0], pointSizeRange[1]))
2424 TCU_THROW(NotSupportedError, "Tested point size is not supported");
2426 const float n = (testPointSize - pointSizeRange[0]) / pointSizeGranularity;
2428 if (deFloatFrac(n) != 0.0f || n * pointSizeGranularity + pointSizeRange[0] != testPointSize)
2429 TCU_THROW(NotSupportedError, "Exact match of point size is required for the test");
2433 else if (m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT)
2435 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, conservativeRasterizationProperties);
2437 if (extraOverestimationSize > conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize)
2438 TCU_THROW(NotSupportedError, "Specified overestimation size is not supported");
2440 if (topologyLineOrPoint)
2442 if (!conservativeRasterizationProperties.conservativePointAndLineRasterization)
2443 TCU_THROW(NotSupportedError, "Conservative line and point rasterization is not supported");
2446 if (isPrimitiveTopologyTriangle(m_conservativeTestConfig.primitiveTopology))
2448 if (m_conservativeTestConfig.degeneratePrimitives)
2450 // Enforce specification minimum required limit to avoid division by zero
2451 DE_ASSERT(subPixelPrecisionBits >= 4);
2453 // Make sure float precision of 22 bits is enough, i.e. resoultion in subpixel quarters less than float precision
2454 if (m_conservativeTestConfig.resolution * (1<<(subPixelPrecisionBits + 2)) > (1<<21))
2455 TCU_THROW(NotSupportedError, "Subpixel resolution is too high to generate degenerate primitives");
2460 TCU_THROW(InternalError, "Non-conservative mode tests are not supported by this class");
2463 class ConservativeTraingleTestInstance : public BaseTriangleTestInstance
2466 ConservativeTraingleTestInstance (Context& context,
2467 ConservativeTestConfig conservativeTestConfig,
2468 VkSampleCountFlagBits sampleCount)
2469 : BaseTriangleTestInstance (context,
2470 conservativeTestConfig.primitiveTopology,
2472 conservativeTestConfig.resolution)
2473 , m_conservativeTestConfig (conservativeTestConfig)
2474 , m_conservativeRasterizationProperties (context.getConservativeRasterizationPropertiesEXT())
2475 , m_rasterizationConservativeStateCreateInfo (initRasterizationConservativeStateCreateInfo())
2476 , m_rasterizationStateCreateInfo (initRasterizationStateCreateInfo())
2479 void generateTriangles (int iteration,
2480 std::vector<tcu::Vec4>& outData,
2481 std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
2482 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
2485 virtual const VkPipelineRasterizationLineStateCreateInfoEXT* getLineRasterizationStateCreateInfo (void);
2487 virtual bool compareAndVerify (std::vector<TriangleSceneSpec::SceneTriangle>& triangles,
2488 tcu::Surface& resultImage,
2489 std::vector<tcu::Vec4>& drawBuffer);
2490 virtual bool compareAndVerifyOverestimatedNormal (std::vector<TriangleSceneSpec::SceneTriangle>& triangles,
2491 tcu::Surface& resultImage);
2492 virtual bool compareAndVerifyOverestimatedDegenerate (std::vector<TriangleSceneSpec::SceneTriangle>& triangles,
2493 tcu::Surface& resultImage);
2494 virtual bool compareAndVerifyUnderestimatedNormal (std::vector<TriangleSceneSpec::SceneTriangle>& triangles,
2495 tcu::Surface& resultImage);
2496 virtual bool compareAndVerifyUnderestimatedDegenerate (std::vector<TriangleSceneSpec::SceneTriangle>& triangles,
2497 tcu::Surface& resultImage);
2498 void generateNormalTriangles (int iteration,
2499 std::vector<tcu::Vec4>& outData,
2500 std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
2501 void generateDegenerateTriangles (int iteration,
2502 std::vector<tcu::Vec4>& outData,
2503 std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
2504 void drawPrimitives (tcu::Surface& result,
2505 const std::vector<tcu::Vec4>& vertexData,
2506 VkPrimitiveTopology primitiveTopology);
2509 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> initRasterizationConservativeStateCreateInfo (void);
2510 const std::vector<VkPipelineRasterizationStateCreateInfo> initRasterizationStateCreateInfo (void);
2512 const ConservativeTestConfig m_conservativeTestConfig;
2513 const VkPhysicalDeviceConservativeRasterizationPropertiesEXT m_conservativeRasterizationProperties;
2514 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> m_rasterizationConservativeStateCreateInfo;
2515 const std::vector<VkPipelineRasterizationStateCreateInfo> m_rasterizationStateCreateInfo;
2518 void ConservativeTraingleTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
2520 if (m_conservativeTestConfig.degeneratePrimitives)
2521 generateDegenerateTriangles(iteration, outData, outTriangles);
2523 generateNormalTriangles(iteration, outData, outTriangles);
2526 void ConservativeTraingleTestInstance::generateNormalTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
2528 const float halfPixel = 1.0f / float(m_renderSize);
2529 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
2530 const float overestimate = 2.0f * halfPixel * (m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize);
2531 const float overestimateMargin = overestimate;
2532 const float underestimateMargin = 0.0f;
2533 const bool isOverestimate = m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
2534 const float margin = isOverestimate ? overestimateMargin : underestimateMargin;
2535 const char* overestimateIterationComments[] = { "Corner touch", "Any portion pixel coverage", "Edge touch" };
2544 const float edge = 2 * halfPixel + margin;
2545 const float left = -1.0f + edge;
2546 const float right = +1.0f - edge;
2547 const float up = -1.0f + edge;
2548 const float down = +1.0f - edge;
2550 outData[0] = tcu::Vec4( left, down, 0.0f, 1.0f);
2551 outData[1] = tcu::Vec4( left, up, 0.0f, 1.0f);
2552 outData[2] = tcu::Vec4(right, down, 0.0f, 1.0f);
2554 outData[3] = tcu::Vec4( left, up, 0.0f, 1.0f);
2555 outData[4] = tcu::Vec4(right, down, 0.0f, 1.0f);
2556 outData[5] = tcu::Vec4(right, up, 0.0f, 1.0f);
2564 const float eps = halfPixel / 32.0f;
2565 const float edge = 4.0f * halfPixel + margin - eps;
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 edge = 6.0f * halfPixel + margin;
2586 const float left = -1.0f + edge;
2587 const float right = +1.0f - edge;
2588 const float up = -1.0f + edge;
2589 const float down = +1.0f - edge;
2591 outData[0] = tcu::Vec4( left, down, 0.0f, 1.0f);
2592 outData[1] = tcu::Vec4( left, up, 0.0f, 1.0f);
2593 outData[2] = tcu::Vec4(right, down, 0.0f, 1.0f);
2595 outData[3] = tcu::Vec4( left, up, 0.0f, 1.0f);
2596 outData[4] = tcu::Vec4(right, down, 0.0f, 1.0f);
2597 outData[5] = tcu::Vec4(right, up, 0.0f, 1.0f);
2603 TCU_THROW(InternalError, "Unexpected iteration");
2606 outTriangles.resize(outData.size() / 3);
2608 for (size_t ndx = 0; ndx < outTriangles.size(); ++ndx)
2610 outTriangles[ndx].positions[0] = outData[3 * ndx + 0]; outTriangles[ndx].sharedEdge[0] = false;
2611 outTriangles[ndx].positions[1] = outData[3 * ndx + 1]; outTriangles[ndx].sharedEdge[1] = false;
2612 outTriangles[ndx].positions[2] = outData[3 * ndx + 2]; outTriangles[ndx].sharedEdge[2] = false;
2618 m_context.getTestContext().getLog()
2619 << tcu::TestLog::Message
2620 << "Testing " << overestimateIterationComments[iteration] << " "
2621 << "with rendering " << outTriangles.size() << " triangle(s):"
2622 << tcu::TestLog::EndMessage;
2626 m_context.getTestContext().getLog()
2627 << tcu::TestLog::Message
2628 << "Rendering " << outTriangles.size() << " triangle(s):"
2629 << tcu::TestLog::EndMessage;
2632 for (size_t ndx = 0; ndx < outTriangles.size(); ++ndx)
2634 const deUint32 multiplier = m_renderSize / 2;
2636 m_context.getTestContext().getLog()
2637 << tcu::TestLog::Message
2638 << "Triangle " << (ndx + 1) << ":"
2639 << "\n\t" << outTriangles[ndx].positions[0] << " == " << (float(multiplier) * outTriangles[ndx].positions[0]) << "/" << multiplier
2640 << "\n\t" << outTriangles[ndx].positions[1] << " == " << (float(multiplier) * outTriangles[ndx].positions[1]) << "/" << multiplier
2641 << "\n\t" << outTriangles[ndx].positions[2] << " == " << (float(multiplier) * outTriangles[ndx].positions[2]) << "/" << multiplier
2642 << tcu::TestLog::EndMessage;
2646 void ConservativeTraingleTestInstance::generateDegenerateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
2648 tcu::TestLog& log = m_context.getTestContext().getLog();
2649 const float pixelSize = 2.0f / float(m_renderSize);
2650 const deUint32 subPixels = 1u << m_context.getDeviceProperties().limits.subPixelPrecisionBits;
2651 const float subPixelSize = pixelSize / float(subPixels);
2652 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
2653 const float totalOverestimate = m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize;
2654 const float totalOverestimateInSubPixels = deFloatCeil(totalOverestimate * float(subPixels));
2655 const float overestimate = subPixelSize * totalOverestimateInSubPixels;
2656 const float overestimateSafetyMargin = subPixelSize * 0.125f;
2657 const float overestimateMargin = overestimate + overestimateSafetyMargin;
2658 const float underestimateMargin = 0.0f;
2659 const bool isOverestimate = m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
2660 const float margin = isOverestimate ? overestimateMargin : underestimateMargin;
2661 const char* overestimateIterationComments[] = { "Backfacing", "Generate pixels", "Use provoking vertex" };
2663 if (pixelSize < 2 * overestimateMargin)
2664 TCU_THROW(NotSupportedError, "Could not generate degenerate triangle for such overestimate parameters");
2674 for (int rowNdx = 0; rowNdx < 3; ++rowNdx)
2675 for (int colNdx = 0; colNdx < 4; ++colNdx)
2677 const float offsetX = -1.0f + float(4 * (colNdx + 1)) * pixelSize;
2678 const float offsetY = -1.0f + float(4 * (rowNdx + 1)) * pixelSize;
2679 const float left = offsetX + margin;
2680 const float right = offsetX + margin + 0.25f * subPixelSize;
2681 const float up = offsetY + margin;
2682 const float down = offsetY + margin + 0.25f * subPixelSize;
2683 const bool luPresent = (rowNdx & 1) == 0;
2684 const bool rdPresent = (rowNdx & 2) == 0;
2685 const bool luCW = (colNdx & 1) == 0;
2686 const bool rdCW = (colNdx & 2) == 0;
2688 DE_ASSERT(left < right);
2689 DE_ASSERT(up < down);
2695 // CW triangle left up
2696 outData.push_back(tcu::Vec4( left, down, 0.0f, 1.0f));
2697 outData.push_back(tcu::Vec4( left, up, 0.0f, 1.0f));
2698 outData.push_back(tcu::Vec4(right, up, 0.0f, 1.0f));
2702 // CCW triangle left up
2703 outData.push_back(tcu::Vec4(right, up, 0.0f, 1.0f));
2704 outData.push_back(tcu::Vec4( left, up, 0.0f, 1.0f));
2705 outData.push_back(tcu::Vec4( left, down, 0.0f, 1.0f));
2713 // CW triangle right down
2714 outData.push_back(tcu::Vec4(right, up, 0.0f, 1.0f));
2715 outData.push_back(tcu::Vec4(right, down, 0.0f, 1.0f));
2716 outData.push_back(tcu::Vec4( left, down, 0.0f, 1.0f));
2720 // CCW triangle right down
2721 outData.push_back(tcu::Vec4( left, down, 0.0f, 1.0f));
2722 outData.push_back(tcu::Vec4(right, down, 0.0f, 1.0f));
2723 outData.push_back(tcu::Vec4(right, up, 0.0f, 1.0f));
2732 TCU_THROW(InternalError, "Unexpected iteration");
2735 outTriangles.resize(outData.size() / 3);
2737 for (size_t ndx = 0; ndx < outTriangles.size(); ++ndx)
2739 outTriangles[ndx].positions[0] = outData[3 * ndx + 0]; outTriangles[ndx].sharedEdge[0] = false;
2740 outTriangles[ndx].positions[1] = outData[3 * ndx + 1]; outTriangles[ndx].sharedEdge[1] = false;
2741 outTriangles[ndx].positions[2] = outData[3 * ndx + 2]; outTriangles[ndx].sharedEdge[2] = false;
2747 m_context.getTestContext().getLog()
2748 << tcu::TestLog::Message
2749 << "Testing " << overestimateIterationComments[iteration] << " "
2750 << "with rendering " << outTriangles.size() << " triangle(s):"
2751 << tcu::TestLog::EndMessage;
2755 m_context.getTestContext().getLog()
2756 << tcu::TestLog::Message
2757 << "Rendering " << outTriangles.size() << " triangle(s):"
2758 << tcu::TestLog::EndMessage;
2761 for (int ndx = 0; ndx < (int)outTriangles.size(); ++ndx)
2763 const deUint32 multiplierInt = m_renderSize / 2;
2764 const deUint32 multiplierFrac = subPixels;
2765 std::string coordsString;
2767 for (size_t vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
2769 const tcu::Vec4& pos = outTriangles[ndx].positions[vertexNdx];
2770 std::ostringstream coordsFloat;
2771 std::ostringstream coordsNatural;
2773 for (int coordNdx = 0; coordNdx < 2; ++coordNdx)
2775 const char* sep = (coordNdx < 1) ? "," : "";
2776 const float coord = pos[coordNdx];
2777 const char sign = deSign(coord) < 0 ? '-' : '+';
2778 const float m = deFloatFloor(float(multiplierInt) * deFloatAbs(coord));
2779 const float r = deFloatFrac(float(multiplierInt) * deFloatAbs(coord)) * float(multiplierFrac);
2781 coordsFloat << std::fixed << std::setw(13) << std::setprecision(10) << coord << sep;
2782 coordsNatural << sign << '(' << m << '+' << r << '/' << multiplierFrac << ')' << sep;
2785 coordsString += "\n\t[" + coordsFloat.str() + "] == [" + coordsNatural.str() + "] / " + de::toString(multiplierInt);
2788 log << tcu::TestLog::Message
2789 << "Triangle " << (ndx + 1) << ':'
2791 << tcu::TestLog::EndMessage;
2795 void ConservativeTraingleTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology)
2797 if (m_conservativeTestConfig.degeneratePrimitives && getIteration() == 2)
2799 // Set provoking vertex color to white
2800 tcu::Vec4 colorProvoking (1.0f, 1.0f, 1.0f, 1.0f);
2801 tcu::Vec4 colorOther (0.0f, 1.0f, 1.0f, 1.0f);
2802 std::vector<tcu::Vec4> colorData;
2804 colorData.reserve(vertexData.size());
2806 for (size_t vertexNdx = 0; vertexNdx < vertexData.size(); ++vertexNdx)
2807 if (vertexNdx % 3 == 0)
2808 colorData.push_back(colorProvoking);
2810 colorData.push_back(colorOther);
2812 BaseRenderingTestInstance::drawPrimitives(result, vertexData, colorData, primitiveTopology);
2815 BaseRenderingTestInstance::drawPrimitives(result, vertexData, primitiveTopology);
2818 bool ConservativeTraingleTestInstance::compareAndVerify (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage, std::vector<tcu::Vec4>& drawBuffer)
2820 DE_UNREF(drawBuffer);
2822 switch (m_conservativeTestConfig.conservativeRasterizationMode)
2824 case VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT:
2826 if (m_conservativeTestConfig.degeneratePrimitives)
2827 return compareAndVerifyOverestimatedDegenerate(triangles, resultImage);
2829 return compareAndVerifyOverestimatedNormal(triangles, resultImage);
2834 case VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT:
2836 if (m_conservativeTestConfig.degeneratePrimitives)
2837 return compareAndVerifyUnderestimatedDegenerate(triangles, resultImage);
2839 return compareAndVerifyUnderestimatedNormal(triangles, resultImage);
2845 TCU_THROW(InternalError, "Unknown conservative rasterization mode");
2849 bool ConservativeTraingleTestInstance::compareAndVerifyOverestimatedNormal (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage)
2851 DE_UNREF(triangles);
2853 const int start = getIteration() + 1;
2854 const int end = resultImage.getHeight() - start;
2855 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
2856 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
2857 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
2858 tcu::TestLog& log = m_context.getTestContext().getLog();
2861 deUint32 errValue = 0;
2864 DE_ASSERT(resultImage.getHeight() == resultImage.getWidth());
2866 for (int y = start; result && y < end; ++y)
2867 for (int x = start; result && x < end; ++x)
2869 if (resultImage.getPixel(x,y).getPacked() != foregroundColor.getPacked())
2874 errValue = resultImage.getPixel(x,y).getPacked();
2882 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
2883 tcu::Surface expectedImage (resultImage.getWidth(), resultImage.getHeight());
2885 for (int y = 0; y < errorMask.getHeight(); ++y)
2886 for (int x = 0; x < errorMask.getWidth(); ++x)
2888 errorMask.setPixel(x, y, backgroundColor);
2889 expectedImage.setPixel(x, y, backgroundColor);
2892 for (int y = start; y < end; ++y)
2893 for (int x = start; x < end; ++x)
2895 expectedImage.setPixel(x, y, foregroundColor);
2897 if (resultImage.getPixel(x, y).getPacked() != foregroundColor.getPacked())
2898 errorMask.setPixel(x, y, unexpectedPixelColor);
2901 log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
2902 << tcu::TestLog::EndMessage;
2903 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
2904 << tcu::TestLog::Image("Result", "Result", resultImage)
2905 << tcu::TestLog::Image("Expected", "Expected", expectedImage)
2906 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
2907 << tcu::TestLog::EndImageSet;
2911 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
2912 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
2913 << tcu::TestLog::Image("Result", "Result", resultImage)
2914 << tcu::TestLog::EndImageSet;
2920 bool ConservativeTraingleTestInstance::compareAndVerifyOverestimatedDegenerate (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage)
2922 DE_UNREF(triangles);
2924 const char* iterationComments[] = { "Cull back face triangles", "Cull front face triangles", "Cull none" };
2925 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
2926 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
2927 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
2928 tcu::TestLog& log = m_context.getTestContext().getLog();
2930 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
2932 for (int y = 0; y < resultImage.getHeight(); ++y)
2933 for (int x = 0; x < resultImage.getWidth(); ++x)
2934 referenceImage.setPixel(x, y, backgroundColor);
2936 if (m_conservativeRasterizationProperties.degenerateTrianglesRasterized)
2938 if (getIteration() != 0)
2940 log << tcu::TestLog::Message << "Triangles expected to be rasterized with at least one pixel of white color each" << tcu::TestLog::EndMessage;
2942 for (int rowNdx = 0; rowNdx < 3; ++rowNdx)
2943 for (int colNdx = 0; colNdx < 4; ++colNdx)
2945 referenceImage.setPixel(4 * (colNdx + 1), 4 * (rowNdx + 1), foregroundColor);
2947 // Allow implementations that need to be extra conservative with degenerate triangles,
2948 // which may cause extra coverage.
2949 if (resultImage.getPixel(4 * (colNdx + 1) - 1, 4 * (rowNdx + 1) - 1) == foregroundColor)
2950 referenceImage.setPixel(4 * (colNdx + 1) - 1, 4 * (rowNdx + 1) - 1, foregroundColor);
2951 if (resultImage.getPixel(4 * (colNdx + 1) - 1, 4 * (rowNdx + 1)) == foregroundColor)
2952 referenceImage.setPixel(4 * (colNdx + 1) - 1, 4 * (rowNdx + 1), foregroundColor);
2953 if (resultImage.getPixel(4 * (colNdx + 1), 4 * (rowNdx + 1) - 1) == foregroundColor)
2954 referenceImage.setPixel(4 * (colNdx + 1), 4 * (rowNdx + 1) - 1, foregroundColor);
2958 log << tcu::TestLog::Message << "Triangles expected to be culled due to backfacing culling and all degenerate triangles assumed to be backfacing" << tcu::TestLog::EndMessage;
2961 log << tcu::TestLog::Message << "Triangles expected to be culled due to degenerateTrianglesRasterized=false" << tcu::TestLog::EndMessage;
2963 for (int y = 0; result && y < resultImage.getHeight(); ++y)
2964 for (int x = 0; result && x < resultImage.getWidth(); ++x)
2966 if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
2976 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
2978 for (int y = 0; y < errorMask.getHeight(); ++y)
2979 for (int x = 0; x < errorMask.getWidth(); ++x)
2981 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
2982 errorMask.setPixel(x, y, unexpectedPixelColor);
2984 errorMask.setPixel(x, y, backgroundColor);
2987 log << tcu::TestLog::Message << "Invalid pixels found for mode '" << iterationComments[getIteration()] << "'"
2988 << tcu::TestLog::EndMessage;
2989 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
2990 << tcu::TestLog::Image("Result", "Result", resultImage)
2991 << tcu::TestLog::Image("Reference", "Reference", referenceImage)
2992 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
2993 << tcu::TestLog::EndImageSet;
2997 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
2998 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
2999 << tcu::TestLog::Image("Result", "Result", resultImage)
3000 << tcu::TestLog::EndImageSet;
3006 bool ConservativeTraingleTestInstance::compareAndVerifyUnderestimatedNormal (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage)
3008 DE_UNREF(triangles);
3010 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
3011 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
3012 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
3013 const tcu::IVec2 viewportSize = tcu::IVec2(resultImage.getWidth(), resultImage.getHeight());
3014 tcu::TestLog& log = m_context.getTestContext().getLog();
3017 deUint32 errValue = 0;
3018 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
3021 DE_ASSERT(resultImage.getHeight() == resultImage.getWidth());
3023 for (int y = 0; y < resultImage.getHeight(); ++y)
3024 for (int x = 0; x < resultImage.getWidth(); ++x)
3025 referenceImage.setPixel(x, y, backgroundColor);
3027 for (size_t triangleNdx = 0; triangleNdx < triangles.size(); ++triangleNdx)
3029 const tcu::Vec4& p0 = triangles[triangleNdx].positions[0];
3030 const tcu::Vec4& p1 = triangles[triangleNdx].positions[1];
3031 const tcu::Vec4& p2 = triangles[triangleNdx].positions[2];
3033 for (int y = 0; y < resultImage.getHeight(); ++y)
3034 for (int x = 0; x < resultImage.getWidth(); ++x)
3036 if (calculateUnderestimateTriangleCoverage(p0, p1, p2, tcu::IVec2(x,y), m_subpixelBits, viewportSize) == tcu::COVERAGE_FULL)
3037 referenceImage.setPixel(x, y, foregroundColor);
3041 for (int y = 0; result && y < resultImage.getHeight(); ++y)
3042 for (int x = 0; result && x < resultImage.getWidth(); ++x)
3043 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
3048 errValue = resultImage.getPixel(x,y).getPacked();
3053 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
3055 for (int y = 0; y < errorMask.getHeight(); ++y)
3056 for (int x = 0; x < errorMask.getWidth(); ++x)
3058 if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
3059 errorMask.setPixel(x, y, unexpectedPixelColor);
3061 errorMask.setPixel(x, y, backgroundColor);
3064 log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
3065 << tcu::TestLog::EndMessage;
3066 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3067 << tcu::TestLog::Image("Result", "Result", resultImage)
3068 << tcu::TestLog::Image("Refernce", "Refernce", referenceImage)
3069 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
3070 << tcu::TestLog::EndImageSet;
3074 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
3075 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3076 << tcu::TestLog::Image("Result", "Result", resultImage)
3077 << tcu::TestLog::EndImageSet;
3083 bool ConservativeTraingleTestInstance::compareAndVerifyUnderestimatedDegenerate (std::vector<TriangleSceneSpec::SceneTriangle>& triangles, tcu::Surface& resultImage)
3085 DE_UNREF(triangles);
3087 const char* iterationComments[] = { "Cull back face triangles", "Cull front face triangles", "Cull none" };
3088 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
3089 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
3090 tcu::TestLog& log = m_context.getTestContext().getLog();
3093 deUint32 errValue = 0;
3096 if (m_conservativeRasterizationProperties.degenerateTrianglesRasterized)
3098 if (getIteration() != 0)
3099 log << tcu::TestLog::Message << "Triangles expected to be not rendered due to no one triangle can fully cover fragment" << tcu::TestLog::EndMessage;
3101 log << tcu::TestLog::Message << "Triangles expected to be culled due to backfacing culling and all degenerate triangles assumed to be backfacing" << tcu::TestLog::EndMessage;
3104 log << tcu::TestLog::Message << "Triangles expected to be culled due to degenerateTrianglesRasterized=false" << tcu::TestLog::EndMessage;
3106 for (int y = 0; result && y < resultImage.getHeight(); ++y)
3107 for (int x = 0; result && x < resultImage.getWidth(); ++x)
3109 if (resultImage.getPixel(x, y).getPacked() != backgroundColor.getPacked())
3114 errValue = resultImage.getPixel(x,y).getPacked();
3122 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
3123 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
3125 for (int y = 0; y < resultImage.getHeight(); ++y)
3126 for (int x = 0; x < resultImage.getWidth(); ++x)
3127 referenceImage.setPixel(x, y, backgroundColor);
3129 for (int y = 0; y < errorMask.getHeight(); ++y)
3130 for (int x = 0; x < errorMask.getWidth(); ++x)
3132 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
3133 errorMask.setPixel(x, y, unexpectedPixelColor);
3135 errorMask.setPixel(x, y, backgroundColor);
3138 log << tcu::TestLog::Message << "Invalid pixels found for mode '" << iterationComments[getIteration()] << "' starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
3139 << tcu::TestLog::EndMessage;
3141 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3142 << tcu::TestLog::Image("Result", "Result", resultImage)
3143 << tcu::TestLog::Image("Reference", "Reference", referenceImage)
3144 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
3145 << tcu::TestLog::EndImageSet;
3149 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
3150 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3151 << tcu::TestLog::Image("Result", "Result", resultImage)
3152 << tcu::TestLog::EndImageSet;
3158 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> ConservativeTraingleTestInstance::initRasterizationConservativeStateCreateInfo (void)
3160 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
3161 std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> result;
3163 result.reserve(getIterationCount());
3165 for (int iteration = 0; iteration < getIterationCount(); ++iteration)
3167 const VkPipelineRasterizationConservativeStateCreateInfoEXT rasterizationConservativeStateCreateInfo =
3169 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
3170 DE_NULL, // const void* pNext;
3171 (VkPipelineRasterizationConservativeStateCreateFlagsEXT)0, // VkPipelineRasterizationConservativeStateCreateFlagsEXT flags;
3172 m_conservativeTestConfig.conservativeRasterizationMode, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
3173 extraOverestimationSize // float extraPrimitiveOverestimationSize;
3176 result.push_back(rasterizationConservativeStateCreateInfo);
3182 const std::vector<VkPipelineRasterizationStateCreateInfo> ConservativeTraingleTestInstance::initRasterizationStateCreateInfo (void)
3184 std::vector<VkPipelineRasterizationStateCreateInfo> result;
3186 result.reserve(getIterationCount());
3188 for (int iteration = 0; iteration < getIterationCount(); ++iteration)
3190 const VkCullModeFlags cullModeFlags = (!m_conservativeTestConfig.degeneratePrimitives) ? VK_CULL_MODE_NONE
3191 : (iteration == 0) ? VK_CULL_MODE_BACK_BIT
3192 : (iteration == 1) ? VK_CULL_MODE_FRONT_BIT
3193 : VK_CULL_MODE_NONE;
3195 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
3197 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
3198 &m_rasterizationConservativeStateCreateInfo[iteration], // const void* pNext;
3199 0, // VkPipelineRasterizationStateCreateFlags flags;
3200 false, // VkBool32 depthClampEnable;
3201 false, // VkBool32 rasterizerDiscardEnable;
3202 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
3203 cullModeFlags, // VkCullModeFlags cullMode;
3204 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
3205 VK_FALSE, // VkBool32 depthBiasEnable;
3206 0.0f, // float depthBiasConstantFactor;
3207 0.0f, // float depthBiasClamp;
3208 0.0f, // float depthBiasSlopeFactor;
3209 getLineWidth(), // float lineWidth;
3212 result.push_back(rasterizationStateCreateInfo);
3218 const VkPipelineRasterizationStateCreateInfo* ConservativeTraingleTestInstance::getRasterizationStateCreateInfo (void) const
3220 return &m_rasterizationStateCreateInfo[getIteration()];
3223 const VkPipelineRasterizationLineStateCreateInfoEXT* ConservativeTraingleTestInstance::getLineRasterizationStateCreateInfo (void)
3229 class ConservativeLineTestInstance : public BaseLineTestInstance
3232 ConservativeLineTestInstance (Context& context,
3233 ConservativeTestConfig conservativeTestConfig,
3234 VkSampleCountFlagBits sampleCount);
3236 void generateLines (int iteration,
3237 std::vector<tcu::Vec4>& outData,
3238 std::vector<LineSceneSpec::SceneLine>& outLines);
3239 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
3242 virtual const VkPipelineRasterizationLineStateCreateInfoEXT* getLineRasterizationStateCreateInfo (void);
3244 virtual bool compareAndVerify (std::vector<LineSceneSpec::SceneLine>& lines,
3245 tcu::Surface& resultImage,
3246 std::vector<tcu::Vec4>& drawBuffer);
3247 virtual bool compareAndVerifyOverestimatedNormal (std::vector<LineSceneSpec::SceneLine>& lines,
3248 tcu::Surface& resultImage);
3249 virtual bool compareAndVerifyOverestimatedDegenerate (std::vector<LineSceneSpec::SceneLine>& lines,
3250 tcu::Surface& resultImage);
3251 virtual bool compareAndVerifyUnderestimatedNormal (std::vector<LineSceneSpec::SceneLine>& lines,
3252 tcu::Surface& resultImage);
3253 virtual bool compareAndVerifyUnderestimatedDegenerate (std::vector<LineSceneSpec::SceneLine>& lines,
3254 tcu::Surface& resultImage);
3255 void generateNormalLines (int iteration,
3256 std::vector<tcu::Vec4>& outData,
3257 std::vector<LineSceneSpec::SceneLine>& outLines);
3258 void generateDegenerateLines (int iteration,
3259 std::vector<tcu::Vec4>& outData,
3260 std::vector<LineSceneSpec::SceneLine>& outLines);
3261 void drawPrimitives (tcu::Surface& result,
3262 const std::vector<tcu::Vec4>& vertexData,
3263 VkPrimitiveTopology primitiveTopology);
3266 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> initRasterizationConservativeStateCreateInfo (void);
3267 const std::vector<VkPipelineRasterizationStateCreateInfo> initRasterizationStateCreateInfo (void);
3269 const ConservativeTestConfig m_conservativeTestConfig;
3270 const VkPhysicalDeviceConservativeRasterizationPropertiesEXT m_conservativeRasterizationProperties;
3271 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> m_rasterizationConservativeStateCreateInfo;
3272 const std::vector<VkPipelineRasterizationStateCreateInfo> m_rasterizationStateCreateInfo;
3275 ConservativeLineTestInstance::ConservativeLineTestInstance (Context& context,
3276 ConservativeTestConfig conservativeTestConfig,
3277 VkSampleCountFlagBits sampleCount)
3278 : BaseLineTestInstance (
3280 conservativeTestConfig.primitiveTopology,
3281 PRIMITIVEWIDENESS_NARROW,
3282 PRIMITIVESTRICTNESS_IGNORE,
3284 LINESTIPPLE_DISABLED,
3285 VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT,
3287 conservativeTestConfig.resolution,
3288 conservativeTestConfig.lineWidth
3290 , m_conservativeTestConfig (conservativeTestConfig)
3291 , m_conservativeRasterizationProperties (context.getConservativeRasterizationPropertiesEXT())
3292 , m_rasterizationConservativeStateCreateInfo (initRasterizationConservativeStateCreateInfo())
3293 , m_rasterizationStateCreateInfo (initRasterizationStateCreateInfo())
3297 void ConservativeLineTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
3299 if (m_conservativeTestConfig.degeneratePrimitives)
3300 generateDegenerateLines(iteration, outData, outLines);
3302 generateNormalLines(iteration, outData, outLines);
3305 void ConservativeLineTestInstance::generateNormalLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
3307 const char* iterationComment = "";
3308 const float halfPixel = 1.0f / float(m_renderSize);
3309 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
3310 const float overestimate = 2.0f * halfPixel * (m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize);
3311 const float overestimateMargin = overestimate;
3312 const float underestimateMargin = 0.0f;
3313 const bool isOverestimate = m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
3314 const float margin = isOverestimate ? overestimateMargin : underestimateMargin;
3315 const float edge = 4 * halfPixel + margin;
3316 const float left = -1.0f + edge;
3317 const float right = +1.0f - edge;
3318 const float up = -1.0f + edge;
3319 const float down = +1.0f - edge;
3325 const char* iterationComments[] = { "Horizontal up line", "Vertical line", "Horizontal down line" };
3327 iterationComment = iterationComments[iteration];
3333 outData.push_back(tcu::Vec4( left, up + halfPixel, 0.0f, 1.0f));
3334 outData.push_back(tcu::Vec4( right, up + halfPixel, 0.0f, 1.0f));
3341 outData.push_back(tcu::Vec4( left + halfPixel, up, 0.0f, 1.0f));
3342 outData.push_back(tcu::Vec4( left + halfPixel, down, 0.0f, 1.0f));
3349 outData.push_back(tcu::Vec4( left, down - halfPixel, 0.0f, 1.0f));
3350 outData.push_back(tcu::Vec4( right, down - halfPixel, 0.0f, 1.0f));
3356 TCU_THROW(InternalError, "Unexpected iteration");
3361 const char* iterationComments[] = { "Horizontal lines", "Vertical lines", "Diagonal lines" };
3362 const deUint32 subPixels = 1u << m_subpixelBits;
3363 const float subPixelSize = 2.0f * halfPixel / float(subPixels);
3364 const float blockStep = 16.0f * 2.0f * halfPixel;
3365 const float lineWidth = 2.0f * halfPixel * getLineWidth();
3366 const float offsets[] =
3368 float(1) * blockStep,
3369 float(2) * blockStep + halfPixel,
3370 float(3) * blockStep + 0.5f * lineWidth + 2.0f * subPixelSize,
3371 float(4) * blockStep + 0.5f * lineWidth - 2.0f * subPixelSize,
3374 iterationComment = iterationComments[iteration];
3376 outData.reserve(DE_LENGTH_OF_ARRAY(offsets));
3382 for (size_t lineNdx = 0; lineNdx < DE_LENGTH_OF_ARRAY(offsets); ++lineNdx)
3384 outData.push_back(tcu::Vec4( left + halfPixel, up + offsets[lineNdx], 0.0f, 1.0f));
3385 outData.push_back(tcu::Vec4(right - halfPixel, up + offsets[lineNdx], 0.0f, 1.0f));
3393 for (size_t lineNdx = 0; lineNdx < DE_LENGTH_OF_ARRAY(offsets); ++lineNdx)
3395 outData.push_back(tcu::Vec4(left + offsets[lineNdx], up + halfPixel, 0.0f, 1.0f));
3396 outData.push_back(tcu::Vec4(left + offsets[lineNdx], down - halfPixel, 0.0f, 1.0f));
3404 for (size_t lineNdx = 0; lineNdx < DE_LENGTH_OF_ARRAY(offsets); ++lineNdx)
3406 outData.push_back(tcu::Vec4(left + offsets[lineNdx], up + halfPixel, 0.0f, 1.0f));
3407 outData.push_back(tcu::Vec4( right - halfPixel, down - offsets[lineNdx], 0.0f, 1.0f));
3414 TCU_THROW(InternalError, "Unexpected iteration");
3418 DE_ASSERT(outData.size() % 2 == 0);
3419 outLines.resize(outData.size() / 2);
3420 for(size_t lineNdx = 0; lineNdx < outLines.size(); ++lineNdx)
3422 outLines[lineNdx].positions[0] = outData[2 * lineNdx + 0];
3423 outLines[lineNdx].positions[1] = outData[2 * lineNdx + 1];
3427 m_context.getTestContext().getLog()
3428 << tcu::TestLog::Message
3429 << "Testing " << iterationComment << " "
3430 << "with rendering " << outLines.size() << " line(s):"
3431 << tcu::TestLog::EndMessage;
3433 for (int ndx = 0; ndx < (int)outLines.size(); ++ndx)
3435 const deUint32 multiplier = m_renderSize / 2;
3437 m_context.getTestContext().getLog()
3438 << tcu::TestLog::Message
3439 << "Line " << (ndx+1) << ":"
3440 << "\n\t" << outLines[ndx].positions[0] << " == " << (float(multiplier) * outLines[ndx].positions[0]) << "/" << multiplier
3441 << "\n\t" << outLines[ndx].positions[1] << " == " << (float(multiplier) * outLines[ndx].positions[1]) << "/" << multiplier
3442 << tcu::TestLog::EndMessage;
3446 void ConservativeLineTestInstance::generateDegenerateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
3448 const bool isOverestimate = m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
3449 const float pixelSize = 2.0f / float(m_renderSize);
3450 const deUint32 subPixels = 1u << m_context.getDeviceProperties().limits.subPixelPrecisionBits;
3451 const float subPixelSize = pixelSize / float(subPixels);
3452 const char* iterationComments[] = { "Horizontal line", "Vertical line", "Diagonal line" };
3458 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
3459 const float totalOverestimate = m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize;
3460 const float totalOverestimateInSubPixels = deFloatCeil(totalOverestimate * float(subPixels));
3461 const float overestimate = subPixelSize * totalOverestimateInSubPixels;
3462 const float overestimateSafetyMargin = subPixelSize * 0.125f;
3463 const float margin = overestimate + overestimateSafetyMargin;
3464 const float originOffset = -1.0f + 1 * pixelSize;
3465 const float originLeft = originOffset + margin;
3466 const float originRight = originOffset + margin + 0.25f * subPixelSize;
3467 const float originUp = originOffset + margin;
3468 const float originDown = originOffset + margin + 0.25f * subPixelSize;
3474 outData.push_back(tcu::Vec4( originLeft, originUp, 0.0f, 1.0f));
3475 outData.push_back(tcu::Vec4(originRight, originUp, 0.0f, 1.0f));
3482 outData.push_back(tcu::Vec4( originLeft, originUp, 0.0f, 1.0f));
3483 outData.push_back(tcu::Vec4( originLeft, originDown, 0.0f, 1.0f));
3490 outData.push_back(tcu::Vec4( originLeft, originUp, 0.0f, 1.0f));
3491 outData.push_back(tcu::Vec4(originRight, originDown, 0.0f, 1.0f));
3497 TCU_THROW(InternalError, "Unexpected iteration");
3502 size_t rowStart = 3 * getIteration();
3503 size_t rowEnd = 3 * (getIteration() + 1);
3505 for (size_t rowNdx = rowStart; rowNdx < rowEnd; ++rowNdx)
3506 for (size_t colNdx = 0; colNdx < 3 * 3; ++colNdx)
3508 const float originOffsetY = -1.0f + float(4 * (1 + rowNdx)) * pixelSize;
3509 const float originOffsetX = -1.0f + float(4 * (1 + colNdx)) * pixelSize;
3510 const float x0 = float(rowNdx % 3);
3511 const float y0 = float(rowNdx / 3);
3512 const float x1 = float(colNdx % 3);
3513 const float y1 = float(colNdx / 3);
3514 const tcu::Vec4 p0 = tcu::Vec4(originOffsetX + x0 * pixelSize / 2.0f, originOffsetY + y0 * pixelSize / 2.0f, 0.0f, 1.0f);
3515 const tcu::Vec4 p1 = tcu::Vec4(originOffsetX + x1 * pixelSize / 2.0f, originOffsetY + y1 * pixelSize / 2.0f, 0.0f, 1.0f);
3517 if (x0 == x1 && y0 == y1)
3520 outData.push_back(p0);
3521 outData.push_back(p1);
3525 outLines.resize(outData.size() / 2);
3527 for (size_t ndx = 0; ndx < outLines.size(); ++ndx)
3529 outLines[ndx].positions[0] = outData[2 * ndx + 0];
3530 outLines[ndx].positions[1] = outData[2 * ndx + 1];
3534 m_context.getTestContext().getLog()
3535 << tcu::TestLog::Message
3536 << "Testing " << iterationComments[iteration] << " "
3537 << "with rendering " << outLines.size() << " line(s):"
3538 << tcu::TestLog::EndMessage;
3540 for (int ndx = 0; ndx < (int)outLines.size(); ++ndx)
3542 const deUint32 multiplierInt = m_renderSize / 2;
3543 const deUint32 multiplierFrac = subPixels;
3544 std::string coordsString;
3546 for (size_t vertexNdx = 0; vertexNdx < 2; ++vertexNdx)
3548 const tcu::Vec4& pos = outLines[ndx].positions[vertexNdx];
3549 std::ostringstream coordsFloat;
3550 std::ostringstream coordsNatural;
3552 for (int coordNdx = 0; coordNdx < 2; ++coordNdx)
3554 const char* sep = (coordNdx < 1) ? "," : "";
3555 const float coord = pos[coordNdx];
3556 const char sign = deSign(coord) < 0 ? '-' : '+';
3557 const float m = deFloatFloor(float(multiplierInt) * deFloatAbs(coord));
3558 const float r = deFloatFrac(float(multiplierInt) * deFloatAbs(coord)) * float(multiplierFrac);
3560 coordsFloat << std::fixed << std::setw(13) << std::setprecision(10) << coord << sep;
3561 coordsNatural << sign << '(' << m << '+' << r << '/' << multiplierFrac << ')' << sep;
3564 coordsString += "\n\t[" + coordsFloat.str() + "] == [" + coordsNatural.str() + "] / " + de::toString(multiplierInt);
3567 m_context.getTestContext().getLog()
3568 << tcu::TestLog::Message
3569 << "Line " << (ndx + 1) << ':'
3571 << tcu::TestLog::EndMessage;
3575 void ConservativeLineTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology)
3577 if (m_conservativeTestConfig.degeneratePrimitives)
3579 // Set provoking vertex color to white
3580 tcu::Vec4 colorProvoking (1.0f, 1.0f, 1.0f, 1.0f);
3581 tcu::Vec4 colorOther (0.0f, 1.0f, 1.0f, 1.0f);
3582 std::vector<tcu::Vec4> colorData;
3584 colorData.reserve(vertexData.size());
3586 for (size_t vertexNdx = 0; vertexNdx < vertexData.size(); ++vertexNdx)
3587 if (vertexNdx % 2 == 0)
3588 colorData.push_back(colorProvoking);
3590 colorData.push_back(colorOther);
3592 BaseRenderingTestInstance::drawPrimitives(result, vertexData, colorData, primitiveTopology);
3595 BaseRenderingTestInstance::drawPrimitives(result, vertexData, primitiveTopology);
3598 bool ConservativeLineTestInstance::compareAndVerify (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage, std::vector<tcu::Vec4>& drawBuffer)
3600 DE_UNREF(drawBuffer);
3602 switch (m_conservativeTestConfig.conservativeRasterizationMode)
3604 case VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT:
3606 if (m_conservativeTestConfig.degeneratePrimitives)
3607 return compareAndVerifyOverestimatedDegenerate(lines, resultImage);
3609 return compareAndVerifyOverestimatedNormal(lines, resultImage);
3613 case VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT:
3615 if (m_conservativeTestConfig.degeneratePrimitives)
3616 return compareAndVerifyUnderestimatedDegenerate(lines, resultImage);
3618 return compareAndVerifyUnderestimatedNormal(lines, resultImage);
3624 TCU_THROW(InternalError, "Unknown conservative rasterization mode");
3628 bool ConservativeLineTestInstance::compareAndVerifyOverestimatedNormal (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage)
3632 const int b = 3; // bar width
3633 const int w = resultImage.getWidth() - 1;
3634 const int h = resultImage.getHeight() - 1;
3635 const int xStarts[] = { 1, 1, 1 };
3636 const int xEnds[] = { w - 1, b, w - 1 };
3637 const int yStarts[] = { 1, 1, h - b };
3638 const int yEnds[] = { b, h - 1, h - 1 };
3639 const int xStart = xStarts[getIteration()];
3640 const int xEnd = xEnds[getIteration()];
3641 const int yStart = yStarts[getIteration()];
3642 const int yEnd = yEnds[getIteration()];
3643 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
3644 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
3645 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
3646 tcu::TestLog& log = m_context.getTestContext().getLog();
3649 deUint32 errValue = 0;
3652 DE_ASSERT(resultImage.getHeight() == resultImage.getWidth());
3654 for (int y = yStart; result && y < yEnd; ++y)
3655 for (int x = xStart; result && x < xEnd; ++x)
3657 if (resultImage.getPixel(x,y).getPacked() != foregroundColor.getPacked())
3662 errValue = resultImage.getPixel(x,y).getPacked();
3670 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
3672 for (int y = 0; y < errorMask.getHeight(); ++y)
3673 for (int x = 0; x < errorMask.getWidth(); ++x)
3674 errorMask.setPixel(x, y, backgroundColor);
3676 for (int y = yStart; y < yEnd; ++y)
3677 for (int x = xStart; x < xEnd; ++x)
3679 if (resultImage.getPixel(x,y).getPacked() != foregroundColor.getPacked())
3680 errorMask.setPixel(x,y, unexpectedPixelColor);
3683 log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
3684 << tcu::TestLog::EndMessage;
3685 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3686 << tcu::TestLog::Image("Result", "Result", resultImage)
3687 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
3688 << tcu::TestLog::EndImageSet;
3692 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
3693 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3694 << tcu::TestLog::Image("Result", "Result", resultImage)
3695 << tcu::TestLog::EndImageSet;
3701 bool ConservativeLineTestInstance::compareAndVerifyOverestimatedDegenerate (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage)
3705 const char* iterationComments[] = { "Horizontal line", "Vertical line", "Diagonal line" };
3706 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
3707 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
3708 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
3709 tcu::TestLog& log = m_context.getTestContext().getLog();
3711 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
3713 for (int y = 0; y < resultImage.getHeight(); ++y)
3714 for (int x = 0; x < resultImage.getWidth(); ++x)
3715 referenceImage.setPixel(x, y, backgroundColor);
3717 if (m_conservativeRasterizationProperties.degenerateLinesRasterized)
3719 log << tcu::TestLog::Message << "Lines expected to be rasterized with white color" << tcu::TestLog::EndMessage;
3721 // This pixel will alway be covered due to the placement of the line.
3722 referenceImage.setPixel(1, 1, foregroundColor);
3724 // Additional pixels will be covered based on the extra bloat added to the primitive.
3725 const float extraOverestimation = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
3726 const int xExtent = 1 + int((extraOverestimation * 2.0f) + 0.5f);
3727 const int yExtent = xExtent;
3729 for (int y = 0; y <= yExtent; ++y)
3730 for (int x = 0; x <= xExtent; ++x)
3731 referenceImage.setPixel(x, y, foregroundColor);
3734 log << tcu::TestLog::Message << "Lines expected to be culled" << tcu::TestLog::EndMessage;
3736 for (int y = 0; result && y < resultImage.getHeight(); ++y)
3737 for (int x = 0; result && x < resultImage.getWidth(); ++x)
3739 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
3749 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
3751 for (int y = 0; y < errorMask.getHeight(); ++y)
3752 for (int x = 0; x < errorMask.getWidth(); ++x)
3754 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
3755 errorMask.setPixel(x, y, unexpectedPixelColor);
3757 errorMask.setPixel(x, y, backgroundColor);
3760 log << tcu::TestLog::Message << "Invalid pixels found for mode " << iterationComments[getIteration()]
3761 << tcu::TestLog::EndMessage;
3762 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3763 << tcu::TestLog::Image("Result", "Result", resultImage)
3764 << tcu::TestLog::Image("Reference", "Reference", referenceImage)
3765 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
3766 << tcu::TestLog::EndImageSet;
3770 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
3771 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3772 << tcu::TestLog::Image("Result", "Result", resultImage)
3773 << tcu::TestLog::EndImageSet;
3779 bool ConservativeLineTestInstance::compareAndVerifyUnderestimatedNormal (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage)
3783 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
3784 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
3785 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
3786 tcu::TestLog& log = m_context.getTestContext().getLog();
3791 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
3793 DE_ASSERT(resultImage.getHeight() == resultImage.getWidth());
3795 for (int y = 0; y < referenceImage.getHeight(); ++y)
3796 for (int x = 0; x < referenceImage.getWidth(); ++x)
3797 referenceImage.setPixel(x, y, backgroundColor);
3799 if (getLineWidth() > 1.0f)
3801 const tcu::IVec2 viewportSize(resultImage.getWidth(), resultImage.getHeight());
3803 for (size_t lineNdx = 0; lineNdx < lines.size(); ++lineNdx)
3804 for (int y = 0; y < resultImage.getHeight(); ++y)
3805 for (int x = 0; x < resultImage.getWidth(); ++x)
3807 if (calculateUnderestimateLineCoverage(lines[lineNdx].positions[0], lines[lineNdx].positions[1], getLineWidth(), tcu::IVec2(x,y), viewportSize) == tcu::COVERAGE_FULL)
3808 referenceImage.setPixel(x, y, foregroundColor);
3812 for (int y = 0; result && y < resultImage.getHeight(); ++y)
3813 for (int x = 0; result && x < resultImage.getWidth(); ++x)
3815 if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
3820 errValue = resultImage.getPixel(x,y);
3828 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
3830 for (int y = 0; y < errorMask.getHeight(); ++y)
3831 for (int x = 0; x < errorMask.getWidth(); ++x)
3832 errorMask.setPixel(x, y, backgroundColor);
3834 for (int y = 0; y < errorMask.getHeight(); ++y)
3835 for (int x = 0; x < errorMask.getWidth(); ++x)
3837 if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
3838 errorMask.setPixel(x, y, unexpectedPixelColor);
3841 log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " errValue=" << errValue
3842 << tcu::TestLog::EndMessage;
3843 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3844 << tcu::TestLog::Image("Result", "Result", resultImage)
3845 << tcu::TestLog::Image("Reference", "Reference", referenceImage)
3846 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
3847 << tcu::TestLog::EndImageSet;
3851 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
3852 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3853 << tcu::TestLog::Image("Result", "Result", resultImage)
3854 << tcu::TestLog::EndImageSet;
3860 bool ConservativeLineTestInstance::compareAndVerifyUnderestimatedDegenerate (std::vector<LineSceneSpec::SceneLine>& lines, tcu::Surface& resultImage)
3864 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
3865 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
3866 tcu::TestLog& log = m_context.getTestContext().getLog();
3868 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
3870 for (int y = 0; y < resultImage.getHeight(); ++y)
3871 for (int x = 0; x < resultImage.getWidth(); ++x)
3872 referenceImage.setPixel(x, y, backgroundColor);
3874 log << tcu::TestLog::Message << "No lines expected to be rasterized" << tcu::TestLog::EndMessage;
3876 for (int y = 0; result && y < resultImage.getHeight(); ++y)
3877 for (int x = 0; result && x < resultImage.getWidth(); ++x)
3879 if (resultImage.getPixel(x,y).getPacked() != referenceImage.getPixel(x,y).getPacked())
3889 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
3891 for (int y = 0; y < errorMask.getHeight(); ++y)
3892 for (int x = 0; x < errorMask.getWidth(); ++x)
3894 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
3895 errorMask.setPixel(x, y, unexpectedPixelColor);
3897 errorMask.setPixel(x, y, backgroundColor);
3900 log << tcu::TestLog::Message << "Invalid pixels found" << tcu::TestLog::EndMessage;
3901 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3902 << tcu::TestLog::Image("Result", "Result", resultImage)
3903 << tcu::TestLog::Image("Reference", "Reference", referenceImage)
3904 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
3905 << tcu::TestLog::EndImageSet;
3909 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
3910 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
3911 << tcu::TestLog::Image("Result", "Result", resultImage)
3912 << tcu::TestLog::EndImageSet;
3918 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> ConservativeLineTestInstance::initRasterizationConservativeStateCreateInfo (void)
3920 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
3921 std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> result;
3923 result.reserve(getIterationCount());
3925 for (int iteration = 0; iteration < getIterationCount(); ++iteration)
3927 const VkPipelineRasterizationConservativeStateCreateInfoEXT rasterizationConservativeStateCreateInfo =
3929 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
3930 DE_NULL, // const void* pNext;
3931 (VkPipelineRasterizationConservativeStateCreateFlagsEXT)0, // VkPipelineRasterizationConservativeStateCreateFlagsEXT flags;
3932 m_conservativeTestConfig.conservativeRasterizationMode, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
3933 extraOverestimationSize // float extraPrimitiveOverestimationSize;
3936 result.push_back(rasterizationConservativeStateCreateInfo);
3942 const std::vector<VkPipelineRasterizationStateCreateInfo> ConservativeLineTestInstance::initRasterizationStateCreateInfo (void)
3944 std::vector<VkPipelineRasterizationStateCreateInfo> result;
3946 result.reserve(getIterationCount());
3948 for (int iteration = 0; iteration < getIterationCount(); ++iteration)
3950 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
3952 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
3953 &m_rasterizationConservativeStateCreateInfo[iteration], // const void* pNext;
3954 0, // VkPipelineRasterizationStateCreateFlags flags;
3955 false, // VkBool32 depthClampEnable;
3956 false, // VkBool32 rasterizerDiscardEnable;
3957 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
3958 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
3959 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
3960 VK_FALSE, // VkBool32 depthBiasEnable;
3961 0.0f, // float depthBiasConstantFactor;
3962 0.0f, // float depthBiasClamp;
3963 0.0f, // float depthBiasSlopeFactor;
3964 getLineWidth(), // float lineWidth;
3967 result.push_back(rasterizationStateCreateInfo);
3973 const VkPipelineRasterizationStateCreateInfo* ConservativeLineTestInstance::getRasterizationStateCreateInfo (void) const
3975 return &m_rasterizationStateCreateInfo[getIteration()];
3978 const VkPipelineRasterizationLineStateCreateInfoEXT* ConservativeLineTestInstance::getLineRasterizationStateCreateInfo (void)
3984 class ConservativePointTestInstance : public PointTestInstance
3987 ConservativePointTestInstance (Context& context,
3988 ConservativeTestConfig conservativeTestConfig,
3989 VkSampleCountFlagBits sampleCount)
3990 : PointTestInstance (
3992 PRIMITIVEWIDENESS_NARROW,
3993 PRIMITIVESTRICTNESS_IGNORE,
3995 LINESTIPPLE_DISABLED,
3996 VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT,
3998 conservativeTestConfig.resolution,
3999 conservativeTestConfig.lineWidth
4001 , m_conservativeTestConfig (conservativeTestConfig)
4002 , m_conservativeRasterizationProperties (context.getConservativeRasterizationPropertiesEXT())
4003 , m_rasterizationConservativeStateCreateInfo (initRasterizationConservativeStateCreateInfo())
4004 , m_rasterizationStateCreateInfo (initRasterizationStateCreateInfo())
4009 void generatePoints (int iteration,
4010 std::vector<tcu::Vec4>& outData,
4011 std::vector<PointSceneSpec::ScenePoint>& outPoints);
4012 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
4015 virtual const VkPipelineRasterizationLineStateCreateInfoEXT* getLineRasterizationStateCreateInfo (void);
4017 virtual bool compareAndVerify (std::vector<PointSceneSpec::ScenePoint>& points,
4018 tcu::Surface& resultImage,
4019 std::vector<tcu::Vec4>& drawBuffer);
4020 virtual bool compareAndVerifyOverestimated (std::vector<PointSceneSpec::ScenePoint>& points,
4021 tcu::Surface& resultImage);
4022 virtual bool compareAndVerifyUnderestimated (std::vector<PointSceneSpec::ScenePoint>& points,
4023 tcu::Surface& resultImage);
4026 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> initRasterizationConservativeStateCreateInfo (void);
4027 const std::vector<VkPipelineRasterizationStateCreateInfo> initRasterizationStateCreateInfo (void);
4029 const ConservativeTestConfig m_conservativeTestConfig;
4030 const VkPhysicalDeviceConservativeRasterizationPropertiesEXT m_conservativeRasterizationProperties;
4031 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> m_rasterizationConservativeStateCreateInfo;
4032 const std::vector<VkPipelineRasterizationStateCreateInfo> m_rasterizationStateCreateInfo;
4033 std::vector<int> m_renderStart;
4034 std::vector<int> m_renderEnd;
4037 void ConservativePointTestInstance::generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints)
4039 const float pixelSize = 2.0f / float(m_renderSize);
4040 const bool isOverestimate = m_conservativeTestConfig.conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT;
4042 m_renderStart.clear();
4043 m_renderEnd.clear();
4047 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
4048 const float overestimate = m_conservativeRasterizationProperties.primitiveOverestimationSize + extraOverestimationSize;
4049 const float halfRenderAreaSize = overestimate + 0.5f;
4050 const float pointCenterOffset = 2.0f + 0.5f * float(iteration) + halfRenderAreaSize;
4051 const float pointEdgeStart = pointCenterOffset - halfRenderAreaSize;
4052 const float pointEdgeEnd = pointEdgeStart + 2 * halfRenderAreaSize;
4053 const int renderStart = int(deFloatFloor(pointEdgeStart)) + int((deFloatFrac(pointEdgeStart) > 0.0f) ? 0 : -1);
4054 const int renderEnd = int(deFloatCeil(pointEdgeEnd)) + int((deFloatFrac(pointEdgeEnd) > 0.0f) ? 0 : 1);
4056 outData.push_back(tcu::Vec4(-1.0f + pixelSize * pointCenterOffset, -1.0f + pixelSize * pointCenterOffset, 0.0f, 1.0f));
4058 m_renderStart.push_back(renderStart);
4059 m_renderEnd.push_back(renderEnd);
4063 const float pointSize = m_conservativeTestConfig.lineWidth;
4064 const float halfRenderAreaSize = pointSize / 2.0f;
4070 const float pointCenterOffset = (pointSize + 1.0f + deFloatFrac(pointSize)) / 2.0f;
4071 const float pointEdgeStart = pointCenterOffset - halfRenderAreaSize;
4072 const float pointEdgeEnd = pointEdgeStart + 2.0f * halfRenderAreaSize;
4073 const int renderStart = (m_renderSize / 2) + int(deFloatCeil(pointEdgeStart));
4074 const int renderEnd = (m_renderSize / 2) + int(deFloatFloor(pointEdgeEnd));
4076 outData.push_back(tcu::Vec4(pixelSize * pointCenterOffset, pixelSize * pointCenterOffset, 0.0f, 1.0f));
4078 m_renderStart.push_back(renderStart);
4079 m_renderEnd.push_back(renderEnd);
4086 const float subPixelSize = 1.0f / float(1u<<(m_subpixelBits - 1));
4087 const float pointBottomLeft = 1.0f - subPixelSize;
4088 const float pointCenterOffset = pointBottomLeft + pointSize / 2.0f;
4089 const float pointEdgeStart = pointCenterOffset - halfRenderAreaSize;
4090 const float pointEdgeEnd = pointEdgeStart + 2.0f * halfRenderAreaSize;
4091 const int renderStart = (m_renderSize / 2) + int(deFloatCeil(pointEdgeStart));
4092 const int renderEnd = (m_renderSize / 2) + int(deFloatFloor(pointEdgeEnd));
4094 outData.push_back(tcu::Vec4(pixelSize * pointCenterOffset, pixelSize * pointCenterOffset, 0.0f, 1.0f));
4096 m_renderStart.push_back(renderStart);
4097 m_renderEnd.push_back(renderEnd);
4104 // Edges of a point are considered not covered. Top-left coverage rule is not applicable for underestimate rasterization.
4105 const float pointCenterOffset = (pointSize + deFloatFrac(pointSize)) / 2.0f;
4106 const float pointEdgeStart = pointCenterOffset - halfRenderAreaSize;
4107 const float pointEdgeEnd = pointEdgeStart + 2.0f * halfRenderAreaSize;
4108 const int renderStart = (m_renderSize / 2) + int(deFloatCeil(pointEdgeStart)) + 1;
4109 const int renderEnd = (m_renderSize / 2) + int(deFloatFloor(pointEdgeEnd)) - 1;
4111 outData.push_back(tcu::Vec4(pixelSize * pointCenterOffset, pixelSize * pointCenterOffset, 0.0f, 1.0f));
4113 m_renderStart.push_back(renderStart);
4114 m_renderEnd.push_back(renderEnd);
4120 TCU_THROW(InternalError, "Unexpected iteration");
4124 outPoints.resize(outData.size());
4125 for (size_t ndx = 0; ndx < outPoints.size(); ++ndx)
4127 outPoints[ndx].position = outData[ndx];
4128 outPoints[ndx].pointSize = getPointSize();
4132 m_context.getTestContext().getLog()
4133 << tcu::TestLog::Message
4134 << "Testing conservative point rendering "
4135 << "with rendering " << outPoints.size() << " points(s):"
4136 << tcu::TestLog::EndMessage;
4137 for (int ndx = 0; ndx < (int)outPoints.size(); ++ndx)
4139 const deUint32 multiplier = m_renderSize / 2;
4141 m_context.getTestContext().getLog()
4142 << tcu::TestLog::Message
4143 << "Point " << (ndx+1) << ":"
4144 << "\n\t" << outPoints[ndx].position << " == " << (float(multiplier) * outPoints[ndx].position) << "/" << multiplier
4145 << tcu::TestLog::EndMessage;
4149 bool ConservativePointTestInstance::compareAndVerify (std::vector<PointSceneSpec::ScenePoint>& points, tcu::Surface& resultImage, std::vector<tcu::Vec4>& drawBuffer)
4151 DE_UNREF(drawBuffer);
4153 switch (m_conservativeTestConfig.conservativeRasterizationMode)
4155 case VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT:
4157 return compareAndVerifyOverestimated(points, resultImage);
4159 case VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT:
4161 return compareAndVerifyUnderestimated(points, resultImage);
4165 TCU_THROW(InternalError, "Unknown conservative rasterization mode");
4169 bool ConservativePointTestInstance::compareAndVerifyOverestimated (std::vector<PointSceneSpec::ScenePoint>& points, tcu::Surface& resultImage)
4173 const char* iterationComments[] = { "Edges and corners", "Partial coverage", "Edges and corners" };
4174 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
4175 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
4176 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
4177 tcu::TestLog& log = m_context.getTestContext().getLog();
4180 deUint32 errValue = 0;
4183 log << tcu::TestLog::Message << "Points expected to be rasterized with white color" << tcu::TestLog::EndMessage;
4184 log << tcu::TestLog::Message << "Testing " << iterationComments[getIteration()] << tcu::TestLog::EndMessage;
4186 for (size_t renderAreaNdx = 0; result && renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
4188 const int renderStart = m_renderStart[renderAreaNdx];
4189 const int renderEnd = m_renderEnd[renderAreaNdx];
4191 for (int y = renderStart; result && y < renderEnd; ++y)
4192 for (int x = renderStart; result && x < renderEnd; ++x)
4194 if (resultImage.getPixel(x,y).getPacked() != foregroundColor.getPacked())
4199 errValue = resultImage.getPixel(x, y).getPacked();
4208 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
4209 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
4210 std::ostringstream css;
4212 for (int y = 0; y < resultImage.getHeight(); ++y)
4213 for (int x = 0; x < resultImage.getWidth(); ++x)
4214 referenceImage.setPixel(x, y, backgroundColor);
4216 for (size_t renderAreaNdx = 0; renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
4218 const int renderStart = m_renderStart[renderAreaNdx];
4219 const int renderEnd = m_renderEnd[renderAreaNdx];
4221 for (int y = renderStart; y < renderEnd; ++y)
4222 for (int x = renderStart; x < renderEnd; ++x)
4223 referenceImage.setPixel(x, y, foregroundColor);
4226 for (int y = 0; y < errorMask.getHeight(); ++y)
4227 for (int x = 0; x < errorMask.getWidth(); ++x)
4229 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
4230 errorMask.setPixel(x, y, unexpectedPixelColor);
4232 errorMask.setPixel(x, y, backgroundColor);
4236 for (size_t renderAreaNdx = 0; renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
4238 const int renderStart = m_renderStart[renderAreaNdx];
4239 const int renderEnd = m_renderEnd[renderAreaNdx];
4241 css << "[" << renderStart << "," << renderEnd << ") x [" << renderStart << "," << renderEnd << ")" << std::endl;
4244 log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
4245 << tcu::TestLog::EndMessage;
4246 log << tcu::TestLog::Message << "Expected area(s) to be filled:" << css.str()
4247 << tcu::TestLog::EndMessage;
4248 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
4249 << tcu::TestLog::Image("Result", "Result", resultImage)
4250 << tcu::TestLog::Image("Reference", "Reference", referenceImage)
4251 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
4252 << tcu::TestLog::EndImageSet;
4256 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
4257 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
4258 << tcu::TestLog::Image("Result", "Result", resultImage)
4259 << tcu::TestLog::EndImageSet;
4265 bool ConservativePointTestInstance::compareAndVerifyUnderestimated (std::vector<PointSceneSpec::ScenePoint>& points, tcu::Surface& resultImage)
4269 const char* iterationComments[] = { "Full coverage", "Full coverage with subpixel", "Exact coverage" };
4270 const tcu::RGBA backgroundColor = tcu::RGBA(0, 0, 0, 255);
4271 const tcu::RGBA foregroundColor = tcu::RGBA(255, 255, 255, 255);
4272 const tcu::RGBA unexpectedPixelColor = tcu::RGBA(255, 0, 0, 255);
4273 tcu::TestLog& log = m_context.getTestContext().getLog();
4276 deUint32 errValue = 0;
4278 tcu::Surface referenceImage (resultImage.getWidth(), resultImage.getHeight());
4280 log << tcu::TestLog::Message << "Points expected to be rasterized with white color" << tcu::TestLog::EndMessage;
4281 log << tcu::TestLog::Message << "Testing " << iterationComments[getIteration()] << tcu::TestLog::EndMessage;
4283 for (int y = 0; y < resultImage.getHeight(); ++y)
4284 for (int x = 0; x < resultImage.getWidth(); ++x)
4285 referenceImage.setPixel(x, y, backgroundColor);
4287 for (size_t renderAreaNdx = 0; result && renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
4289 const int renderStart = m_renderStart[renderAreaNdx];
4290 const int renderEnd = m_renderEnd[renderAreaNdx];
4292 for (int y = renderStart; y < renderEnd; ++y)
4293 for (int x = renderStart; x < renderEnd; ++x)
4294 referenceImage.setPixel(x, y, foregroundColor);
4297 for (int y = 0; result && y < resultImage.getHeight(); ++y)
4298 for (int x = 0; result && x < resultImage.getWidth(); ++x)
4300 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
4305 errValue = resultImage.getPixel(x, y).getPacked();
4313 tcu::Surface errorMask (resultImage.getWidth(), resultImage.getHeight());
4314 std::ostringstream css;
4316 for (int y = 0; y < errorMask.getHeight(); ++y)
4317 for (int x = 0; x < errorMask.getWidth(); ++x)
4319 if (resultImage.getPixel(x, y).getPacked() != referenceImage.getPixel(x, y).getPacked())
4320 errorMask.setPixel(x, y, unexpectedPixelColor);
4322 errorMask.setPixel(x, y, backgroundColor);
4326 for (size_t renderAreaNdx = 0; renderAreaNdx < m_renderStart.size(); ++renderAreaNdx)
4328 const int renderStart = m_renderStart[renderAreaNdx];
4329 const int renderEnd = m_renderEnd[renderAreaNdx];
4331 css << "[" << renderStart << "," << renderEnd << ") x [" << renderStart << "," << renderEnd << ")" << std::endl;
4334 log << tcu::TestLog::Message << "Invalid pixels found starting at " << errX << "," << errY << " value=0x" << std::hex << errValue
4335 << tcu::TestLog::EndMessage;
4336 log << tcu::TestLog::Message << "Expected area(s) to be filled:" << css.str()
4337 << tcu::TestLog::EndMessage;
4338 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
4339 << tcu::TestLog::Image("Result", "Result", resultImage)
4340 << tcu::TestLog::Image("Reference", "Reference", referenceImage)
4341 << tcu::TestLog::Image("ErrorMask", "ErrorMask", errorMask)
4342 << tcu::TestLog::EndImageSet;
4346 log << tcu::TestLog::Message << "No invalid pixels found." << tcu::TestLog::EndMessage;
4347 log << tcu::TestLog::ImageSet("Verification result", "Result of rendering")
4348 << tcu::TestLog::Image("Result", "Result", resultImage)
4349 << tcu::TestLog::EndImageSet;
4355 const std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> ConservativePointTestInstance::initRasterizationConservativeStateCreateInfo (void)
4357 const float extraOverestimationSize = getExtraOverestimationSize(m_conservativeTestConfig.extraOverestimationSize, m_conservativeRasterizationProperties);
4358 std::vector<VkPipelineRasterizationConservativeStateCreateInfoEXT> result;
4360 result.reserve(getIterationCount());
4362 for (int iteration = 0; iteration < getIterationCount(); ++iteration)
4364 const VkPipelineRasterizationConservativeStateCreateInfoEXT rasterizationConservativeStateCreateInfo =
4366 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
4367 DE_NULL, // const void* pNext;
4368 (VkPipelineRasterizationConservativeStateCreateFlagsEXT)0, // VkPipelineRasterizationConservativeStateCreateFlagsEXT flags;
4369 m_conservativeTestConfig.conservativeRasterizationMode, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
4370 extraOverestimationSize // float extraPrimitiveOverestimationSize;
4373 result.push_back(rasterizationConservativeStateCreateInfo);
4379 const std::vector<VkPipelineRasterizationStateCreateInfo> ConservativePointTestInstance::initRasterizationStateCreateInfo (void)
4381 std::vector<VkPipelineRasterizationStateCreateInfo> result;
4383 result.reserve(getIterationCount());
4385 for (int iteration = 0; iteration < getIterationCount(); ++iteration)
4387 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
4389 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
4390 &m_rasterizationConservativeStateCreateInfo[iteration], // const void* pNext;
4391 0, // VkPipelineRasterizationStateCreateFlags flags;
4392 false, // VkBool32 depthClampEnable;
4393 false, // VkBool32 rasterizerDiscardEnable;
4394 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
4395 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
4396 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
4397 VK_FALSE, // VkBool32 depthBiasEnable;
4398 0.0f, // float depthBiasConstantFactor;
4399 0.0f, // float depthBiasClamp;
4400 0.0f, // float depthBiasSlopeFactor;
4401 0.0f, // float lineWidth;
4404 result.push_back(rasterizationStateCreateInfo);
4410 const VkPipelineRasterizationStateCreateInfo* ConservativePointTestInstance::getRasterizationStateCreateInfo (void) const
4412 return &m_rasterizationStateCreateInfo[getIteration()];
4415 const VkPipelineRasterizationLineStateCreateInfoEXT* ConservativePointTestInstance::getLineRasterizationStateCreateInfo (void)
4421 template <typename ConcreteTestInstance>
4422 class WidenessTestCase : public BaseRenderingTestCase
4425 WidenessTestCase (tcu::TestContext& context,
4426 const std::string& name,
4427 const std::string& description,
4428 PrimitiveWideness wideness,
4429 PrimitiveStrictness strictness,
4431 VkSampleCountFlagBits sampleCount,
4432 LineStipple stipple,
4433 VkLineRasterizationModeEXT lineRasterizationMode,
4434 deUint32 additionalRenderSize = 0)
4435 : BaseRenderingTestCase (context, name, description, sampleCount)
4436 , m_wideness(wideness)
4437 , m_strictness (strictness)
4438 , m_isLineTest (isLineTest)
4439 , m_stipple (stipple)
4440 , m_lineRasterizationMode (lineRasterizationMode)
4441 , m_additionalRenderSize (additionalRenderSize)
4444 virtual TestInstance* createInstance (Context& context) const
4446 return new ConcreteTestInstance(context, m_wideness, m_strictness, m_sampleCount, m_stipple, m_lineRasterizationMode, m_additionalRenderSize);
4449 virtual void checkSupport (Context& context) const
4453 if (m_wideness == PRIMITIVEWIDENESS_WIDE)
4454 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_WIDE_LINES);
4456 switch (m_lineRasterizationMode)
4459 TCU_THROW(InternalError, "Unknown line rasterization mode");
4461 case VK_LINE_RASTERIZATION_MODE_EXT_LAST:
4463 if (m_strictness == PRIMITIVESTRICTNESS_STRICT)
4464 if (!context.getDeviceProperties().limits.strictLines)
4465 TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
4467 if (m_strictness == PRIMITIVESTRICTNESS_NONSTRICT)
4468 if (context.getDeviceProperties().limits.strictLines)
4469 TCU_THROW(NotSupportedError, "Nonstrict rasterization is not supported");
4474 case VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT:
4476 if (!context.getDeviceProperties().limits.strictLines)
4477 TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
4479 if (getLineStippleEnable() &&
4480 !context.getLineRasterizationFeaturesEXT().stippledRectangularLines)
4481 TCU_THROW(NotSupportedError, "Stippled rectangular lines not supported");
4485 case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT:
4487 if (!context.getLineRasterizationFeaturesEXT().rectangularLines)
4488 TCU_THROW(NotSupportedError, "Rectangular lines not supported");
4490 if (getLineStippleEnable() &&
4491 !context.getLineRasterizationFeaturesEXT().stippledRectangularLines)
4492 TCU_THROW(NotSupportedError, "Stippled rectangular lines not supported");
4496 case VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT:
4498 if (!context.getLineRasterizationFeaturesEXT().bresenhamLines)
4499 TCU_THROW(NotSupportedError, "Bresenham lines not supported");
4501 if (getLineStippleEnable() &&
4502 !context.getLineRasterizationFeaturesEXT().stippledBresenhamLines)
4503 TCU_THROW(NotSupportedError, "Stippled Bresenham lines not supported");
4507 case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT:
4509 if (!context.getLineRasterizationFeaturesEXT().smoothLines)
4510 TCU_THROW(NotSupportedError, "Smooth lines not supported");
4512 if (getLineStippleEnable() &&
4513 !context.getLineRasterizationFeaturesEXT().stippledSmoothLines)
4514 TCU_THROW(NotSupportedError, "Stippled smooth lines not supported");
4521 if (m_wideness == PRIMITIVEWIDENESS_WIDE)
4522 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);
4526 bool getLineStippleEnable (void) const { return m_stipple != LINESTIPPLE_DISABLED; }
4527 virtual bool getLineStippleDynamic (void) const { return m_stipple == LINESTIPPLE_DYNAMIC; };
4530 const PrimitiveWideness m_wideness;
4531 const PrimitiveStrictness m_strictness;
4532 const bool m_isLineTest;
4533 const LineStipple m_stipple;
4534 const VkLineRasterizationModeEXT m_lineRasterizationMode;
4535 const deUint32 m_additionalRenderSize;
4538 class LinesTestInstance : public BaseLineTestInstance
4541 LinesTestInstance (Context& context, PrimitiveWideness wideness, PrimitiveStrictness strictness, VkSampleCountFlagBits sampleCount, LineStipple stipple, VkLineRasterizationModeEXT lineRasterizationMode, deUint32 additionalRenderSize = 0)
4542 : BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, wideness, strictness, sampleCount, stipple, lineRasterizationMode, additionalRenderSize)
4545 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
4548 void LinesTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
4555 // \note: these values are chosen arbitrarily
4556 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
4557 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
4558 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
4559 outData[3] = tcu::Vec4( -0.3f, 0.2f, 0.0f, 1.0f);
4560 outData[4] = tcu::Vec4( -1.5f, -0.4f, 0.0f, 1.0f);
4561 outData[5] = tcu::Vec4( 0.1f, 0.5f, 0.0f, 1.0f);
4562 outData[6] = tcu::Vec4( 0.75f, -0.4f, 0.0f, 1.0f);
4563 outData[7] = tcu::Vec4( 0.3f, 0.8f, 0.0f, 1.0f);
4567 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
4568 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
4569 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
4570 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
4571 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
4572 outData[5] = tcu::Vec4( 0.18f, -0.2f, 0.0f, 1.0f);
4573 outData[6] = tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f);
4574 outData[7] = tcu::Vec4( 0.0f, -1.0f, 0.0f, 1.0f);
4578 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
4579 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
4580 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
4581 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
4582 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
4583 outData[5] = tcu::Vec4( 0.8f, -0.7f, 0.0f, 1.0f);
4584 outData[6] = tcu::Vec4( 0.9f, 0.7f, 0.0f, 1.0f);
4585 outData[7] = tcu::Vec4( -0.9f, 0.7f, 0.0f, 1.0f);
4590 outLines[0].positions[0] = outData[0];
4591 outLines[0].positions[1] = outData[1];
4592 outLines[1].positions[0] = outData[2];
4593 outLines[1].positions[1] = outData[3];
4594 outLines[2].positions[0] = outData[4];
4595 outLines[2].positions[1] = outData[5];
4596 outLines[3].positions[0] = outData[6];
4597 outLines[3].positions[1] = outData[7];
4600 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outLines.size() << " lines(s): (width = " << getLineWidth() << ")" << tcu::TestLog::EndMessage;
4601 for (int lineNdx = 0; lineNdx < (int)outLines.size(); ++lineNdx)
4603 m_context.getTestContext().getLog()
4604 << tcu::TestLog::Message
4605 << "Line " << (lineNdx+1) << ":"
4606 << "\n\t" << outLines[lineNdx].positions[0]
4607 << "\n\t" << outLines[lineNdx].positions[1]
4608 << tcu::TestLog::EndMessage;
4612 class LineStripTestInstance : public BaseLineTestInstance
4615 LineStripTestInstance (Context& context, PrimitiveWideness wideness, PrimitiveStrictness strictness, VkSampleCountFlagBits sampleCount, LineStipple stipple, VkLineRasterizationModeEXT lineRasterizationMode, deUint32)
4616 : BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, wideness, strictness, sampleCount, stipple, lineRasterizationMode)
4619 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
4622 void LineStripTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
4629 // \note: these values are chosen arbitrarily
4630 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
4631 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
4632 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
4633 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
4637 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
4638 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
4639 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
4640 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
4644 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
4645 outData[1] = tcu::Vec4( 0.9f, -0.9f, 0.0f, 1.0f);
4646 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
4647 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
4652 outLines[0].positions[0] = outData[0];
4653 outLines[0].positions[1] = outData[1];
4654 outLines[1].positions[0] = outData[1];
4655 outLines[1].positions[1] = outData[2];
4656 outLines[2].positions[0] = outData[2];
4657 outLines[2].positions[1] = outData[3];
4660 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering line strip, width = " << getLineWidth() << ", " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
4661 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
4663 m_context.getTestContext().getLog()
4664 << tcu::TestLog::Message
4665 << "\t" << outData[vtxNdx]
4666 << tcu::TestLog::EndMessage;
4670 class FillRuleTestInstance : public BaseRenderingTestInstance
4673 enum FillRuleCaseType
4675 FILLRULECASE_BASIC = 0,
4676 FILLRULECASE_REVERSED,
4677 FILLRULECASE_CLIPPED_FULL,
4678 FILLRULECASE_CLIPPED_PARTIAL,
4679 FILLRULECASE_PROJECTED,
4683 FillRuleTestInstance (Context& context, FillRuleCaseType type, VkSampleCountFlagBits sampleCount);
4684 virtual tcu::TestStatus iterate (void);
4688 virtual const VkPipelineColorBlendStateCreateInfo* getColorBlendStateCreateInfo (void) const;
4689 int getRenderSize (FillRuleCaseType type) const;
4690 int getNumIterations (FillRuleCaseType type) const;
4691 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const;
4693 const FillRuleCaseType m_caseType;
4695 const int m_iterationCount;
4696 bool m_allIterationsPassed;
4700 FillRuleTestInstance::FillRuleTestInstance (Context& context, FillRuleCaseType type, VkSampleCountFlagBits sampleCount)
4701 : BaseRenderingTestInstance (context, sampleCount, getRenderSize(type))
4704 , m_iterationCount (getNumIterations(type))
4705 , m_allIterationsPassed (true)
4707 DE_ASSERT(type < FILLRULECASE_LAST);
4710 tcu::TestStatus FillRuleTestInstance::iterate (void)
4712 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
4713 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
4714 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
4715 const int thresholdRed = 1 << (8 - colorBits[0]);
4716 const int thresholdGreen = 1 << (8 - colorBits[1]);
4717 const int thresholdBlue = 1 << (8 - colorBits[2]);
4718 tcu::Surface resultImage (m_renderSize, m_renderSize);
4719 std::vector<tcu::Vec4> drawBuffer;
4721 generateTriangles(m_iteration, drawBuffer);
4725 const std::vector<tcu::Vec4> colorBuffer (drawBuffer.size(), tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
4727 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Drawing gray triangles with shared edges.\nEnabling additive blending to detect overlapping fragments." << tcu::TestLog::EndMessage;
4729 drawPrimitives(resultImage, drawBuffer, colorBuffer, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
4732 // verify no overdraw
4734 const tcu::RGBA triangleColor = tcu::RGBA(127, 127, 127, 255);
4735 bool overdraw = false;
4737 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Verifying result." << tcu::TestLog::EndMessage;
4739 for (int y = 0; y < resultImage.getHeight(); ++y)
4740 for (int x = 0; x < resultImage.getWidth(); ++x)
4742 const tcu::RGBA color = resultImage.getPixel(x, y);
4744 // color values are greater than triangle color? Allow lower values for multisampled edges and background.
4745 if ((color.getRed() - triangleColor.getRed()) > thresholdRed ||
4746 (color.getGreen() - triangleColor.getGreen()) > thresholdGreen ||
4747 (color.getBlue() - triangleColor.getBlue()) > thresholdBlue)
4753 m_context.getTestContext().getLog() << tcu::TestLog::Message << "No overlapping fragments detected." << tcu::TestLog::EndMessage;
4756 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Overlapping fragments detected, image is not valid." << tcu::TestLog::EndMessage;
4757 m_allIterationsPassed = false;
4761 // verify no missing fragments in the full viewport case
4762 if (m_caseType == FILLRULECASE_CLIPPED_FULL)
4764 bool missingFragments = false;
4766 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Searching missing fragments." << tcu::TestLog::EndMessage;
4768 for (int y = 0; y < resultImage.getHeight(); ++y)
4769 for (int x = 0; x < resultImage.getWidth(); ++x)
4771 const tcu::RGBA color = resultImage.getPixel(x, y);
4773 // black? (background)
4774 if (color.getRed() <= thresholdRed ||
4775 color.getGreen() <= thresholdGreen ||
4776 color.getBlue() <= thresholdBlue)
4777 missingFragments = true;
4781 if (!missingFragments)
4782 m_context.getTestContext().getLog() << tcu::TestLog::Message << "No missing fragments detected." << tcu::TestLog::EndMessage;
4785 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Missing fragments detected, image is not valid." << tcu::TestLog::EndMessage;
4787 m_allIterationsPassed = false;
4791 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result of rendering", "Result of rendering")
4792 << tcu::TestLog::Image("Result", "Result", resultImage)
4793 << tcu::TestLog::EndImageSet;
4796 if (++m_iteration == m_iterationCount)
4798 if (m_allIterationsPassed)
4799 return tcu::TestStatus::pass("Pass");
4801 return tcu::TestStatus::fail("Found invalid pixels");
4804 return tcu::TestStatus::incomplete();
4807 int FillRuleTestInstance::getRenderSize (FillRuleCaseType type) const
4809 if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
4810 return RESOLUTION_POT / 4;
4812 return RESOLUTION_POT;
4815 int FillRuleTestInstance::getNumIterations (FillRuleCaseType type) const
4817 if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
4823 void FillRuleTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const
4827 case FILLRULECASE_BASIC:
4828 case FILLRULECASE_REVERSED:
4829 case FILLRULECASE_PROJECTED:
4831 const int numRows = 4;
4832 const int numColumns = 4;
4833 const float quadSide = 0.15f;
4834 de::Random rnd (0xabcd);
4836 outData.resize(6 * numRows * numColumns);
4838 for (int col = 0; col < numColumns; ++col)
4839 for (int row = 0; row < numRows; ++row)
4841 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);
4842 const float rotation = (float)(iteration * numColumns * numRows + col * numRows + row) / (float)(m_iterationCount * numColumns * numRows) * DE_PI / 2.0f;
4843 const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
4844 const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x());
4845 const tcu::Vec2 quad[4] =
4847 center + sideH + sideV,
4848 center + sideH - sideV,
4849 center - sideH - sideV,
4850 center - sideH + sideV,
4853 if (m_caseType == FILLRULECASE_BASIC)
4855 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
4856 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
4857 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
4858 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
4859 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
4860 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
4862 else if (m_caseType == FILLRULECASE_REVERSED)
4864 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
4865 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
4866 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
4867 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
4868 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
4869 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
4871 else if (m_caseType == FILLRULECASE_PROJECTED)
4873 const float w0 = rnd.getFloat(0.1f, 4.0f);
4874 const float w1 = rnd.getFloat(0.1f, 4.0f);
4875 const float w2 = rnd.getFloat(0.1f, 4.0f);
4876 const float w3 = rnd.getFloat(0.1f, 4.0f);
4878 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
4879 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x() * w1, quad[1].y() * w1, 0.0f, w1);
4880 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
4881 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
4882 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
4883 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x() * w3, quad[3].y() * w3, 0.0f, w3);
4886 DE_ASSERT(DE_FALSE);
4892 case FILLRULECASE_CLIPPED_PARTIAL:
4893 case FILLRULECASE_CLIPPED_FULL:
4895 const float quadSide = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (1.0f) : (2.0f);
4896 const tcu::Vec2 center = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (tcu::Vec2(0.5f, 0.5f)) : (tcu::Vec2(0.0f, 0.0f));
4897 const float rotation = (float)(iteration) / (float)(m_iterationCount - 1) * DE_PI / 2.0f;
4898 const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
4899 const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x());
4900 const tcu::Vec2 quad[4] =
4902 center + sideH + sideV,
4903 center + sideH - sideV,
4904 center - sideH - sideV,
4905 center - sideH + sideV,
4909 outData[0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
4910 outData[1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
4911 outData[2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
4912 outData[3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
4913 outData[4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
4914 outData[5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
4919 DE_ASSERT(DE_FALSE);
4923 const VkPipelineColorBlendStateCreateInfo* FillRuleTestInstance::getColorBlendStateCreateInfo (void) const
4925 static const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
4927 true, // VkBool32 blendEnable;
4928 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
4929 VK_BLEND_FACTOR_ONE, // VkBlend destBlendColor;
4930 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
4931 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
4932 VK_BLEND_FACTOR_ONE, // VkBlend destBlendAlpha;
4933 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
4934 (VK_COLOR_COMPONENT_R_BIT |
4935 VK_COLOR_COMPONENT_G_BIT |
4936 VK_COLOR_COMPONENT_B_BIT |
4937 VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask;
4940 static const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
4942 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
4943 DE_NULL, // const void* pNext;
4944 0, // VkPipelineColorBlendStateCreateFlags flags;
4945 false, // VkBool32 logicOpEnable;
4946 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
4947 1u, // deUint32 attachmentCount;
4948 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
4949 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
4952 return &colorBlendStateParams;
4956 class FillRuleTestCase : public BaseRenderingTestCase
4959 FillRuleTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, FillRuleTestInstance::FillRuleCaseType type, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
4960 : BaseRenderingTestCase (context, name, description, sampleCount)
4964 virtual TestInstance* createInstance (Context& context) const
4966 return new FillRuleTestInstance(context, m_type, m_sampleCount);
4969 const FillRuleTestInstance::FillRuleCaseType m_type;
4972 class CullingTestInstance : public BaseRenderingTestInstance
4975 CullingTestInstance (Context& context, VkCullModeFlags cullMode, VkPrimitiveTopology primitiveTopology, VkFrontFace frontFace, VkPolygonMode polygonMode)
4976 : BaseRenderingTestInstance (context, VK_SAMPLE_COUNT_1_BIT, RESOLUTION_POT)
4977 , m_cullMode (cullMode)
4978 , m_primitiveTopology (primitiveTopology)
4979 , m_frontFace (frontFace)
4980 , m_polygonMode (polygonMode)
4981 , m_multisampling (true)
4984 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
4986 tcu::TestStatus iterate (void);
4989 void generateVertices (std::vector<tcu::Vec4>& outData) const;
4990 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const;
4991 void extractLines (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, std::vector<LineSceneSpec::SceneLine>& outLines) const;
4992 void extractPoints (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, std::vector<PointSceneSpec::ScenePoint>& outPoints) const;
4993 bool triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const;
4995 const VkCullModeFlags m_cullMode;
4996 const VkPrimitiveTopology m_primitiveTopology;
4997 const VkFrontFace m_frontFace;
4998 const VkPolygonMode m_polygonMode;
4999 const bool m_multisampling;
5003 tcu::TestStatus CullingTestInstance::iterate (void)
5005 DE_ASSERT(m_polygonMode <= VK_POLYGON_MODE_POINT);
5007 tcu::Surface resultImage (m_renderSize, m_renderSize);
5008 std::vector<tcu::Vec4> drawBuffer;
5009 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
5010 std::vector<PointSceneSpec::ScenePoint> points;
5011 std::vector<LineSceneSpec::SceneLine> lines;
5013 const InstanceInterface& vk = m_context.getInstanceInterface();
5014 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
5015 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(vk, physicalDevice);
5017 if (!(deviceFeatures.fillModeNonSolid) && (m_polygonMode == VK_POLYGON_MODE_LINE || m_polygonMode == VK_POLYGON_MODE_POINT))
5018 TCU_THROW(NotSupportedError, "Wireframe fill modes are not supported");
5021 generateVertices(drawBuffer);
5022 extractTriangles(triangles, drawBuffer);
5024 if (m_polygonMode == VK_POLYGON_MODE_LINE)
5025 extractLines(triangles ,lines);
5026 else if (m_polygonMode == VK_POLYGON_MODE_POINT)
5027 extractPoints(triangles, points);
5031 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Setting front face to " << m_frontFace << tcu::TestLog::EndMessage;
5032 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Setting cull face to " << m_cullMode << tcu::TestLog::EndMessage;
5033 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Drawing test pattern (" << m_primitiveTopology << ")" << tcu::TestLog::EndMessage;
5035 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
5040 RasterizationArguments args;
5041 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
5042 bool isCompareOk = false;
5044 args.numSamples = m_multisampling ? 1 : 0;
5045 args.subpixelBits = m_subpixelBits;
5046 args.redBits = colorBits[0];
5047 args.greenBits = colorBits[1];
5048 args.blueBits = colorBits[2];
5050 switch (m_polygonMode)
5052 case VK_POLYGON_MODE_LINE:
5054 LineSceneSpec scene;
5055 scene.lineWidth = 0;
5056 scene.lines.swap(lines);
5057 isCompareOk = verifyLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
5060 case VK_POLYGON_MODE_POINT:
5062 PointSceneSpec scene;
5063 scene.points.swap(points);
5064 isCompareOk = verifyPointGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
5069 TriangleSceneSpec scene;
5070 scene.triangles.swap(triangles);
5071 isCompareOk = verifyTriangleGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), tcu::VERIFICATIONMODE_WEAK);
5077 return tcu::TestStatus::pass("Pass");
5079 return tcu::TestStatus::fail("Incorrect rendering");
5083 void CullingTestInstance::generateVertices (std::vector<tcu::Vec4>& outData) const
5085 de::Random rnd(543210);
5088 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
5090 outData[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
5091 outData[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
5092 outData[vtxNdx].z() = 0.0f;
5093 outData[vtxNdx].w() = 1.0f;
5097 void CullingTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const
5099 const bool cullDirection = (m_cullMode == VK_CULL_MODE_FRONT_BIT) ^ (m_frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE);
5102 if (m_cullMode == VK_CULL_MODE_FRONT_AND_BACK)
5105 switch (m_primitiveTopology)
5107 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
5109 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
5111 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
5112 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
5113 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
5115 if (triangleOrder(v0, v1, v2) != cullDirection)
5117 TriangleSceneSpec::SceneTriangle tri;
5118 tri.positions[0] = v0; tri.sharedEdge[0] = false;
5119 tri.positions[1] = v1; tri.sharedEdge[1] = false;
5120 tri.positions[2] = v2; tri.sharedEdge[2] = false;
5122 outTriangles.push_back(tri);
5128 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
5130 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
5132 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
5133 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
5134 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
5136 if (triangleOrder(v0, v1, v2) != (cullDirection ^ (vtxNdx % 2 != 0)))
5138 TriangleSceneSpec::SceneTriangle tri;
5139 tri.positions[0] = v0; tri.sharedEdge[0] = false;
5140 tri.positions[1] = v1; tri.sharedEdge[1] = false;
5141 tri.positions[2] = v2; tri.sharedEdge[2] = false;
5143 outTriangles.push_back(tri);
5149 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
5151 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
5153 const tcu::Vec4& v0 = vertices[0];
5154 const tcu::Vec4& v1 = vertices[vtxNdx + 0];
5155 const tcu::Vec4& v2 = vertices[vtxNdx + 1];
5157 if (triangleOrder(v0, v1, v2) != cullDirection)
5159 TriangleSceneSpec::SceneTriangle tri;
5160 tri.positions[0] = v0; tri.sharedEdge[0] = false;
5161 tri.positions[1] = v1; tri.sharedEdge[1] = false;
5162 tri.positions[2] = v2; tri.sharedEdge[2] = false;
5164 outTriangles.push_back(tri);
5175 void CullingTestInstance::extractLines (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles,
5176 std::vector<LineSceneSpec::SceneLine>& outLines) const
5178 for (int triNdx = 0; triNdx < (int)outTriangles.size(); ++triNdx)
5180 for (int vrtxNdx = 0; vrtxNdx < 2; ++vrtxNdx)
5182 LineSceneSpec::SceneLine line;
5183 line.positions[0] = outTriangles.at(triNdx).positions[vrtxNdx];
5184 line.positions[1] = outTriangles.at(triNdx).positions[vrtxNdx + 1];
5186 outLines.push_back(line);
5188 LineSceneSpec::SceneLine line;
5189 line.positions[0] = outTriangles.at(triNdx).positions[2];
5190 line.positions[1] = outTriangles.at(triNdx).positions[0];
5191 outLines.push_back(line);
5195 void CullingTestInstance::extractPoints (std::vector<TriangleSceneSpec::SceneTriangle> &outTriangles,
5196 std::vector<PointSceneSpec::ScenePoint> &outPoints) const
5198 for (int triNdx = 0; triNdx < (int)outTriangles.size(); ++triNdx)
5200 for (int vrtxNdx = 0; vrtxNdx < 3; ++vrtxNdx)
5202 PointSceneSpec::ScenePoint point;
5203 point.position = outTriangles.at(triNdx).positions[vrtxNdx];
5204 point.pointSize = 1.0f;
5206 outPoints.push_back(point);
5211 bool CullingTestInstance::triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const
5213 const tcu::Vec2 s0 = v0.swizzle(0, 1) / v0.w();
5214 const tcu::Vec2 s1 = v1.swizzle(0, 1) / v1.w();
5215 const tcu::Vec2 s2 = v2.swizzle(0, 1) / v2.w();
5218 return ((s1.x() - s0.x()) * (s2.y() - s0.y()) - (s2.x() - s0.x()) * (s1.y() - s0.y())) > 0;
5222 const VkPipelineRasterizationStateCreateInfo* CullingTestInstance::getRasterizationStateCreateInfo (void) const
5224 static VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
5226 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
5227 DE_NULL, // const void* pNext;
5228 0, // VkPipelineRasterizationStateCreateFlags flags;
5229 false, // VkBool32 depthClipEnable;
5230 false, // VkBool32 rasterizerDiscardEnable;
5231 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
5232 VK_CULL_MODE_NONE, // VkCullMode cullMode;
5233 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
5234 VK_FALSE, // VkBool32 depthBiasEnable;
5235 0.0f, // float depthBias;
5236 0.0f, // float depthBiasClamp;
5237 0.0f, // float slopeScaledDepthBias;
5238 getLineWidth(), // float lineWidth;
5241 rasterizationStateCreateInfo.lineWidth = getLineWidth();
5242 rasterizationStateCreateInfo.cullMode = m_cullMode;
5243 rasterizationStateCreateInfo.frontFace = m_frontFace;
5244 rasterizationStateCreateInfo.polygonMode = m_polygonMode;
5246 return &rasterizationStateCreateInfo;
5249 class CullingTestCase : public BaseRenderingTestCase
5252 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)
5253 : BaseRenderingTestCase (context, name, description, sampleCount)
5254 , m_cullMode (cullMode)
5255 , m_primitiveTopology (primitiveTopology)
5256 , m_frontFace (frontFace)
5257 , m_polygonMode (polygonMode)
5260 virtual TestInstance* createInstance (Context& context) const
5262 return new CullingTestInstance(context, m_cullMode, m_primitiveTopology, m_frontFace, m_polygonMode);
5264 void checkSupport (Context& context) const;
5266 const VkCullModeFlags m_cullMode;
5267 const VkPrimitiveTopology m_primitiveTopology;
5268 const VkFrontFace m_frontFace;
5269 const VkPolygonMode m_polygonMode;
5272 void CullingTestCase::checkSupport (Context& context) const
5274 if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset"))
5276 const VkPhysicalDevicePortabilitySubsetFeaturesKHR& subsetFeatures = context.getPortabilitySubsetFeatures();
5277 if (m_polygonMode == VK_POLYGON_MODE_POINT && !subsetFeatures.pointPolygons)
5278 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Point polygons are not supported by this implementation");
5279 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN && !subsetFeatures.triangleFans)
5280 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
5284 class DiscardTestInstance : public BaseRenderingTestInstance
5287 DiscardTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, deBool queryFragmentShaderInvocations)
5288 : BaseRenderingTestInstance (context, VK_SAMPLE_COUNT_1_BIT, RESOLUTION_POT)
5289 , m_primitiveTopology (primitiveTopology)
5290 , m_queryFragmentShaderInvocations (queryFragmentShaderInvocations)
5293 virtual const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
5294 tcu::TestStatus iterate (void);
5297 void generateVertices (std::vector<tcu::Vec4>& outData) const;
5298 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const;
5299 void extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices) const;
5300 void extractPoints (std::vector<PointSceneSpec::ScenePoint>& outPoints, const std::vector<tcu::Vec4>& vertices) const;
5301 void drawPrimitivesDiscard (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, VkPrimitiveTopology primitiveTopology, Move<VkQueryPool>& queryPool);
5303 const VkPrimitiveTopology m_primitiveTopology;
5304 const deBool m_queryFragmentShaderInvocations;
5307 tcu::TestStatus DiscardTestInstance::iterate (void)
5309 const DeviceInterface& vkd = m_context.getDeviceInterface();
5310 const VkDevice vkDevice = m_context.getDevice();
5311 deUint64 queryResult = 0u;
5312 tcu::Surface resultImage (m_renderSize, m_renderSize);
5313 std::vector<tcu::Vec4> drawBuffer;
5314 std::vector<PointSceneSpec::ScenePoint> points;
5315 std::vector<LineSceneSpec::SceneLine> lines;
5316 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
5318 generateVertices(drawBuffer);
5320 switch (m_primitiveTopology)
5322 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
5323 extractPoints(points, drawBuffer);
5326 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
5327 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
5328 extractLines(lines, drawBuffer);
5331 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
5332 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
5333 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
5334 extractTriangles(triangles, drawBuffer);
5341 const VkQueryPoolCreateInfo queryPoolCreateInfo =
5343 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // VkStructureType sType
5344 DE_NULL, // const void* pNext
5345 (VkQueryPoolCreateFlags)0, // VkQueryPoolCreateFlags flags
5346 VK_QUERY_TYPE_PIPELINE_STATISTICS , // VkQueryType queryType
5347 1u, // deUint32 entryCount
5348 VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT, // VkQueryPipelineStatisticFlags pipelineStatistics
5351 if (m_queryFragmentShaderInvocations)
5353 Move<VkQueryPool> queryPool = createQueryPool(vkd, vkDevice, &queryPoolCreateInfo);
5355 drawPrimitivesDiscard(resultImage, drawBuffer, m_primitiveTopology, queryPool);
5356 vkd.getQueryPoolResults(vkDevice, *queryPool, 0u, 1u, sizeof(deUint64), &queryResult, 0u, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
5359 BaseRenderingTestInstance::drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
5363 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
5365 const RasterizationArguments args =
5367 0, // int numSamples;
5368 (int)m_subpixelBits, // int subpixelBits;
5369 colorBits[0], // int redBits;
5370 colorBits[1], // int greenBits;
5371 colorBits[2] // int blueBits;
5374 // Empty scene to compare to, primitives should be discarded before rasterization
5375 TriangleSceneSpec scene;
5377 const bool isCompareOk = verifyTriangleGroupRasterization(resultImage,
5380 m_context.getTestContext().getLog(),
5381 tcu::VERIFICATIONMODE_STRICT);
5385 if (m_queryFragmentShaderInvocations && queryResult > 0u)
5386 return tcu::TestStatus::fail("Fragment shader invocations occured");
5388 return tcu::TestStatus::pass("Pass");
5391 return tcu::TestStatus::fail("Incorrect rendering");
5395 void DiscardTestInstance::generateVertices (std::vector<tcu::Vec4>& outData) const
5397 de::Random rnd(12345);
5401 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
5403 outData[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
5404 outData[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
5405 outData[vtxNdx].z() = 0.0f;
5406 outData[vtxNdx].w() = 1.0f;
5410 void DiscardTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const
5412 switch (m_primitiveTopology)
5414 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
5416 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
5418 TriangleSceneSpec::SceneTriangle tri;
5419 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
5420 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
5421 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
5423 tri.positions[0] = v0;
5424 tri.positions[1] = v1;
5425 tri.positions[2] = v2;
5427 outTriangles.push_back(tri);
5433 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
5435 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
5437 TriangleSceneSpec::SceneTriangle tri;
5438 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
5439 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
5440 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
5442 tri.positions[0] = v0;
5443 tri.positions[1] = v1;
5444 tri.positions[2] = v2;
5446 outTriangles.push_back(tri);
5452 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
5454 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
5456 TriangleSceneSpec::SceneTriangle tri;
5457 const tcu::Vec4& v0 = vertices[0];
5458 const tcu::Vec4& v1 = vertices[vtxNdx + 0];
5459 const tcu::Vec4& v2 = vertices[vtxNdx + 1];
5461 tri.positions[0] = v0;
5462 tri.positions[1] = v1;
5463 tri.positions[2] = v2;
5465 outTriangles.push_back(tri);
5476 void DiscardTestInstance::extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices) const
5478 switch (m_primitiveTopology)
5480 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
5482 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; vtxNdx += 2)
5484 LineSceneSpec::SceneLine line;
5486 line.positions[0] = vertices[vtxNdx + 0];
5487 line.positions[1] = vertices[vtxNdx + 1];
5489 outLines.push_back(line);
5495 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
5497 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
5499 LineSceneSpec::SceneLine line;
5501 line.positions[0] = vertices[vtxNdx + 0];
5502 line.positions[1] = vertices[vtxNdx + 1];
5504 outLines.push_back(line);
5515 void DiscardTestInstance::extractPoints (std::vector<PointSceneSpec::ScenePoint>& outPoints, const std::vector<tcu::Vec4>& vertices) const
5517 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
5519 for (int vrtxNdx = 0; vrtxNdx < 3; ++vrtxNdx)
5521 PointSceneSpec::ScenePoint point;
5523 point.position = vertices[vrtxNdx];
5524 point.pointSize = 1.0f;
5526 outPoints.push_back(point);
5531 const VkPipelineRasterizationStateCreateInfo* DiscardTestInstance::getRasterizationStateCreateInfo (void) const
5533 static const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
5535 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
5536 NULL, // const void* pNext;
5537 0, // VkPipelineRasterizationStateCreateFlags flags;
5538 VK_FALSE, // VkBool32 depthClipEnable;
5539 VK_TRUE, // VkBool32 rasterizerDiscardEnable;
5540 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
5541 VK_CULL_MODE_NONE, // VkCullMode cullMode;
5542 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
5543 VK_FALSE, // VkBool32 depthBiasEnable;
5544 0.0f, // float depthBias;
5545 0.0f, // float depthBiasClamp;
5546 0.0f, // float slopeScaledDepthBias;
5547 getLineWidth(), // float lineWidth;
5550 return &rasterizationStateCreateInfo;
5553 void DiscardTestInstance::drawPrimitivesDiscard (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, VkPrimitiveTopology primitiveTopology, Move<VkQueryPool>& queryPool)
5555 const DeviceInterface& vkd = m_context.getDeviceInterface();
5556 const VkDevice vkDevice = m_context.getDevice();
5557 const VkPhysicalDeviceProperties properties = m_context.getDeviceProperties();
5558 const VkQueue queue = m_context.getUniversalQueue();
5559 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
5560 Allocator& allocator = m_context.getDefaultAllocator();
5562 const size_t attributeBatchSize = positionData.size() * sizeof(tcu::Vec4);
5563 const VkDeviceSize vertexBufferOffset = 0;
5564 de::MovePtr<Allocation> vertexBufferMemory;
5565 Move<VkBuffer> vertexBuffer;
5566 Move<VkCommandBuffer> commandBuffer;
5567 Move<VkPipeline> graphicsPipeline;
5569 if (attributeBatchSize > properties.limits.maxVertexInputAttributeOffset)
5571 std::stringstream message;
5572 message << "Larger vertex input attribute offset is needed (" << attributeBatchSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
5573 TCU_THROW(NotSupportedError, message.str().c_str());
5576 // Create Graphics Pipeline
5578 const VkVertexInputBindingDescription vertexInputBindingDescription =
5580 0u, // deUint32 binding;
5581 sizeof(tcu::Vec4), // deUint32 strideInBytes;
5582 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
5585 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
5588 0u, // deUint32 location;
5589 0u, // deUint32 binding;
5590 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
5591 0u // deUint32 offsetInBytes;
5594 1u, // deUint32 location;
5595 0u, // deUint32 binding;
5596 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
5597 (deUint32)attributeBatchSize // deUint32 offsetInBytes;
5601 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
5603 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
5604 DE_NULL, // const void* pNext;
5605 0, // VkPipelineVertexInputStateCreateFlags flags;
5606 1u, // deUint32 bindingCount;
5607 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
5608 2u, // deUint32 attributeCount;
5609 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
5612 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(m_renderSize)));
5613 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(m_renderSize)));
5615 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
5617 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
5618 DE_NULL, // const void* pNext;
5619 0u, // VkPipelineMultisampleStateCreateFlags flags;
5620 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
5621 VK_FALSE, // VkBool32 sampleShadingEnable;
5622 0.0f, // float minSampleShading;
5623 DE_NULL, // const VkSampleMask* pSampleMask;
5624 VK_FALSE, // VkBool32 alphaToCoverageEnable;
5625 VK_FALSE // VkBool32 alphaToOneEnable;
5628 graphicsPipeline = makeGraphicsPipeline(vkd, // const DeviceInterface& vk
5629 vkDevice, // const VkDevice device
5630 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
5631 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
5632 DE_NULL, // const VkShaderModule tessellationControlShaderModule
5633 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
5634 DE_NULL, // const VkShaderModule geometryShaderModule
5635 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
5636 *m_renderPass, // const VkRenderPass renderPass
5637 viewports, // const std::vector<VkViewport>& viewports
5638 scissors, // const std::vector<VkRect2D>& scissors
5639 primitiveTopology, // const VkPrimitiveTopology topology
5640 0u, // const deUint32 subpass
5641 0u, // const deUint32 patchControlPoints
5642 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
5643 getRasterizationStateCreateInfo(), // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
5644 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
5645 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo,
5646 getColorBlendStateCreateInfo()); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
5649 // Create Vertex Buffer
5651 const VkBufferCreateInfo vertexBufferParams =
5653 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
5654 DE_NULL, // const void* pNext;
5655 0u, // VkBufferCreateFlags flags;
5656 attributeBatchSize * 2, // VkDeviceSize size;
5657 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
5658 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
5659 1u, // deUint32 queueFamilyCount;
5660 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
5663 const std::vector<tcu::Vec4> colorData (positionData.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
5665 vertexBuffer = createBuffer(vkd, vkDevice, &vertexBufferParams);
5666 vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
5668 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
5670 // Load vertices into vertex buffer
5671 deMemcpy(vertexBufferMemory->getHostPtr(), positionData.data(), attributeBatchSize);
5672 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) + attributeBatchSize, colorData.data(), attributeBatchSize);
5673 flushAlloc(vkd, vkDevice, *vertexBufferMemory);
5676 // Create Command Buffer
5677 commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5679 // Begin Command Buffer
5680 beginCommandBuffer(vkd, *commandBuffer);
5682 addImageTransitionBarrier(*commandBuffer, // VkCommandBuffer commandBuffer
5683 *m_image, // VkImage image
5684 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
5685 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
5686 0, // VkAccessFlags srcAccessMask
5687 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
5688 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
5689 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
5691 if (m_multisampling)
5693 addImageTransitionBarrier(*commandBuffer, // VkCommandBuffer commandBuffer
5694 *m_resolvedImage, // VkImage image
5695 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
5696 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
5697 0, // VkAccessFlags srcAccessMask
5698 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
5699 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
5700 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
5704 vkd.cmdResetQueryPool(*commandBuffer, *queryPool, 0u, 1u);
5706 // Begin render pass and start query
5707 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));
5708 vkd.cmdBeginQuery(*commandBuffer, *queryPool, 0u, (VkQueryControlFlags)0u);
5709 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
5710 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL);
5711 vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
5712 vkd.cmdDraw(*commandBuffer, (deUint32)positionData.size(), 1, 0, 0);
5713 endRenderPass(vkd, *commandBuffer);
5714 vkd.cmdEndQuery(*commandBuffer, *queryPool, 0u);
5717 copyImageToBuffer(vkd, *commandBuffer, m_multisampling ? *m_resolvedImage : *m_image, *m_resultBuffer, tcu::IVec2(m_renderSize, m_renderSize));
5719 endCommandBuffer(vkd, *commandBuffer);
5723 float pointSize = getPointSize();
5725 deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize);
5726 flushAlloc(vkd, vkDevice, *m_uniformBufferMemory);
5730 submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());
5732 invalidateAlloc(vkd, vkDevice, *m_resultBufferMemory);
5733 tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderSize, m_renderSize, 1), m_resultBufferMemory->getHostPtr()));
5736 class DiscardTestCase : public BaseRenderingTestCase
5739 DiscardTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkPrimitiveTopology primitiveTopology, deBool queryFragmentShaderInvocations, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
5740 : BaseRenderingTestCase (context, name, description, sampleCount)
5741 , m_primitiveTopology (primitiveTopology)
5742 , m_queryFragmentShaderInvocations (queryFragmentShaderInvocations)
5745 virtual TestInstance* createInstance (Context& context) const
5747 return new DiscardTestInstance (context, m_primitiveTopology, m_queryFragmentShaderInvocations);
5750 virtual void checkSupport (Context& context) const
5752 if (m_queryFragmentShaderInvocations)
5753 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY);
5755 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN &&
5756 context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
5757 !context.getPortabilitySubsetFeatures().triangleFans)
5758 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
5762 const VkPrimitiveTopology m_primitiveTopology;
5763 const deBool m_queryFragmentShaderInvocations;
5766 class TriangleInterpolationTestInstance : public BaseRenderingTestInstance
5770 TriangleInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount)
5771 : BaseRenderingTestInstance (context, sampleCount, RESOLUTION_POT)
5772 , m_primitiveTopology (primitiveTopology)
5773 , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
5774 , m_iterationCount (3)
5776 , m_allIterationsPassed (true)
5777 , m_flatshade ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
5780 tcu::TestStatus iterate (void);
5784 void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
5785 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
5788 VkPrimitiveTopology m_primitiveTopology;
5789 const bool m_projective;
5790 const int m_iterationCount;
5792 bool m_allIterationsPassed;
5793 const deBool m_flatshade;
5796 tcu::TestStatus TriangleInterpolationTestInstance::iterate (void)
5798 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
5799 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
5800 tcu::Surface resultImage (m_renderSize, m_renderSize);
5801 std::vector<tcu::Vec4> drawBuffer;
5802 std::vector<tcu::Vec4> colorBuffer;
5803 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
5806 generateVertices(m_iteration, drawBuffer, colorBuffer);
5807 extractTriangles(triangles, drawBuffer, colorBuffer);
5811 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
5812 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
5813 m_context.getTestContext().getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
5817 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitiveTopology);
5821 RasterizationArguments args;
5822 TriangleSceneSpec scene;
5823 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
5825 args.numSamples = m_multisampling ? 1 : 0;
5826 args.subpixelBits = m_subpixelBits;
5827 args.redBits = colorBits[0];
5828 args.greenBits = colorBits[1];
5829 args.blueBits = colorBits[2];
5831 scene.triangles.swap(triangles);
5833 if (!verifyTriangleGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog()))
5834 m_allIterationsPassed = false;
5838 if (++m_iteration == m_iterationCount)
5840 if (m_allIterationsPassed)
5841 return tcu::TestStatus::pass("Pass");
5843 return tcu::TestStatus::fail("Found invalid pixel values");
5846 return tcu::TestStatus::incomplete();
5849 void TriangleInterpolationTestInstance::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
5851 // use only red, green and blue
5852 const tcu::Vec4 colors[] =
5854 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
5855 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
5856 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
5859 de::Random rnd(123 + iteration * 1000 + (int)m_primitiveTopology);
5861 outVertices.resize(6);
5862 outColors.resize(6);
5864 for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
5866 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
5867 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
5868 outVertices[vtxNdx].z() = 0.0f;
5871 outVertices[vtxNdx].w() = 1.0f;
5874 const float w = rnd.getFloat(0.2f, 4.0f);
5876 outVertices[vtxNdx].x() *= w;
5877 outVertices[vtxNdx].y() *= w;
5878 outVertices[vtxNdx].z() *= w;
5879 outVertices[vtxNdx].w() = w;
5882 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
5886 void TriangleInterpolationTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
5888 switch (m_primitiveTopology)
5890 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
5892 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
5894 TriangleSceneSpec::SceneTriangle tri;
5895 tri.positions[0] = vertices[vtxNdx + 0];
5896 tri.positions[1] = vertices[vtxNdx + 1];
5897 tri.positions[2] = vertices[vtxNdx + 2];
5898 tri.sharedEdge[0] = false;
5899 tri.sharedEdge[1] = false;
5900 tri.sharedEdge[2] = false;
5904 tri.colors[0] = colors[vtxNdx];
5905 tri.colors[1] = colors[vtxNdx];
5906 tri.colors[2] = colors[vtxNdx];
5910 tri.colors[0] = colors[vtxNdx + 0];
5911 tri.colors[1] = colors[vtxNdx + 1];
5912 tri.colors[2] = colors[vtxNdx + 2];
5915 outTriangles.push_back(tri);
5920 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
5922 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
5924 TriangleSceneSpec::SceneTriangle tri;
5925 tri.positions[0] = vertices[vtxNdx + 0];
5926 tri.positions[1] = vertices[vtxNdx + 1];
5927 tri.positions[2] = vertices[vtxNdx + 2];
5928 tri.sharedEdge[0] = false;
5929 tri.sharedEdge[1] = false;
5930 tri.sharedEdge[2] = false;
5934 tri.colors[0] = colors[vtxNdx];
5935 tri.colors[1] = colors[vtxNdx];
5936 tri.colors[2] = colors[vtxNdx];
5940 tri.colors[0] = colors[vtxNdx + 0];
5941 tri.colors[1] = colors[vtxNdx + 1];
5942 tri.colors[2] = colors[vtxNdx + 2];
5945 outTriangles.push_back(tri);
5950 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
5952 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
5954 TriangleSceneSpec::SceneTriangle tri;
5955 tri.positions[0] = vertices[0];
5956 tri.positions[1] = vertices[vtxNdx + 0];
5957 tri.positions[2] = vertices[vtxNdx + 1];
5958 tri.sharedEdge[0] = false;
5959 tri.sharedEdge[1] = false;
5960 tri.sharedEdge[2] = false;
5964 tri.colors[0] = colors[vtxNdx];
5965 tri.colors[1] = colors[vtxNdx];
5966 tri.colors[2] = colors[vtxNdx];
5970 tri.colors[0] = colors[0];
5971 tri.colors[1] = colors[vtxNdx + 0];
5972 tri.colors[2] = colors[vtxNdx + 1];
5975 outTriangles.push_back(tri);
5985 class TriangleInterpolationTestCase : public BaseRenderingTestCase
5988 TriangleInterpolationTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
5989 : BaseRenderingTestCase (context, name, description, sampleCount, (flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
5990 , m_primitiveTopology (primitiveTopology)
5994 virtual TestInstance* createInstance (Context& context) const
5996 return new TriangleInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_sampleCount);
5999 virtual void checkSupport (Context& context) const
6001 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN &&
6002 context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
6003 !context.getPortabilitySubsetFeatures().triangleFans)
6005 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
6009 const VkPrimitiveTopology m_primitiveTopology;
6013 class LineInterpolationTestInstance : public BaseRenderingTestInstance
6016 LineInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, PrimitiveStrictness strictness, VkSampleCountFlagBits sampleCount);
6018 virtual tcu::TestStatus iterate (void);
6021 void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
6022 void extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
6023 virtual float getLineWidth (void) const;
6025 VkPrimitiveTopology m_primitiveTopology;
6026 const bool m_projective;
6027 const int m_iterationCount;
6028 const PrimitiveWideness m_primitiveWideness;
6031 bool m_allIterationsPassed;
6032 float m_maxLineWidth;
6033 std::vector<float> m_lineWidths;
6035 PrimitiveStrictness m_strictness;
6038 LineInterpolationTestInstance::LineInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, PrimitiveStrictness strictness, VkSampleCountFlagBits sampleCount)
6039 : BaseRenderingTestInstance (context, sampleCount)
6040 , m_primitiveTopology (primitiveTopology)
6041 , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
6042 , m_iterationCount (3)
6043 , m_primitiveWideness (wideness)
6045 , m_allIterationsPassed (true)
6046 , m_maxLineWidth (1.0f)
6047 , m_flatshade ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
6048 , m_strictness (strictness)
6050 DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
6052 // create line widths
6053 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
6055 m_lineWidths.resize(m_iterationCount, 1.0f);
6057 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
6059 const float* range = context.getDeviceProperties().limits.lineWidthRange;
6061 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
6063 DE_ASSERT(range[1] > 1.0f);
6065 // set hand picked sizes
6066 m_lineWidths.push_back(5.0f);
6067 m_lineWidths.push_back(10.0f);
6068 m_lineWidths.push_back(range[1]);
6069 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
6071 m_maxLineWidth = range[1];
6077 tcu::TestStatus LineInterpolationTestInstance::iterate (void)
6079 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
6080 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
6081 const float lineWidth = getLineWidth();
6082 tcu::Surface resultImage (m_renderSize, m_renderSize);
6083 std::vector<tcu::Vec4> drawBuffer;
6084 std::vector<tcu::Vec4> colorBuffer;
6085 std::vector<LineSceneSpec::SceneLine> lines;
6088 if (lineWidth <= m_maxLineWidth)
6091 generateVertices(m_iteration, drawBuffer, colorBuffer);
6092 extractLines(lines, drawBuffer, colorBuffer);
6096 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
6097 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
6098 m_context.getTestContext().getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
6102 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitiveTopology);
6106 RasterizationArguments args;
6107 LineSceneSpec scene;
6109 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
6111 args.numSamples = m_multisampling ? 1 : 0;
6112 args.subpixelBits = m_subpixelBits;
6113 args.redBits = colorBits[0];
6114 args.greenBits = colorBits[1];
6115 args.blueBits = colorBits[2];
6117 scene.lines.swap(lines);
6118 scene.lineWidth = getLineWidth();
6120 switch (m_strictness)
6122 case PRIMITIVESTRICTNESS_STRICT:
6124 if (!verifyTriangulatedLineGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog(), true))
6125 m_allIterationsPassed = false;
6130 case PRIMITIVESTRICTNESS_NONSTRICT:
6131 case PRIMITIVESTRICTNESS_IGNORE:
6133 if (!verifyTriangulatedLineGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog(), false, true))
6134 m_allIterationsPassed = false;
6140 TCU_THROW(InternalError, "Not implemented");
6145 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
6148 if (++m_iteration == m_iterationCount)
6150 if (m_allIterationsPassed)
6151 return tcu::TestStatus::pass("Pass");
6153 return tcu::TestStatus::fail("Incorrect rasterization");
6156 return tcu::TestStatus::incomplete();
6159 void LineInterpolationTestInstance::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
6161 // use only red, green and blue
6162 const tcu::Vec4 colors[] =
6164 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
6165 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
6166 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
6169 de::Random rnd(123 + iteration * 1000 + (int)m_primitiveTopology);
6171 outVertices.resize(6);
6172 outColors.resize(6);
6174 for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
6176 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
6177 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
6178 outVertices[vtxNdx].z() = 0.0f;
6181 outVertices[vtxNdx].w() = 1.0f;
6184 const float w = rnd.getFloat(0.2f, 4.0f);
6186 outVertices[vtxNdx].x() *= w;
6187 outVertices[vtxNdx].y() *= w;
6188 outVertices[vtxNdx].z() *= w;
6189 outVertices[vtxNdx].w() = w;
6192 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
6196 void LineInterpolationTestInstance::extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
6198 switch (m_primitiveTopology)
6200 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
6202 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; vtxNdx += 2)
6204 LineSceneSpec::SceneLine line;
6205 line.positions[0] = vertices[vtxNdx + 0];
6206 line.positions[1] = vertices[vtxNdx + 1];
6210 line.colors[0] = colors[vtxNdx];
6211 line.colors[1] = colors[vtxNdx];
6215 line.colors[0] = colors[vtxNdx + 0];
6216 line.colors[1] = colors[vtxNdx + 1];
6219 outLines.push_back(line);
6224 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
6226 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
6228 LineSceneSpec::SceneLine line;
6229 line.positions[0] = vertices[vtxNdx + 0];
6230 line.positions[1] = vertices[vtxNdx + 1];
6234 line.colors[0] = colors[vtxNdx];
6235 line.colors[1] = colors[vtxNdx];
6239 line.colors[0] = colors[vtxNdx + 0];
6240 line.colors[1] = colors[vtxNdx + 1];
6243 outLines.push_back(line);
6253 float LineInterpolationTestInstance::getLineWidth (void) const
6255 return m_lineWidths[m_iteration];
6258 class LineInterpolationTestCase : public BaseRenderingTestCase
6261 LineInterpolationTestCase (tcu::TestContext& context,
6262 const std::string& name,
6263 const std::string& description,
6264 VkPrimitiveTopology primitiveTopology,
6266 PrimitiveWideness wideness,
6267 PrimitiveStrictness strictness,
6268 VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
6269 : BaseRenderingTestCase (context, name, description, sampleCount, (flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
6270 , m_primitiveTopology (primitiveTopology)
6272 , m_wideness (wideness)
6273 , m_strictness (strictness)
6276 virtual TestInstance* createInstance (Context& context) const
6278 return new LineInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_wideness, m_strictness, m_sampleCount);
6281 virtual void checkSupport (Context& context) const
6283 if (m_strictness == PRIMITIVESTRICTNESS_STRICT &&
6284 !context.getDeviceProperties().limits.strictLines)
6285 TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
6287 if (m_wideness == PRIMITIVEWIDENESS_WIDE)
6288 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_WIDE_LINES);
6291 const VkPrimitiveTopology m_primitiveTopology;
6293 const PrimitiveWideness m_wideness;
6294 const PrimitiveStrictness m_strictness;
6297 class StrideZeroCase : public vkt::TestCase
6302 std::vector<tcu::Vec2> bufferData;
6303 deUint32 drawVertexCount;
6306 StrideZeroCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const Params& params)
6307 : vkt::TestCase (testCtx, name, description)
6311 virtual ~StrideZeroCase (void) {}
6313 virtual void initPrograms (vk::SourceCollections& programCollection) const;
6314 virtual TestInstance* createInstance (Context& context) const;
6315 virtual void checkSupport (Context& context) const;
6317 static constexpr vk::VkFormat kColorFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
6318 static constexpr vk::VkFormatFeatureFlags kColorFeatures = (vk::VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | vk::VK_FORMAT_FEATURE_TRANSFER_SRC_BIT);
6319 static constexpr vk::VkImageUsageFlags kColorUsage = (vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
6324 // | a | b | a = (-0.5, -0.5)
6325 // | | | b = ( 0.5, -0.5)
6326 // +-----------+ c = (-0.5, 0.5)
6327 // | | | d = ( 0.5, 0.5)
6332 static constexpr deUint32 kImageDim = 2u;
6333 static const float kCornerDelta; // 0.5f;
6335 static const tcu::Vec4 kClearColor;
6336 static const tcu::Vec4 kDrawColor;
6342 const float StrideZeroCase::kCornerDelta = 0.5f;
6343 const tcu::Vec4 StrideZeroCase::kClearColor (0.0f, 0.0f, 0.0f, 1.0f);
6344 const tcu::Vec4 StrideZeroCase::kDrawColor (1.0f, 1.0f, 1.0f, 1.0f);
6346 class StrideZeroInstance : public vkt::TestInstance
6349 StrideZeroInstance (Context& context, const StrideZeroCase::Params& params)
6350 : vkt::TestInstance (context)
6354 virtual ~StrideZeroInstance (void) {}
6356 virtual tcu::TestStatus iterate (void);
6359 StrideZeroCase::Params m_params;
6362 void StrideZeroCase::initPrograms (vk::SourceCollections& programCollection) const
6364 std::ostringstream vert;
6365 std::ostringstream frag;
6367 std::ostringstream drawColor;
6369 << std::setprecision(2) << std::fixed
6370 << "vec4(" << kDrawColor.x() << ", " << kDrawColor.y() << ", " << kDrawColor.z() << ", " << kDrawColor.w() << ")";
6374 << "layout (location=0) in vec2 inPos;\n"
6375 << "void main() {\n"
6376 << " gl_Position = vec4(inPos, 0.0, 1.0);\n"
6377 << " gl_PointSize = 1.0;\n"
6383 << "layout (location=0) out vec4 outColor;\n"
6384 << "void main() {\n"
6385 << " outColor = " << drawColor.str() << ";\n"
6389 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
6390 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
6393 TestInstance* StrideZeroCase::createInstance (Context& context) const
6395 return new StrideZeroInstance(context, m_params);
6398 void StrideZeroCase::checkSupport (Context& context) const
6400 const auto properties = vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), kColorFormat);
6401 if ((properties.optimalTilingFeatures & kColorFeatures) != kColorFeatures)
6402 TCU_THROW(NotSupportedError, "Required image format not supported");
6405 // Creates a vertex buffer with the given data but uses zero as the binding stride.
6406 // Then, tries to draw the requested number of points. Only the first point should ever be used.
6407 tcu::TestStatus StrideZeroInstance::iterate (void)
6409 const auto& vkd = m_context.getDeviceInterface();
6410 const auto device = m_context.getDevice();
6411 auto& alloc = m_context.getDefaultAllocator();
6412 const auto queue = m_context.getUniversalQueue();
6413 const auto queueIndex = m_context.getUniversalQueueFamilyIndex();
6414 constexpr auto kImageDim = StrideZeroCase::kImageDim;
6415 const auto colorExtent = vk::makeExtent3D(kImageDim, kImageDim, 1u);
6417 // Prepare vertex buffer.
6418 const auto vertexBufferSize = static_cast<vk::VkDeviceSize>(m_params.bufferData.size() * sizeof(decltype(m_params.bufferData)::value_type));
6419 const auto vertexBufferInfo = vk::makeBufferCreateInfo(vertexBufferSize, vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
6420 const vk::BufferWithMemory vertexBuffer( vkd, device, alloc, vertexBufferInfo, vk::MemoryRequirement::HostVisible);
6421 auto& vertexBufferAlloc = vertexBuffer.getAllocation();
6422 const vk::VkDeviceSize vertexBufferOffset = 0ull;
6423 deMemcpy(vertexBufferAlloc.getHostPtr(), m_params.bufferData.data(), static_cast<size_t>(vertexBufferSize));
6424 flushAlloc(vkd, device, vertexBufferAlloc);
6426 // Prepare render image.
6427 const vk::VkImageCreateInfo colorAttachmentInfo =
6429 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
6430 nullptr, // const void* pNext;
6431 0u, // VkImageCreateFlags flags;
6432 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType;
6433 StrideZeroCase::kColorFormat, // VkFormat format;
6434 colorExtent, // VkExtent3D extent;
6435 1u, // deUint32 mipLevels;
6436 1u, // deUint32 arrayLayers;
6437 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
6438 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
6439 StrideZeroCase::kColorUsage, // VkImageUsageFlags usage;
6440 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
6441 1u, // deUint32 queueFamilyIndexCount;
6442 &queueIndex, // const deUint32* pQueueFamilyIndices;
6443 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
6445 const vk::ImageWithMemory colorAttachment(vkd, device, alloc, colorAttachmentInfo, vk::MemoryRequirement::Any);
6447 const auto colorSubresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
6448 const auto colorAttachmentView = vk::makeImageView(vkd, device, colorAttachment.get(), vk::VK_IMAGE_VIEW_TYPE_2D, StrideZeroCase::kColorFormat, colorSubresourceRange);
6450 const vk::VkVertexInputBindingDescription vertexBinding =
6452 0u, // deUint32 binding;
6453 0u, // deUint32 stride; [IMPORTANT]
6454 vk::VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
6457 const vk::VkVertexInputAttributeDescription vertexAttribute =
6459 0u, // deUint32 location;
6460 0u, // deUint32 binding;
6461 vk::VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
6462 0u, // deUint32 offset;
6465 const vk::VkPipelineVertexInputStateCreateInfo vertexInput =
6467 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
6468 nullptr, // const void* pNext;
6469 0u, // VkPipelineVertexInputStateCreateFlags flags;
6470 1u, // deUint32 vertexBindingDescriptionCount;
6471 &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
6472 1u, // deUint32 vertexAttributeDescriptionCount;
6473 &vertexAttribute, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
6476 const auto renderArea = vk::makeRect2D(kImageDim, kImageDim);
6477 const auto viewports = std::vector<vk::VkViewport>(1, vk::makeViewport(kImageDim, kImageDim));
6478 const auto scissors = std::vector<vk::VkRect2D>(1, renderArea);
6479 const auto pipelineLayout = vk::makePipelineLayout(vkd, device);
6480 const auto vertexShader = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
6481 const auto fragmentShader = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
6482 const auto renderPass = vk::makeRenderPass(vkd, device, StrideZeroCase::kColorFormat);
6483 const auto graphicsPipeline = vk::makeGraphicsPipeline(vkd, device, pipelineLayout.get(),
6484 vertexShader.get(), DE_NULL, DE_NULL, DE_NULL, fragmentShader.get(), // Shaders.
6485 renderPass.get(), viewports, scissors, vk::VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0u, 0u, // Render pass, viewports, scissors, topology.
6486 &vertexInput); // Vertex input state.
6487 const auto framebuffer = vk::makeFramebuffer(vkd, device, renderPass.get(), colorAttachmentView.get(), kImageDim, kImageDim);
6489 const auto cmdPool = vk::makeCommandPool(vkd, device, queueIndex);
6490 const auto cmdBufferPtr = vk::allocateCommandBuffer(vkd, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6491 const auto cmdBuffer = cmdBufferPtr.get();
6493 // Buffer used to verify results.
6494 const auto tcuFormat = vk::mapVkFormat(StrideZeroCase::kColorFormat);
6495 const auto colorBufferSize = static_cast<vk::VkDeviceSize>(tcu::getPixelSize(tcuFormat)) * kImageDim * kImageDim;
6496 const auto colorBufferInfo = vk::makeBufferCreateInfo(colorBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT);
6497 const vk::BufferWithMemory colorBuffer (vkd, device, alloc, colorBufferInfo, vk::MemoryRequirement::HostVisible);
6498 auto& colorBufferAlloc = colorBuffer.getAllocation();
6499 void* colorBufferPtr = colorBufferAlloc.getHostPtr();
6500 const auto colorLayers = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
6501 const auto copyRegion = vk::makeBufferImageCopy(colorExtent, colorLayers);
6503 // Barriers from attachment to buffer and buffer to host.
6504 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);
6505 const auto colorBufferBarrier = vk::makeBufferMemoryBarrier (vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_HOST_READ_BIT, colorBuffer.get(), 0ull, colorBufferSize);
6507 vk::beginCommandBuffer(vkd, cmdBuffer);
6508 vk::beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), renderArea, StrideZeroCase::kClearColor);
6509 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
6510 vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
6511 vkd.cmdDraw(cmdBuffer, m_params.drawVertexCount, 1u, 0u, 0u);
6512 vk::endRenderPass(vkd, cmdBuffer);
6513 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &colorAttachmentBarrier);
6514 vkd.cmdCopyImageToBuffer(cmdBuffer, colorAttachment.get(), vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, colorBuffer.get(), 1u, ©Region);
6515 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &colorBufferBarrier, 0u, nullptr);
6516 vk::endCommandBuffer(vkd, cmdBuffer);
6518 vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
6520 // Invalidate color buffer alloc.
6521 vk::invalidateAlloc(vkd, device, colorBufferAlloc);
6524 const int imageDimI = static_cast<int>(kImageDim);
6525 const tcu::ConstPixelBufferAccess colorPixels (tcuFormat, imageDimI, imageDimI, 1, colorBufferPtr);
6526 tcu::TestStatus testStatus = tcu::TestStatus::pass("Pass");
6527 auto& log = m_context.getTestContext().getLog();
6529 for (int x = 0; x < imageDimI; ++x)
6530 for (int y = 0; y < imageDimI; ++y)
6532 // Only the top-left corner should have draw data.
6533 const auto expectedColor = ((x == 0 && y == 0) ? StrideZeroCase::kDrawColor : StrideZeroCase::kClearColor);
6534 const auto imageColor = colorPixels.getPixel(x, y);
6536 if (expectedColor != imageColor)
6539 << tcu::TestLog::Message
6540 << "Unexpected color found in pixel (" << x << ", " << y << "): "
6541 << "expected (" << expectedColor.x() << ", " << expectedColor.y() << ", " << expectedColor.z() << ", " << expectedColor.w() << ") "
6542 << "and found (" << imageColor.x() << ", " << imageColor.y() << ", " << imageColor.z() << ", " << imageColor.w() << ")"
6543 << tcu::TestLog::EndMessage;
6545 testStatus = tcu::TestStatus::fail("Failed; Check log for details");
6552 void createRasterizationTests (tcu::TestCaseGroup* rasterizationTests)
6554 tcu::TestContext& testCtx = rasterizationTests->getTestContext();
6558 tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(testCtx, "primitives", "Primitive rasterization");
6560 rasterizationTests->addChild(primitives);
6562 tcu::TestCaseGroup* const nostippleTests = new tcu::TestCaseGroup(testCtx, "no_stipple", "No stipple");
6563 tcu::TestCaseGroup* const stippleStaticTests = new tcu::TestCaseGroup(testCtx, "static_stipple", "Line stipple static");
6564 tcu::TestCaseGroup* const stippleDynamicTests = new tcu::TestCaseGroup(testCtx, "dynamic_stipple", "Line stipple dynamic");
6565 tcu::TestCaseGroup* const strideZeroTests = new tcu::TestCaseGroup(testCtx, "stride_zero", "Test input assembly with stride zero");
6567 primitives->addChild(nostippleTests);
6568 primitives->addChild(stippleStaticTests);
6569 primitives->addChild(stippleDynamicTests);
6570 primitives->addChild(strideZeroTests);
6575 StrideZeroCase::Params params;
6576 params.bufferData.emplace_back(-StrideZeroCase::kCornerDelta, -StrideZeroCase::kCornerDelta);
6577 params.drawVertexCount = 1u;
6578 strideZeroTests->addChild(new StrideZeroCase(testCtx, "single_point", "Attempt to draw 1 point with stride 0", params));
6581 StrideZeroCase::Params params;
6582 params.bufferData.emplace_back(-StrideZeroCase::kCornerDelta, -StrideZeroCase::kCornerDelta);
6583 params.bufferData.emplace_back( StrideZeroCase::kCornerDelta, -StrideZeroCase::kCornerDelta);
6584 params.bufferData.emplace_back(-StrideZeroCase::kCornerDelta, StrideZeroCase::kCornerDelta);
6585 params.bufferData.emplace_back( StrideZeroCase::kCornerDelta, StrideZeroCase::kCornerDelta);
6586 params.drawVertexCount = static_cast<deUint32>(params.bufferData.size());
6587 strideZeroTests->addChild(new StrideZeroCase(testCtx, "four_points", "Attempt to draw 4 points with stride 0 and 4 points in the buffer", params));
6590 StrideZeroCase::Params params;
6591 params.bufferData.emplace_back(-StrideZeroCase::kCornerDelta, -StrideZeroCase::kCornerDelta);
6592 params.drawVertexCount = 100000u;
6593 strideZeroTests->addChild(new StrideZeroCase(testCtx, "many_points", "Attempt to draw many points with stride 0 with one point in the buffer", params));
6597 nostippleTests->addChild(new BaseTestCase<TrianglesTestInstance> (testCtx, "triangles", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result"));
6598 nostippleTests->addChild(new BaseTestCase<TriangleStripTestInstance> (testCtx, "triangle_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, verify rasterization result"));
6599 nostippleTests->addChild(new BaseTestCase<TriangleFanTestInstance> (testCtx, "triangle_fan", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, verify rasterization result"));
6600 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));
6602 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));
6603 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));
6604 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));
6605 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));
6607 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));
6608 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));
6609 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));
6610 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));
6612 for (int i = 0; i < 3; ++i) {
6614 tcu::TestCaseGroup *g = i == 2 ? stippleDynamicTests : i == 1 ? stippleStaticTests : nostippleTests;
6616 LineStipple stipple = (LineStipple)i;
6618 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT, i == 0 ? RESOLUTION_NPOT : 0));
6619 g->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "line_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
6620 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, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
6621 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, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT));
6623 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "rectangular_lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT));
6624 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, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT));
6625 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, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT));
6626 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, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT));
6628 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "bresenham_lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT));
6629 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, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT));
6630 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, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT));
6631 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, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT));
6633 g->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "smooth_lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, true, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT));
6634 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, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT));
6635 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, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT));
6636 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, VK_SAMPLE_COUNT_1_BIT, stipple, VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT));
6642 tcu::TestCaseGroup* const primitiveSize = new tcu::TestCaseGroup(testCtx, "primitive_size", "Primitive size");
6643 rasterizationTests->addChild(primitiveSize);
6647 tcu::TestCaseGroup* const points = new tcu::TestCaseGroup(testCtx, "points", "Point size");
6649 static const struct TestCombinations
6651 const deUint32 renderSize;
6652 const float pointSize;
6653 } testCombinations[] =
6665 for (size_t testCombNdx = 0; testCombNdx < DE_LENGTH_OF_ARRAY(testCombinations); testCombNdx++)
6667 std::string testCaseName = "point_size_" + de::toString(testCombinations[testCombNdx].pointSize);
6668 deUint32 renderSize = testCombinations[testCombNdx].renderSize;
6669 float pointSize = testCombinations[testCombNdx].pointSize;
6671 points->addChild(new PointSizeTestCase<PointSizeTestInstance> (testCtx, testCaseName, testCaseName, renderSize, pointSize));
6674 primitiveSize->addChild(points);
6680 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(testCtx, "fill_rules", "Primitive fill rules");
6682 rasterizationTests->addChild(fillRules);
6684 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_BASIC));
6685 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad_reverse", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_REVERSED));
6686 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_full", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_FULL));
6687 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_partly", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_PARTIAL));
6688 fillRules->addChild(new FillRuleTestCase(testCtx, "projected", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_PROJECTED));
6693 static const struct CullMode
6695 VkCullModeFlags mode;
6699 { VK_CULL_MODE_FRONT_BIT, "front_" },
6700 { VK_CULL_MODE_BACK_BIT, "back_" },
6701 { VK_CULL_MODE_FRONT_AND_BACK, "both_" },
6703 static const struct PrimitiveType
6705 VkPrimitiveTopology type;
6707 } primitiveTypes[] =
6709 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangles" },
6710 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, "triangle_strip" },
6711 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, "triangle_fan" },
6713 static const struct FrontFaceOrder
6716 const char* postfix;
6719 { VK_FRONT_FACE_COUNTER_CLOCKWISE, "" },
6720 { VK_FRONT_FACE_CLOCKWISE, "_reverse" },
6723 static const struct PolygonMode
6729 { VK_POLYGON_MODE_FILL, "" },
6730 { VK_POLYGON_MODE_LINE, "_line" },
6731 { VK_POLYGON_MODE_POINT, "_point" }
6734 tcu::TestCaseGroup* const culling = new tcu::TestCaseGroup(testCtx, "culling", "Culling");
6736 rasterizationTests->addChild(culling);
6738 for (int cullModeNdx = 0; cullModeNdx < DE_LENGTH_OF_ARRAY(cullModes); ++cullModeNdx)
6739 for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveNdx)
6740 for (int frontOrderNdx = 0; frontOrderNdx < DE_LENGTH_OF_ARRAY(frontOrders); ++frontOrderNdx)
6741 for (int polygonModeNdx = 0; polygonModeNdx < DE_LENGTH_OF_ARRAY(polygonModes); ++polygonModeNdx)
6743 if (!(cullModes[cullModeNdx].mode == VK_CULL_MODE_FRONT_AND_BACK && polygonModes[polygonModeNdx].mode != VK_POLYGON_MODE_FILL))
6745 const std::string name = std::string(cullModes[cullModeNdx].prefix) + primitiveTypes[primitiveNdx].name + frontOrders[frontOrderNdx].postfix + polygonModes[polygonModeNdx].name;
6746 culling->addChild(new CullingTestCase(testCtx, name, "Test primitive culling.", cullModes[cullModeNdx].mode, primitiveTypes[primitiveNdx].type, frontOrders[frontOrderNdx].mode, polygonModes[polygonModeNdx].mode));
6753 static const struct PrimitiveType
6755 VkPrimitiveTopology type;
6757 } primitiveTypes[] =
6759 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangle_list" },
6760 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, "triangle_strip" },
6761 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, "triangle_fan" },
6762 { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, "line_list" },
6763 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, "line_strip" },
6764 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, "point_list" }
6767 static const struct queryPipeline
6773 { DE_FALSE, "query_pipeline_false" },
6774 { DE_TRUE, "query_pipeline_true" },
6777 tcu::TestCaseGroup* const discard = new tcu::TestCaseGroup(testCtx, "discard", "Rasterizer discard");
6779 for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveNdx)
6781 tcu::TestCaseGroup* const primitive = new tcu::TestCaseGroup(testCtx, primitiveTypes[primitiveNdx].name, "Rasterizer discard");
6783 for (int useQueryNdx = 0; useQueryNdx < DE_LENGTH_OF_ARRAY(queryPipeline); useQueryNdx++)
6785 const std::string name = std::string(queryPipeline[useQueryNdx].name);
6787 primitive->addChild(new DiscardTestCase(testCtx, name, "Test primitive discarding.", primitiveTypes[primitiveNdx].type, queryPipeline[useQueryNdx].useQuery));
6790 discard->addChild(primitive);
6793 rasterizationTests->addChild(discard);
6802 } overestimateSizes;
6804 const overestimateSizes overestimateNormalSizes[] =
6813 { -TCU_INFINITY, "min" },
6814 { TCU_INFINITY, "max" },
6816 const overestimateSizes overestimateDegenerate[] =
6820 { -TCU_INFINITY, "min" },
6821 { TCU_INFINITY, "max" },
6823 const overestimateSizes underestimateLineWidths[] =
6829 const overestimateSizes underestimatePointSizes[] =
6838 const struct PrimitiveType
6840 VkPrimitiveTopology type;
6845 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangles" },
6846 { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, "lines" },
6847 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, "points" }
6849 const VkSampleCountFlagBits samples[] =
6851 VK_SAMPLE_COUNT_1_BIT,
6852 VK_SAMPLE_COUNT_2_BIT,
6853 VK_SAMPLE_COUNT_4_BIT,
6854 VK_SAMPLE_COUNT_8_BIT,
6855 VK_SAMPLE_COUNT_16_BIT,
6856 VK_SAMPLE_COUNT_32_BIT,
6857 VK_SAMPLE_COUNT_64_BIT
6860 tcu::TestCaseGroup* const conservative = new tcu::TestCaseGroup(testCtx, "conservative", "Conservative rasterization tests");
6862 rasterizationTests->addChild(conservative);
6865 tcu::TestCaseGroup* const overestimate = new tcu::TestCaseGroup(testCtx, "overestimate", "Overestimate tests");
6867 conservative->addChild(overestimate);
6869 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); ++samplesNdx)
6871 const std::string samplesGroupName = "samples_" + de::toString(samples[samplesNdx]);
6873 tcu::TestCaseGroup* const samplesGroup = new tcu::TestCaseGroup(testCtx, samplesGroupName.c_str(), "Samples tests");
6875 overestimate->addChild(samplesGroup);
6877 for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveTypeNdx)
6879 tcu::TestCaseGroup* const primitiveGroup = new tcu::TestCaseGroup(testCtx, primitiveTypes[primitiveTypeNdx].name, "Primitive tests");
6881 samplesGroup->addChild(primitiveGroup);
6884 tcu::TestCaseGroup* const normal = new tcu::TestCaseGroup(testCtx, "normal", "Normal conservative rasterization tests");
6886 primitiveGroup->addChild(normal);
6888 for (int overestimateSizesNdx = 0; overestimateSizesNdx < DE_LENGTH_OF_ARRAY(overestimateNormalSizes); ++overestimateSizesNdx)
6890 const ConservativeTestConfig config =
6892 VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
6893 overestimateNormalSizes[overestimateSizesNdx].size, // float extraOverestimationSize;
6894 primitiveTypes[primitiveTypeNdx].type, // VkPrimitiveTopology primitiveTopology;
6895 false, // bool degeneratePrimitives;
6896 1.0f, // float lineWidth;
6897 RESOLUTION_POT, // deUint32 resolution;
6900 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
6901 normal->addChild(new ConservativeTestCase<ConservativeTraingleTestInstance> (testCtx,
6902 overestimateNormalSizes[overestimateSizesNdx].name,
6903 "Overestimate test, verify rasterization result",
6905 samples[samplesNdx]));
6907 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_LINE_LIST)
6908 normal->addChild(new ConservativeTestCase<ConservativeLineTestInstance> (testCtx,
6909 overestimateNormalSizes[overestimateSizesNdx].name,
6910 "Overestimate test, verify rasterization result",
6912 samples[samplesNdx]));
6914 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
6915 normal->addChild(new ConservativeTestCase<ConservativePointTestInstance> (testCtx,
6916 overestimateNormalSizes[overestimateSizesNdx].name,
6917 "Overestimate test, verify rasterization result",
6919 samples[samplesNdx]));
6924 tcu::TestCaseGroup* const degenerate = new tcu::TestCaseGroup(testCtx, "degenerate", "Degenerate primitives conservative rasterization tests");
6926 primitiveGroup->addChild(degenerate);
6928 for (int overestimateSizesNdx = 0; overestimateSizesNdx < DE_LENGTH_OF_ARRAY(overestimateDegenerate); ++overestimateSizesNdx)
6930 const ConservativeTestConfig config =
6932 VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
6933 overestimateDegenerate[overestimateSizesNdx].size, // float extraOverestimationSize;
6934 primitiveTypes[primitiveTypeNdx].type, // VkPrimitiveTopology primitiveTopology;
6935 true, // bool degeneratePrimitives;
6936 1.0f, // float lineWidth;
6937 64u, // deUint32 resolution;
6940 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
6941 degenerate->addChild(new ConservativeTestCase<ConservativeTraingleTestInstance> (testCtx,
6942 overestimateDegenerate[overestimateSizesNdx].name,
6943 "Overestimate triangle test, verify rasterization result",
6945 samples[samplesNdx]));
6947 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_LINE_LIST)
6948 degenerate->addChild(new ConservativeTestCase<ConservativeLineTestInstance> (testCtx,
6949 overestimateDegenerate[overestimateSizesNdx].name,
6950 "Overestimate line test, verify rasterization result",
6952 samples[samplesNdx]));
6960 tcu::TestCaseGroup* const underestimate = new tcu::TestCaseGroup(testCtx, "underestimate", "Underestimate tests");
6962 conservative->addChild(underestimate);
6964 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); ++samplesNdx)
6966 const std::string samplesGroupName = "samples_" + de::toString(samples[samplesNdx]);
6968 tcu::TestCaseGroup* const samplesGroup = new tcu::TestCaseGroup(testCtx, samplesGroupName.c_str(), "Samples tests");
6970 underestimate->addChild(samplesGroup);
6972 for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveTypeNdx)
6974 tcu::TestCaseGroup* const primitiveGroup = new tcu::TestCaseGroup(testCtx, primitiveTypes[primitiveTypeNdx].name, "Primitive tests");
6976 samplesGroup->addChild(primitiveGroup);
6979 tcu::TestCaseGroup* const normal = new tcu::TestCaseGroup(testCtx, "normal", "Normal conservative rasterization tests");
6981 primitiveGroup->addChild(normal);
6983 ConservativeTestConfig config =
6985 VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
6986 0.0f, // float extraOverestimationSize;
6987 primitiveTypes[primitiveTypeNdx].type, // VkPrimitiveTopology primitiveTopology;
6988 false, // bool degeneratePrimitives;
6989 1.0f, // float lineWidth;
6990 64u, // deUint32 resolution;
6993 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
6994 normal->addChild(new ConservativeTestCase<ConservativeTraingleTestInstance> (testCtx,
6996 "Underestimate test, verify rasterization result",
6998 samples[samplesNdx]));
7000 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_LINE_LIST)
7002 for (int underestimateWidthNdx = 0; underestimateWidthNdx < DE_LENGTH_OF_ARRAY(underestimateLineWidths); ++underestimateWidthNdx)
7004 config.lineWidth = underestimateLineWidths[underestimateWidthNdx].size;
7005 normal->addChild(new ConservativeTestCase<ConservativeLineTestInstance> (testCtx,
7006 underestimateLineWidths[underestimateWidthNdx].name,
7007 "Underestimate test, verify rasterization result",
7009 samples[samplesNdx]));
7013 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
7015 for (int underestimatePointSizeNdx = 0; underestimatePointSizeNdx < DE_LENGTH_OF_ARRAY(underestimatePointSizes); ++underestimatePointSizeNdx)
7017 config.lineWidth = underestimatePointSizes[underestimatePointSizeNdx].size;
7018 normal->addChild(new ConservativeTestCase<ConservativePointTestInstance> (testCtx,
7019 underestimatePointSizes[underestimatePointSizeNdx].name,
7020 "Underestimate test, verify rasterization result",
7022 samples[samplesNdx]));
7028 tcu::TestCaseGroup* const degenerate = new tcu::TestCaseGroup(testCtx, "degenerate", "Degenerate primitives conservative rasterization tests");
7030 primitiveGroup->addChild(degenerate);
7032 ConservativeTestConfig config =
7034 VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
7035 0.0f, // float extraOverestimationSize;
7036 primitiveTypes[primitiveTypeNdx].type, // VkPrimitiveTopology primitiveTopology;
7037 true, // bool degeneratePrimitives;
7038 1.0f, // float lineWidth;
7039 64u, // deUint32 resolution;
7042 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
7043 degenerate->addChild(new ConservativeTestCase<ConservativeTraingleTestInstance> (testCtx,
7045 "Underestimate triangle test, verify rasterization result",
7047 samples[samplesNdx]));
7049 if (primitiveTypes[primitiveTypeNdx].type == VK_PRIMITIVE_TOPOLOGY_LINE_LIST)
7051 for (int underestimateWidthNdx = 0; underestimateWidthNdx < DE_LENGTH_OF_ARRAY(underestimateLineWidths); ++underestimateWidthNdx)
7053 config.lineWidth = underestimateLineWidths[underestimateWidthNdx].size;
7054 degenerate->addChild(new ConservativeTestCase<ConservativeLineTestInstance> (testCtx,
7055 underestimateLineWidths[underestimateWidthNdx].name,
7056 "Underestimate line test, verify rasterization result",
7058 samples[samplesNdx]));
7069 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(testCtx, "interpolation", "Test interpolation");
7071 rasterizationTests->addChild(interpolation);
7075 tcu::TestCaseGroup* const basic = new tcu::TestCaseGroup(testCtx, "basic", "Non-projective interpolation");
7077 interpolation->addChild(basic);
7079 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_NONE));
7080 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_NONE));
7081 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_NONE));
7082 basic->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE));
7083 basic->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE));
7084 basic->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE));
7085 basic->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE));
7087 basic->addChild(new LineInterpolationTestCase (testCtx, "strict_lines", "Verify strict line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT));
7088 basic->addChild(new LineInterpolationTestCase (testCtx, "strict_line_strip", "Verify strict line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT));
7089 basic->addChild(new LineInterpolationTestCase (testCtx, "strict_lines_wide", "Verify strict wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_STRICT));
7090 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));
7092 basic->addChild(new LineInterpolationTestCase (testCtx, "non_strict_lines", "Verify non-strict line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_NONSTRICT));
7093 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));
7094 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));
7095 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));
7100 tcu::TestCaseGroup* const projected = new tcu::TestCaseGroup(testCtx, "projected", "Projective interpolation");
7102 interpolation->addChild(projected);
7104 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_PROJECTED));
7105 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_PROJECTED));
7106 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_PROJECTED));
7107 projected->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE));
7108 projected->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE));
7109 projected->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE));
7110 projected->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE));
7112 projected->addChild(new LineInterpolationTestCase (testCtx, "strict_lines", "Verify strict line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT));
7113 projected->addChild(new LineInterpolationTestCase (testCtx, "strict_line_strip", "Verify strict line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT));
7114 projected->addChild(new LineInterpolationTestCase (testCtx, "strict_lines_wide", "Verify strict wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_STRICT));
7115 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));
7117 projected->addChild(new LineInterpolationTestCase (testCtx, "non_strict_lines", "Verify non-strict line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_NONSTRICT));
7118 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));
7119 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));
7120 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));
7126 tcu::TestCaseGroup* const flatshading = new tcu::TestCaseGroup(testCtx, "flatshading", "Test flatshading");
7128 rasterizationTests->addChild(flatshading);
7130 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_FLATSHADE));
7131 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_FLATSHADE));
7132 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_FLATSHADE));
7133 flatshading->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE));
7134 flatshading->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE));
7135 flatshading->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE));
7136 flatshading->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE));
7138 flatshading->addChild(new LineInterpolationTestCase (testCtx, "strict_lines", "Verify strict line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT));
7139 flatshading->addChild(new LineInterpolationTestCase (testCtx, "strict_line_strip", "Verify strict line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT));
7140 flatshading->addChild(new LineInterpolationTestCase (testCtx, "strict_lines_wide", "Verify strict wide line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_STRICT));
7141 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));
7143 flatshading->addChild(new LineInterpolationTestCase (testCtx, "non_strict_lines", "Verify non-strict line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_NONSTRICT));
7144 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));
7145 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));
7146 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));
7149 const VkSampleCountFlagBits samples[] =
7151 VK_SAMPLE_COUNT_2_BIT,
7152 VK_SAMPLE_COUNT_4_BIT,
7153 VK_SAMPLE_COUNT_8_BIT,
7154 VK_SAMPLE_COUNT_16_BIT,
7155 VK_SAMPLE_COUNT_32_BIT,
7156 VK_SAMPLE_COUNT_64_BIT
7159 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
7161 std::ostringstream caseName;
7163 caseName << "_multisample_" << (2 << samplesNdx) << "_bit";
7167 tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(testCtx, ("primitives" + caseName.str()).c_str(), "Primitive rasterization");
7169 rasterizationTests->addChild(primitives);
7171 tcu::TestCaseGroup* const nostippleTests = new tcu::TestCaseGroup(testCtx, "no_stipple", "No stipple");
7172 tcu::TestCaseGroup* const stippleStaticTests = new tcu::TestCaseGroup(testCtx, "static_stipple", "Line stipple static");
7173 tcu::TestCaseGroup* const stippleDynamicTests = new tcu::TestCaseGroup(testCtx, "dynamic_stipple", "Line stipple dynamic");
7175 primitives->addChild(nostippleTests);
7176 primitives->addChild(stippleStaticTests);
7177 primitives->addChild(stippleDynamicTests);
7179 nostippleTests->addChild(new BaseTestCase<TrianglesTestInstance> (testCtx, "triangles", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result", samples[samplesNdx]));
7180 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));
7182 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));
7183 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));
7185 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));
7186 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));
7188 for (int i = 0; i < 3; ++i) {
7190 tcu::TestCaseGroup *g = i == 2 ? stippleDynamicTests : i == 1 ? stippleStaticTests : nostippleTests;
7192 LineStipple stipple = (LineStipple)i;
7194 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, i == 0 ? RESOLUTION_NPOT : 0));
7195 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));
7196 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));
7197 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));
7199 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));
7200 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));
7201 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));
7202 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));
7204 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));
7205 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));
7206 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));
7207 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));
7209 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));
7210 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));
7211 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));
7212 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));
7218 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(testCtx, ("fill_rules" + caseName.str()).c_str(), "Primitive fill rules");
7220 rasterizationTests->addChild(fillRules);
7222 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_BASIC, samples[samplesNdx]));
7223 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad_reverse", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_REVERSED, samples[samplesNdx]));
7224 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_full", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_FULL, samples[samplesNdx]));
7225 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_partly", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_PARTIAL, samples[samplesNdx]));
7226 fillRules->addChild(new FillRuleTestCase(testCtx, "projected", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_PROJECTED, samples[samplesNdx]));
7231 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(testCtx, ("interpolation" + caseName.str()).c_str(), "Test interpolation");
7233 rasterizationTests->addChild(interpolation);
7235 interpolation->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_NONE, samples[samplesNdx]));
7236 interpolation->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_IGNORE, samples[samplesNdx]));
7237 interpolation->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, PRIMITIVESTRICTNESS_IGNORE, samples[samplesNdx]));
7239 interpolation->addChild(new LineInterpolationTestCase (testCtx, "strict_lines", "Verify strict line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, PRIMITIVESTRICTNESS_STRICT, samples[samplesNdx]));
7240 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]));
7242 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]));
7243 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]));
7247 // .provoking_vertex
7249 rasterizationTests->addChild(createProvokingVertexTests(testCtx));
7254 tcu::TestCaseGroup* const lineContinuity = new tcu::TestCaseGroup(testCtx, "line_continuity", "Test line continuity");
7255 static const char dataDir[] = "rasterization/line_continuity";
7261 bool requireFillModeNonSolid;
7264 static const Case cases[] =
7266 { "line-strip", "Test line strip drawing produces continuous lines", false },
7267 { "polygon-mode-lines", "Test triangles drawn with lines are continuous", true }
7270 rasterizationTests->addChild(lineContinuity);
7272 for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
7274 const std::string fileName = cases[i].name + ".amber";
7275 cts_amber::AmberTestCase* testCase = cts_amber::createAmberTestCase(testCtx, cases[i].name.c_str(), cases[i].desc.c_str(), dataDir, fileName);
7277 if (cases[i].requireFillModeNonSolid)
7279 testCase->addRequirement("Features.fillModeNonSolid");
7282 lineContinuity->addChild(testCase);
7288 tcu::TestCaseGroup* const depthBias = new tcu::TestCaseGroup(testCtx, "depth_bias", "Test depth bias");
7289 static const char dataDir[] = "rasterization/depth_bias";
7294 vk::VkFormat format;
7295 std::string description;
7298 {"d16_unorm", vk::VK_FORMAT_D16_UNORM, "Test depth bias with format D16_UNORM"},
7299 {"d32_sfloat", vk::VK_FORMAT_D32_SFLOAT, "Test depth bias with format D32_SFLOAT"},
7300 {"d24_unorm", vk::VK_FORMAT_D24_UNORM_S8_UINT, "Test depth bias with format D24_UNORM_S8_UINT"}
7303 for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
7305 const VkImageCreateInfo vkImageCreateInfo = {
7306 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType
7309 VK_IMAGE_TYPE_2D, // imageType
7310 cases[i].format, // format
7311 {250, 250, 1}, // extent
7314 VK_SAMPLE_COUNT_1_BIT, // samples
7315 VK_IMAGE_TILING_OPTIMAL, // tiling
7316 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // usage
7317 VK_SHARING_MODE_EXCLUSIVE, // sharingMode
7318 0, // queueFamilyIndexCount
7319 nullptr, // pQueueFamilyIndices
7320 VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
7323 std::vector<std::string> requirements = std::vector<std::string>(0);
7324 std::vector<VkImageCreateInfo> imageRequirements;
7325 imageRequirements.push_back(vkImageCreateInfo);
7326 const std::string fileName = cases[i].name + ".amber";
7327 cts_amber::AmberTestCase* testCase = cts_amber::createAmberTestCase(testCtx, cases[i].name.c_str(), cases[i].description.c_str(), dataDir, fileName, requirements, imageRequirements);
7329 depthBias->addChild(testCase);
7332 rasterizationTests->addChild(depthBias);
7335 // Fragment shader side effects.
7337 rasterizationTests->addChild(createFragSideEffectsTests(testCtx));
7343 tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
7345 return createTestGroup(testCtx, "rasterization", "Rasterization Tests", createRasterizationTests);