1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2014 The Android Open Source Project
6 * Copyright (c) 2016 The Khronos Group Inc.
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 * \brief Tessellation Utilities
23 *//*--------------------------------------------------------------------*/
25 #include "vktTessellationUtil.hpp"
26 #include "vkTypeUtil.hpp"
31 namespace tessellation
36 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize,
37 const VkBufferUsageFlags usage)
39 const VkBufferCreateInfo bufferCreateInfo =
41 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
42 DE_NULL, // const void* pNext;
43 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags;
44 bufferSize, // VkDeviceSize size;
45 usage, // VkBufferUsageFlags usage;
46 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
47 0u, // deUint32 queueFamilyIndexCount;
48 DE_NULL, // const deUint32* pQueueFamilyIndices;
50 return bufferCreateInfo;
53 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags srcAccessMask,
54 const VkAccessFlags dstAccessMask,
55 const VkBuffer buffer,
56 const VkDeviceSize offset,
57 const VkDeviceSize bufferSizeBytes)
59 const VkBufferMemoryBarrier barrier =
61 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
62 DE_NULL, // const void* pNext;
63 srcAccessMask, // VkAccessFlags srcAccessMask;
64 dstAccessMask, // VkAccessFlags dstAccessMask;
65 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
66 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
67 buffer, // VkBuffer buffer;
68 offset, // VkDeviceSize offset;
69 bufferSizeBytes, // VkDeviceSize size;
74 VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask,
75 const VkAccessFlags dstAccessMask,
76 const VkImageLayout oldLayout,
77 const VkImageLayout newLayout,
79 const VkImageSubresourceRange subresourceRange)
81 const VkImageMemoryBarrier barrier =
83 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
84 DE_NULL, // const void* pNext;
85 srcAccessMask, // VkAccessFlags outputMask;
86 dstAccessMask, // VkAccessFlags inputMask;
87 oldLayout, // VkImageLayout oldLayout;
88 newLayout, // VkImageLayout newLayout;
89 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
90 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
91 image, // VkImage image;
92 subresourceRange, // VkImageSubresourceRange subresourceRange;
97 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
99 const VkCommandPoolCreateInfo info =
101 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
102 DE_NULL, // const void* pNext;
103 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags;
104 queueFamilyIndex, // deUint32 queueFamilyIndex;
106 return createCommandPool(vk, device, &info);
110 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk,
111 const VkDevice device,
112 const VkDescriptorPool descriptorPool,
113 const VkDescriptorSetLayout setLayout)
115 const VkDescriptorSetAllocateInfo info =
117 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
118 DE_NULL, // const void* pNext;
119 descriptorPool, // VkDescriptorPool descriptorPool;
120 1u, // deUint32 descriptorSetCount;
121 &setLayout, // const VkDescriptorSetLayout* pSetLayouts;
123 return allocateDescriptorSet(vk, device, &info);
126 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk,
127 const VkDevice device,
128 const VkDescriptorSetLayout descriptorSetLayout)
130 const VkPipelineLayoutCreateInfo info =
132 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
133 DE_NULL, // const void* pNext;
134 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
135 1u, // deUint32 setLayoutCount;
136 &descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
137 0u, // deUint32 pushConstantRangeCount;
138 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
140 return createPipelineLayout(vk, device, &info);
143 Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface& vk,
144 const VkDevice device)
146 const VkPipelineLayoutCreateInfo info =
148 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
149 DE_NULL, // const void* pNext;
150 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
151 0u, // deUint32 setLayoutCount;
152 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
153 0u, // deUint32 pushConstantRangeCount;
154 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
156 return createPipelineLayout(vk, device, &info);
159 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
160 const VkDevice device,
161 const VkPipelineLayout pipelineLayout,
162 const VkShaderModule shaderModule,
163 const VkSpecializationInfo* specInfo)
165 const VkPipelineShaderStageCreateInfo shaderStageInfo =
167 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
168 DE_NULL, // const void* pNext;
169 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
170 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
171 shaderModule, // VkShaderModule module;
172 "main", // const char* pName;
173 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
175 const VkComputePipelineCreateInfo pipelineInfo =
177 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
178 DE_NULL, // const void* pNext;
179 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
180 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage;
181 pipelineLayout, // VkPipelineLayout layout;
182 DE_NULL, // VkPipeline basePipelineHandle;
183 0, // deInt32 basePipelineIndex;
185 return createComputePipeline(vk, device, DE_NULL , &pipelineInfo);
188 VkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& size, const VkFormat format, const VkImageUsageFlags usage, const deUint32 numArrayLayers)
190 const VkImageCreateInfo imageInfo =
192 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
193 DE_NULL, // const void* pNext;
194 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
195 VK_IMAGE_TYPE_2D, // VkImageType imageType;
196 format, // VkFormat format;
197 makeExtent3D(size.x(), size.y(), 1), // VkExtent3D extent;
198 1u, // uint32_t mipLevels;
199 numArrayLayers, // uint32_t arrayLayers;
200 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
201 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
202 usage, // VkImageUsageFlags usage;
203 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
204 0u, // uint32_t queueFamilyIndexCount;
205 DE_NULL, // const uint32_t* pQueueFamilyIndices;
206 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
211 Move<VkImageView> makeImageView (const DeviceInterface& vk,
212 const VkDevice vkDevice,
214 const VkImageViewType viewType,
215 const VkFormat format,
216 const VkImageSubresourceRange subresourceRange)
218 const VkImageViewCreateInfo imageViewParams =
220 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
221 DE_NULL, // const void* pNext;
222 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags;
223 image, // VkImage image;
224 viewType, // VkImageViewType viewType;
225 format, // VkFormat format;
226 makeComponentMappingRGBA(), // VkComponentMapping components;
227 subresourceRange, // VkImageSubresourceRange subresourceRange;
229 return createImageView(vk, vkDevice, &imageViewParams);
232 VkBufferImageCopy makeBufferImageCopy (const VkExtent3D extent,
233 const VkImageSubresourceLayers subresourceLayers)
235 const VkBufferImageCopy copyParams =
237 0ull, // VkDeviceSize bufferOffset;
238 0u, // deUint32 bufferRowLength;
239 0u, // deUint32 bufferImageHeight;
240 subresourceLayers, // VkImageSubresourceLayers imageSubresource;
241 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
242 extent, // VkExtent3D imageExtent;
247 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
249 const VkCommandBufferBeginInfo info =
251 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
252 DE_NULL, // const void* pNext;
253 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
254 DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
256 VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
259 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
261 VK_CHECK(vk.endCommandBuffer(commandBuffer));
264 void submitCommandsAndWait (const DeviceInterface& vk,
265 const VkDevice device,
267 const VkCommandBuffer commandBuffer)
269 const Unique<VkFence> fence(createFence(vk, device));
271 const VkSubmitInfo submitInfo =
273 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
274 DE_NULL, // const void* pNext;
275 0u, // uint32_t waitSemaphoreCount;
276 DE_NULL, // const VkSemaphore* pWaitSemaphores;
277 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
278 1u, // uint32_t commandBufferCount;
279 &commandBuffer, // const VkCommandBuffer* pCommandBuffers;
280 0u, // uint32_t signalSemaphoreCount;
281 DE_NULL, // const VkSemaphore* pSignalSemaphores;
283 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
284 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
287 void beginRenderPass (const DeviceInterface& vk,
288 const VkCommandBuffer commandBuffer,
289 const VkRenderPass renderPass,
290 const VkFramebuffer framebuffer,
291 const VkRect2D& renderArea,
292 const tcu::Vec4& clearColor)
294 const VkClearValue clearValue = makeClearValueColor(clearColor);
296 const VkRenderPassBeginInfo renderPassBeginInfo = {
297 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
298 DE_NULL, // const void* pNext;
299 renderPass, // VkRenderPass renderPass;
300 framebuffer, // VkFramebuffer framebuffer;
301 renderArea, // VkRect2D renderArea;
302 1u, // uint32_t clearValueCount;
303 &clearValue, // const VkClearValue* pClearValues;
306 vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
309 void beginRenderPassWithRasterizationDisabled (const DeviceInterface& vk,
310 const VkCommandBuffer commandBuffer,
311 const VkRenderPass renderPass,
312 const VkFramebuffer framebuffer)
314 const VkRect2D renderArea = {{ 0, 0 }, { 0, 0 }};
316 const VkRenderPassBeginInfo renderPassBeginInfo = {
317 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
318 DE_NULL, // const void* pNext;
319 renderPass, // VkRenderPass renderPass;
320 framebuffer, // VkFramebuffer framebuffer;
321 renderArea, // VkRect2D renderArea;
322 0u, // uint32_t clearValueCount;
323 DE_NULL, // const VkClearValue* pClearValues;
326 vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
329 void endRenderPass (const DeviceInterface& vk,
330 const VkCommandBuffer commandBuffer)
332 vk.cmdEndRenderPass(commandBuffer);
335 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
336 const VkDevice device,
337 const VkFormat colorFormat)
339 const VkAttachmentDescription colorAttachmentDescription =
341 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
342 colorFormat, // VkFormat format;
343 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
344 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
345 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
346 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
347 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
348 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
349 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
352 const VkAttachmentReference colorAttachmentReference =
354 0u, // deUint32 attachment;
355 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
358 const VkAttachmentReference depthAttachmentReference =
360 VK_ATTACHMENT_UNUSED, // deUint32 attachment;
361 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout;
364 const VkSubpassDescription subpassDescription =
366 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
367 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
368 0u, // deUint32 inputAttachmentCount;
369 DE_NULL, // const VkAttachmentReference* pInputAttachments;
370 1u, // deUint32 colorAttachmentCount;
371 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
372 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
373 &depthAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment;
374 0u, // deUint32 preserveAttachmentCount;
375 DE_NULL // const deUint32* pPreserveAttachments;
378 const VkRenderPassCreateInfo renderPassInfo =
380 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
381 DE_NULL, // const void* pNext;
382 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
383 1u, // deUint32 attachmentCount;
384 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments;
385 1u, // deUint32 subpassCount;
386 &subpassDescription, // const VkSubpassDescription* pSubpasses;
387 0u, // deUint32 dependencyCount;
388 DE_NULL // const VkSubpassDependency* pDependencies;
391 return createRenderPass(vk, device, &renderPassInfo);
394 Move<VkRenderPass> makeRenderPassWithoutAttachments (const DeviceInterface& vk,
395 const VkDevice device)
397 const VkAttachmentReference unusedAttachment =
399 VK_ATTACHMENT_UNUSED, // deUint32 attachment;
400 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout;
403 const VkSubpassDescription subpassDescription =
405 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
406 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
407 0u, // deUint32 inputAttachmentCount;
408 DE_NULL, // const VkAttachmentReference* pInputAttachments;
409 0u, // deUint32 colorAttachmentCount;
410 DE_NULL, // const VkAttachmentReference* pColorAttachments;
411 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
412 &unusedAttachment, // const VkAttachmentReference* pDepthStencilAttachment;
413 0u, // deUint32 preserveAttachmentCount;
414 DE_NULL // const deUint32* pPreserveAttachments;
417 const VkRenderPassCreateInfo renderPassInfo =
419 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
420 DE_NULL, // const void* pNext;
421 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
422 0u, // deUint32 attachmentCount;
423 DE_NULL, // const VkAttachmentDescription* pAttachments;
424 1u, // deUint32 subpassCount;
425 &subpassDescription, // const VkSubpassDescription* pSubpasses;
426 0u, // deUint32 dependencyCount;
427 DE_NULL // const VkSubpassDependency* pDependencies;
430 return createRenderPass(vk, device, &renderPassInfo);
433 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk,
434 const VkDevice device,
435 const VkRenderPass renderPass,
436 const VkImageView colorAttachment,
437 const deUint32 width,
438 const deUint32 height,
439 const deUint32 layers)
441 const VkFramebufferCreateInfo framebufferInfo = {
442 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
443 DE_NULL, // const void* pNext;
444 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
445 renderPass, // VkRenderPass renderPass;
446 1u, // uint32_t attachmentCount;
447 &colorAttachment, // const VkImageView* pAttachments;
448 width, // uint32_t width;
449 height, // uint32_t height;
450 layers, // uint32_t layers;
453 return createFramebuffer(vk, device, &framebufferInfo);
456 Move<VkFramebuffer> makeFramebufferWithoutAttachments (const DeviceInterface& vk,
457 const VkDevice device,
458 const VkRenderPass renderPass)
460 const VkFramebufferCreateInfo framebufferInfo = {
461 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
462 DE_NULL, // const void* pNext;
463 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
464 renderPass, // VkRenderPass renderPass;
465 0u, // uint32_t attachmentCount;
466 DE_NULL, // const VkImageView* pAttachments;
467 1u, // uint32_t width;
468 1u, // uint32_t height;
469 1u, // uint32_t layers;
472 return createFramebuffer(vk, device, &framebufferInfo);
475 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface& vk,
476 const VkDevice device,
477 const VkShaderStageFlagBits stage,
478 const ProgramBinary& binary,
479 const VkSpecializationInfo* specInfo)
481 VkShaderModule module;
484 case (VK_SHADER_STAGE_VERTEX_BIT):
485 DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
486 m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
487 module = *m_vertexShaderModule;
490 case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
491 DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
492 m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
493 module = *m_tessControlShaderModule;
496 case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
497 DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
498 m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
499 module = *m_tessEvaluationShaderModule;
502 case (VK_SHADER_STAGE_GEOMETRY_BIT):
503 DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
504 m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
505 module = *m_geometryShaderModule;
508 case (VK_SHADER_STAGE_FRAGMENT_BIT):
509 DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
510 m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
511 module = *m_fragmentShaderModule;
515 DE_FATAL("Invalid shader stage");
519 const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
521 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
522 DE_NULL, // const void* pNext;
523 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
524 stage, // VkShaderStageFlagBits stage;
525 module, // VkShaderModule module;
526 "main", // const char* pName;
527 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
530 m_shaderStageFlags |= stage;
531 m_shaderStages.push_back(pipelineShaderStageInfo);
536 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride)
538 const VkVertexInputBindingDescription bindingDesc =
540 0u, // uint32_t binding;
541 stride, // uint32_t stride;
542 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
544 const VkVertexInputAttributeDescription attributeDesc =
546 0u, // uint32_t location;
547 0u, // uint32_t binding;
548 vertexFormat, // VkFormat format;
549 0u, // uint32_t offset;
552 m_vertexInputBindings.clear();
553 m_vertexInputBindings.push_back(bindingDesc);
555 m_vertexInputAttributes.clear();
556 m_vertexInputAttributes.push_back(attributeDesc);
562 inline const T* dataPointer (const std::vector<T>& vec)
564 return (vec.size() != 0 ? &vec[0] : DE_NULL);
567 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface& vk,
568 const VkDevice device,
569 const VkPipelineLayout pipelineLayout,
570 const VkRenderPass renderPass)
572 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
574 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
575 DE_NULL, // const void* pNext;
576 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
577 static_cast<deUint32>(m_vertexInputBindings.size()), // uint32_t vertexBindingDescriptionCount;
578 dataPointer(m_vertexInputBindings), // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
579 static_cast<deUint32>(m_vertexInputAttributes.size()), // uint32_t vertexAttributeDescriptionCount;
580 dataPointer(m_vertexInputAttributes), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
583 const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
584 : m_primitiveTopology;
585 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
587 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
588 DE_NULL, // const void* pNext;
589 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
590 topology, // VkPrimitiveTopology topology;
591 VK_FALSE, // VkBool32 primitiveRestartEnable;
594 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
596 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
597 DE_NULL, // const void* pNext;
598 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
599 m_patchControlPoints, // uint32_t patchControlPoints;
602 const VkViewport viewport = makeViewport(
604 static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()),
607 const VkRect2D scissor = {
609 makeExtent2D(m_renderSize.x(), m_renderSize.y()),
612 const bool haveRenderSize = m_renderSize.x() > 0 && m_renderSize.y() > 0;
614 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
616 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
617 DE_NULL, // const void* pNext;
618 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
619 1u, // uint32_t viewportCount;
620 haveRenderSize ? &viewport : DE_NULL, // const VkViewport* pViewports;
621 1u, // uint32_t scissorCount;
622 haveRenderSize ? &scissor : DE_NULL, // const VkRect2D* pScissors;
625 const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0);
626 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
628 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
629 DE_NULL, // const void* pNext;
630 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
631 VK_FALSE, // VkBool32 depthClampEnable;
632 isRasterizationDisabled, // VkBool32 rasterizerDiscardEnable;
633 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
634 m_cullModeFlags, // VkCullModeFlags cullMode;
635 m_frontFace, // VkFrontFace frontFace;
636 VK_FALSE, // VkBool32 depthBiasEnable;
637 0.0f, // float depthBiasConstantFactor;
638 0.0f, // float depthBiasClamp;
639 0.0f, // float depthBiasSlopeFactor;
640 1.0f, // float lineWidth;
643 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
645 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
646 DE_NULL, // const void* pNext;
647 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
648 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
649 VK_FALSE, // VkBool32 sampleShadingEnable;
650 0.0f, // float minSampleShading;
651 DE_NULL, // const VkSampleMask* pSampleMask;
652 VK_FALSE, // VkBool32 alphaToCoverageEnable;
653 VK_FALSE // VkBool32 alphaToOneEnable;
656 const VkStencilOpState stencilOpState = makeStencilOpState(
657 VK_STENCIL_OP_KEEP, // stencil fail
658 VK_STENCIL_OP_KEEP, // depth & stencil pass
659 VK_STENCIL_OP_KEEP, // depth only fail
660 VK_COMPARE_OP_NEVER, // compare op
665 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
667 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
668 DE_NULL, // const void* pNext;
669 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
670 VK_FALSE, // VkBool32 depthTestEnable;
671 VK_FALSE, // VkBool32 depthWriteEnable;
672 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
673 VK_FALSE, // VkBool32 depthBoundsTestEnable;
674 VK_FALSE, // VkBool32 stencilTestEnable;
675 stencilOpState, // VkStencilOpState front;
676 stencilOpState, // VkStencilOpState back;
677 0.0f, // float minDepthBounds;
678 1.0f, // float maxDepthBounds;
681 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
682 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
684 m_blendEnable, // VkBool32 blendEnable;
685 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
686 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor;
687 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
688 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
689 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor;
690 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
691 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
694 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
696 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
697 DE_NULL, // const void* pNext;
698 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
699 VK_FALSE, // VkBool32 logicOpEnable;
700 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
701 1u, // deUint32 attachmentCount;
702 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
703 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
706 std::vector<VkDynamicState> dynamicStates;
709 dynamicStates.push_back(VK_DYNAMIC_STATE_VIEWPORT);
710 dynamicStates.push_back(VK_DYNAMIC_STATE_SCISSOR);
713 const VkPipelineDynamicStateCreateInfo pipelineDynamicStateInfo =
715 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
716 DE_NULL, // const void* pNext;
717 0, // VkPipelineDynamicStateCreateFlags flags;
718 static_cast<deUint32>(dynamicStates.size()), // uint32_t dynamicStateCount;
719 (dynamicStates.empty() ? DE_NULL : &dynamicStates[0]), // const VkDynamicState* pDynamicStates;
722 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
724 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
725 DE_NULL, // const void* pNext;
726 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
727 static_cast<deUint32>(m_shaderStages.size()), // deUint32 stageCount;
728 &m_shaderStages[0], // const VkPipelineShaderStageCreateInfo* pStages;
729 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
730 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
731 (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState;
732 (isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo), // const VkPipelineViewportStateCreateInfo* pViewportState;
733 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
734 (isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo), // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
735 (isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo), // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
736 (isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo), // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
737 &pipelineDynamicStateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
738 pipelineLayout, // VkPipelineLayout layout;
739 renderPass, // VkRenderPass renderPass;
740 0u, // deUint32 subpass;
741 DE_NULL, // VkPipeline basePipelineHandle;
742 0, // deInt32 basePipelineIndex;
745 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
748 float getClampedTessLevel (const SpacingMode mode, const float tessLevel)
752 case SPACINGMODE_EQUAL: return de::max(1.0f, tessLevel);
753 case SPACINGMODE_FRACTIONAL_ODD: return de::max(1.0f, tessLevel);
754 case SPACINGMODE_FRACTIONAL_EVEN: return de::max(2.0f, tessLevel);
761 int getRoundedTessLevel (const SpacingMode mode, const float clampedTessLevel)
763 static const int minimumMaxTessGenLevel = 64; //!< Minimum maxTessellationGenerationLevel defined by the spec.
765 int result = (int)deFloatCeil(clampedTessLevel);
769 case SPACINGMODE_EQUAL: break;
770 case SPACINGMODE_FRACTIONAL_ODD: result += 1 - result % 2; break;
771 case SPACINGMODE_FRACTIONAL_EVEN: result += result % 2; break;
775 DE_ASSERT(de::inRange<int>(result, 1, minimumMaxTessGenLevel));
776 DE_UNREF(minimumMaxTessGenLevel);
781 int getClampedRoundedTessLevel (const SpacingMode mode, const float tessLevel)
783 return getRoundedTessLevel(mode, getClampedTessLevel(mode, tessLevel));
786 void getClampedRoundedTriangleTessLevels (const SpacingMode spacingMode,
787 const float* innerSrc,
788 const float* outerSrc,
792 innerDst[0] = getClampedRoundedTessLevel(spacingMode, innerSrc[0]);
793 for (int i = 0; i < 3; i++)
794 outerDst[i] = getClampedRoundedTessLevel(spacingMode, outerSrc[i]);
797 void getClampedRoundedQuadTessLevels (const SpacingMode spacingMode,
798 const float* innerSrc,
799 const float* outerSrc,
803 for (int i = 0; i < 2; i++)
804 innerDst[i] = getClampedRoundedTessLevel(spacingMode, innerSrc[i]);
805 for (int i = 0; i < 4; i++)
806 outerDst[i] = getClampedRoundedTessLevel(spacingMode, outerSrc[i]);
809 void getClampedRoundedIsolineTessLevels (const SpacingMode spacingMode,
810 const float* outerSrc,
813 outerDst[0] = getClampedRoundedTessLevel(SPACINGMODE_EQUAL, outerSrc[0]);
814 outerDst[1] = getClampedRoundedTessLevel(spacingMode, outerSrc[1]);
817 int numOuterTessellationLevels (const TessPrimitiveType primType)
821 case TESSPRIMITIVETYPE_TRIANGLES: return 3;
822 case TESSPRIMITIVETYPE_QUADS: return 4;
823 case TESSPRIMITIVETYPE_ISOLINES: return 2;
830 bool isPatchDiscarded (const TessPrimitiveType primitiveType, const float* outerLevels)
832 const int numOuterLevels = numOuterTessellationLevels(primitiveType);
833 for (int i = 0; i < numOuterLevels; i++)
834 if (outerLevels[i] <= 0.0f)
839 std::string getTessellationLevelsString (const TessLevels& tessLevels, const TessPrimitiveType primitiveType)
841 std::ostringstream str;
842 switch (primitiveType)
844 case TESSPRIMITIVETYPE_ISOLINES:
845 str << "inner: { }, "
846 << "outer: { " << tessLevels.outer[0] << ", " << tessLevels.outer[1] << " }";
849 case TESSPRIMITIVETYPE_TRIANGLES:
850 str << "inner: { " << tessLevels.inner[0] << " }, "
851 << "outer: { " << tessLevels.outer[0] << ", " << tessLevels.outer[1] << ", " << tessLevels.outer[2] << " }";
854 case TESSPRIMITIVETYPE_QUADS:
855 str << "inner: { " << tessLevels.inner[0] << ", " << tessLevels.inner[1] << " }, "
856 << "outer: { " << tessLevels.outer[0] << ", " << tessLevels.outer[1] << ", " << tessLevels.outer[2] << ", " << tessLevels.outer[3] << " }";
866 //! Assumes array sizes inner[2] and outer[4].
867 std::string getTessellationLevelsString (const float* inner, const float* outer)
869 const TessLevels tessLevels =
871 { inner[0], inner[1] },
872 { outer[0], outer[1], outer[2], outer[3] }
874 return getTessellationLevelsString(tessLevels, TESSPRIMITIVETYPE_QUADS);
877 // \note The tessellation coordinates generated by this function could break some of the rules given in the spec
878 // (e.g. it may not exactly hold that u+v+w == 1.0f, or [uvw] + (1.0f-[uvw]) == 1.0f).
879 std::vector<tcu::Vec3> generateReferenceTriangleTessCoords (const SpacingMode spacingMode,
885 std::vector<tcu::Vec3> tessCoords;
889 if (outer0 == 1 && outer1 == 1 && outer2 == 1)
891 tessCoords.push_back(tcu::Vec3(1.0f, 0.0f, 0.0f));
892 tessCoords.push_back(tcu::Vec3(0.0f, 1.0f, 0.0f));
893 tessCoords.push_back(tcu::Vec3(0.0f, 0.0f, 1.0f));
897 return generateReferenceTriangleTessCoords(spacingMode, spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
898 outer0, outer1, outer2);
902 for (int i = 0; i < outer0; i++) { const float v = (float)i / (float)outer0; tessCoords.push_back(tcu::Vec3( 0.0f, v, 1.0f - v)); }
903 for (int i = 0; i < outer1; i++) { const float v = (float)i / (float)outer1; tessCoords.push_back(tcu::Vec3(1.0f - v, 0.0f, v)); }
904 for (int i = 0; i < outer2; i++) { const float v = (float)i / (float)outer2; tessCoords.push_back(tcu::Vec3( v, 1.0f - v, 0.0f)); }
906 const int numInnerTriangles = inner/2;
907 for (int innerTriangleNdx = 0; innerTriangleNdx < numInnerTriangles; innerTriangleNdx++)
909 const int curInnerTriangleLevel = inner - 2*(innerTriangleNdx+1);
911 if (curInnerTriangleLevel == 0)
912 tessCoords.push_back(tcu::Vec3(1.0f/3.0f));
915 const float minUVW = (float)(2 * (innerTriangleNdx + 1)) / (float)(3 * inner);
916 const float maxUVW = 1.0f - 2.0f*minUVW;
917 const tcu::Vec3 corners[3] =
919 tcu::Vec3(maxUVW, minUVW, minUVW),
920 tcu::Vec3(minUVW, maxUVW, minUVW),
921 tcu::Vec3(minUVW, minUVW, maxUVW)
924 for (int i = 0; i < curInnerTriangleLevel; i++)
926 const float f = (float)i / (float)curInnerTriangleLevel;
927 for (int j = 0; j < 3; j++)
928 tessCoords.push_back((1.0f - f)*corners[j] + f*corners[(j+1)%3]);
937 // \note The tessellation coordinates generated by this function could break some of the rules given in the spec
938 // (e.g. it may not exactly hold that [uv] + (1.0f-[uv]) == 1.0f).
939 std::vector<tcu::Vec3> generateReferenceQuadTessCoords (const SpacingMode spacingMode,
947 std::vector<tcu::Vec3> tessCoords;
949 if (inner0 == 1 || inner1 == 1)
951 if (inner0 == 1 && inner1 == 1 && outer0 == 1 && outer1 == 1 && outer2 == 1 && outer3 == 1)
953 tessCoords.push_back(tcu::Vec3(0.0f, 0.0f, 0.0f));
954 tessCoords.push_back(tcu::Vec3(1.0f, 0.0f, 0.0f));
955 tessCoords.push_back(tcu::Vec3(0.0f, 1.0f, 0.0f));
956 tessCoords.push_back(tcu::Vec3(1.0f, 1.0f, 0.0f));
960 return generateReferenceQuadTessCoords(spacingMode, inner0 > 1 ? inner0 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
961 inner1 > 1 ? inner1 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
962 outer0, outer1, outer2, outer3);
966 for (int i = 0; i < outer0; i++) { const float v = (float)i / (float)outer0; tessCoords.push_back(tcu::Vec3( 0.0f, v, 0.0f)); }
967 for (int i = 0; i < outer1; i++) { const float v = (float)i / (float)outer1; tessCoords.push_back(tcu::Vec3(1.0f - v, 0.0f, 0.0f)); }
968 for (int i = 0; i < outer2; i++) { const float v = (float)i / (float)outer2; tessCoords.push_back(tcu::Vec3( 1.0f, 1.0f - v, 0.0f)); }
969 for (int i = 0; i < outer3; i++) { const float v = (float)i / (float)outer3; tessCoords.push_back(tcu::Vec3( v, 1.0f, 0.0f)); }
971 for (int innerVtxY = 0; innerVtxY < inner1-1; innerVtxY++)
972 for (int innerVtxX = 0; innerVtxX < inner0-1; innerVtxX++)
973 tessCoords.push_back(tcu::Vec3((float)(innerVtxX + 1) / (float)inner0,
974 (float)(innerVtxY + 1) / (float)inner1,
981 // \note The tessellation coordinates generated by this function could break some of the rules given in the spec
982 // (e.g. it may not exactly hold that [uv] + (1.0f-[uv]) == 1.0f).
983 std::vector<tcu::Vec3> generateReferenceIsolineTessCoords (const int outer0, const int outer1)
985 std::vector<tcu::Vec3> tessCoords;
987 for (int y = 0; y < outer0; y++)
988 for (int x = 0; x < outer1+1; x++)
989 tessCoords.push_back(tcu::Vec3((float)x / (float)outer1,
990 (float)y / (float)outer0,
996 static int referencePointModePrimitiveCount (const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const float* innerLevels, const float* outerLevels)
998 if (isPatchDiscarded(primitiveType, outerLevels))
1001 switch (primitiveType)
1003 case TESSPRIMITIVETYPE_TRIANGLES:
1007 getClampedRoundedTriangleTessLevels(spacingMode, innerLevels, outerLevels, &inner, &outer[0]);
1008 return static_cast<int>(generateReferenceTriangleTessCoords(spacingMode, inner, outer[0], outer[1], outer[2]).size());
1011 case TESSPRIMITIVETYPE_QUADS:
1015 getClampedRoundedQuadTessLevels(spacingMode, innerLevels, outerLevels, &inner[0], &outer[0]);
1016 return static_cast<int>(generateReferenceQuadTessCoords(spacingMode, inner[0], inner[1], outer[0], outer[1], outer[2], outer[3]).size());
1019 case TESSPRIMITIVETYPE_ISOLINES:
1022 getClampedRoundedIsolineTessLevels(spacingMode, &outerLevels[0], &outer[0]);
1023 return static_cast<int>(generateReferenceIsolineTessCoords(outer[0], outer[1]).size());
1032 static int referenceTriangleNonPointModePrimitiveCount (const SpacingMode spacingMode, const int inner, const int outer0, const int outer1, const int outer2)
1036 if (outer0 == 1 && outer1 == 1 && outer2 == 1)
1039 return referenceTriangleNonPointModePrimitiveCount(spacingMode, spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
1040 outer0, outer1, outer2);
1044 int result = outer0 + outer1 + outer2;
1046 const int numInnerTriangles = inner/2;
1047 for (int innerTriangleNdx = 0; innerTriangleNdx < numInnerTriangles; innerTriangleNdx++)
1049 const int curInnerTriangleLevel = inner - 2*(innerTriangleNdx+1);
1051 if (curInnerTriangleLevel == 1)
1054 result += 2*3*curInnerTriangleLevel;
1061 static int referenceQuadNonPointModePrimitiveCount (const SpacingMode spacingMode, const int inner0, const int inner1, const int outer0, const int outer1, const int outer2, const int outer3)
1063 if (inner0 == 1 || inner1 == 1)
1065 if (inner0 == 1 && inner1 == 1 && outer0 == 1 && outer1 == 1 && outer2 == 1 && outer3 == 1)
1068 return referenceQuadNonPointModePrimitiveCount(spacingMode, inner0 > 1 ? inner0 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
1069 inner1 > 1 ? inner1 : spacingMode == SPACINGMODE_FRACTIONAL_ODD ? 3 : 2,
1070 outer0, outer1, outer2, outer3);
1073 return 2*(inner0-2)*(inner1-2) + 2*(inner0-2) + 2*(inner1-2) + outer0+outer1+outer2+outer3;
1076 static inline int referenceIsolineNonPointModePrimitiveCount (const int outer0, const int outer1)
1078 return outer0*outer1;
1081 static int referenceNonPointModePrimitiveCount (const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const float* innerLevels, const float* outerLevels)
1083 if (isPatchDiscarded(primitiveType, outerLevels))
1086 switch (primitiveType)
1088 case TESSPRIMITIVETYPE_TRIANGLES:
1092 getClampedRoundedTriangleTessLevels(spacingMode, innerLevels, outerLevels, &inner, &outer[0]);
1093 return referenceTriangleNonPointModePrimitiveCount(spacingMode, inner, outer[0], outer[1], outer[2]);
1096 case TESSPRIMITIVETYPE_QUADS:
1100 getClampedRoundedQuadTessLevels(spacingMode, innerLevels, outerLevels, &inner[0], &outer[0]);
1101 return referenceQuadNonPointModePrimitiveCount(spacingMode, inner[0], inner[1], outer[0], outer[1], outer[2], outer[3]);
1104 case TESSPRIMITIVETYPE_ISOLINES:
1107 getClampedRoundedIsolineTessLevels(spacingMode, &outerLevels[0], &outer[0]);
1108 return referenceIsolineNonPointModePrimitiveCount(outer[0], outer[1]);
1117 int numVerticesPerPrimitive (const TessPrimitiveType primitiveType, const bool usePointMode)
1122 switch (primitiveType)
1124 case TESSPRIMITIVETYPE_TRIANGLES: return 3;
1125 case TESSPRIMITIVETYPE_QUADS: return 3; // quads are composed of two triangles
1126 case TESSPRIMITIVETYPE_ISOLINES: return 2;
1133 int referencePrimitiveCount (const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const bool usePointMode, const float* innerLevels, const float* outerLevels)
1135 return usePointMode ? referencePointModePrimitiveCount (primitiveType, spacingMode, innerLevels, outerLevels)
1136 : referenceNonPointModePrimitiveCount (primitiveType, spacingMode, innerLevels, outerLevels);
1139 //! In point mode this should return the number of unique vertices, while in non-point mode the maximum theoretical number of verticies.
1140 //! Actual implementation will likely return a much smaller number because the shader isn't required to be run for duplicate coordinates.
1141 int referenceVertexCount (const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const bool usePointMode, const float* innerLevels, const float* outerLevels)
1143 return referencePrimitiveCount(primitiveType, spacingMode, usePointMode, innerLevels, outerLevels)
1144 * numVerticesPerPrimitive(primitiveType, usePointMode);
1147 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
1149 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
1151 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
1152 throw tcu::NotSupportedError("Tessellation shader not supported");
1154 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
1155 throw tcu::NotSupportedError("Geometry shader not supported");
1157 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
1158 throw tcu::NotSupportedError("Double-precision floats not supported");
1160 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
1161 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
1163 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
1164 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
1166 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
1167 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");