Modify spirv_assembly tests adding dependency on 16bit_storage extension
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / vktDrawUtil.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan CTS Framework
3  * --------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 Google Inc.
7  *
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
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  *//*!
21  * \file
22  * \brief Utility for generating simple work
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktDrawUtil.hpp"
26 #include "rrMultisamplePixelBufferAccess.hpp"
27 #include "vkBufferWithMemory.hpp"
28 #include "vkImageWithMemory.hpp"
29 #include "vkTypeUtil.hpp"
30 #include "rrRenderer.hpp"
31 #include "rrRenderState.hpp"
32 #include "rrPrimitiveTypes.hpp"
33 #include "tcuTextureUtil.hpp"
34 #include "tcuTestLog.hpp"
35 #include "deArrayUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37
38 namespace vkt
39 {
40 namespace drawutil
41 {
42
43 using namespace de;
44 using namespace tcu;
45 using namespace vk;
46
47 static VkCompareOp mapCompareOp (rr::TestFunc compareFunc)
48 {
49         switch (compareFunc)
50         {
51                 case rr::TESTFUNC_NEVER:                                return VK_COMPARE_OP_NEVER;
52                 case rr::TESTFUNC_LESS:                                 return VK_COMPARE_OP_LESS;
53                 case rr::TESTFUNC_EQUAL:                                return VK_COMPARE_OP_EQUAL;
54                 case rr::TESTFUNC_LEQUAL:                               return VK_COMPARE_OP_LESS_OR_EQUAL;
55                 case rr::TESTFUNC_GREATER:                              return VK_COMPARE_OP_GREATER;
56                 case rr::TESTFUNC_NOTEQUAL:                             return VK_COMPARE_OP_NOT_EQUAL;
57                 case rr::TESTFUNC_GEQUAL:                               return VK_COMPARE_OP_GREATER_OR_EQUAL;
58                 case rr::TESTFUNC_ALWAYS:                               return VK_COMPARE_OP_ALWAYS;
59                 default:
60                         DE_ASSERT(false);
61         }
62         return VK_COMPARE_OP_LAST;
63 }
64
65 rr::PrimitiveType mapVkPrimitiveToRRPrimitive(const vk::VkPrimitiveTopology& primitiveTopology)
66 {
67         static const rr::PrimitiveType primitiveTypeTable[] =
68         {
69                 rr::PRIMITIVETYPE_POINTS,
70                 rr::PRIMITIVETYPE_LINES,
71                 rr::PRIMITIVETYPE_LINE_STRIP,
72                 rr::PRIMITIVETYPE_TRIANGLES,
73                 rr::PRIMITIVETYPE_TRIANGLE_STRIP,
74                 rr::PRIMITIVETYPE_TRIANGLE_FAN,
75                 rr::PRIMITIVETYPE_LINES_ADJACENCY,
76                 rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY,
77                 rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY,
78                 rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY
79         };
80
81         return de::getSizedArrayElement<vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST>(primitiveTypeTable, primitiveTopology);
82 }
83
84 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize                     bufferSize,
85                                                                                  const VkBufferUsageFlags       usage)
86 {
87         const VkBufferCreateInfo bufferCreateInfo =
88         {
89                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
90                 DE_NULL,                                                                // const void*                  pNext;
91                 (VkBufferCreateFlags)0,                                 // VkBufferCreateFlags  flags;
92                 bufferSize,                                                             // VkDeviceSize                 size;
93                 usage,                                                                  // VkBufferUsageFlags   usage;
94                 VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
95                 0u,                                                                             // deUint32                             queueFamilyIndexCount;
96                 DE_NULL,                                                                // const deUint32*              pQueueFamilyIndices;
97         };
98         return bufferCreateInfo;
99 }
100
101 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags      srcAccessMask,
102                                                                                            const VkAccessFlags  dstAccessMask,
103                                                                                            const VkBuffer               buffer,
104                                                                                            const VkDeviceSize   offset,
105                                                                                            const VkDeviceSize   bufferSizeBytes)
106 {
107         const VkBufferMemoryBarrier barrier =
108         {
109                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
110                 DE_NULL,                                                                        // const void*          pNext;
111                 srcAccessMask,                                                          // VkAccessFlags        srcAccessMask;
112                 dstAccessMask,                                                          // VkAccessFlags        dstAccessMask;
113                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
114                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     destQueueFamilyIndex;
115                 buffer,                                                                         // VkBuffer                     buffer;
116                 offset,                                                                         // VkDeviceSize         offset;
117                 bufferSizeBytes,                                                        // VkDeviceSize         size;
118         };
119         return barrier;
120 }
121
122 VkImageMemoryBarrier makeImageMemoryBarrier     (const VkAccessFlags                    srcAccessMask,
123                                                                                          const VkAccessFlags                    dstAccessMask,
124                                                                                          const VkImageLayout                    oldLayout,
125                                                                                          const VkImageLayout                    newLayout,
126                                                                                          const VkImage                                  image,
127                                                                                          const VkImageSubresourceRange  subresourceRange)
128 {
129         const VkImageMemoryBarrier barrier =
130         {
131                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
132                 DE_NULL,                                                                                // const void*                          pNext;
133                 srcAccessMask,                                                                  // VkAccessFlags                        outputMask;
134                 dstAccessMask,                                                                  // VkAccessFlags                        inputMask;
135                 oldLayout,                                                                              // VkImageLayout                        oldLayout;
136                 newLayout,                                                                              // VkImageLayout                        newLayout;
137                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
138                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     destQueueFamilyIndex;
139                 image,                                                                                  // VkImage                                      image;
140                 subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
141         };
142         return barrier;
143 }
144
145 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
146 {
147         const VkCommandPoolCreateInfo info =
148         {
149                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                     // VkStructureType                      sType;
150                 DE_NULL,                                                                                        // const void*                          pNext;
151                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,        // VkCommandPoolCreateFlags     flags;
152                 queueFamilyIndex,                                                                       // deUint32                                     queueFamilyIndex;
153         };
154         return createCommandPool(vk, device, &info);
155 }
156
157 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
158 {
159         const VkCommandBufferAllocateInfo info =
160         {
161                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,         // VkStructureType              sType;
162                 DE_NULL,                                                                                        // const void*                  pNext;
163                 commandPool,                                                                            // VkCommandPool                commandPool;
164                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                        // VkCommandBufferLevel level;
165                 1u,                                                                                                     // deUint32                             commandBufferCount;
166         };
167         return allocateCommandBuffer(vk, device, &info);
168 }
169
170 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&                 vk,
171                                                                                  const VkDevice                                 device,
172                                                                                  const VkDescriptorPool                 descriptorPool,
173                                                                                  const VkDescriptorSetLayout    setLayout)
174 {
175         const VkDescriptorSetAllocateInfo info =
176         {
177                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,         // VkStructureType                              sType;
178                 DE_NULL,                                                                                        // const void*                                  pNext;
179                 descriptorPool,                                                                         // VkDescriptorPool                             descriptorPool;
180                 1u,                                                                                                     // deUint32                                             descriptorSetCount;
181                 &setLayout,                                                                                     // const VkDescriptorSetLayout* pSetLayouts;
182         };
183         return allocateDescriptorSet(vk, device, &info);
184 }
185
186 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&               vk,
187                                                                                    const VkDevice                               device,
188                                                                                    const VkDescriptorSetLayout  descriptorSetLayout)
189 {
190         const VkPipelineLayoutCreateInfo info =
191         {
192                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
193                 DE_NULL,                                                                                        // const void*                                  pNext;
194                 (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags  flags;
195                 1u,                                                                                                     // deUint32                                             setLayoutCount;
196                 &descriptorSetLayout,                                                           // const VkDescriptorSetLayout* pSetLayouts;
197                 0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
198                 DE_NULL,                                                                                        // const VkPushConstantRange*   pPushConstantRanges;
199         };
200         return createPipelineLayout(vk, device, &info);
201 }
202
203 Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface&             vk,
204                                                                                                                          const VkDevice                         device)
205 {
206         const VkPipelineLayoutCreateInfo info =
207         {
208                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
209                 DE_NULL,                                                                                        // const void*                                  pNext;
210                 (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags  flags;
211                 0u,                                                                                                     // deUint32                                             setLayoutCount;
212                 DE_NULL,                                                                                        // const VkDescriptorSetLayout* pSetLayouts;
213                 0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
214                 DE_NULL,                                                                                        // const VkPushConstantRange*   pPushConstantRanges;
215         };
216         return createPipelineLayout(vk, device, &info);
217 }
218
219 Move<VkImageView> makeImageView (const DeviceInterface&                 vk,
220                                                                  const VkDevice                                 device,
221                                                                  const VkImage                                  image,
222                                                                  const VkImageViewType                  viewType,
223                                                                  const VkFormat                                 format,
224                                                                  const VkImageSubresourceRange  subresourceRange)
225 {
226         const VkImageViewCreateInfo imageViewParams =
227         {
228                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
229                 DE_NULL,                                                                                // const void*                          pNext;
230                 (VkImageViewCreateFlags)0,                                              // VkImageViewCreateFlags       flags;
231                 image,                                                                                  // VkImage                                      image;
232                 viewType,                                                                               // VkImageViewType                      viewType;
233                 format,                                                                                 // VkFormat                                     format;
234                 makeComponentMappingRGBA(),                                             // VkComponentMapping           components;
235                 subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
236         };
237         return createImageView(vk, device, &imageViewParams);
238 }
239
240 VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers   subresourceLayers,
241                                                                            const VkExtent3D                                     extent)
242 {
243         const VkBufferImageCopy copyParams =
244         {
245                 0ull,                                                                           //      VkDeviceSize                            bufferOffset;
246                 0u,                                                                                     //      deUint32                                        bufferRowLength;
247                 0u,                                                                                     //      deUint32                                        bufferImageHeight;
248                 subresourceLayers,                                                      //      VkImageSubresourceLayers        imageSubresource;
249                 makeOffset3D(0, 0, 0),                                          //      VkOffset3D                                      imageOffset;
250                 extent,                                                                         //      VkExtent3D                                      imageExtent;
251         };
252         return copyParams;
253 }
254
255 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
256 {
257         const VkCommandBufferBeginInfo info =
258         {
259                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                                      sType;
260                 DE_NULL,                                                                                // const void*                                                          pNext;
261                 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags                            flags;
262                 DE_NULL,                                                                                // const VkCommandBufferInheritanceInfo*        pInheritanceInfo;
263         };
264         VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
265 }
266
267 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
268 {
269         VK_CHECK(vk.endCommandBuffer(commandBuffer));
270 }
271
272 void submitCommandsAndWait (const DeviceInterface&      vk,
273                                                         const VkDevice                  device,
274                                                         const VkQueue                   queue,
275                                                         const VkCommandBuffer   commandBuffer)
276 {
277         const VkFenceCreateInfo fenceInfo =
278         {
279                 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
280                 DE_NULL,                                                                // const void*                  pNext;
281                 (VkFenceCreateFlags)0,                                  // VkFenceCreateFlags   flags;
282         };
283         const Unique<VkFence> fence(createFence(vk, device, &fenceInfo));
284
285         const VkSubmitInfo submitInfo =
286         {
287                 VK_STRUCTURE_TYPE_SUBMIT_INFO,          // VkStructureType                                      sType;
288                 DE_NULL,                                                        // const void*                                          pNext;
289                 0u,                                                                     // uint32_t                                                     waitSemaphoreCount;
290                 DE_NULL,                                                        // const VkSemaphore*                           pWaitSemaphores;
291                 DE_NULL,                                                        // const VkPipelineStageFlags*          pWaitDstStageMask;
292                 1u,                                                                     // uint32_t                                                     commandBufferCount;
293                 &commandBuffer,                                         // const VkCommandBuffer*                       pCommandBuffers;
294                 0u,                                                                     // uint32_t                                                     signalSemaphoreCount;
295                 DE_NULL,                                                        // const VkSemaphore*                           pSignalSemaphores;
296         };
297         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
298         VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
299 }
300
301 std::string getPrimitiveTopologyShortName (const VkPrimitiveTopology topology)
302 {
303         std::string name(getPrimitiveTopologyName(topology));
304         return de::toLower(name.substr(22));
305 }
306
307 DrawState::DrawState(const vk::VkPrimitiveTopology topology_, deUint32 renderWidth_, deUint32 renderHeight_)
308         : topology                              (topology_)
309         , colorFormat                   (VK_FORMAT_R8G8B8A8_UNORM)
310         , renderSize                    (tcu::UVec2(renderWidth_, renderHeight_))
311         , depthClampEnable              (false)
312         , depthTestEnable               (false)
313         , depthWriteEnable              (false)
314         , compareOp                             (rr::TESTFUNC_LESS)
315         , depthBoundsTestEnable (false)
316         , blendEnable                   (false)
317         , lineWidth                             (1.0)
318         , numPatchControlPoints (0)
319         , numSamples                    (VK_SAMPLE_COUNT_1_BIT)
320         , sampleShadingEnable   (false)
321 {
322         DE_ASSERT(renderSize.x() != 0 && renderSize.y() != 0);
323 }
324
325 ReferenceDrawContext::~ReferenceDrawContext (void)
326 {
327 }
328
329 void ReferenceDrawContext::draw (void)
330 {
331         m_refImage.setStorage(vk::mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y());
332         tcu::clear(m_refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
333
334         {
335                 const rr::Program                                               program(&m_vertexShader, &m_fragmentShader);
336                 const rr::MultisamplePixelBufferAccess  referenceColorBuffer = rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(m_refImage.getAccess());
337                 const rr::RenderTarget                                  renderTarget(referenceColorBuffer);
338                 const rr::RenderState                                   renderState((rr::ViewportState(referenceColorBuffer)), rr::VIEWPORTORIENTATION_UPPER_LEFT);
339                 const rr::Renderer                                              renderer;
340                 const rr::VertexAttrib                                  vertexAttrib[] =
341                 {
342                         rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &m_drawCallData.vertices[0])
343                 };
344
345                 renderer.draw(rr::DrawCommand(  renderState,
346                                                                                 renderTarget,
347                                                                                 program,
348                                                                                 DE_LENGTH_OF_ARRAY(vertexAttrib),
349                                                                                 &vertexAttrib[0],
350                                                                                 rr::PrimitiveList(mapVkPrimitiveToRRPrimitive(m_drawState.topology), (int)m_drawCallData.vertices.size(), 0)));
351
352         }
353
354 }
355
356 tcu::ConstPixelBufferAccess ReferenceDrawContext::getColorPixels (void) const
357 {
358         return tcu::ConstPixelBufferAccess( m_refImage.getAccess().getFormat(),
359                                                                                 m_refImage.getAccess().getWidth(),
360                                                                                 m_refImage.getAccess().getHeight(),
361                                                                                 m_refImage.getAccess().getDepth(),
362                                                                                 m_refImage.getAccess().getDataPtr());
363 }
364
365 VulkanDrawContext::VulkanDrawContext ( Context&                         context,
366                                                                           const DrawState&              drawState,
367                                                                           const DrawCallData&   drawCallData,
368                                                                           const VulkanProgram&  vulkanProgram)
369         : DrawContext   (drawState, drawCallData)
370         , m_context             (context)
371         , m_program             (vulkanProgram)
372 {
373         const DeviceInterface&  vk                                              = m_context.getDeviceInterface();
374         const VkDevice                  device                                  = m_context.getDevice();
375         Allocator&                              allocator                               = m_context.getDefaultAllocator();
376         VkImageSubresourceRange colorSubresourceRange;
377         Move<VkSampler>                 sampler;
378
379         // Command buffer
380         {
381                 m_cmdPool                       = makeCommandPool(vk, device, m_context.getUniversalQueueFamilyIndex());
382                 m_cmdBuffer                     = makeCommandBuffer(vk, device, *m_cmdPool);
383         }
384
385         // Color attachment image
386         {
387                 const VkImageUsageFlags usage                   = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
388                 colorSubresourceRange                                   = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
389                 const VkImageCreateInfo imageCreateInfo =
390                 {
391                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
392                         DE_NULL,                                                                                                                                        // const void*                          pNext;
393                         (VkImageCreateFlags)0,                                                                                                          // VkImageCreateFlags           flags;
394                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
395                         m_drawState.colorFormat,                                                                                                        // VkFormat                                     format;
396                         makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u),       // VkExtent3D                           extent;
397                         1u,                                                                                                                                                     // uint32_t                                     mipLevels;
398                         1u,                                                                                                                                                     // uint32_t                                     arrayLayers;
399                         (VkSampleCountFlagBits)m_drawState.numSamples,                                                          // VkSampleCountFlagBits        samples;
400                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
401                         usage,                                                                                                                                          // VkImageUsageFlags            usage;
402                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
403                         0u,                                                                                                                                                     // uint32_t                                     queueFamilyIndexCount;
404                         DE_NULL,                                                                                                                                        // const uint32_t*                      pQueueFamilyIndices;
405                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                        initialLayout;
406                 };
407
408                 m_colorImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
409                 m_colorImageView = makeImageView(vk, device, **m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_drawState.colorFormat, colorSubresourceRange);
410
411                 // Buffer to copy attachment data after rendering
412
413                 const VkDeviceSize bitmapSize = tcu::getPixelSize(mapVkFormat(m_drawState.colorFormat)) * m_drawState.renderSize.x() * m_drawState.renderSize.y();
414                 m_colorAttachmentBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
415                         vk, device, allocator, makeBufferCreateInfo(bitmapSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
416
417                 {
418                         const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
419                         deMemset(alloc.getHostPtr(), 0, (size_t)bitmapSize);
420                         flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bitmapSize);
421                 }
422         }
423
424         // Vertex buffer
425         {
426                 const VkDeviceSize bufferSize = m_drawCallData.vertices.size() * sizeof(m_drawCallData.vertices[0]);
427                 m_vertexBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
428                         vk, device, allocator, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
429
430                 const Allocation& alloc = m_vertexBuffer->getAllocation();
431                 deMemcpy(alloc.getHostPtr(), &m_drawCallData.vertices[0], (size_t)bufferSize);
432                 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bufferSize);
433         }
434
435         // bind descriptor sets
436         {
437                 if (!vulkanProgram.descriptorSetLayout)
438                         m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
439                 else
440                         m_pipelineLayout = makePipelineLayout(vk, device, vulkanProgram.descriptorSetLayout);
441         }
442
443         // Renderpass
444         {
445                 std::vector<VkAttachmentDescription> attachmentDescriptions;
446                 const VkAttachmentDescription attachDescriptors[] =
447                 {
448                         {
449                                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
450                                 m_drawState.colorFormat,                                                        // VkFormat                                                     format;
451                                 (VkSampleCountFlagBits)m_drawState.numSamples,          // VkSampleCountFlagBits                        samples;
452                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
453                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
454                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
455                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
456                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                        initialLayout;
457                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
458                         },
459                         {
460                                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags
461                                 m_drawState.depthFormat,                                                        // VkFormat                                                     format
462                                 (VkSampleCountFlagBits)m_drawState.numSamples,          // VkSampleCountFlagBits                        samples
463                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp
464                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp
465                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp
466                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp
467                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                        initialLayout
468                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        finalLayout
469
470                         }
471                 };
472
473                 const VkAttachmentReference attachmentReferences[] =
474                 {
475                         {
476                                 0u,                                                                                                     // uint32_t                     attachment
477                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout
478                         },
479                         {
480                                 1u,                                                                                                     // uint32_t                     attachment
481                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL        // VkImageLayout        layout
482                         },
483                         {
484                                 VK_ATTACHMENT_UNUSED,                                                           // deUint32         attachment;
485                                 VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout    layout;
486                         }
487                 };
488
489                 attachmentDescriptions.push_back(attachDescriptors[0]);
490                 if (!!vulkanProgram.depthImageView)
491                         attachmentDescriptions.push_back(attachDescriptors[1]);
492
493                 deUint32 depthReferenceNdx = !!vulkanProgram.depthImageView ? 1 : 2;
494                 const VkSubpassDescription subpassDescription =
495                 {
496                         (VkSubpassDescriptionFlags)0,                                           // VkSubpassDescriptionFlags            flags;
497                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
498                         0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
499                         DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
500                         1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
501                         &attachmentReferences[0],                                                       // const VkAttachmentReference*         pColorAttachments;
502                         DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
503                         &attachmentReferences[depthReferenceNdx],                       // const VkAttachmentReference*         pDepthStencilAttachment;
504                         0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
505                         DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
506                 };
507
508                 const VkRenderPassCreateInfo renderPassInfo =
509                 {
510                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
511                         DE_NULL,                                                                                        // const void*                                          pNext;
512                         (VkRenderPassCreateFlags)0,                                                     // VkRenderPassCreateFlags                      flags;
513                         (deUint32)attachmentDescriptions.size(),                        // deUint32                                                     attachmentCount;
514                         &attachmentDescriptions[0],                                                     // const VkAttachmentDescription*       pAttachments;
515                         1u,                                                                                                     // deUint32                                                     subpassCount;
516                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
517                         0u,                                                                                                     // deUint32                                                     dependencyCount;
518                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
519                 };
520
521                 m_renderPass = createRenderPass(vk, device, &renderPassInfo);
522         }
523
524         // Framebuffer
525         {
526                 std::vector<VkImageView>        attachmentBindInfos;
527                 deUint32                                        numAttachments;
528                 attachmentBindInfos.push_back(*m_colorImageView);
529                 if (!!vulkanProgram.depthImageView)
530                         attachmentBindInfos.push_back(vulkanProgram.depthImageView);
531
532                 numAttachments = (deUint32)(attachmentBindInfos.size());
533                 const VkFramebufferCreateInfo framebufferInfo = {
534                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,              // VkStructureType                                              sType;
535                         DE_NULL,                                                                                // const void*                                                  pNext;
536                         (VkFramebufferCreateFlags)0,                                    // VkFramebufferCreateFlags                             flags;
537                         *m_renderPass,                                                                  // VkRenderPass                                                 renderPass;
538                         numAttachments,                                                                 // uint32_t                                                             attachmentCount;
539                         &attachmentBindInfos[0],                                                // const VkImageView*                                   pAttachments;
540                         m_drawState.renderSize.x(),                                             // uint32_t                                                             width;
541                         m_drawState.renderSize.y(),                                             // uint32_t                                                             height;
542                         1u,                                                                                             // uint32_t                                                             layers;
543                 };
544
545                 m_framebuffer = createFramebuffer(vk, device, &framebufferInfo);
546         }
547
548         // Graphics pipeline
549         {
550                 const deUint32  vertexStride    = sizeof(Vec4);
551                 const VkFormat  vertexFormat    = VK_FORMAT_R32G32B32A32_SFLOAT;
552
553                 DE_ASSERT(m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST || m_drawState.numPatchControlPoints > 0);
554
555                 const VkVertexInputBindingDescription bindingDesc =
556                 {
557                         0u,                                                                     // uint32_t                             binding;
558                         vertexStride,                                           // uint32_t                             stride;
559                         VK_VERTEX_INPUT_RATE_VERTEX,            // VkVertexInputRate    inputRate;
560                 };
561                 const VkVertexInputAttributeDescription attributeDesc =
562                 {
563                         0u,                                                                     // uint32_t                     location;
564                         0u,                                                                     // uint32_t                     binding;
565                         vertexFormat,                                           // VkFormat                     format;
566                         0u,                                                                     // uint32_t                     offset;
567                 };
568
569                 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
570                 {
571                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                              sType;
572                         DE_NULL,                                                                                                                // const void*                                                                  pNext;
573                         (VkPipelineVertexInputStateCreateFlags)0,                                               // VkPipelineVertexInputStateCreateFlags                flags;
574                         1u,                                                                                                                             // uint32_t                                                                             vertexBindingDescriptionCount;
575                         &bindingDesc,                                                                                                   // const VkVertexInputBindingDescription*               pVertexBindingDescriptions;
576                         1u,                                                                                                                             // uint32_t                                                                             vertexAttributeDescriptionCount;
577                         &attributeDesc,                                                                                                 // const VkVertexInputAttributeDescription*             pVertexAttributeDescriptions;
578                 };
579
580                 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
581                 {
582                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                              sType;
583                         DE_NULL,                                                                                                                // const void*                                                                  pNext;
584                         (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags              flags;
585                         m_drawState.topology,                                                                                   // VkPrimitiveTopology                                                  topology;
586                         VK_FALSE,                                                                                                               // VkBool32                                                                             primitiveRestartEnable;
587                 };
588
589                 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
590                 {
591                         VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,              // VkStructureType                                                              sType;
592                         DE_NULL,                                                                                                                // const void*                                                                  pNext;
593                         (VkPipelineTessellationStateCreateFlags)0,                                              // VkPipelineTessellationStateCreateFlags               flags;
594                         m_drawState.numPatchControlPoints,                                                              // uint32_t                                                                             patchControlPoints;
595                 };
596
597                 const VkViewport viewport = makeViewport(
598                         0.0f, 0.0f,
599                         static_cast<float>(m_drawState.renderSize.x()), static_cast<float>(m_drawState.renderSize.y()),
600                         0.0f, 1.0f);
601
602                 const VkRect2D scissor = {
603                         makeOffset2D(0, 0),
604                         makeExtent2D(m_drawState.renderSize.x(), m_drawState.renderSize.y()),
605                 };
606
607                 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
608                 {
609                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                                                                      sType;
610                         DE_NULL,                                                                                                // const void*                                                                          pNext;
611                         (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewportStateCreateFlags                           flags;
612                         1u,                                                                                                             // uint32_t                                                                                     viewportCount;
613                         &viewport,                                                                                              // const VkViewport*                                                            pViewports;
614                         1u,                                                                                                             // uint32_t                                                                                     scissorCount;
615                         &scissor,                                                                                               // const VkRect2D*                                                                      pScissors;
616                 };
617
618                 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
619                 {
620                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
621                         DE_NULL,                                                                                                                // const void*                                                          pNext;
622                         (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags      flags;
623                         m_drawState.depthClampEnable,                                                                   // VkBool32                                                                     depthClampEnable;
624                         VK_FALSE,                                                                                                               // VkBool32                                                                     rasterizerDiscardEnable;
625                         VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
626                         VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
627                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
628                         VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
629                         0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
630                         0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
631                         0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
632                         m_drawState.lineWidth,                                                                                  // float                                                                        lineWidth;
633                 };
634
635                 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
636                 {
637                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
638                         DE_NULL,                                                                                                        // const void*                                                          pNext;
639                         (VkPipelineMultisampleStateCreateFlags)0,                                       // VkPipelineMultisampleStateCreateFlags        flags;
640                         (VkSampleCountFlagBits)m_drawState.numSamples,                          // VkSampleCountFlagBits                                        rasterizationSamples;
641                         m_drawState.sampleShadingEnable ? VK_TRUE : VK_FALSE,           // VkBool32                                                                     sampleShadingEnable;
642                         m_drawState.sampleShadingEnable ? 1.0f : 0.0f,                          // float                                                                        minSampleShading;
643                         DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
644                         VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
645                         VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
646                 };
647
648                 const VkStencilOpState stencilOpState = makeStencilOpState(
649                         VK_STENCIL_OP_KEEP,             // stencil fail
650                         VK_STENCIL_OP_KEEP,             // depth & stencil pass
651                         VK_STENCIL_OP_KEEP,             // depth only fail
652                         VK_COMPARE_OP_NEVER,    // compare op
653                         0u,                                             // compare mask
654                         0u,                                             // write mask
655                         0u);                                    // reference
656
657                 if (m_drawState.depthBoundsTestEnable && !context.getDeviceFeatures().depthBounds)
658                         TCU_THROW(NotSupportedError, "depthBounds not supported");
659
660                 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
661                 {
662                         VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
663                         DE_NULL,                                                                                                        // const void*                                                          pNext;
664                         (VkPipelineDepthStencilStateCreateFlags)0,                                      // VkPipelineDepthStencilStateCreateFlags       flags;
665                         m_drawState.depthTestEnable,                                                            // VkBool32                                                                     depthTestEnable;
666                         m_drawState.depthWriteEnable,                                                           // VkBool32                                                                     depthWriteEnable;
667                         mapCompareOp(m_drawState.compareOp),                                            // VkCompareOp                                                          depthCompareOp;
668                         m_drawState.depthBoundsTestEnable,                                                      // VkBool32                                                                     depthBoundsTestEnable
669                         VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
670                         stencilOpState,                                                                                         // VkStencilOpState                                                     front;
671                         stencilOpState,                                                                                         // VkStencilOpState                                                     back;
672                         0.0f,                                                                                                           // float                                                                        minDepthBounds;
673                         1.0f,                                                                                                           // float                                                                        maxDepthBounds;
674                 };
675
676                 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
677                 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
678                 {
679                         m_drawState.blendEnable,                        // VkBool32                                     blendEnable;
680                         VK_BLEND_FACTOR_SRC_ALPHA,                      // VkBlendFactor                        srcColorBlendFactor;
681                         VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        dstColorBlendFactor;
682                         VK_BLEND_OP_ADD,                                        // VkBlendOp                            colorBlendOp;
683                         VK_BLEND_FACTOR_SRC_ALPHA,                      // VkBlendFactor                        srcAlphaBlendFactor;
684                         VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        dstAlphaBlendFactor;
685                         VK_BLEND_OP_ADD,                                        // VkBlendOp                            alphaBlendOp;
686                         colorComponentsAll,                                     // VkColorComponentFlags        colorWriteMask;
687                 };
688
689                 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
690                 {
691                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
692                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
693                         (VkPipelineColorBlendStateCreateFlags)0,                                        // VkPipelineColorBlendStateCreateFlags                 flags;
694                         VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
695                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
696                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
697                         &pipelineColorBlendAttachmentState,                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
698                         { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConstants[4];
699                 };
700
701                 // Create shader stages
702
703                 std::vector<VkPipelineShaderStageCreateInfo>    shaderStages;
704                 VkShaderStageFlags                                                              stageFlags = (VkShaderStageFlags)0;
705
706                 DE_ASSERT(m_program.shaders.size() <= MAX_NUM_SHADER_MODULES);
707                 for (deUint32 shaderNdx = 0; shaderNdx < m_program.shaders.size(); ++shaderNdx)
708                 {
709                         m_shaderModules[shaderNdx] = createShaderModule(vk, device, *m_program.shaders[shaderNdx].binary, (VkShaderModuleCreateFlags)0);
710
711                         const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
712                         {
713                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
714                                 DE_NULL,                                                                                                // const void*                                                  pNext;
715                                 (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
716                                 m_program.shaders[shaderNdx].stage,                                             // VkShaderStageFlagBits                                stage;
717                                 *m_shaderModules[shaderNdx],                                                    // VkShaderModule                                               module;
718                                 "main",                                                                                                 // const char*                                                  pName;
719                                 DE_NULL,                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
720                         };
721
722                         shaderStages.push_back(pipelineShaderStageInfo);
723                         stageFlags |= m_program.shaders[shaderNdx].stage;
724                 }
725
726                 DE_ASSERT(
727                         (m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) ||
728                         (stageFlags & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)));
729
730                 const bool tessellationEnabled = (m_drawState.topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
731                 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
732                 {
733                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                                                // VkStructureType                                                                      sType;
734                         DE_NULL,                                                                                                                                // const void*                                                                          pNext;
735                         (VkPipelineCreateFlags)0,                                                                                               // VkPipelineCreateFlags                                                        flags;
736                         static_cast<deUint32>(shaderStages.size()),                                                             // deUint32                                                                                     stageCount;
737                         &shaderStages[0],                                                                                                               // const VkPipelineShaderStageCreateInfo*                       pStages;
738                         &vertexInputStateInfo,                                                                                                  // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
739                         &pipelineInputAssemblyStateInfo,                                                                                // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
740                         (tessellationEnabled ? &pipelineTessellationStateInfo : DE_NULL),               // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
741                         &pipelineViewportStateInfo,                                                                                             // const VkPipelineViewportStateCreateInfo*                     pViewportState;
742                         &pipelineRasterizationStateInfo,                                                                                // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
743                         &pipelineMultisampleStateInfo,                                                                                  // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
744                         &pipelineDepthStencilStateInfo,                                                                                 // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
745                         &pipelineColorBlendStateInfo,                                                                                   // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
746                         DE_NULL,                                                                                                                                // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
747                         *m_pipelineLayout,                                                                                                              // VkPipelineLayout                                                                     layout;
748                         *m_renderPass,                                                                                                                  // VkRenderPass                                                                         renderPass;
749                         0u,                                                                                                                                             // deUint32                                                                                     subpass;
750                         DE_NULL,                                                                                                                                // VkPipeline                                                                           basePipelineHandle;
751                         0,                                                                                                                                              // deInt32                                                                                      basePipelineIndex;
752                 };
753
754                 m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
755         }
756
757         // Record commands
758         {
759                 const VkDeviceSize zeroOffset = 0ull;
760
761                 beginCommandBuffer(vk, *m_cmdBuffer);
762                 if (!!vulkanProgram.descriptorSet)
763                         vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &vulkanProgram.descriptorSet, 0u, DE_NULL);
764
765                 // Begin render pass
766                 {
767                         std::vector<VkClearValue> clearValues;
768
769                         clearValues.push_back(makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
770                         if (!!vulkanProgram.depthImageView)
771                                 clearValues.push_back(makeClearValueDepthStencil(0.0, 0));
772
773                         const VkRect2D          renderArea =
774                         {
775                                 makeOffset2D(0, 0),
776                                 makeExtent2D(m_drawState.renderSize.x(), m_drawState.renderSize.y())
777                         };
778
779                         const VkRenderPassBeginInfo renderPassBeginInfo = {
780                                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                                                       // VkStructureType                                                              sType;
781                                 DE_NULL,                                                                                                                        // const void*                                                                  pNext;
782                                 *m_renderPass,                                                                                                          // VkRenderPass                                                                 renderPass;
783                                 *m_framebuffer,                                                                                                         // VkFramebuffer                                                                framebuffer;
784                                 renderArea,                                                                                                                     // VkRect2D                                                                             renderArea;
785                                 static_cast<deUint32>(clearValues.size()),                                                      // uint32_t                                                                             clearValueCount;
786                                 &clearValues[0],                                                                                                        // const VkClearValue*                                                  pClearValues;
787                         };
788
789                         vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
790                 }
791
792                 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
793                 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(**m_vertexBuffer), &zeroOffset);
794
795                 vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_drawCallData.vertices.size()), 1u, 0u, 0u);
796                 vk.cmdEndRenderPass(*m_cmdBuffer);
797
798                 // Barrier: draw -> copy from image
799                 {
800                         const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
801                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
802                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
803                                 **m_colorImage, colorSubresourceRange);
804
805                         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
806                                 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
807                 }
808
809                 // Resolve multisample image
810                 {
811                         if (m_drawState.numSamples != VK_SAMPLE_COUNT_1_BIT)
812                         {
813                                 const VkImageResolve imageResolve =
814                                 {
815                                         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
816                                         { 0, 0, 0},
817                                         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
818                                         { 0, 0, 0},
819                                         makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u)
820                                 };
821
822                                 const VkImageCreateInfo resolveImageCreateInfo =
823                                 {
824                                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                            // VkStructureType                      sType
825                                         DE_NULL,                                                                                        // const void*                          pNext
826                                         (VkImageCreateFlags)0,                                                          // VkImageCreateFlags           flags
827                                         VK_IMAGE_TYPE_2D,                                                                       // VkImageType                          imageType
828                                         m_drawState.colorFormat,                                                        // VkFormat                                     format
829                                         makeExtent3D(m_drawState.renderSize.x(),                        // VkExtent3D                           extent;
830                                                         m_drawState.renderSize.y(), 1u),
831                                         1u,                                                                                                     // uint32_t                                     mipLevels
832                                         1u,                                                                                                     // uint32_t                                     arrayLayers
833                                         VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits        samples
834                                         VK_IMAGE_TILING_OPTIMAL,                                                        // VkImaageTiling                       tiling
835                                         VK_IMAGE_USAGE_TRANSFER_DST_BIT |                                       // VkImageUsageFlags            usage
836                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
837                                         VK_SHARING_MODE_EXCLUSIVE,                                                      // VkSharingModeExclusive       sharingMode
838                                         0u,                                                                                                     // uint32_t                                     queueFamilyIndexCount
839                                         DE_NULL,                                                                                        // const uint32_t*                      pQueueFamilyIndices
840                                         VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout                        initialLayout
841                                 };
842
843                                 m_resolveImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, resolveImageCreateInfo, MemoryRequirement::Any));
844
845                                 const VkImageMemoryBarrier resolveBarrier = makeImageMemoryBarrier(
846                                                 0u, VK_ACCESS_TRANSFER_READ_BIT,
847                                                 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
848                                                 **m_resolveImage, colorSubresourceRange);
849
850                                 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
851                                                 0u, DE_NULL, 0u, DE_NULL, 1u, &resolveBarrier);
852
853                                 vk.cmdResolveImage(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
854                                                 **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &imageResolve);
855
856                                 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
857                                         VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
858                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
859                                         **m_resolveImage, colorSubresourceRange);
860
861                                 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
862                                         0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
863                         }
864                         else
865                                 m_resolveImage = m_colorImage;
866
867                         const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
868                                         makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u));
869                         vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, &copyRegion);
870                 }
871
872                 // Barrier: copy to buffer -> host read
873                 {
874                         const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(
875                                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
876                                 **m_colorAttachmentBuffer, 0ull, VK_WHOLE_SIZE);
877
878                         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
879                                 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
880                 }
881
882                 endCommandBuffer(vk, *m_cmdBuffer);
883         }
884 }
885
886 VulkanDrawContext::~VulkanDrawContext (void)
887 {
888 }
889
890 void VulkanDrawContext::draw (void)
891 {
892         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
893         const VkDevice                  device          = m_context.getDevice();
894         const VkQueue                   queue           = m_context.getUniversalQueue();
895         tcu::TestLog&                   log                     = m_context.getTestContext().getLog();
896
897         submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
898
899         log << tcu::LogImageSet("attachments", "") << tcu::LogImage("color0", "", getColorPixels()) << tcu::TestLog::EndImageSet;
900 }
901
902 tcu::ConstPixelBufferAccess VulkanDrawContext::getColorPixels (void) const
903 {
904         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
905         const VkDevice                  device          = m_context.getDevice();
906
907         const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
908         invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), VK_WHOLE_SIZE);
909
910         return tcu::ConstPixelBufferAccess(mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u, alloc.getHostPtr());
911 }
912 } // drawutil
913 } // vkt