Add new draw elements base vertex tests am: 3c865084eb
[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         , blendEnable                   (false)
316         , lineWidth                             (1.0)
317         , numPatchControlPoints (0)
318         , numSamples                    (VK_SAMPLE_COUNT_1_BIT)
319         , sampleShadingEnable   (false)
320 {
321         DE_ASSERT(renderSize.x() != 0 && renderSize.y() != 0);
322 }
323
324 ReferenceDrawContext::~ReferenceDrawContext (void)
325 {
326 }
327
328 void ReferenceDrawContext::draw (void)
329 {
330         m_refImage.setStorage(vk::mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y());
331         tcu::clear(m_refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
332
333         {
334                 const rr::Program                                               program(&m_vertexShader, &m_fragmentShader);
335                 const rr::MultisamplePixelBufferAccess  referenceColorBuffer = rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(m_refImage.getAccess());
336                 const rr::RenderTarget                                  renderTarget(referenceColorBuffer);
337                 const rr::RenderState                                   renderState((rr::ViewportState(referenceColorBuffer)), rr::VIEWPORTORIENTATION_UPPER_LEFT);
338                 const rr::Renderer                                              renderer;
339                 const rr::VertexAttrib                                  vertexAttrib[] =
340                 {
341                         rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &m_drawCallData.vertices[0])
342                 };
343
344                 renderer.draw(rr::DrawCommand(  renderState,
345                                                                                 renderTarget,
346                                                                                 program,
347                                                                                 DE_LENGTH_OF_ARRAY(vertexAttrib),
348                                                                                 &vertexAttrib[0],
349                                                                                 rr::PrimitiveList(mapVkPrimitiveToRRPrimitive(m_drawState.topology), (int)m_drawCallData.vertices.size(), 0)));
350
351         }
352
353 }
354
355 tcu::ConstPixelBufferAccess ReferenceDrawContext::getColorPixels (void) const
356 {
357         return tcu::ConstPixelBufferAccess( m_refImage.getAccess().getFormat(),
358                                                                                 m_refImage.getAccess().getWidth(),
359                                                                                 m_refImage.getAccess().getHeight(),
360                                                                                 m_refImage.getAccess().getDepth(),
361                                                                                 m_refImage.getAccess().getDataPtr());
362 }
363
364 VulkanDrawContext::VulkanDrawContext (  Context&                                context,
365                                                                                 const DrawState&                drawState,
366                                                                                 const DrawCallData&             drawCallData,
367                                                                                 VulkanProgram&  vulkanProgram)
368         : DrawContext                                           (drawState, drawCallData)
369         , m_context                                                     (context)
370         , m_program                                                     (vulkanProgram)
371 {
372         const DeviceInterface&  vk                                              = m_context.getDeviceInterface();
373         const VkDevice                  device                                  = m_context.getDevice();
374         Allocator&                              allocator                               = m_context.getDefaultAllocator();
375         VkImageSubresourceRange colorSubresourceRange;
376         Move<VkSampler>                 sampler;
377
378         // Command buffer
379         {
380                 m_cmdPool                       = makeCommandPool(vk, device, m_context.getUniversalQueueFamilyIndex());
381                 m_cmdBuffer                     = makeCommandBuffer(vk, device, *m_cmdPool);
382         }
383
384         // Color attachment image
385         {
386                 const VkImageUsageFlags usage                   = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
387                 colorSubresourceRange                                   = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
388                 const VkImageCreateInfo imageCreateInfo =
389                 {
390                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
391                         DE_NULL,                                                                                                                                        // const void*                          pNext;
392                         (VkImageCreateFlags)0,                                                                                                          // VkImageCreateFlags           flags;
393                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
394                         m_drawState.colorFormat,                                                                                                        // VkFormat                                     format;
395                         makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u),       // VkExtent3D                           extent;
396                         1u,                                                                                                                                                     // uint32_t                                     mipLevels;
397                         1u,                                                                                                                                                     // uint32_t                                     arrayLayers;
398                         (VkSampleCountFlagBits)m_drawState.numSamples,                                                          // VkSampleCountFlagBits        samples;
399                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
400                         usage,                                                                                                                                          // VkImageUsageFlags            usage;
401                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
402                         0u,                                                                                                                                                     // uint32_t                                     queueFamilyIndexCount;
403                         DE_NULL,                                                                                                                                        // const uint32_t*                      pQueueFamilyIndices;
404                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                        initialLayout;
405                 };
406
407                 m_colorImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
408                 m_colorImageView = makeImageView(vk, device, **m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_drawState.colorFormat, colorSubresourceRange);
409
410                 // Buffer to copy attachment data after rendering
411
412                 const VkDeviceSize bitmapSize = tcu::getPixelSize(mapVkFormat(m_drawState.colorFormat)) * m_drawState.renderSize.x() * m_drawState.renderSize.y();
413                 m_colorAttachmentBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
414                         vk, device, allocator, makeBufferCreateInfo(bitmapSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
415
416                 {
417                         const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
418                         deMemset(alloc.getHostPtr(), 0, (size_t)bitmapSize);
419                         flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bitmapSize);
420                 }
421         }
422
423         // Vertex buffer
424         {
425                 const VkDeviceSize bufferSize = m_drawCallData.vertices.size() * sizeof(m_drawCallData.vertices[0]);
426                 m_vertexBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
427                         vk, device, allocator, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
428
429                 const Allocation& alloc = m_vertexBuffer->getAllocation();
430                 deMemcpy(alloc.getHostPtr(), &m_drawCallData.vertices[0], (size_t)bufferSize);
431                 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bufferSize);
432         }
433
434         // bind descriptor sets
435         {
436                 if (!vulkanProgram.descriptorSetLayout)
437                         m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
438                 else
439                         m_pipelineLayout = makePipelineLayout(vk, device, vulkanProgram.descriptorSetLayout.get());
440         }
441
442         // Renderpass
443         {
444                 std::vector<VkAttachmentDescription> attachmentDescriptions;
445                 const VkAttachmentDescription attachDescriptors[] =
446                 {
447                         {
448                                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
449                                 m_drawState.colorFormat,                                                        // VkFormat                                                     format;
450                                 (VkSampleCountFlagBits)m_drawState.numSamples,          // VkSampleCountFlagBits                        samples;
451                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
452                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
453                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
454                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
455                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                        initialLayout;
456                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
457                         },
458                         {
459                                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags
460                                 m_drawState.depthFormat,                                                        // VkFormat                                                     format
461                                 (VkSampleCountFlagBits)m_drawState.numSamples,          // VkSampleCountFlagBits                        samples
462                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp
463                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp
464                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp
465                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp
466                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                        initialLayout
467                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        finalLayout
468
469                         }
470                 };
471
472                 const VkAttachmentReference attachmentReferences[] =
473                 {
474                         {
475                                 0u,                                                                                                     // uint32_t                     attachment
476                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout
477                         },
478                         {
479                                 1u,                                                                                                     // uint32_t                     attachment
480                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL        // VkImageLayout        layout
481                         },
482                         {
483                                 VK_ATTACHMENT_UNUSED,                                                           // deUint32         attachment;
484                                 VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout    layout;
485                         }
486                 };
487
488                 attachmentDescriptions.push_back(attachDescriptors[0]);
489                 if (vulkanProgram.depthImageView)
490                         attachmentDescriptions.push_back(attachDescriptors[1]);
491
492                 deUint32 depthReferenceNdx = vulkanProgram.depthImageView ? 1 : 2;
493                 const VkSubpassDescription subpassDescription =
494                 {
495                         (VkSubpassDescriptionFlags)0,                                           // VkSubpassDescriptionFlags            flags;
496                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
497                         0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
498                         DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
499                         1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
500                         &attachmentReferences[0],                                                       // const VkAttachmentReference*         pColorAttachments;
501                         DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
502                         &attachmentReferences[depthReferenceNdx],                       // const VkAttachmentReference*         pDepthStencilAttachment;
503                         0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
504                         DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
505                 };
506
507                 const VkRenderPassCreateInfo renderPassInfo =
508                 {
509                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
510                         DE_NULL,                                                                                        // const void*                                          pNext;
511                         (VkRenderPassCreateFlags)0,                                                     // VkRenderPassCreateFlags                      flags;
512                         (deUint32)attachmentDescriptions.size(),                        // deUint32                                                     attachmentCount;
513                         &attachmentDescriptions[0],                                                     // const VkAttachmentDescription*       pAttachments;
514                         1u,                                                                                                     // deUint32                                                     subpassCount;
515                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
516                         0u,                                                                                                     // deUint32                                                     dependencyCount;
517                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
518                 };
519
520                 m_renderPass = createRenderPass(vk, device, &renderPassInfo);
521         }
522
523         // Framebuffer
524         {
525                 std::vector<VkImageView>        attachmentBindInfos;
526                 deUint32                                        numAttachments;
527                 attachmentBindInfos.push_back(*m_colorImageView);
528                 if (vulkanProgram.depthImageView)
529                         attachmentBindInfos.push_back(*vulkanProgram.depthImageView);
530
531                 numAttachments = (deUint32)(attachmentBindInfos.size());
532                 const VkFramebufferCreateInfo framebufferInfo = {
533                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,              // VkStructureType                                              sType;
534                         DE_NULL,                                                                                // const void*                                                  pNext;
535                         (VkFramebufferCreateFlags)0,                                    // VkFramebufferCreateFlags                             flags;
536                         *m_renderPass,                                                                  // VkRenderPass                                                 renderPass;
537                         numAttachments,                                                                 // uint32_t                                                             attachmentCount;
538                         &attachmentBindInfos[0],                                                // const VkImageView*                                   pAttachments;
539                         m_drawState.renderSize.x(),                                             // uint32_t                                                             width;
540                         m_drawState.renderSize.y(),                                             // uint32_t                                                             height;
541                         1u,                                                                                             // uint32_t                                                             layers;
542                 };
543
544                 m_framebuffer = createFramebuffer(vk, device, &framebufferInfo);
545         }
546
547         // Graphics pipeline
548         {
549                 const deUint32  vertexStride    = sizeof(Vec4);
550                 const VkFormat  vertexFormat    = VK_FORMAT_R32G32B32A32_SFLOAT;
551
552                 DE_ASSERT(m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST || m_drawState.numPatchControlPoints > 0);
553
554                 const VkVertexInputBindingDescription bindingDesc =
555                 {
556                         0u,                                                                     // uint32_t                             binding;
557                         vertexStride,                                           // uint32_t                             stride;
558                         VK_VERTEX_INPUT_RATE_VERTEX,            // VkVertexInputRate    inputRate;
559                 };
560                 const VkVertexInputAttributeDescription attributeDesc =
561                 {
562                         0u,                                                                     // uint32_t                     location;
563                         0u,                                                                     // uint32_t                     binding;
564                         vertexFormat,                                           // VkFormat                     format;
565                         0u,                                                                     // uint32_t                     offset;
566                 };
567
568                 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
569                 {
570                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                              sType;
571                         DE_NULL,                                                                                                                // const void*                                                                  pNext;
572                         (VkPipelineVertexInputStateCreateFlags)0,                                               // VkPipelineVertexInputStateCreateFlags                flags;
573                         1u,                                                                                                                             // uint32_t                                                                             vertexBindingDescriptionCount;
574                         &bindingDesc,                                                                                                   // const VkVertexInputBindingDescription*               pVertexBindingDescriptions;
575                         1u,                                                                                                                             // uint32_t                                                                             vertexAttributeDescriptionCount;
576                         &attributeDesc,                                                                                                 // const VkVertexInputAttributeDescription*             pVertexAttributeDescriptions;
577                 };
578
579                 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
580                 {
581                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                              sType;
582                         DE_NULL,                                                                                                                // const void*                                                                  pNext;
583                         (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags              flags;
584                         m_drawState.topology,                                                                                   // VkPrimitiveTopology                                                  topology;
585                         VK_FALSE,                                                                                                               // VkBool32                                                                             primitiveRestartEnable;
586                 };
587
588                 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
589                 {
590                         VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,              // VkStructureType                                                              sType;
591                         DE_NULL,                                                                                                                // const void*                                                                  pNext;
592                         (VkPipelineTessellationStateCreateFlags)0,                                              // VkPipelineTessellationStateCreateFlags               flags;
593                         m_drawState.numPatchControlPoints,                                                              // uint32_t                                                                             patchControlPoints;
594                 };
595
596                 const VkViewport viewport = makeViewport(
597                         0.0f, 0.0f,
598                         static_cast<float>(m_drawState.renderSize.x()), static_cast<float>(m_drawState.renderSize.y()),
599                         0.0f, 1.0f);
600
601                 const VkRect2D scissor = {
602                         makeOffset2D(0, 0),
603                         makeExtent2D(m_drawState.renderSize.x(), m_drawState.renderSize.y()),
604                 };
605
606                 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
607                 {
608                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                                                                      sType;
609                         DE_NULL,                                                                                                // const void*                                                                          pNext;
610                         (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewportStateCreateFlags                           flags;
611                         1u,                                                                                                             // uint32_t                                                                                     viewportCount;
612                         &viewport,                                                                                              // const VkViewport*                                                            pViewports;
613                         1u,                                                                                                             // uint32_t                                                                                     scissorCount;
614                         &scissor,                                                                                               // const VkRect2D*                                                                      pScissors;
615                 };
616
617                 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
618                 {
619                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
620                         DE_NULL,                                                                                                                // const void*                                                          pNext;
621                         (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags      flags;
622                         m_drawState.depthClampEnable,                                                                   // VkBool32                                                                     depthClampEnable;
623                         VK_FALSE,                                                                                                               // VkBool32                                                                     rasterizerDiscardEnable;
624                         VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
625                         VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
626                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
627                         VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
628                         0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
629                         0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
630                         0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
631                         m_drawState.lineWidth,                                                                                  // float                                                                        lineWidth;
632                 };
633
634                 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
635                 {
636                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
637                         DE_NULL,                                                                                                        // const void*                                                          pNext;
638                         (VkPipelineMultisampleStateCreateFlags)0,                                       // VkPipelineMultisampleStateCreateFlags        flags;
639                         (VkSampleCountFlagBits)m_drawState.numSamples,                          // VkSampleCountFlagBits                                        rasterizationSamples;
640                         m_drawState.sampleShadingEnable ? VK_TRUE : VK_FALSE,           // VkBool32                                                                     sampleShadingEnable;
641                         m_drawState.sampleShadingEnable ? 1.0f : 0.0f,                          // float                                                                        minSampleShading;
642                         DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
643                         VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
644                         VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
645                 };
646
647                 const VkStencilOpState stencilOpState = makeStencilOpState(
648                         VK_STENCIL_OP_KEEP,             // stencil fail
649                         VK_STENCIL_OP_KEEP,             // depth & stencil pass
650                         VK_STENCIL_OP_KEEP,             // depth only fail
651                         VK_COMPARE_OP_NEVER,    // compare op
652                         0u,                                             // compare mask
653                         0u,                                             // write mask
654                         0u);                                    // reference
655
656                 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
657                 {
658                         VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
659                         DE_NULL,                                                                                                        // const void*                                                          pNext;
660                         (VkPipelineDepthStencilStateCreateFlags)0,                                      // VkPipelineDepthStencilStateCreateFlags       flags;
661                         m_drawState.depthTestEnable,                                                            // VkBool32                                                                     depthTestEnable;
662                         m_drawState.depthWriteEnable,                                                           // VkBool32                                                                     depthWriteEnable;
663                         mapCompareOp(m_drawState.compareOp),                                            // VkCompareOp                                                          depthCompareOp;
664                         VK_TRUE,                                                                                                        // VkBool32                                                                     depthBoundsTestEnable;
665                         VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
666                         stencilOpState,                                                                                         // VkStencilOpState                                                     front;
667                         stencilOpState,                                                                                         // VkStencilOpState                                                     back;
668                         0.0f,                                                                                                           // float                                                                        minDepthBounds;
669                         1.0f,                                                                                                           // float                                                                        maxDepthBounds;
670                 };
671
672                 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
673                 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
674                 {
675                         m_drawState.blendEnable,                        // VkBool32                                     blendEnable;
676                         VK_BLEND_FACTOR_SRC_ALPHA,                      // VkBlendFactor                        srcColorBlendFactor;
677                         VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        dstColorBlendFactor;
678                         VK_BLEND_OP_ADD,                                        // VkBlendOp                            colorBlendOp;
679                         VK_BLEND_FACTOR_SRC_ALPHA,                      // VkBlendFactor                        srcAlphaBlendFactor;
680                         VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        dstAlphaBlendFactor;
681                         VK_BLEND_OP_ADD,                                        // VkBlendOp                            alphaBlendOp;
682                         colorComponentsAll,                                     // VkColorComponentFlags        colorWriteMask;
683                 };
684
685                 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
686                 {
687                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
688                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
689                         (VkPipelineColorBlendStateCreateFlags)0,                                        // VkPipelineColorBlendStateCreateFlags                 flags;
690                         VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
691                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
692                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
693                         &pipelineColorBlendAttachmentState,                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
694                         { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConstants[4];
695                 };
696
697                 // Create shader stages
698
699                 std::vector<VkPipelineShaderStageCreateInfo>    shaderStages;
700                 VkShaderStageFlags                                                              stageFlags = (VkShaderStageFlags)0;
701
702                 DE_ASSERT(m_program.shaders.size() <= MAX_NUM_SHADER_MODULES);
703                 for (deUint32 shaderNdx = 0; shaderNdx < m_program.shaders.size(); ++shaderNdx)
704                 {
705                         m_shaderModules[shaderNdx] = createShaderModule(vk, device, *m_program.shaders[shaderNdx].binary, (VkShaderModuleCreateFlags)0);
706
707                         const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
708                         {
709                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
710                                 DE_NULL,                                                                                                // const void*                                                  pNext;
711                                 (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
712                                 m_program.shaders[shaderNdx].stage,                                             // VkShaderStageFlagBits                                stage;
713                                 *m_shaderModules[shaderNdx],                                                    // VkShaderModule                                               module;
714                                 "main",                                                                                                 // const char*                                                  pName;
715                                 DE_NULL,                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
716                         };
717
718                         shaderStages.push_back(pipelineShaderStageInfo);
719                         stageFlags |= m_program.shaders[shaderNdx].stage;
720                 }
721
722                 DE_ASSERT(
723                         (m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) ||
724                         (stageFlags & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)));
725
726                 const bool tessellationEnabled = (m_drawState.topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST);
727                 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
728                 {
729                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                                                // VkStructureType                                                                      sType;
730                         DE_NULL,                                                                                                                                // const void*                                                                          pNext;
731                         (VkPipelineCreateFlags)0,                                                                                               // VkPipelineCreateFlags                                                        flags;
732                         static_cast<deUint32>(shaderStages.size()),                                                             // deUint32                                                                                     stageCount;
733                         &shaderStages[0],                                                                                                               // const VkPipelineShaderStageCreateInfo*                       pStages;
734                         &vertexInputStateInfo,                                                                                                  // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
735                         &pipelineInputAssemblyStateInfo,                                                                                // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
736                         (tessellationEnabled ? &pipelineTessellationStateInfo : DE_NULL),               // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
737                         &pipelineViewportStateInfo,                                                                                             // const VkPipelineViewportStateCreateInfo*                     pViewportState;
738                         &pipelineRasterizationStateInfo,                                                                                // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
739                         &pipelineMultisampleStateInfo,                                                                                  // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
740                         &pipelineDepthStencilStateInfo,                                                                                 // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
741                         &pipelineColorBlendStateInfo,                                                                                   // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
742                         DE_NULL,                                                                                                                                // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
743                         *m_pipelineLayout,                                                                                                              // VkPipelineLayout                                                                     layout;
744                         *m_renderPass,                                                                                                                  // VkRenderPass                                                                         renderPass;
745                         0u,                                                                                                                                             // deUint32                                                                                     subpass;
746                         DE_NULL,                                                                                                                                // VkPipeline                                                                           basePipelineHandle;
747                         0,                                                                                                                                              // deInt32                                                                                      basePipelineIndex;
748                 };
749
750                 m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
751         }
752
753         // Record commands
754         {
755                 const VkDeviceSize zeroOffset = 0ull;
756
757                 beginCommandBuffer(vk, *m_cmdBuffer);
758                 if (vulkanProgram.descriptorSet)
759                         vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &*vulkanProgram.descriptorSet, 0u, DE_NULL);
760
761                 // Begin render pass
762                 {
763                         std::vector<VkClearValue> clearValues;
764
765                         clearValues.push_back(makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
766                         if (vulkanProgram.depthImageView)
767                                 clearValues.push_back(makeClearValueDepthStencil(0.0, 0));
768
769                         const VkRect2D          renderArea =
770                         {
771                                 makeOffset2D(0, 0),
772                                 makeExtent2D(m_drawState.renderSize.x(), m_drawState.renderSize.y())
773                         };
774
775                         const VkRenderPassBeginInfo renderPassBeginInfo = {
776                                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                                                       // VkStructureType                                                              sType;
777                                 DE_NULL,                                                                                                                        // const void*                                                                  pNext;
778                                 *m_renderPass,                                                                                                          // VkRenderPass                                                                 renderPass;
779                                 *m_framebuffer,                                                                                                         // VkFramebuffer                                                                framebuffer;
780                                 renderArea,                                                                                                                     // VkRect2D                                                                             renderArea;
781                                 static_cast<deUint32>(clearValues.size()),                                                      // uint32_t                                                                             clearValueCount;
782                                 &clearValues[0],                                                                                                        // const VkClearValue*                                                  pClearValues;
783                         };
784
785                         vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
786                 }
787
788                 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
789                 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(**m_vertexBuffer), &zeroOffset);
790
791                 vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_drawCallData.vertices.size()), 1u, 0u, 0u);
792                 vk.cmdEndRenderPass(*m_cmdBuffer);
793
794                 // Barrier: draw -> copy from image
795                 {
796                         const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
797                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
798                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
799                                 **m_colorImage, colorSubresourceRange);
800
801                         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
802                                 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
803                 }
804
805                 // Resolve multisample image
806                 {
807                         if (m_drawState.numSamples != VK_SAMPLE_COUNT_1_BIT)
808                         {
809                                 const VkImageResolve imageResolve =
810                                 {
811                                         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
812                                         { 0, 0, 0},
813                                         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
814                                         { 0, 0, 0},
815                                         makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u)
816                                 };
817
818                                 const VkImageCreateInfo resolveImageCreateInfo =
819                                 {
820                                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                            // VkStructureType                      sType
821                                         DE_NULL,                                                                                        // const void*                          pNext
822                                         (VkImageCreateFlags)0,                                                          // VkImageCreateFlags           flags
823                                         VK_IMAGE_TYPE_2D,                                                                       // VkImageType                          imageType
824                                         m_drawState.colorFormat,                                                        // VkFormat                                     format
825                                         makeExtent3D(m_drawState.renderSize.x(),                        // VkExtent3D                           extent;
826                                                         m_drawState.renderSize.y(), 1u),
827                                         1u,                                                                                                     // uint32_t                                     mipLevels
828                                         1u,                                                                                                     // uint32_t                                     arrayLayers
829                                         VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits        samples
830                                         VK_IMAGE_TILING_OPTIMAL,                                                        // VkImaageTiling                       tiling
831                                         VK_IMAGE_USAGE_TRANSFER_DST_BIT |                                       // VkImageUsageFlags            usage
832                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
833                                         VK_SHARING_MODE_EXCLUSIVE,                                                      // VkSharingModeExclusive       sharingMode
834                                         0u,                                                                                                     // uint32_t                                     queueFamilyIndexCount
835                                         DE_NULL,                                                                                        // const uint32_t*                      pQueueFamilyIndices
836                                         VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout                        initialLayout
837                                 };
838
839                                 m_resolveImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, resolveImageCreateInfo, MemoryRequirement::Any));
840
841                                 const VkImageMemoryBarrier resolveBarrier = makeImageMemoryBarrier(
842                                                 0u, VK_ACCESS_TRANSFER_READ_BIT,
843                                                 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
844                                                 **m_resolveImage, colorSubresourceRange);
845
846                                 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
847                                                 0u, DE_NULL, 0u, DE_NULL, 1u, &resolveBarrier);
848
849                                 vk.cmdResolveImage(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
850                                                 **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &imageResolve);
851
852                                 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
853                                         VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
854                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
855                                         **m_resolveImage, colorSubresourceRange);
856
857                                 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
858                                         0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
859                         }
860                         else
861                                 m_resolveImage = m_colorImage;
862
863                         const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
864                                         makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u));
865                         vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, &copyRegion);
866                 }
867
868                 // Barrier: copy to buffer -> host read
869                 {
870                         const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(
871                                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
872                                 **m_colorAttachmentBuffer, 0ull, VK_WHOLE_SIZE);
873
874                         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
875                                 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
876                 }
877
878                 endCommandBuffer(vk, *m_cmdBuffer);
879         }
880 }
881
882 VulkanDrawContext::~VulkanDrawContext (void)
883 {
884 }
885
886 void VulkanDrawContext::draw (void)
887 {
888         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
889         const VkDevice                  device          = m_context.getDevice();
890         const VkQueue                   queue           = m_context.getUniversalQueue();
891         tcu::TestLog&                   log                     = m_context.getTestContext().getLog();
892
893         submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
894
895         log << tcu::LogImageSet("attachments", "") << tcu::LogImage("color0", "", getColorPixels()) << tcu::TestLog::EndImageSet;
896 }
897
898 tcu::ConstPixelBufferAccess VulkanDrawContext::getColorPixels (void) const
899 {
900         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
901         const VkDevice                  device          = m_context.getDevice();
902
903         const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
904         invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), VK_WHOLE_SIZE);
905
906         return tcu::ConstPixelBufferAccess(mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u, alloc.getHostPtr());
907 }
908 } // drawutil
909 } // vkt