Fix issues in pipeline.timestamp.transfer_tests
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineEarlyFragmentTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  * Copyright (c) 2015 The Khronos Group 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 Early fragment tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktPipelineEarlyFragmentTests.hpp"
26 #include "vktTestCaseUtil.hpp"
27
28 #include "vkDefs.hpp"
29 #include "vkRef.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkPlatform.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkStrUtil.hpp"
36 #include "vkTypeUtil.hpp"
37 #include "vkQueryUtil.hpp"
38 #include "vkImageUtil.hpp"
39
40 #include "deUniquePtr.hpp"
41 #include "deStringUtil.hpp"
42
43 #include <string>
44
45 using namespace vk;
46
47 namespace vkt
48 {
49 namespace pipeline
50 {
51 namespace
52 {
53
54 // \note Some utility functions are general, but others are custom tailored to this test.
55
56 class Buffer
57 {
58 public:
59                                                                         Buffer                  (const DeviceInterface&         vk,
60                                                                                                          const VkDevice                         device,
61                                                                                                          Allocator&                                     allocator,
62                                                                                                          const VkBufferCreateInfo&      bufferCreateInfo,
63                                                                                                          const MemoryRequirement        memoryRequirement)
64
65                                                                                 : m_buffer              (createBuffer(vk, device, &bufferCreateInfo))
66                                                                                 , m_allocation  (allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), memoryRequirement))
67                                                                         {
68                                                                                 VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset()));
69                                                                         }
70
71         const VkBuffer&                                 get                             (void) const { return *m_buffer; }
72         const VkBuffer&                                 operator*               (void) const { return get(); }
73         Allocation&                                             getAllocation   (void) const { return *m_allocation; }
74
75 private:
76         const Unique<VkBuffer>                  m_buffer;
77         const de::UniquePtr<Allocation> m_allocation;
78
79         // "deleted"
80                                                                         Buffer                  (const Buffer&);
81         Buffer&                                                 operator=               (const Buffer&);
82 };
83
84 class Image
85 {
86 public:
87                                                                         Image                   (const DeviceInterface&         vk,
88                                                                                                          const VkDevice                         device,
89                                                                                                          Allocator&                                     allocator,
90                                                                                                          const VkImageCreateInfo&       imageCreateInfo,
91                                                                                                          const MemoryRequirement        memoryRequirement)
92
93                                                                                 : m_image               (createImage(vk, device, &imageCreateInfo))
94                                                                                 , m_allocation  (allocator.allocate(getImageMemoryRequirements(vk, device, *m_image), memoryRequirement))
95                                                                         {
96                                                                                 VK_CHECK(vk.bindImageMemory(device, *m_image, m_allocation->getMemory(), m_allocation->getOffset()));
97                                                                         }
98
99         const VkImage&                                  get                             (void) const { return *m_image; }
100         const VkImage&                                  operator*               (void) const { return get(); }
101         Allocation&                                             getAllocation   (void) const { return *m_allocation; }
102
103 private:
104         const Unique<VkImage>                   m_image;
105         const de::UniquePtr<Allocation> m_allocation;
106
107         // "deleted"
108                                                                         Image                   (const Image&);
109         Image&                                                  operator=               (const Image&);
110 };
111
112 Move<VkImageView> makeImageView (const DeviceInterface&                 vk,
113                                                                  const VkDevice                                 vkDevice,
114                                                                  const VkImage                                  image,
115                                                                  const VkImageViewType                  imageViewType,
116                                                                  const VkFormat                                 format,
117                                                                  const VkImageSubresourceRange  subresourceRange)
118 {
119         const VkImageViewCreateInfo imageViewParams =
120         {
121                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
122                 DE_NULL,                                                                                // const void*                          pNext;
123                 (VkImageViewCreateFlags)0,                                              // VkImageViewCreateFlags       flags;
124                 image,                                                                                  // VkImage                                      image;
125                 imageViewType,                                                                  // VkImageViewType                      viewType;
126                 format,                                                                                 // VkFormat                                     format;
127                 makeComponentMappingRGBA(),                                             // VkComponentMapping           components;
128                 subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
129         };
130         return createImageView(vk, vkDevice, &imageViewParams);
131 }
132
133 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize                     bufferSize,
134                                                                                  const VkBufferUsageFlags       usage)
135 {
136         const VkBufferCreateInfo bufferCreateInfo =
137         {
138                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
139                 DE_NULL,                                                                // const void*                  pNext;
140                 (VkBufferCreateFlags)0,                                 // VkBufferCreateFlags  flags;
141                 bufferSize,                                                             // VkDeviceSize                 size;
142                 usage,                                                                  // VkBufferUsageFlags   usage;
143                 VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
144                 0u,                                                                             // deUint32                             queueFamilyIndexCount;
145                 DE_NULL,                                                                // const deUint32*              pQueueFamilyIndices;
146         };
147         return bufferCreateInfo;
148 }
149
150 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&                 vk,
151                                                                                  const VkDevice                                 device,
152                                                                                  const VkDescriptorPool                 descriptorPool,
153                                                                                  const VkDescriptorSetLayout    setLayout)
154 {
155         const VkDescriptorSetAllocateInfo allocateParams =
156         {
157                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,         // VkStructureType                              sType;
158                 DE_NULL,                                                                                        // const void*                                  pNext;
159                 descriptorPool,                                                                         // VkDescriptorPool                             descriptorPool;
160                 1u,                                                                                                     // deUint32                                             setLayoutCount;
161                 &setLayout,                                                                                     // const VkDescriptorSetLayout* pSetLayouts;
162         };
163         return allocateDescriptorSet(vk, device, &allocateParams);
164 }
165
166 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&               vk,
167                                                                                    const VkDevice                               device,
168                                                                                    const VkDescriptorSetLayout  descriptorSetLayout)
169 {
170         const VkPipelineLayoutCreateInfo pipelineLayoutParams =
171         {
172                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
173                 DE_NULL,                                                                                        // const void*                                          pNext;
174                 (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags          flags;
175                 1u,                                                                                                     // deUint32                                                     setLayoutCount;
176                 &descriptorSetLayout,                                                           // const VkDescriptorSetLayout*         pSetLayouts;
177                 0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
178                 DE_NULL,                                                                                        // const VkPushConstantRange*           pPushConstantRanges;
179         };
180         return createPipelineLayout(vk, device, &pipelineLayoutParams);
181 }
182
183 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
184 {
185         const VkCommandPoolCreateInfo commandPoolParams =
186         {
187                 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                     // VkStructureType                      sType;
188                 DE_NULL,                                                                                        // const void*                          pNext;
189                 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,        // VkCommandPoolCreateFlags     flags;
190                 queueFamilyIndex,                                                                       // deUint32                                     queueFamilyIndex;
191         };
192         return createCommandPool(vk, device, &commandPoolParams);
193 }
194
195 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
196 {
197         const VkCommandBufferAllocateInfo bufferAllocateParams =
198         {
199                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,         // VkStructureType                      sType;
200                 DE_NULL,                                                                                        // const void*                          pNext;
201                 commandPool,                                                                            // VkCommandPool                        commandPool;
202                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                        // VkCommandBufferLevel         level;
203                 1u,                                                                                                     // deUint32                                     bufferCount;
204         };
205         return allocateCommandBuffer(vk, device, &bufferAllocateParams);
206 }
207
208 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
209 {
210         const VkCommandBufferBeginInfo commandBufBeginParams =
211         {
212                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
213                 DE_NULL,                                                                                // const void*                                          pNext;
214                 (VkCommandBufferUsageFlags)0,                                   // VkCommandBufferUsageFlags            flags;
215                 DE_NULL,                                                                                // const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
216         };
217         VK_CHECK(vk.beginCommandBuffer(commandBuffer, &commandBufBeginParams));
218 }
219
220 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
221 {
222         VK_CHECK(vk.endCommandBuffer(commandBuffer));
223 }
224
225 void submitCommandsAndWait (const DeviceInterface&      vk,
226                                                         const VkDevice                  device,
227                                                         const VkQueue                   queue,
228                                                         const VkCommandBuffer   commandBuffer)
229 {
230         const VkFenceCreateInfo fenceParams =
231         {
232                 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
233                 DE_NULL,                                                                // const void*                  pNext;
234                 (VkFenceCreateFlags)0,                                  // VkFenceCreateFlags   flags;
235         };
236         const Unique<VkFence> fence(createFence(vk, device, &fenceParams));
237
238         const VkSubmitInfo submitInfo =
239         {
240                 VK_STRUCTURE_TYPE_SUBMIT_INFO,          // VkStructureType                      sType;
241                 DE_NULL,                                                        // const void*                          pNext;
242                 0u,                                                                     // deUint32                                     waitSemaphoreCount;
243                 DE_NULL,                                                        // const VkSemaphore*           pWaitSemaphores;
244                 DE_NULL,                                                        // const VkPipelineStageFlags*    pWaitDstStageMask;
245                 1u,                                                                     // deUint32                                     commandBufferCount;
246                 &commandBuffer,                                         // const VkCommandBuffer*       pCommandBuffers;
247                 0u,                                                                     // deUint32                                     signalSemaphoreCount;
248                 DE_NULL,                                                        // const VkSemaphore*           pSignalSemaphores;
249         };
250
251         VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
252         VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
253 }
254
255 VkImageMemoryBarrier makeImageMemoryBarrier     (const VkAccessFlags                    srcAccessMask,
256                                                                                          const VkAccessFlags                    dstAccessMask,
257                                                                                          const VkImageLayout                    oldLayout,
258                                                                                          const VkImageLayout                    newLayout,
259                                                                                          const VkImage                                  image,
260                                                                                          const VkImageSubresourceRange  subresourceRange)
261 {
262         const VkImageMemoryBarrier barrier =
263         {
264                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
265                 DE_NULL,                                                                                // const void*                          pNext;
266                 srcAccessMask,                                                                  // VkAccessFlags                        outputMask;
267                 dstAccessMask,                                                                  // VkAccessFlags                        inputMask;
268                 oldLayout,                                                                              // VkImageLayout                        oldLayout;
269                 newLayout,                                                                              // VkImageLayout                        newLayout;
270                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
271                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     destQueueFamilyIndex;
272                 image,                                                                                  // VkImage                                      image;
273                 subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
274         };
275         return barrier;
276 }
277
278 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags      srcAccessMask,
279                                                                                            const VkAccessFlags  dstAccessMask,
280                                                                                            const VkBuffer               buffer,
281                                                                                            const VkDeviceSize   offset,
282                                                                                            const VkDeviceSize   bufferSizeBytes)
283 {
284         const VkBufferMemoryBarrier barrier =
285         {
286                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
287                 DE_NULL,                                                                        // const void*          pNext;
288                 srcAccessMask,                                                          // VkAccessFlags        srcAccessMask;
289                 dstAccessMask,                                                          // VkAccessFlags        dstAccessMask;
290                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
291                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     destQueueFamilyIndex;
292                 buffer,                                                                         // VkBuffer                     buffer;
293                 offset,                                                                         // VkDeviceSize         offset;
294                 bufferSizeBytes,                                                        // VkDeviceSize         size;
295         };
296         return barrier;
297 }
298
299 //! Basic 2D image.
300 inline VkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& size, const VkFormat format, const VkImageUsageFlags usage)
301 {
302         const VkImageCreateInfo imageParams =
303         {
304                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                    // VkStructureType                      sType;
305                 DE_NULL,                                                                                                // const void*                          pNext;
306                 (VkImageCreateFlags)0,                                                                  // VkImageCreateFlags           flags;
307                 VK_IMAGE_TYPE_2D,                                                                               // VkImageType                          imageType;
308                 format,                                                                                                 // VkFormat                                     format;
309                 makeExtent3D(size.x(), size.y(), 1),                                    // VkExtent3D                           extent;
310                 1u,                                                                                                             // deUint32                                     mipLevels;
311                 1u,                                                                                                             // deUint32                                     arrayLayers;
312                 VK_SAMPLE_COUNT_1_BIT,                                                                  // VkSampleCountFlagBits        samples;
313                 VK_IMAGE_TILING_OPTIMAL,                                                                // VkImageTiling                        tiling;
314                 usage,                                                                                                  // VkImageUsageFlags            usage;
315                 VK_SHARING_MODE_EXCLUSIVE,                                                              // VkSharingMode                        sharingMode;
316                 0u,                                                                                                             // deUint32                                     queueFamilyIndexCount;
317                 DE_NULL,                                                                                                // const deUint32*                      pQueueFamilyIndices;
318                 VK_IMAGE_LAYOUT_UNDEFINED,                                                              // VkImageLayout                        initialLayout;
319         };
320         return imageParams;
321 }
322
323 void beginRenderPass (const DeviceInterface&    vk,
324                                           const VkCommandBuffer         commandBuffer,
325                                           const VkRenderPass            renderPass,
326                                           const VkFramebuffer           framebuffer,
327                                           const VkRect2D&                       renderArea,
328                                           const tcu::Vec4&                      clearColor,
329                                           const float                           clearDepth,
330                                           const deUint32                        clearStencil)
331 {
332         const VkClearValue clearValues[] =
333         {
334                 makeClearValueColor(clearColor),                                                // attachment 0
335                 makeClearValueDepthStencil(clearDepth, clearStencil),   // attachment 1
336         };
337
338         const VkRenderPassBeginInfo renderPassBeginInfo = {
339                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType         sType;
340                 DE_NULL,                                                                                // const void*             pNext;
341                 renderPass,                                                                             // VkRenderPass            renderPass;
342                 framebuffer,                                                                    // VkFramebuffer           framebuffer;
343                 renderArea,                                                                             // VkRect2D                renderArea;
344                 DE_LENGTH_OF_ARRAY(clearValues),                                // uint32_t                clearValueCount;
345                 clearValues,                                                                    // const VkClearValue*     pClearValues;
346         };
347
348         vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
349 }
350
351 void endRenderPass (const DeviceInterface&      vk,
352                                         const VkCommandBuffer   commandBuffer)
353 {
354         vk.cmdEndRenderPass(commandBuffer);
355 }
356
357 Move<VkRenderPass> makeRenderPass (const DeviceInterface&       vk,
358                                                                    const VkDevice                       device,
359                                                                    const VkFormat                       colorFormat,
360                                                                    const bool                           useDepthStencilAttachment,
361                                                                    const VkFormat                       depthStencilFormat)
362 {
363         const VkAttachmentDescription attachments[] =
364         {
365                 // color
366                 {
367                         (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
368                         colorFormat,                                                                            // VkFormat                                                     format;
369                         VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
370                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
371                         VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
372                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
373                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
374                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
375                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
376                 },
377                 // depth/stencil
378                 {
379                         (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
380                         depthStencilFormat,                                                                     // VkFormat                                                     format;
381                         VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
382                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
383                         VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
384                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           stencilLoadOp;
385                         VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          stencilStoreOp;
386                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout;
387                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        finalLayout;
388                 }
389         };
390
391         const VkAttachmentReference unusedAttachmentReference =
392         {
393                 VK_ATTACHMENT_UNUSED,                                                           // deUint32                     attachment;
394                 VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout        layout;
395         };
396
397         const VkAttachmentReference colorAttachmentReference =
398         {
399                 0u,                                                                                                     // deUint32                     attachment;
400                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
401         };
402
403         const VkAttachmentReference depthStencilAttachmentReference =
404         {
405                 1u,                                                                                                     // deUint32                     attachment;
406                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL        // VkImageLayout        layout;
407         };
408
409         const VkAttachmentReference* pDepthStencilAttachment = (useDepthStencilAttachment ? &depthStencilAttachmentReference : &unusedAttachmentReference);
410
411         const VkSubpassDescription subpassDescription =
412         {
413                 0u,                                                                                                     // VkSubpassDescriptionFlags            flags;
414                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
415                 0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
416                 DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
417                 1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
418                 &colorAttachmentReference,                                                      // const VkAttachmentReference*         pColorAttachments;
419                 DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
420                 pDepthStencilAttachment,                                                        // const VkAttachmentReference*         pDepthStencilAttachment;
421                 0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
422                 DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
423         };
424
425         const VkRenderPassCreateInfo renderPassInfo =
426         {
427                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
428                 DE_NULL,                                                                                        // const void*                                          pNext;
429                 (VkRenderPassCreateFlags)0,                                                     // VkRenderPassCreateFlags                      flags;
430                 (useDepthStencilAttachment ? 2u : 1u),                          // deUint32                                                     attachmentCount;
431                 attachments,                                                                            // const VkAttachmentDescription*       pAttachments;
432                 1u,                                                                                                     // deUint32                                                     subpassCount;
433                 &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
434                 0u,                                                                                                     // deUint32                                                     dependencyCount;
435                 DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
436         };
437
438         return createRenderPass(vk, device, &renderPassInfo);
439 }
440
441 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface&             vk,
442                                                                          const VkDevice                         device,
443                                                                          const VkRenderPass                     renderPass,
444                                                                          const deUint32                         attachmentCount,
445                                                                          const VkImageView*                     pAttachments,
446                                                                          const tcu::IVec2                       size)
447 {
448         const VkFramebufferCreateInfo framebufferInfo = {
449                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,              // VkStructureType                             sType;
450                 DE_NULL,                                                                                // const void*                                 pNext;
451                 (VkFramebufferCreateFlags)0,                                    // VkFramebufferCreateFlags                    flags;
452                 renderPass,                                                                             // VkRenderPass                                renderPass;
453                 attachmentCount,                                                                // uint32_t                                    attachmentCount;
454                 pAttachments,                                                                   // const VkImageView*                          pAttachments;
455                 static_cast<deUint32>(size.x()),                                // uint32_t                                    width;
456                 static_cast<deUint32>(size.y()),                                // uint32_t                                    height;
457                 1u,                                                                                             // uint32_t                                    layers;
458         };
459
460         return createFramebuffer(vk, device, &framebufferInfo);
461 }
462
463 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&   vk,
464                                                                            const VkDevice                       device,
465                                                                            const VkPipelineLayout       pipelineLayout,
466                                                                            const VkRenderPass           renderPass,
467                                                                            const VkShaderModule         vertexModule,
468                                                                            const VkShaderModule         fragmentModule,
469                                                                            const tcu::IVec2&            renderSize,
470                                                                            const bool                           enableDepthTest,
471                                                                            const bool                           enableStencilTest)
472 {
473         const VkVertexInputBindingDescription vertexInputBindingDescription =
474         {
475                 0u,                                                             // uint32_t                             binding;
476                 sizeof(tcu::Vec4),                              // uint32_t                             stride;         // Vertex is a 4-element vector XYZW, position only
477                 VK_VERTEX_INPUT_RATE_VERTEX,    // VkVertexInputRate    inputRate;
478         };
479
480         const VkVertexInputAttributeDescription vertexInputAttributeDescription =
481         {
482                 0u,                                                                     // uint32_t                     location;
483                 0u,                                                                     // uint32_t                     binding;
484                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat                     format;
485                 0u,                                                                     // uint32_t                     offset;
486         };
487
488         const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
489         {
490                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                             sType;
491                 DE_NULL,                                                                                                        // const void*                                 pNext;
492                 (VkPipelineVertexInputStateCreateFlags)0,                                       // VkPipelineVertexInputStateCreateFlags       flags;
493                 1u,                                                                                                                     // uint32_t                                    vertexBindingDescriptionCount;
494                 &vertexInputBindingDescription,                                                         // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
495                 1u,                                                                                                                     // uint32_t                                    vertexAttributeDescriptionCount;
496                 &vertexInputAttributeDescription,                                                       // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
497         };
498
499         const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
500         {
501                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                             sType;
502                 DE_NULL,                                                                                                                // const void*                                 pNext;
503                 (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags     flags;
504                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology                         topology;
505                 VK_FALSE,                                                                                                               // VkBool32                                    primitiveRestartEnable;
506         };
507
508         const VkViewport viewport = makeViewport(
509                 0.0f, 0.0f,
510                 static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()),
511                 0.0f, 1.0f);
512
513         const VkRect2D scissor = {
514                 makeOffset2D(0, 0),
515                 makeExtent2D(renderSize.x(), renderSize.y()),
516         };
517
518         const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
519         {
520                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                             sType;
521                 DE_NULL,                                                                                                // const void*                                 pNext;
522                 (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewportStateCreateFlags          flags;
523                 1u,                                                                                                             // uint32_t                                    viewportCount;
524                 &viewport,                                                                                              // const VkViewport*                           pViewports;
525                 1u,                                                                                                             // uint32_t                                    scissorCount;
526                 &scissor,                                                                                               // const VkRect2D*                             pScissors;
527         };
528
529         const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
530         {
531                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                          sType;
532                 DE_NULL,                                                                                                                // const void*                              pNext;
533                 (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags  flags;
534                 VK_FALSE,                                                                                                               // VkBool32                                 depthClampEnable;
535                 VK_FALSE,                                                                                                               // VkBool32                                 rasterizerDiscardEnable;
536                 VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
537                 VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
538                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
539                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
540                 0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
541                 0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
542                 0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
543                 1.0f,                                                                                                                   // float                                                                        lineWidth;
544         };
545
546         const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
547         {
548                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
549                 DE_NULL,                                                                                                        // const void*                                                          pNext;
550                 (VkPipelineMultisampleStateCreateFlags)0,                                       // VkPipelineMultisampleStateCreateFlags        flags;
551                 VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
552                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
553                 0.0f,                                                                                                           // float                                                                        minSampleShading;
554                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
555                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
556                 VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
557         };
558
559         const VkStencilOpState stencilOpState = makeStencilOpState(
560                 VK_STENCIL_OP_KEEP,             // stencil fail
561                 VK_STENCIL_OP_KEEP,             // depth & stencil pass
562                 VK_STENCIL_OP_KEEP,             // depth only fail
563                 VK_COMPARE_OP_EQUAL,    // compare op
564                 1u,                                             // compare mask
565                 1u,                                             // write mask
566                 1u);                                    // reference
567
568         VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
569         {
570                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
571                 DE_NULL,                                                                                                        // const void*                                                          pNext;
572                 (VkPipelineDepthStencilStateCreateFlags)0,                                      // VkPipelineDepthStencilStateCreateFlags       flags;
573                 enableDepthTest,                                                                                        // VkBool32                                                                     depthTestEnable;
574                 VK_TRUE,                                                                                                        // VkBool32                                                                     depthWriteEnable;
575                 VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
576                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
577                 enableStencilTest,                                                                                      // VkBool32                                                                     stencilTestEnable;
578                 stencilOpState,                                                                                         // VkStencilOpState                                                     front;
579                 stencilOpState,                                                                                         // VkStencilOpState                                                     back;
580                 0.0f,                                                                                                           // float                                                                        minDepthBounds;
581                 1.0f,                                                                                                           // float                                                                        maxDepthBounds;
582         };
583
584         const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
585         // Number of blend attachments must equal the number of color attachments.
586         const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
587         {
588                 VK_FALSE,                                                       // VkBool32                                     blendEnable;
589                 VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        srcColorBlendFactor;
590                 VK_BLEND_FACTOR_ZERO,                           // VkBlendFactor                        dstColorBlendFactor;
591                 VK_BLEND_OP_ADD,                                        // VkBlendOp                            colorBlendOp;
592                 VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        srcAlphaBlendFactor;
593                 VK_BLEND_FACTOR_ZERO,                           // VkBlendFactor                        dstAlphaBlendFactor;
594                 VK_BLEND_OP_ADD,                                        // VkBlendOp                            alphaBlendOp;
595                 colorComponentsAll,                                     // VkColorComponentFlags        colorWriteMask;
596         };
597
598         const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
599         {
600                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
601                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
602                 (VkPipelineColorBlendStateCreateFlags)0,                                        // VkPipelineColorBlendStateCreateFlags                 flags;
603                 VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
604                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
605                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
606                 &pipelineColorBlendAttachmentState,                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
607                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConstants[4];
608         };
609
610         const VkPipelineShaderStageCreateInfo pShaderStages[] =
611         {
612                 {
613                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
614                         DE_NULL,                                                                                                // const void*                                                  pNext;
615                         (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
616                         VK_SHADER_STAGE_VERTEX_BIT,                                                             // VkShaderStageFlagBits                                stage;
617                         vertexModule,                                                                                   // VkShaderModule                                               module;
618                         "main",                                                                                                 // const char*                                                  pName;
619                         DE_NULL,                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
620                 },
621                 {
622                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
623                         DE_NULL,                                                                                                // const void*                                                  pNext;
624                         (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
625                         VK_SHADER_STAGE_FRAGMENT_BIT,                                                   // VkShaderStageFlagBits                                stage;
626                         fragmentModule,                                                                                 // VkShaderModule                                               module;
627                         "main",                                                                                                 // const char*                                                  pName;
628                         DE_NULL,                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
629                 }
630         };
631
632         const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
633         {
634                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
635                 DE_NULL,                                                                                        // const void*                                                                          pNext;
636                 (VkPipelineCreateFlags)0,                                                       // VkPipelineCreateFlags                                                        flags;
637                 DE_LENGTH_OF_ARRAY(pShaderStages),                                      // deUint32                                                                                     stageCount;
638                 pShaderStages,                                                                          // const VkPipelineShaderStageCreateInfo*                       pStages;
639                 &vertexInputStateInfo,                                                          // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
640                 &pipelineInputAssemblyStateInfo,                                        // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
641                 DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
642                 &pipelineViewportStateInfo,                                                     // const VkPipelineViewportStateCreateInfo*                     pViewportState;
643                 &pipelineRasterizationStateInfo,                                        // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
644                 &pipelineMultisampleStateInfo,                                          // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
645                 &pipelineDepthStencilStateInfo,                                         // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
646                 &pipelineColorBlendStateInfo,                                           // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
647                 DE_NULL,                                                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
648                 pipelineLayout,                                                                         // VkPipelineLayout                                                                     layout;
649                 renderPass,                                                                                     // VkRenderPass                                                                         renderPass;
650                 0u,                                                                                                     // deUint32                                                                                     subpass;
651                 DE_NULL,                                                                                        // VkPipeline                                                                           basePipelineHandle;
652                 0,                                                                                                      // deInt32                                                                                      basePipelineIndex;
653         };
654
655         return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
656 }
657
658 VkBufferImageCopy makeBufferImageCopy (const VkImageAspectFlags aspectFlags, const tcu::IVec2& renderSize)
659 {
660         const VkBufferImageCopy copyParams =
661         {
662                 0ull,                                                                                                                   //      VkDeviceSize                            bufferOffset;
663                 0u,                                                                                                                             //      deUint32                                        bufferRowLength;
664                 0u,                                                                                                                             //      deUint32                                        bufferImageHeight;
665                 makeImageSubresourceLayers(aspectFlags, 0u, 0u, 1u),                    //      VkImageSubresourceLayers        imageSubresource;
666                 makeOffset3D(0, 0, 0),                                                                                  //      VkOffset3D                                      imageOffset;
667                 makeExtent3D(renderSize.x(), renderSize.y(), 1u),                               //      VkExtent3D                                      imageExtent;
668         };
669         return copyParams;
670 }
671
672 void commandClearStencilAttachment (const DeviceInterface&      vk,
673                                                                         const VkCommandBuffer   commandBuffer,
674                                                                         const VkOffset2D&               offset,
675                                                                         const VkExtent2D&               extent,
676                                                                         const deUint32                  clearValue)
677 {
678         const VkClearAttachment stencilAttachment =
679         {
680                 VK_IMAGE_ASPECT_STENCIL_BIT,                                    // VkImageAspectFlags    aspectMask;
681                 0u,                                                                                             // uint32_t              colorAttachment;
682                 makeClearValueDepthStencil(0.0f, clearValue),   // VkClearValue          clearValue;
683         };
684
685         const VkClearRect rect =
686         {
687                 { offset, extent },             // VkRect2D    rect;
688                 0u,                                             // uint32_t    baseArrayLayer;
689                 1u,                                             // uint32_t    layerCount;
690         };
691
692         vk.cmdClearAttachments(commandBuffer, 1u, &stencilAttachment, 1u, &rect);
693 }
694
695 VkImageAspectFlags getImageAspectFlags (const VkFormat format)
696 {
697         const tcu::TextureFormat tcuFormat = mapVkFormat(format);
698
699         if      (tcuFormat.order == tcu::TextureFormat::DS)             return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
700         else if (tcuFormat.order == tcu::TextureFormat::D)              return VK_IMAGE_ASPECT_DEPTH_BIT;
701         else if (tcuFormat.order == tcu::TextureFormat::S)              return VK_IMAGE_ASPECT_STENCIL_BIT;
702
703         DE_ASSERT(false);
704         return 0u;
705 }
706
707 bool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, const VkPhysicalDevice device, const VkFormat format)
708 {
709         VkFormatProperties formatProps;
710         instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
711         return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
712 }
713
714 VkFormat pickSupportedDepthStencilFormat (const InstanceInterface&      instanceInterface,
715                                                                                   const VkPhysicalDevice        device,
716                                                                                   const deUint32                        numFormats,
717                                                                                   const VkFormat*                       pFormats)
718 {
719         for (deUint32 i = 0; i < numFormats; ++i)
720                 if (isSupportedDepthStencilFormat(instanceInterface, device, pFormats[i]))
721                         return pFormats[i];
722         return VK_FORMAT_UNDEFINED;
723 }
724
725 enum Flags
726 {
727         FLAG_TEST_DEPTH                                                 = 1u << 0,
728         FLAG_TEST_STENCIL                                               = 1u << 1,
729         FLAG_DONT_USE_TEST_ATTACHMENT                   = 1u << 2,
730         FLAG_DONT_USE_EARLY_FRAGMENT_TESTS              = 1u << 3,
731 };
732
733 class EarlyFragmentTest : public TestCase
734 {
735 public:
736                                                 EarlyFragmentTest       (tcu::TestContext&              testCtx,
737                                                                                          const std::string              name,
738                                                                                          const deUint32                 flags);
739
740         void                            initPrograms            (SourceCollections&             programCollection) const;
741         TestInstance*           createInstance          (Context&                               context) const;
742
743 private:
744         const deUint32          m_flags;
745 };
746
747 EarlyFragmentTest::EarlyFragmentTest (tcu::TestContext& testCtx, const std::string name, const deUint32 flags)
748         : TestCase      (testCtx, name, "")
749         , m_flags       (flags)
750 {
751 }
752
753 void EarlyFragmentTest::initPrograms (SourceCollections& programCollection) const
754 {
755         // Vertex
756         {
757                 std::ostringstream src;
758                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
759                         << "\n"
760                         << "layout(location = 0) in highp vec4 position;\n"
761                         << "\n"
762                         << "out gl_PerVertex {\n"
763                         << "   vec4 gl_Position;\n"
764                         << "};\n"
765                         << "\n"
766                         << "void main (void)\n"
767                         << "{\n"
768                         << "    gl_Position = position;\n"
769                         << "}\n";
770
771                 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
772         }
773
774         // Fragment
775         {
776                 const bool useEarlyTests = (m_flags & FLAG_DONT_USE_EARLY_FRAGMENT_TESTS) == 0;
777                 std::ostringstream src;
778                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
779                         << "\n"
780                         << (useEarlyTests ? "layout(early_fragment_tests) in;\n" : "")
781                         << "layout(location = 0) out highp vec4 fragColor;\n"
782                         << "\n"
783                         << "layout(binding = 0) coherent buffer Output {\n"
784                         << "    uint result;\n"
785                         << "} sb_out;\n"
786                         << "\n"
787                         << "void main (void)\n"
788                         << "{\n"
789                         << "    atomicAdd(sb_out.result, 1u);\n"
790                         << "    fragColor = vec4(1.0, 1.0, 0.0, 1.0);\n"
791                         << "}\n";
792
793                 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
794         }
795 }
796
797 class EarlyFragmentTestInstance : public TestInstance
798 {
799 public:
800                                                         EarlyFragmentTestInstance (Context& context, const deUint32 flags);
801
802         tcu::TestStatus                 iterate                                   (void);
803
804 private:
805         enum TestMode
806         {
807                 MODE_INVALID,
808                 MODE_DEPTH,
809                 MODE_STENCIL,
810         };
811
812         const TestMode                  m_testMode;
813         const bool                              m_useTestAttachment;
814         const bool                              m_useEarlyTests;
815 };
816
817 EarlyFragmentTestInstance::EarlyFragmentTestInstance (Context& context, const deUint32 flags)
818         : TestInstance                  (context)
819         , m_testMode                    (flags & FLAG_TEST_DEPTH   ? MODE_DEPTH :
820                                                          flags & FLAG_TEST_STENCIL ? MODE_STENCIL : MODE_INVALID)
821         , m_useTestAttachment   ((flags & FLAG_DONT_USE_TEST_ATTACHMENT) == 0)
822         , m_useEarlyTests               ((flags & FLAG_DONT_USE_EARLY_FRAGMENT_TESTS) == 0)
823 {
824         DE_ASSERT(m_testMode != MODE_INVALID);
825 }
826
827 tcu::TestStatus EarlyFragmentTestInstance::iterate (void)
828 {
829         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
830         const InstanceInterface&        vki                                     = m_context.getInstanceInterface();
831         const VkDevice                          device                          = m_context.getDevice();
832         const VkPhysicalDevice          physDevice                      = m_context.getPhysicalDevice();
833         const VkQueue                           queue                           = m_context.getUniversalQueue();
834         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
835         Allocator&                                      allocator                       = m_context.getDefaultAllocator();
836
837         // Color attachment
838
839         const tcu::IVec2                          renderSize                    = tcu::IVec2(32, 32);
840         const VkFormat                            colorFormat                   = VK_FORMAT_R8G8B8A8_UNORM;
841         const VkImageSubresourceRange colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
842         const Image                                       colorImage                    (vk, device, allocator, makeImageCreateInfo(renderSize, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT), MemoryRequirement::Any);
843         const Unique<VkImageView>         colorImageView                (makeImageView(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange));
844
845         // Test attachment (depth or stencil)
846         static const VkFormat stencilFormats[] =
847         {
848                 // One of the following formats must be supported, as per spec requirement.
849                 VK_FORMAT_S8_UINT,
850                 VK_FORMAT_D16_UNORM_S8_UINT,
851                 VK_FORMAT_D24_UNORM_S8_UINT,
852                 VK_FORMAT_D32_SFLOAT_S8_UINT,
853         };
854
855         const VkFormat testFormat = (m_testMode == MODE_STENCIL ? pickSupportedDepthStencilFormat(vki, physDevice, DE_LENGTH_OF_ARRAY(stencilFormats), stencilFormats)
856                                                                                                                         : VK_FORMAT_D16_UNORM);         // spec requires this format to be supported
857         if (testFormat == VK_FORMAT_UNDEFINED)
858                 return tcu::TestStatus::fail("Required depth/stencil format not supported");
859
860         if (m_useTestAttachment)
861                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Using depth/stencil format " << getFormatName(testFormat) << tcu::TestLog::EndMessage;
862
863         const VkImageSubresourceRange testSubresourceRange        = makeImageSubresourceRange(getImageAspectFlags(testFormat), 0u, 1u, 0u, 1u);
864         const Image                                       testImage                               (vk, device, allocator, makeImageCreateInfo(renderSize, testFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT), MemoryRequirement::Any);
865         const Unique<VkImageView>         testImageView                   (makeImageView(vk, device, *testImage, VK_IMAGE_VIEW_TYPE_2D, testFormat, testSubresourceRange));
866         const VkImageView                         attachmentImages[]      = { *colorImageView, *testImageView };
867         const deUint32                            numUsedAttachmentImages = (m_useTestAttachment ? 2u : 1u);
868
869         // Vertex buffer
870
871         const deUint32     numVertices                   = 6;
872         const VkDeviceSize vertexBufferSizeBytes = sizeof(tcu::Vec4) * numVertices;
873         const Buffer       vertexBuffer                  (vk, device, allocator, makeBufferCreateInfo(vertexBufferSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible);
874
875         {
876                 const Allocation& alloc = vertexBuffer.getAllocation();
877                 tcu::Vec4* const pVertices = reinterpret_cast<tcu::Vec4*>(alloc.getHostPtr());
878
879                 pVertices[0] = tcu::Vec4( 1.0f, -1.0f,  0.5f,  1.0f);
880                 pVertices[1] = tcu::Vec4(-1.0f, -1.0f,  0.0f,  1.0f);
881                 pVertices[2] = tcu::Vec4(-1.0f,  1.0f,  0.5f,  1.0f);
882
883                 pVertices[3] = tcu::Vec4(-1.0f,  1.0f,  0.5f,  1.0f);
884                 pVertices[4] = tcu::Vec4( 1.0f,  1.0f,  1.0f,  1.0f);
885                 pVertices[5] = tcu::Vec4( 1.0f, -1.0f,  0.5f,  1.0f);
886
887                 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), vertexBufferSizeBytes);
888                 // No barrier needed, flushed memory is automatically visible
889         }
890
891         // Result buffer
892
893         const VkDeviceSize resultBufferSizeBytes = sizeof(deUint32);
894         const Buffer resultBuffer(vk, device, allocator, makeBufferCreateInfo(resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
895
896         {
897                 const Allocation& alloc = resultBuffer.getAllocation();
898                 deUint32* const pData = static_cast<deUint32*>(alloc.getHostPtr());
899
900                 *pData = 0;
901                 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), resultBufferSizeBytes);
902         }
903
904         // Render result buffer (to retrieve color attachment contents)
905
906         const VkDeviceSize colorBufferSizeBytes = tcu::getPixelSize(mapVkFormat(colorFormat)) * renderSize.x() * renderSize.y();
907         const Buffer       colorBuffer                  (vk, device, allocator, makeBufferCreateInfo(colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible);
908
909         // Descriptors
910
911         const Unique<VkDescriptorSetLayout> descriptorSetLayout(DescriptorSetLayoutBuilder()
912                 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
913                 .build(vk, device));
914
915         const Unique<VkDescriptorPool> descriptorPool(DescriptorPoolBuilder()
916                 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
917                 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
918
919         const Unique<VkDescriptorSet> descriptorSet                              (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
920         const VkDescriptorBufferInfo  resultBufferDescriptorInfo = makeDescriptorBufferInfo(resultBuffer.get(), 0ull, resultBufferSizeBytes);
921
922         DescriptorSetUpdateBuilder()
923                 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferDescriptorInfo)
924                 .update(vk, device);
925
926         // Pipeline
927
928         const Unique<VkShaderModule>    vertexModule  (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
929         const Unique<VkShaderModule>    fragmentModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
930         const Unique<VkRenderPass>              renderPass        (makeRenderPass(vk, device, colorFormat, m_useTestAttachment, testFormat));
931         const Unique<VkFramebuffer>             framebuffer       (makeFramebuffer(vk, device, *renderPass, numUsedAttachmentImages, attachmentImages, renderSize));
932         const Unique<VkPipelineLayout>  pipelineLayout(makePipelineLayout(vk, device, *descriptorSetLayout));
933         const Unique<VkPipeline>                pipeline          (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule, renderSize,
934                                                                                                   (m_testMode == MODE_DEPTH), (m_testMode == MODE_STENCIL)));
935         const Unique<VkCommandPool>             cmdPool           (makeCommandPool(vk, device, queueFamilyIndex));
936         const Unique<VkCommandBuffer>   cmdBuffer         (makeCommandBuffer(vk, device, *cmdPool));
937
938         // Draw commands
939
940         {
941                 const VkRect2D renderArea = {
942                         makeOffset2D(0, 0),
943                         makeExtent2D(renderSize.x(), renderSize.y()),
944                 };
945                 const tcu::Vec4 clearColor(0.0f, 0.0f, 0.0f, 1.0f);
946                 const VkDeviceSize vertexBufferOffset = 0ull;
947
948                 beginCommandBuffer(vk, *cmdBuffer);
949
950                 {
951                         const VkImageMemoryBarrier barriers[] = {
952                                 makeImageMemoryBarrier(
953                                         0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
954                                         VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
955                                         *colorImage, colorSubresourceRange),
956                                 makeImageMemoryBarrier(
957                                         0u, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
958                                         VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
959                                         *testImage, testSubresourceRange),
960                         };
961
962                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u,
963                                 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers);
964                 }
965
966                 // Will clear the attachments with specified depth and stencil values.
967                 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor, 0.5f, 0u);
968
969                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
970                 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
971                 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
972
973                 // Mask half of the attachment image with value that will pass the stencil test.
974                 if (m_useTestAttachment && m_testMode == MODE_STENCIL)
975                         commandClearStencilAttachment(vk, *cmdBuffer, makeOffset2D(0, 0), makeExtent2D(renderSize.x()/2, renderSize.y()), 1u);
976
977                 vk.cmdDraw(*cmdBuffer, numVertices, 1u, 0u, 0u);
978                 endRenderPass(vk, *cmdBuffer);
979
980                 {
981                         const VkBufferMemoryBarrier shaderWriteBarrier = makeBufferMemoryBarrier(
982                                 VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, resultBufferSizeBytes);
983
984                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
985                                 0u, DE_NULL, 1u, &shaderWriteBarrier, 0u, DE_NULL);
986
987                         const VkImageMemoryBarrier preCopyColorImageBarrier = makeImageMemoryBarrier(
988                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
989                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
990                                 *colorImage, colorSubresourceRange);
991
992                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
993                                 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyColorImageBarrier);
994
995                         const VkBufferImageCopy copyRegion = makeBufferImageCopy(VK_IMAGE_ASPECT_COLOR_BIT, renderSize);
996                         vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, &copyRegion);
997
998                         const VkBufferMemoryBarrier postCopyColorBufferBarrier = makeBufferMemoryBarrier(
999                                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, colorBufferSizeBytes);
1000
1001                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u,
1002                                 0u, DE_NULL, 1u, &postCopyColorBufferBarrier, 0u, DE_NULL);
1003                 }
1004
1005                 endCommandBuffer(vk, *cmdBuffer);
1006                 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1007         }
1008
1009         // Log result image
1010         {
1011                 const Allocation& alloc = colorBuffer.getAllocation();
1012                 invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), colorBufferSizeBytes);
1013
1014                 const tcu::ConstPixelBufferAccess imagePixelAccess(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1, alloc.getHostPtr());
1015
1016                 tcu::TestLog& log = m_context.getTestContext().getLog();
1017                 log << tcu::TestLog::Image("color0", "Rendered image", imagePixelAccess);
1018         }
1019
1020         // Verify results
1021         {
1022                 const Allocation& alloc = resultBuffer.getAllocation();
1023                 invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), resultBufferSizeBytes);
1024
1025                 const int  actualCounter           = *static_cast<deInt32*>(alloc.getHostPtr());
1026                 const bool expectPartialResult = (m_useEarlyTests && m_useTestAttachment);
1027                 const int  expectedCounter         = expectPartialResult ? renderSize.x() * renderSize.y() / 2 : renderSize.x() * renderSize.y();
1028                 const int  tolerance               = expectPartialResult ? de::max(renderSize.x(), renderSize.y()) * 3  : 0;
1029                 const int  expectedMin         = de::max(0, expectedCounter - tolerance);
1030                 const int  expectedMax             = expectedCounter + tolerance;
1031
1032                 tcu::TestLog& log = m_context.getTestContext().getLog();
1033                 log << tcu::TestLog::Message << "Expected value"
1034                         << (expectPartialResult ? " in range: [" + de::toString(expectedMin) + ", " + de::toString(expectedMax) + "]" : ": " + de::toString(expectedCounter))
1035                         << tcu::TestLog::EndMessage;
1036                 log << tcu::TestLog::Message << "Result value: " << de::toString(actualCounter) << tcu::TestLog::EndMessage;
1037
1038                 if (expectedMin <= actualCounter && actualCounter <= expectedMax)
1039                         return tcu::TestStatus::pass("Success");
1040                 else
1041                         return tcu::TestStatus::fail("Value out of range");
1042         }
1043 }
1044
1045 TestInstance* EarlyFragmentTest::createInstance (Context& context) const
1046 {
1047         // Check required features
1048         {
1049                 VkPhysicalDeviceFeatures features;
1050                 context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features);
1051
1052                 // SSBO writes in fragment shader
1053                 if (!features.fragmentStoresAndAtomics)
1054                         throw tcu::NotSupportedError("Missing required feature: fragmentStoresAndAtomics");
1055         }
1056
1057         return new EarlyFragmentTestInstance(context, m_flags);
1058 }
1059
1060 } // anonymous ns
1061
1062 tcu::TestCaseGroup* createEarlyFragmentTests (tcu::TestContext& testCtx)
1063 {
1064         de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "early_fragment", "early fragment test cases"));
1065
1066         static const struct
1067         {
1068                 std::string caseName;
1069                 deUint32        flags;
1070         } cases[] =
1071         {
1072                 { "no_early_fragment_tests_depth",                                      FLAG_TEST_DEPTH   | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS                                                                  },
1073                 { "no_early_fragment_tests_stencil",                            FLAG_TEST_STENCIL | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS                                                                  },
1074                 { "early_fragment_tests_depth",                                         FLAG_TEST_DEPTH                                                                                                                                                 },
1075                 { "early_fragment_tests_stencil",                                       FLAG_TEST_STENCIL                                                                                                                                               },
1076                 { "no_early_fragment_tests_depth_no_attachment",        FLAG_TEST_DEPTH   | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS | FLAG_DONT_USE_TEST_ATTACHMENT  },
1077                 { "no_early_fragment_tests_stencil_no_attachment",      FLAG_TEST_STENCIL | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS | FLAG_DONT_USE_TEST_ATTACHMENT  },
1078                 { "early_fragment_tests_depth_no_attachment",           FLAG_TEST_DEPTH   |                                                                              FLAG_DONT_USE_TEST_ATTACHMENT  },
1079                 { "early_fragment_tests_stencil_no_attachment",         FLAG_TEST_STENCIL |                                                                              FLAG_DONT_USE_TEST_ATTACHMENT  },
1080         };
1081
1082         for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i)
1083                 testGroup->addChild(new EarlyFragmentTest(testCtx, cases[i].caseName, cases[i].flags));
1084
1085         return testGroup.release();
1086 }
1087
1088 } // pipeline
1089 } // vkt