1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2014 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Functional rasterization tests.
24 *//*--------------------------------------------------------------------*/
26 #include "vktRasterizationTests.hpp"
27 #include "tcuRasterizationVerifier.hpp"
28 #include "tcuSurface.hpp"
29 #include "tcuRenderTarget.hpp"
30 #include "tcuVectorUtil.hpp"
31 #include "tcuStringTemplate.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "tcuResultCollector.hpp"
34 #include "vkImageUtil.hpp"
35 #include "deStringUtil.hpp"
36 #include "deRandom.hpp"
37 #include "vktTestCase.hpp"
38 #include "vktTestCaseUtil.hpp"
39 #include "vktTestGroupUtil.hpp"
40 #include "vkPrograms.hpp"
41 #include "vkMemUtil.hpp"
42 #include "vkRefUtil.hpp"
43 #include "vkQueryUtil.hpp"
44 #include "vkBuilderUtil.hpp"
45 #include "vkTypeUtil.hpp"
46 #include "vkCmdUtil.hpp"
47 #include "vkObjUtil.hpp"
55 namespace rasterization
60 using tcu::RasterizationArguments;
61 using tcu::TriangleSceneSpec;
62 using tcu::PointSceneSpec;
63 using tcu::LineSceneSpec;
64 using tcu::LineInterpolationMethod;
66 static const char* const s_shaderVertexTemplate = "#version 310 es\n"
67 "layout(location = 0) in highp vec4 a_position;\n"
68 "layout(location = 1) in highp vec4 a_color;\n"
69 "layout(location = 0) ${INTERPOLATION}out highp vec4 v_color;\n"
70 "layout (set=0, binding=0) uniform PointSize {\n"
71 " highp float u_pointSize;\n"
75 " gl_Position = a_position;\n"
76 " gl_PointSize = u_pointSize;\n"
77 " v_color = a_color;\n"
80 static const char* const s_shaderFragmentTemplate = "#version 310 es\n"
81 "layout(location = 0) out highp vec4 fragColor;\n"
82 "layout(location = 0) ${INTERPOLATION}in highp vec4 v_color;\n"
85 " fragColor = v_color;\n"
87 enum InterpolationCaseFlags
89 INTERPOLATIONFLAGS_NONE = 0,
90 INTERPOLATIONFLAGS_PROJECTED = (1 << 1),
91 INTERPOLATIONFLAGS_FLATSHADE = (1 << 2),
94 enum PrimitiveWideness
96 PRIMITIVEWIDENESS_NARROW = 0,
97 PRIMITIVEWIDENESS_WIDE,
99 PRIMITIVEWIDENESS_LAST
102 class BaseRenderingTestCase : public TestCase
105 BaseRenderingTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deBool flatshade = DE_FALSE);
106 virtual ~BaseRenderingTestCase (void);
108 virtual void initPrograms (vk::SourceCollections& programCollection) const;
111 const VkSampleCountFlagBits m_sampleCount;
112 const deBool m_flatshade;
115 BaseRenderingTestCase::BaseRenderingTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount, deBool flatshade)
116 : TestCase(context, name, description)
117 , m_sampleCount (sampleCount)
118 , m_flatshade (flatshade)
122 void BaseRenderingTestCase::initPrograms (vk::SourceCollections& programCollection) const
124 tcu::StringTemplate vertexSource (s_shaderVertexTemplate);
125 tcu::StringTemplate fragmentSource (s_shaderFragmentTemplate);
126 std::map<std::string, std::string> params;
128 params["INTERPOLATION"] = (m_flatshade) ? ("flat ") : ("");
130 programCollection.glslSources.add("vertext_shader") << glu::VertexSource(vertexSource.specialize(params));
131 programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fragmentSource.specialize(params));
134 BaseRenderingTestCase::~BaseRenderingTestCase (void)
138 class BaseRenderingTestInstance : public TestInstance
142 DEFAULT_RENDER_SIZE = 256
145 BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deUint32 renderSize = DEFAULT_RENDER_SIZE);
146 ~BaseRenderingTestInstance (void);
149 void addImageTransitionBarrier (VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const;
150 void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology);
151 void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, const std::vector<tcu::Vec4>& coloDrata, VkPrimitiveTopology primitiveTopology);
152 virtual float getLineWidth (void) const;
153 virtual float getPointSize (void) const;
156 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
159 const VkPipelineColorBlendStateCreateInfo* getColorBlendStateCreateInfo (void) const;
161 const tcu::TextureFormat& getTextureFormat (void) const;
163 const deUint32 m_renderSize;
164 const VkSampleCountFlagBits m_sampleCount;
165 const deUint32 m_subpixelBits;
166 const deBool m_multisampling;
168 const VkFormat m_imageFormat;
169 const tcu::TextureFormat m_textureFormat;
170 Move<VkCommandPool> m_commandPool;
172 Move<VkImage> m_image;
173 de::MovePtr<Allocation> m_imageMemory;
174 Move<VkImageView> m_imageView;
176 Move<VkImage> m_resolvedImage;
177 de::MovePtr<Allocation> m_resolvedImageMemory;
178 Move<VkImageView> m_resolvedImageView;
180 Move<VkRenderPass> m_renderPass;
181 Move<VkFramebuffer> m_frameBuffer;
183 Move<VkDescriptorPool> m_descriptorPool;
184 Move<VkDescriptorSet> m_descriptorSet;
185 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
187 Move<VkBuffer> m_uniformBuffer;
188 de::MovePtr<Allocation> m_uniformBufferMemory;
189 const VkDeviceSize m_uniformBufferSize;
191 Move<VkPipelineLayout> m_pipelineLayout;
193 Move<VkShaderModule> m_vertexShaderModule;
194 Move<VkShaderModule> m_fragmentShaderModule;
196 Move<VkBuffer> m_resultBuffer;
197 de::MovePtr<Allocation> m_resultBufferMemory;
198 const VkDeviceSize m_resultBufferSize;
201 BaseRenderingTestInstance::BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount, deUint32 renderSize)
202 : TestInstance (context)
203 , m_renderSize (renderSize)
204 , m_sampleCount (sampleCount)
205 , m_subpixelBits (context.getDeviceProperties().limits.subPixelPrecisionBits)
206 , m_multisampling (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
207 , m_imageFormat (VK_FORMAT_R8G8B8A8_UNORM)
208 , m_textureFormat (vk::mapVkFormat(m_imageFormat))
209 , m_uniformBufferSize (sizeof(float))
210 , m_resultBufferSize (renderSize * renderSize * m_textureFormat.getPixelSize())
212 const DeviceInterface& vkd = m_context.getDeviceInterface();
213 const VkDevice vkDevice = m_context.getDevice();
214 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
215 Allocator& allocator = m_context.getDefaultAllocator();
216 DescriptorPoolBuilder descriptorPoolBuilder;
217 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
220 m_commandPool = createCommandPool(vkd, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
224 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
225 VkImageFormatProperties properties;
227 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
230 VK_IMAGE_TILING_OPTIMAL,
233 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
235 TCU_THROW(NotSupportedError, "Format not supported");
238 if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
240 TCU_THROW(NotSupportedError, "Format not supported");
243 const VkImageCreateInfo imageCreateInfo =
245 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
246 DE_NULL, // const void* pNext;
247 0u, // VkImageCreateFlags flags;
248 VK_IMAGE_TYPE_2D, // VkImageType imageType;
249 m_imageFormat, // VkFormat format;
250 { m_renderSize, m_renderSize, 1u }, // VkExtent3D extent;
251 1u, // deUint32 mipLevels;
252 1u, // deUint32 arrayLayers;
253 m_sampleCount, // VkSampleCountFlagBits samples;
254 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
255 imageUsage, // VkImageUsageFlags usage;
256 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
257 1u, // deUint32 queueFamilyIndexCount;
258 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
259 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
262 m_image = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
264 m_imageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_image), MemoryRequirement::Any);
265 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_image, m_imageMemory->getMemory(), m_imageMemory->getOffset()));
270 const VkImageViewCreateInfo imageViewCreateInfo =
272 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
273 DE_NULL, // const void* pNext;
274 0u, // VkImageViewCreateFlags flags;
275 *m_image, // VkImage image;
276 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
277 m_imageFormat, // VkFormat format;
278 makeComponentMappingRGBA(), // VkComponentMapping components;
280 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
281 0u, // deUint32 baseMipLevel;
282 1u, // deUint32 mipLevels;
283 0u, // deUint32 baseArrayLayer;
284 1u, // deUint32 arraySize;
285 }, // VkImageSubresourceRange subresourceRange;
288 m_imageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
295 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
296 VkImageFormatProperties properties;
298 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
301 VK_IMAGE_TILING_OPTIMAL,
304 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
306 TCU_THROW(NotSupportedError, "Format not supported");
309 const VkImageCreateInfo imageCreateInfo =
311 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
312 DE_NULL, // const void* pNext;
313 0u, // VkImageCreateFlags flags;
314 VK_IMAGE_TYPE_2D, // VkImageType imageType;
315 m_imageFormat, // VkFormat format;
316 { m_renderSize, m_renderSize, 1u }, // VkExtent3D extent;
317 1u, // deUint32 mipLevels;
318 1u, // deUint32 arrayLayers;
319 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
320 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
321 imageUsage, // VkImageUsageFlags usage;
322 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
323 1u, // deUint32 queueFamilyIndexCount;
324 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
325 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
328 m_resolvedImage = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
329 m_resolvedImageMemory = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_resolvedImage), MemoryRequirement::Any);
330 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_resolvedImage, m_resolvedImageMemory->getMemory(), m_resolvedImageMemory->getOffset()));
333 // Resolved Image View
335 const VkImageViewCreateInfo imageViewCreateInfo =
337 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
338 DE_NULL, // const void* pNext;
339 0u, // VkImageViewCreateFlags flags;
340 *m_resolvedImage, // VkImage image;
341 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
342 m_imageFormat, // VkFormat format;
343 makeComponentMappingRGBA(), // VkComponentMapping components;
345 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
346 0u, // deUint32 baseMipLevel;
347 1u, // deUint32 mipLevels;
348 0u, // deUint32 baseArrayLayer;
349 1u, // deUint32 arraySize;
350 }, // VkImageSubresourceRange subresourceRange;
353 m_resolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
360 const VkImageLayout imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
361 const VkAttachmentDescription attachmentDesc[] =
364 0u, // VkAttachmentDescriptionFlags flags;
365 m_imageFormat, // VkFormat format;
366 m_sampleCount, // VkSampleCountFlagBits samples;
367 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
368 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
369 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
370 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
371 imageLayout, // VkImageLayout initialLayout;
372 imageLayout, // VkImageLayout finalLayout;
375 0u, // VkAttachmentDescriptionFlags flags;
376 m_imageFormat, // VkFormat format;
377 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
378 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
379 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
380 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
381 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
382 imageLayout, // VkImageLayout initialLayout;
383 imageLayout, // VkImageLayout finalLayout;
387 const VkAttachmentReference attachmentRef =
389 0u, // deUint32 attachment;
390 imageLayout, // VkImageLayout layout;
393 const VkAttachmentReference resolveAttachmentRef =
395 1u, // deUint32 attachment;
396 imageLayout, // VkImageLayout layout;
399 const VkSubpassDescription subpassDesc =
401 0u, // VkSubpassDescriptionFlags flags;
402 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
403 0u, // deUint32 inputAttachmentCount;
404 DE_NULL, // const VkAttachmentReference* pInputAttachments;
405 1u, // deUint32 colorAttachmentCount;
406 &attachmentRef, // const VkAttachmentReference* pColorAttachments;
407 m_multisampling ? &resolveAttachmentRef : DE_NULL, // const VkAttachmentReference* pResolveAttachments;
408 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
409 0u, // deUint32 preserveAttachmentCount;
410 DE_NULL, // const VkAttachmentReference* pPreserveAttachments;
413 const VkRenderPassCreateInfo renderPassCreateInfo =
415 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
416 DE_NULL, // const void* pNext;
417 0u, // VkRenderPassCreateFlags flags;
418 m_multisampling ? 2u : 1u, // deUint32 attachmentCount;
419 attachmentDesc, // const VkAttachmentDescription* pAttachments;
420 1u, // deUint32 subpassCount;
421 &subpassDesc, // const VkSubpassDescription* pSubpasses;
422 0u, // deUint32 dependencyCount;
423 DE_NULL, // const VkSubpassDependency* pDependencies;
426 m_renderPass = createRenderPass(vkd, vkDevice, &renderPassCreateInfo, DE_NULL);
431 const VkImageView attachments[] =
437 const VkFramebufferCreateInfo framebufferCreateInfo =
439 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
440 DE_NULL, // const void* pNext;
441 0u, // VkFramebufferCreateFlags flags;
442 *m_renderPass, // VkRenderPass renderPass;
443 m_multisampling ? 2u : 1u, // deUint32 attachmentCount;
444 attachments, // const VkImageView* pAttachments;
445 m_renderSize, // deUint32 width;
446 m_renderSize, // deUint32 height;
447 1u, // deUint32 layers;
450 m_frameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL);
455 const VkBufferCreateInfo bufferCreateInfo =
457 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
458 DE_NULL, // const void* pNext;
459 0u, // VkBufferCreateFlags flags;
460 m_uniformBufferSize, // VkDeviceSize size;
461 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, // VkBufferUsageFlags usage;
462 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
463 1u, // deUint32 queueFamilyIndexCount;
464 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
467 m_uniformBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo);
468 m_uniformBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_uniformBuffer), MemoryRequirement::HostVisible);
470 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_uniformBuffer, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset()));
475 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
476 m_descriptorPool = descriptorPoolBuilder.build(vkd, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
478 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_ALL);
479 m_descriptorSetLayout = descriptorSetLayoutBuilder.build(vkd, vkDevice);
481 const VkDescriptorSetAllocateInfo descriptorSetParams =
483 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
487 &m_descriptorSetLayout.get(),
490 m_descriptorSet = allocateDescriptorSet(vkd, vkDevice, &descriptorSetParams);
492 const VkDescriptorBufferInfo descriptorBufferInfo =
494 *m_uniformBuffer, // VkBuffer buffer;
495 0u, // VkDeviceSize offset;
496 VK_WHOLE_SIZE // VkDeviceSize range;
499 const VkWriteDescriptorSet writeDescritporSet =
501 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
502 DE_NULL, // const void* pNext;
503 *m_descriptorSet, // VkDescriptorSet destSet;
504 0, // deUint32 destBinding;
505 0, // deUint32 destArrayElement;
506 1u, // deUint32 count;
507 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, // VkDescriptorType descriptorType;
508 DE_NULL, // const VkDescriptorImageInfo* pImageInfo;
509 &descriptorBufferInfo, // const VkDescriptorBufferInfo* pBufferInfo;
510 DE_NULL // const VkBufferView* pTexelBufferView;
513 vkd.updateDescriptorSets(vkDevice, 1u, &writeDescritporSet, 0u, DE_NULL);
518 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
520 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
521 DE_NULL, // const void* pNext;
522 0u, // VkPipelineLayoutCreateFlags flags;
523 1u, // deUint32 descriptorSetCount;
524 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
525 0u, // deUint32 pushConstantRangeCount;
526 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
529 m_pipelineLayout = createPipelineLayout(vkd, vkDevice, &pipelineLayoutCreateInfo);
534 m_vertexShaderModule = createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("vertext_shader"), 0);
535 m_fragmentShaderModule = createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("fragment_shader"), 0);
540 const VkBufferCreateInfo bufferCreateInfo =
542 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
543 DE_NULL, // const void* pNext;
544 0u, // VkBufferCreateFlags flags;
545 m_resultBufferSize, // VkDeviceSize size;
546 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
547 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
548 1u, // deUint32 queueFamilyIndexCount;
549 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
552 m_resultBuffer = createBuffer(vkd, vkDevice, &bufferCreateInfo);
553 m_resultBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_resultBuffer), MemoryRequirement::HostVisible);
555 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));
558 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Sample count = " << getSampleCountFlagsStr(m_sampleCount) << tcu::TestLog::EndMessage;
559 m_context.getTestContext().getLog() << tcu::TestLog::Message << "SUBPIXEL_BITS = " << m_subpixelBits << tcu::TestLog::EndMessage;
562 BaseRenderingTestInstance::~BaseRenderingTestInstance (void)
567 void BaseRenderingTestInstance::addImageTransitionBarrier(VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const
570 const DeviceInterface& vkd = m_context.getDeviceInterface();
572 const VkImageSubresourceRange subResourcerange =
574 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
575 0, // deUint32 baseMipLevel;
576 1, // deUint32 levelCount;
577 0, // deUint32 baseArrayLayer;
578 1 // deUint32 layerCount;
581 const VkImageMemoryBarrier imageBarrier =
583 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
584 DE_NULL, // const void* pNext;
585 srcAccessMask, // VkAccessFlags srcAccessMask;
586 dstAccessMask, // VkAccessFlags dstAccessMask;
587 oldLayout, // VkImageLayout oldLayout;
588 newLayout, // VkImageLayout newLayout;
589 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
590 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
591 image, // VkImage image;
592 subResourcerange // VkImageSubresourceRange subresourceRange;
595 vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier);
598 void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology)
600 // default to color white
601 const std::vector<tcu::Vec4> colorData(vertexData.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
603 drawPrimitives(result, vertexData, colorData, primitiveTopology);
606 void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology)
608 const DeviceInterface& vkd = m_context.getDeviceInterface();
609 const VkDevice vkDevice = m_context.getDevice();
610 const VkQueue queue = m_context.getUniversalQueue();
611 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
612 Allocator& allocator = m_context.getDefaultAllocator();
613 const size_t attributeBatchSize = positionData.size() * sizeof(tcu::Vec4);
615 Move<VkCommandBuffer> commandBuffer;
616 Move<VkPipeline> graphicsPipeline;
617 Move<VkBuffer> vertexBuffer;
618 de::MovePtr<Allocation> vertexBufferMemory;
619 const VkPhysicalDeviceProperties properties = m_context.getDeviceProperties();
621 if (attributeBatchSize > properties.limits.maxVertexInputAttributeOffset)
623 std::stringstream message;
624 message << "Larger vertex input attribute offset is needed (" << attributeBatchSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
625 TCU_THROW(NotSupportedError, message.str().c_str());
628 // Create Graphics Pipeline
630 const VkVertexInputBindingDescription vertexInputBindingDescription =
632 0u, // deUint32 binding;
633 sizeof(tcu::Vec4), // deUint32 strideInBytes;
634 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
637 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
640 0u, // deUint32 location;
641 0u, // deUint32 binding;
642 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
643 0u // deUint32 offsetInBytes;
646 1u, // deUint32 location;
647 0u, // deUint32 binding;
648 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
649 (deUint32)attributeBatchSize // deUint32 offsetInBytes;
653 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
655 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
656 DE_NULL, // const void* pNext;
657 0, // VkPipelineVertexInputStateCreateFlags flags;
658 1u, // deUint32 bindingCount;
659 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
660 2u, // deUint32 attributeCount;
661 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
664 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(m_renderSize)));
665 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(m_renderSize)));
667 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
669 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
670 DE_NULL, // const void* pNext;
671 0u, // VkPipelineMultisampleStateCreateFlags flags;
672 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
673 VK_FALSE, // VkBool32 sampleShadingEnable;
674 0.0f, // float minSampleShading;
675 DE_NULL, // const VkSampleMask* pSampleMask;
676 VK_FALSE, // VkBool32 alphaToCoverageEnable;
677 VK_FALSE // VkBool32 alphaToOneEnable;
680 graphicsPipeline = makeGraphicsPipeline(vkd, // const DeviceInterface& vk
681 vkDevice, // const VkDevice device
682 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
683 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
684 DE_NULL, // const VkShaderModule tessellationControlShaderModule
685 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
686 DE_NULL, // const VkShaderModule geometryShaderModule
687 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
688 *m_renderPass, // const VkRenderPass renderPass
689 viewports, // const std::vector<VkViewport>& viewports
690 scissors, // const std::vector<VkRect2D>& scissors
691 primitiveTopology, // const VkPrimitiveTopology topology
692 0u, // const deUint32 subpass
693 0u, // const deUint32 patchControlPoints
694 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
695 getRasterizationStateCreateInfo(), // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
696 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
697 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo,
698 getColorBlendStateCreateInfo()); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
701 // Create Vertex Buffer
703 const VkBufferCreateInfo vertexBufferParams =
705 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
706 DE_NULL, // const void* pNext;
707 0u, // VkBufferCreateFlags flags;
708 attributeBatchSize * 2, // VkDeviceSize size;
709 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
710 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
711 1u, // deUint32 queueFamilyCount;
712 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
715 vertexBuffer = createBuffer(vkd, vkDevice, &vertexBufferParams);
716 vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
718 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
720 // Load vertices into vertex buffer
721 deMemcpy(vertexBufferMemory->getHostPtr(), positionData.data(), attributeBatchSize);
722 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) + attributeBatchSize, colorData.data(), attributeBatchSize);
723 flushMappedMemoryRange(vkd, vkDevice, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset(), vertexBufferParams.size);
726 // Create Command Buffer
727 commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
729 // Begin Command Buffer
730 beginCommandBuffer(vkd, *commandBuffer);
732 addImageTransitionBarrier(*commandBuffer, *m_image,
733 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
734 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
735 0, // VkAccessFlags srcAccessMask
736 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
737 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
738 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
740 if (m_multisampling) {
741 addImageTransitionBarrier(*commandBuffer, *m_resolvedImage,
742 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
743 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
744 0, // VkAccessFlags srcAccessMask
745 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
746 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
747 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
751 beginRenderPass(vkd, *commandBuffer, *m_renderPass, *m_frameBuffer, vk::makeRect2D(0, 0, m_renderSize, m_renderSize), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
753 const VkDeviceSize vertexBufferOffset = 0;
755 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
756 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL);
757 vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
758 vkd.cmdDraw(*commandBuffer, (deUint32)positionData.size(), 1, 0, 0);
759 endRenderPass(vkd, *commandBuffer);
764 const VkBufferMemoryBarrier bufferBarrier =
766 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
767 DE_NULL, // const void* pNext;
768 VK_ACCESS_TRANSFER_WRITE_BIT, // VkMemoryOutputFlags outputMask;
769 VK_ACCESS_HOST_READ_BIT, // VkMemoryInputFlags inputMask;
770 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
771 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
772 *m_resultBuffer, // VkBuffer buffer;
773 0u, // VkDeviceSize offset;
774 m_resultBufferSize // VkDeviceSize size;
777 const VkBufferImageCopy copyRegion =
779 0u, // VkDeviceSize bufferOffset;
780 m_renderSize, // deUint32 bufferRowLength;
781 m_renderSize, // deUint32 bufferImageHeight;
782 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u }, // VkImageSubresourceCopy imageSubresource;
783 { 0, 0, 0 }, // VkOffset3D imageOffset;
784 { m_renderSize, m_renderSize, 1u } // VkExtent3D imageExtent;
787 addImageTransitionBarrier(*commandBuffer,
788 m_multisampling ? *m_resolvedImage : *m_image,
789 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
790 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
791 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
792 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
793 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
794 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); // VkImageLayout newLayout;)
797 vkd.cmdCopyImageToBuffer(*commandBuffer, *m_resolvedImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, ©Region);
799 vkd.cmdCopyImageToBuffer(*commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, ©Region);
801 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
804 endCommandBuffer(vkd, *commandBuffer);
808 float pointSize = getPointSize();
809 deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize);
810 flushMappedMemoryRange(vkd, vkDevice, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset(), m_uniformBufferSize);
814 submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());
816 invalidateMappedMemoryRange(vkd, vkDevice, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(), m_resultBufferSize);
817 tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderSize, m_renderSize, 1), m_resultBufferMemory->getHostPtr()));
820 float BaseRenderingTestInstance::getLineWidth (void) const
825 float BaseRenderingTestInstance::getPointSize (void) const
830 const VkPipelineRasterizationStateCreateInfo* BaseRenderingTestInstance::getRasterizationStateCreateInfo (void) const
832 static VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
834 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
835 DE_NULL, // const void* pNext;
836 0, // VkPipelineRasterizationStateCreateFlags flags;
837 false, // VkBool32 depthClipEnable;
838 false, // VkBool32 rasterizerDiscardEnable;
839 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
840 VK_CULL_MODE_NONE, // VkCullMode cullMode;
841 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
842 VK_FALSE, // VkBool32 depthBiasEnable;
843 0.0f, // float depthBias;
844 0.0f, // float depthBiasClamp;
845 0.0f, // float slopeScaledDepthBias;
846 getLineWidth(), // float lineWidth;
849 rasterizationStateCreateInfo.lineWidth = getLineWidth();
850 return &rasterizationStateCreateInfo;
853 const VkPipelineColorBlendStateCreateInfo* BaseRenderingTestInstance::getColorBlendStateCreateInfo (void) const
855 static const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
857 false, // VkBool32 blendEnable;
858 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
859 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor;
860 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
861 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
862 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha;
863 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
864 (VK_COLOR_COMPONENT_R_BIT |
865 VK_COLOR_COMPONENT_G_BIT |
866 VK_COLOR_COMPONENT_B_BIT |
867 VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask;
870 static const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
872 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
873 DE_NULL, // const void* pNext;
874 0, // VkPipelineColorBlendStateCreateFlags flags;
875 false, // VkBool32 logicOpEnable;
876 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
877 1u, // deUint32 attachmentCount;
878 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
879 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
882 return &colorBlendStateParams;
885 const tcu::TextureFormat& BaseRenderingTestInstance::getTextureFormat (void) const
887 return m_textureFormat;
890 class BaseTriangleTestInstance : public BaseRenderingTestInstance
893 BaseTriangleTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, VkSampleCountFlagBits sampleCount);
894 virtual tcu::TestStatus iterate (void);
897 virtual void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles) = DE_NULL;
900 const int m_iterationCount;
901 VkPrimitiveTopology m_primitiveTopology;
902 bool m_allIterationsPassed;
905 BaseTriangleTestInstance::BaseTriangleTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, VkSampleCountFlagBits sampleCount)
906 : BaseRenderingTestInstance (context, sampleCount)
908 , m_iterationCount (3)
909 , m_primitiveTopology (primitiveTopology)
910 , m_allIterationsPassed (true)
914 tcu::TestStatus BaseTriangleTestInstance::iterate (void)
916 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
917 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
918 tcu::Surface resultImage (m_renderSize, m_renderSize);
919 std::vector<tcu::Vec4> drawBuffer;
920 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
922 generateTriangles(m_iteration, drawBuffer, triangles);
925 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
930 RasterizationArguments args;
931 TriangleSceneSpec scene;
933 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
935 args.numSamples = m_multisampling ? 1 : 0;
936 args.subpixelBits = m_subpixelBits;
937 args.redBits = colorBits[0];
938 args.greenBits = colorBits[1];
939 args.blueBits = colorBits[2];
941 scene.triangles.swap(triangles);
943 compareOk = verifyTriangleGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
946 m_allIterationsPassed = false;
950 if (++m_iteration == m_iterationCount)
952 if (m_allIterationsPassed)
953 return tcu::TestStatus::pass("Pass");
955 return tcu::TestStatus::fail("Incorrect rasterization");
958 return tcu::TestStatus::incomplete();
961 class BaseLineTestInstance : public BaseRenderingTestInstance
964 BaseLineTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount);
965 virtual tcu::TestStatus iterate (void);
966 virtual float getLineWidth (void) const;
969 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines) = DE_NULL;
972 const int m_iterationCount;
973 VkPrimitiveTopology m_primitiveTopology;
974 const PrimitiveWideness m_primitiveWideness;
975 bool m_allIterationsPassed;
976 float m_maxLineWidth;
977 std::vector<float> m_lineWidths;
980 BaseLineTestInstance::BaseLineTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
981 : BaseRenderingTestInstance (context, sampleCount)
983 , m_iterationCount (3)
984 , m_primitiveTopology (primitiveTopology)
985 , m_primitiveWideness (wideness)
986 , m_allIterationsPassed (true)
987 , m_maxLineWidth (1.0f)
989 DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
991 if (!context.getDeviceProperties().limits.strictLines)
992 TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
994 // create line widths
995 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
997 m_lineWidths.resize(m_iterationCount, 1.0f);
999 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
1001 if (!m_context.getDeviceFeatures().wideLines)
1002 TCU_THROW(NotSupportedError , "wide line support required");
1004 const float* range = context.getDeviceProperties().limits.lineWidthRange;
1006 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
1008 // no wide line support
1009 if (range[1] <= 1.0f)
1010 TCU_THROW(NotSupportedError, "wide line support required");
1012 // set hand picked sizes
1013 m_lineWidths.push_back(5.0f);
1014 m_lineWidths.push_back(10.0f);
1015 m_lineWidths.push_back(range[1]);
1016 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
1018 m_maxLineWidth = range[1];
1024 tcu::TestStatus BaseLineTestInstance::iterate (void)
1026 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1027 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1028 const float lineWidth = getLineWidth();
1029 tcu::Surface resultImage (m_renderSize, m_renderSize);
1030 std::vector<tcu::Vec4> drawBuffer;
1031 std::vector<LineSceneSpec::SceneLine> lines;
1034 if (lineWidth <= m_maxLineWidth)
1037 generateLines(m_iteration, drawBuffer, lines);
1040 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
1044 RasterizationArguments args;
1045 LineSceneSpec scene;
1048 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1050 args.numSamples = m_multisampling ? 1 : 0;
1051 args.subpixelBits = m_subpixelBits;
1052 args.redBits = colorBits[0];
1053 args.greenBits = colorBits[1];
1054 args.blueBits = colorBits[2];
1056 scene.lines.swap(lines);
1057 scene.lineWidth = lineWidth;
1059 if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog()))
1060 m_allIterationsPassed = false;
1064 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
1067 if (++m_iteration == m_iterationCount)
1069 if (m_allIterationsPassed)
1070 return tcu::TestStatus::pass("Pass");
1072 return tcu::TestStatus::fail("Incorrect rasterization");
1075 return tcu::TestStatus::incomplete();
1079 float BaseLineTestInstance::getLineWidth (void) const
1081 return m_lineWidths[m_iteration];
1085 class PointTestInstance : public BaseRenderingTestInstance
1088 PointTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount);
1089 virtual tcu::TestStatus iterate (void);
1090 virtual float getPointSize (void) const;
1093 virtual void generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints);
1096 const int m_iterationCount;
1097 const PrimitiveWideness m_primitiveWideness;
1098 bool m_allIterationsPassed;
1099 float m_maxPointSize;
1100 std::vector<float> m_pointSizes;
1103 PointTestInstance::PointTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
1104 : BaseRenderingTestInstance (context, sampleCount)
1106 , m_iterationCount (3)
1107 , m_primitiveWideness (wideness)
1108 , m_allIterationsPassed (true)
1109 , m_maxPointSize (1.0f)
1111 // create point sizes
1112 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
1114 m_pointSizes.resize(m_iterationCount, 1.0f);
1116 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
1118 if (!m_context.getDeviceFeatures().largePoints)
1119 TCU_THROW(NotSupportedError , "large point support required");
1121 const float* range = context.getDeviceProperties().limits.pointSizeRange;
1123 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_ALIASED_POINT_SIZE_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
1125 // no wide line support
1126 if (range[1] <= 1.0f)
1127 TCU_THROW(NotSupportedError , "wide point support required");
1129 // set hand picked sizes
1130 m_pointSizes.push_back(10.0f);
1131 m_pointSizes.push_back(25.0f);
1132 m_pointSizes.push_back(range[1]);
1133 DE_ASSERT((int)m_pointSizes.size() == m_iterationCount);
1135 m_maxPointSize = range[1];
1141 tcu::TestStatus PointTestInstance::iterate (void)
1143 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1144 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1145 const float pointSize = getPointSize();
1146 tcu::Surface resultImage (m_renderSize, m_renderSize);
1147 std::vector<tcu::Vec4> drawBuffer;
1148 std::vector<PointSceneSpec::ScenePoint> points;
1151 if (pointSize <= m_maxPointSize)
1154 generatePoints(m_iteration, drawBuffer, points);
1157 drawPrimitives(resultImage, drawBuffer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
1162 RasterizationArguments args;
1163 PointSceneSpec scene;
1165 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1167 args.numSamples = m_multisampling ? 1 : 0;
1168 args.subpixelBits = m_subpixelBits;
1169 args.redBits = colorBits[0];
1170 args.greenBits = colorBits[1];
1171 args.blueBits = colorBits[2];
1173 scene.points.swap(points);
1175 compareOk = verifyPointGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
1178 m_allIterationsPassed = false;
1182 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point size " << pointSize << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
1185 if (++m_iteration == m_iterationCount)
1187 if (m_allIterationsPassed)
1188 return tcu::TestStatus::pass("Pass");
1190 return tcu::TestStatus::fail("Incorrect rasterization");
1193 return tcu::TestStatus::incomplete();
1196 float PointTestInstance::getPointSize (void) const
1198 return m_pointSizes[m_iteration];
1201 void PointTestInstance::generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints)
1208 // \note: these values are chosen arbitrarily
1209 outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f);
1210 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1211 outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f);
1212 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1213 outData[4] = tcu::Vec4(-0.2f, -0.4f, 0.0f, 1.0f);
1214 outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f);
1218 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1219 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1220 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1221 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1222 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1223 outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f);
1227 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1228 outData[1] = tcu::Vec4( 0.3f, -0.9f, 0.0f, 1.0f);
1229 outData[2] = tcu::Vec4( -0.4f, -0.1f, 0.0f, 1.0f);
1230 outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f);
1231 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1232 outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f);
1236 outPoints.resize(outData.size());
1237 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
1239 outPoints[pointNdx].position = outData[pointNdx];
1240 outPoints[pointNdx].pointSize = getPointSize();
1244 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outPoints.size() << " point(s): (point size = " << getPointSize() << ")" << tcu::TestLog::EndMessage;
1245 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
1246 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point " << (pointNdx+1) << ":\t" << outPoints[pointNdx].position << tcu::TestLog::EndMessage;
1249 template <typename ConcreteTestInstance>
1250 class BaseTestCase : public BaseRenderingTestCase
1253 BaseTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
1254 : BaseRenderingTestCase(context, name, description, sampleCount)
1257 virtual TestInstance* createInstance (Context& context) const
1259 return new ConcreteTestInstance(context, m_sampleCount);
1263 class TrianglesTestInstance : public BaseTriangleTestInstance
1266 TrianglesTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
1267 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, sampleCount)
1270 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
1273 void TrianglesTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
1280 // \note: these values are chosen arbitrarily
1281 outData[0] = tcu::Vec4( 0.2f, 0.8f, 0.0f, 1.0f);
1282 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1283 outData[2] = tcu::Vec4( 0.5f, 0.3f, 0.0f, 1.0f);
1284 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1285 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
1286 outData[5] = tcu::Vec4(-0.4f, 0.2f, 0.0f, 1.0f);
1290 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1291 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1292 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1293 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1294 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1295 outData[5] = tcu::Vec4( 0.4f, 1.2f, 0.0f, 1.0f);
1299 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1300 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1301 outData[2] = tcu::Vec4( -1.1f, -0.1f, 0.0f, 1.0f);
1302 outData[3] = tcu::Vec4(-0.11f, 0.2f, 0.0f, 1.0f);
1303 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1304 outData[5] = tcu::Vec4( -0.4f, 0.4f, 0.0f, 1.0f);
1308 outTriangles.resize(2);
1309 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
1310 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false;
1311 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false;
1313 outTriangles[1].positions[0] = outData[3]; outTriangles[1].sharedEdge[0] = false;
1314 outTriangles[1].positions[1] = outData[4]; outTriangles[1].sharedEdge[1] = false;
1315 outTriangles[1].positions[2] = outData[5]; outTriangles[1].sharedEdge[2] = false;
1318 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outTriangles.size() << " triangle(s):" << tcu::TestLog::EndMessage;
1319 for (int triangleNdx = 0; triangleNdx < (int)outTriangles.size(); ++triangleNdx)
1321 m_context.getTestContext().getLog()
1322 << tcu::TestLog::Message
1323 << "Triangle " << (triangleNdx+1) << ":"
1324 << "\n\t" << outTriangles[triangleNdx].positions[0]
1325 << "\n\t" << outTriangles[triangleNdx].positions[1]
1326 << "\n\t" << outTriangles[triangleNdx].positions[2]
1327 << tcu::TestLog::EndMessage;
1331 class TriangleStripTestInstance : public BaseTriangleTestInstance
1334 TriangleStripTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
1335 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, sampleCount)
1338 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
1341 void TriangleStripTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
1348 // \note: these values are chosen arbitrarily
1349 outData[0] = tcu::Vec4(-0.504f, 0.8f, 0.0f, 1.0f);
1350 outData[1] = tcu::Vec4(-0.2f, -0.2f, 0.0f, 1.0f);
1351 outData[2] = tcu::Vec4(-0.2f, 0.199f, 0.0f, 1.0f);
1352 outData[3] = tcu::Vec4( 0.5f, 0.201f, 0.0f, 1.0f);
1353 outData[4] = tcu::Vec4( 1.5f, 0.4f, 0.0f, 1.0f);
1357 outData[0] = tcu::Vec4(-0.499f, 0.129f, 0.0f, 1.0f);
1358 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1359 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1360 outData[3] = tcu::Vec4( 0.11f, -0.31f, 0.0f, 1.0f);
1361 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1365 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1366 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1367 outData[2] = tcu::Vec4(-0.87f, -0.1f, 0.0f, 1.0f);
1368 outData[3] = tcu::Vec4(-0.11f, 0.19f, 0.0f, 1.0f);
1369 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1373 outTriangles.resize(3);
1374 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
1375 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = true;
1376 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = false;
1378 outTriangles[1].positions[0] = outData[2]; outTriangles[1].sharedEdge[0] = true;
1379 outTriangles[1].positions[1] = outData[1]; outTriangles[1].sharedEdge[1] = false;
1380 outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true;
1382 outTriangles[2].positions[0] = outData[2]; outTriangles[2].sharedEdge[0] = true;
1383 outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false;
1384 outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false;
1387 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering triangle strip, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1388 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1390 m_context.getTestContext().getLog()
1391 << tcu::TestLog::Message
1392 << "\t" << outData[vtxNdx]
1393 << tcu::TestLog::EndMessage;
1397 class TriangleFanTestInstance : public BaseTriangleTestInstance
1400 TriangleFanTestInstance (Context& context, VkSampleCountFlagBits sampleCount)
1401 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, sampleCount)
1404 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
1407 void TriangleFanTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
1414 // \note: these values are chosen arbitrarily
1415 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1416 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1417 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1418 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1419 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
1423 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1424 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1425 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1426 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1427 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1431 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1432 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1433 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1434 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1435 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1439 outTriangles.resize(3);
1440 outTriangles[0].positions[0] = outData[0]; outTriangles[0].sharedEdge[0] = false;
1441 outTriangles[0].positions[1] = outData[1]; outTriangles[0].sharedEdge[1] = false;
1442 outTriangles[0].positions[2] = outData[2]; outTriangles[0].sharedEdge[2] = true;
1444 outTriangles[1].positions[0] = outData[0]; outTriangles[1].sharedEdge[0] = true;
1445 outTriangles[1].positions[1] = outData[2]; outTriangles[1].sharedEdge[1] = false;
1446 outTriangles[1].positions[2] = outData[3]; outTriangles[1].sharedEdge[2] = true;
1448 outTriangles[2].positions[0] = outData[0]; outTriangles[2].sharedEdge[0] = true;
1449 outTriangles[2].positions[1] = outData[3]; outTriangles[2].sharedEdge[1] = false;
1450 outTriangles[2].positions[2] = outData[4]; outTriangles[2].sharedEdge[2] = false;
1453 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering triangle fan, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1454 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1456 m_context.getTestContext().getLog()
1457 << tcu::TestLog::Message
1458 << "\t" << outData[vtxNdx]
1459 << tcu::TestLog::EndMessage;
1463 template <typename ConcreteTestInstance>
1464 class WidenessTestCase : public BaseRenderingTestCase
1467 WidenessTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
1468 : BaseRenderingTestCase(context, name, description, sampleCount)
1469 , m_wideness(wideness)
1472 virtual TestInstance* createInstance (Context& context) const
1474 return new ConcreteTestInstance(context, m_wideness, m_sampleCount);
1477 const PrimitiveWideness m_wideness;
1480 class LinesTestInstance : public BaseLineTestInstance
1483 LinesTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
1484 : BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, wideness, sampleCount)
1487 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
1490 void LinesTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
1497 // \note: these values are chosen arbitrarily
1498 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1499 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1500 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1501 outData[3] = tcu::Vec4(-0.3f, 0.2f, 0.0f, 1.0f);
1502 outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
1503 outData[5] = tcu::Vec4( 0.1f, 0.5f, 0.0f, 1.0f);
1507 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1508 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1509 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1510 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1511 outData[4] = tcu::Vec4( 0.88f, 0.9f, 0.0f, 1.0f);
1512 outData[5] = tcu::Vec4( 0.18f, -0.2f, 0.0f, 1.0f);
1516 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1517 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1518 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1519 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1520 outData[4] = tcu::Vec4( 0.88f, 0.7f, 0.0f, 1.0f);
1521 outData[5] = tcu::Vec4( 0.8f, -0.7f, 0.0f, 1.0f);
1526 outLines[0].positions[0] = outData[0];
1527 outLines[0].positions[1] = outData[1];
1528 outLines[1].positions[0] = outData[2];
1529 outLines[1].positions[1] = outData[3];
1530 outLines[2].positions[0] = outData[4];
1531 outLines[2].positions[1] = outData[5];
1534 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outLines.size() << " lines(s): (width = " << getLineWidth() << ")" << tcu::TestLog::EndMessage;
1535 for (int lineNdx = 0; lineNdx < (int)outLines.size(); ++lineNdx)
1537 m_context.getTestContext().getLog()
1538 << tcu::TestLog::Message
1539 << "Line " << (lineNdx+1) << ":"
1540 << "\n\t" << outLines[lineNdx].positions[0]
1541 << "\n\t" << outLines[lineNdx].positions[1]
1542 << tcu::TestLog::EndMessage;
1546 class LineStripTestInstance : public BaseLineTestInstance
1549 LineStripTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
1550 : BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, wideness, sampleCount)
1553 virtual void generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
1556 void LineStripTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
1563 // \note: these values are chosen arbitrarily
1564 outData[0] = tcu::Vec4( 0.01f, 0.0f, 0.0f, 1.0f);
1565 outData[1] = tcu::Vec4( 0.5f, 0.2f, 0.0f, 1.0f);
1566 outData[2] = tcu::Vec4( 0.46f, 0.3f, 0.0f, 1.0f);
1567 outData[3] = tcu::Vec4(-0.5f, 0.2f, 0.0f, 1.0f);
1571 outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1572 outData[1] = tcu::Vec4(-0.501f, -0.3f, 0.0f, 1.0f);
1573 outData[2] = tcu::Vec4( 0.11f, -0.2f, 0.0f, 1.0f);
1574 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1578 outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1579 outData[1] = tcu::Vec4( 1.1f, -0.9f, 0.0f, 1.0f);
1580 outData[2] = tcu::Vec4( 0.7f, -0.1f, 0.0f, 1.0f);
1581 outData[3] = tcu::Vec4( 0.11f, 0.2f, 0.0f, 1.0f);
1586 outLines[0].positions[0] = outData[0];
1587 outLines[0].positions[1] = outData[1];
1588 outLines[1].positions[0] = outData[1];
1589 outLines[1].positions[1] = outData[2];
1590 outLines[2].positions[0] = outData[2];
1591 outLines[2].positions[1] = outData[3];
1594 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering line strip, width = " << getLineWidth() << ", " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1595 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1597 m_context.getTestContext().getLog()
1598 << tcu::TestLog::Message
1599 << "\t" << outData[vtxNdx]
1600 << tcu::TestLog::EndMessage;
1604 class FillRuleTestInstance : public BaseRenderingTestInstance
1607 enum FillRuleCaseType
1609 FILLRULECASE_BASIC = 0,
1610 FILLRULECASE_REVERSED,
1611 FILLRULECASE_CLIPPED_FULL,
1612 FILLRULECASE_CLIPPED_PARTIAL,
1613 FILLRULECASE_PROJECTED,
1617 FillRuleTestInstance (Context& context, FillRuleCaseType type, VkSampleCountFlagBits sampleCount);
1618 virtual tcu::TestStatus iterate (void);
1622 virtual const VkPipelineColorBlendStateCreateInfo* getColorBlendStateCreateInfo (void) const;
1623 int getRenderSize (FillRuleCaseType type) const;
1624 int getNumIterations (FillRuleCaseType type) const;
1625 void generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const;
1627 const FillRuleCaseType m_caseType;
1629 const int m_iterationCount;
1630 bool m_allIterationsPassed;
1634 FillRuleTestInstance::FillRuleTestInstance (Context& context, FillRuleCaseType type, VkSampleCountFlagBits sampleCount)
1635 : BaseRenderingTestInstance (context, sampleCount, getRenderSize(type))
1638 , m_iterationCount (getNumIterations(type))
1639 , m_allIterationsPassed (true)
1641 DE_ASSERT(type < FILLRULECASE_LAST);
1644 tcu::TestStatus FillRuleTestInstance::iterate (void)
1646 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1647 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1648 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1649 const int thresholdRed = 1 << (8 - colorBits[0]);
1650 const int thresholdGreen = 1 << (8 - colorBits[1]);
1651 const int thresholdBlue = 1 << (8 - colorBits[2]);
1652 tcu::Surface resultImage (m_renderSize, m_renderSize);
1653 std::vector<tcu::Vec4> drawBuffer;
1655 generateTriangles(m_iteration, drawBuffer);
1659 const std::vector<tcu::Vec4> colorBuffer (drawBuffer.size(), tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
1661 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Drawing gray triangles with shared edges.\nEnabling additive blending to detect overlapping fragments." << tcu::TestLog::EndMessage;
1663 drawPrimitives(resultImage, drawBuffer, colorBuffer, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
1666 // verify no overdraw
1668 const tcu::RGBA triangleColor = tcu::RGBA(127, 127, 127, 255);
1669 bool overdraw = false;
1671 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Verifying result." << tcu::TestLog::EndMessage;
1673 for (int y = 0; y < resultImage.getHeight(); ++y)
1674 for (int x = 0; x < resultImage.getWidth(); ++x)
1676 const tcu::RGBA color = resultImage.getPixel(x, y);
1678 // color values are greater than triangle color? Allow lower values for multisampled edges and background.
1679 if ((color.getRed() - triangleColor.getRed()) > thresholdRed ||
1680 (color.getGreen() - triangleColor.getGreen()) > thresholdGreen ||
1681 (color.getBlue() - triangleColor.getBlue()) > thresholdBlue)
1687 m_context.getTestContext().getLog() << tcu::TestLog::Message << "No overlapping fragments detected." << tcu::TestLog::EndMessage;
1690 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Overlapping fragments detected, image is not valid." << tcu::TestLog::EndMessage;
1691 m_allIterationsPassed = false;
1695 // verify no missing fragments in the full viewport case
1696 if (m_caseType == FILLRULECASE_CLIPPED_FULL)
1698 bool missingFragments = false;
1700 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Searching missing fragments." << tcu::TestLog::EndMessage;
1702 for (int y = 0; y < resultImage.getHeight(); ++y)
1703 for (int x = 0; x < resultImage.getWidth(); ++x)
1705 const tcu::RGBA color = resultImage.getPixel(x, y);
1707 // black? (background)
1708 if (color.getRed() <= thresholdRed ||
1709 color.getGreen() <= thresholdGreen ||
1710 color.getBlue() <= thresholdBlue)
1711 missingFragments = true;
1715 if (!missingFragments)
1716 m_context.getTestContext().getLog() << tcu::TestLog::Message << "No missing fragments detected." << tcu::TestLog::EndMessage;
1719 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Missing fragments detected, image is not valid." << tcu::TestLog::EndMessage;
1721 m_allIterationsPassed = false;
1725 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result of rendering", "Result of rendering")
1726 << tcu::TestLog::Image("Result", "Result", resultImage)
1727 << tcu::TestLog::EndImageSet;
1730 if (++m_iteration == m_iterationCount)
1732 if (m_allIterationsPassed)
1733 return tcu::TestStatus::pass("Pass");
1735 return tcu::TestStatus::fail("Found invalid pixels");
1738 return tcu::TestStatus::incomplete();
1741 int FillRuleTestInstance::getRenderSize (FillRuleCaseType type) const
1743 if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
1744 return DEFAULT_RENDER_SIZE / 4;
1746 return DEFAULT_RENDER_SIZE;
1749 int FillRuleTestInstance::getNumIterations (FillRuleCaseType type) const
1751 if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
1757 void FillRuleTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const
1761 case FILLRULECASE_BASIC:
1762 case FILLRULECASE_REVERSED:
1763 case FILLRULECASE_PROJECTED:
1765 const int numRows = 4;
1766 const int numColumns = 4;
1767 const float quadSide = 0.15f;
1768 de::Random rnd (0xabcd);
1770 outData.resize(6 * numRows * numColumns);
1772 for (int col = 0; col < numColumns; ++col)
1773 for (int row = 0; row < numRows; ++row)
1775 const tcu::Vec2 center = tcu::Vec2(((float)row + 0.5f) / (float)numRows * 2.0f - 1.0f, ((float)col + 0.5f) / (float)numColumns * 2.0f - 1.0f);
1776 const float rotation = (float)(iteration * numColumns * numRows + col * numRows + row) / (float)(m_iterationCount * numColumns * numRows) * DE_PI / 2.0f;
1777 const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
1778 const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x());
1779 const tcu::Vec2 quad[4] =
1781 center + sideH + sideV,
1782 center + sideH - sideV,
1783 center - sideH - sideV,
1784 center - sideH + sideV,
1787 if (m_caseType == FILLRULECASE_BASIC)
1789 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1790 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1791 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1792 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1793 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1794 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1796 else if (m_caseType == FILLRULECASE_REVERSED)
1798 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1799 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1800 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1801 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1802 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1803 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1805 else if (m_caseType == FILLRULECASE_PROJECTED)
1807 const float w0 = rnd.getFloat(0.1f, 4.0f);
1808 const float w1 = rnd.getFloat(0.1f, 4.0f);
1809 const float w2 = rnd.getFloat(0.1f, 4.0f);
1810 const float w3 = rnd.getFloat(0.1f, 4.0f);
1812 outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
1813 outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x() * w1, quad[1].y() * w1, 0.0f, w1);
1814 outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
1815 outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
1816 outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
1817 outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x() * w3, quad[3].y() * w3, 0.0f, w3);
1820 DE_ASSERT(DE_FALSE);
1826 case FILLRULECASE_CLIPPED_PARTIAL:
1827 case FILLRULECASE_CLIPPED_FULL:
1829 const float quadSide = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (1.0f) : (2.0f);
1830 const tcu::Vec2 center = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (tcu::Vec2(0.5f, 0.5f)) : (tcu::Vec2(0.0f, 0.0f));
1831 const float rotation = (float)(iteration) / (float)(m_iterationCount - 1) * DE_PI / 2.0f;
1832 const tcu::Vec2 sideH = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
1833 const tcu::Vec2 sideV = tcu::Vec2(sideH.y(), -sideH.x());
1834 const tcu::Vec2 quad[4] =
1836 center + sideH + sideV,
1837 center + sideH - sideV,
1838 center - sideH - sideV,
1839 center - sideH + sideV,
1843 outData[0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1844 outData[1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1845 outData[2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1846 outData[3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1847 outData[4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1848 outData[5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1853 DE_ASSERT(DE_FALSE);
1857 const VkPipelineColorBlendStateCreateInfo* FillRuleTestInstance::getColorBlendStateCreateInfo (void) const
1859 static const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1861 true, // VkBool32 blendEnable;
1862 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
1863 VK_BLEND_FACTOR_ONE, // VkBlend destBlendColor;
1864 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
1865 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
1866 VK_BLEND_FACTOR_ONE, // VkBlend destBlendAlpha;
1867 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
1868 (VK_COLOR_COMPONENT_R_BIT |
1869 VK_COLOR_COMPONENT_G_BIT |
1870 VK_COLOR_COMPONENT_B_BIT |
1871 VK_COLOR_COMPONENT_A_BIT) // VkChannelFlags channelWriteMask;
1874 static const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1876 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1877 DE_NULL, // const void* pNext;
1878 0, // VkPipelineColorBlendStateCreateFlags flags;
1879 false, // VkBool32 logicOpEnable;
1880 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1881 1u, // deUint32 attachmentCount;
1882 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1883 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
1886 return &colorBlendStateParams;
1890 class FillRuleTestCase : public BaseRenderingTestCase
1893 FillRuleTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, FillRuleTestInstance::FillRuleCaseType type, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
1894 : BaseRenderingTestCase (context, name, description, sampleCount)
1898 virtual TestInstance* createInstance (Context& context) const
1900 return new FillRuleTestInstance(context, m_type, m_sampleCount);
1903 const FillRuleTestInstance::FillRuleCaseType m_type;
1906 class CullingTestInstance : public BaseRenderingTestInstance
1909 CullingTestInstance (Context& context, VkCullModeFlags cullMode, VkPrimitiveTopology primitiveTopology, VkFrontFace frontFace, VkPolygonMode polygonMode)
1910 : BaseRenderingTestInstance (context, VK_SAMPLE_COUNT_1_BIT, DEFAULT_RENDER_SIZE)
1911 , m_cullMode (cullMode)
1912 , m_primitiveTopology (primitiveTopology)
1913 , m_frontFace (frontFace)
1914 , m_polygonMode (polygonMode)
1915 , m_multisampling (true)
1918 const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
1920 tcu::TestStatus iterate (void);
1923 void generateVertices (std::vector<tcu::Vec4>& outData) const;
1924 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const;
1925 void extractLines (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, std::vector<LineSceneSpec::SceneLine>& outLines) const;
1926 void extractPoints (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, std::vector<PointSceneSpec::ScenePoint>& outPoints) const;
1927 bool triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const;
1929 const VkCullModeFlags m_cullMode;
1930 const VkPrimitiveTopology m_primitiveTopology;
1931 const VkFrontFace m_frontFace;
1932 const VkPolygonMode m_polygonMode;
1933 const bool m_multisampling;
1937 tcu::TestStatus CullingTestInstance::iterate (void)
1939 DE_ASSERT(m_polygonMode <= VK_POLYGON_MODE_POINT);
1941 tcu::Surface resultImage (m_renderSize, m_renderSize);
1942 std::vector<tcu::Vec4> drawBuffer;
1943 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
1944 std::vector<PointSceneSpec::ScenePoint> points;
1945 std::vector<LineSceneSpec::SceneLine> lines;
1947 const InstanceInterface& vk = m_context.getInstanceInterface();
1948 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1949 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(vk, physicalDevice);
1951 if (!(deviceFeatures.fillModeNonSolid) && (m_polygonMode == VK_POLYGON_MODE_LINE || m_polygonMode == VK_POLYGON_MODE_POINT))
1952 TCU_THROW(NotSupportedError, "Wireframe fill modes are not supported");
1955 generateVertices(drawBuffer);
1956 extractTriangles(triangles, drawBuffer);
1958 if (m_polygonMode == VK_POLYGON_MODE_LINE)
1959 extractLines(triangles ,lines);
1960 else if (m_polygonMode == VK_POLYGON_MODE_POINT)
1961 extractPoints(triangles, points);
1965 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Setting front face to " << m_frontFace << tcu::TestLog::EndMessage;
1966 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Setting cull face to " << m_cullMode << tcu::TestLog::EndMessage;
1967 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Drawing test pattern (" << m_primitiveTopology << ")" << tcu::TestLog::EndMessage;
1969 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
1974 RasterizationArguments args;
1975 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1976 bool isCompareOk = false;
1978 args.numSamples = m_multisampling ? 1 : 0;
1979 args.subpixelBits = m_subpixelBits;
1980 args.redBits = colorBits[0];
1981 args.greenBits = colorBits[1];
1982 args.blueBits = colorBits[2];
1984 switch (m_polygonMode)
1986 case VK_POLYGON_MODE_LINE:
1988 LineSceneSpec scene;
1989 scene.lineWidth = 0;
1990 scene.lines.swap(lines);
1991 isCompareOk = verifyLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
1994 case VK_POLYGON_MODE_POINT:
1996 PointSceneSpec scene;
1997 scene.points.swap(points);
1998 isCompareOk = verifyPointGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
2003 TriangleSceneSpec scene;
2004 scene.triangles.swap(triangles);
2005 isCompareOk = verifyTriangleGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), tcu::VERIFICATIONMODE_WEAK);
2011 return tcu::TestStatus::pass("Pass");
2013 return tcu::TestStatus::fail("Incorrect rendering");
2017 void CullingTestInstance::generateVertices (std::vector<tcu::Vec4>& outData) const
2019 de::Random rnd(543210);
2022 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
2024 outData[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
2025 outData[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
2026 outData[vtxNdx].z() = 0.0f;
2027 outData[vtxNdx].w() = 1.0f;
2031 void CullingTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const
2033 const bool cullDirection = (m_cullMode == VK_CULL_MODE_FRONT_BIT) ^ (m_frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE);
2036 if (m_cullMode == VK_CULL_MODE_FRONT_AND_BACK)
2039 switch (m_primitiveTopology)
2041 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
2043 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
2045 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
2046 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
2047 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
2049 if (triangleOrder(v0, v1, v2) != cullDirection)
2051 TriangleSceneSpec::SceneTriangle tri;
2052 tri.positions[0] = v0; tri.sharedEdge[0] = false;
2053 tri.positions[1] = v1; tri.sharedEdge[1] = false;
2054 tri.positions[2] = v2; tri.sharedEdge[2] = false;
2056 outTriangles.push_back(tri);
2062 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
2064 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
2066 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
2067 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
2068 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
2070 if (triangleOrder(v0, v1, v2) != (cullDirection ^ (vtxNdx % 2 != 0)))
2072 TriangleSceneSpec::SceneTriangle tri;
2073 tri.positions[0] = v0; tri.sharedEdge[0] = false;
2074 tri.positions[1] = v1; tri.sharedEdge[1] = false;
2075 tri.positions[2] = v2; tri.sharedEdge[2] = false;
2077 outTriangles.push_back(tri);
2083 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
2085 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2087 const tcu::Vec4& v0 = vertices[0];
2088 const tcu::Vec4& v1 = vertices[vtxNdx + 0];
2089 const tcu::Vec4& v2 = vertices[vtxNdx + 1];
2091 if (triangleOrder(v0, v1, v2) != cullDirection)
2093 TriangleSceneSpec::SceneTriangle tri;
2094 tri.positions[0] = v0; tri.sharedEdge[0] = false;
2095 tri.positions[1] = v1; tri.sharedEdge[1] = false;
2096 tri.positions[2] = v2; tri.sharedEdge[2] = false;
2098 outTriangles.push_back(tri);
2109 void CullingTestInstance::extractLines (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles,
2110 std::vector<LineSceneSpec::SceneLine>& outLines) const
2112 for (int triNdx = 0; triNdx < (int)outTriangles.size(); ++triNdx)
2114 for (int vrtxNdx = 0; vrtxNdx < 2; ++vrtxNdx)
2116 LineSceneSpec::SceneLine line;
2117 line.positions[0] = outTriangles.at(triNdx).positions[vrtxNdx];
2118 line.positions[1] = outTriangles.at(triNdx).positions[vrtxNdx + 1];
2120 outLines.push_back(line);
2122 LineSceneSpec::SceneLine line;
2123 line.positions[0] = outTriangles.at(triNdx).positions[2];
2124 line.positions[1] = outTriangles.at(triNdx).positions[0];
2125 outLines.push_back(line);
2129 void CullingTestInstance::extractPoints (std::vector<TriangleSceneSpec::SceneTriangle> &outTriangles,
2130 std::vector<PointSceneSpec::ScenePoint> &outPoints) const
2132 for (int triNdx = 0; triNdx < (int)outTriangles.size(); ++triNdx)
2134 for (int vrtxNdx = 0; vrtxNdx < 3; ++vrtxNdx)
2136 PointSceneSpec::ScenePoint point;
2137 point.position = outTriangles.at(triNdx).positions[vrtxNdx];
2138 point.pointSize = 1.0f;
2140 outPoints.push_back(point);
2145 bool CullingTestInstance::triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const
2147 const tcu::Vec2 s0 = v0.swizzle(0, 1) / v0.w();
2148 const tcu::Vec2 s1 = v1.swizzle(0, 1) / v1.w();
2149 const tcu::Vec2 s2 = v2.swizzle(0, 1) / v2.w();
2152 return ((s1.x() - s0.x()) * (s2.y() - s0.y()) - (s2.x() - s0.x()) * (s1.y() - s0.y())) > 0;
2156 const VkPipelineRasterizationStateCreateInfo* CullingTestInstance::getRasterizationStateCreateInfo (void) const
2158 static VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
2160 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
2161 DE_NULL, // const void* pNext;
2162 0, // VkPipelineRasterizationStateCreateFlags flags;
2163 false, // VkBool32 depthClipEnable;
2164 false, // VkBool32 rasterizerDiscardEnable;
2165 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
2166 VK_CULL_MODE_NONE, // VkCullMode cullMode;
2167 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
2168 VK_FALSE, // VkBool32 depthBiasEnable;
2169 0.0f, // float depthBias;
2170 0.0f, // float depthBiasClamp;
2171 0.0f, // float slopeScaledDepthBias;
2172 getLineWidth(), // float lineWidth;
2175 rasterizationStateCreateInfo.lineWidth = getLineWidth();
2176 rasterizationStateCreateInfo.cullMode = m_cullMode;
2177 rasterizationStateCreateInfo.frontFace = m_frontFace;
2178 rasterizationStateCreateInfo.polygonMode = m_polygonMode;
2180 return &rasterizationStateCreateInfo;
2183 class CullingTestCase : public BaseRenderingTestCase
2186 CullingTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkCullModeFlags cullMode, VkPrimitiveTopology primitiveTopology, VkFrontFace frontFace, VkPolygonMode polygonMode, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2187 : BaseRenderingTestCase (context, name, description, sampleCount)
2188 , m_cullMode (cullMode)
2189 , m_primitiveTopology (primitiveTopology)
2190 , m_frontFace (frontFace)
2191 , m_polygonMode (polygonMode)
2194 virtual TestInstance* createInstance (Context& context) const
2196 return new CullingTestInstance(context, m_cullMode, m_primitiveTopology, m_frontFace, m_polygonMode);
2199 const VkCullModeFlags m_cullMode;
2200 const VkPrimitiveTopology m_primitiveTopology;
2201 const VkFrontFace m_frontFace;
2202 const VkPolygonMode m_polygonMode;
2205 class DiscardTestInstance : public BaseRenderingTestInstance
2208 DiscardTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, deBool queryFragmentShaderInvocations)
2209 : BaseRenderingTestInstance (context, VK_SAMPLE_COUNT_1_BIT, DEFAULT_RENDER_SIZE)
2210 , m_primitiveTopology (primitiveTopology)
2211 , m_queryFragmentShaderInvocations (queryFragmentShaderInvocations)
2214 virtual const VkPipelineRasterizationStateCreateInfo* getRasterizationStateCreateInfo (void) const;
2215 tcu::TestStatus iterate (void);
2218 void generateVertices (std::vector<tcu::Vec4>& outData) const;
2219 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const;
2220 void extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices) const;
2221 void extractPoints (std::vector<PointSceneSpec::ScenePoint>& outPoints, const std::vector<tcu::Vec4>& vertices) const;
2222 void drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, VkPrimitiveTopology primitiveTopology, Move<VkQueryPool>& queryPool);
2224 const VkPrimitiveTopology m_primitiveTopology;
2225 const deBool m_queryFragmentShaderInvocations;
2228 tcu::TestStatus DiscardTestInstance::iterate (void)
2230 const DeviceInterface& vkd = m_context.getDeviceInterface();
2231 const VkDevice vkDevice = m_context.getDevice();
2232 deUint64 queryResult = 0u;
2233 tcu::Surface resultImage (m_renderSize, m_renderSize);
2234 std::vector<tcu::Vec4> drawBuffer;
2235 std::vector<PointSceneSpec::ScenePoint> points;
2236 std::vector<LineSceneSpec::SceneLine> lines;
2237 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
2239 generateVertices(drawBuffer);
2241 switch (m_primitiveTopology)
2243 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
2244 extractPoints(points, drawBuffer);
2247 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
2248 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
2249 extractLines(lines, drawBuffer);
2252 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
2253 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
2254 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
2255 extractTriangles(triangles, drawBuffer);
2262 const VkQueryPoolCreateInfo queryPoolCreateInfo =
2264 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // VkStructureType sType
2265 DE_NULL, // const void* pNext
2266 (VkQueryPoolCreateFlags)0, // VkQueryPoolCreateFlags flags
2267 VK_QUERY_TYPE_PIPELINE_STATISTICS , // VkQueryType queryType
2268 1u, // deUint32 entryCount
2269 VK_QUERY_PIPELINE_STATISTIC_FRAGMENT_SHADER_INVOCATIONS_BIT, // VkQueryPipelineStatisticFlags pipelineStatistics
2272 if (m_queryFragmentShaderInvocations)
2274 Move<VkQueryPool> queryPool = createQueryPool(vkd, vkDevice, &queryPoolCreateInfo);
2276 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology, queryPool);
2277 vkd.getQueryPoolResults(vkDevice, *queryPool, 0u, 1u, sizeof(deUint64), &queryResult, 0u, VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
2280 BaseRenderingTestInstance::drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
2284 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
2286 const RasterizationArguments args =
2288 0, // int numSamples;
2289 (int)m_subpixelBits, // int subpixelBits;
2290 colorBits[0], // int redBits;
2291 colorBits[1], // int greenBits;
2292 colorBits[2] // int blueBits;
2295 // Empty scene to compare to, primitives should be discarded before rasterization
2296 TriangleSceneSpec scene;
2298 const bool isCompareOk = verifyTriangleGroupRasterization(resultImage,
2301 m_context.getTestContext().getLog(),
2302 tcu::VERIFICATIONMODE_STRICT);
2306 if (m_queryFragmentShaderInvocations && queryResult > 0u)
2307 return tcu::TestStatus::fail("Fragment shader invocations occured");
2309 return tcu::TestStatus::pass("Pass");
2312 return tcu::TestStatus::fail("Incorrect rendering");
2316 void DiscardTestInstance::generateVertices (std::vector<tcu::Vec4>& outData) const
2318 de::Random rnd(12345);
2322 for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
2324 outData[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
2325 outData[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
2326 outData[vtxNdx].z() = 0.0f;
2327 outData[vtxNdx].w() = 1.0f;
2331 void DiscardTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const
2333 switch (m_primitiveTopology)
2335 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
2337 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
2339 TriangleSceneSpec::SceneTriangle tri;
2340 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
2341 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
2342 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
2344 tri.positions[0] = v0;
2345 tri.positions[1] = v1;
2346 tri.positions[2] = v2;
2348 outTriangles.push_back(tri);
2354 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
2356 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
2358 TriangleSceneSpec::SceneTriangle tri;
2359 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
2360 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
2361 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
2363 tri.positions[0] = v0;
2364 tri.positions[1] = v1;
2365 tri.positions[2] = v2;
2367 outTriangles.push_back(tri);
2373 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
2375 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2377 TriangleSceneSpec::SceneTriangle tri;
2378 const tcu::Vec4& v0 = vertices[0];
2379 const tcu::Vec4& v1 = vertices[vtxNdx + 0];
2380 const tcu::Vec4& v2 = vertices[vtxNdx + 1];
2382 tri.positions[0] = v0;
2383 tri.positions[1] = v1;
2384 tri.positions[2] = v2;
2386 outTriangles.push_back(tri);
2397 void DiscardTestInstance::extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices) const
2399 switch (m_primitiveTopology)
2401 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
2403 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; vtxNdx += 2)
2405 LineSceneSpec::SceneLine line;
2407 line.positions[0] = vertices[vtxNdx + 0];
2408 line.positions[1] = vertices[vtxNdx + 1];
2410 outLines.push_back(line);
2416 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
2418 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2420 LineSceneSpec::SceneLine line;
2422 line.positions[0] = vertices[vtxNdx + 0];
2423 line.positions[1] = vertices[vtxNdx + 1];
2425 outLines.push_back(line);
2436 void DiscardTestInstance::extractPoints (std::vector<PointSceneSpec::ScenePoint>& outPoints, const std::vector<tcu::Vec4>& vertices) const
2438 for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
2440 for (int vrtxNdx = 0; vrtxNdx < 3; ++vrtxNdx)
2442 PointSceneSpec::ScenePoint point;
2444 point.position = vertices[vrtxNdx];
2445 point.pointSize = 1.0f;
2447 outPoints.push_back(point);
2452 const VkPipelineRasterizationStateCreateInfo* DiscardTestInstance::getRasterizationStateCreateInfo (void) const
2454 static const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo =
2456 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
2457 NULL, // const void* pNext;
2458 0, // VkPipelineRasterizationStateCreateFlags flags;
2459 VK_FALSE, // VkBool32 depthClipEnable;
2460 VK_TRUE, // VkBool32 rasterizerDiscardEnable;
2461 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
2462 VK_CULL_MODE_NONE, // VkCullMode cullMode;
2463 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
2464 VK_FALSE, // VkBool32 depthBiasEnable;
2465 0.0f, // float depthBias;
2466 0.0f, // float depthBiasClamp;
2467 0.0f, // float slopeScaledDepthBias;
2468 getLineWidth(), // float lineWidth;
2471 return &rasterizationStateCreateInfo;
2474 void DiscardTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, VkPrimitiveTopology primitiveTopology, Move<VkQueryPool>& queryPool)
2476 const DeviceInterface& vkd = m_context.getDeviceInterface();
2477 const VkDevice vkDevice = m_context.getDevice();
2478 const VkPhysicalDeviceProperties properties = m_context.getDeviceProperties();
2479 const VkQueue queue = m_context.getUniversalQueue();
2480 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2481 Allocator& allocator = m_context.getDefaultAllocator();
2483 const size_t attributeBatchSize = positionData.size() * sizeof(tcu::Vec4);
2484 const VkDeviceSize vertexBufferOffset = 0;
2485 de::MovePtr<Allocation> vertexBufferMemory;
2486 Move<VkBuffer> vertexBuffer;
2487 Move<VkCommandBuffer> commandBuffer;
2488 Move<VkPipeline> graphicsPipeline;
2490 if (attributeBatchSize > properties.limits.maxVertexInputAttributeOffset)
2492 std::stringstream message;
2493 message << "Larger vertex input attribute offset is needed (" << attributeBatchSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
2494 TCU_THROW(NotSupportedError, message.str().c_str());
2497 // Create Graphics Pipeline
2499 const VkVertexInputBindingDescription vertexInputBindingDescription =
2501 0u, // deUint32 binding;
2502 sizeof(tcu::Vec4), // deUint32 strideInBytes;
2503 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
2506 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
2509 0u, // deUint32 location;
2510 0u, // deUint32 binding;
2511 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
2512 0u // deUint32 offsetInBytes;
2515 1u, // deUint32 location;
2516 0u, // deUint32 binding;
2517 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
2518 (deUint32)attributeBatchSize // deUint32 offsetInBytes;
2522 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2524 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
2525 DE_NULL, // const void* pNext;
2526 0, // VkPipelineVertexInputStateCreateFlags flags;
2527 1u, // deUint32 bindingCount;
2528 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
2529 2u, // deUint32 attributeCount;
2530 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
2533 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(m_renderSize)));
2534 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(m_renderSize)));
2536 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2538 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
2539 DE_NULL, // const void* pNext;
2540 0u, // VkPipelineMultisampleStateCreateFlags flags;
2541 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
2542 VK_FALSE, // VkBool32 sampleShadingEnable;
2543 0.0f, // float minSampleShading;
2544 DE_NULL, // const VkSampleMask* pSampleMask;
2545 VK_FALSE, // VkBool32 alphaToCoverageEnable;
2546 VK_FALSE // VkBool32 alphaToOneEnable;
2549 graphicsPipeline = makeGraphicsPipeline(vkd, // const DeviceInterface& vk
2550 vkDevice, // const VkDevice device
2551 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
2552 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
2553 DE_NULL, // const VkShaderModule tessellationControlShaderModule
2554 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
2555 DE_NULL, // const VkShaderModule geometryShaderModule
2556 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
2557 *m_renderPass, // const VkRenderPass renderPass
2558 viewports, // const std::vector<VkViewport>& viewports
2559 scissors, // const std::vector<VkRect2D>& scissors
2560 primitiveTopology, // const VkPrimitiveTopology topology
2561 0u, // const deUint32 subpass
2562 0u, // const deUint32 patchControlPoints
2563 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
2564 getRasterizationStateCreateInfo(), // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
2565 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
2566 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo,
2567 getColorBlendStateCreateInfo()); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
2570 // Create Vertex Buffer
2572 const VkBufferCreateInfo vertexBufferParams =
2574 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2575 DE_NULL, // const void* pNext;
2576 0u, // VkBufferCreateFlags flags;
2577 attributeBatchSize * 2, // VkDeviceSize size;
2578 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
2579 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2580 1u, // deUint32 queueFamilyCount;
2581 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
2584 const std::vector<tcu::Vec4> colorData (positionData.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
2586 vertexBuffer = createBuffer(vkd, vkDevice, &vertexBufferParams);
2587 vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
2589 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
2591 // Load vertices into vertex buffer
2592 deMemcpy(vertexBufferMemory->getHostPtr(), positionData.data(), attributeBatchSize);
2593 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) + attributeBatchSize, colorData.data(), attributeBatchSize);
2594 flushMappedMemoryRange(vkd, vkDevice, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset(), vertexBufferParams.size);
2597 // Create Command Buffer
2598 commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2600 // Begin Command Buffer
2601 beginCommandBuffer(vkd, *commandBuffer);
2603 addImageTransitionBarrier(*commandBuffer, // VkCommandBuffer commandBuffer
2604 *m_image, // VkImage image
2605 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
2606 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
2607 0, // VkAccessFlags srcAccessMask
2608 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
2609 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
2610 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
2612 if (m_multisampling)
2614 addImageTransitionBarrier(*commandBuffer, // VkCommandBuffer commandBuffer
2615 *m_resolvedImage, // VkImage image
2616 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
2617 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
2618 0, // VkAccessFlags srcAccessMask
2619 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
2620 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
2621 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); // VkImageLayout newLayout;
2625 vkd.cmdResetQueryPool(*commandBuffer, *queryPool, 0u, 1u);
2627 // Begin render pass and start query
2628 beginRenderPass(vkd, *commandBuffer, *m_renderPass, *m_frameBuffer, vk::makeRect2D(0, 0, m_renderSize, m_renderSize), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
2629 vkd.cmdBeginQuery(*commandBuffer, *queryPool, 0u, (VkQueryControlFlags)0u);
2630 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
2631 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL);
2632 vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
2633 vkd.cmdDraw(*commandBuffer, (deUint32)positionData.size(), 1, 0, 0);
2634 endRenderPass(vkd, *commandBuffer);
2635 vkd.cmdEndQuery(*commandBuffer, *queryPool, 0u);
2639 const VkBufferMemoryBarrier bufferBarrier =
2641 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2642 DE_NULL, // const void* pNext;
2643 VK_ACCESS_TRANSFER_WRITE_BIT, // VkMemoryOutputFlags outputMask;
2644 VK_ACCESS_HOST_READ_BIT, // VkMemoryInputFlags inputMask;
2645 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2646 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
2647 *m_resultBuffer, // VkBuffer buffer;
2648 0u, // VkDeviceSize offset;
2649 m_resultBufferSize // VkDeviceSize size;
2652 const VkBufferImageCopy copyRegion =
2654 0u, // VkDeviceSize bufferOffset;
2655 m_renderSize, // deUint32 bufferRowLength;
2656 m_renderSize, // deUint32 bufferImageHeight;
2657 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u }, // VkImageSubresourceCopy imageSubresource;
2658 { 0, 0, 0 }, // VkOffset3D imageOffset;
2659 { m_renderSize, m_renderSize, 1u } // VkExtent3D imageExtent;
2662 addImageTransitionBarrier(*commandBuffer, // VkCommandBuffer commandBuffer
2663 m_multisampling ? *m_resolvedImage : *m_image, // VkImage image
2664 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
2665 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
2666 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
2667 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
2668 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
2669 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); // VkImageLayout newLayout;)
2671 if (m_multisampling)
2672 vkd.cmdCopyImageToBuffer(*commandBuffer, *m_resolvedImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, ©Region);
2674 vkd.cmdCopyImageToBuffer(*commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, ©Region);
2676 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);
2679 endCommandBuffer(vkd, *commandBuffer);
2683 float pointSize = getPointSize();
2685 deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize);
2686 flushMappedMemoryRange(vkd, vkDevice, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset(), m_uniformBufferSize);
2690 submitCommandsAndWait(vkd, vkDevice, queue, commandBuffer.get());
2692 invalidateMappedMemoryRange(vkd, vkDevice, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(), m_resultBufferSize);
2693 tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderSize, m_renderSize, 1), m_resultBufferMemory->getHostPtr()));
2696 class DiscardTestCase : public BaseRenderingTestCase
2699 DiscardTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkPrimitiveTopology primitiveTopology, deBool queryFragmentShaderInvocations, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2700 : BaseRenderingTestCase (context, name, description, sampleCount)
2701 , m_primitiveTopology (primitiveTopology)
2702 , m_queryFragmentShaderInvocations (queryFragmentShaderInvocations)
2705 virtual TestInstance* createInstance (Context& context) const
2707 if (m_queryFragmentShaderInvocations && !context.getDeviceFeatures().pipelineStatisticsQuery)
2708 throw tcu::NotSupportedError("Pipeline statistics queries are not supported");
2710 return new DiscardTestInstance (context, m_primitiveTopology, m_queryFragmentShaderInvocations);
2714 const VkPrimitiveTopology m_primitiveTopology;
2715 const deBool m_queryFragmentShaderInvocations;
2718 class TriangleInterpolationTestInstance : public BaseRenderingTestInstance
2722 TriangleInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount)
2723 : BaseRenderingTestInstance (context, sampleCount, DEFAULT_RENDER_SIZE)
2724 , m_primitiveTopology (primitiveTopology)
2725 , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
2726 , m_iterationCount (3)
2728 , m_allIterationsPassed (true)
2729 , m_flatshade ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2732 tcu::TestStatus iterate (void);
2736 void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
2737 void extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
2740 VkPrimitiveTopology m_primitiveTopology;
2741 const bool m_projective;
2742 const int m_iterationCount;
2744 bool m_allIterationsPassed;
2745 const deBool m_flatshade;
2748 tcu::TestStatus TriangleInterpolationTestInstance::iterate (void)
2750 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
2751 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
2752 tcu::Surface resultImage (m_renderSize, m_renderSize);
2753 std::vector<tcu::Vec4> drawBuffer;
2754 std::vector<tcu::Vec4> colorBuffer;
2755 std::vector<TriangleSceneSpec::SceneTriangle> triangles;
2758 generateVertices(m_iteration, drawBuffer, colorBuffer);
2759 extractTriangles(triangles, drawBuffer, colorBuffer);
2763 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
2764 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
2765 m_context.getTestContext().getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
2769 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitiveTopology);
2773 RasterizationArguments args;
2774 TriangleSceneSpec scene;
2775 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
2777 args.numSamples = m_multisampling ? 1 : 0;
2778 args.subpixelBits = m_subpixelBits;
2779 args.redBits = colorBits[0];
2780 args.greenBits = colorBits[1];
2781 args.blueBits = colorBits[2];
2783 scene.triangles.swap(triangles);
2785 if (!verifyTriangleGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog()))
2786 m_allIterationsPassed = false;
2790 if (++m_iteration == m_iterationCount)
2792 if (m_allIterationsPassed)
2793 return tcu::TestStatus::pass("Pass");
2795 return tcu::TestStatus::fail("Found invalid pixel values");
2798 return tcu::TestStatus::incomplete();
2801 void TriangleInterpolationTestInstance::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
2803 // use only red, green and blue
2804 const tcu::Vec4 colors[] =
2806 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
2807 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
2808 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
2811 de::Random rnd(123 + iteration * 1000 + (int)m_primitiveTopology);
2813 outVertices.resize(6);
2814 outColors.resize(6);
2816 for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
2818 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
2819 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
2820 outVertices[vtxNdx].z() = 0.0f;
2823 outVertices[vtxNdx].w() = 1.0f;
2826 const float w = rnd.getFloat(0.2f, 4.0f);
2828 outVertices[vtxNdx].x() *= w;
2829 outVertices[vtxNdx].y() *= w;
2830 outVertices[vtxNdx].z() *= w;
2831 outVertices[vtxNdx].w() = w;
2834 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
2838 void TriangleInterpolationTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
2840 switch (m_primitiveTopology)
2842 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
2844 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
2846 TriangleSceneSpec::SceneTriangle tri;
2847 tri.positions[0] = vertices[vtxNdx + 0];
2848 tri.positions[1] = vertices[vtxNdx + 1];
2849 tri.positions[2] = vertices[vtxNdx + 2];
2850 tri.sharedEdge[0] = false;
2851 tri.sharedEdge[1] = false;
2852 tri.sharedEdge[2] = false;
2856 tri.colors[0] = colors[vtxNdx];
2857 tri.colors[1] = colors[vtxNdx];
2858 tri.colors[2] = colors[vtxNdx];
2862 tri.colors[0] = colors[vtxNdx + 0];
2863 tri.colors[1] = colors[vtxNdx + 1];
2864 tri.colors[2] = colors[vtxNdx + 2];
2867 outTriangles.push_back(tri);
2872 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
2874 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
2876 TriangleSceneSpec::SceneTriangle tri;
2877 tri.positions[0] = vertices[vtxNdx + 0];
2878 tri.positions[1] = vertices[vtxNdx + 1];
2879 tri.positions[2] = vertices[vtxNdx + 2];
2880 tri.sharedEdge[0] = false;
2881 tri.sharedEdge[1] = false;
2882 tri.sharedEdge[2] = false;
2886 tri.colors[0] = colors[vtxNdx];
2887 tri.colors[1] = colors[vtxNdx];
2888 tri.colors[2] = colors[vtxNdx];
2892 tri.colors[0] = colors[vtxNdx + 0];
2893 tri.colors[1] = colors[vtxNdx + 1];
2894 tri.colors[2] = colors[vtxNdx + 2];
2897 outTriangles.push_back(tri);
2902 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
2904 for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2906 TriangleSceneSpec::SceneTriangle tri;
2907 tri.positions[0] = vertices[0];
2908 tri.positions[1] = vertices[vtxNdx + 0];
2909 tri.positions[2] = vertices[vtxNdx + 1];
2910 tri.sharedEdge[0] = false;
2911 tri.sharedEdge[1] = false;
2912 tri.sharedEdge[2] = false;
2916 tri.colors[0] = colors[vtxNdx];
2917 tri.colors[1] = colors[vtxNdx];
2918 tri.colors[2] = colors[vtxNdx];
2922 tri.colors[0] = colors[0];
2923 tri.colors[1] = colors[vtxNdx + 0];
2924 tri.colors[2] = colors[vtxNdx + 1];
2927 outTriangles.push_back(tri);
2937 class TriangleInterpolationTestCase : public BaseRenderingTestCase
2940 TriangleInterpolationTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2941 : BaseRenderingTestCase (context, name, description, sampleCount, (flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2942 , m_primitiveTopology (primitiveTopology)
2946 virtual TestInstance* createInstance (Context& context) const
2948 return new TriangleInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_sampleCount);
2951 const VkPrimitiveTopology m_primitiveTopology;
2955 class LineInterpolationTestInstance : public BaseRenderingTestInstance
2958 LineInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount);
2960 virtual tcu::TestStatus iterate (void);
2963 void generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
2964 void extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
2965 virtual float getLineWidth (void) const;
2967 VkPrimitiveTopology m_primitiveTopology;
2968 const bool m_projective;
2969 const int m_iterationCount;
2970 const PrimitiveWideness m_primitiveWideness;
2973 bool m_allIterationsPassed;
2974 float m_maxLineWidth;
2975 std::vector<float> m_lineWidths;
2979 LineInterpolationTestInstance::LineInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
2980 : BaseRenderingTestInstance (context, sampleCount)
2981 , m_primitiveTopology (primitiveTopology)
2982 , m_projective ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
2983 , m_iterationCount (3)
2984 , m_primitiveWideness (wideness)
2986 , m_allIterationsPassed (true)
2987 , m_maxLineWidth (1.0f)
2988 , m_flatshade ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2990 DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
2992 if (!context.getDeviceProperties().limits.strictLines)
2993 TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
2995 // create line widths
2996 if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
2998 m_lineWidths.resize(m_iterationCount, 1.0f);
3000 else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
3002 if (!m_context.getDeviceFeatures().wideLines)
3003 TCU_THROW(NotSupportedError , "wide line support required");
3005 const float* range = context.getDeviceProperties().limits.lineWidthRange;
3007 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
3009 // no wide line support
3010 if (range[1] <= 1.0f)
3011 throw tcu::NotSupportedError("wide line support required");
3013 // set hand picked sizes
3014 m_lineWidths.push_back(5.0f);
3015 m_lineWidths.push_back(10.0f);
3016 m_lineWidths.push_back(range[1]);
3017 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
3019 m_maxLineWidth = range[1];
3025 tcu::TestStatus LineInterpolationTestInstance::iterate (void)
3027 const std::string iterationDescription = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
3028 const tcu::ScopedLogSection section (m_context.getTestContext().getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
3029 const float lineWidth = getLineWidth();
3030 tcu::Surface resultImage (m_renderSize, m_renderSize);
3031 std::vector<tcu::Vec4> drawBuffer;
3032 std::vector<tcu::Vec4> colorBuffer;
3033 std::vector<LineSceneSpec::SceneLine> lines;
3036 if (lineWidth <= m_maxLineWidth)
3039 generateVertices(m_iteration, drawBuffer, colorBuffer);
3040 extractLines(lines, drawBuffer, colorBuffer);
3044 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
3045 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
3046 m_context.getTestContext().getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
3050 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitiveTopology);
3054 RasterizationArguments args;
3055 LineSceneSpec scene;
3057 tcu::IVec4 colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
3059 args.numSamples = m_multisampling ? 1 : 0;
3060 args.subpixelBits = m_subpixelBits;
3061 args.redBits = colorBits[0];
3062 args.greenBits = colorBits[1];
3063 args.blueBits = colorBits[2];
3065 scene.lines.swap(lines);
3066 scene.lineWidth = getLineWidth();
3068 if (!verifyTriangulatedLineGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog()))
3069 m_allIterationsPassed = false;
3073 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
3076 if (++m_iteration == m_iterationCount)
3078 if (m_allIterationsPassed)
3079 return tcu::TestStatus::pass("Pass");
3081 return tcu::TestStatus::fail("Incorrect rasterization");
3084 return tcu::TestStatus::incomplete();
3087 void LineInterpolationTestInstance::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
3089 // use only red, green and blue
3090 const tcu::Vec4 colors[] =
3092 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
3093 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
3094 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
3097 de::Random rnd(123 + iteration * 1000 + (int)m_primitiveTopology);
3099 outVertices.resize(6);
3100 outColors.resize(6);
3102 for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
3104 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
3105 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
3106 outVertices[vtxNdx].z() = 0.0f;
3109 outVertices[vtxNdx].w() = 1.0f;
3112 const float w = rnd.getFloat(0.2f, 4.0f);
3114 outVertices[vtxNdx].x() *= w;
3115 outVertices[vtxNdx].y() *= w;
3116 outVertices[vtxNdx].z() *= w;
3117 outVertices[vtxNdx].w() = w;
3120 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
3124 void LineInterpolationTestInstance::extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
3126 switch (m_primitiveTopology)
3128 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
3130 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; vtxNdx += 2)
3132 LineSceneSpec::SceneLine line;
3133 line.positions[0] = vertices[vtxNdx + 0];
3134 line.positions[1] = vertices[vtxNdx + 1];
3138 line.colors[0] = colors[vtxNdx];
3139 line.colors[1] = colors[vtxNdx];
3143 line.colors[0] = colors[vtxNdx + 0];
3144 line.colors[1] = colors[vtxNdx + 1];
3147 outLines.push_back(line);
3152 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
3154 for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
3156 LineSceneSpec::SceneLine line;
3157 line.positions[0] = vertices[vtxNdx + 0];
3158 line.positions[1] = vertices[vtxNdx + 1];
3162 line.colors[0] = colors[vtxNdx];
3163 line.colors[1] = colors[vtxNdx];
3167 line.colors[0] = colors[vtxNdx + 0];
3168 line.colors[1] = colors[vtxNdx + 1];
3171 outLines.push_back(line);
3181 float LineInterpolationTestInstance::getLineWidth (void) const
3183 return m_lineWidths[m_iteration];
3186 class LineInterpolationTestCase : public BaseRenderingTestCase
3189 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)
3190 : BaseRenderingTestCase (context, name, description, sampleCount, (flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
3191 , m_primitiveTopology (primitiveTopology)
3193 , m_wideness (wideness)
3196 virtual TestInstance* createInstance (Context& context) const
3198 return new LineInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_wideness, m_sampleCount);
3201 const VkPrimitiveTopology m_primitiveTopology;
3203 const PrimitiveWideness m_wideness;
3206 void createRasterizationTests (tcu::TestCaseGroup* rasterizationTests)
3208 tcu::TestContext& testCtx = rasterizationTests->getTestContext();
3212 tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(testCtx, "primitives", "Primitive rasterization");
3214 rasterizationTests->addChild(primitives);
3216 primitives->addChild(new BaseTestCase<TrianglesTestInstance> (testCtx, "triangles", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result"));
3217 primitives->addChild(new BaseTestCase<TriangleStripTestInstance> (testCtx, "triangle_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, verify rasterization result"));
3218 primitives->addChild(new BaseTestCase<TriangleFanTestInstance> (testCtx, "triangle_fan", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, verify rasterization result"));
3219 primitives->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW));
3220 primitives->addChild(new WidenessTestCase<LineStripTestInstance> (testCtx, "line_strip", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result", PRIMITIVEWIDENESS_NARROW));
3221 primitives->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines_wide", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
3222 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));
3223 primitives->addChild(new WidenessTestCase<PointTestInstance> (testCtx, "points", "Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result", PRIMITIVEWIDENESS_WIDE));
3228 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(testCtx, "fill_rules", "Primitive fill rules");
3230 rasterizationTests->addChild(fillRules);
3232 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_BASIC));
3233 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad_reverse", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_REVERSED));
3234 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_full", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_FULL));
3235 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_partly", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_PARTIAL));
3236 fillRules->addChild(new FillRuleTestCase(testCtx, "projected", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_PROJECTED));
3241 static const struct CullMode
3243 VkCullModeFlags mode;
3247 { VK_CULL_MODE_FRONT_BIT, "front_" },
3248 { VK_CULL_MODE_BACK_BIT, "back_" },
3249 { VK_CULL_MODE_FRONT_AND_BACK, "both_" },
3251 static const struct PrimitiveType
3253 VkPrimitiveTopology type;
3255 } primitiveTypes[] =
3257 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangles" },
3258 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, "triangle_strip" },
3259 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, "triangle_fan" },
3261 static const struct FrontFaceOrder
3264 const char* postfix;
3267 { VK_FRONT_FACE_COUNTER_CLOCKWISE, "" },
3268 { VK_FRONT_FACE_CLOCKWISE, "_reverse" },
3271 static const struct PolygonMode
3277 { VK_POLYGON_MODE_FILL, "" },
3278 { VK_POLYGON_MODE_LINE, "_line" },
3279 { VK_POLYGON_MODE_POINT, "_point" }
3282 tcu::TestCaseGroup* const culling = new tcu::TestCaseGroup(testCtx, "culling", "Culling");
3284 rasterizationTests->addChild(culling);
3286 for (int cullModeNdx = 0; cullModeNdx < DE_LENGTH_OF_ARRAY(cullModes); ++cullModeNdx)
3287 for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveNdx)
3288 for (int frontOrderNdx = 0; frontOrderNdx < DE_LENGTH_OF_ARRAY(frontOrders); ++frontOrderNdx)
3289 for (int polygonModeNdx = 0; polygonModeNdx < DE_LENGTH_OF_ARRAY(polygonModes); ++polygonModeNdx)
3291 if (!(cullModes[cullModeNdx].mode == VK_CULL_MODE_FRONT_AND_BACK && polygonModes[polygonModeNdx].mode != VK_POLYGON_MODE_FILL))
3293 const std::string name = std::string(cullModes[cullModeNdx].prefix) + primitiveTypes[primitiveNdx].name + frontOrders[frontOrderNdx].postfix + polygonModes[polygonModeNdx].name;
3294 culling->addChild(new CullingTestCase(testCtx, name, "Test primitive culling.", cullModes[cullModeNdx].mode, primitiveTypes[primitiveNdx].type, frontOrders[frontOrderNdx].mode, polygonModes[polygonModeNdx].mode));
3301 static const struct PrimitiveType
3303 VkPrimitiveTopology type;
3305 } primitiveTypes[] =
3307 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangle_list" },
3308 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, "triangle_strip" },
3309 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, "triangle_fan" },
3310 { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, "line_list" },
3311 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, "line_strip" },
3312 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, "point_list" }
3315 static const struct queryPipeline
3321 { DE_FALSE, "query_pipeline_false" },
3322 { DE_TRUE, "query_pipeline_true" },
3325 tcu::TestCaseGroup* const discard = new tcu::TestCaseGroup(testCtx, "discard", "Rasterizer discard");
3327 for (int primitiveNdx = 0; primitiveNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveNdx)
3329 tcu::TestCaseGroup* const primitive = new tcu::TestCaseGroup(testCtx, primitiveTypes[primitiveNdx].name, "Rasterizer discard");
3331 for (int useQueryNdx = 0; useQueryNdx < DE_LENGTH_OF_ARRAY(queryPipeline); useQueryNdx++)
3333 const std::string name = std::string(queryPipeline[useQueryNdx].name);
3335 primitive->addChild(new DiscardTestCase(testCtx, name, "Test primitive discarding.", primitiveTypes[primitiveNdx].type, queryPipeline[useQueryNdx].useQuery));
3338 discard->addChild(primitive);
3341 rasterizationTests->addChild(discard);
3346 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(testCtx, "interpolation", "Test interpolation");
3348 rasterizationTests->addChild(interpolation);
3352 tcu::TestCaseGroup* const basic = new tcu::TestCaseGroup(testCtx, "basic", "Non-projective interpolation");
3354 interpolation->addChild(basic);
3356 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_NONE));
3357 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_NONE));
3358 basic->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_NONE));
3359 basic->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW));
3360 basic->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW));
3361 basic->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE));
3362 basic->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE));
3367 tcu::TestCaseGroup* const projected = new tcu::TestCaseGroup(testCtx, "projected", "Projective interpolation");
3369 interpolation->addChild(projected);
3371 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_PROJECTED));
3372 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_PROJECTED));
3373 projected->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_PROJECTED));
3374 projected->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW));
3375 projected->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_NARROW));
3376 projected->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE));
3377 projected->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_PROJECTED, PRIMITIVEWIDENESS_WIDE));
3383 tcu::TestCaseGroup* const flatshading = new tcu::TestCaseGroup(testCtx, "flatshading", "Test flatshading");
3385 rasterizationTests->addChild(flatshading);
3387 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_FLATSHADE));
3388 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_strip", "Verify triangle strip flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, INTERPOLATIONFLAGS_FLATSHADE));
3389 flatshading->addChild(new TriangleInterpolationTestCase (testCtx, "triangle_fan", "Verify triangle fan flatshading", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, INTERPOLATIONFLAGS_FLATSHADE));
3390 flatshading->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW));
3391 flatshading->addChild(new LineInterpolationTestCase (testCtx, "line_strip", "Verify line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_NARROW));
3392 flatshading->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE));
3393 flatshading->addChild(new LineInterpolationTestCase (testCtx, "line_strip_wide","Verify wide line strip flatshading", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, INTERPOLATIONFLAGS_FLATSHADE, PRIMITIVEWIDENESS_WIDE));
3396 const VkSampleCountFlagBits samples[] =
3398 VK_SAMPLE_COUNT_2_BIT,
3399 VK_SAMPLE_COUNT_4_BIT,
3400 VK_SAMPLE_COUNT_8_BIT,
3401 VK_SAMPLE_COUNT_16_BIT,
3402 VK_SAMPLE_COUNT_32_BIT,
3403 VK_SAMPLE_COUNT_64_BIT
3406 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
3408 std::ostringstream caseName;
3410 caseName << "_multisample_" << (2 << samplesNdx) << "_bit";
3414 tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(testCtx, ("primitives" + caseName.str()).c_str(), "Primitive rasterization");
3416 rasterizationTests->addChild(primitives);
3418 primitives->addChild(new BaseTestCase<TrianglesTestInstance> (testCtx, "triangles", "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result", samples[samplesNdx]));
3419 primitives->addChild(new WidenessTestCase<LinesTestInstance> (testCtx, "lines", "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result", PRIMITIVEWIDENESS_NARROW, samples[samplesNdx]));
3420 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]));
3421 primitives->addChild(new WidenessTestCase<PointTestInstance> (testCtx, "points", "Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result", PRIMITIVEWIDENESS_WIDE, samples[samplesNdx]));
3426 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(testCtx, ("fill_rules" + caseName.str()).c_str(), "Primitive fill rules");
3428 rasterizationTests->addChild(fillRules);
3430 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_BASIC, samples[samplesNdx]));
3431 fillRules->addChild(new FillRuleTestCase(testCtx, "basic_quad_reverse", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_REVERSED, samples[samplesNdx]));
3432 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_full", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_FULL, samples[samplesNdx]));
3433 fillRules->addChild(new FillRuleTestCase(testCtx, "clipped_partly", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_CLIPPED_PARTIAL, samples[samplesNdx]));
3434 fillRules->addChild(new FillRuleTestCase(testCtx, "projected", "Verify fill rules", FillRuleTestInstance::FILLRULECASE_PROJECTED, samples[samplesNdx]));
3439 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(testCtx, ("interpolation" + caseName.str()).c_str(), "Test interpolation");
3441 rasterizationTests->addChild(interpolation);
3443 interpolation->addChild(new TriangleInterpolationTestCase (testCtx, "triangles", "Verify triangle interpolation", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, INTERPOLATIONFLAGS_NONE, samples[samplesNdx]));
3444 interpolation->addChild(new LineInterpolationTestCase (testCtx, "lines", "Verify line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_NARROW, samples[samplesNdx]));
3445 interpolation->addChild(new LineInterpolationTestCase (testCtx, "lines_wide", "Verify wide line interpolation", VK_PRIMITIVE_TOPOLOGY_LINE_LIST, INTERPOLATIONFLAGS_NONE, PRIMITIVEWIDENESS_WIDE, samples[samplesNdx]));
3452 tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
3454 return createTestGroup(testCtx, "rasterization", "Rasterization Tests", createRasterizationTests);