Merge vk-gl-cts/vulkan-cts-1.1.4 into vk-gl-cts/vulkan-cts-1.1.5
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / util / 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 "vkBarrierUtil.hpp"
30 #include "vkTypeUtil.hpp"
31 #include "vkCmdUtil.hpp"
32 #include "vkObjUtil.hpp"
33 #include "rrRenderer.hpp"
34 #include "rrRenderState.hpp"
35 #include "rrPrimitiveTypes.hpp"
36 #include "tcuTextureUtil.hpp"
37 #include "tcuTestLog.hpp"
38 #include "deArrayUtil.hpp"
39 #include "vkBuilderUtil.hpp"
40 #include "vkCmdUtil.hpp"
41
42 namespace vkt
43 {
44 namespace drawutil
45 {
46
47 using namespace de;
48 using namespace tcu;
49 using namespace vk;
50
51 static VkCompareOp mapCompareOp (rr::TestFunc compareFunc)
52 {
53         switch (compareFunc)
54         {
55                 case rr::TESTFUNC_NEVER:                                return VK_COMPARE_OP_NEVER;
56                 case rr::TESTFUNC_LESS:                                 return VK_COMPARE_OP_LESS;
57                 case rr::TESTFUNC_EQUAL:                                return VK_COMPARE_OP_EQUAL;
58                 case rr::TESTFUNC_LEQUAL:                               return VK_COMPARE_OP_LESS_OR_EQUAL;
59                 case rr::TESTFUNC_GREATER:                              return VK_COMPARE_OP_GREATER;
60                 case rr::TESTFUNC_NOTEQUAL:                             return VK_COMPARE_OP_NOT_EQUAL;
61                 case rr::TESTFUNC_GEQUAL:                               return VK_COMPARE_OP_GREATER_OR_EQUAL;
62                 case rr::TESTFUNC_ALWAYS:                               return VK_COMPARE_OP_ALWAYS;
63                 default:
64                         DE_ASSERT(false);
65         }
66         return VK_COMPARE_OP_LAST;
67 }
68
69 rr::PrimitiveType mapVkPrimitiveToRRPrimitive(const vk::VkPrimitiveTopology& primitiveTopology)
70 {
71         static const rr::PrimitiveType primitiveTypeTable[] =
72         {
73                 rr::PRIMITIVETYPE_POINTS,
74                 rr::PRIMITIVETYPE_LINES,
75                 rr::PRIMITIVETYPE_LINE_STRIP,
76                 rr::PRIMITIVETYPE_TRIANGLES,
77                 rr::PRIMITIVETYPE_TRIANGLE_STRIP,
78                 rr::PRIMITIVETYPE_TRIANGLE_FAN,
79                 rr::PRIMITIVETYPE_LINES_ADJACENCY,
80                 rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY,
81                 rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY,
82                 rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY
83         };
84
85         return de::getSizedArrayElement<vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST>(primitiveTypeTable, primitiveTopology);
86 }
87
88 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
89 {
90         const VkCommandBufferAllocateInfo info =
91         {
92                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,         // VkStructureType              sType;
93                 DE_NULL,                                                                                        // const void*                  pNext;
94                 commandPool,                                                                            // VkCommandPool                commandPool;
95                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                        // VkCommandBufferLevel level;
96                 1u,                                                                                                     // deUint32                             commandBufferCount;
97         };
98         return allocateCommandBuffer(vk, device, &info);
99 }
100
101 VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers   subresourceLayers,
102                                                                            const VkExtent3D                                     extent)
103 {
104         const VkBufferImageCopy copyParams =
105         {
106                 0ull,                                                                           //      VkDeviceSize                            bufferOffset;
107                 0u,                                                                                     //      deUint32                                        bufferRowLength;
108                 0u,                                                                                     //      deUint32                                        bufferImageHeight;
109                 subresourceLayers,                                                      //      VkImageSubresourceLayers        imageSubresource;
110                 makeOffset3D(0, 0, 0),                                          //      VkOffset3D                                      imageOffset;
111                 extent,                                                                         //      VkExtent3D                                      imageExtent;
112         };
113         return copyParams;
114 }
115
116 std::string getPrimitiveTopologyShortName (const VkPrimitiveTopology topology)
117 {
118         std::string name(getPrimitiveTopologyName(topology));
119         return de::toLower(name.substr(22));
120 }
121
122 DrawState::DrawState(const vk::VkPrimitiveTopology topology_, deUint32 renderWidth_, deUint32 renderHeight_, const int subpixelBits_)
123         : topology                                      (topology_)
124         , colorFormat                           (VK_FORMAT_R8G8B8A8_UNORM)
125         , renderSize                            (tcu::UVec2(renderWidth_, renderHeight_))
126         , depthClampEnable                      (false)
127         , depthTestEnable                       (false)
128         , depthWriteEnable                      (false)
129         , compareOp                                     (rr::TESTFUNC_LESS)
130         , depthBoundsTestEnable         (false)
131         , blendEnable                           (false)
132         , lineWidth                                     (1.0)
133         , numPatchControlPoints         (0)
134         , numSamples                            (VK_SAMPLE_COUNT_1_BIT)
135         , sampleShadingEnable           (false)
136         , subpixelBits                  (subpixelBits_)
137         , explicitDepthClipEnable       (false)
138         , depthClipEnable                       (false)
139 {
140         DE_ASSERT(renderSize.x() != 0 && renderSize.y() != 0);
141 }
142
143 ReferenceDrawContext::~ReferenceDrawContext (void)
144 {
145 }
146
147 void ReferenceDrawContext::draw (void)
148 {
149         m_refImage.setStorage(vk::mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y());
150         tcu::clear(m_refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
151
152         {
153                 const rr::Program                                               program(&m_vertexShader, &m_fragmentShader);
154                 const rr::MultisamplePixelBufferAccess  referenceColorBuffer = rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(m_refImage.getAccess());
155                 const rr::RenderTarget                                  renderTarget(referenceColorBuffer);
156                 const rr::RenderState                                   renderState((rr::ViewportState(referenceColorBuffer)), m_drawState.subpixelBits, rr::VIEWPORTORIENTATION_UPPER_LEFT);
157                 const rr::Renderer                                              renderer;
158                 const rr::VertexAttrib                                  vertexAttrib[] =
159                 {
160                         rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &m_drawCallData.vertices[0])
161                 };
162
163                 renderer.draw(rr::DrawCommand(  renderState,
164                                                                                 renderTarget,
165                                                                                 program,
166                                                                                 DE_LENGTH_OF_ARRAY(vertexAttrib),
167                                                                                 &vertexAttrib[0],
168                                                                                 rr::PrimitiveList(mapVkPrimitiveToRRPrimitive(m_drawState.topology), (int)m_drawCallData.vertices.size(), 0)));
169
170         }
171
172 }
173
174 tcu::ConstPixelBufferAccess ReferenceDrawContext::getColorPixels (void) const
175 {
176         return tcu::ConstPixelBufferAccess( m_refImage.getAccess().getFormat(),
177                                                                                 m_refImage.getAccess().getWidth(),
178                                                                                 m_refImage.getAccess().getHeight(),
179                                                                                 m_refImage.getAccess().getDepth(),
180                                                                                 m_refImage.getAccess().getDataPtr());
181 }
182
183 VulkanDrawContext::VulkanDrawContext (Context&                          context,
184                                                                           const DrawState&              drawState,
185                                                                           const DrawCallData&   drawCallData,
186                                                                           const VulkanProgram&  vulkanProgram)
187         : DrawContext   (drawState, drawCallData)
188         , m_context             (context)
189         , m_program             (vulkanProgram)
190 {
191         const DeviceInterface&  vk                                              = m_context.getDeviceInterface();
192         const VkDevice                  device                                  = m_context.getDevice();
193         Allocator&                              allocator                               = m_context.getDefaultAllocator();
194         VkImageSubresourceRange colorSubresourceRange;
195         Move<VkSampler>                 sampler;
196
197         // Command buffer
198         {
199                 m_cmdPool                       = makeCommandPool(vk, device, m_context.getUniversalQueueFamilyIndex());
200                 m_cmdBuffer                     = makeCommandBuffer(vk, device, *m_cmdPool);
201         }
202
203         // Color attachment image
204         {
205                 const VkImageUsageFlags usage                   = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
206                 colorSubresourceRange                                   = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
207                 const VkImageCreateInfo imageCreateInfo =
208                 {
209                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
210                         DE_NULL,                                                                                                                                        // const void*                          pNext;
211                         (VkImageCreateFlags)0,                                                                                                          // VkImageCreateFlags           flags;
212                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
213                         m_drawState.colorFormat,                                                                                                        // VkFormat                                     format;
214                         makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u),       // VkExtent3D                           extent;
215                         1u,                                                                                                                                                     // uint32_t                                     mipLevels;
216                         1u,                                                                                                                                                     // uint32_t                                     arrayLayers;
217                         (VkSampleCountFlagBits)m_drawState.numSamples,                                                          // VkSampleCountFlagBits        samples;
218                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
219                         usage,                                                                                                                                          // VkImageUsageFlags            usage;
220                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
221                         0u,                                                                                                                                                     // uint32_t                                     queueFamilyIndexCount;
222                         DE_NULL,                                                                                                                                        // const uint32_t*                      pQueueFamilyIndices;
223                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                        initialLayout;
224                 };
225
226                 m_colorImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
227                 m_colorImageView = makeImageView(vk, device, **m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_drawState.colorFormat, colorSubresourceRange);
228
229                 // Buffer to copy attachment data after rendering
230
231                 const VkDeviceSize bitmapSize = tcu::getPixelSize(mapVkFormat(m_drawState.colorFormat)) * m_drawState.renderSize.x() * m_drawState.renderSize.y();
232                 m_colorAttachmentBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
233                         vk, device, allocator, makeBufferCreateInfo(bitmapSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
234
235                 {
236                         const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
237                         deMemset(alloc.getHostPtr(), 0, (size_t)bitmapSize);
238                         flushAlloc(vk, device, alloc);
239                 }
240         }
241
242         // Vertex buffer
243         {
244                 const VkDeviceSize bufferSize = m_drawCallData.vertices.size() * sizeof(m_drawCallData.vertices[0]);
245                 m_vertexBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(
246                         vk, device, allocator, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
247
248                 const Allocation& alloc = m_vertexBuffer->getAllocation();
249                 deMemcpy(alloc.getHostPtr(), &m_drawCallData.vertices[0], (size_t)bufferSize);
250                 flushAlloc(vk, device, alloc);
251         }
252
253         // bind descriptor sets
254         {
255                 m_pipelineLayout = makePipelineLayout(vk, device, vulkanProgram.descriptorSetLayout);
256         }
257
258         // Renderpass
259         {
260                 std::vector<VkAttachmentDescription> attachmentDescriptions;
261                 const VkAttachmentDescription attachDescriptors[] =
262                 {
263                         {
264                                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
265                                 m_drawState.colorFormat,                                                        // VkFormat                                                     format;
266                                 (VkSampleCountFlagBits)m_drawState.numSamples,          // VkSampleCountFlagBits                        samples;
267                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
268                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
269                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
270                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
271                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                        initialLayout;
272                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
273                         },
274                         {
275                                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags
276                                 m_drawState.depthFormat,                                                        // VkFormat                                                     format
277                                 (VkSampleCountFlagBits)m_drawState.numSamples,          // VkSampleCountFlagBits                        samples
278                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp
279                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp
280                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp
281                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp
282                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                        initialLayout
283                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        finalLayout
284
285                         }
286                 };
287
288                 const VkAttachmentReference attachmentReferences[] =
289                 {
290                         {
291                                 0u,                                                                                                     // uint32_t                     attachment
292                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout
293                         },
294                         {
295                                 1u,                                                                                                     // uint32_t                     attachment
296                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL        // VkImageLayout        layout
297                         },
298                         {
299                                 VK_ATTACHMENT_UNUSED,                                                           // deUint32                     attachment;
300                                 VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout        layout;
301                         }
302                 };
303
304                 attachmentDescriptions.push_back(attachDescriptors[0]);
305                 if (!!vulkanProgram.depthImageView)
306                         attachmentDescriptions.push_back(attachDescriptors[1]);
307
308                 deUint32 depthReferenceNdx = !!vulkanProgram.depthImageView ? 1 : 2;
309                 const VkSubpassDescription subpassDescription =
310                 {
311                         (VkSubpassDescriptionFlags)0,                                           // VkSubpassDescriptionFlags            flags;
312                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
313                         0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
314                         DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
315                         1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
316                         &attachmentReferences[0],                                                       // const VkAttachmentReference*         pColorAttachments;
317                         DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
318                         &attachmentReferences[depthReferenceNdx],                       // const VkAttachmentReference*         pDepthStencilAttachment;
319                         0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
320                         DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
321                 };
322
323                 const VkRenderPassCreateInfo renderPassInfo =
324                 {
325                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
326                         DE_NULL,                                                                                        // const void*                                          pNext;
327                         (VkRenderPassCreateFlags)0,                                                     // VkRenderPassCreateFlags                      flags;
328                         (deUint32)attachmentDescriptions.size(),                        // deUint32                                                     attachmentCount;
329                         &attachmentDescriptions[0],                                                     // const VkAttachmentDescription*       pAttachments;
330                         1u,                                                                                                     // deUint32                                                     subpassCount;
331                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
332                         0u,                                                                                                     // deUint32                                                     dependencyCount;
333                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
334                 };
335
336                 m_renderPass = createRenderPass(vk, device, &renderPassInfo);
337         }
338
339         // Framebuffer
340         {
341                 std::vector<VkImageView>        attachmentBindInfos;
342                 deUint32                                        numAttachments;
343                 attachmentBindInfos.push_back(*m_colorImageView);
344                 if (!!vulkanProgram.depthImageView)
345                         attachmentBindInfos.push_back(vulkanProgram.depthImageView);
346
347                 numAttachments = (deUint32)(attachmentBindInfos.size());
348                 const VkFramebufferCreateInfo framebufferInfo = {
349                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,              // VkStructureType                                              sType;
350                         DE_NULL,                                                                                // const void*                                                  pNext;
351                         (VkFramebufferCreateFlags)0,                                    // VkFramebufferCreateFlags                             flags;
352                         *m_renderPass,                                                                  // VkRenderPass                                                 renderPass;
353                         numAttachments,                                                                 // uint32_t                                                             attachmentCount;
354                         &attachmentBindInfos[0],                                                // const VkImageView*                                   pAttachments;
355                         m_drawState.renderSize.x(),                                             // uint32_t                                                             width;
356                         m_drawState.renderSize.y(),                                             // uint32_t                                                             height;
357                         1u,                                                                                             // uint32_t                                                             layers;
358                 };
359
360                 m_framebuffer = createFramebuffer(vk, device, &framebufferInfo);
361         }
362
363         // Graphics pipeline
364         {
365                 VkShaderModule  vertShader                      = DE_NULL;
366                 VkShaderModule  tessControlShader       = DE_NULL;
367                 VkShaderModule  tessEvalShader          = DE_NULL;
368                 VkShaderModule  geomShader                      = DE_NULL;
369                 VkShaderModule  fragShader                      = DE_NULL;
370
371                 DE_ASSERT(m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST || m_drawState.numPatchControlPoints > 0);
372
373                 const std::vector<VkViewport>   viewports       (1, makeViewport(m_drawState.renderSize));
374                 const std::vector<VkRect2D>             scissors        (1, makeRect2D(m_drawState.renderSize));
375
376                 VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
377                 {
378                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
379                         DE_NULL,                                                                                                                // const void*                                                          pNext;
380                         (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags      flags;
381                         m_drawState.depthClampEnable,                                                                   // VkBool32                                                                     depthClampEnable;
382                         VK_FALSE,                                                                                                               // VkBool32                                                                     rasterizerDiscardEnable;
383                         VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
384                         VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
385                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
386                         VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
387                         0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
388                         0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
389                         0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
390                         m_drawState.lineWidth,                                                                                  // float                                                                        lineWidth;
391                 };
392
393                 VkPipelineRasterizationDepthClipStateCreateInfoEXT pipelineRasterizationDepthCliptateInfo =
394                 {
395                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT,      // VkStructureType                                                                              sType;
396                         DE_NULL,                                                                                                                                        // const void*                                                                                  pNext;
397                         (VkPipelineRasterizationDepthClipStateCreateFlagsEXT)0,                                         // VkPipelineRasterizationDepthClipStateCreateFlagsEXT  flags;
398                         m_drawState.depthClipEnable,                                                                                            // VkBool32                                                                                             depthClipEnable;
399                 };
400                 if (m_drawState.explicitDepthClipEnable)
401                         pipelineRasterizationStateInfo.pNext = &pipelineRasterizationDepthCliptateInfo;
402
403                 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
404                 {
405                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
406                         DE_NULL,                                                                                                        // const void*                                                          pNext;
407                         (VkPipelineMultisampleStateCreateFlags)0,                                       // VkPipelineMultisampleStateCreateFlags        flags;
408                         (VkSampleCountFlagBits)m_drawState.numSamples,                          // VkSampleCountFlagBits                                        rasterizationSamples;
409                         m_drawState.sampleShadingEnable ? VK_TRUE : VK_FALSE,           // VkBool32                                                                     sampleShadingEnable;
410                         m_drawState.sampleShadingEnable ? 1.0f : 0.0f,                          // float                                                                        minSampleShading;
411                         DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
412                         VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
413                         VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
414                 };
415
416                 const VkStencilOpState stencilOpState = makeStencilOpState(
417                         VK_STENCIL_OP_KEEP,             // stencil fail
418                         VK_STENCIL_OP_KEEP,             // depth & stencil pass
419                         VK_STENCIL_OP_KEEP,             // depth only fail
420                         VK_COMPARE_OP_NEVER,    // compare op
421                         0u,                                             // compare mask
422                         0u,                                             // write mask
423                         0u);                                    // reference
424
425                 if (m_drawState.depthBoundsTestEnable && !context.getDeviceFeatures().depthBounds)
426                         TCU_THROW(NotSupportedError, "depthBounds not supported");
427
428                 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
429                 {
430                         VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
431                         DE_NULL,                                                                                                        // const void*                                                          pNext;
432                         (VkPipelineDepthStencilStateCreateFlags)0,                                      // VkPipelineDepthStencilStateCreateFlags       flags;
433                         m_drawState.depthTestEnable,                                                            // VkBool32                                                                     depthTestEnable;
434                         m_drawState.depthWriteEnable,                                                           // VkBool32                                                                     depthWriteEnable;
435                         mapCompareOp(m_drawState.compareOp),                                            // VkCompareOp                                                          depthCompareOp;
436                         m_drawState.depthBoundsTestEnable,                                                      // VkBool32                                                                     depthBoundsTestEnable
437                         VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
438                         stencilOpState,                                                                                         // VkStencilOpState                                                     front;
439                         stencilOpState,                                                                                         // VkStencilOpState                                                     back;
440                         0.0f,                                                                                                           // float                                                                        minDepthBounds;
441                         1.0f,                                                                                                           // float                                                                        maxDepthBounds;
442                 };
443
444                 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
445                 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
446                 {
447                         m_drawState.blendEnable,                        // VkBool32                                     blendEnable;
448                         VK_BLEND_FACTOR_SRC_ALPHA,                      // VkBlendFactor                        srcColorBlendFactor;
449                         VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        dstColorBlendFactor;
450                         VK_BLEND_OP_ADD,                                        // VkBlendOp                            colorBlendOp;
451                         VK_BLEND_FACTOR_SRC_ALPHA,                      // VkBlendFactor                        srcAlphaBlendFactor;
452                         VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        dstAlphaBlendFactor;
453                         VK_BLEND_OP_ADD,                                        // VkBlendOp                            alphaBlendOp;
454                         colorComponentsAll,                                     // VkColorComponentFlags        colorWriteMask;
455                 };
456
457                 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
458                 {
459                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
460                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
461                         (VkPipelineColorBlendStateCreateFlags)0,                                        // VkPipelineColorBlendStateCreateFlags                 flags;
462                         VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
463                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
464                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
465                         &pipelineColorBlendAttachmentState,                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
466                         { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConstants[4];
467                 };
468
469                 VkShaderStageFlags stageFlags = (VkShaderStageFlags)0;
470
471                 DE_ASSERT(m_program.shaders.size() <= MAX_NUM_SHADER_MODULES);
472                 for (deUint32 shaderNdx = 0; shaderNdx < m_program.shaders.size(); ++shaderNdx)
473                 {
474                         m_shaderModules[shaderNdx] = createShaderModule(vk, device, *m_program.shaders[shaderNdx].binary, (VkShaderModuleCreateFlags)0);
475
476                         stageFlags |= m_program.shaders[shaderNdx].stage;
477
478                         switch(m_program.shaders[shaderNdx].stage)
479                         {
480                                 case VK_SHADER_STAGE_VERTEX_BIT:
481                                         vertShader = *m_shaderModules[shaderNdx];
482                                         break;
483                                 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
484                                         tessControlShader = *m_shaderModules[shaderNdx];
485                                         break;
486                                 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
487                                         tessEvalShader = *m_shaderModules[shaderNdx];
488                                         break;
489                                 case VK_SHADER_STAGE_GEOMETRY_BIT:
490                                         geomShader = *m_shaderModules[shaderNdx];
491                                         break;
492                                 default:
493                                         DE_ASSERT(m_program.shaders[shaderNdx].stage == VK_SHADER_STAGE_FRAGMENT_BIT);
494                                         fragShader = *m_shaderModules[shaderNdx];
495                                         break;
496                         }
497                 }
498
499                 DE_ASSERT(
500                         (m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) ||
501                         (stageFlags & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)));
502
503                 m_pipeline = makeGraphicsPipeline(vk,                                                                   // const DeviceInterface&                        vk
504                                                                                   device,                                                               // const VkDevice                                device
505                                                                                   *m_pipelineLayout,                                    // const VkPipelineLayout                        pipelineLayout
506                                                                                   vertShader,                                                   // const VkShaderModule                          vertexShaderModule
507                                                                                   tessControlShader,                                    // const VkShaderModule                          tessellationControlShaderModule
508                                                                                   tessEvalShader,                                               // const VkShaderModule                          tessellationEvalShaderModule
509                                                                                   geomShader,                                                   // const VkShaderModule                          geometryShaderModule
510                                                                                   fragShader,                                                   // const VkShaderModule                          fragmentShaderModule
511                                                                                   *m_renderPass,                                                // const VkRenderPass                            renderPass
512                                                                                   viewports,                                                    // const std::vector<VkViewport>&                viewports
513                                                                                   scissors,                                                             // const std::vector<VkRect2D>&                  scissors
514                                                                                   m_drawState.topology,                                 // const VkPrimitiveTopology                     topology
515                                                                                   0u,                                                                   // const deUint32                                subpass
516                                                                                   m_drawState.numPatchControlPoints,    // const deUint32                                patchControlPoints
517                                                                                   DE_NULL,                                                              // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
518                                                                                   &pipelineRasterizationStateInfo,              // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
519                                                                                   &pipelineMultisampleStateInfo,                // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
520                                                                                   &pipelineDepthStencilStateInfo,               // const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
521                                                                                   &pipelineColorBlendStateInfo);                // const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
522         }
523
524         // Record commands
525         {
526                 const VkDeviceSize zeroOffset = 0ull;
527
528                 beginCommandBuffer(vk, *m_cmdBuffer);
529                 if (!!vulkanProgram.descriptorSet)
530                         vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &vulkanProgram.descriptorSet, 0u, DE_NULL);
531
532                 // Begin render pass
533                 if (!!vulkanProgram.depthImageView)
534                         beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_drawState.renderSize.x(), m_drawState.renderSize.y()), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0.0f, 0);
535                 else
536                         beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_drawState.renderSize.x(), m_drawState.renderSize.y()), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
537
538                 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
539                 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(**m_vertexBuffer), &zeroOffset);
540
541                 vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_drawCallData.vertices.size()), 1u, 0u, 0u);
542                 endRenderPass(vk, *m_cmdBuffer);
543
544                 // Barrier: draw -> copy from image
545                 {
546                         const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
547                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
548                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
549                                 **m_colorImage, colorSubresourceRange);
550
551                         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
552                                 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
553                 }
554
555                 // Resolve multisample image
556                 {
557                         if (m_drawState.numSamples != VK_SAMPLE_COUNT_1_BIT)
558                         {
559                                 const VkImageResolve imageResolve =
560                                 {
561                                         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
562                                         { 0, 0, 0},
563                                         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
564                                         { 0, 0, 0},
565                                         makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u)
566                                 };
567
568                                 const VkImageCreateInfo resolveImageCreateInfo =
569                                 {
570                                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                            // VkStructureType                      sType
571                                         DE_NULL,                                                                                        // const void*                          pNext
572                                         (VkImageCreateFlags)0,                                                          // VkImageCreateFlags           flags
573                                         VK_IMAGE_TYPE_2D,                                                                       // VkImageType                          imageType
574                                         m_drawState.colorFormat,                                                        // VkFormat                                     format
575                                         makeExtent3D(m_drawState.renderSize.x(),                        // VkExtent3D                           extent;
576                                                         m_drawState.renderSize.y(), 1u),
577                                         1u,                                                                                                     // uint32_t                                     mipLevels
578                                         1u,                                                                                                     // uint32_t                                     arrayLayers
579                                         VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits        samples
580                                         VK_IMAGE_TILING_OPTIMAL,                                                        // VkImaageTiling                       tiling
581                                         VK_IMAGE_USAGE_TRANSFER_DST_BIT |                                       // VkImageUsageFlags            usage
582                                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
583                                         VK_SHARING_MODE_EXCLUSIVE,                                                      // VkSharingModeExclusive       sharingMode
584                                         0u,                                                                                                     // uint32_t                                     queueFamilyIndexCount
585                                         DE_NULL,                                                                                        // const uint32_t*                      pQueueFamilyIndices
586                                         VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout                        initialLayout
587                                 };
588
589                                 m_resolveImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, resolveImageCreateInfo, MemoryRequirement::Any));
590
591                                 const VkImageMemoryBarrier resolveBarrier = makeImageMemoryBarrier(
592                                                 0u, VK_ACCESS_TRANSFER_READ_BIT,
593                                                 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
594                                                 **m_resolveImage, colorSubresourceRange);
595
596                                 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
597                                                 0u, DE_NULL, 0u, DE_NULL, 1u, &resolveBarrier);
598
599                                 vk.cmdResolveImage(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
600                                                 **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &imageResolve);
601
602                                 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
603                                         VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
604                                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
605                                         **m_resolveImage, colorSubresourceRange);
606
607                                 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
608                                         0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
609                         }
610                         else
611                                 m_resolveImage = m_colorImage;
612
613                         const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
614                                         makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u));
615                         vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, &copyRegion);
616                 }
617
618                 // Barrier: copy to buffer -> host read
619                 {
620                         const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier(
621                                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
622                                 **m_colorAttachmentBuffer, 0ull, VK_WHOLE_SIZE);
623
624                         vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
625                                 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
626                 }
627
628                 endCommandBuffer(vk, *m_cmdBuffer);
629         }
630 }
631
632 VulkanDrawContext::~VulkanDrawContext (void)
633 {
634 }
635
636 void VulkanDrawContext::draw (void)
637 {
638         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
639         const VkDevice                  device          = m_context.getDevice();
640         const VkQueue                   queue           = m_context.getUniversalQueue();
641         tcu::TestLog&                   log                     = m_context.getTestContext().getLog();
642
643         submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
644
645         log << tcu::LogImageSet("attachments", "") << tcu::LogImage("color0", "", getColorPixels()) << tcu::TestLog::EndImageSet;
646 }
647
648 tcu::ConstPixelBufferAccess VulkanDrawContext::getColorPixels (void) const
649 {
650         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
651         const VkDevice                  device          = m_context.getDevice();
652
653         const Allocation& alloc = m_colorAttachmentBuffer->getAllocation();
654         invalidateAlloc(vk, device, alloc);
655
656         return tcu::ConstPixelBufferAccess(mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u, alloc.getHostPtr());
657 }
658 } // drawutil
659 } // vkt