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 "vktRasterizationTests.hpp"
27 #include "tcuRasterizationVerifier.hpp"
28 #include "tcuSurface.hpp"
29 #include "tcuRenderTarget.hpp"
30 #include "tcuVectorUtil.hpp"
31 #include "tcuStringTemplate.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "tcuResultCollector.hpp"
34 #include "vkImageUtil.hpp"
35 #include "deStringUtil.hpp"
36 #include "deRandom.hpp"
37 #include "vktTestCase.hpp"
38 #include "vktTestCaseUtil.hpp"
39 #include "vktTestGroupUtil.hpp"
40 #include "vkPrograms.hpp"
41 #include "vkMemUtil.hpp"
42 #include "vkRefUtil.hpp"
43 #include "vkQueryUtil.hpp"
44 #include "vkBuilderUtil.hpp"
45 #include "vkTypeUtil.hpp"
46 #include "vkCmdUtil.hpp"
47 #include "vkObjUtil.hpp"
55 namespace rasterization
60 using tcu::RasterizationArguments;
61 using tcu::TriangleSceneSpec;
62 using tcu::PointSceneSpec;
63 using tcu::LineSceneSpec;
64 using tcu::LineInterpolationMethod;
66 static const char* const s_shaderVertexTemplate = "#version 310 es\n"
67 "layout(location = 0) in highp vec4 a_position;\n"
68 "layout(location = 1) in highp vec4 a_color;\n"
69 "layout(location = 0) ${INTERPOLATION}out highp vec4 v_color;\n"
70 "layout (set=0, binding=0) uniform PointSize {\n"
71 " highp float u_pointSize;\n"
75 " gl_Position = a_position;\n"
76 " gl_PointSize = u_pointSize;\n"
77 " v_color = a_color;\n"
80 static const char* const s_shaderFragmentTemplate = "#version 310 es\n"
81 "layout(location = 0) out highp vec4 fragColor;\n"
82 "layout(location = 0) ${INTERPOLATION}in highp vec4 v_color;\n"
85 " fragColor = v_color;\n"
87 enum InterpolationCaseFlags
89 INTERPOLATIONFLAGS_NONE = 0,
90 INTERPOLATIONFLAGS_PROJECTED = (1 << 1),
91 INTERPOLATIONFLAGS_FLATSHADE = (1 << 2),
94 enum PrimitiveWideness
96 PRIMITIVEWIDENESS_NARROW = 0,
97 PRIMITIVEWIDENESS_WIDE,
99 PRIMITIVEWIDENESS_LAST
102 class BaseRenderingTestCase : public TestCase
105 BaseRenderingTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deBool flatshade = DE_FALSE);
106 virtual ~BaseRenderingTestCase (void);
108 virtual void initPrograms (vk::SourceCollections& programCollection) const;
111 const VkSampleCountFlagBits m_sampleCount;
112 const deBool m_flatshade;
115 BaseRenderingTestCase::BaseRenderingTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount, deBool flatshade)
116 : TestCase(context, name, description)
117 , m_sampleCount (sampleCount)
118 , m_flatshade (flatshade)
122 void BaseRenderingTestCase::initPrograms (vk::SourceCollections& programCollection) const
124 tcu::StringTemplate vertexSource (s_shaderVertexTemplate);
125 tcu::StringTemplate fragmentSource (s_shaderFragmentTemplate);
126 std::map<std::string, std::string> params;
128 params["INTERPOLATION"] = (m_flatshade) ? ("flat ") : ("");
130 programCollection.glslSources.add("vertext_shader") << glu::VertexSource(vertexSource.specialize(params));
131 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fragmentSource.specialize(params));
134 BaseRenderingTestCase::~BaseRenderingTestCase (void)
138 class BaseRenderingTestInstance : public TestInstance
142 DEFAULT_RENDER_SIZE = 256
145 BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deUint32 renderSize = DEFAULT_RENDER_SIZE);
146 ~BaseRenderingTestInstance (void);
149 void addImageTransitionBarrier (VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const;
150 void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology);
151 void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, const std::vector<tcu::Vec4>& coloDrata, VkPrimitiveTopology primitiveTopology);
152 virtual float getLineWidth (void) const;
153 virtual float getPointSize (void) const;
156 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
159 const VkPipelineColorBlendStateCreateInfo* getColorBlendStateCreateInfo (void) const;
161 const tcu::TextureFormat& getTextureFormat (void) const;
163 const deUint32 m_renderSize;
164 const VkSampleCountFlagBits m_sampleCount;
165 const deUint32 m_subpixelBits;
166 const deBool m_multisampling;
168 const VkFormat m_imageFormat;
169 const tcu::TextureFormat m_textureFormat;
170 Move<VkCommandPool> m_commandPool;
172 Move<VkImage> m_image;
173 de::MovePtr<Allocation> m_imageMemory;
174 Move<VkImageView> m_imageView;
176 Move<VkImage> m_resolvedImage;
177 de::MovePtr<Allocation> m_resolvedImageMemory;
178 Move<VkImageView> m_resolvedImageView;
180 Move<VkRenderPass> m_renderPass;
181 Move<VkFramebuffer> m_frameBuffer;
183 Move<VkDescriptorPool> m_descriptorPool;
184 Move<VkDescriptorSet> m_descriptorSet;
185 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
187 Move<VkBuffer> m_uniformBuffer;
188 de::MovePtr<Allocation> m_uniformBufferMemory;
189 const VkDeviceSize m_uniformBufferSize;
191 Move<VkPipelineLayout> m_pipelineLayout;
193 Move<VkShaderModule> m_vertexShaderModule;
194 Move<VkShaderModule> m_fragmentShaderModule;
196 Move<VkBuffer> m_resultBuffer;
197 de::MovePtr<Allocation> m_resultBufferMemory;
198 const VkDeviceSize m_resultBufferSize;
201 BaseRenderingTestInstance::BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount, deUint32 renderSize)
202 : TestInstance (context)
203 , m_renderSize (renderSize)
204 , m_sampleCount (sampleCount)
205 , m_subpixelBits (context.getDeviceProperties().limits.subPixelPrecisionBits)
206 , m_multisampling (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
207 , m_imageFormat (VK_FORMAT_R8G8B8A8_UNORM)
208 , m_textureFormat (vk::mapVkFormat(m_imageFormat))
209 , m_uniformBufferSize (sizeof(float))
210 , m_resultBufferSize (renderSize * renderSize * m_textureFormat.getPixelSize())
212 const DeviceInterface& vkd = m_context.getDeviceInterface();
213 const VkDevice vkDevice = m_context.getDevice();
214 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
215 Allocator& allocator = m_context.getDefaultAllocator();
216 DescriptorPoolBuilder descriptorPoolBuilder;
217 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
220 m_commandPool = createCommandPool(vkd, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
224 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
225 VkImageFormatProperties properties;
227 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
230 VK_IMAGE_TILING_OPTIMAL,
233 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
235 TCU_THROW(NotSupportedError, "Format not supported");
238 if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
240 TCU_THROW(NotSupportedError, "Format not supported");
243 const VkImageCreateInfo imageCreateInfo =
245 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
246 DE_NULL, // const void* pNext;
247 0u, // VkImageCreateFlags flags;
248 VK_IMAGE_TYPE_2D, // VkImageType imageType;
249 m_imageFormat, // VkFormat format;
250 { m_renderSize, m_renderSize, 1u }, // VkExtent3D extent;
251 1u, // deUint32 mipLevels;
252 1u, // deUint32 arrayLayers;
253 m_sampleCount, // VkSampleCountFlagBits samples;
254 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
255 imageUsage, // VkImageUsageFlags usage;
256 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
257 1u, // deUint32 queueFamilyIndexCount;
258 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
259 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
262 m_image = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
264 m_imageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_image), MemoryRequirement::Any);
265 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_image, m_imageMemory->getMemory(), m_imageMemory->getOffset()));
270 const VkImageViewCreateInfo imageViewCreateInfo =
272 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
273 DE_NULL, // const void* pNext;
274 0u, // VkImageViewCreateFlags flags;
275 *m_image, // VkImage image;
276 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
277 m_imageFormat, // VkFormat format;
278 makeComponentMappingRGBA(), // VkComponentMapping components;
280 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
281 0u, // deUint32 baseMipLevel;
282 1u, // deUint32 mipLevels;
283 0u, // deUint32 baseArrayLayer;
284 1u, // deUint32 arraySize;
285 }, // VkImageSubresourceRange subresourceRange;
288 m_imageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
295 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
296 VkImageFormatProperties properties;
298 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
301 VK_IMAGE_TILING_OPTIMAL,
304 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
306 TCU_THROW(NotSupportedError, "Format not supported");
309 const VkImageCreateInfo imageCreateInfo =
311 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
312 DE_NULL, // const void* pNext;
313 0u, // VkImageCreateFlags flags;
314 VK_IMAGE_TYPE_2D, // VkImageType imageType;
315 m_imageFormat, // VkFormat format;
316 { m_renderSize, m_renderSize, 1u }, // VkExtent3D extent;
317 1u, // deUint32 mipLevels;
318 1u, // deUint32 arrayLayers;
319 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
320 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
321 imageUsage, // VkImageUsageFlags usage;
322 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
323 1u, // deUint32 queueFamilyIndexCount;
324 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
325 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
328 m_resolvedImage = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
329 m_resolvedImageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_resolvedImage), MemoryRequirement::Any);
330 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_resolvedImage, m_resolvedImageMemory->getMemory(), m_resolvedImageMemory->getOffset()));
333 // Resolved Image View
335 const VkImageViewCreateInfo imageViewCreateInfo =
337 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
338 DE_NULL, // const void* pNext;
339 0u, // VkImageViewCreateFlags flags;
340 *m_resolvedImage, // VkImage image;
341 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
342 m_imageFormat, // VkFormat format;
343 makeComponentMappingRGBA(), // VkComponentMapping components;
345 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
346 0u, // deUint32 baseMipLevel;
347 1u, // deUint32 mipLevels;
348 0u, // deUint32 baseArrayLayer;
349 1u, // deUint32 arraySize;
350 }, // VkImageSubresourceRange subresourceRange;
353 m_resolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
360 const VkImageLayout imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
361 const VkAttachmentDescription attachmentDesc[] =
364 0u, // VkAttachmentDescriptionFlags flags;
365 m_imageFormat, // VkFormat format;
366 m_sampleCount, // VkSampleCountFlagBits samples;
367 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
368 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
369 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
370 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
371 imageLayout, // VkImageLayout initialLayout;
372 imageLayout, // VkImageLayout finalLayout;
375 0u, // VkAttachmentDescriptionFlags flags;
376 m_imageFormat, // VkFormat format;
377 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
378 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
379 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
380 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
381 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
382 imageLayout, // VkImageLayout initialLayout;
383 imageLayout, // VkImageLayout finalLayout;
387 const VkAttachmentReference attachmentRef =
389 0u, // deUint32 attachment;
390 imageLayout, // VkImageLayout layout;
393 const VkAttachmentReference resolveAttachmentRef =
395 1u, // deUint32 attachment;
396 imageLayout, // VkImageLayout layout;
399 const VkSubpassDescription subpassDesc =
401 0u, // VkSubpassDescriptionFlags flags;
402 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
403 0u, // deUint32 inputAttachmentCount;
404 DE_NULL, // const VkAttachmentReference* pInputAttachments;
405 1u, // deUint32 colorAttachmentCount;
406 &attachmentRef, // const VkAttachmentReference* pColorAttachments;
407 m_multisampling ? &resolveAttachmentRef : DE_NULL, // const VkAttachmentReference* pResolveAttachments;
408 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
409 0u, // deUint32 preserveAttachmentCount;
410 DE_NULL, // const VkAttachmentReference* pPreserveAttachments;
413 const VkRenderPassCreateInfo renderPassCreateInfo =
415 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
416 DE_NULL, // const void* pNext;
417 0u, // VkRenderPassCreateFlags flags;
418 m_multisampling ? 2u : 1u, // deUint32 attachmentCount;
419 attachmentDesc, // const VkAttachmentDescription* pAttachments;
420 1u, // deUint32 subpassCount;
421 &subpassDesc, // const VkSubpassDescription* pSubpasses;
422 0u, // deUint32 dependencyCount;
423 DE_NULL, // const VkSubpassDependency* pDependencies;
426 m_renderPass = createRenderPass(vkd, vkDevice, &renderPassCreateInfo, DE_NULL);
431 const VkImageView attachments[] =
437 const VkFramebufferCreateInfo framebufferCreateInfo =
439 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
440 DE_NULL, // const void* pNext;
441 0u, // VkFramebufferCreateFlags flags;
442 *m_renderPass, // VkRenderPass renderPass;
443 m_multisampling ? 2u : 1u, // deUint32 attachmentCount;
444 attachments, // const VkImageView* pAttachments;
445 m_renderSize, // deUint32 width;
446 m_renderSize, // deUint32 height;
447 1u, // deUint32 layers;
450 m_frameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL);
455 const VkBufferCreateInfo bufferCreateInfo =
457 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
458 DE_NULL, // const void* pNext;
459 0u, // VkBufferCreateFlags flags;
460 m_uniformBufferSize, // VkDeviceSize size;
461 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage;
462 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
463 1u, // deUint32 queueFamilyIndexCount;
464 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
467 m_uniformBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo);
468 m_uniformBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_uniformBuffer), MemoryRequirement::HostVisible);
470 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_uniformBuffer, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset()));
475 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
476 m_descriptorPool = descriptorPoolBuilder.build(vkd, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
478 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_ALL);
479 m_descriptorSetLayout = descriptorSetLayoutBuilder.build(vkd, vkDevice);
481 const VkDescriptorSetAllocateInfo descriptorSetParams =
483 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
487 &m_descriptorSetLayout.get(),
490 m_descriptorSet = allocateDescriptorSet(vkd, vkDevice, &descriptorSetParams);
492 const VkDescriptorBufferInfo descriptorBufferInfo =
494 *m_uniformBuffer, // VkBuffer buffer;
495 0u, // VkDeviceSize offset;
496 VK_WHOLE_SIZE // VkDeviceSize range;
499 const VkWriteDescriptorSet writeDescritporSet =
501 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
502 DE_NULL, // const void* pNext;
503 *m_descriptorSet, // VkDescriptorSet destSet;
504 0, // deUint32 destBinding;
505 0, // deUint32 destArrayElement;
506 1u, // deUint32 count;
507 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType descriptorType;
508 DE_NULL, // const VkDescriptorImageInfo* pImageInfo;
509 &descriptorBufferInfo, // const VkDescriptorBufferInfo* pBufferInfo;
510 DE_NULL // const VkBufferView* pTexelBufferView;
513 vkd.updateDescriptorSets(vkDevice, 1u, &writeDescritporSet, 0u, DE_NULL);
518 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
520 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
521 DE_NULL, // const void* pNext;
522 0u, // VkPipelineLayoutCreateFlags flags;
523 1u, // deUint32 descriptorSetCount;
524 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
525 0u, // deUint32 pushConstantRangeCount;
526 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
529 m_pipelineLayout = createPipelineLayout(vkd, vkDevice, &pipelineLayoutCreateInfo);
534 m_vertexShaderModule = createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("vertext_shader"), 0);
535 m_fragmentShaderModule = createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("fragment_shader"), 0);
540 const VkBufferCreateInfo bufferCreateInfo =
542 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
543 DE_NULL, // const void* pNext;
544 0u, // VkBufferCreateFlags flags;
545 m_resultBufferSize, // VkDeviceSize size;
546 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
547 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
548 1u, // deUint32 queueFamilyIndexCount;
549 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
552 m_resultBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo);
553 m_resultBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_resultBuffer), MemoryRequirement::HostVisible);
555 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));
558 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Sample count = " << getSampleCountFlagsStr(m_sampleCount) << tcu::TestLog::EndMessage;
559 m_context.getTestContext().getLog() << tcu::TestLog::Message << "SUBPIXEL_BITS = " << m_subpixelBits << tcu::TestLog::EndMessage;
562 BaseRenderingTestInstance::~BaseRenderingTestInstance (void)
567 void BaseRenderingTestInstance::addImageTransitionBarrier(VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const
570 const DeviceInterface& vkd = m_context.getDeviceInterface();
572 const VkImageSubresourceRange subResourcerange =
574 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
575 0, // deUint32 baseMipLevel;
576 1, // deUint32 levelCount;
577 0, // deUint32 baseArrayLayer;
578 1 // deUint32 layerCount;
581 const VkImageMemoryBarrier imageBarrier =
583 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
584 DE_NULL, // const void* pNext;
585 srcAccessMask, // VkAccessFlags srcAccessMask;
586 dstAccessMask, // VkAccessFlags dstAccessMask;
587 oldLayout, // VkImageLayout oldLayout;
588 newLayout, // VkImageLayout newLayout;
589 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
590 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
591 image, // VkImage image;
592 subResourcerange // VkImageSubresourceRange subresourceRange;
595 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier);
598 void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology)
600 // default to color white
601 const std::vector<tcu::Vec4> colorData(vertexData.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
603 drawPrimitives(result, vertexData, colorData, primitiveTopology);
606 void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology)
608 const DeviceInterface& vkd = m_context.getDeviceInterface();
609 const VkDevice vkDevice = m_context.getDevice();
610 const VkQueue queue = m_context.getUniversalQueue();
611 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
612 Allocator& allocator = m_context.getDefaultAllocator();
613 const size_t attributeBatchSize = positionData.size() * sizeof(tcu::Vec4);
615 Move<VkCommandBuffer> commandBuffer;
616 Move<VkPipeline> graphicsPipeline;
617 Move<VkBuffer> vertexBuffer;
618 de::MovePtr<Allocation> vertexBufferMemory;
619 const VkPhysicalDeviceProperties properties = m_context.getDeviceProperties();
621 if (attributeBatchSize > properties.limits.maxVertexInputAttributeOffset)
623 std::stringstream message;
624 message << "Larger vertex input attribute offset is needed (" << attributeBatchSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
625 TCU_THROW(NotSupportedError, message.str().c_str());
628 // Create Graphics Pipeline
630 const VkVertexInputBindingDescription vertexInputBindingDescription =
632 0u, // deUint32 binding;
633 sizeof(tcu::Vec4), // deUint32 strideInBytes;
634 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
637 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
640 0u, // deUint32 location;
641 0u, // deUint32 binding;
642 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
643 0u // deUint32 offsetInBytes;
646 1u, // deUint32 location;
647 0u, // deUint32 binding;
648 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
649 (deUint32)attributeBatchSize // deUint32 offsetInBytes;
653 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
655 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
656 DE_NULL, // const void* pNext;
657 0, // VkPipelineVertexInputStateCreateFlags flags;
658 1u, // deUint32 bindingCount;
659 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
660 2u, // deUint32 attributeCount;
661 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
664 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(m_renderSize)));
665 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(m_renderSize)));
667 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
669 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
670 DE_NULL, // const void* pNext;
671 0u, // VkPipelineMultisampleStateCreateFlags flags;
672 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
673 VK_FALSE, // VkBool32 sampleShadingEnable;
674 0.0f, // float minSampleShading;
675 DE_NULL, // const VkSampleMask* pSampleMask;
676 VK_FALSE, // VkBool32 alphaToCoverageEnable;
677 VK_FALSE // VkBool32 alphaToOneEnable;
680 graphicsPipeline = makeGraphicsPipeline(vkd, // const DeviceInterface& vk
681 vkDevice, // const VkDevice device
682 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
683 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
684 DE_NULL, // const VkShaderModule tessellationControlShaderModule
685 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
686 DE_NULL, // const VkShaderModule geometryShaderModule
687 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
688 *m_renderPass, // const VkRenderPass renderPass
689 viewports, // const std::vector<VkViewport>& viewports
690 scissors, // const std::vector<VkRect2D>& scissors
691 primitiveTopology, // const VkPrimitiveTopology topology
692 0u, // const deUint32 subpass
693 0u, // const deUint32 patchControlPoints
694 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
695 getRasterizationStateCreateInfo(), // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
696 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
697 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo,
698 getColorBlendStateCreateInfo()); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
701 // Create Vertex Buffer
703 const VkBufferCreateInfo vertexBufferParams =
705 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
706 DE_NULL, // const void* pNext;
707 0u, // VkBufferCreateFlags flags;
708 attributeBatchSize * 2, // VkDeviceSize size;
709 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
710 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
711 1u, // deUint32 queueFamilyCount;
712 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
715 vertexBuffer = createBuffer(vkd, vkDevice, &vertexBufferParams);
716 vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
718 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
720 // Load vertices into vertex buffer
721 deMemcpy(vertexBufferMemory->getHostPtr(), positionData.data(), attributeBatchSize);
722 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) + attributeBatchSize, colorData.data(), attributeBatchSize);
723 flushMappedMemoryRange(vkd, vkDevice, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset(), vertexBufferParams.size);
726 // Create Command Buffer
727 commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
729 // Begin Command Buffer
730 beginCommandBuffer(vkd, *commandBuffer);
732 addImageTransitionBarrier(*commandBuffer, *m_image,
733 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
734 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
735 0, // VkAccessFlags srcAccessMask
736 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
737 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
738 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
740 if (m_multisampling) {
741 addImageTransitionBarrier(*commandBuffer, *m_resolvedImage,
742 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
743 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
744 0, // VkAccessFlags srcAccessMask
745 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
746 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
747 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
751 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));
753 const VkDeviceSize vertexBufferOffset = 0;
755 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
756 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL);
757 vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
758 vkd.cmdDraw(*commandBuffer, (deUint32)positionData.size(), 1, 0, 0);
759 endRenderPass(vkd, *commandBuffer);
764 const VkBufferMemoryBarrier bufferBarrier =
766 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
767 DE_NULL, // const void* pNext;
768 VK_ACCESS_TRANSFER_WRITE_BIT, // VkMemoryOutputFlags outputMask;
769 VK_ACCESS_HOST_READ_BIT, // VkMemoryInputFlags inputMask;
770 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
771 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
772 *m_resultBuffer, // VkBuffer buffer;
773 0u, // VkDeviceSize offset;
774 m_resultBufferSize // VkDeviceSize size;
777 const VkBufferImageCopy copyRegion =
779 0u, // VkDeviceSize bufferOffset;
780 m_renderSize, // deUint32 bufferRowLength;
781 m_renderSize, // deUint32 bufferImageHeight;
782 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u }, // VkImageSubresourceCopy imageSubresource;
783 { 0, 0, 0 }, // VkOffset3D imageOffset;
784 { m_renderSize, m_renderSize, 1u } // VkExtent3D imageExtent;
787 addImageTransitionBarrier(*commandBuffer,
788 m_multisampling ? *m_resolvedImage : *m_image,
789 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
790 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
791 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
792 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
793 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
794 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); // VkImageLayout newLayout;)
797 vkd.cmdCopyImageToBuffer(*commandBuffer, *m_resolvedImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, ©Region);
799 vkd.cmdCopyImageToBuffer(*commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, ©Region);
801 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
804 endCommandBuffer(vkd, *commandBuffer);
808 float pointSize = getPointSize();
809 deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize);
810 flushMappedMemoryRange(vkd, vkDevice, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset(), m_uniformBufferSize);
814 submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());
816 invalidateMappedMemoryRange(vkd, vkDevice, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(), m_resultBufferSize);
817 tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderSize, m_renderSize, 1), m_resultBufferMemory->getHostPtr()));
820 float BaseRenderingTestInstance::getLineWidth (void) const
825 float BaseRenderingTestInstance::getPointSize (void) const
830 const VkPipelineRasterizationStateCreateInfo* BaseRenderingTestInstance::getRasterizationStateCreateInfo (void) const
832 static VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
834 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
835 DE_NULL, // const void* pNext;
836 0, // VkPipelineRasterizationStateCreateFlags flags;
837 false, // VkBool32 depthClipEnable;
838 false, // VkBool32 rasterizerDiscardEnable;
839 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
840 VK_CULL_MODE_NONE, // VkCullMode cullMode;
841 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
842 VK_FALSE, // VkBool32 depthBiasEnable;
843 0.0f, // float depthBias;
844 0.0f, // float depthBiasClamp;
845 0.0f, // float slopeScaledDepthBias;
846 getLineWidth(), // float lineWidth;
849 rasterizationStateCreateInfo.lineWidth = getLineWidth();
850 return &rasterizationStateCreateInfo;
853 const VkPipelineColorBlendStateCreateInfo* BaseRenderingTestInstance::getColorBlendStateCreateInfo (void) const
855 static const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
857 false, // VkBool32 blendEnable;
858 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
859 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor;
860 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
861 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
862 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha;
863 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
864 (VK_COLOR_COMPONENT_R_BIT |
865 VK_COLOR_COMPONENT_G_BIT |
866 VK_COLOR_COMPONENT_B_BIT |
867 VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask;
870 static const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
872 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
873 DE_NULL, // const void* pNext;
874 0, // VkPipelineColorBlendStateCreateFlags flags;
875 false, // VkBool32 logicOpEnable;
876 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
877 1u, // deUint32 attachmentCount;
878 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
879 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
882 return &colorBlendStateParams;
885 const tcu::TextureFormat& BaseRenderingTestInstance::getTextureFormat (void) const
887 return m_textureFormat;
890 class BaseTriangleTestInstance : public BaseRenderingTestInstance
893 BaseTriangleTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, VkSampleCountFlagBits sampleCount);
894 virtual tcu::TestStatus iterate (void);
897 virtual void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles) = DE_NULL;
900 const int m_iterationCount;
901 VkPrimitiveTopology m_primitiveTopology;
902 bool m_allIterationsPassed;
905 BaseTriangleTestInstance::BaseTriangleTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, VkSampleCountFlagBits sampleCount)
906 : BaseRenderingTestInstance (context, sampleCount)
908 , m_iterationCount (3)
909 , m_primitiveTopology (primitiveTopology)
910 , m_allIterationsPassed (true)
914 tcu::TestStatus BaseTriangleTestInstance::iterate (void)
916 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
917 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
918 tcu::Surface resultImage (m_renderSize, m_renderSize);
919 std::vector<tcu::Vec4> drawBuffer;
920 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
922 generateTriangles(m_iteration, drawBuffer, triangles);
925 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
930 RasterizationArguments args;
931 TriangleSceneSpec scene;
933 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
935 args.numSamples = m_multisampling ? 1 : 0;
936 args.subpixelBits = m_subpixelBits;
937 args.redBits = colorBits[0];
938 args.greenBits = colorBits[1];
939 args.blueBits = colorBits[2];
941 scene.triangles.swap(triangles);
943 compareOk = verifyTriangleGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
946 m_allIterationsPassed = false;
950 if (++m_iteration == m_iterationCount)
952 if (m_allIterationsPassed)
953 return tcu::TestStatus::pass("Pass");
955 return tcu::TestStatus::fail("Incorrect rasterization");
958 return tcu::TestStatus::incomplete();
961 class BaseLineTestInstance : public BaseRenderingTestInstance
964 BaseLineTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount);
965 virtual tcu::TestStatus iterate (void);
966 virtual float getLineWidth (void) const;
969 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines) = DE_NULL;
972 const int m_iterationCount;
973 VkPrimitiveTopology m_primitiveTopology;
974 const PrimitiveWideness m_primitiveWideness;
975 bool m_allIterationsPassed;
976 float m_maxLineWidth;
977 std::vector<float> m_lineWidths;
980 BaseLineTestInstance::BaseLineTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
981 : BaseRenderingTestInstance (context, sampleCount)
983 , m_iterationCount (3)
984 , m_primitiveTopology (primitiveTopology)
985 , m_primitiveWideness (wideness)
986 , m_allIterationsPassed (true)
987 , m_maxLineWidth (1.0f)
989 DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
991 if (!context.getDeviceProperties().limits.strictLines)
992 TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
994 // create line widths
995 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
997 m_lineWidths.resize(m_iterationCount, 1.0f);
999 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
1001 if (!m_context.getDeviceFeatures().wideLines)
1002 TCU_THROW(NotSupportedError , "wide line support required");
1004 const float* range = context.getDeviceProperties().limits.lineWidthRange;
1006 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
1008 // no wide line support
1009 if (range[1] <= 1.0f)
1010 TCU_THROW(NotSupportedError, "wide line support required");
1012 // set hand picked sizes
1013 m_lineWidths.push_back(5.0f);
1014 m_lineWidths.push_back(10.0f);
1015 m_lineWidths.push_back(range[1]);
1016 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
1018 m_maxLineWidth = range[1];
1024 tcu::TestStatus BaseLineTestInstance::iterate (void)
1026 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1027 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1028 const float lineWidth = getLineWidth();
1029 tcu::Surface resultImage (m_renderSize, m_renderSize);
1030 std::vector<tcu::Vec4> drawBuffer;
1031 std::vector<LineSceneSpec::SceneLine> lines;
1034 if (lineWidth <= m_maxLineWidth)
1037 generateLines(m_iteration, drawBuffer, lines);
1040 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
1044 RasterizationArguments args;
1045 LineSceneSpec scene;
1048 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1050 args.numSamples = m_multisampling ? 1 : 0;
1051 args.subpixelBits = m_subpixelBits;
1052 args.redBits = colorBits[0];
1053 args.greenBits = colorBits[1];
1054 args.blueBits = colorBits[2];
1056 scene.lines.swap(lines);
1057 scene.lineWidth = lineWidth;
1059 if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog()))
1060 m_allIterationsPassed = false;
1064 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
1067 if (++m_iteration == m_iterationCount)
1069 if (m_allIterationsPassed)
1070 return tcu::TestStatus::pass("Pass");
1072 return tcu::TestStatus::fail("Incorrect rasterization");
1075 return tcu::TestStatus::incomplete();
1079 float BaseLineTestInstance::getLineWidth (void) const
1081 return m_lineWidths[m_iteration];
1085 class PointTestInstance : public BaseRenderingTestInstance
1088 PointTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount);
1089 virtual tcu::TestStatus iterate (void);
1090 virtual float getPointSize (void) const;
1093 virtual void generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints);
1096 const int m_iterationCount;
1097 const PrimitiveWideness m_primitiveWideness;
1098 bool m_allIterationsPassed;
1099 float m_maxPointSize;
1100 std::vector<float> m_pointSizes;
1103 PointTestInstance::PointTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
1104 : BaseRenderingTestInstance (context, sampleCount)
1106 , m_iterationCount (3)
1107 , m_primitiveWideness (wideness)
1108 , m_allIterationsPassed (true)
1109 , m_maxPointSize (1.0f)
1111 // create point sizes
1112 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
1114 m_pointSizes.resize(m_iterationCount, 1.0f);
1116 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
1118 if (!m_context.getDeviceFeatures().largePoints)
1119 TCU_THROW(NotSupportedError , "large point support required");
1121 const float* range = context.getDeviceProperties().limits.pointSizeRange;
1123 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_ALIASED_POINT_SIZE_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
1125 // no wide line support
1126 if (range[1] <= 1.0f)
1127 TCU_THROW(NotSupportedError , "wide point support required");
1129 // set hand picked sizes
1130 m_pointSizes.push_back(10.0f);
1131 m_pointSizes.push_back(25.0f);
1132 m_pointSizes.push_back(range[1]);
1133 DE_ASSERT((int)m_pointSizes.size() == m_iterationCount);
1135 m_maxPointSize = range[1];
1141 tcu::TestStatus PointTestInstance::iterate (void)
1143 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1144 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1145 const float pointSize = getPointSize();
1146 tcu::Surface resultImage (m_renderSize, m_renderSize);
1147 std::vector<tcu::Vec4> drawBuffer;
1148 std::vector<PointSceneSpec::ScenePoint> points;
1151 if (pointSize <= m_maxPointSize)
1154 generatePoints(m_iteration, drawBuffer, points);
1157 drawPrimitives(resultImage, drawBuffer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
1162 RasterizationArguments args;
1163 PointSceneSpec scene;
1165 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1167 args.numSamples = m_multisampling ? 1 : 0;
1168 args.subpixelBits = m_subpixelBits;
1169 args.redBits = colorBits[0];
1170 args.greenBits = colorBits[1];
1171 args.blueBits = colorBits[2];
1173 scene.points.swap(points);
1175 compareOk = verifyPointGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
1178 m_allIterationsPassed = false;
1182 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point size " << pointSize << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
1185 if (++m_iteration == m_iterationCount)
1187 if (m_allIterationsPassed)
1188 return tcu::TestStatus::pass("Pass");
1190 return tcu::TestStatus::fail("Incorrect rasterization");
1193 return tcu::TestStatus::incomplete();
1196 float PointTestInstance::getPointSize (void) const
1198 return m_pointSizes[m_iteration];
1201 void PointTestInstance::generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints)
1208 // \note: these values are chosen arbitrarily
1209 outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f);
1210 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1211 outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f);
1212 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1213 outData[4] = tcu::Vec4(-0.2f, -0.4f, 0.0f, 1.0f);
1214 outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f);
1218 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1219 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1220 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1221 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1222 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1223 outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f);
1227 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1228 outData[1] = tcu::Vec4( 0.3f, -0.9f, 0.0f, 1.0f);
1229 outData[2] = tcu::Vec4( -0.4f, -0.1f, 0.0f, 1.0f);
1230 outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f);
1231 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1232 outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f);
1236 outPoints.resize(outData.size());
1237 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
1239 outPoints[pointNdx].position = outData[pointNdx];
1240 outPoints[pointNdx].pointSize = getPointSize();
1244 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outPoints.size() << " point(s): (point size = " << getPointSize() << ")" << tcu::TestLog::EndMessage;
1245 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
1246 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point " << (pointNdx+1) << ":\t" << outPoints[pointNdx].position << tcu::TestLog::EndMessage;
1249 template <typename ConcreteTestInstance>
1250 class BaseTestCase : public BaseRenderingTestCase
1253 BaseTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
1254 : BaseRenderingTestCase(context, name, description, sampleCount)
1257 virtual TestInstance* createInstance (Context& context) const
1259 return new ConcreteTestInstance(context, m_sampleCount);
1263 class TrianglesTestInstance : public BaseTriangleTestInstance
1266 TrianglesTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
1267 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, sampleCount)
1270 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
1273 void TrianglesTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
1280 // \note: these values are chosen arbitrarily
1281 outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f);
1282 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1283 outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f);
1284 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1285 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
1286 outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f);
1290 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1291 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1292 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1293 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1294 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1295 outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f);
1299 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1300 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1301 outData[2] = tcu::Vec4( -1.1f, -0.1f, 0.0f, 1.0f);
1302 outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f);
1303 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1304 outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f);
1308 outTriangles.resize(2);
1309 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
1310 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false;
1311 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false;
1313 outTriangles[1].positions[0] = outData[3]; outTriangles[1].sharedEdge[0] = false;
1314 outTriangles[1].positions[1] = outData[4]; outTriangles[1].sharedEdge[1] = false;
1315 outTriangles[1].positions[2] = outData[5]; outTriangles[1].sharedEdge[2] = false;
1318 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outTriangles.size() << " triangle(s):" << tcu::TestLog::EndMessage;
1319 for (int triangleNdx = 0; triangleNdx < (int)outTriangles.size(); ++triangleNdx)
1321 m_context.getTestContext().getLog()
1322 << tcu::TestLog::Message
1323 << "Triangle " << (triangleNdx+1) << ":"
1324 << "\n\t" << outTriangles[triangleNdx].positions[0]
1325 << "\n\t" << outTriangles[triangleNdx].positions[1]
1326 << "\n\t" << outTriangles[triangleNdx].positions[2]
1327 << tcu::TestLog::EndMessage;
1331 class TriangleStripTestInstance : public BaseTriangleTestInstance
1334 TriangleStripTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
1335 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, sampleCount)
1338 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
1341 void TriangleStripTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
1348 // \note: these values are chosen arbitrarily
1349 outData[0] = tcu::Vec4(-0.504f, 0.8f, 0.0f, 1.0f);
1350 outData[1] = tcu::Vec4(-0.2f, -0.2f, 0.0f, 1.0f);
1351 outData[2] = tcu::Vec4(-0.2f, 0.199f, 0.0f, 1.0f);
1352 outData[3] = tcu::Vec4( 0.5f, 0.201f, 0.0f, 1.0f);
1353 outData[4] = tcu::Vec4( 1.5f, 0.4f, 0.0f, 1.0f);
1357 outData[0] = tcu::Vec4(-0.499f, 0.129f, 0.0f, 1.0f);
1358 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1359 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1360 outData[3] = tcu::Vec4( 0.11f, -0.31f, 0.0f, 1.0f);
1361 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1365 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1366 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1367 outData[2] = tcu::Vec4(-0.87f, -0.1f, 0.0f, 1.0f);
1368 outData[3] = tcu::Vec4(-0.11f, 0.19f, 0.0f, 1.0f);
1369 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1373 outTriangles.resize(3);
1374 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
1375 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = true;
1376 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false;
1378 outTriangles[1].positions[0] = outData[2]; outTriangles[1].sharedEdge[0] = true;
1379 outTriangles[1].positions[1] = outData[1]; outTriangles[1].sharedEdge[1] = false;
1380 outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true;
1382 outTriangles[2].positions[0] = outData[2]; outTriangles[2].sharedEdge[0] = true;
1383 outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false;
1384 outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false;
1387 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering triangle strip, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1388 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1390 m_context.getTestContext().getLog()
1391 << tcu::TestLog::Message
1392 << "\t" << outData[vtxNdx]
1393 << tcu::TestLog::EndMessage;
1397 class TriangleFanTestInstance : public BaseTriangleTestInstance
1400 TriangleFanTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
1401 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, sampleCount)
1404 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
1407 void TriangleFanTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
1414 // \note: these values are chosen arbitrarily
1415 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1416 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1417 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1418 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1419 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
1423 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1424 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1425 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1426 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1427 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1431 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1432 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1433 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1434 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1435 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1439 outTriangles.resize(3);
1440 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
1441 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false;
1442 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = true;
1444 outTriangles[1].positions[0] = outData[0]; outTriangles[1].sharedEdge[0] = true;
1445 outTriangles[1].positions[1] = outData[2]; outTriangles[1].sharedEdge[1] = false;
1446 outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true;
1448 outTriangles[2].positions[0] = outData[0]; outTriangles[2].sharedEdge[0] = true;
1449 outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false;
1450 outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false;
1453 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering triangle fan, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1454 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1456 m_context.getTestContext().getLog()
1457 << tcu::TestLog::Message
1458 << "\t" << outData[vtxNdx]
1459 << tcu::TestLog::EndMessage;
1463 template <typename ConcreteTestInstance>
1464 class WidenessTestCase : public BaseRenderingTestCase
1467 WidenessTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
1468 : BaseRenderingTestCase(context, name, description, sampleCount)
1469 , m_wideness(wideness)
1472 virtual TestInstance* createInstance (Context& context) const
1474 return new ConcreteTestInstance(context, m_wideness, m_sampleCount);
1477 const PrimitiveWideness m_wideness;
1480 class LinesTestInstance : public BaseLineTestInstance
1483 LinesTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
1484 : BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, wideness, sampleCount)
1487 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
1490 void LinesTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
1497 // \note: these values are chosen arbitrarily
1498 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1499 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1500 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1501 outData[3] = tcu::Vec4(-0.3f, 0.2f, 0.0f, 1.0f);
1502 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
1503 outData[5] = tcu::Vec4( 0.1f, 0.5f, 0.0f, 1.0f);
1507 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1508 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1509 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1510 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1511 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1512 outData[5] = tcu::Vec4( 0.18f, -0.2f, 0.0f, 1.0f);
1516 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1517 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1518 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1519 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1520 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1521 outData[5] = tcu::Vec4( 0.8f, -0.7f, 0.0f, 1.0f);
1526 outLines[0].positions[0] = outData[0];
1527 outLines[0].positions[1] = outData[1];
1528 outLines[1].positions[0] = outData[2];
1529 outLines[1].positions[1] = outData[3];
1530 outLines[2].positions[0] = outData[4];
1531 outLines[2].positions[1] = outData[5];
1534 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outLines.size() << " lines(s): (width = " << getLineWidth() << ")" << tcu::TestLog::EndMessage;
1535 for (int lineNdx = 0; lineNdx < (int)outLines.size(); ++lineNdx)
1537 m_context.getTestContext().getLog()
1538 << tcu::TestLog::Message
1539 << "Line " << (lineNdx+1) << ":"
1540 << "\n\t" << outLines[lineNdx].positions[0]
1541 << "\n\t" << outLines[lineNdx].positions[1]
1542 << tcu::TestLog::EndMessage;
1546 class LineStripTestInstance : public BaseLineTestInstance
1549 LineStripTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
1550 : BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, wideness, sampleCount)
1553 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
1556 void LineStripTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
1563 // \note: these values are chosen arbitrarily
1564 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1565 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1566 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1567 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1571 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1572 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1573 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1574 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1578 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1579 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1580 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1581 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1586 outLines[0].positions[0] = outData[0];
1587 outLines[0].positions[1] = outData[1];
1588 outLines[1].positions[0] = outData[1];
1589 outLines[1].positions[1] = outData[2];
1590 outLines[2].positions[0] = outData[2];
1591 outLines[2].positions[1] = outData[3];
1594 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering line strip, width = " << getLineWidth() << ", " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1595 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1597 m_context.getTestContext().getLog()
1598 << tcu::TestLog::Message
1599 << "\t" << outData[vtxNdx]
1600 << tcu::TestLog::EndMessage;
1604 class FillRuleTestInstance : public BaseRenderingTestInstance
1607 enum FillRuleCaseType
1609 FILLRULECASE_BASIC = 0,
1610 FILLRULECASE_REVERSED,
1611 FILLRULECASE_CLIPPED_FULL,
1612 FILLRULECASE_CLIPPED_PARTIAL,
1613 FILLRULECASE_PROJECTED,
1617 FillRuleTestInstance (Context& context, FillRuleCaseType type, VkSampleCountFlagBits sampleCount);
1618 virtual tcu::TestStatus iterate (void);
1622 virtual const VkPipelineColorBlendStateCreateInfo* getColorBlendStateCreateInfo (void) const;
1623 int getRenderSize (FillRuleCaseType type) const;
1624 int getNumIterations (FillRuleCaseType type) const;
1625 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const;
1627 const FillRuleCaseType m_caseType;
1629 const int m_iterationCount;
1630 bool m_allIterationsPassed;
1634 FillRuleTestInstance::FillRuleTestInstance (Context& context, FillRuleCaseType type, VkSampleCountFlagBits sampleCount)
1635 : BaseRenderingTestInstance (context, sampleCount, getRenderSize(type))
1638 , m_iterationCount (getNumIterations(type))
1639 , m_allIterationsPassed (true)
1641 DE_ASSERT(type < FILLRULECASE_LAST);
1644 tcu::TestStatus FillRuleTestInstance::iterate (void)
1646 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1647 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1648 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1649 const int thresholdRed = 1 << (8 - colorBits[0]);
1650 const int thresholdGreen = 1 << (8 - colorBits[1]);
1651 const int thresholdBlue = 1 << (8 - colorBits[2]);
1652 tcu::Surface resultImage (m_renderSize, m_renderSize);
1653 std::vector<tcu::Vec4> drawBuffer;
1655 generateTriangles(m_iteration, drawBuffer);
1659 const std::vector<tcu::Vec4> colorBuffer (drawBuffer.size(), tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
1661 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Drawing gray triangles with shared edges.\nEnabling additive blending to detect overlapping fragments." << tcu::TestLog::EndMessage;
1663 drawPrimitives(resultImage, drawBuffer, colorBuffer, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
1666 // verify no overdraw
1668 const tcu::RGBA triangleColor = tcu::RGBA(127, 127, 127, 255);
1669 bool overdraw = false;
1671 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Verifying result." << tcu::TestLog::EndMessage;
1673 for (int y = 0; y < resultImage.getHeight(); ++y)
1674 for (int x = 0; x < resultImage.getWidth(); ++x)
1676 const tcu::RGBA color = resultImage.getPixel(x, y);
1678 // color values are greater than triangle color? Allow lower values for multisampled edges and background.
1679 if ((color.getRed() - triangleColor.getRed()) > thresholdRed ||
1680 (color.getGreen() - triangleColor.getGreen()) > thresholdGreen ||
1681 (color.getBlue() - triangleColor.getBlue()) > thresholdBlue)
1687 m_context.getTestContext().getLog() << tcu::TestLog::Message << "No overlapping fragments detected." << tcu::TestLog::EndMessage;
1690 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Overlapping fragments detected, image is not valid." << tcu::TestLog::EndMessage;
1691 m_allIterationsPassed = false;
1695 // verify no missing fragments in the full viewport case
1696 if (m_caseType == FILLRULECASE_CLIPPED_FULL)
1698 bool missingFragments = false;
1700 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Searching missing fragments." << tcu::TestLog::EndMessage;
1702 for (int y = 0; y < resultImage.getHeight(); ++y)
1703 for (int x = 0; x < resultImage.getWidth(); ++x)
1705 const tcu::RGBA color = resultImage.getPixel(x, y);
1707 // black? (background)
1708 if (color.getRed() <= thresholdRed ||
1709 color.getGreen() <= thresholdGreen ||
1710 color.getBlue() <= thresholdBlue)
1711 missingFragments = true;
1715 if (!missingFragments)
1716 m_context.getTestContext().getLog() << tcu::TestLog::Message << "No missing fragments detected." << tcu::TestLog::EndMessage;
1719 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Missing fragments detected, image is not valid." << tcu::TestLog::EndMessage;
1721 m_allIterationsPassed = false;
1725 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result of rendering", "Result of rendering")
1726 << tcu::TestLog::Image("Result", "Result", resultImage)
1727 << tcu::TestLog::EndImageSet;
1730 if (++m_iteration == m_iterationCount)
1732 if (m_allIterationsPassed)
1733 return tcu::TestStatus::pass("Pass");
1735 return tcu::TestStatus::fail("Found invalid pixels");
1738 return tcu::TestStatus::incomplete();
1741 int FillRuleTestInstance::getRenderSize (FillRuleCaseType type) const
1743 if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
1744 return DEFAULT_RENDER_SIZE / 4;
1746 return DEFAULT_RENDER_SIZE;
1749 int FillRuleTestInstance::getNumIterations (FillRuleCaseType type) const
1751 if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
1757 void FillRuleTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const
1761 case FILLRULECASE_BASIC:
1762 case FILLRULECASE_REVERSED:
1763 case FILLRULECASE_PROJECTED:
1765 const int numRows = 4;
1766 const int numColumns = 4;
1767 const float quadSide = 0.15f;
1768 de::Random rnd (0xabcd);
1770 outData.resize(6 * numRows * numColumns);
1772 for (int col = 0; col < numColumns; ++col)
1773 for (int row = 0; row < numRows; ++row)
1775 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);
1776 const float rotation = (float)(iteration * numColumns * numRows + col * numRows + row) / (float)(m_iterationCount * numColumns * numRows) * DE_PI / 2.0f;
1777 const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
1778 const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x());
1779 const tcu::Vec2 quad[4] =
1781 center + sideH + sideV,
1782 center + sideH - sideV,
1783 center - sideH - sideV,
1784 center - sideH + sideV,
1787 if (m_caseType == FILLRULECASE_BASIC)
1789 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1790 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1791 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1792 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1793 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1794 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1796 else if (m_caseType == FILLRULECASE_REVERSED)
1798 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1799 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1800 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1801 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1802 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1803 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1805 else if (m_caseType == FILLRULECASE_PROJECTED)
1807 const float w0 = rnd.getFloat(0.1f, 4.0f);
1808 const float w1 = rnd.getFloat(0.1f, 4.0f);
1809 const float w2 = rnd.getFloat(0.1f, 4.0f);
1810 const float w3 = rnd.getFloat(0.1f, 4.0f);
1812 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
1813 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x() * w1, quad[1].y() * w1, 0.0f, w1);
1814 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
1815 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
1816 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
1817 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x() * w3, quad[3].y() * w3, 0.0f, w3);
1820 DE_ASSERT(DE_FALSE);
1826 case FILLRULECASE_CLIPPED_PARTIAL:
1827 case FILLRULECASE_CLIPPED_FULL:
1829 const float quadSide = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (1.0f) : (2.0f);
1830 const tcu::Vec2 center = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (tcu::Vec2(0.5f, 0.5f)) : (tcu::Vec2(0.0f, 0.0f));
1831 const float rotation = (float)(iteration) / (float)(m_iterationCount - 1) * DE_PI / 2.0f;
1832 const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
1833 const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x());
1834 const tcu::Vec2 quad[4] =
1836 center + sideH + sideV,
1837 center + sideH - sideV,
1838 center - sideH - sideV,
1839 center - sideH + sideV,
1843 outData[0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1844 outData[1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1845 outData[2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1846 outData[3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1847 outData[4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1848 outData[5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1853 DE_ASSERT(DE_FALSE);
1857 const VkPipelineColorBlendStateCreateInfo* FillRuleTestInstance::getColorBlendStateCreateInfo (void) const
1859 static const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1861 true, // VkBool32 blendEnable;
1862 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
1863 VK_BLEND_FACTOR_ONE, // VkBlend destBlendColor;
1864 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
1865 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
1866 VK_BLEND_FACTOR_ONE, // VkBlend destBlendAlpha;
1867 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
1868 (VK_COLOR_COMPONENT_R_BIT |
1869 VK_COLOR_COMPONENT_G_BIT |
1870 VK_COLOR_COMPONENT_B_BIT |
1871 VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask;
1874 static const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1876 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1877 DE_NULL, // const void* pNext;
1878 0, // VkPipelineColorBlendStateCreateFlags flags;
1879 false, // VkBool32 logicOpEnable;
1880 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1881 1u, // deUint32 attachmentCount;
1882 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1883 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
1886 return &colorBlendStateParams;
1890 class FillRuleTestCase : public BaseRenderingTestCase
1893 FillRuleTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, FillRuleTestInstance::FillRuleCaseType type, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
1894 : BaseRenderingTestCase (context, name, description, sampleCount)
1898 virtual TestInstance* createInstance (Context& context) const
1900 return new FillRuleTestInstance(context, m_type, m_sampleCount);
1903 const FillRuleTestInstance::FillRuleCaseType m_type;
1906 class CullingTestInstance : public BaseRenderingTestInstance
1909 CullingTestInstance (Context& context, VkCullModeFlags cullMode, VkPrimitiveTopology primitiveTopology, VkFrontFace frontFace, VkPolygonMode polygonMode)
1910 : BaseRenderingTestInstance (context, VK_SAMPLE_COUNT_1_BIT, DEFAULT_RENDER_SIZE)
1911 , m_cullMode (cullMode)
1912 , m_primitiveTopology (primitiveTopology)
1913 , m_frontFace (frontFace)
1914 , m_polygonMode (polygonMode)
1915 , m_multisampling (true)
1918 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
1920 tcu::TestStatus iterate (void);
1923 void generateVertices (std::vector<tcu::Vec4>& outData) const;
1924 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const;
1925 void extractLines (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, std::vector<LineSceneSpec::SceneLine>& outLines) const;
1926 void extractPoints (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, std::vector<PointSceneSpec::ScenePoint>& outPoints) const;
1927 bool triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const;
1929 const VkCullModeFlags m_cullMode;
1930 const VkPrimitiveTopology m_primitiveTopology;
1931 const VkFrontFace m_frontFace;
1932 const VkPolygonMode m_polygonMode;
1933 const bool m_multisampling;
1937 tcu::TestStatus CullingTestInstance::iterate (void)
1939 DE_ASSERT(m_polygonMode <= VK_POLYGON_MODE_POINT);
1941 tcu::Surface resultImage (m_renderSize, m_renderSize);
1942 std::vector<tcu::Vec4> drawBuffer;
1943 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
1944 std::vector<PointSceneSpec::ScenePoint> points;
1945 std::vector<LineSceneSpec::SceneLine> lines;
1947 const InstanceInterface& vk = m_context.getInstanceInterface();
1948 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1949 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(vk, physicalDevice);
1951 if (!(deviceFeatures.fillModeNonSolid) && (m_polygonMode == VK_POLYGON_MODE_LINE || m_polygonMode == VK_POLYGON_MODE_POINT))
1952 TCU_THROW(NotSupportedError, "Wireframe fill modes are not supported");
1955 generateVertices(drawBuffer);
1956 extractTriangles(triangles, drawBuffer);
1958 if (m_polygonMode == VK_POLYGON_MODE_LINE)
1959 extractLines(triangles ,lines);
1960 else if (m_polygonMode == VK_POLYGON_MODE_POINT)
1961 extractPoints(triangles, points);
1965 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Setting front face to " << m_frontFace << tcu::TestLog::EndMessage;
1966 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Setting cull face to " << m_cullMode << tcu::TestLog::EndMessage;
1967 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Drawing test pattern (" << m_primitiveTopology << ")" << tcu::TestLog::EndMessage;
1969 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
1974 RasterizationArguments args;
1975 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1976 bool isCompareOk = false;
1978 args.numSamples = m_multisampling ? 1 : 0;
1979 args.subpixelBits = m_subpixelBits;
1980 args.redBits = colorBits[0];
1981 args.greenBits = colorBits[1];
1982 args.blueBits = colorBits[2];
1984 switch (m_polygonMode)
1986 case VK_POLYGON_MODE_LINE:
1988 LineSceneSpec scene;
1989 scene.lineWidth = 0;
1990 scene.lines.swap(lines);
1991 isCompareOk = verifyLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
1994 case VK_POLYGON_MODE_POINT:
1996 PointSceneSpec scene;
1997 scene.points.swap(points);
1998 isCompareOk = verifyPointGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
2003 TriangleSceneSpec scene;
2004 scene.triangles.swap(triangles);
2005 isCompareOk = verifyTriangleGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), tcu::VERIFICATIONMODE_WEAK);
2011 return tcu::TestStatus::pass("Pass");
2013 return tcu::TestStatus::fail("Incorrect rendering");
2017 void CullingTestInstance::generateVertices (std::vector<tcu::Vec4>& outData) const
2019 de::Random rnd(543210);
2022 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
2024 outData[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
2025 outData[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
2026 outData[vtxNdx].z() = 0.0f;
2027 outData[vtxNdx].w() = 1.0f;
2031 void CullingTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const
2033 const bool cullDirection = (m_cullMode == VK_CULL_MODE_FRONT_BIT) ^ (m_frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE);
2036 if (m_cullMode == VK_CULL_MODE_FRONT_AND_BACK)
2039 switch (m_primitiveTopology)
2041 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
2043 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
2045 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
2046 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
2047 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
2049 if (triangleOrder(v0, v1, v2) != cullDirection)
2051 TriangleSceneSpec::SceneTriangle tri;
2052 tri.positions[0] = v0; tri.sharedEdge[0] = false;
2053 tri.positions[1] = v1; tri.sharedEdge[1] = false;
2054 tri.positions[2] = v2; tri.sharedEdge[2] = false;
2056 outTriangles.push_back(tri);
2062 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
2064 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
2066 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
2067 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
2068 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
2070 if (triangleOrder(v0, v1, v2) != (cullDirection ^ (vtxNdx % 2 != 0)))
2072 TriangleSceneSpec::SceneTriangle tri;
2073 tri.positions[0] = v0; tri.sharedEdge[0] = false;
2074 tri.positions[1] = v1; tri.sharedEdge[1] = false;
2075 tri.positions[2] = v2; tri.sharedEdge[2] = false;
2077 outTriangles.push_back(tri);
2083 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
2085 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2087 const tcu::Vec4& v0 = vertices[0];
2088 const tcu::Vec4& v1 = vertices[vtxNdx + 0];
2089 const tcu::Vec4& v2 = vertices[vtxNdx + 1];
2091 if (triangleOrder(v0, v1, v2) != cullDirection)
2093 TriangleSceneSpec::SceneTriangle tri;
2094 tri.positions[0] = v0; tri.sharedEdge[0] = false;
2095 tri.positions[1] = v1; tri.sharedEdge[1] = false;
2096 tri.positions[2] = v2; tri.sharedEdge[2] = false;
2098 outTriangles.push_back(tri);
2109 void CullingTestInstance::extractLines (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles,
2110 std::vector<LineSceneSpec::SceneLine>& outLines) const
2112 for (int triNdx = 0; triNdx < (int)outTriangles.size(); ++triNdx)
2114 for (int vrtxNdx = 0; vrtxNdx < 2; ++vrtxNdx)
2116 LineSceneSpec::SceneLine line;
2117 line.positions[0] = outTriangles.at(triNdx).positions[vrtxNdx];
2118 line.positions[1] = outTriangles.at(triNdx).positions[vrtxNdx + 1];
2120 outLines.push_back(line);
2122 LineSceneSpec::SceneLine line;
2123 line.positions[0] = outTriangles.at(triNdx).positions[2];
2124 line.positions[1] = outTriangles.at(triNdx).positions[0];
2125 outLines.push_back(line);
2129 void CullingTestInstance::extractPoints (std::vector<TriangleSceneSpec::SceneTriangle> &outTriangles,
2130 std::vector<PointSceneSpec::ScenePoint> &outPoints) const
2132 for (int triNdx = 0; triNdx < (int)outTriangles.size(); ++triNdx)
2134 for (int vrtxNdx = 0; vrtxNdx < 3; ++vrtxNdx)
2136 PointSceneSpec::ScenePoint point;
2137 point.position = outTriangles.at(triNdx).positions[vrtxNdx];
2138 point.pointSize = 1.0f;
2140 outPoints.push_back(point);
2145 bool CullingTestInstance::triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const
2147 const tcu::Vec2 s0 = v0.swizzle(0, 1) / v0.w();
2148 const tcu::Vec2 s1 = v1.swizzle(0, 1) / v1.w();
2149 const tcu::Vec2 s2 = v2.swizzle(0, 1) / v2.w();
2152 return ((s1.x() - s0.x()) * (s2.y() - s0.y()) - (s2.x() - s0.x()) * (s1.y() - s0.y())) > 0;
2156 const VkPipelineRasterizationStateCreateInfo* CullingTestInstance::getRasterizationStateCreateInfo (void) const
2158 static VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
2160 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
2161 DE_NULL, // const void* pNext;
2162 0, // VkPipelineRasterizationStateCreateFlags flags;
2163 false, // VkBool32 depthClipEnable;
2164 false, // VkBool32 rasterizerDiscardEnable;
2165 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
2166 VK_CULL_MODE_NONE, // VkCullMode cullMode;
2167 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
2168 VK_FALSE, // VkBool32 depthBiasEnable;
2169 0.0f, // float depthBias;
2170 0.0f, // float depthBiasClamp;
2171 0.0f, // float slopeScaledDepthBias;
2172 getLineWidth(), // float lineWidth;
2175 rasterizationStateCreateInfo.lineWidth = getLineWidth();
2176 rasterizationStateCreateInfo.cullMode = m_cullMode;
2177 rasterizationStateCreateInfo.frontFace = m_frontFace;
2178 rasterizationStateCreateInfo.polygonMode = m_polygonMode;
2180 return &rasterizationStateCreateInfo;
2183 class CullingTestCase : public BaseRenderingTestCase
2186 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)
2187 : BaseRenderingTestCase (context, name, description, sampleCount)
2188 , m_cullMode (cullMode)
2189 , m_primitiveTopology (primitiveTopology)
2190 , m_frontFace (frontFace)
2191 , m_polygonMode (polygonMode)
2194 virtual TestInstance* createInstance (Context& context) const
2196 return new CullingTestInstance(context, m_cullMode, m_primitiveTopology, m_frontFace, m_polygonMode);
2199 const VkCullModeFlags m_cullMode;
2200 const VkPrimitiveTopology m_primitiveTopology;
2201 const VkFrontFace m_frontFace;
2202 const VkPolygonMode m_polygonMode;
2205 class TriangleInterpolationTestInstance : public BaseRenderingTestInstance
2209 TriangleInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount)
2210 : BaseRenderingTestInstance (context, sampleCount, DEFAULT_RENDER_SIZE)
2211 , m_primitiveTopology (primitiveTopology)
2212 , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
2213 , m_iterationCount (3)
2215 , m_allIterationsPassed (true)
2216 , m_flatshade ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2219 tcu::TestStatus iterate (void);
2223 void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
2224 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
2227 VkPrimitiveTopology m_primitiveTopology;
2228 const bool m_projective;
2229 const int m_iterationCount;
2231 bool m_allIterationsPassed;
2232 const deBool m_flatshade;
2235 tcu::TestStatus TriangleInterpolationTestInstance::iterate (void)
2237 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
2238 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
2239 tcu::Surface resultImage (m_renderSize, m_renderSize);
2240 std::vector<tcu::Vec4> drawBuffer;
2241 std::vector<tcu::Vec4> colorBuffer;
2242 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
2245 generateVertices(m_iteration, drawBuffer, colorBuffer);
2246 extractTriangles(triangles, drawBuffer, colorBuffer);
2250 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
2251 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
2252 m_context.getTestContext().getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
2256 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitiveTopology);
2260 RasterizationArguments args;
2261 TriangleSceneSpec scene;
2262 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
2264 args.numSamples = m_multisampling ? 1 : 0;
2265 args.subpixelBits = m_subpixelBits;
2266 args.redBits = colorBits[0];
2267 args.greenBits = colorBits[1];
2268 args.blueBits = colorBits[2];
2270 scene.triangles.swap(triangles);
2272 if (!verifyTriangleGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog()))
2273 m_allIterationsPassed = false;
2277 if (++m_iteration == m_iterationCount)
2279 if (m_allIterationsPassed)
2280 return tcu::TestStatus::pass("Pass");
2282 return tcu::TestStatus::fail("Found invalid pixel values");
2285 return tcu::TestStatus::incomplete();
2288 void TriangleInterpolationTestInstance::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
2290 // use only red, green and blue
2291 const tcu::Vec4 colors[] =
2293 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
2294 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
2295 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
2298 de::Random rnd(123 + iteration * 1000 + (int)m_primitiveTopology);
2300 outVertices.resize(6);
2301 outColors.resize(6);
2303 for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
2305 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
2306 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
2307 outVertices[vtxNdx].z() = 0.0f;
2310 outVertices[vtxNdx].w() = 1.0f;
2313 const float w = rnd.getFloat(0.2f, 4.0f);
2315 outVertices[vtxNdx].x() *= w;
2316 outVertices[vtxNdx].y() *= w;
2317 outVertices[vtxNdx].z() *= w;
2318 outVertices[vtxNdx].w() = w;
2321 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
2325 void TriangleInterpolationTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
2327 switch (m_primitiveTopology)
2329 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
2331 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
2333 TriangleSceneSpec::SceneTriangle tri;
2334 tri.positions[0] = vertices[vtxNdx + 0];
2335 tri.positions[1] = vertices[vtxNdx + 1];
2336 tri.positions[2] = vertices[vtxNdx + 2];
2337 tri.sharedEdge[0] = false;
2338 tri.sharedEdge[1] = false;
2339 tri.sharedEdge[2] = false;
2343 tri.colors[0] = colors[vtxNdx];
2344 tri.colors[1] = colors[vtxNdx];
2345 tri.colors[2] = colors[vtxNdx];
2349 tri.colors[0] = colors[vtxNdx + 0];
2350 tri.colors[1] = colors[vtxNdx + 1];
2351 tri.colors[2] = colors[vtxNdx + 2];
2354 outTriangles.push_back(tri);
2359 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
2361 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
2363 TriangleSceneSpec::SceneTriangle tri;
2364 tri.positions[0] = vertices[vtxNdx + 0];
2365 tri.positions[1] = vertices[vtxNdx + 1];
2366 tri.positions[2] = vertices[vtxNdx + 2];
2367 tri.sharedEdge[0] = false;
2368 tri.sharedEdge[1] = false;
2369 tri.sharedEdge[2] = false;
2373 tri.colors[0] = colors[vtxNdx];
2374 tri.colors[1] = colors[vtxNdx];
2375 tri.colors[2] = colors[vtxNdx];
2379 tri.colors[0] = colors[vtxNdx + 0];
2380 tri.colors[1] = colors[vtxNdx + 1];
2381 tri.colors[2] = colors[vtxNdx + 2];
2384 outTriangles.push_back(tri);
2389 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
2391 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2393 TriangleSceneSpec::SceneTriangle tri;
2394 tri.positions[0] = vertices[0];
2395 tri.positions[1] = vertices[vtxNdx + 0];
2396 tri.positions[2] = vertices[vtxNdx + 1];
2397 tri.sharedEdge[0] = false;
2398 tri.sharedEdge[1] = false;
2399 tri.sharedEdge[2] = false;
2403 tri.colors[0] = colors[vtxNdx];
2404 tri.colors[1] = colors[vtxNdx];
2405 tri.colors[2] = colors[vtxNdx];
2409 tri.colors[0] = colors[0];
2410 tri.colors[1] = colors[vtxNdx + 0];
2411 tri.colors[2] = colors[vtxNdx + 1];
2414 outTriangles.push_back(tri);
2424 class TriangleInterpolationTestCase : public BaseRenderingTestCase
2427 TriangleInterpolationTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2428 : BaseRenderingTestCase (context, name, description, sampleCount, (flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2429 , m_primitiveTopology (primitiveTopology)
2433 virtual TestInstance* createInstance (Context& context) const
2435 return new TriangleInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_sampleCount);
2438 const VkPrimitiveTopology m_primitiveTopology;
2442 class LineInterpolationTestInstance : public BaseRenderingTestInstance
2445 LineInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount);
2447 virtual tcu::TestStatus iterate (void);
2450 void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
2451 void extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
2452 virtual float getLineWidth (void) const;
2454 VkPrimitiveTopology m_primitiveTopology;
2455 const bool m_projective;
2456 const int m_iterationCount;
2457 const PrimitiveWideness m_primitiveWideness;
2460 bool m_allIterationsPassed;
2461 float m_maxLineWidth;
2462 std::vector<float> m_lineWidths;
2466 LineInterpolationTestInstance::LineInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
2467 : BaseRenderingTestInstance (context, sampleCount)
2468 , m_primitiveTopology (primitiveTopology)
2469 , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
2470 , m_iterationCount (3)
2471 , m_primitiveWideness (wideness)
2473 , m_allIterationsPassed (true)
2474 , m_maxLineWidth (1.0f)
2475 , m_flatshade ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2477 DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
2479 if (!context.getDeviceProperties().limits.strictLines)
2480 TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
2482 // create line widths
2483 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
2485 m_lineWidths.resize(m_iterationCount, 1.0f);
2487 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
2489 if (!m_context.getDeviceFeatures().wideLines)
2490 TCU_THROW(NotSupportedError , "wide line support required");
2492 const float* range = context.getDeviceProperties().limits.lineWidthRange;
2494 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
2496 // no wide line support
2497 if (range[1] <= 1.0f)
2498 throw tcu::NotSupportedError("wide line support required");
2500 // set hand picked sizes
2501 m_lineWidths.push_back(5.0f);
2502 m_lineWidths.push_back(10.0f);
2503 m_lineWidths.push_back(range[1]);
2504 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
2506 m_maxLineWidth = range[1];
2512 tcu::TestStatus LineInterpolationTestInstance::iterate (void)
2514 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
2515 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
2516 const float lineWidth = getLineWidth();
2517 tcu::Surface resultImage (m_renderSize, m_renderSize);
2518 std::vector<tcu::Vec4> drawBuffer;
2519 std::vector<tcu::Vec4> colorBuffer;
2520 std::vector<LineSceneSpec::SceneLine> lines;
2523 if (lineWidth <= m_maxLineWidth)
2526 generateVertices(m_iteration, drawBuffer, colorBuffer);
2527 extractLines(lines, drawBuffer, colorBuffer);
2531 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
2532 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
2533 m_context.getTestContext().getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
2537 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitiveTopology);
2541 RasterizationArguments args;
2542 LineSceneSpec scene;
2544 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
2546 args.numSamples = m_multisampling ? 1 : 0;
2547 args.subpixelBits = m_subpixelBits;
2548 args.redBits = colorBits[0];
2549 args.greenBits = colorBits[1];
2550 args.blueBits = colorBits[2];
2552 scene.lines.swap(lines);
2553 scene.lineWidth = getLineWidth();
2555 if (!verifyTriangulatedLineGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog()))
2556 m_allIterationsPassed = false;
2560 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
2563 if (++m_iteration == m_iterationCount)
2565 if (m_allIterationsPassed)
2566 return tcu::TestStatus::pass("Pass");
2568 return tcu::TestStatus::fail("Incorrect rasterization");
2571 return tcu::TestStatus::incomplete();
2574 void LineInterpolationTestInstance::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
2576 // use only red, green and blue
2577 const tcu::Vec4 colors[] =
2579 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
2580 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
2581 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
2584 de::Random rnd(123 + iteration * 1000 + (int)m_primitiveTopology);
2586 outVertices.resize(6);
2587 outColors.resize(6);
2589 for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
2591 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
2592 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
2593 outVertices[vtxNdx].z() = 0.0f;
2596 outVertices[vtxNdx].w() = 1.0f;
2599 const float w = rnd.getFloat(0.2f, 4.0f);
2601 outVertices[vtxNdx].x() *= w;
2602 outVertices[vtxNdx].y() *= w;
2603 outVertices[vtxNdx].z() *= w;
2604 outVertices[vtxNdx].w() = w;
2607 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
2611 void LineInterpolationTestInstance::extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
2613 switch (m_primitiveTopology)
2615 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
2617 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; vtxNdx += 2)
2619 LineSceneSpec::SceneLine line;
2620 line.positions[0] = vertices[vtxNdx + 0];
2621 line.positions[1] = vertices[vtxNdx + 1];
2625 line.colors[0] = colors[vtxNdx];
2626 line.colors[1] = colors[vtxNdx];
2630 line.colors[0] = colors[vtxNdx + 0];
2631 line.colors[1] = colors[vtxNdx + 1];
2634 outLines.push_back(line);
2639 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
2641 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2643 LineSceneSpec::SceneLine line;
2644 line.positions[0] = vertices[vtxNdx + 0];
2645 line.positions[1] = vertices[vtxNdx + 1];
2649 line.colors[0] = colors[vtxNdx];
2650 line.colors[1] = colors[vtxNdx];
2654 line.colors[0] = colors[vtxNdx + 0];
2655 line.colors[1] = colors[vtxNdx + 1];
2658 outLines.push_back(line);
2668 float LineInterpolationTestInstance::getLineWidth (void) const
2670 return m_lineWidths[m_iteration];
2673 class LineInterpolationTestCase : public BaseRenderingTestCase
2676 LineInterpolationTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2677 : BaseRenderingTestCase (context, name, description, sampleCount, (flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2678 , m_primitiveTopology (primitiveTopology)
2680 , m_wideness (wideness)
2683 virtual TestInstance* createInstance (Context& context) const
2685 return new LineInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_wideness, m_sampleCount);
2688 const VkPrimitiveTopology m_primitiveTopology;
2690 const PrimitiveWideness m_wideness;
2693 void createRasterizationTests (tcu::TestCaseGroup* rasterizationTests)
2695 tcu::TestContext& testCtx = rasterizationTests->getTestContext();
2699 tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(testCtx, "primitives", "Primitive rasterization");
2701 rasterizationTests->addChild(primitives);
2703 primitives->addChild(new BaseTestCase<TrianglesTestInstance> (testCtx, "triangles", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result"));
2704 primitives->addChild(new BaseTestCase<TriangleStripTestInstance> (testCtx, "triangle_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, verify rasterization result"));
2705 primitives->addChild(new BaseTestCase<TriangleFanTestInstance> (testCtx, "triangle_fan", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, verify rasterization result"));
2706 primitives->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW));
2707 primitives->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "line_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result", PRIMITIVEWIDENESS_NARROW));
2708 primitives->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
2709 primitives->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "line_strip_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
2710 primitives->addChild(new WidenessTestCase<PointTestInstance> (testCtx, "points", "Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
2715 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(testCtx, "fill_rules", "Primitive fill rules");
2717 rasterizationTests->addChild(fillRules);
2719 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_BASIC));
2720 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad_reverse", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_REVERSED));
2721 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_full", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_FULL));
2722 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_partly", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_PARTIAL));
2723 fillRules->addChild(new FillRuleTestCase(testCtx, "projected", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_PROJECTED));
2728 static const struct CullMode
2730 VkCullModeFlags mode;
2734 { VK_CULL_MODE_FRONT_BIT, "front_" },
2735 { VK_CULL_MODE_BACK_BIT, "back_" },
2736 { VK_CULL_MODE_FRONT_AND_BACK, "both_" },
2738 static const struct PrimitiveType
2740 VkPrimitiveTopology type;
2742 } primitiveTypes[] =
2744 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangles" },
2745 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, "triangle_strip" },
2746 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, "triangle_fan" },
2748 static const struct FrontFaceOrder
2751 const char* postfix;
2754 { VK_FRONT_FACE_COUNTER_CLOCKWISE, "" },
2755 { VK_FRONT_FACE_CLOCKWISE, "_reverse" },
2758 static const struct PolygonMode
2764 { VK_POLYGON_MODE_FILL, "" },
2765 { VK_POLYGON_MODE_LINE, "_line" },
2766 { VK_POLYGON_MODE_POINT, "_point" }
2769 tcu::TestCaseGroup* const culling = new tcu::TestCaseGroup(testCtx, "culling", "Culling");
2771 rasterizationTests->addChild(culling);
2773 for (int cullModeNdx = 0; cullModeNdx < DE_LENGTH_OF_ARRAY(cullModes); ++cullModeNdx)
2774 for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveNdx)
2775 for (int frontOrderNdx = 0; frontOrderNdx < DE_LENGTH_OF_ARRAY(frontOrders); ++frontOrderNdx)
2776 for (int polygonModeNdx = 0; polygonModeNdx < DE_LENGTH_OF_ARRAY(polygonModes); ++polygonModeNdx)
2778 if (!(cullModes[cullModeNdx].mode == VK_CULL_MODE_FRONT_AND_BACK && polygonModes[polygonModeNdx].mode != VK_POLYGON_MODE_FILL))
2780 const std::string name = std::string(cullModes[cullModeNdx].prefix) + primitiveTypes[primitiveNdx].name + frontOrders[frontOrderNdx].postfix + polygonModes[polygonModeNdx].name;
2781 culling->addChild(new CullingTestCase(testCtx, name, "Test primitive culling.", cullModes[cullModeNdx].mode, primitiveTypes[primitiveNdx].type, frontOrders[frontOrderNdx].mode, polygonModes[polygonModeNdx].mode));
2788 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(testCtx, "interpolation", "Test interpolation");
2790 rasterizationTests->addChild(interpolation);
2794 tcu::TestCaseGroup* const basic = new tcu::TestCaseGroup(testCtx, "basic", "Non-projective interpolation");
2796 interpolation->addChild(basic);
2798 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_NONE));
2799 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_NONE));
2800 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_NONE));
2801 basic->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW));
2802 basic->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW));
2803 basic->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE));
2804 basic->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE));
2809 tcu::TestCaseGroup* const projected = new tcu::TestCaseGroup(testCtx, "projected", "Projective interpolation");
2811 interpolation->addChild(projected);
2813 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_PROJECTED));
2814 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_PROJECTED));
2815 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_PROJECTED));
2816 projected->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW));
2817 projected->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW));
2818 projected->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE));
2819 projected->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE));
2825 tcu::TestCaseGroup* const flatshading = new tcu::TestCaseGroup(testCtx, "flatshading", "Test flatshading");
2827 rasterizationTests->addChild(flatshading);
2829 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_FLATSHADE));
2830 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_FLATSHADE));
2831 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_FLATSHADE));
2832 flatshading->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW));
2833 flatshading->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW));
2834 flatshading->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE));
2835 flatshading->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE));
2838 const VkSampleCountFlagBits samples[] =
2840 VK_SAMPLE_COUNT_2_BIT,
2841 VK_SAMPLE_COUNT_4_BIT,
2842 VK_SAMPLE_COUNT_8_BIT,
2843 VK_SAMPLE_COUNT_16_BIT,
2844 VK_SAMPLE_COUNT_32_BIT,
2845 VK_SAMPLE_COUNT_64_BIT
2848 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2850 std::ostringstream caseName;
2852 caseName << "_multisample_" << (2 << samplesNdx) << "_bit";
2856 tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(testCtx, ("primitives" + caseName.str()).c_str(), "Primitive rasterization");
2858 rasterizationTests->addChild(primitives);
2860 primitives->addChild(new BaseTestCase<TrianglesTestInstance> (testCtx, "triangles", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result", samples[samplesNdx]));
2861 primitives->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, samples[samplesNdx]));
2862 primitives->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE, samples[samplesNdx]));
2863 primitives->addChild(new WidenessTestCase<PointTestInstance> (testCtx, "points", "Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result", PRIMITIVEWIDENESS_WIDE, samples[samplesNdx]));
2868 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(testCtx, ("fill_rules" + caseName.str()).c_str(), "Primitive fill rules");
2870 rasterizationTests->addChild(fillRules);
2872 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_BASIC, samples[samplesNdx]));
2873 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad_reverse", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_REVERSED, samples[samplesNdx]));
2874 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_full", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_FULL, samples[samplesNdx]));
2875 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_partly", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_PARTIAL, samples[samplesNdx]));
2876 fillRules->addChild(new FillRuleTestCase(testCtx, "projected", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_PROJECTED, samples[samplesNdx]));
2881 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(testCtx, ("interpolation" + caseName.str()).c_str(), "Test interpolation");
2883 rasterizationTests->addChild(interpolation);
2885 interpolation->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_NONE, samples[samplesNdx]));
2886 interpolation->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, samples[samplesNdx]));
2887 interpolation->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, samples[samplesNdx]));
2894 tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
2896 return createTestGroup(testCtx, "rasterization", "Rasterization Tests", createRasterizationTests);