Merge vk-gl-cts/vulkan-cts-1.0.0 into vk-gl-cts/vulkan-cts-1.0.1
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineSpecConstantUtil.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Pipeline specialization constants test utilities
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktPipelineSpecConstantUtil.hpp"
25 #include "vkTypeUtil.hpp"
26 #include <vector>
27
28 namespace vkt
29 {
30 namespace pipeline
31 {
32
33 using namespace vk;
34
35 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize                     bufferSize,
36                                                                                  const VkBufferUsageFlags       usage)
37 {
38         const VkBufferCreateInfo bufferCreateInfo =
39         {
40                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
41                 DE_NULL,                                                                // const void*                  pNext;
42                 (VkBufferCreateFlags)0,                                 // VkBufferCreateFlags  flags;
43                 bufferSize,                                                             // VkDeviceSize                 size;
44                 usage,                                                                  // VkBufferUsageFlags   usage;
45                 VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
46                 0u,                                                                             // deUint32                             queueFamilyIndexCount;
47                 DE_NULL,                                                                // const deUint32*              pQueueFamilyIndices;
48         };
49         return bufferCreateInfo;
50 }
51
52 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags      srcAccessMask,
53                                                                                            const VkAccessFlags  dstAccessMask,
54                                                                                            const VkBuffer               buffer,
55                                                                                            const VkDeviceSize   offset,
56                                                                                            const VkDeviceSize   bufferSizeBytes)
57 {
58         const VkBufferMemoryBarrier barrier =
59         {
60                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
61                 DE_NULL,                                                                        // const void*          pNext;
62                 srcAccessMask,                                                          // VkAccessFlags        srcAccessMask;
63                 dstAccessMask,                                                          // VkAccessFlags        dstAccessMask;
64                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
65                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     destQueueFamilyIndex;
66                 buffer,                                                                         // VkBuffer                     buffer;
67                 offset,                                                                         // VkDeviceSize         offset;
68                 bufferSizeBytes,                                                        // VkDeviceSize         size;
69         };
70         return barrier;
71 }
72
73 VkImageMemoryBarrier makeImageMemoryBarrier     (const VkAccessFlags                    srcAccessMask,
74                                                                                          const VkAccessFlags                    dstAccessMask,
75                                                                                          const VkImageLayout                    oldLayout,
76                                                                                          const VkImageLayout                    newLayout,
77                                                                                          const VkImage                                  image,
78                                                                                          const VkImageSubresourceRange  subresourceRange)
79 {
80         const VkImageMemoryBarrier barrier =
81         {
82                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
83                 DE_NULL,                                                                                // const void*                          pNext;
84                 srcAccessMask,                                                                  // VkAccessFlags                        outputMask;
85                 dstAccessMask,                                                                  // VkAccessFlags                        inputMask;
86                 oldLayout,                                                                              // VkImageLayout                        oldLayout;
87                 newLayout,                                                                              // VkImageLayout                        newLayout;
88                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
89                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     destQueueFamilyIndex;
90                 image,                                                                                  // VkImage                                      image;
91                 subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
92         };
93         return barrier;
94 }
95
96 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
97 {
98         const VkCommandPoolCreateInfo info =
99         {
100                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                     // VkStructureType                      sType;
101                 DE_NULL,                                                                                        // const void*                          pNext;
102                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,        // VkCommandPoolCreateFlags     flags;
103                 queueFamilyIndex,                                                                       // deUint32                                     queueFamilyIndex;
104         };
105         return createCommandPool(vk, device, &info);
106 }
107
108 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
109 {
110         const VkCommandBufferAllocateInfo info =
111         {
112                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,         // VkStructureType              sType;
113                 DE_NULL,                                                                                        // const void*                  pNext;
114                 commandPool,                                                                            // VkCommandPool                commandPool;
115                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                        // VkCommandBufferLevel level;
116                 1u,                                                                                                     // deUint32                             commandBufferCount;
117         };
118         return allocateCommandBuffer(vk, device, &info);
119 }
120
121 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&                 vk,
122                                                                                  const VkDevice                                 device,
123                                                                                  const VkDescriptorPool                 descriptorPool,
124                                                                                  const VkDescriptorSetLayout    setLayout)
125 {
126         const VkDescriptorSetAllocateInfo info =
127         {
128                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,         // VkStructureType                              sType;
129                 DE_NULL,                                                                                        // const void*                                  pNext;
130                 descriptorPool,                                                                         // VkDescriptorPool                             descriptorPool;
131                 1u,                                                                                                     // deUint32                                             descriptorSetCount;
132                 &setLayout,                                                                                     // const VkDescriptorSetLayout* pSetLayouts;
133         };
134         return allocateDescriptorSet(vk, device, &info);
135 }
136
137 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&               vk,
138                                                                                    const VkDevice                               device,
139                                                                                    const VkDescriptorSetLayout  descriptorSetLayout)
140 {
141         const VkPipelineLayoutCreateInfo info =
142         {
143                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
144                 DE_NULL,                                                                                        // const void*                                  pNext;
145                 (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags  flags;
146                 1u,                                                                                                     // deUint32                                             setLayoutCount;
147                 &descriptorSetLayout,                                                           // const VkDescriptorSetLayout* pSetLayouts;
148                 0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
149                 DE_NULL,                                                                                        // const VkPushConstantRange*   pPushConstantRanges;
150         };
151         return createPipelineLayout(vk, device, &info);
152 }
153
154 Move<VkPipeline> makeComputePipeline (const DeviceInterface&            vk,
155                                                                           const VkDevice                                device,
156                                                                           const VkPipelineLayout                pipelineLayout,
157                                                                           const VkShaderModule                  shaderModule,
158                                                                           const VkSpecializationInfo*   specInfo)
159 {
160         const VkPipelineShaderStageCreateInfo shaderStageInfo =
161         {
162                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                      sType;
163                 DE_NULL,                                                                                                // const void*                                          pNext;
164                 (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags     flags;
165                 VK_SHADER_STAGE_COMPUTE_BIT,                                                    // VkShaderStageFlagBits                        stage;
166                 shaderModule,                                                                                   // VkShaderModule                                       module;
167                 "main",                                                                                                 // const char*                                          pName;
168                 specInfo,                                                                                               // const VkSpecializationInfo*          pSpecializationInfo;
169         };
170         const VkComputePipelineCreateInfo pipelineInfo =
171         {
172                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,         // VkStructureType                                      sType;
173                 DE_NULL,                                                                                        // const void*                                          pNext;
174                 (VkPipelineCreateFlags)0,                                                       // VkPipelineCreateFlags                        flags;
175                 shaderStageInfo,                                                                        // VkPipelineShaderStageCreateInfo      stage;
176                 pipelineLayout,                                                                         // VkPipelineLayout                                     layout;
177                 DE_NULL,                                                                                        // VkPipeline                                           basePipelineHandle;
178                 0,                                                                                                      // deInt32                                                      basePipelineIndex;
179         };
180         return createComputePipeline(vk, device, DE_NULL , &pipelineInfo);
181 }
182
183 VkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& size, const VkFormat format, const VkImageUsageFlags usage)
184 {
185         const VkImageCreateInfo imageInfo =
186         {
187                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType          sType;
188                 DE_NULL,                                                                        // const void*              pNext;
189                 (VkImageCreateFlags)0,                                          // VkImageCreateFlags       flags;
190                 VK_IMAGE_TYPE_2D,                                                       // VkImageType              imageType;
191                 format,                                                                         // VkFormat                 format;
192                 makeExtent3D(size.x(), size.y(), 1),            // VkExtent3D               extent;
193                 1u,                                                                                     // uint32_t                 mipLevels;
194                 1u,                                                                                     // uint32_t                 arrayLayers;
195                 VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits    samples;
196                 VK_IMAGE_TILING_OPTIMAL,                                        // VkImageTiling            tiling;
197                 usage,                                                                          // VkImageUsageFlags        usage;
198                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode            sharingMode;
199                 0u,                                                                                     // uint32_t                 queueFamilyIndexCount;
200                 DE_NULL,                                                                        // const uint32_t*          pQueueFamilyIndices;
201                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout            initialLayout;
202         };
203         return imageInfo;
204 }
205
206 Move<VkImageView> makeImageView (const DeviceInterface&                 vk,
207                                                                  const VkDevice                                 vkDevice,
208                                                                  const VkImage                                  image,
209                                                                  const VkImageViewType                  viewType,
210                                                                  const VkFormat                                 format)
211 {
212         const VkImageViewCreateInfo imageViewParams =
213         {
214                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
215                 DE_NULL,                                                                                // const void*                          pNext;
216                 (VkImageViewCreateFlags)0,                                              // VkImageViewCreateFlags       flags;
217                 image,                                                                                  // VkImage                                      image;
218                 viewType,                                                                               // VkImageViewType                      viewType;
219                 format,                                                                                 // VkFormat                                     format;
220                 makeComponentMappingRGBA(),                                             // VkComponentMapping           components;
221                 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u),   // VkImageSubresourceRange      subresourceRange;
222         };
223         return createImageView(vk, vkDevice, &imageViewParams);
224 }
225
226 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
227 {
228         const VkCommandBufferBeginInfo info =
229         {
230                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                          sType;
231                 DE_NULL,                                                                                // const void*                              pNext;
232                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags                flags;
233                 DE_NULL,                                                                                // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
234         };
235         VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
236 }
237
238 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
239 {
240         VK_CHECK(vk.endCommandBuffer(commandBuffer));
241 }
242
243 void submitCommandsAndWait (const DeviceInterface&      vk,
244                                                         const VkDevice                  device,
245                                                         const VkQueue                   queue,
246                                                         const VkCommandBuffer   commandBuffer)
247 {
248         const VkFenceCreateInfo fenceInfo =
249         {
250                 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
251                 DE_NULL,                                                                // const void*                  pNext;
252                 (VkFenceCreateFlags)0,                                  // VkFenceCreateFlags   flags;
253         };
254         const Unique<VkFence> fence(createFence(vk, device, &fenceInfo));
255
256         const VkSubmitInfo submitInfo =
257         {
258                 VK_STRUCTURE_TYPE_SUBMIT_INFO,          // VkStructureType                sType;
259                 DE_NULL,                                                        // const void*                    pNext;
260                 0u,                                                                     // uint32_t                       waitSemaphoreCount;
261                 DE_NULL,                                                        // const VkSemaphore*             pWaitSemaphores;
262                 DE_NULL,                                                        // const VkPipelineStageFlags*    pWaitDstStageMask;
263                 1u,                                                                     // uint32_t                       commandBufferCount;
264                 &commandBuffer,                                         // const VkCommandBuffer*         pCommandBuffers;
265                 0u,                                                                     // uint32_t                       signalSemaphoreCount;
266                 DE_NULL,                                                        // const VkSemaphore*             pSignalSemaphores;
267         };
268         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
269         VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
270 }
271
272 void beginRenderPass (const DeviceInterface&    vk,
273                                           const VkCommandBuffer         commandBuffer,
274                                           const VkRenderPass            renderPass,
275                                           const VkFramebuffer           framebuffer,
276                                           const VkRect2D&                       renderArea,
277                                           const tcu::Vec4&                      clearColor)
278 {
279         const VkClearValue clearValue = makeClearValueColor(clearColor);
280
281         const VkRenderPassBeginInfo renderPassBeginInfo = {
282                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType         sType;
283                 DE_NULL,                                                                                // const void*             pNext;
284                 renderPass,                                                                             // VkRenderPass            renderPass;
285                 framebuffer,                                                                    // VkFramebuffer           framebuffer;
286                 renderArea,                                                                             // VkRect2D                renderArea;
287                 1u,                                                                                             // uint32_t                clearValueCount;
288                 &clearValue,                                                                    // const VkClearValue*     pClearValues;
289         };
290
291         vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
292 }
293
294 void endRenderPass (const DeviceInterface&      vk,
295                                         const VkCommandBuffer   commandBuffer)
296 {
297         vk.cmdEndRenderPass(commandBuffer);
298 }
299
300 Move<VkRenderPass> makeRenderPass (const DeviceInterface&       vk,
301                                                                    const VkDevice                       device,
302                                                                    const VkFormat                       colorFormat)
303 {
304         const VkAttachmentDescription colorAttachmentDescription =
305         {
306                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
307                 colorFormat,                                                                            // VkFormat                                                     format;
308                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
309                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
310                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
311                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
312                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
313                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
314                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout                                        finalLayout;
315         };
316
317         const VkAttachmentReference colorAttachmentReference =
318         {
319                 0u,                                                                                                     // deUint32                     attachment;
320                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
321         };
322
323         const VkAttachmentReference depthAttachmentReference =
324         {
325                 VK_ATTACHMENT_UNUSED,                                                           // deUint32                     attachment;
326                 VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout        layout;
327         };
328
329         const VkSubpassDescription subpassDescription =
330         {
331                 (VkSubpassDescriptionFlags)0,                                           // VkSubpassDescriptionFlags            flags;
332                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
333                 0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
334                 DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
335                 1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
336                 &colorAttachmentReference,                                                      // const VkAttachmentReference*         pColorAttachments;
337                 DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
338                 &depthAttachmentReference,                                                      // const VkAttachmentReference*         pDepthStencilAttachment;
339                 0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
340                 DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
341         };
342
343         const VkRenderPassCreateInfo renderPassInfo =
344         {
345                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
346                 DE_NULL,                                                                                        // const void*                                          pNext;
347                 (VkRenderPassCreateFlags)0,                                                     // VkRenderPassCreateFlags                      flags;
348                 1u,                                                                                                     // deUint32                                                     attachmentCount;
349                 &colorAttachmentDescription,                                            // const VkAttachmentDescription*       pAttachments;
350                 1u,                                                                                                     // deUint32                                                     subpassCount;
351                 &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
352                 0u,                                                                                                     // deUint32                                                     dependencyCount;
353                 DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
354         };
355
356         return createRenderPass(vk, device, &renderPassInfo);
357 }
358
359 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface&             vk,
360                                                                          const VkDevice                         device,
361                                                                          const VkRenderPass                     renderPass,
362                                                                          const VkImageView                      colorAttachment,
363                                                                          const deUint32                         width,
364                                                                          const deUint32                         height)
365 {
366         const VkFramebufferCreateInfo framebufferInfo = {
367                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,              // VkStructureType                             sType;
368                 DE_NULL,                                                                                // const void*                                 pNext;
369                 (VkFramebufferCreateFlags)0,                                    // VkFramebufferCreateFlags                    flags;
370                 renderPass,                                                                             // VkRenderPass                                renderPass;
371                 1u,                                                                                             // uint32_t                                    attachmentCount;
372                 &colorAttachment,                                                               // const VkImageView*                          pAttachments;
373                 width,                                                                                  // uint32_t                                    width;
374                 height,                                                                                 // uint32_t                                    height;
375                 1u,                                                                                             // uint32_t                                    layers;
376         };
377
378         return createFramebuffer(vk, device, &framebufferInfo);
379 }
380
381 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface&                     vk,
382                                                                                                                          const VkDevice                                 device,
383                                                                                                                          const VkShaderStageFlagBits    stage,
384                                                                                                                          const ProgramBinary&                   binary,
385                                                                                                                          const VkSpecializationInfo*    specInfo)
386 {
387         VkShaderModule module;
388         switch (stage)
389         {
390                 case (VK_SHADER_STAGE_VERTEX_BIT):
391                         DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
392                         m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
393                         module = *m_vertexShaderModule;
394                         break;
395
396                 case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
397                         DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
398                         m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
399                         module = *m_tessControlShaderModule;
400                         break;
401
402                 case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
403                         DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
404                         m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
405                         module = *m_tessEvaluationShaderModule;
406                         break;
407
408                 case (VK_SHADER_STAGE_GEOMETRY_BIT):
409                         DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
410                         m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
411                         module = *m_geometryShaderModule;
412                         break;
413
414                 case (VK_SHADER_STAGE_FRAGMENT_BIT):
415                         DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
416                         m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
417                         module = *m_fragmentShaderModule;
418                         break;
419
420                 default:
421                         DE_FATAL("Invalid shader stage");
422                         return *this;
423         }
424
425         const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
426         {
427                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
428                 DE_NULL,                                                                                                // const void*                                                  pNext;
429                 (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
430                 stage,                                                                                                  // VkShaderStageFlagBits                                stage;
431                 module,                                                                                                 // VkShaderModule                                               module;
432                 "main",                                                                                                 // const char*                                                  pName;
433                 specInfo,                                                                                               // const VkSpecializationInfo*                  pSpecializationInfo;
434         };
435
436         m_shaderStageFlags |= stage;
437         m_shaderStages.push_back(pipelineShaderStageInfo);
438
439         return *this;
440 }
441
442 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface& vk,
443                                                                                                  const VkDevice                 device,
444                                                                                                  const VkPipelineLayout pipelineLayout,
445                                                                                                  const VkRenderPass             renderPass)
446 {
447         const VkVertexInputBindingDescription vertexInputBindingDescription =
448         {
449                 0u,                                                             // uint32_t                             binding;
450                 sizeof(tcu::Vec4),                              // uint32_t                             stride;         // Vertex is a 4-element vector XYZW, position only
451                 VK_VERTEX_INPUT_RATE_VERTEX,    // VkVertexInputRate    inputRate;
452         };
453
454         const VkVertexInputAttributeDescription vertexInputAttributeDescription =
455         {
456                 0u,                                                                     // uint32_t                     location;
457                 0u,                                                                     // uint32_t                     binding;
458                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat                     format;
459                 0u,                                                                     // uint32_t                     offset;
460         };
461
462         const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
463         {
464                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                             sType;
465                 DE_NULL,                                                                                                        // const void*                                 pNext;
466                 (VkPipelineVertexInputStateCreateFlags)0,                                       // VkPipelineVertexInputStateCreateFlags       flags;
467                 1u,                                                                                                                     // uint32_t                                    vertexBindingDescriptionCount;
468                 &vertexInputBindingDescription,                                                         // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
469                 1u,                                                                                                                     // uint32_t                                    vertexAttributeDescriptionCount;
470                 &vertexInputAttributeDescription,                                                       // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
471         };
472
473         const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
474         const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
475         {
476                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                             sType;
477                 DE_NULL,                                                                                                                // const void*                                 pNext;
478                 (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags     flags;
479                 topology,                                                                                                               // VkPrimitiveTopology                         topology;
480                 VK_FALSE,                                                                                                               // VkBool32                                    primitiveRestartEnable;
481         };
482
483         const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
484         {
485                 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,              // VkStructureType                             sType;
486                 DE_NULL,                                                                                                                // const void*                                 pNext;
487                 (VkPipelineTessellationStateCreateFlags)0,                                              // VkPipelineTessellationStateCreateFlags      flags;
488                 3u,                                                                                                                             // uint32_t                                    patchControlPoints;
489         };
490
491         const VkViewport viewport = makeViewport(
492                 0.0f, 0.0f,
493                 static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()),
494                 0.0f, 1.0f);
495
496         const VkRect2D scissor = {
497                 makeOffset2D(0, 0),
498                 makeExtent2D(m_renderSize.x(), m_renderSize.y()),
499         };
500
501         const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
502         {
503                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                             sType;
504                 DE_NULL,                                                                                                // const void*                                 pNext;
505                 (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewportStateCreateFlags          flags;
506                 1u,                                                                                                             // uint32_t                                    viewportCount;
507                 &viewport,                                                                                              // const VkViewport*                           pViewports;
508                 1u,                                                                                                             // uint32_t                                    scissorCount;
509                 &scissor,                                                                                               // const VkRect2D*                             pScissors;
510         };
511
512         const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
513         {
514                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                          sType;
515                 DE_NULL,                                                                                                                // const void*                              pNext;
516                 (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags  flags;
517                 VK_FALSE,                                                                                                               // VkBool32                                 depthClampEnable;
518                 VK_FALSE,                                                                                                               // VkBool32                                 rasterizerDiscardEnable;
519                 VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
520                 VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
521                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
522                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
523                 0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
524                 0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
525                 0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
526                 1.0f,                                                                                                                   // float                                                                        lineWidth;
527         };
528
529         const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
530         {
531                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
532                 DE_NULL,                                                                                                        // const void*                                                          pNext;
533                 (VkPipelineMultisampleStateCreateFlags)0,                                       // VkPipelineMultisampleStateCreateFlags        flags;
534                 VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
535                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
536                 0.0f,                                                                                                           // float                                                                        minSampleShading;
537                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
538                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
539                 VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
540         };
541
542         const VkStencilOpState stencilOpStateBasic = makeStencilOpState(
543                 VK_STENCIL_OP_KEEP,             // stencil fail
544                 VK_STENCIL_OP_KEEP,             // depth & stencil pass
545                 VK_STENCIL_OP_KEEP,             // depth only fail
546                 VK_COMPARE_OP_NEVER,    // compare op
547                 0u,                                             // compare mask
548                 0u,                                             // write mask
549                 0u);                                    // reference
550
551         VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
552         {
553                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
554                 DE_NULL,                                                                                                        // const void*                                                          pNext;
555                 (VkPipelineDepthStencilStateCreateFlags)0,                                      // VkPipelineDepthStencilStateCreateFlags       flags;
556                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthTestEnable;
557                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthWriteEnable;
558                 VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
559                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
560                 VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
561                 stencilOpStateBasic,                                                                            // VkStencilOpState                                                     front;
562                 stencilOpStateBasic,                                                                            // VkStencilOpState                                                     back;
563                 0.0f,                                                                                                           // float                                                                        minDepthBounds;
564                 1.0f,                                                                                                           // float                                                                        maxDepthBounds;
565         };
566
567         const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
568         const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
569         {
570                 VK_FALSE,                                                       // VkBool32                                     blendEnable;
571                 VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        srcColorBlendFactor;
572                 VK_BLEND_FACTOR_ZERO,                           // VkBlendFactor                        dstColorBlendFactor;
573                 VK_BLEND_OP_ADD,                                        // VkBlendOp                            colorBlendOp;
574                 VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        srcAlphaBlendFactor;
575                 VK_BLEND_FACTOR_ZERO,                           // VkBlendFactor                        dstAlphaBlendFactor;
576                 VK_BLEND_OP_ADD,                                        // VkBlendOp                            alphaBlendOp;
577                 colorComponentsAll,                                     // VkColorComponentFlags        colorWriteMask;
578         };
579
580         const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
581         {
582                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
583                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
584                 (VkPipelineColorBlendStateCreateFlags)0,                                        // VkPipelineColorBlendStateCreateFlags                 flags;
585                 VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
586                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
587                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
588                 &pipelineColorBlendAttachmentState,                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
589                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConstants[4];
590         };
591
592         const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
593         {
594                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
595                 DE_NULL,                                                                                        // const void*                                                                          pNext;
596                 (VkPipelineCreateFlags)0,                                                       // VkPipelineCreateFlags                                                        flags;
597                 static_cast<deUint32>(m_shaderStages.size()),           // deUint32                                                                                     stageCount;
598                 &m_shaderStages[0],                                                                     // const VkPipelineShaderStageCreateInfo*                       pStages;
599                 &vertexInputStateInfo,                                                          // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
600                 &pipelineInputAssemblyStateInfo,                                        // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
601                 (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo*             pTessellationState;
602                 &pipelineViewportStateInfo,                                                     // const VkPipelineViewportStateCreateInfo*                     pViewportState;
603                 &pipelineRasterizationStateInfo,                                        // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
604                 &pipelineMultisampleStateInfo,                                          // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
605                 &pipelineDepthStencilStateInfo,                                         // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
606                 &pipelineColorBlendStateInfo,                                           // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
607                 DE_NULL,                                                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
608                 pipelineLayout,                                                                         // VkPipelineLayout                                                                     layout;
609                 renderPass,                                                                                     // VkRenderPass                                                                         renderPass;
610                 0u,                                                                                                     // deUint32                                                                                     subpass;
611                 DE_NULL,                                                                                        // VkPipeline                                                                           basePipelineHandle;
612                 0,                                                                                                      // deInt32                                                                                      basePipelineIndex;
613         };
614
615         return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
616 }
617
618 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
619 {
620         const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
621
622         if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
623                 throw tcu::NotSupportedError("Tessellation shader not supported");
624
625         if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
626                 throw tcu::NotSupportedError("Geometry shader not supported");
627
628         if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
629                 throw tcu::NotSupportedError("Double-precision floats not supported");
630
631         if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
632                 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
633
634         if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
635                 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
636 }
637
638 } // pipeline
639 } // vkt