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"
53 namespace rasterization
58 using tcu::RasterizationArguments;
59 using tcu::TriangleSceneSpec;
60 using tcu::PointSceneSpec;
61 using tcu::LineSceneSpec;
62 using tcu::LineInterpolationMethod;
64 static const char* const s_shaderVertexTemplate = "#version 310 es\n"
65 "layout(location = 0) in highp vec4 a_position;\n"
66 "layout(location = 1) in highp vec4 a_color;\n"
67 "layout(location = 0) ${INTERPOLATION}out highp vec4 v_color;\n"
68 "layout (set=0, binding=0) uniform PointSize {\n"
69 " highp float u_pointSize;\n"
73 " gl_Position = a_position;\n"
74 " gl_PointSize = u_pointSize;\n"
75 " v_color = a_color;\n"
78 static const char* const s_shaderFragmentTemplate = "#version 310 es\n"
79 "layout(location = 0) out highp vec4 fragColor;\n"
80 "layout(location = 0) ${INTERPOLATION}in highp vec4 v_color;\n"
83 " fragColor = v_color;\n"
85 enum InterpolationCaseFlags
87 INTERPOLATIONFLAGS_NONE = 0,
88 INTERPOLATIONFLAGS_PROJECTED = (1 << 1),
89 INTERPOLATIONFLAGS_FLATSHADE = (1 << 2),
92 enum PrimitiveWideness
94 PRIMITIVEWIDENESS_NARROW = 0,
95 PRIMITIVEWIDENESS_WIDE,
97 PRIMITIVEWIDENESS_LAST
100 class BaseRenderingTestCase : public TestCase
103 BaseRenderingTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deBool flatshade = DE_FALSE);
104 virtual ~BaseRenderingTestCase (void);
106 virtual void initPrograms (vk::SourceCollections& programCollection) const;
109 const VkSampleCountFlagBits m_sampleCount;
110 const deBool m_flatshade;
113 BaseRenderingTestCase::BaseRenderingTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount, deBool flatshade)
114 : TestCase(context, name, description)
115 , m_sampleCount (sampleCount)
116 , m_flatshade (flatshade)
120 void BaseRenderingTestCase::initPrograms (vk::SourceCollections& programCollection) const
122 tcu::StringTemplate vertexSource (s_shaderVertexTemplate);
123 tcu::StringTemplate fragmentSource (s_shaderFragmentTemplate);
124 std::map<std::string, std::string> params;
126 params["INTERPOLATION"] = (m_flatshade) ? ("flat ") : ("");
128 programCollection.glslSources.add("vertext_shader") << glu::VertexSource(vertexSource.specialize(params));
129 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fragmentSource.specialize(params));
132 BaseRenderingTestCase::~BaseRenderingTestCase (void)
136 class BaseRenderingTestInstance : public TestInstance
140 DEFAULT_RENDER_SIZE = 256
143 BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deUint32 renderSize = DEFAULT_RENDER_SIZE);
144 ~BaseRenderingTestInstance (void);
147 void addImageTransitionBarrier (VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const;
148 void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology);
149 void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, const std::vector<tcu::Vec4>& coloDrata, VkPrimitiveTopology primitiveTopology);
150 virtual float getLineWidth (void) const;
151 virtual float getPointSize (void) const;
154 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
157 const VkPipelineColorBlendStateCreateInfo* getColorBlendStateCreateInfo (void) const;
159 const tcu::TextureFormat& getTextureFormat (void) const;
161 const deUint32 m_renderSize;
162 const VkSampleCountFlagBits m_sampleCount;
163 const deUint32 m_subpixelBits;
164 const deBool m_multisampling;
166 const VkFormat m_imageFormat;
167 const tcu::TextureFormat m_textureFormat;
168 Move<VkCommandPool> m_commandPool;
170 Move<VkImage> m_image;
171 de::MovePtr<Allocation> m_imageMemory;
172 Move<VkImageView> m_imageView;
174 Move<VkImage> m_resolvedImage;
175 de::MovePtr<Allocation> m_resolvedImageMemory;
176 Move<VkImageView> m_resolvedImageView;
178 Move<VkRenderPass> m_renderPass;
179 Move<VkFramebuffer> m_frameBuffer;
181 Move<VkDescriptorPool> m_descriptorPool;
182 Move<VkDescriptorSet> m_descriptorSet;
183 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
185 Move<VkBuffer> m_uniformBuffer;
186 de::MovePtr<Allocation> m_uniformBufferMemory;
187 const VkDeviceSize m_uniformBufferSize;
189 Move<VkPipelineLayout> m_pipelineLayout;
191 Move<VkShaderModule> m_vertexShaderModule;
192 Move<VkShaderModule> m_fragmentShaderModule;
194 Move<VkFence> m_fence;
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);
539 m_fence = createFence(vkd, vkDevice);
543 const VkBufferCreateInfo bufferCreateInfo =
545 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
546 DE_NULL, // const void* pNext;
547 0u, // VkBufferCreateFlags flags;
548 m_resultBufferSize, // VkDeviceSize size;
549 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
550 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
551 1u, // deUint32 queueFamilyIndexCount;
552 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
555 m_resultBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo);
556 m_resultBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_resultBuffer), MemoryRequirement::HostVisible);
558 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));
561 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Sample count = " << getSampleCountFlagsStr(m_sampleCount) << tcu::TestLog::EndMessage;
562 m_context.getTestContext().getLog() << tcu::TestLog::Message << "SUBPIXEL_BITS = " << m_subpixelBits << tcu::TestLog::EndMessage;
565 BaseRenderingTestInstance::~BaseRenderingTestInstance (void)
570 void BaseRenderingTestInstance::addImageTransitionBarrier(VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const
573 const DeviceInterface& vkd = m_context.getDeviceInterface();
575 const VkImageSubresourceRange subResourcerange =
577 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
578 0, // deUint32 baseMipLevel;
579 1, // deUint32 levelCount;
580 0, // deUint32 baseArrayLayer;
581 1 // deUint32 layerCount;
584 const VkImageMemoryBarrier imageBarrier =
586 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
587 DE_NULL, // const void* pNext;
588 srcAccessMask, // VkAccessFlags srcAccessMask;
589 dstAccessMask, // VkAccessFlags dstAccessMask;
590 oldLayout, // VkImageLayout oldLayout;
591 newLayout, // VkImageLayout newLayout;
592 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
593 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
594 image, // VkImage image;
595 subResourcerange // VkImageSubresourceRange subresourceRange;
598 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier);
601 void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology)
603 // default to color white
604 const std::vector<tcu::Vec4> colorData(vertexData.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
606 drawPrimitives(result, vertexData, colorData, primitiveTopology);
609 void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology)
611 const DeviceInterface& vkd = m_context.getDeviceInterface();
612 const VkDevice vkDevice = m_context.getDevice();
613 const VkQueue queue = m_context.getUniversalQueue();
614 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
615 Allocator& allocator = m_context.getDefaultAllocator();
616 const size_t attributeBatchSize = positionData.size() * sizeof(tcu::Vec4);
618 Move<VkCommandBuffer> commandBuffer;
619 Move<VkPipeline> graphicsPipeline;
620 Move<VkBuffer> vertexBuffer;
621 de::MovePtr<Allocation> vertexBufferMemory;
622 const VkPhysicalDeviceProperties properties = m_context.getDeviceProperties();
624 if (attributeBatchSize > properties.limits.maxVertexInputAttributeOffset)
626 std::stringstream message;
627 message << "Larger vertex input attribute offset is needed (" << attributeBatchSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
628 TCU_THROW(NotSupportedError, message.str().c_str());
631 // Create Graphics Pipeline
633 const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
636 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
637 DE_NULL, // const void* pNext;
638 0, // VkPipelineShaderStageCreateFlags flags;
639 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStage stage;
640 *m_vertexShaderModule, // VkShader shader;
641 "main", // const char* pName;
642 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
645 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
646 DE_NULL, // const void* pNext;
647 0, // VkPipelineShaderStageCreateFlags flags;
648 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStage stage;
649 *m_fragmentShaderModule, // VkShader shader;
650 "main", // const char* pName;
651 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
655 const VkVertexInputBindingDescription vertexInputBindingDescription =
657 0u, // deUint32 binding;
658 sizeof(tcu::Vec4), // deUint32 strideInBytes;
659 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
662 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
665 0u, // deUint32 location;
666 0u, // deUint32 binding;
667 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
668 0u // deUint32 offsetInBytes;
671 1u, // deUint32 location;
672 0u, // deUint32 binding;
673 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
674 (deUint32)attributeBatchSize // deUint32 offsetInBytes;
678 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
680 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
681 DE_NULL, // const void* pNext;
682 0, // VkPipelineVertexInputStateCreateFlags flags;
683 1u, // deUint32 bindingCount;
684 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
685 2u, // deUint32 attributeCount;
686 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
689 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
691 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
692 DE_NULL, // const void* pNext;
693 0, // VkPipelineInputAssemblyStateCreateFlags flags;
694 primitiveTopology, // VkPrimitiveTopology topology;
695 false // VkBool32 primitiveRestartEnable;
698 const VkViewport viewport =
700 0.0f, // float originX;
701 0.0f, // float originY;
702 (float)m_renderSize, // float width;
703 (float)m_renderSize, // float height;
704 0.0f, // float minDepth;
705 1.0f // float maxDepth;
708 const VkRect2D scissor =
710 { 0, 0 }, // VkOffset2D offset;
711 { m_renderSize, m_renderSize } // VkExtent2D extent;
714 const VkPipelineViewportStateCreateInfo viewportStateParams =
716 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
717 DE_NULL, // const void* pNext;
718 0, // VkPipelineViewportStateCreateFlags flags;
719 1u, // deUint32 viewportCount;
720 &viewport, // const VkViewport* pViewports;
721 1u, // deUint32 scissorCount;
722 &scissor // const VkRect2D* pScissors;
725 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
727 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
728 DE_NULL, // const void* pNext;
729 0u, // VkPipelineMultisampleStateCreateFlags flags;
730 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
731 VK_FALSE, // VkBool32 sampleShadingEnable;
732 0.0f, // float minSampleShading;
733 DE_NULL, // const VkSampleMask* pSampleMask;
734 VK_FALSE, // VkBool32 alphaToCoverageEnable;
735 VK_FALSE // VkBool32 alphaToOneEnable;
738 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
740 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
741 DE_NULL, // const void* pNext;
742 0u, // VkPipelineCreateFlags flags;
743 2u, // deUint32 stageCount;
744 shaderStageParams, // const VkPipelineShaderStageCreateInfo* pStages;
745 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
746 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
747 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
748 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
749 getRasterizationStateCreateInfo(), // const VkPipelineRasterStateCreateInfo* pRasterizationState;
750 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
751 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
752 getColorBlendStateCreateInfo(), // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
753 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
754 *m_pipelineLayout, // VkPipelineLayout layout;
755 *m_renderPass, // VkRenderPass renderPass;
756 0u, // deUint32 subpass;
757 0u, // VkPipeline basePipelineHandle;
758 0u // deInt32 basePipelineIndex;
761 graphicsPipeline = createGraphicsPipeline(vkd, vkDevice, DE_NULL, &graphicsPipelineParams);
764 // Create Vertex Buffer
766 const VkBufferCreateInfo vertexBufferParams =
768 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
769 DE_NULL, // const void* pNext;
770 0u, // VkBufferCreateFlags flags;
771 attributeBatchSize * 2, // VkDeviceSize size;
772 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
773 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
774 1u, // deUint32 queueFamilyCount;
775 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
778 vertexBuffer = createBuffer(vkd, vkDevice, &vertexBufferParams);
779 vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
781 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
783 // Load vertices into vertex buffer
784 deMemcpy(vertexBufferMemory->getHostPtr(), positionData.data(), attributeBatchSize);
785 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) + attributeBatchSize, colorData.data(), attributeBatchSize);
786 flushMappedMemoryRange(vkd, vkDevice, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset(), vertexBufferParams.size);
789 // Create Command Buffer
790 commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
792 // Begin Command Buffer
794 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
796 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
797 DE_NULL, // const void* pNext;
798 0u, // VkCmdBufferOptimizeFlags flags;
799 DE_NULL // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
802 VK_CHECK(vkd.beginCommandBuffer(*commandBuffer, &cmdBufferBeginInfo));
805 addImageTransitionBarrier(*commandBuffer, *m_image,
806 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
807 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
808 0, // VkAccessFlags srcAccessMask
809 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
810 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
811 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
813 if (m_multisampling) {
814 addImageTransitionBarrier(*commandBuffer, *m_resolvedImage,
815 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
816 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
817 0, // VkAccessFlags srcAccessMask
818 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
819 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
820 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
825 const VkClearValue clearValue = makeClearValueColorF32(0.0, 0.0, 0.0, 1.0);
827 const VkRenderPassBeginInfo renderPassBeginInfo =
829 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
830 DE_NULL, // const void* pNext;
831 *m_renderPass, // VkRenderPass renderPass;
832 *m_frameBuffer, // VkFramebuffer framebuffer;
835 { m_renderSize, m_renderSize }
836 }, // VkRect2D renderArea;
837 1u, // deUint32 clearValueCount;
838 &clearValue // const VkClearValue* pClearValues;
841 vkd.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
844 const VkDeviceSize vertexBufferOffset = 0;
846 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
847 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL);
848 vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
849 vkd.cmdDraw(*commandBuffer, (deUint32)positionData.size(), 1, 0, 0);
850 vkd.cmdEndRenderPass(*commandBuffer);
855 const VkBufferMemoryBarrier bufferBarrier =
857 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
858 DE_NULL, // const void* pNext;
859 VK_ACCESS_TRANSFER_WRITE_BIT, // VkMemoryOutputFlags outputMask;
860 VK_ACCESS_HOST_READ_BIT, // VkMemoryInputFlags inputMask;
861 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
862 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
863 *m_resultBuffer, // VkBuffer buffer;
864 0u, // VkDeviceSize offset;
865 m_resultBufferSize // VkDeviceSize size;
868 const VkBufferImageCopy copyRegion =
870 0u, // VkDeviceSize bufferOffset;
871 m_renderSize, // deUint32 bufferRowLength;
872 m_renderSize, // deUint32 bufferImageHeight;
873 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u }, // VkImageSubresourceCopy imageSubresource;
874 { 0, 0, 0 }, // VkOffset3D imageOffset;
875 { m_renderSize, m_renderSize, 1u } // VkExtent3D imageExtent;
878 addImageTransitionBarrier(*commandBuffer,
879 m_multisampling ? *m_resolvedImage : *m_image,
880 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
881 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
882 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
883 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
884 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
885 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); // VkImageLayout newLayout;)
888 vkd.cmdCopyImageToBuffer(*commandBuffer, *m_resolvedImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, ©Region);
890 vkd.cmdCopyImageToBuffer(*commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, ©Region);
892 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);
895 VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
899 float pointSize = getPointSize();
900 deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize);
901 flushMappedMemoryRange(vkd, vkDevice, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset(), m_uniformBufferSize);
906 const VkSubmitInfo submitInfo =
908 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
909 DE_NULL, // const void* pNext;
910 0u, // deUint32 waitSemaphoreCount;
911 DE_NULL, // const VkSemaphore* pWaitSemaphores;
912 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
913 1u, // deUint32 commandBufferCount;
914 &commandBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
915 0u, // deUint32 signalSemaphoreCount;
916 DE_NULL, // const VkSemaphore* pSignalSemaphores;
919 VK_CHECK(vkd.resetFences(vkDevice, 1, &m_fence.get()));
920 VK_CHECK(vkd.queueSubmit(queue, 1, &submitInfo, *m_fence));
921 VK_CHECK(vkd.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
924 invalidateMappedMemoryRange(vkd, vkDevice, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(), m_resultBufferSize);
925 tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderSize, m_renderSize, 1), m_resultBufferMemory->getHostPtr()));
928 float BaseRenderingTestInstance::getLineWidth (void) const
933 float BaseRenderingTestInstance::getPointSize (void) const
938 const VkPipelineRasterizationStateCreateInfo* BaseRenderingTestInstance::getRasterizationStateCreateInfo (void) const
940 static VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
942 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
943 DE_NULL, // const void* pNext;
944 0, // VkPipelineRasterizationStateCreateFlags flags;
945 false, // VkBool32 depthClipEnable;
946 false, // VkBool32 rasterizerDiscardEnable;
947 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
948 VK_CULL_MODE_NONE, // VkCullMode cullMode;
949 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
950 VK_FALSE, // VkBool32 depthBiasEnable;
951 0.0f, // float depthBias;
952 0.0f, // float depthBiasClamp;
953 0.0f, // float slopeScaledDepthBias;
954 getLineWidth(), // float lineWidth;
957 rasterizationStateCreateInfo.lineWidth = getLineWidth();
958 return &rasterizationStateCreateInfo;
961 const VkPipelineColorBlendStateCreateInfo* BaseRenderingTestInstance::getColorBlendStateCreateInfo (void) const
963 static const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
965 false, // VkBool32 blendEnable;
966 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
967 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor;
968 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
969 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
970 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha;
971 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
972 (VK_COLOR_COMPONENT_R_BIT |
973 VK_COLOR_COMPONENT_G_BIT |
974 VK_COLOR_COMPONENT_B_BIT |
975 VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask;
978 static const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
980 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
981 DE_NULL, // const void* pNext;
982 0, // VkPipelineColorBlendStateCreateFlags flags;
983 false, // VkBool32 logicOpEnable;
984 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
985 1u, // deUint32 attachmentCount;
986 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
987 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
990 return &colorBlendStateParams;
993 const tcu::TextureFormat& BaseRenderingTestInstance::getTextureFormat (void) const
995 return m_textureFormat;
998 class BaseTriangleTestInstance : public BaseRenderingTestInstance
1001 BaseTriangleTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, VkSampleCountFlagBits sampleCount);
1002 virtual tcu::TestStatus iterate (void);
1005 virtual void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles) = DE_NULL;
1008 const int m_iterationCount;
1009 VkPrimitiveTopology m_primitiveTopology;
1010 bool m_allIterationsPassed;
1013 BaseTriangleTestInstance::BaseTriangleTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, VkSampleCountFlagBits sampleCount)
1014 : BaseRenderingTestInstance (context, sampleCount)
1016 , m_iterationCount (3)
1017 , m_primitiveTopology (primitiveTopology)
1018 , m_allIterationsPassed (true)
1022 tcu::TestStatus BaseTriangleTestInstance::iterate (void)
1024 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1025 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1026 tcu::Surface resultImage (m_renderSize, m_renderSize);
1027 std::vector<tcu::Vec4> drawBuffer;
1028 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
1030 generateTriangles(m_iteration, drawBuffer, triangles);
1033 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
1038 RasterizationArguments args;
1039 TriangleSceneSpec scene;
1041 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1043 args.numSamples = m_multisampling ? 1 : 0;
1044 args.subpixelBits = m_subpixelBits;
1045 args.redBits = colorBits[0];
1046 args.greenBits = colorBits[1];
1047 args.blueBits = colorBits[2];
1049 scene.triangles.swap(triangles);
1051 compareOk = verifyTriangleGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
1054 m_allIterationsPassed = false;
1058 if (++m_iteration == m_iterationCount)
1060 if (m_allIterationsPassed)
1061 return tcu::TestStatus::pass("Pass");
1063 return tcu::TestStatus::fail("Incorrect rasterization");
1066 return tcu::TestStatus::incomplete();
1069 class BaseLineTestInstance : public BaseRenderingTestInstance
1072 BaseLineTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount);
1073 virtual tcu::TestStatus iterate (void);
1074 virtual float getLineWidth (void) const;
1077 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines) = DE_NULL;
1080 const int m_iterationCount;
1081 VkPrimitiveTopology m_primitiveTopology;
1082 const PrimitiveWideness m_primitiveWideness;
1083 bool m_allIterationsPassed;
1084 float m_maxLineWidth;
1085 std::vector<float> m_lineWidths;
1088 BaseLineTestInstance::BaseLineTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
1089 : BaseRenderingTestInstance (context, sampleCount)
1091 , m_iterationCount (3)
1092 , m_primitiveTopology (primitiveTopology)
1093 , m_primitiveWideness (wideness)
1094 , m_allIterationsPassed (true)
1095 , m_maxLineWidth (1.0f)
1097 DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
1099 if (!context.getDeviceProperties().limits.strictLines)
1100 TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
1102 // create line widths
1103 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
1105 m_lineWidths.resize(m_iterationCount, 1.0f);
1107 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
1109 if (!m_context.getDeviceFeatures().wideLines)
1110 TCU_THROW(NotSupportedError , "wide line support required");
1112 const float* range = context.getDeviceProperties().limits.lineWidthRange;
1114 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
1116 // no wide line support
1117 if (range[1] <= 1.0f)
1118 TCU_THROW(NotSupportedError, "wide line support required");
1120 // set hand picked sizes
1121 m_lineWidths.push_back(5.0f);
1122 m_lineWidths.push_back(10.0f);
1123 m_lineWidths.push_back(range[1]);
1124 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
1126 m_maxLineWidth = range[1];
1132 tcu::TestStatus BaseLineTestInstance::iterate (void)
1134 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1135 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1136 const float lineWidth = getLineWidth();
1137 tcu::Surface resultImage (m_renderSize, m_renderSize);
1138 std::vector<tcu::Vec4> drawBuffer;
1139 std::vector<LineSceneSpec::SceneLine> lines;
1142 if (lineWidth <= m_maxLineWidth)
1145 generateLines(m_iteration, drawBuffer, lines);
1148 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
1152 RasterizationArguments args;
1153 LineSceneSpec scene;
1156 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1158 args.numSamples = m_multisampling ? 1 : 0;
1159 args.subpixelBits = m_subpixelBits;
1160 args.redBits = colorBits[0];
1161 args.greenBits = colorBits[1];
1162 args.blueBits = colorBits[2];
1164 scene.lines.swap(lines);
1165 scene.lineWidth = lineWidth;
1167 if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog()))
1168 m_allIterationsPassed = false;
1172 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
1175 if (++m_iteration == m_iterationCount)
1177 if (m_allIterationsPassed)
1178 return tcu::TestStatus::pass("Pass");
1180 return tcu::TestStatus::fail("Incorrect rasterization");
1183 return tcu::TestStatus::incomplete();
1187 float BaseLineTestInstance::getLineWidth (void) const
1189 return m_lineWidths[m_iteration];
1193 class PointTestInstance : public BaseRenderingTestInstance
1196 PointTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount);
1197 virtual tcu::TestStatus iterate (void);
1198 virtual float getPointSize (void) const;
1201 virtual void generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints);
1204 const int m_iterationCount;
1205 const PrimitiveWideness m_primitiveWideness;
1206 bool m_allIterationsPassed;
1207 float m_maxPointSize;
1208 std::vector<float> m_pointSizes;
1211 PointTestInstance::PointTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
1212 : BaseRenderingTestInstance (context, sampleCount)
1214 , m_iterationCount (3)
1215 , m_primitiveWideness (wideness)
1216 , m_allIterationsPassed (true)
1217 , m_maxPointSize (1.0f)
1219 // create point sizes
1220 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
1222 m_pointSizes.resize(m_iterationCount, 1.0f);
1224 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
1226 if (!m_context.getDeviceFeatures().largePoints)
1227 TCU_THROW(NotSupportedError , "large point support required");
1229 const float* range = context.getDeviceProperties().limits.pointSizeRange;
1231 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_ALIASED_POINT_SIZE_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
1233 // no wide line support
1234 if (range[1] <= 1.0f)
1235 TCU_THROW(NotSupportedError , "wide point support required");
1237 // set hand picked sizes
1238 m_pointSizes.push_back(10.0f);
1239 m_pointSizes.push_back(25.0f);
1240 m_pointSizes.push_back(range[1]);
1241 DE_ASSERT((int)m_pointSizes.size() == m_iterationCount);
1243 m_maxPointSize = range[1];
1249 tcu::TestStatus PointTestInstance::iterate (void)
1251 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1252 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1253 const float pointSize = getPointSize();
1254 tcu::Surface resultImage (m_renderSize, m_renderSize);
1255 std::vector<tcu::Vec4> drawBuffer;
1256 std::vector<PointSceneSpec::ScenePoint> points;
1259 if (pointSize <= m_maxPointSize)
1262 generatePoints(m_iteration, drawBuffer, points);
1265 drawPrimitives(resultImage, drawBuffer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
1270 RasterizationArguments args;
1271 PointSceneSpec scene;
1273 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1275 args.numSamples = m_multisampling ? 1 : 0;
1276 args.subpixelBits = m_subpixelBits;
1277 args.redBits = colorBits[0];
1278 args.greenBits = colorBits[1];
1279 args.blueBits = colorBits[2];
1281 scene.points.swap(points);
1283 compareOk = verifyPointGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
1286 m_allIterationsPassed = false;
1290 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point size " << pointSize << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
1293 if (++m_iteration == m_iterationCount)
1295 if (m_allIterationsPassed)
1296 return tcu::TestStatus::pass("Pass");
1298 return tcu::TestStatus::fail("Incorrect rasterization");
1301 return tcu::TestStatus::incomplete();
1304 float PointTestInstance::getPointSize (void) const
1306 return m_pointSizes[m_iteration];
1309 void PointTestInstance::generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints)
1316 // \note: these values are chosen arbitrarily
1317 outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f);
1318 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1319 outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f);
1320 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1321 outData[4] = tcu::Vec4(-0.2f, -0.4f, 0.0f, 1.0f);
1322 outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f);
1326 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1327 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1328 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1329 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1330 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1331 outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f);
1335 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1336 outData[1] = tcu::Vec4( 0.3f, -0.9f, 0.0f, 1.0f);
1337 outData[2] = tcu::Vec4( -0.4f, -0.1f, 0.0f, 1.0f);
1338 outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f);
1339 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1340 outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f);
1344 outPoints.resize(outData.size());
1345 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
1347 outPoints[pointNdx].position = outData[pointNdx];
1348 outPoints[pointNdx].pointSize = getPointSize();
1352 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outPoints.size() << " point(s): (point size = " << getPointSize() << ")" << tcu::TestLog::EndMessage;
1353 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
1354 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point " << (pointNdx+1) << ":\t" << outPoints[pointNdx].position << tcu::TestLog::EndMessage;
1357 template <typename ConcreteTestInstance>
1358 class BaseTestCase : public BaseRenderingTestCase
1361 BaseTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
1362 : BaseRenderingTestCase(context, name, description, sampleCount)
1365 virtual TestInstance* createInstance (Context& context) const
1367 return new ConcreteTestInstance(context, m_sampleCount);
1371 class TrianglesTestInstance : public BaseTriangleTestInstance
1374 TrianglesTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
1375 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, sampleCount)
1378 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
1381 void TrianglesTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
1388 // \note: these values are chosen arbitrarily
1389 outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f);
1390 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1391 outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f);
1392 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1393 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
1394 outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f);
1398 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1399 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1400 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1401 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1402 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1403 outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f);
1407 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1408 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1409 outData[2] = tcu::Vec4( -1.1f, -0.1f, 0.0f, 1.0f);
1410 outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f);
1411 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1412 outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f);
1416 outTriangles.resize(2);
1417 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
1418 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false;
1419 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false;
1421 outTriangles[1].positions[0] = outData[3]; outTriangles[1].sharedEdge[0] = false;
1422 outTriangles[1].positions[1] = outData[4]; outTriangles[1].sharedEdge[1] = false;
1423 outTriangles[1].positions[2] = outData[5]; outTriangles[1].sharedEdge[2] = false;
1426 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outTriangles.size() << " triangle(s):" << tcu::TestLog::EndMessage;
1427 for (int triangleNdx = 0; triangleNdx < (int)outTriangles.size(); ++triangleNdx)
1429 m_context.getTestContext().getLog()
1430 << tcu::TestLog::Message
1431 << "Triangle " << (triangleNdx+1) << ":"
1432 << "\n\t" << outTriangles[triangleNdx].positions[0]
1433 << "\n\t" << outTriangles[triangleNdx].positions[1]
1434 << "\n\t" << outTriangles[triangleNdx].positions[2]
1435 << tcu::TestLog::EndMessage;
1439 class TriangleStripTestInstance : public BaseTriangleTestInstance
1442 TriangleStripTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
1443 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, sampleCount)
1446 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
1449 void TriangleStripTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
1456 // \note: these values are chosen arbitrarily
1457 outData[0] = tcu::Vec4(-0.504f, 0.8f, 0.0f, 1.0f);
1458 outData[1] = tcu::Vec4(-0.2f, -0.2f, 0.0f, 1.0f);
1459 outData[2] = tcu::Vec4(-0.2f, 0.199f, 0.0f, 1.0f);
1460 outData[3] = tcu::Vec4( 0.5f, 0.201f, 0.0f, 1.0f);
1461 outData[4] = tcu::Vec4( 1.5f, 0.4f, 0.0f, 1.0f);
1465 outData[0] = tcu::Vec4(-0.499f, 0.129f, 0.0f, 1.0f);
1466 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1467 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1468 outData[3] = tcu::Vec4( 0.11f, -0.31f, 0.0f, 1.0f);
1469 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1473 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1474 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1475 outData[2] = tcu::Vec4(-0.87f, -0.1f, 0.0f, 1.0f);
1476 outData[3] = tcu::Vec4(-0.11f, 0.19f, 0.0f, 1.0f);
1477 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1481 outTriangles.resize(3);
1482 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
1483 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = true;
1484 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false;
1486 outTriangles[1].positions[0] = outData[2]; outTriangles[1].sharedEdge[0] = true;
1487 outTriangles[1].positions[1] = outData[1]; outTriangles[1].sharedEdge[1] = false;
1488 outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true;
1490 outTriangles[2].positions[0] = outData[2]; outTriangles[2].sharedEdge[0] = true;
1491 outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false;
1492 outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false;
1495 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering triangle strip, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1496 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1498 m_context.getTestContext().getLog()
1499 << tcu::TestLog::Message
1500 << "\t" << outData[vtxNdx]
1501 << tcu::TestLog::EndMessage;
1505 class TriangleFanTestInstance : public BaseTriangleTestInstance
1508 TriangleFanTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
1509 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, sampleCount)
1512 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
1515 void TriangleFanTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
1522 // \note: these values are chosen arbitrarily
1523 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1524 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1525 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1526 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1527 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
1531 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1532 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1533 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1534 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1535 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1539 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1540 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1541 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1542 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1543 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1547 outTriangles.resize(3);
1548 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
1549 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false;
1550 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = true;
1552 outTriangles[1].positions[0] = outData[0]; outTriangles[1].sharedEdge[0] = true;
1553 outTriangles[1].positions[1] = outData[2]; outTriangles[1].sharedEdge[1] = false;
1554 outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true;
1556 outTriangles[2].positions[0] = outData[0]; outTriangles[2].sharedEdge[0] = true;
1557 outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false;
1558 outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false;
1561 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering triangle fan, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1562 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1564 m_context.getTestContext().getLog()
1565 << tcu::TestLog::Message
1566 << "\t" << outData[vtxNdx]
1567 << tcu::TestLog::EndMessage;
1571 template <typename ConcreteTestInstance>
1572 class WidenessTestCase : public BaseRenderingTestCase
1575 WidenessTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
1576 : BaseRenderingTestCase(context, name, description, sampleCount)
1577 , m_wideness(wideness)
1580 virtual TestInstance* createInstance (Context& context) const
1582 return new ConcreteTestInstance(context, m_wideness, m_sampleCount);
1585 const PrimitiveWideness m_wideness;
1588 class LinesTestInstance : public BaseLineTestInstance
1591 LinesTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
1592 : BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, wideness, sampleCount)
1595 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
1598 void LinesTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
1605 // \note: these values are chosen arbitrarily
1606 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1607 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1608 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1609 outData[3] = tcu::Vec4(-0.3f, 0.2f, 0.0f, 1.0f);
1610 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
1611 outData[5] = tcu::Vec4( 0.1f, 0.5f, 0.0f, 1.0f);
1615 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1616 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1617 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1618 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1619 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1620 outData[5] = tcu::Vec4( 0.18f, -0.2f, 0.0f, 1.0f);
1624 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1625 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1626 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1627 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1628 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1629 outData[5] = tcu::Vec4( 0.8f, -0.7f, 0.0f, 1.0f);
1634 outLines[0].positions[0] = outData[0];
1635 outLines[0].positions[1] = outData[1];
1636 outLines[1].positions[0] = outData[2];
1637 outLines[1].positions[1] = outData[3];
1638 outLines[2].positions[0] = outData[4];
1639 outLines[2].positions[1] = outData[5];
1642 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outLines.size() << " lines(s): (width = " << getLineWidth() << ")" << tcu::TestLog::EndMessage;
1643 for (int lineNdx = 0; lineNdx < (int)outLines.size(); ++lineNdx)
1645 m_context.getTestContext().getLog()
1646 << tcu::TestLog::Message
1647 << "Line " << (lineNdx+1) << ":"
1648 << "\n\t" << outLines[lineNdx].positions[0]
1649 << "\n\t" << outLines[lineNdx].positions[1]
1650 << tcu::TestLog::EndMessage;
1654 class LineStripTestInstance : public BaseLineTestInstance
1657 LineStripTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
1658 : BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, wideness, sampleCount)
1661 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
1664 void LineStripTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
1671 // \note: these values are chosen arbitrarily
1672 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1673 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1674 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1675 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1679 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1680 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1681 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1682 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1686 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1687 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1688 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1689 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1694 outLines[0].positions[0] = outData[0];
1695 outLines[0].positions[1] = outData[1];
1696 outLines[1].positions[0] = outData[1];
1697 outLines[1].positions[1] = outData[2];
1698 outLines[2].positions[0] = outData[2];
1699 outLines[2].positions[1] = outData[3];
1702 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering line strip, width = " << getLineWidth() << ", " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1703 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1705 m_context.getTestContext().getLog()
1706 << tcu::TestLog::Message
1707 << "\t" << outData[vtxNdx]
1708 << tcu::TestLog::EndMessage;
1712 class FillRuleTestInstance : public BaseRenderingTestInstance
1715 enum FillRuleCaseType
1717 FILLRULECASE_BASIC = 0,
1718 FILLRULECASE_REVERSED,
1719 FILLRULECASE_CLIPPED_FULL,
1720 FILLRULECASE_CLIPPED_PARTIAL,
1721 FILLRULECASE_PROJECTED,
1725 FillRuleTestInstance (Context& context, FillRuleCaseType type, VkSampleCountFlagBits sampleCount);
1726 virtual tcu::TestStatus iterate (void);
1730 virtual const VkPipelineColorBlendStateCreateInfo* getColorBlendStateCreateInfo (void) const;
1731 int getRenderSize (FillRuleCaseType type) const;
1732 int getNumIterations (FillRuleCaseType type) const;
1733 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const;
1735 const FillRuleCaseType m_caseType;
1737 const int m_iterationCount;
1738 bool m_allIterationsPassed;
1742 FillRuleTestInstance::FillRuleTestInstance (Context& context, FillRuleCaseType type, VkSampleCountFlagBits sampleCount)
1743 : BaseRenderingTestInstance (context, sampleCount, getRenderSize(type))
1746 , m_iterationCount (getNumIterations(type))
1747 , m_allIterationsPassed (true)
1749 DE_ASSERT(type < FILLRULECASE_LAST);
1752 tcu::TestStatus FillRuleTestInstance::iterate (void)
1754 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1755 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1756 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1757 const int thresholdRed = 1 << (8 - colorBits[0]);
1758 const int thresholdGreen = 1 << (8 - colorBits[1]);
1759 const int thresholdBlue = 1 << (8 - colorBits[2]);
1760 tcu::Surface resultImage (m_renderSize, m_renderSize);
1761 std::vector<tcu::Vec4> drawBuffer;
1763 generateTriangles(m_iteration, drawBuffer);
1767 const std::vector<tcu::Vec4> colorBuffer (drawBuffer.size(), tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
1769 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Drawing gray triangles with shared edges.\nEnabling additive blending to detect overlapping fragments." << tcu::TestLog::EndMessage;
1771 drawPrimitives(resultImage, drawBuffer, colorBuffer, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
1774 // verify no overdraw
1776 const tcu::RGBA triangleColor = tcu::RGBA(127, 127, 127, 255);
1777 bool overdraw = false;
1779 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Verifying result." << tcu::TestLog::EndMessage;
1781 for (int y = 0; y < resultImage.getHeight(); ++y)
1782 for (int x = 0; x < resultImage.getWidth(); ++x)
1784 const tcu::RGBA color = resultImage.getPixel(x, y);
1786 // color values are greater than triangle color? Allow lower values for multisampled edges and background.
1787 if ((color.getRed() - triangleColor.getRed()) > thresholdRed ||
1788 (color.getGreen() - triangleColor.getGreen()) > thresholdGreen ||
1789 (color.getBlue() - triangleColor.getBlue()) > thresholdBlue)
1795 m_context.getTestContext().getLog() << tcu::TestLog::Message << "No overlapping fragments detected." << tcu::TestLog::EndMessage;
1798 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Overlapping fragments detected, image is not valid." << tcu::TestLog::EndMessage;
1799 m_allIterationsPassed = false;
1803 // verify no missing fragments in the full viewport case
1804 if (m_caseType == FILLRULECASE_CLIPPED_FULL)
1806 bool missingFragments = false;
1808 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Searching missing fragments." << tcu::TestLog::EndMessage;
1810 for (int y = 0; y < resultImage.getHeight(); ++y)
1811 for (int x = 0; x < resultImage.getWidth(); ++x)
1813 const tcu::RGBA color = resultImage.getPixel(x, y);
1815 // black? (background)
1816 if (color.getRed() <= thresholdRed ||
1817 color.getGreen() <= thresholdGreen ||
1818 color.getBlue() <= thresholdBlue)
1819 missingFragments = true;
1823 if (!missingFragments)
1824 m_context.getTestContext().getLog() << tcu::TestLog::Message << "No missing fragments detected." << tcu::TestLog::EndMessage;
1827 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Missing fragments detected, image is not valid." << tcu::TestLog::EndMessage;
1829 m_allIterationsPassed = false;
1833 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result of rendering", "Result of rendering")
1834 << tcu::TestLog::Image("Result", "Result", resultImage)
1835 << tcu::TestLog::EndImageSet;
1838 if (++m_iteration == m_iterationCount)
1840 if (m_allIterationsPassed)
1841 return tcu::TestStatus::pass("Pass");
1843 return tcu::TestStatus::fail("Found invalid pixels");
1846 return tcu::TestStatus::incomplete();
1849 int FillRuleTestInstance::getRenderSize (FillRuleCaseType type) const
1851 if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
1852 return DEFAULT_RENDER_SIZE / 4;
1854 return DEFAULT_RENDER_SIZE;
1857 int FillRuleTestInstance::getNumIterations (FillRuleCaseType type) const
1859 if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
1865 void FillRuleTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const
1869 case FILLRULECASE_BASIC:
1870 case FILLRULECASE_REVERSED:
1871 case FILLRULECASE_PROJECTED:
1873 const int numRows = 4;
1874 const int numColumns = 4;
1875 const float quadSide = 0.15f;
1876 de::Random rnd (0xabcd);
1878 outData.resize(6 * numRows * numColumns);
1880 for (int col = 0; col < numColumns; ++col)
1881 for (int row = 0; row < numRows; ++row)
1883 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);
1884 const float rotation = (float)(iteration * numColumns * numRows + col * numRows + row) / (float)(m_iterationCount * numColumns * numRows) * DE_PI / 2.0f;
1885 const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
1886 const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x());
1887 const tcu::Vec2 quad[4] =
1889 center + sideH + sideV,
1890 center + sideH - sideV,
1891 center - sideH - sideV,
1892 center - sideH + sideV,
1895 if (m_caseType == FILLRULECASE_BASIC)
1897 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1898 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1899 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1900 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1901 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1902 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1904 else if (m_caseType == FILLRULECASE_REVERSED)
1906 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1907 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1908 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1909 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1910 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1911 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1913 else if (m_caseType == FILLRULECASE_PROJECTED)
1915 const float w0 = rnd.getFloat(0.1f, 4.0f);
1916 const float w1 = rnd.getFloat(0.1f, 4.0f);
1917 const float w2 = rnd.getFloat(0.1f, 4.0f);
1918 const float w3 = rnd.getFloat(0.1f, 4.0f);
1920 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
1921 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x() * w1, quad[1].y() * w1, 0.0f, w1);
1922 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
1923 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
1924 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
1925 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x() * w3, quad[3].y() * w3, 0.0f, w3);
1928 DE_ASSERT(DE_FALSE);
1934 case FILLRULECASE_CLIPPED_PARTIAL:
1935 case FILLRULECASE_CLIPPED_FULL:
1937 const float quadSide = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (1.0f) : (2.0f);
1938 const tcu::Vec2 center = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (tcu::Vec2(0.5f, 0.5f)) : (tcu::Vec2(0.0f, 0.0f));
1939 const float rotation = (float)(iteration) / (float)(m_iterationCount - 1) * DE_PI / 2.0f;
1940 const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
1941 const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x());
1942 const tcu::Vec2 quad[4] =
1944 center + sideH + sideV,
1945 center + sideH - sideV,
1946 center - sideH - sideV,
1947 center - sideH + sideV,
1951 outData[0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1952 outData[1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1953 outData[2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1954 outData[3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1955 outData[4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1956 outData[5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1961 DE_ASSERT(DE_FALSE);
1965 const VkPipelineColorBlendStateCreateInfo* FillRuleTestInstance::getColorBlendStateCreateInfo (void) const
1967 static const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1969 true, // VkBool32 blendEnable;
1970 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
1971 VK_BLEND_FACTOR_ONE, // VkBlend destBlendColor;
1972 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
1973 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
1974 VK_BLEND_FACTOR_ONE, // VkBlend destBlendAlpha;
1975 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
1976 (VK_COLOR_COMPONENT_R_BIT |
1977 VK_COLOR_COMPONENT_G_BIT |
1978 VK_COLOR_COMPONENT_B_BIT |
1979 VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask;
1982 static const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1984 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1985 DE_NULL, // const void* pNext;
1986 0, // VkPipelineColorBlendStateCreateFlags flags;
1987 false, // VkBool32 logicOpEnable;
1988 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1989 1u, // deUint32 attachmentCount;
1990 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1991 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
1994 return &colorBlendStateParams;
1998 class FillRuleTestCase : public BaseRenderingTestCase
2001 FillRuleTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, FillRuleTestInstance::FillRuleCaseType type, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2002 : BaseRenderingTestCase (context, name, description, sampleCount)
2006 virtual TestInstance* createInstance (Context& context) const
2008 return new FillRuleTestInstance(context, m_type, m_sampleCount);
2011 const FillRuleTestInstance::FillRuleCaseType m_type;
2014 class CullingTestInstance : public BaseRenderingTestInstance
2017 CullingTestInstance (Context& context, VkCullModeFlags cullMode, VkPrimitiveTopology primitiveTopology, VkFrontFace frontFace, VkPolygonMode polygonMode)
2018 : BaseRenderingTestInstance (context, VK_SAMPLE_COUNT_1_BIT, DEFAULT_RENDER_SIZE)
2019 , m_cullMode (cullMode)
2020 , m_primitiveTopology (primitiveTopology)
2021 , m_frontFace (frontFace)
2022 , m_polygonMode (polygonMode)
2023 , m_multisampling (true)
2026 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
2028 tcu::TestStatus iterate (void);
2031 void generateVertices (std::vector<tcu::Vec4>& outData) const;
2032 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const;
2033 void extractLines (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, std::vector<LineSceneSpec::SceneLine>& outLines) const;
2034 void extractPoints (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, std::vector<PointSceneSpec::ScenePoint>& outPoints) const;
2035 bool triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const;
2037 const VkCullModeFlags m_cullMode;
2038 const VkPrimitiveTopology m_primitiveTopology;
2039 const VkFrontFace m_frontFace;
2040 const VkPolygonMode m_polygonMode;
2041 const bool m_multisampling;
2045 tcu::TestStatus CullingTestInstance::iterate (void)
2047 DE_ASSERT(m_polygonMode < VK_POLYGON_MODE_LAST);
2049 tcu::Surface resultImage (m_renderSize, m_renderSize);
2050 std::vector<tcu::Vec4> drawBuffer;
2051 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
2052 std::vector<PointSceneSpec::ScenePoint> points;
2053 std::vector<LineSceneSpec::SceneLine> lines;
2055 const InstanceInterface& vk = m_context.getInstanceInterface();
2056 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
2057 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(vk, physicalDevice);
2059 if (!(deviceFeatures.fillModeNonSolid) && (m_polygonMode == VK_POLYGON_MODE_LINE || m_polygonMode == VK_POLYGON_MODE_POINT))
2060 TCU_THROW(NotSupportedError, "Wireframe fill modes are not supported");
2063 generateVertices(drawBuffer);
2064 extractTriangles(triangles, drawBuffer);
2066 if (m_polygonMode == VK_POLYGON_MODE_LINE)
2067 extractLines(triangles ,lines);
2068 else if (m_polygonMode == VK_POLYGON_MODE_POINT)
2069 extractPoints(triangles, points);
2073 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Setting front face to " << m_frontFace << tcu::TestLog::EndMessage;
2074 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Setting cull face to " << m_cullMode << tcu::TestLog::EndMessage;
2075 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Drawing test pattern (" << m_primitiveTopology << ")" << tcu::TestLog::EndMessage;
2077 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
2082 RasterizationArguments args;
2083 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
2084 bool isCompareOk = false;
2086 args.numSamples = m_multisampling ? 1 : 0;
2087 args.subpixelBits = m_subpixelBits;
2088 args.redBits = colorBits[0];
2089 args.greenBits = colorBits[1];
2090 args.blueBits = colorBits[2];
2092 switch (m_polygonMode)
2094 case VK_POLYGON_MODE_LINE:
2096 LineSceneSpec scene;
2097 scene.lineWidth = 0;
2098 scene.lines.swap(lines);
2099 isCompareOk = verifyLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
2102 case VK_POLYGON_MODE_POINT:
2104 PointSceneSpec scene;
2105 scene.points.swap(points);
2106 isCompareOk = verifyPointGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
2111 TriangleSceneSpec scene;
2112 scene.triangles.swap(triangles);
2113 isCompareOk = verifyTriangleGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), tcu::VERIFICATIONMODE_WEAK);
2119 return tcu::TestStatus::pass("Pass");
2121 return tcu::TestStatus::fail("Incorrect rendering");
2125 void CullingTestInstance::generateVertices (std::vector<tcu::Vec4>& outData) const
2127 de::Random rnd(543210);
2130 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
2132 outData[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
2133 outData[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
2134 outData[vtxNdx].z() = 0.0f;
2135 outData[vtxNdx].w() = 1.0f;
2139 void CullingTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const
2141 const bool cullDirection = (m_cullMode == VK_CULL_MODE_FRONT_BIT) ^ (m_frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE);
2144 if (m_cullMode == VK_CULL_MODE_FRONT_AND_BACK)
2147 switch (m_primitiveTopology)
2149 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
2151 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
2153 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
2154 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
2155 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
2157 if (triangleOrder(v0, v1, v2) != cullDirection)
2159 TriangleSceneSpec::SceneTriangle tri;
2160 tri.positions[0] = v0; tri.sharedEdge[0] = false;
2161 tri.positions[1] = v1; tri.sharedEdge[1] = false;
2162 tri.positions[2] = v2; tri.sharedEdge[2] = false;
2164 outTriangles.push_back(tri);
2170 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
2172 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
2174 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
2175 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
2176 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
2178 if (triangleOrder(v0, v1, v2) != (cullDirection ^ (vtxNdx % 2 != 0)))
2180 TriangleSceneSpec::SceneTriangle tri;
2181 tri.positions[0] = v0; tri.sharedEdge[0] = false;
2182 tri.positions[1] = v1; tri.sharedEdge[1] = false;
2183 tri.positions[2] = v2; tri.sharedEdge[2] = false;
2185 outTriangles.push_back(tri);
2191 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
2193 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2195 const tcu::Vec4& v0 = vertices[0];
2196 const tcu::Vec4& v1 = vertices[vtxNdx + 0];
2197 const tcu::Vec4& v2 = vertices[vtxNdx + 1];
2199 if (triangleOrder(v0, v1, v2) != cullDirection)
2201 TriangleSceneSpec::SceneTriangle tri;
2202 tri.positions[0] = v0; tri.sharedEdge[0] = false;
2203 tri.positions[1] = v1; tri.sharedEdge[1] = false;
2204 tri.positions[2] = v2; tri.sharedEdge[2] = false;
2206 outTriangles.push_back(tri);
2217 void CullingTestInstance::extractLines (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles,
2218 std::vector<LineSceneSpec::SceneLine>& outLines) const
2220 for (int triNdx = 0; triNdx < (int)outTriangles.size(); ++triNdx)
2222 for (int vrtxNdx = 0; vrtxNdx < 2; ++vrtxNdx)
2224 LineSceneSpec::SceneLine line;
2225 line.positions[0] = outTriangles.at(triNdx).positions[vrtxNdx];
2226 line.positions[1] = outTriangles.at(triNdx).positions[vrtxNdx + 1];
2228 outLines.push_back(line);
2230 LineSceneSpec::SceneLine line;
2231 line.positions[0] = outTriangles.at(triNdx).positions[2];
2232 line.positions[1] = outTriangles.at(triNdx).positions[0];
2233 outLines.push_back(line);
2237 void CullingTestInstance::extractPoints (std::vector<TriangleSceneSpec::SceneTriangle> &outTriangles,
2238 std::vector<PointSceneSpec::ScenePoint> &outPoints) const
2240 for (int triNdx = 0; triNdx < (int)outTriangles.size(); ++triNdx)
2242 for (int vrtxNdx = 0; vrtxNdx < 3; ++vrtxNdx)
2244 PointSceneSpec::ScenePoint point;
2245 point.position = outTriangles.at(triNdx).positions[vrtxNdx];
2246 point.pointSize = 1.0f;
2248 outPoints.push_back(point);
2253 bool CullingTestInstance::triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const
2255 const tcu::Vec2 s0 = v0.swizzle(0, 1) / v0.w();
2256 const tcu::Vec2 s1 = v1.swizzle(0, 1) / v1.w();
2257 const tcu::Vec2 s2 = v2.swizzle(0, 1) / v2.w();
2260 return ((s1.x() - s0.x()) * (s2.y() - s0.y()) - (s2.x() - s0.x()) * (s1.y() - s0.y())) > 0;
2264 const VkPipelineRasterizationStateCreateInfo* CullingTestInstance::getRasterizationStateCreateInfo (void) const
2266 static VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
2268 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
2269 DE_NULL, // const void* pNext;
2270 0, // VkPipelineRasterizationStateCreateFlags flags;
2271 false, // VkBool32 depthClipEnable;
2272 false, // VkBool32 rasterizerDiscardEnable;
2273 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
2274 VK_CULL_MODE_NONE, // VkCullMode cullMode;
2275 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
2276 VK_FALSE, // VkBool32 depthBiasEnable;
2277 0.0f, // float depthBias;
2278 0.0f, // float depthBiasClamp;
2279 0.0f, // float slopeScaledDepthBias;
2280 getLineWidth(), // float lineWidth;
2283 rasterizationStateCreateInfo.lineWidth = getLineWidth();
2284 rasterizationStateCreateInfo.cullMode = m_cullMode;
2285 rasterizationStateCreateInfo.frontFace = m_frontFace;
2286 rasterizationStateCreateInfo.polygonMode = m_polygonMode;
2288 return &rasterizationStateCreateInfo;
2291 class CullingTestCase : public BaseRenderingTestCase
2294 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)
2295 : BaseRenderingTestCase (context, name, description, sampleCount)
2296 , m_cullMode (cullMode)
2297 , m_primitiveTopology (primitiveTopology)
2298 , m_frontFace (frontFace)
2299 , m_polygonMode (polygonMode)
2302 virtual TestInstance* createInstance (Context& context) const
2304 return new CullingTestInstance(context, m_cullMode, m_primitiveTopology, m_frontFace, m_polygonMode);
2307 const VkCullModeFlags m_cullMode;
2308 const VkPrimitiveTopology m_primitiveTopology;
2309 const VkFrontFace m_frontFace;
2310 const VkPolygonMode m_polygonMode;
2313 class TriangleInterpolationTestInstance : public BaseRenderingTestInstance
2317 TriangleInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount)
2318 : BaseRenderingTestInstance (context, sampleCount, DEFAULT_RENDER_SIZE)
2319 , m_primitiveTopology (primitiveTopology)
2320 , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
2321 , m_iterationCount (3)
2323 , m_allIterationsPassed (true)
2324 , m_flatshade ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2327 tcu::TestStatus iterate (void);
2331 void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
2332 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
2335 VkPrimitiveTopology m_primitiveTopology;
2336 const bool m_projective;
2337 const int m_iterationCount;
2339 bool m_allIterationsPassed;
2340 const deBool m_flatshade;
2343 tcu::TestStatus TriangleInterpolationTestInstance::iterate (void)
2345 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
2346 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
2347 tcu::Surface resultImage (m_renderSize, m_renderSize);
2348 std::vector<tcu::Vec4> drawBuffer;
2349 std::vector<tcu::Vec4> colorBuffer;
2350 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
2353 generateVertices(m_iteration, drawBuffer, colorBuffer);
2354 extractTriangles(triangles, drawBuffer, colorBuffer);
2358 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
2359 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
2360 m_context.getTestContext().getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
2364 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitiveTopology);
2368 RasterizationArguments args;
2369 TriangleSceneSpec scene;
2370 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
2372 args.numSamples = m_multisampling ? 1 : 0;
2373 args.subpixelBits = m_subpixelBits;
2374 args.redBits = colorBits[0];
2375 args.greenBits = colorBits[1];
2376 args.blueBits = colorBits[2];
2378 scene.triangles.swap(triangles);
2380 if (!verifyTriangleGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog()))
2381 m_allIterationsPassed = false;
2385 if (++m_iteration == m_iterationCount)
2387 if (m_allIterationsPassed)
2388 return tcu::TestStatus::pass("Pass");
2390 return tcu::TestStatus::fail("Found invalid pixel values");
2393 return tcu::TestStatus::incomplete();
2396 void TriangleInterpolationTestInstance::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
2398 // use only red, green and blue
2399 const tcu::Vec4 colors[] =
2401 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
2402 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
2403 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
2406 de::Random rnd(123 + iteration * 1000 + (int)m_primitiveTopology);
2408 outVertices.resize(6);
2409 outColors.resize(6);
2411 for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
2413 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
2414 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
2415 outVertices[vtxNdx].z() = 0.0f;
2418 outVertices[vtxNdx].w() = 1.0f;
2421 const float w = rnd.getFloat(0.2f, 4.0f);
2423 outVertices[vtxNdx].x() *= w;
2424 outVertices[vtxNdx].y() *= w;
2425 outVertices[vtxNdx].z() *= w;
2426 outVertices[vtxNdx].w() = w;
2429 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
2433 void TriangleInterpolationTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
2435 switch (m_primitiveTopology)
2437 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
2439 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
2441 TriangleSceneSpec::SceneTriangle tri;
2442 tri.positions[0] = vertices[vtxNdx + 0];
2443 tri.positions[1] = vertices[vtxNdx + 1];
2444 tri.positions[2] = vertices[vtxNdx + 2];
2445 tri.sharedEdge[0] = false;
2446 tri.sharedEdge[1] = false;
2447 tri.sharedEdge[2] = false;
2451 tri.colors[0] = colors[vtxNdx];
2452 tri.colors[1] = colors[vtxNdx];
2453 tri.colors[2] = colors[vtxNdx];
2457 tri.colors[0] = colors[vtxNdx + 0];
2458 tri.colors[1] = colors[vtxNdx + 1];
2459 tri.colors[2] = colors[vtxNdx + 2];
2462 outTriangles.push_back(tri);
2467 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
2469 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
2471 TriangleSceneSpec::SceneTriangle tri;
2472 tri.positions[0] = vertices[vtxNdx + 0];
2473 tri.positions[1] = vertices[vtxNdx + 1];
2474 tri.positions[2] = vertices[vtxNdx + 2];
2475 tri.sharedEdge[0] = false;
2476 tri.sharedEdge[1] = false;
2477 tri.sharedEdge[2] = false;
2481 tri.colors[0] = colors[vtxNdx];
2482 tri.colors[1] = colors[vtxNdx];
2483 tri.colors[2] = colors[vtxNdx];
2487 tri.colors[0] = colors[vtxNdx + 0];
2488 tri.colors[1] = colors[vtxNdx + 1];
2489 tri.colors[2] = colors[vtxNdx + 2];
2492 outTriangles.push_back(tri);
2497 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
2499 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2501 TriangleSceneSpec::SceneTriangle tri;
2502 tri.positions[0] = vertices[0];
2503 tri.positions[1] = vertices[vtxNdx + 0];
2504 tri.positions[2] = vertices[vtxNdx + 1];
2505 tri.sharedEdge[0] = false;
2506 tri.sharedEdge[1] = false;
2507 tri.sharedEdge[2] = false;
2511 tri.colors[0] = colors[vtxNdx];
2512 tri.colors[1] = colors[vtxNdx];
2513 tri.colors[2] = colors[vtxNdx];
2517 tri.colors[0] = colors[0];
2518 tri.colors[1] = colors[vtxNdx + 0];
2519 tri.colors[2] = colors[vtxNdx + 1];
2522 outTriangles.push_back(tri);
2532 class TriangleInterpolationTestCase : public BaseRenderingTestCase
2535 TriangleInterpolationTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2536 : BaseRenderingTestCase (context, name, description, sampleCount, (flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2537 , m_primitiveTopology (primitiveTopology)
2541 virtual TestInstance* createInstance (Context& context) const
2543 return new TriangleInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_sampleCount);
2546 const VkPrimitiveTopology m_primitiveTopology;
2550 class LineInterpolationTestInstance : public BaseRenderingTestInstance
2553 LineInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount);
2555 virtual tcu::TestStatus iterate (void);
2558 void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
2559 void extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
2560 virtual float getLineWidth (void) const;
2562 VkPrimitiveTopology m_primitiveTopology;
2563 const bool m_projective;
2564 const int m_iterationCount;
2565 const PrimitiveWideness m_primitiveWideness;
2568 bool m_allIterationsPassed;
2569 float m_maxLineWidth;
2570 std::vector<float> m_lineWidths;
2574 LineInterpolationTestInstance::LineInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
2575 : BaseRenderingTestInstance (context, sampleCount)
2576 , m_primitiveTopology (primitiveTopology)
2577 , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
2578 , m_iterationCount (3)
2579 , m_primitiveWideness (wideness)
2581 , m_allIterationsPassed (true)
2582 , m_maxLineWidth (1.0f)
2583 , m_flatshade ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2585 DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
2587 if (!context.getDeviceProperties().limits.strictLines)
2588 TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
2590 // create line widths
2591 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
2593 m_lineWidths.resize(m_iterationCount, 1.0f);
2595 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
2597 if (!m_context.getDeviceFeatures().wideLines)
2598 TCU_THROW(NotSupportedError , "wide line support required");
2600 const float* range = context.getDeviceProperties().limits.lineWidthRange;
2602 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
2604 // no wide line support
2605 if (range[1] <= 1.0f)
2606 throw tcu::NotSupportedError("wide line support required");
2608 // set hand picked sizes
2609 m_lineWidths.push_back(5.0f);
2610 m_lineWidths.push_back(10.0f);
2611 m_lineWidths.push_back(range[1]);
2612 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
2614 m_maxLineWidth = range[1];
2620 tcu::TestStatus LineInterpolationTestInstance::iterate (void)
2622 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
2623 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
2624 const float lineWidth = getLineWidth();
2625 tcu::Surface resultImage (m_renderSize, m_renderSize);
2626 std::vector<tcu::Vec4> drawBuffer;
2627 std::vector<tcu::Vec4> colorBuffer;
2628 std::vector<LineSceneSpec::SceneLine> lines;
2631 if (lineWidth <= m_maxLineWidth)
2634 generateVertices(m_iteration, drawBuffer, colorBuffer);
2635 extractLines(lines, drawBuffer, colorBuffer);
2639 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
2640 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
2641 m_context.getTestContext().getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
2645 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitiveTopology);
2649 RasterizationArguments args;
2650 LineSceneSpec scene;
2652 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
2654 args.numSamples = m_multisampling ? 1 : 0;
2655 args.subpixelBits = m_subpixelBits;
2656 args.redBits = colorBits[0];
2657 args.greenBits = colorBits[1];
2658 args.blueBits = colorBits[2];
2660 scene.lines.swap(lines);
2661 scene.lineWidth = getLineWidth();
2663 if (!verifyTriangulatedLineGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog()))
2664 m_allIterationsPassed = false;
2668 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
2671 if (++m_iteration == m_iterationCount)
2673 if (m_allIterationsPassed)
2674 return tcu::TestStatus::pass("Pass");
2676 return tcu::TestStatus::fail("Incorrect rasterization");
2679 return tcu::TestStatus::incomplete();
2682 void LineInterpolationTestInstance::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
2684 // use only red, green and blue
2685 const tcu::Vec4 colors[] =
2687 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
2688 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
2689 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
2692 de::Random rnd(123 + iteration * 1000 + (int)m_primitiveTopology);
2694 outVertices.resize(6);
2695 outColors.resize(6);
2697 for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
2699 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
2700 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
2701 outVertices[vtxNdx].z() = 0.0f;
2704 outVertices[vtxNdx].w() = 1.0f;
2707 const float w = rnd.getFloat(0.2f, 4.0f);
2709 outVertices[vtxNdx].x() *= w;
2710 outVertices[vtxNdx].y() *= w;
2711 outVertices[vtxNdx].z() *= w;
2712 outVertices[vtxNdx].w() = w;
2715 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
2719 void LineInterpolationTestInstance::extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
2721 switch (m_primitiveTopology)
2723 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
2725 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; vtxNdx += 2)
2727 LineSceneSpec::SceneLine line;
2728 line.positions[0] = vertices[vtxNdx + 0];
2729 line.positions[1] = vertices[vtxNdx + 1];
2733 line.colors[0] = colors[vtxNdx];
2734 line.colors[1] = colors[vtxNdx];
2738 line.colors[0] = colors[vtxNdx + 0];
2739 line.colors[1] = colors[vtxNdx + 1];
2742 outLines.push_back(line);
2747 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
2749 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2751 LineSceneSpec::SceneLine line;
2752 line.positions[0] = vertices[vtxNdx + 0];
2753 line.positions[1] = vertices[vtxNdx + 1];
2757 line.colors[0] = colors[vtxNdx];
2758 line.colors[1] = colors[vtxNdx];
2762 line.colors[0] = colors[vtxNdx + 0];
2763 line.colors[1] = colors[vtxNdx + 1];
2766 outLines.push_back(line);
2776 float LineInterpolationTestInstance::getLineWidth (void) const
2778 return m_lineWidths[m_iteration];
2781 class LineInterpolationTestCase : public BaseRenderingTestCase
2784 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)
2785 : BaseRenderingTestCase (context, name, description, sampleCount, (flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2786 , m_primitiveTopology (primitiveTopology)
2788 , m_wideness (wideness)
2791 virtual TestInstance* createInstance (Context& context) const
2793 return new LineInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_wideness, m_sampleCount);
2796 const VkPrimitiveTopology m_primitiveTopology;
2798 const PrimitiveWideness m_wideness;
2801 void createRasterizationTests (tcu::TestCaseGroup* rasterizationTests)
2803 tcu::TestContext& testCtx = rasterizationTests->getTestContext();
2807 tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(testCtx, "primitives", "Primitive rasterization");
2809 rasterizationTests->addChild(primitives);
2811 primitives->addChild(new BaseTestCase<TrianglesTestInstance> (testCtx, "triangles", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result"));
2812 primitives->addChild(new BaseTestCase<TriangleStripTestInstance> (testCtx, "triangle_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, verify rasterization result"));
2813 primitives->addChild(new BaseTestCase<TriangleFanTestInstance> (testCtx, "triangle_fan", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, verify rasterization result"));
2814 primitives->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW));
2815 primitives->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "line_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result", PRIMITIVEWIDENESS_NARROW));
2816 primitives->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
2817 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));
2818 primitives->addChild(new WidenessTestCase<PointTestInstance> (testCtx, "points", "Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
2823 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(testCtx, "fill_rules", "Primitive fill rules");
2825 rasterizationTests->addChild(fillRules);
2827 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_BASIC));
2828 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad_reverse", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_REVERSED));
2829 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_full", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_FULL));
2830 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_partly", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_PARTIAL));
2831 fillRules->addChild(new FillRuleTestCase(testCtx, "projected", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_PROJECTED));
2836 static const struct CullMode
2838 VkCullModeFlags mode;
2842 { VK_CULL_MODE_FRONT_BIT, "front_" },
2843 { VK_CULL_MODE_BACK_BIT, "back_" },
2844 { VK_CULL_MODE_FRONT_AND_BACK, "both_" },
2846 static const struct PrimitiveType
2848 VkPrimitiveTopology type;
2850 } primitiveTypes[] =
2852 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangles" },
2853 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, "triangle_strip" },
2854 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, "triangle_fan" },
2856 static const struct FrontFaceOrder
2859 const char* postfix;
2862 { VK_FRONT_FACE_COUNTER_CLOCKWISE, "" },
2863 { VK_FRONT_FACE_CLOCKWISE, "_reverse" },
2866 static const struct PolygonMode
2872 { VK_POLYGON_MODE_FILL, "" },
2873 { VK_POLYGON_MODE_LINE, "_line" },
2874 { VK_POLYGON_MODE_POINT, "_point" }
2877 tcu::TestCaseGroup* const culling = new tcu::TestCaseGroup(testCtx, "culling", "Culling");
2879 rasterizationTests->addChild(culling);
2881 for (int cullModeNdx = 0; cullModeNdx < DE_LENGTH_OF_ARRAY(cullModes); ++cullModeNdx)
2882 for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveNdx)
2883 for (int frontOrderNdx = 0; frontOrderNdx < DE_LENGTH_OF_ARRAY(frontOrders); ++frontOrderNdx)
2884 for (int polygonModeNdx = 0; polygonModeNdx < DE_LENGTH_OF_ARRAY(polygonModes); ++polygonModeNdx)
2886 if (!(cullModes[cullModeNdx].mode == VK_CULL_MODE_FRONT_AND_BACK && polygonModes[polygonModeNdx].mode != VK_POLYGON_MODE_FILL))
2888 const std::string name = std::string(cullModes[cullModeNdx].prefix) + primitiveTypes[primitiveNdx].name + frontOrders[frontOrderNdx].postfix + polygonModes[polygonModeNdx].name;
2889 culling->addChild(new CullingTestCase(testCtx, name, "Test primitive culling.", cullModes[cullModeNdx].mode, primitiveTypes[primitiveNdx].type, frontOrders[frontOrderNdx].mode, polygonModes[polygonModeNdx].mode));
2896 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(testCtx, "interpolation", "Test interpolation");
2898 rasterizationTests->addChild(interpolation);
2902 tcu::TestCaseGroup* const basic = new tcu::TestCaseGroup(testCtx, "basic", "Non-projective interpolation");
2904 interpolation->addChild(basic);
2906 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_NONE));
2907 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_NONE));
2908 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_NONE));
2909 basic->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW));
2910 basic->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW));
2911 basic->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE));
2912 basic->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE));
2917 tcu::TestCaseGroup* const projected = new tcu::TestCaseGroup(testCtx, "projected", "Projective interpolation");
2919 interpolation->addChild(projected);
2921 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_PROJECTED));
2922 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_PROJECTED));
2923 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_PROJECTED));
2924 projected->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW));
2925 projected->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW));
2926 projected->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE));
2927 projected->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE));
2933 tcu::TestCaseGroup* const flatshading = new tcu::TestCaseGroup(testCtx, "flatshading", "Test flatshading");
2935 rasterizationTests->addChild(flatshading);
2937 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_FLATSHADE));
2938 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_FLATSHADE));
2939 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_FLATSHADE));
2940 flatshading->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW));
2941 flatshading->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW));
2942 flatshading->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE));
2943 flatshading->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE));
2946 const VkSampleCountFlagBits samples[] =
2948 VK_SAMPLE_COUNT_2_BIT,
2949 VK_SAMPLE_COUNT_4_BIT,
2950 VK_SAMPLE_COUNT_8_BIT,
2951 VK_SAMPLE_COUNT_16_BIT,
2952 VK_SAMPLE_COUNT_32_BIT,
2953 VK_SAMPLE_COUNT_64_BIT
2956 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2958 std::ostringstream caseName;
2960 caseName << "_multisample_" << (2 << samplesNdx) << "_bit";
2964 tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(testCtx, ("primitives" + caseName.str()).c_str(), "Primitive rasterization");
2966 rasterizationTests->addChild(primitives);
2968 primitives->addChild(new BaseTestCase<TrianglesTestInstance> (testCtx, "triangles", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result", samples[samplesNdx]));
2969 primitives->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, samples[samplesNdx]));
2970 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]));
2971 primitives->addChild(new WidenessTestCase<PointTestInstance> (testCtx, "points", "Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result", PRIMITIVEWIDENESS_WIDE, samples[samplesNdx]));
2976 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(testCtx, ("fill_rules" + caseName.str()).c_str(), "Primitive fill rules");
2978 rasterizationTests->addChild(fillRules);
2980 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_BASIC, samples[samplesNdx]));
2981 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad_reverse", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_REVERSED, samples[samplesNdx]));
2982 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_full", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_FULL, samples[samplesNdx]));
2983 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_partly", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_PARTIAL, samples[samplesNdx]));
2984 fillRules->addChild(new FillRuleTestCase(testCtx, "projected", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_PROJECTED, samples[samplesNdx]));
2989 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(testCtx, ("interpolation" + caseName.str()).c_str(), "Test interpolation");
2991 rasterizationTests->addChild(interpolation);
2993 interpolation->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_NONE, samples[samplesNdx]));
2994 interpolation->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, samples[samplesNdx]));
2995 interpolation->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, samples[samplesNdx]));
3002 tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
3004 return createTestGroup(testCtx, "rasterization", "Rasterization Tests", createRasterizationTests);