8ff7b9c34b8921aa21db70962017d47cf3b3e356
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / shaderrender / vktShaderRenderBuiltinVarTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7  * Copyright (c) 2016 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Shader builtin variable tests.
24  *//*--------------------------------------------------------------------*/
25
26 #include "vktShaderRenderBuiltinVarTests.hpp"
27
28 #include "tcuFloat.hpp"
29 #include "deUniquePtr.hpp"
30 #include "vkDefs.hpp"
31 #include "vktShaderRender.hpp"
32 #include "gluShaderUtil.hpp"
33 #include "tcuImageCompare.hpp"
34 #include "tcuStringTemplate.hpp"
35 #include "tcuTextureUtil.hpp"
36 #include "tcuTestLog.hpp"
37 #include "vktDrawUtil.hpp"
38 #include "vkImageUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkMemUtil.hpp"
41
42 #include "deMath.h"
43 #include "deRandom.hpp"
44
45 #include <map>
46
47 using namespace std;
48 using namespace tcu;
49 using namespace vk;
50 using namespace de;
51
52 namespace vkt
53 {
54 using namespace drawutil;
55
56 namespace sr
57 {
58
59 namespace
60 {
61
62 enum
63 {
64         FRONTFACE_RENDERWIDTH                   = 16,
65         FRONTFACE_RENDERHEIGHT                  = 16
66 };
67
68 class FrontFacingVertexShader : public rr::VertexShader
69 {
70 public:
71         FrontFacingVertexShader (void)
72                 : rr::VertexShader(1, 0)
73         {
74                 m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
75         }
76
77         void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
78         {
79                 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
80                 {
81                         packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0],
82                                                                                                                                          packets[packetNdx]->instanceNdx,
83                                                                                                                                          packets[packetNdx]->vertexNdx);
84                 }
85         }
86 };
87
88 class FrontFacingFragmentShader : public rr::FragmentShader
89 {
90 public:
91         FrontFacingFragmentShader (void)
92                 : rr::FragmentShader(0, 1)
93         {
94                 m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
95         }
96
97         void shadeFragments (rr::FragmentPacket* , const int numPackets, const rr::FragmentShadingContext& context) const
98         {
99                 tcu::Vec4 color;
100                 for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
101                 {
102                         for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
103                         {
104                                 if (context.visibleFace == rr::FACETYPE_FRONT)
105                                         color = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
106                                 else
107                                         color = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
108                                 rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
109                         }
110                 }
111         }
112 };
113
114 class BuiltinGlFrontFacingCaseInstance : public ShaderRenderCaseInstance
115 {
116 public:
117                                         BuiltinGlFrontFacingCaseInstance        (Context& context, VkPrimitiveTopology topology);
118
119         TestStatus              iterate                                                         (void);
120 private:
121         const VkPrimitiveTopology                                                       m_topology;
122 };
123
124 BuiltinGlFrontFacingCaseInstance::BuiltinGlFrontFacingCaseInstance (Context& context, VkPrimitiveTopology topology)
125         : ShaderRenderCaseInstance      (context)
126         , m_topology                            (topology)
127 {
128 }
129
130
131 TestStatus BuiltinGlFrontFacingCaseInstance::iterate (void)
132 {
133         TestLog&                                        log                             = m_context.getTestContext().getLog();
134         std::vector<Vec4>                       vertices;
135         std::vector<VulkanShader>       shaders;
136         FrontFacingVertexShader         vertexShader;
137         FrontFacingFragmentShader       fragmentShader;
138         std::string                                     testDesc;
139
140         vertices.push_back(Vec4( -0.75f,        -0.75f, 0.0f,   1.0f));
141         vertices.push_back(Vec4(  0.0f,         -0.75f, 0.0f,   1.0f));
142         vertices.push_back(Vec4( -0.37f,        0.75f,  0.0f,   1.0f));
143         vertices.push_back(Vec4(  0.37f,        0.75f,  0.0f,   1.0f));
144         vertices.push_back(Vec4(  0.75f,        -0.75f, 0.0f,   1.0f));
145         vertices.push_back(Vec4(  0.0f,         -0.75f, 0.0f,   1.0f));
146
147         shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("vert")));
148         shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("frag")));
149
150         testDesc = "gl_FrontFacing " + getPrimitiveTopologyShortName(m_topology) + " ";
151
152         DrawState                                       drawState               (m_topology, FRONTFACE_RENDERWIDTH, FRONTFACE_RENDERHEIGHT);
153         DrawCallData                            drawCallData    (vertices);
154         VulkanProgram                           vulkanProgram   (shaders);
155
156         VulkanDrawContext                       dc(m_context, drawState, drawCallData, vulkanProgram);
157         dc.draw();
158
159         ReferenceDrawContext            refDrawContext(drawState, drawCallData, vertexShader, fragmentShader);
160         refDrawContext.draw();
161
162         log << TestLog::Image( "reference",
163                                                         "reference",
164                                                         tcu::ConstPixelBufferAccess(tcu::TextureFormat(
165                                                                         refDrawContext.getColorPixels().getFormat()),
166                                                                         refDrawContext.getColorPixels().getWidth(),
167                                                                         refDrawContext.getColorPixels().getHeight(),
168                                                                         1,
169                                                                         refDrawContext.getColorPixels().getDataPtr()));
170
171         log << TestLog::Image(  "result",
172                                                         "result",
173                                                         tcu::ConstPixelBufferAccess(tcu::TextureFormat(
174                                                                         dc.getColorPixels().getFormat()),
175                                                                         dc.getColorPixels().getWidth(),
176                                                                         dc.getColorPixels().getHeight(),
177                                                                         1,
178                                                                         dc.getColorPixels().getDataPtr()));
179
180         if (tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
181                                                                                                   "ComparisonResult",
182                                                                                                   "Image comparison result",
183                                                                                                   refDrawContext.getColorPixels(),
184                                                                                                   dc.getColorPixels(),
185                                                                                                   UVec4(0u),
186                                                                                                   IVec3(1,1,0),
187                                                                                                   false,
188                                                                                                   tcu::COMPARE_LOG_RESULT))
189         {
190                 testDesc += "passed";
191                 return tcu::TestStatus::pass(testDesc.c_str());
192         }
193         else
194         {
195                 testDesc += "failed";
196                 return tcu::TestStatus::fail(testDesc.c_str());
197         }
198 }
199
200 class BuiltinGlFrontFacingCase : public TestCase
201 {
202 public:
203                                                                 BuiltinGlFrontFacingCase        (TestContext& testCtx, VkPrimitiveTopology topology, const char* name, const char* description);
204         virtual                                         ~BuiltinGlFrontFacingCase       (void);
205
206         void                                            initPrograms                            (SourceCollections& dst) const;
207         TestInstance*                           createInstance                          (Context& context) const;
208
209 private:
210                                                                 BuiltinGlFrontFacingCase        (const BuiltinGlFrontFacingCase&);      // not allowed!
211         BuiltinGlFrontFacingCase&       operator=                                       (const BuiltinGlFrontFacingCase&);      // not allowed!
212
213         const VkPrimitiveTopology       m_topology;
214 };
215
216 BuiltinGlFrontFacingCase::BuiltinGlFrontFacingCase (TestContext& testCtx, VkPrimitiveTopology topology, const char* name, const char* description)
217         : TestCase                                      (testCtx, name, description)
218         , m_topology                            (topology)
219 {
220 }
221
222 BuiltinGlFrontFacingCase::~BuiltinGlFrontFacingCase (void)
223 {
224 }
225
226 void BuiltinGlFrontFacingCase::initPrograms (SourceCollections& programCollection) const
227 {
228         {
229                 std::ostringstream vertexSource;
230                 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
231                         << "\n"
232                         << "layout(location = 0) in highp vec4 position;\n"
233                         << "void main()\n"
234                         << "{\n"
235                         << "gl_Position = position;\n"
236                         << "gl_PointSize = 1.0;\n"
237                         << "}\n";
238                 programCollection.glslSources.add("vert") << glu::VertexSource(vertexSource.str());
239         }
240
241         {
242                 std::ostringstream fragmentSource;
243                 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
244                         << "\n"
245                         << "layout(location = 0) out mediump vec4 color;\n"
246                         << "void main()\n"
247                         << "{\n"
248                         << "if (gl_FrontFacing)\n"
249                         << "    color = vec4(1.0, 0.0, 0.0, 1.0);\n"
250                         << "else\n"
251                         << "    color = vec4(0.0, 1.0, 0.0, 1.0);\n"
252                         << "}\n";
253                 programCollection.glslSources.add("frag") << glu::FragmentSource(fragmentSource.str());
254         }
255 }
256
257 TestInstance* BuiltinGlFrontFacingCase::createInstance (Context& context) const
258 {
259         return new BuiltinGlFrontFacingCaseInstance(context, m_topology);
260 }
261
262 class BuiltinFragDepthCaseInstance : public TestInstance
263 {
264 public:
265         enum
266         {
267                 RENDERWIDTH             = 16,
268                 RENDERHEIGHT    = 16
269         };
270                                         BuiltinFragDepthCaseInstance            (Context& context, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, float defaultDepth, bool depthClampEnable, const VkSampleCountFlagBits samples);
271         TestStatus              iterate                                                         (void);
272
273         bool                    validateDepthBuffer                                     (const tcu::ConstPixelBufferAccess& validationBuffer, const tcu::ConstPixelBufferAccess& markerBuffer, const float tolerance) const;
274 private:
275         const VkPrimitiveTopology               m_topology;
276         const VkFormat                                  m_format;
277         const bool                                              m_largeDepthEnable;
278         const float                                             m_defaultDepthValue;
279         const bool                                              m_depthClampEnable;
280         const VkSampleCountFlagBits             m_samples;
281         const tcu::UVec2                                m_renderSize;
282         const float                                             m_largeDepthBase;
283 };
284
285 BuiltinFragDepthCaseInstance::BuiltinFragDepthCaseInstance (Context& context, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, float defaultDepth, bool depthClampEnable, const VkSampleCountFlagBits samples)
286         : TestInstance                  (context)
287         , m_topology                    (topology)
288         , m_format                              (format)
289         , m_largeDepthEnable    (largeDepthEnable)
290         , m_defaultDepthValue   (defaultDepth)
291         , m_depthClampEnable    (depthClampEnable)
292         , m_samples                             (samples)
293         , m_renderSize                  (RENDERWIDTH, RENDERHEIGHT)
294         , m_largeDepthBase              (20.0f)
295 {
296         const InstanceInterface&        vki                                     = m_context.getInstanceInterface();
297         const VkPhysicalDevice          physicalDevice          = m_context.getPhysicalDevice();
298
299         try
300         {
301                 VkImageFormatProperties         imageFormatProperties;
302                 VkFormatProperties                      formatProperties;
303
304                 if (m_context.getDeviceFeatures().fragmentStoresAndAtomics == VK_FALSE)
305                         throw tcu::NotSupportedError("fragmentStoresAndAtomics not supported");
306
307                 imageFormatProperties = getPhysicalDeviceImageFormatProperties(vki, physicalDevice, m_format, VK_IMAGE_TYPE_2D,
308                                 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, (VkImageCreateFlags)0);
309
310                 if ((imageFormatProperties.sampleCounts & m_samples) == 0)
311                         throw tcu::NotSupportedError("Image format and sample count not supported");
312
313                 formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, VK_FORMAT_R8G8B8A8_UINT);
314
315                 if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
316                         throw tcu::NotSupportedError("MarkerImage format not supported as storage image");
317         }
318         catch (const vk::Error& e)
319         {
320                 if (e.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
321                         throw tcu::NotSupportedError("Image format not supported");
322                 else
323                         throw;
324
325         }
326 }
327
328 TestStatus BuiltinFragDepthCaseInstance::iterate (void)
329 {
330         const VkDevice                                  device                          = m_context.getDevice();
331         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
332         const VkQueue                                   queue                           = m_context.getUniversalQueue();
333         Allocator&                                              allocator                       = m_context.getDefaultAllocator();
334         const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
335         TestLog&                                                log                                     = m_context.getTestContext().getLog();
336         const deUint32                                  scale                           = 4;                                                                            // To account for std140 stride
337         const VkDeviceSize                              pixelCount                      = m_renderSize.x() * m_renderSize.y();
338         std::string                                             testDesc;
339         Move<VkImage>                                   depthResolveImage;
340         Move<VkImageView>                               depthResolveImageView;
341         MovePtr<Allocation>                             depthResolveAllocation;
342         Move<VkImage>                                   depthImage;
343         Move<VkImageView>                               depthImageView;
344         MovePtr<Allocation>                             depthImageAllocation;
345         Move<VkBuffer>                                  controlBuffer;
346         MovePtr<Allocation>                             controlBufferAllocation;
347         Move<VkImage>                                   markerImage;
348         Move<VkImageView>                               markerImageView;
349         MovePtr<Allocation>                             markerImageAllocation;
350         Move<VkBuffer>                                  markerBuffer;
351         MovePtr<Allocation>                             markerBufferAllocation;
352         Move<VkBuffer>                                  validationBuffer;
353         MovePtr<Allocation>                             validationAlloc;
354         MovePtr<Allocation>                             depthInitAllocation;
355         Move<VkCommandPool>                             cmdPool;
356         Move<VkCommandBuffer>                   transferCmdBuffer;
357         Move<VkFence>                                   fence;
358         Move<VkSampler>                                 depthSampler;
359
360         // Create Buffer/Image for validation
361         {
362                 VkFormat        resolvedBufferFormat = VK_FORMAT_R32_SFLOAT;
363                 const VkBufferCreateInfo validationBufferCreateInfo =
364                 {
365                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                                                           // VkStructureType              sType
366                         DE_NULL,                                                                                                                                        // const void*                  pNext
367                         (VkBufferCreateFlags)0,                                                                                                         // VkBufferCreateFlags  flags
368                         m_samples * pixelCount * getPixelSize(mapVkFormat(resolvedBufferFormat)),       // VkDeviceSize                 size
369                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                                                                                       // VkBufferUsageFlags   usage
370                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                sharingMode
371                         0u,                                                                                                                                                     // uint32_t                             queueFamilyIndexCount,
372                         DE_NULL                                                                                                                                         // const uint32_t*              pQueueFamilyIndices
373                 };
374
375                 validationBuffer = createBuffer(vk, device, &validationBufferCreateInfo);
376                 validationAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *validationBuffer), MemoryRequirement::HostVisible);
377                 VK_CHECK(vk.bindBufferMemory(device, *validationBuffer, validationAlloc->getMemory(), validationAlloc->getOffset()));
378
379                 const VkImageCreateInfo depthResolveImageCreateInfo =
380                 {
381                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                            // VkStructureType                      sType
382                         DE_NULL,                                                                                                                        // const void*                          pNext
383                         (VkImageCreateFlags)0,                                                                                          // VkImageCreateFlags           flags
384                         VK_IMAGE_TYPE_2D,                                                                                                       // VkIMageType                          imageType
385                         resolvedBufferFormat,                                                                                           // VkFormat                                     format
386                         makeExtent3D(m_samples * m_renderSize.x(), m_renderSize.y(), 1u),       // VkExtent3D                           extent
387                         1u,                                                                                                                                     // uint32_t                                     mipLevels
388                         1u,                                                                                                                                     // uint32_t                                     arrayLayers
389                         VK_SAMPLE_COUNT_1_BIT,                                                                                          // VkSampleCountFlagsBits       samples
390                         VK_IMAGE_TILING_OPTIMAL,                                                                                        // VkImageTiling                        tiling
391                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |                                                                       // VkImageUsageFlags            usage
392                         VK_IMAGE_USAGE_STORAGE_BIT |
393                         VK_IMAGE_USAGE_TRANSFER_DST_BIT,
394                         VK_SHARING_MODE_EXCLUSIVE,                                                                                      // VkSharingMode                        sharingMode
395                         0u,                                                                                                                                     // uint32_t                                     queueFamilyIndexCount
396                         DE_NULL,                                                                                                                        // const uint32_t                       pQueueFamilyIndices
397                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                       // VkImageLayout                        initialLayout
398                 };
399
400                 depthResolveImage = createImage(vk, device, &depthResolveImageCreateInfo, DE_NULL);
401                 depthResolveAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *depthResolveImage), MemoryRequirement::Any);
402                 VK_CHECK(vk.bindImageMemory(device, *depthResolveImage, depthResolveAllocation->getMemory(), depthResolveAllocation->getOffset()));
403
404                 const VkImageViewCreateInfo depthResolveImageViewCreateInfo =
405                 {
406                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                                                               // VkStructureType                      sType
407                         DE_NULL,                                                                                                                                // const void*                          pNext
408                         (VkImageViewCreateFlags)0,                                                                                              // VkImageViewCreateFlags       flags
409                         *depthResolveImage,                                                                                                             // VkImage                                      image
410                         VK_IMAGE_VIEW_TYPE_2D,                                                                                                  // VkImageViewType                      type
411                         resolvedBufferFormat,                                                                                                   // VkFormat                                     format
412                         makeComponentMappingRGBA(),                                                                                             // VkComponentMapping           componentMapping
413                         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)    // VkImageSUbresourceRange      subresourceRange
414                 };
415
416                 depthResolveImageView = createImageView(vk, device, &depthResolveImageViewCreateInfo, DE_NULL);
417         }
418
419         // Marker Buffer
420         {
421                 const VkDeviceSize      size                    = m_samples * m_renderSize.x() * m_renderSize.y() * getPixelSize(mapVkFormat(VK_FORMAT_R8G8B8A8_UINT));
422
423                 const VkBufferCreateInfo markerBufferCreateInfo =
424                 {
425                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                   // VkStructureType                      sType
426                         DE_NULL,                                                                                // const void*                          pNext
427                         (VkBufferCreateFlags)0,                                                 // VkBufferCreateFlags          flags
428                         size,                                                                                   // VkDeviceSize                         size
429                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                               // VkBufferUsageFlags           usage
430                         VK_SHARING_MODE_EXCLUSIVE,                                              // VkSharingMode                        sharingMode
431                         0u,                                                                                             // uint32_t                                     queueFamilyIndexCount
432                         DE_NULL                                                                                 // const uint32_t*                      pQueueFamilyIndices
433                 };
434
435                 markerBuffer = createBuffer(vk, device, &markerBufferCreateInfo, DE_NULL);
436                 markerBufferAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *markerBuffer), MemoryRequirement::HostVisible);
437                 VK_CHECK(vk.bindBufferMemory(device, *markerBuffer, markerBufferAllocation->getMemory(), markerBufferAllocation->getOffset()));
438
439                 const VkImageCreateInfo markerImageCreateInfo =
440                 {
441                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                    // VkStructureType                      sType
442                         DE_NULL,                                                                                                                // const void*                          pNext
443                         (VkImageCreateFlags)0,                                                                                  // VkImageCreateFlags           flags
444                         VK_IMAGE_TYPE_2D,                                                                                               // VkImageType                          imageType
445                         VK_FORMAT_R8G8B8A8_UINT,                                                                                // VkFormat                                     format
446                         makeExtent3D(m_samples * m_renderSize.x(), m_renderSize.y(), 1),// VkExtent3D                           extent
447                         1u,                                                                                                                             // uint32_t                                     mipLevels
448                         1u,                                                                                                                             // uint32_t                                     arrayLayers
449                         VK_SAMPLE_COUNT_1_BIT,                                                                                  // VkSampleCountFlagsBit        smaples
450                         VK_IMAGE_TILING_OPTIMAL,                                                                                // VkImageTiling                        tiling
451                         VK_IMAGE_USAGE_STORAGE_BIT |                                                                    // VkImageUsageFlags            usage
452                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
453                         VK_IMAGE_USAGE_TRANSFER_DST_BIT,
454                         VK_SHARING_MODE_EXCLUSIVE,                                                                              // VkSharingMode                        sharing
455                         0u,                                                                                                                             // uint32_t                                     queueFamilyIndexCount
456                         DE_NULL,                                                                                                                // const uint32_t*                      pQueueFamilyIndices
457                         VK_IMAGE_LAYOUT_UNDEFINED                                                                               // VkImageLayout                        initialLayout
458                 };
459
460                 markerImage = createImage(vk, device, &markerImageCreateInfo, DE_NULL);
461                 markerImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *markerImage), MemoryRequirement::Any);
462                 VK_CHECK(vk.bindImageMemory(device, *markerImage, markerImageAllocation->getMemory(), markerImageAllocation->getOffset()));
463
464                 const VkImageViewCreateInfo markerViewCreateInfo =
465                 {
466                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                               // VkStructureType                      sType
467                         DE_NULL,                                                                                                // const void*                          pNext
468                         (VkImageViewCreateFlags)0,                                                              // VkImageViewCreateFlags       flags
469                         *markerImage,                                                                                   // VkImage                                      image
470                         VK_IMAGE_VIEW_TYPE_2D,                                                                  // VkImageViewType                      viewType
471                         VK_FORMAT_R8G8B8A8_UINT,                                                                // VkFormat                                     format
472                         makeComponentMappingRGBA(),                                                             // VkComponentMapping           components
473                         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)
474                 };
475
476                 markerImageView = createImageView(vk, device, &markerViewCreateInfo, DE_NULL);
477         }
478
479         // Control Buffer
480         {
481                 const VkBufferCreateInfo controlBufferCreateInfo =
482                 {
483                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                   // VkStructureType              sType
484                         DE_NULL,                                                                                                // const void*                  pNext
485                         (VkBufferCreateFlags)0,                                                                 // VkBufferCreateFlags  flags
486                         pixelCount * sizeof(float)* scale,                                              // VkDeviceSize                 size
487                         VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,                                             // VkBufferUsageFlags   usage
488                         VK_SHARING_MODE_EXCLUSIVE,                                                              // VkSharingMode                sharingMode
489                         0u,                                                                                                             // deUint32                             queueFamilyIndexCount
490
491                         DE_NULL                                                                                                 // pQueueFamilyIndices
492                 };
493
494                 controlBuffer = createBuffer(vk, device, &controlBufferCreateInfo, DE_NULL);
495                 controlBufferAllocation = allocator.allocate( getBufferMemoryRequirements(vk, device, *controlBuffer), MemoryRequirement::HostVisible);
496                 VK_CHECK(vk.bindBufferMemory(device, *controlBuffer, controlBufferAllocation->getMemory(), controlBufferAllocation->getOffset()));
497
498                 {
499                         float* bufferData = (float*)(controlBufferAllocation->getHostPtr());
500                         float sign = m_depthClampEnable ? -1.0f : 1.0f;
501                         for (deUint32 ndx = 0; ndx < m_renderSize.x() * m_renderSize.y(); ndx++)
502                         {
503                                 bufferData[ndx * scale] = (float)ndx / 256.0f * sign;
504                                 if (m_largeDepthEnable)
505                                         bufferData[ndx * scale] += m_largeDepthBase;
506                         }
507
508                         const VkMappedMemoryRange range =
509                         {
510                                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
511                                 DE_NULL,
512                                 controlBufferAllocation->getMemory(),
513                                 0u,
514                                 VK_WHOLE_SIZE
515                         };
516
517                         VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
518                 }
519         }
520
521         // Depth Buffer
522         {
523                 VkImageSubresourceRange depthSubresourceRange   = makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u);
524                 const VkImageCreateInfo depthImageCreateInfo    =
525                 {
526                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                    // VkStructureType                      sType
527                         DE_NULL,                                                                                                // const void*                          pNext
528                         (VkImageCreateFlags)0,                                                                  // VkImageCreateFlags           flags
529                         VK_IMAGE_TYPE_2D,                                                                               // VkImageType                          imageType
530                         m_format,                                                                                               // VkFormat                                     format
531                         makeExtent3D(m_renderSize.x(), m_renderSize.y(), 1u),   // VkExtent3D                           extent
532                         1u,                                                                                                             // uint32_t                                     mipLevels
533                         1u,                                                                                                             // uint32_t                                     arrayLayers
534                         m_samples,                                                                                              // VkSampleCountFlagsBits       samples
535                         VK_IMAGE_TILING_OPTIMAL,                                                                // VkImageTiling                        tiling
536                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
537                         VK_IMAGE_USAGE_TRANSFER_DST_BIT |
538                         VK_IMAGE_USAGE_SAMPLED_BIT      |
539                         VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,                    // VkImageUsageFlags            usage
540                         VK_SHARING_MODE_EXCLUSIVE,                                                              // VkShaderingMode                      sharingMode
541                         0u,                                                                                                             // uint32_t                                     queueFamilyIndexCount
542                         DE_NULL,                                                                                                // const uint32_t*                      pQueueFamilyIndices
543                         VK_IMAGE_LAYOUT_UNDEFINED                                                               // VkImageLayout                        initialLayout
544                 };
545
546                 depthImage = createImage(vk, device, &depthImageCreateInfo, DE_NULL);
547                 depthImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *depthImage), MemoryRequirement::Any);
548                 VK_CHECK(vk.bindImageMemory(device, *depthImage, depthImageAllocation->getMemory(), depthImageAllocation->getOffset()));
549
550                 const VkImageViewCreateInfo imageViewParams =
551                 {
552                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
553                         DE_NULL,                                                                                // const void*                          pNext;
554                         (VkImageViewCreateFlags)0,                                              // VkImageViewCreateFlags       flags;
555                         *depthImage,                                                                    // VkImage                                      image;
556                         VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
557                         m_format,                                                                               // VkFormat                                     format;
558                         makeComponentMappingRGBA(),                                             // VkComponentMapping           components;
559                         depthSubresourceRange,                                                  // VkImageSubresourceRange      subresourceRange;
560                 };
561                 depthImageView = createImageView(vk, device, &imageViewParams);
562
563                 const VkSamplerCreateInfo depthSamplerCreateInfo =
564                 {
565                         VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,                  // VkStructureType                      sType
566                         DE_NULL,                                                                                // const void*                          pNext
567                         (VkSamplerCreateFlags)0,                                                // VkSamplerCreateFlags         flags
568                         VK_FILTER_NEAREST,                                                              // VkFilter                                     minFilter
569                         VK_FILTER_NEAREST,                                                              // VkFilter                                     magFilter
570                         VK_SAMPLER_MIPMAP_MODE_NEAREST,                                 // VkSamplerMipMapMode          mipMapMode
571                         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,                  // VkSamplerAddressMode         addressModeU
572                         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,                  // VkSamplerAddressMode         addressModeV
573                         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,                  // VkSamplerAddressMode         addressmodeW
574                         0.0f,                                                                                   // float                                        mipLodBias
575                         VK_FALSE,                                                                               // VkBool32                                     anisotropyEnable
576                         0.0f,                                                                                   // float                                        maxAnisotropy
577                         VK_FALSE,                                                                               // VkBool32                                     compareEnable
578                         VK_COMPARE_OP_NEVER,                                                    // VkCompareOp                          compareOp
579                         0.0f,                                                                                   // float                                        minLod
580                         0.0f,                                                                                   // float                                        maxLod
581                         VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,                // VkBorderColor                        borderColor
582                         VK_FALSE                                                                                // VkBool32                                     unnormalizedCoordinates
583                 };
584
585                 depthSampler = createSampler(vk, device, &depthSamplerCreateInfo, DE_NULL);
586         }
587
588         // Command Pool
589         {
590                 const VkCommandPoolCreateInfo cmdPoolCreateInfo =
591                 {
592                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                     // VkStructureType                      sType
593                         DE_NULL,                                                                                        // const void*                          pNext
594                         VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,        // VkCommandPoolCreateFlags     flags
595                         queueFamilyIndex                                                                        // uint32_t                                     queueFamilyIndex
596                 };
597
598                 cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
599         }
600
601         // Command buffer for data transfers
602         {
603                 const VkCommandBufferAllocateInfo cmdBufferAllocInfo =
604                 {
605                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType              sType,
606                         DE_NULL,                                                                                // const void*                  pNext
607                         *cmdPool,                                                                               // VkCommandPool                commandPool
608                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel level
609                         1u                                                                                              // uint32_t                             bufferCount
610                 };
611
612                 transferCmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocInfo);
613         }
614
615         // Fence for data transfer
616         {
617                 const VkFenceCreateInfo fenceCreateInfo =
618                 {
619                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType
620                         DE_NULL,                                                                // const void*                  pNext
621                         (VkFenceCreateFlags)0                                   // VkFenceCreateFlags   flags
622                 };
623
624                 fence = createFence(vk, device, &fenceCreateInfo);
625         }
626
627         // Initialize Marker Buffer
628         {
629                 VkImageAspectFlags      depthImageAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT;
630                 if (hasStencilComponent(mapVkFormat(m_format).order))
631                         depthImageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
632
633                 const VkImageMemoryBarrier imageBarrier[] =
634                 {
635                         {
636                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType              sType
637                                 DE_NULL,                                                                                // const void*                  pNext
638                                 0,                                                                                              // VkAccessMask                 srcAccessMask
639                                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessMask                 dstAccessMask
640                                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                oldLayout
641                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                newLayout
642                                 VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             srcQueueFamilyIndex
643                                 VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             dstQueueFamilyIndex
644                                 *markerImage,                                                                   // VkImage                              image
645                                 {
646                                         VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask
647                                         0u,                                                                             // uint32_t                             baseMipLevel
648                                         1u,                                                                             // uint32_t                             mipLevels
649                                         0u,                                                                             // uint32_t                             baseArray
650                                         1u                                                                              // uint32_t                             arraySize
651                                 }
652                         },
653                 };
654
655                 const VkImageMemoryBarrier imagePostBarrier[] =
656                 {
657                         {
658                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType              sType
659                                 DE_NULL,                                                                                // const void*                  pNext
660                                 VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlagBits             srcAccessMask
661                                 VK_ACCESS_SHADER_WRITE_BIT,                                             // VkAccessFlagBits             dstAccessMask
662                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                oldLayout
663                                 VK_IMAGE_LAYOUT_GENERAL,                                                // VkImageLayout                newLayout
664                                 VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             srcQueueFamilyIndex
665                                 VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             dstQueueFamilyIndex
666                                 *markerImage,                                                                   // VkImage                              image
667                                 {
668                                         VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask
669                                         0u,                                                                             // uint32_t                             baseMipLevel
670                                         1u,                                                                             // uint32_t                             mipLevels
671                                         0u,                                                                             // uint32_t                             baseArray
672                                         1u                                                                              // uint32_t                             arraySize
673                                 }
674                         },
675                 };
676
677                 const VkCommandBufferBeginInfo  cmdBufferBeginInfo =
678                 {
679                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType
680                         DE_NULL,                                                                                // const void*                                          pNext
681                         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags
682                         (const VkCommandBufferInheritanceInfo*)DE_NULL  // VkCommandBufferInheritanceInfo       pInheritanceInfo
683                 };
684
685                 VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo));
686                 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
687                                 (VkDependencyFlags)0,
688                                 0, (const VkMemoryBarrier*)DE_NULL,
689                                 0, (const VkBufferMemoryBarrier*)DE_NULL,
690                                 DE_LENGTH_OF_ARRAY(imageBarrier), imageBarrier);
691
692                 const VkClearValue                              colorClearValue = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
693                 const VkImageSubresourceRange   colorClearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
694
695                 vk.cmdClearColorImage(*transferCmdBuffer, *markerImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &colorClearValue.color, 1u, &colorClearRange);
696
697                 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
698                                 (VkDependencyFlags)0,
699                                 0, (const VkMemoryBarrier*)DE_NULL,
700                                 0, (const VkBufferMemoryBarrier*)DE_NULL,
701                                 DE_LENGTH_OF_ARRAY(imagePostBarrier), imagePostBarrier);
702
703                 VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer));
704
705                 const VkSubmitInfo submitInfo =
706                 {
707                         VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                      sType
708                         DE_NULL,                                                                // const void*                          pNext
709                         0u,                                                                             // uint32_t                                     waitSemaphoreCount
710                         DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores
711                         (const VkPipelineStageFlags*)DE_NULL,   // const VkPipelineStageFlags*  pWaitDstStageMask
712                         1u,                                                                             // uint32_t                                     commandBufferCount
713                         &transferCmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers
714                         0u,                                                                             // uint32_t                                     signalSemaphoreCount
715                         DE_NULL                                                                 // const VkSemaphore*           pSignalSemaphores
716                 };
717
718                 VK_CHECK(vk.resetFences(device, 1, &fence.get()));
719                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
720                 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull)));
721         }
722
723
724         // Perform Draw
725         {
726                 std::vector<Vec4>                               vertices;
727                 std::vector<VulkanShader>               shaders;
728                 Move<VkDescriptorSetLayout>             descriptorSetLayout;
729                 Move<VkDescriptorPool>                  descriptorPool;
730                 Move<VkDescriptorSet>                   descriptorSet;
731
732                 // Descriptors
733                 {
734                         DescriptorSetLayoutBuilder      layoutBuilder;
735                         layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
736                         layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
737                         descriptorSetLayout = layoutBuilder.build(vk, device);
738                         descriptorPool = DescriptorPoolBuilder()
739                                         .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
740                                         .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
741                                         .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
742
743                         const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
744                         {
745                                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
746                                 DE_NULL,
747                                 *descriptorPool,
748                                 1u,
749                                 &descriptorSetLayout.get()
750                         };
751
752                         descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo);
753
754                         const VkDescriptorBufferInfo bufferInfo =
755                         {
756                                 *controlBuffer,
757                                 0u,
758                                 VK_WHOLE_SIZE
759                         };
760
761                         const VkDescriptorImageInfo imageInfo =
762                         {
763                                 (VkSampler)DE_NULL,
764                                 *markerImageView,
765                                 VK_IMAGE_LAYOUT_GENERAL
766                         };
767
768                         DescriptorSetUpdateBuilder()
769                                 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferInfo)
770                                 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
771                                 .update(vk, device);
772                 }
773
774                 vertices.push_back(Vec4( -0.70f,        0.5f,   0.0f,   1.0f));
775                 vertices.push_back(Vec4(  0.45f,        -0.75f, 0.0f,   1.0f));
776                 vertices.push_back(Vec4(  0.78f,        0.0f,   0.0f,   1.0f));
777                 vertices.push_back(Vec4( -0.1f,         0.6f,   0.0f,   1.0f));
778
779                 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragDepthVert")));
780                 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragDepthFrag")));
781
782                 DrawState                               drawState(m_topology, m_renderSize.x(), m_renderSize.y());
783                 DrawCallData                    drawCallData(vertices);
784                 VulkanProgram                   vulkanProgram(shaders);
785
786                 drawState.depthClampEnable                      = m_depthClampEnable;
787                 drawState.depthFormat                           = m_format;
788                 drawState.numSamples                            = m_samples;
789                 drawState.compareOp                                     = rr::TESTFUNC_ALWAYS;
790                 drawState.depthTestEnable                       = true;
791                 drawState.depthWriteEnable                      = true;
792                 drawState.depthBoundsTestEnable         = true;
793                 drawState.sampleShadingEnable           = true;
794                 vulkanProgram.depthImageView            = *depthImageView;
795                 vulkanProgram.descriptorSetLayout       = *descriptorSetLayout;
796                 vulkanProgram.descriptorSet                     = *descriptorSet;
797
798                 VulkanDrawContext               vulkanDrawContext(m_context, drawState, drawCallData, vulkanProgram);
799                 vulkanDrawContext.draw();
800
801                 log << TestLog::Image(  "resultColor",
802                                                                 "Result Color Buffer",
803                                                                 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
804                                                                                 vulkanDrawContext.getColorPixels().getFormat()),
805                                                                                 vulkanDrawContext.getColorPixels().getWidth(),
806                                                                                 vulkanDrawContext.getColorPixels().getHeight(),
807                                                                                 1,
808                                                                                 vulkanDrawContext.getColorPixels().getDataPtr()));
809
810         }
811
812         // Barrier to transition between first and second pass
813         {
814                 VkImageAspectFlags      depthImageAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT;
815                 if (hasStencilComponent(mapVkFormat(m_format).order))
816                         depthImageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
817
818                 const VkImageMemoryBarrier imageBarrier[] =
819                 {
820                         {
821                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                         // VkStructureType              sType
822                                 DE_NULL,                                                                                                        // const void*                  pNext
823                                 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,                           // VkAccessFlags                srcAccessMask
824                                 VK_ACCESS_SHADER_READ_BIT,                                                                      // VkAccessFlags                dstAccessMask
825                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,                       // VkImageLayout                oldLayout
826                                 VK_IMAGE_LAYOUT_GENERAL,                                                                        // VkImageLayout                newLayout
827                                 0u,                                                                                                                     // deUint32                             srcQueueFamilyIndex
828                                 0u,                                                                                                                     // deUint32                             dstQueueFamilyIndex
829                                 *depthImage,                                                                                            // VkImage                              image
830                                 {
831                                         depthImageAspectFlags,                                                  // VkImageAspectFlags           aspectMask
832                                         0u,                                                                                             // deUint32                                     baseMipLevel
833                                         1u,                                                                                             // deUint32                                     levelCount
834                                         0u,                                                                                             // deUint32                                     baseArrayLayer
835                                         1u                                                                                              // deUint32                                     layerCount
836                                 }
837                         },
838                         {
839                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                         // VkStructureType              sType
840                                 DE_NULL,                                                                                                        // const void*                  pNext
841                                 0u,                                                                                                                     // VkAccessFlags                srcAccessMask
842                                 VK_ACCESS_HOST_READ_BIT,                                                                        // VkAccessFlags                dstAccessMask
843                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                      // VkImageLayout                oldLayout
844                                 VK_IMAGE_LAYOUT_GENERAL,                                                                        // VkImageLayout                newLayout
845                                 0u,                                                                                                                     // deUint32                             srcQueueFamilyIndex
846                                 0u,                                                                                                                     // deUint32                             dstQueueFamilyIndex
847                                 *depthResolveImage,                                                                                     // VkImage                              image
848                                 {
849                                         VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags           aspectMask
850                                         0u,                                                                                             // deUint32                                     baseMipLevel
851                                         1u,                                                                                             // deUint32                                     levelCount
852                                         0u,                                                                                             // deUint32                                     baseArrayLayer
853                                         1u,                                                                                             // deUint32                                     layerCount
854
855                                 }
856                         }
857                 };
858
859                 const VkCommandBufferBeginInfo  cmdBufferBeginInfo =
860                 {
861                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType
862                         DE_NULL,                                                                                // const void*                                          pNext
863                         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags
864                         (const VkCommandBufferInheritanceInfo*)DE_NULL  // VkCommandBufferInheritanceInfo       pInheritanceInfo
865                 };
866
867                 VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo));
868                 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
869                                 (VkDependencyFlags)0,
870                                 0, (const VkMemoryBarrier*)DE_NULL,
871                                 0, (const VkBufferMemoryBarrier*)DE_NULL,
872                                 DE_LENGTH_OF_ARRAY(imageBarrier), imageBarrier);
873                 VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer));
874
875                 const VkSubmitInfo submitInfo =
876                 {
877                         VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                      sType
878                         DE_NULL,                                                                // const void*                          pNext
879                         0u,                                                                             // uint32_t                                     waitSemaphoreCount
880                         DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores
881                         (const VkPipelineStageFlags*)DE_NULL,   // const VkPipelineStageFlags*  pWaitDstStageMask
882                         1u,                                                                             // uint32_t                                     commandBufferCount
883                         &transferCmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers
884                         0u,                                                                             // uint32_t                                     signalSemaphoreCount
885                         DE_NULL                                                                 // const VkSemaphore*           pSignalSemaphores
886                 };
887
888                 VK_CHECK(vk.resetFences(device, 1, &fence.get()));
889                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
890                 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull)));
891         }
892
893         // Resolve Depth Buffer
894         {
895                 std::vector<Vec4>                               vertices;
896                 std::vector<VulkanShader>               shaders;
897                 Move<VkDescriptorSetLayout>             descriptorSetLayout;
898                 Move<VkDescriptorPool>                  descriptorPool;
899                 Move<VkDescriptorSet>                   descriptorSet;
900
901                 // Descriptors
902                 {
903                         DescriptorSetLayoutBuilder      layoutBuilder;
904                         layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
905                         layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
906                         descriptorSetLayout = layoutBuilder.build(vk, device);
907                         descriptorPool = DescriptorPoolBuilder()
908                                         .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
909                                         .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
910                                         .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
911
912                         const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
913                         {
914                                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
915                                 DE_NULL,
916                                 *descriptorPool,
917                                 1u,
918                                 &descriptorSetLayout.get()
919                         };
920
921                         descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo);
922
923                         const VkDescriptorImageInfo depthImageInfo =
924                         {
925                                 *depthSampler,
926                                 *depthImageView,
927                                 VK_IMAGE_LAYOUT_GENERAL
928                         };
929
930                         const VkDescriptorImageInfo imageInfo =
931                         {
932                                 (VkSampler)DE_NULL,
933                                 *depthResolveImageView,
934                                 VK_IMAGE_LAYOUT_GENERAL
935                         };
936
937                         DescriptorSetUpdateBuilder()
938                                 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &depthImageInfo)
939                                 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
940                                 .update(vk, device);
941                 }
942
943                 vertices.push_back(Vec4( -1.0f, -1.0f,  0.0f,   1.0f));
944                 vertices.push_back(Vec4( -1.0f,  1.0f,  0.0f,   1.0f));
945                 vertices.push_back(Vec4(  1.0f, -1.0f,  0.0f,   1.0f));
946                 vertices.push_back(Vec4(  1.0f,  1.0f,  0.0f,   1.0f));
947
948                 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragDepthVertPass2")));
949                 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragDepthFragPass2")));
950
951                 DrawState                               drawState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, m_renderSize.x(), m_renderSize.y());
952                 DrawCallData                    drawCallData(vertices);
953                 VulkanProgram                   vulkanProgram(shaders);
954
955                 drawState.numSamples                            = m_samples;
956                 drawState.sampleShadingEnable           = true;
957                 vulkanProgram.descriptorSetLayout       = *descriptorSetLayout;
958                 vulkanProgram.descriptorSet                     = *descriptorSet;
959
960                 VulkanDrawContext               vulkanDrawContext(m_context, drawState, drawCallData, vulkanProgram);
961                 vulkanDrawContext.draw();
962         }
963
964         // Transfer marker buffer
965         {
966                 const UVec2 copySize            = UVec2(m_renderSize.x() * m_samples, m_renderSize.y());
967                 const VkImageMemoryBarrier imageBarrier =
968                 {
969                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType              sType
970                         DE_NULL,                                                                                // const void*                  pNext
971                         VK_ACCESS_SHADER_WRITE_BIT,                                             // VkAccessFlags                srcAccessMask
972                         VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessMask                 dstAccessMask
973                         VK_IMAGE_LAYOUT_GENERAL,                                                // VkImageLayout                oldLayout
974                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                   // VkImageLayout                newLayout
975                         VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             srcQueueFamilyIndex
976                         VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             dstQueueFamilyIndex
977                         *markerImage,                                                                   // VkImage                              image
978                         {
979                                 VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask
980                                 0u,                                                                             // uint32_t                             baseMipLevel
981                                 1u,                                                                             // uint32_t                             mipLevels
982                                 0u,                                                                             // uint32_t                             baseArray
983                                 1u                                                                              // uint32_t                             arraySize
984                         }
985                 };
986
987                 const VkBufferMemoryBarrier bufferBarrier =
988                 {
989                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType              sType
990                         DE_NULL,                                                                                // const void*                  pNext
991                         VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                srcAccessMask
992                         VK_ACCESS_HOST_READ_BIT,                                                // VkAccessFlags                dstAccessMask
993                         VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             srcQueueFamilyIndex
994                         VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             dstQueueFamilyIndex
995                         *markerBuffer,                                                                  // VkBufer                              buffer
996                         0u,                                                                                             // VkDeviceSize                 offset
997                         VK_WHOLE_SIZE                                                                   // VkDeviceSize                 size
998                 };
999
1000                 const VkBufferImageCopy bufferImageCopy =
1001                 {
1002                         0u,                                                                     // VkDeviceSize         bufferOffset
1003                         copySize.x(),                                           // uint32_t                     bufferRowLength
1004                         copySize.y(),                                           // uint32_t                     bufferImageHeight
1005                         {
1006                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspect
1007                                 0u,                                                     // uint32_t                             mipLevel
1008                                 0u,                                                     // uint32_t                             baseArrayLayer
1009                                 1u                                                      // uint32_t                             layerCount
1010                         },
1011                         { 0, 0, 0 },                                            // VkOffset3D           imageOffset
1012                         {
1013                                 copySize.x(),                           // uint32_t                             width
1014                                 copySize.y(),                           // uint32_t                             height,
1015                                 1u                                                      // uint32_t                             depth
1016                         }
1017                 };
1018
1019                 const VkCommandBufferBeginInfo  cmdBufferBeginInfo =
1020                 {
1021                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType
1022                         DE_NULL,                                                                                // const void*                                          pNext
1023                         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags
1024                         (const VkCommandBufferInheritanceInfo*)DE_NULL  // VkCommandBufferInheritanceInfo       pInheritanceInfo
1025                 };
1026
1027                 VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo));
1028                 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1029                                 (VkDependencyFlags)0,
1030                                 0, (const VkMemoryBarrier*)DE_NULL,
1031                                 0, (const VkBufferMemoryBarrier*)DE_NULL,
1032                                 1, &imageBarrier);
1033                 vk.cmdCopyImageToBuffer(*transferCmdBuffer, *markerImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *markerBuffer, 1u, &bufferImageCopy);
1034                 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1035                                 (VkDependencyFlags)0,
1036                                 0, (const VkMemoryBarrier*)DE_NULL,
1037                                 1, &bufferBarrier,
1038                                 0, (const VkImageMemoryBarrier*)DE_NULL);
1039                 VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer));
1040
1041                 const VkSubmitInfo submitInfo =
1042                 {
1043                         VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                      sType
1044                         DE_NULL,                                                                // const void*                          pNext
1045                         0u,                                                                             // uint32_t                                     waitSemaphoreCount
1046                         DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores
1047                         (const VkPipelineStageFlags*)DE_NULL,   // const VkPipelineStageFlags*  pWaitDstStageMask
1048                         1u,                                                                             // uint32_t                                     commandBufferCount
1049                         &transferCmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers
1050                         0u,                                                                             // uint32_t                                     signalSemaphoreCount
1051                         DE_NULL                                                                 // const VkSemaphore*           pSignalSemaphores
1052                 };
1053
1054                 VK_CHECK(vk.resetFences(device, 1, &fence.get()));
1055                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1056                 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull)));
1057         }
1058
1059         // Verify depth buffer
1060         {
1061                 bool status;
1062
1063                 const VkBufferMemoryBarrier bufferBarrier =
1064                 {
1065                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                        // VkStructureType              sType
1066                         DE_NULL,                                                                                        // const void*                  pNext
1067                         VK_ACCESS_TRANSFER_WRITE_BIT,                                           // VkAccessFlags                srcAccessMask
1068                         VK_ACCESS_HOST_READ_BIT,                                                        // VkAccessFlags                dstAccessMask
1069                         VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             srcQueueFamilyIndex
1070                         VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             dstQueueFamilyIndex
1071                         *validationBuffer,                                                                      // VkBuffer                             buffer
1072                         0u,                                                                                                     // VkDeviceSize                 offset
1073                         VK_WHOLE_SIZE                                                                           // VkDeviceSize                 size
1074                 };
1075
1076                 const VkImageMemoryBarrier imageBarrier =
1077                 {
1078                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType              sType
1079                         DE_NULL,                                                                                        // const void*                  pNext
1080                         VK_ACCESS_SHADER_WRITE_BIT,                                                     // VkAccessFlags                srcAccessMask
1081                         VK_ACCESS_TRANSFER_READ_BIT,                                            // VkAccessFlags                dstAccessMask
1082                         VK_IMAGE_LAYOUT_GENERAL,                                                        // VkImageLayout                oldLayout
1083                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                           // VkImageLayout                newLayout
1084                         VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             srcQueueFamilyIndex
1085                         VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             dstQueueFamilyIndex
1086                         *depthResolveImage,                                                                     // VkImage                              image
1087                         {
1088                                 VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask
1089                                 0u,                                                                             // uint32_t                             baseMipLevel
1090                                 1u,                                                                             // uint32_t                             mipLevels,
1091                                 0u,                                                                             // uint32_t                             baseArray
1092                                 1u,                                                                             // uint32_t                             arraySize
1093                         }
1094                 };
1095
1096                 const VkBufferImageCopy bufferImageCopy =
1097                 {
1098                         0u,                                                                                                     // VkDeviceSize                 bufferOffset
1099                         m_samples * m_renderSize.x(),                                           // uint32_t                             bufferRowLength
1100                         m_renderSize.y(),                                                                       // uint32_t                             bufferImageHeight
1101                         {
1102                                 VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspect
1103                                 0u,                                                                             // uint32_t                             mipLevel
1104                                 0u,                                                                             // uint32_t                             baseArrayLayer
1105                                 1u                                                                              // uint32_t                             layerCount
1106                         },
1107                         { 0, 0, 0 },                                                                            // VkOffset3D                   imageOffset
1108                         {
1109                                 m_samples * m_renderSize.x(),                   // uint32_t                             width
1110                                 m_renderSize.y(),                                               // uint32_t                             height
1111                                 1u                                                                              // uint32_t                             depth
1112                         }
1113                 };
1114
1115                 const VkCommandBufferBeginInfo  cmdBufferBeginInfo =
1116                 {
1117                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType
1118                         DE_NULL,                                                                                // const void*                                          pNext
1119                         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags
1120                         (const VkCommandBufferInheritanceInfo*)DE_NULL  // VkCommandBufferInheritanceInfo       pInheritanceInfo
1121                 };
1122
1123                 VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo));
1124                 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1125                                 (VkDependencyFlags)0,
1126                                 0, (const VkMemoryBarrier*)DE_NULL,
1127                                 0, (const VkBufferMemoryBarrier*)DE_NULL,
1128                                 1, &imageBarrier);
1129                 vk.cmdCopyImageToBuffer(*transferCmdBuffer, *depthResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *validationBuffer, 1u, &bufferImageCopy);
1130                 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1131                                 (VkDependencyFlags)0,
1132                                 0, (const VkMemoryBarrier*)DE_NULL,
1133                                 1, &bufferBarrier,
1134                                 0, (const VkImageMemoryBarrier*)DE_NULL);
1135                 VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer));
1136
1137                 const VkSubmitInfo submitInfo =
1138                 {
1139                         VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                      sType
1140                         DE_NULL,                                                                // const void*                          pNext
1141                         0u,                                                                             // uint32_t                                     waitSemaphoreCount
1142                         DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores
1143                         (const VkPipelineStageFlags*)DE_NULL,   // const VkPipelineStageFlags*  pWaitDstStageMask
1144                         1u,                                                                             // uint32_t                                     commandBufferCount
1145                         &transferCmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers
1146                         0u,                                                                             // uint32_t                                     signalSemaphoreCount
1147                         DE_NULL                                                                 // const VkSemaphore*           pSignalSemaphores
1148                 };
1149
1150                 VK_CHECK(vk.resetFences(device, 1, &fence.get()));
1151                 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
1152                 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull)));
1153
1154                 invalidateMappedMemoryRange(vk, device, validationAlloc->getMemory(), validationAlloc->getOffset(), VK_WHOLE_SIZE);
1155                 invalidateMappedMemoryRange(vk, device, markerBufferAllocation->getMemory(), markerBufferAllocation->getOffset(), VK_WHOLE_SIZE);
1156
1157                 tcu::ConstPixelBufferAccess resultPixelBuffer(mapVkFormat(VK_FORMAT_R32_SFLOAT), m_renderSize.x() * m_samples, m_renderSize.y(), 1u, validationAlloc->getHostPtr());
1158                 tcu::ConstPixelBufferAccess markerPixelBuffer(mapVkFormat(VK_FORMAT_R8G8B8A8_UINT), m_renderSize.x() * m_samples, m_renderSize.y(), 1u, markerBufferAllocation->getHostPtr());
1159                 status = validateDepthBuffer(resultPixelBuffer, markerPixelBuffer, 0.001f);
1160                 testDesc = "gl_FragDepth " + getPrimitiveTopologyShortName(m_topology) + " ";
1161                 if (status)
1162                 {
1163                         testDesc += "passed";
1164                         return tcu::TestStatus::pass(testDesc.c_str());
1165                 }
1166                 else
1167                 {
1168                         log << TestLog::Image("resultDepth", "Result Depth Buffer", resultPixelBuffer);
1169                         testDesc += "failed";
1170                         return tcu::TestStatus::fail(testDesc.c_str());
1171                 }
1172         }
1173 }
1174
1175 bool BuiltinFragDepthCaseInstance::validateDepthBuffer (const tcu::ConstPixelBufferAccess& validationBuffer, const tcu::ConstPixelBufferAccess& markerBuffer, const float tolerance) const
1176 {
1177         TestLog& log = m_context.getTestContext().getLog();
1178
1179         for (deUint32 rowNdx = 0; rowNdx < m_renderSize.y(); rowNdx++)
1180         {
1181                 for (deUint32 colNdx = 0; colNdx < m_renderSize.x(); colNdx++)
1182                 {
1183                         const float multiplier          = m_depthClampEnable ? 0.0f : 1.0f;
1184                         float expectedValue     = (float)(rowNdx * m_renderSize.x() + colNdx)/256.0f * multiplier;
1185
1186                         if (m_largeDepthEnable)
1187                                 expectedValue += m_largeDepthBase;
1188
1189                         if (expectedValue > 1.0f)
1190                                 expectedValue = 1.0f;
1191
1192                         if (expectedValue < 0.0f)
1193                                 expectedValue = 0.0f;
1194
1195                         for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_samples; sampleNdx++)
1196                         {
1197                                 const float     actualValue             = validationBuffer.getPixel(sampleNdx + m_samples * colNdx, rowNdx).x();
1198                                 const float     markerValue             = markerBuffer.getPixel(sampleNdx + m_samples * colNdx, rowNdx).x();
1199
1200                                 if (markerValue != 0)
1201                                 {
1202                                         if (de::abs(expectedValue - actualValue) > tolerance)
1203                                         {
1204                                                 log << TestLog::Message << "Mismatch at pixel (" << colNdx << "," << rowNdx << "," << sampleNdx << "): expected " << expectedValue << " but got " << actualValue << TestLog::EndMessage;
1205                                                 return false;
1206                                         }
1207                                 }
1208                                 else
1209                                 {
1210                                         if (de::abs(actualValue - m_defaultDepthValue) > tolerance)
1211                                         {
1212                                                 log << TestLog::Message << "Mismatch at pixel (" << colNdx << "," << rowNdx << "," << sampleNdx << "): expected " << expectedValue << " but got " << actualValue << TestLog::EndMessage;
1213                                                 return false;
1214                                         }
1215                                 }
1216                         }
1217                 }
1218         }
1219
1220         return true;
1221 }
1222
1223 class BuiltinFragCoordMsaaCaseInstance : public TestInstance
1224 {
1225 public:
1226         enum
1227         {
1228                 RENDERWIDTH             = 16,
1229                 RENDERHEIGHT    = 16
1230         };
1231                                 BuiltinFragCoordMsaaCaseInstance        (Context& context, VkSampleCountFlagBits sampleCount);
1232         TestStatus      iterate                                                         (void);
1233 private:
1234         bool            validateSampleLocations                         (const ConstPixelBufferAccess& sampleLocationBuffer) const;
1235
1236         const tcu::UVec2                                m_renderSize;
1237         const VkSampleCountFlagBits             m_sampleCount;
1238 };
1239
1240 BuiltinFragCoordMsaaCaseInstance::BuiltinFragCoordMsaaCaseInstance (Context& context, VkSampleCountFlagBits sampleCount)
1241         : TestInstance          (context)
1242         , m_renderSize          (RENDERWIDTH, RENDERHEIGHT)
1243         , m_sampleCount         (sampleCount)
1244 {
1245         const InstanceInterface&        vki                                     = m_context.getInstanceInterface();
1246         const VkPhysicalDevice          physicalDevice          = m_context.getPhysicalDevice();
1247
1248         try
1249         {
1250                 VkImageFormatProperties         imageFormatProperties;
1251                 VkFormatProperties                      formatProperties;
1252
1253                 if (m_context.getDeviceFeatures().fragmentStoresAndAtomics == VK_FALSE)
1254                         throw tcu::NotSupportedError("fragmentStoresAndAtomics not supported");
1255
1256                 imageFormatProperties = getPhysicalDeviceImageFormatProperties(vki, physicalDevice, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_TYPE_2D,
1257                                 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, (VkImageCreateFlags)0);
1258
1259                 if ((imageFormatProperties.sampleCounts & m_sampleCount) == 0)
1260                         throw tcu::NotSupportedError("Image format and sample count not supported");
1261
1262                 formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, VK_FORMAT_R32G32B32A32_SFLOAT);
1263
1264                 if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
1265                         throw tcu::NotSupportedError("Output format not supported as storage image");
1266         }
1267         catch (const vk::Error& e)
1268         {
1269                 if (e.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
1270                         throw tcu::NotSupportedError("Image format not supported");
1271                 else
1272                         throw;
1273
1274         }
1275 }
1276
1277 TestStatus BuiltinFragCoordMsaaCaseInstance::iterate (void)
1278 {
1279         const VkDevice                                  device                          = m_context.getDevice();
1280         const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
1281         const VkQueue                                   queue                           = m_context.getUniversalQueue();
1282         Allocator&                                              allocator                       = m_context.getDefaultAllocator();
1283         const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
1284         TestLog&                                                log                                     = m_context.getTestContext().getLog();
1285         Move<VkImage>                                   outputImage;
1286         Move<VkImageView>                               outputImageView;
1287         MovePtr<Allocation>                             outputImageAllocation;
1288         Move<VkDescriptorSetLayout>             descriptorSetLayout;
1289         Move<VkDescriptorPool>                  descriptorPool;
1290         Move<VkDescriptorSet>                   descriptorSet;
1291         Move<VkBuffer>                                  sampleLocationBuffer;
1292         MovePtr<Allocation>                             sampleLocationBufferAllocation;
1293         Move<VkCommandPool>                             cmdPool;
1294         Move<VkCommandBuffer>                   transferCmdBuffer;
1295         Move<VkFence>                                   fence;
1296
1297         // Coordinate result image
1298         {
1299                 const VkImageCreateInfo outputImageCreateInfo =
1300                 {
1301                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                    // VkStructureType                      sType
1302                         DE_NULL,                                                                                                // const void*                          pNext
1303                         (VkImageCreateFlags)0,                                                                  // VkImageCreateFlags           flags
1304                         VK_IMAGE_TYPE_2D,                                                                               // VkImageType                          imageType
1305                         VK_FORMAT_R32G32B32A32_SFLOAT,                                                  // VkFormat                                     format
1306                         makeExtent3D(m_sampleCount * m_renderSize.x(), m_renderSize.y(), 1u),   // VkExtent3D                           extent3d
1307                         1u,                                                                                                             // uint32_t                                     mipLevels
1308                         1u,                                                                                                             // uint32_t                                     arrayLayers
1309                         VK_SAMPLE_COUNT_1_BIT,                                                                  // VkSampleCountFlagBits        samples
1310                         VK_IMAGE_TILING_OPTIMAL,                                                                // VkImageTiling                        tiling
1311                         VK_IMAGE_USAGE_STORAGE_BIT |                                                    // VkImageUsageFlags            usage
1312                         VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1313                         VK_SHARING_MODE_EXCLUSIVE,                                                              // VkSharingMode                        sharingMode
1314                         0u,                                                                                                             // uint32_t                                     queueFamilyIndexCount
1315                         DE_NULL,                                                                                                // const uint32_t*                      pQueueFamilyIndices
1316                         VK_IMAGE_LAYOUT_UNDEFINED                                                               // VkImageLayout                        initialLayout
1317                 };
1318
1319                 outputImage = createImage(vk, device, &outputImageCreateInfo, DE_NULL);
1320                 outputImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *outputImage), MemoryRequirement::Any);
1321                 vk.bindImageMemory(device, *outputImage, outputImageAllocation->getMemory(), outputImageAllocation->getOffset());
1322
1323                 VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1324                 const VkImageViewCreateInfo outputImageViewCreateInfo =
1325                 {
1326                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                               // VkStructureType                      sType
1327                         DE_NULL,                                                                                                // const void*                          pNext
1328                         (VkImageViewCreateFlags)0,                                                              // VkImageViewCreateFlags       flags
1329                         *outputImage,                                                                                   // VkImage                                      image
1330                         VK_IMAGE_VIEW_TYPE_2D,                                                                  // VkImageViewType                      viewType
1331                         VK_FORMAT_R32G32B32A32_SFLOAT,                                                  // VkFormat                                     format,
1332                         makeComponentMappingRGBA(),                                                             // VkComponentMapping           components
1333                         imageSubresourceRange                                                                   // VkImageSubresourceRange      imageSubresourceRange
1334                 };
1335
1336                 outputImageView = createImageView(vk, device, &outputImageViewCreateInfo);
1337         }
1338
1339         // Validation buffer
1340         {
1341                 VkDeviceSize  pixelSize = getPixelSize(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT));
1342                 const VkBufferCreateInfo sampleLocationBufferCreateInfo =
1343                 {
1344                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                           // VkStructureType              sType
1345                         DE_NULL,                                                                                        // const void*                  pNext
1346                         (VkBufferCreateFlags)0,                                                         // VkBufferCreateFlags  flags
1347                         m_sampleCount * m_renderSize.x() * m_renderSize.y() * pixelSize,        // VkDeviceSize                 size
1348                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                                       // VkBufferUsageFlags   usage
1349                         VK_SHARING_MODE_EXCLUSIVE,                                                      // VkSharingMode                mode
1350                         0u,                                                                                                     // uint32_t                             queueFamilyIndexCount
1351                         DE_NULL                                                                                         // const uint32_t*              pQueueFamilyIndices
1352                 };
1353
1354                 sampleLocationBuffer = createBuffer(vk, device, &sampleLocationBufferCreateInfo, DE_NULL);
1355                 sampleLocationBufferAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *sampleLocationBuffer), MemoryRequirement::HostVisible);
1356                 vk.bindBufferMemory(device, *sampleLocationBuffer, sampleLocationBufferAllocation->getMemory(), sampleLocationBufferAllocation->getOffset());
1357         }
1358
1359         // Descriptors
1360         {
1361                 DescriptorSetLayoutBuilder              layoutBuilder;
1362                 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
1363                 descriptorSetLayout = layoutBuilder.build(vk, device);
1364                 descriptorPool = DescriptorPoolBuilder()
1365                         .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1366                         .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1367
1368                 const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
1369                 {
1370                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1371                         DE_NULL,
1372                         *descriptorPool,
1373                         1u,
1374                         &*descriptorSetLayout
1375                 };
1376
1377                 descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo);
1378
1379                 const VkDescriptorImageInfo imageInfo =
1380                 {
1381                         (VkSampler)DE_NULL,
1382                         *outputImageView,
1383                         VK_IMAGE_LAYOUT_GENERAL
1384                 };
1385
1386                 DescriptorSetUpdateBuilder()
1387                         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
1388                         .update(vk, device);
1389         }
1390
1391         // Command Pool
1392         {
1393                 const VkCommandPoolCreateInfo cmdPoolCreateInfo =
1394                 {
1395                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                     // VkStructureType                      sType
1396                         DE_NULL,                                                                                        // const void*                          pNext
1397                         VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,        // VkCommandPoolCreateFlags     flags
1398                         queueFamilyIndex                                                                        // uint32_t                                     queueFamilyIndex
1399                 };
1400
1401                 cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
1402         }
1403
1404         // Command buffer for data transfers
1405         {
1406                 const VkCommandBufferAllocateInfo cmdBufferAllocInfo =
1407                 {
1408                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType              sType,
1409                         DE_NULL,                                                                                // const void*                  pNext
1410                         *cmdPool,                                                                               // VkCommandPool                commandPool
1411                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel level
1412                         1u                                                                                              // uint32_t                             bufferCount
1413                 };
1414
1415                 transferCmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocInfo);
1416         }
1417
1418         // Fence for data transfer
1419         {
1420                 const VkFenceCreateInfo fenceCreateInfo =
1421                 {
1422                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType
1423                         DE_NULL,                                                                // const void*                  pNext
1424                         (VkFenceCreateFlags)0                                   // VkFenceCreateFlags   flags
1425                 };
1426
1427                 fence = createFence(vk, device, &fenceCreateInfo);
1428         }
1429
1430         // Transition the output image to LAYOUT_GENERAL
1431         {
1432                 const VkImageMemoryBarrier barrier =
1433                 {
1434                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType              sType
1435                         DE_NULL,                                                                        // const void*                  pNext
1436                         0u,                                                                                     // VkAccessFlags                srcAccessMask
1437                         VK_ACCESS_SHADER_WRITE_BIT,                                     // VkAccessFlags                dstAccessMask
1438                         VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                oldLayout
1439                         VK_IMAGE_LAYOUT_GENERAL,                                        // VkImageLayout                newLayout
1440                         VK_QUEUE_FAMILY_IGNORED,                                        // uint32_t                             srcQueueFamilyIndex
1441                         VK_QUEUE_FAMILY_IGNORED,                                        // uint32_t                             dstQueueFamilyIndex
1442                         *outputImage,                                                           // VkImage                              image
1443                         {
1444                                 VK_IMAGE_ASPECT_COLOR_BIT,                      // VkImageAspectFlags   aspectMask
1445                                 0u,                                                                     // uint32_t                             baseMipLevel
1446                                 1u,                                                                     // uint32_t                             mipLevels
1447                                 0u,                                                                     // uint32_t                             baseArray
1448                                 1u                                                                      // uint32_t                             arraySize
1449                         }
1450                 };
1451
1452                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1453                 {
1454                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,            // VkStructureType                                      sType
1455                         DE_NULL,                                                                                        // const void*                                          pNext
1456                         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,            // VkCommandBufferUsageFlags            flags
1457                         (const VkCommandBufferInheritanceInfo*)DE_NULL          // VkCommandBufferInheritanceInfo       pInheritanceInfo
1458                 };
1459
1460                 VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo));
1461                 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1462                                 (VkDependencyFlags)0,
1463                                 0, (const VkMemoryBarrier*)DE_NULL,
1464                                 0, (const VkBufferMemoryBarrier*)DE_NULL,
1465                                 1, &barrier);
1466
1467                 VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer));
1468
1469                 const VkSubmitInfo submitInfo =
1470                 {
1471                         VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                      sType
1472                         DE_NULL,                                                                // const void*                          pNext
1473                         0u,                                                                             // uint32_t                                     waitSemaphoreCount
1474                         DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores
1475                         (const VkPipelineStageFlags*)DE_NULL,   // const VkPipelineStageFlags*  pWaitDstStageMask
1476                         1u,                                                                             // uint32_t                                     commandBufferCount
1477                         &transferCmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers
1478                         0u,                                                                             // uint32_t                                     signalSemaphoreCount
1479                         DE_NULL                                                                 // const VkSemaphore*           pSignalSemaphores
1480                 };
1481
1482                 vk.resetFences(device, 1, &fence.get());
1483                 vk.queueSubmit(queue, 1, &submitInfo, *fence);
1484                 vk.waitForFences(device, 1, &fence.get(), true, ~(0ull));
1485         }
1486
1487         // Perform draw
1488         {
1489                 std::vector<Vec4>                               vertices;
1490                 std::vector<VulkanShader>               shaders;
1491
1492                 vertices.push_back(Vec4( -1.0f, -1.0f,  0.0f,   1.0f));
1493                 vertices.push_back(Vec4( -1.0f,  1.0f,  0.0f,   1.0f));
1494                 vertices.push_back(Vec4(  1.0f, -1.0f,  0.0f,   1.0f));
1495                 vertices.push_back(Vec4(  1.0f,  1.0f,  0.0f,   1.0f));
1496
1497                 shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragCoordMsaaVert")));
1498                 shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragCoordMsaaFrag")));
1499
1500                 DrawState                       drawState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, m_renderSize.x(), m_renderSize.y());
1501                 DrawCallData            drawCallData(vertices);
1502                 VulkanProgram           vulkanProgram(shaders);
1503
1504                 drawState.numSamples                            = m_sampleCount;
1505                 drawState.sampleShadingEnable           = true;
1506                 vulkanProgram.descriptorSetLayout       = *descriptorSetLayout;
1507                 vulkanProgram.descriptorSet                     = *descriptorSet;
1508
1509                 VulkanDrawContext       vulkanDrawContext(m_context, drawState, drawCallData, vulkanProgram);
1510                 vulkanDrawContext.draw();
1511
1512                 log << TestLog::Image(  "result",
1513                                                                 "result",
1514                                                                 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1515                                                                                 vulkanDrawContext.getColorPixels().getFormat()),
1516                                                                                 vulkanDrawContext.getColorPixels().getWidth(),
1517                                                                                 vulkanDrawContext.getColorPixels().getHeight(),
1518                                                                                 1,
1519                                                                                 vulkanDrawContext.getColorPixels().getDataPtr()));
1520         }
1521
1522         // Transfer location image to buffer
1523         {
1524                 const VkImageMemoryBarrier imageBarrier =
1525                 {
1526                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType              sType
1527                         DE_NULL,                                                                                // const void*                  pNext
1528                         VK_ACCESS_SHADER_WRITE_BIT,                                             // VkAccessFlags                srcAccessMask
1529                         VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessMask                 dstAccessMask
1530                         VK_IMAGE_LAYOUT_GENERAL,                                                // VkImageLayout                oldLayout
1531                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                   // VkImageLayout                newLayout
1532                         VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             srcQueueFamilyIndex
1533                         VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             dstQueueFamilyIndex
1534                         *outputImage,                                                                   // VkImage                              image
1535                         {
1536                                 VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask
1537                                 0u,                                                                             // uint32_t                             baseMipLevel
1538                                 1u,                                                                             // uint32_t                             mipLevels
1539                                 0u,                                                                             // uint32_t                             baseArray
1540                                 1u                                                                              // uint32_t                             arraySize
1541                         }
1542                 };
1543
1544                 const VkBufferMemoryBarrier bufferBarrier =
1545                 {
1546                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType              sType
1547                         DE_NULL,                                                                                // const void*                  pNext
1548                         VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                srcAccessMask
1549                         VK_ACCESS_HOST_READ_BIT,                                                // VkAccessFlags                dstAccessMask
1550                         VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             srcQueueFamilyIndex
1551                         VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             dstQueueFamilyIndex
1552                         *sampleLocationBuffer,                                                  // VkBufer                              buffer
1553                         0u,                                                                                             // VkDeviceSize                 offset
1554                         VK_WHOLE_SIZE                                                                   // VkDeviceSize                 size
1555                 };
1556
1557                 const VkBufferImageCopy bufferImageCopy =
1558                 {
1559                         0u,                                                                     // VkDeviceSize         bufferOffset
1560                         m_sampleCount * m_renderSize.x(),       // uint32_t                     bufferRowLength
1561                         m_renderSize.y(),                                       // uint32_t                     bufferImageHeight
1562                         {
1563                                 VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspect
1564                                 0u,                                                     // uint32_t                             mipLevel
1565                                 0u,                                                     // uint32_t                             baseArrayLayer
1566                                 1u                                                      // uint32_t                             layerCount
1567                         },
1568                         { 0, 0, 0 },                                            // VkOffset3D           imageOffset
1569                         {
1570                                 m_sampleCount * m_renderSize.x(),       // uint32_t                             width
1571                                 m_renderSize.y(),                       // uint32_t                             height,
1572                                 1u                                                      // uint32_t                             depth
1573                         }
1574                 };
1575
1576                 const VkCommandBufferBeginInfo  cmdBufferBeginInfo =
1577                 {
1578                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType
1579                         DE_NULL,                                                                                // const void*                                          pNext
1580                         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags
1581                         (const VkCommandBufferInheritanceInfo*)DE_NULL  // VkCommandBufferInheritanceInfo       pInheritanceInfo
1582                 };
1583
1584                 VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo));
1585                 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1586                                 (VkDependencyFlags)0,
1587                                 0, (const VkMemoryBarrier*)DE_NULL,
1588                                 0, (const VkBufferMemoryBarrier*)DE_NULL,
1589                                 1, &imageBarrier);
1590                 vk.cmdCopyImageToBuffer(*transferCmdBuffer, *outputImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *sampleLocationBuffer, 1u, &bufferImageCopy);
1591                 vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1592                                 (VkDependencyFlags)0,
1593                                 0, (const VkMemoryBarrier*)DE_NULL,
1594                                 1, &bufferBarrier,
1595                                 0, (const VkImageMemoryBarrier*)DE_NULL);
1596                 VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer));
1597
1598                 const VkSubmitInfo submitInfo =
1599                 {
1600                         VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                      sType
1601                         DE_NULL,                                                                // const void*                          pNext
1602                         0u,                                                                             // uint32_t                                     waitSemaphoreCount
1603                         DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores
1604                         (const VkPipelineStageFlags*)DE_NULL,   // const VkPipelineStageFlags*  pWaitDstStageMask
1605                         1u,                                                                             // uint32_t                                     commandBufferCount
1606                         &transferCmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers
1607                         0u,                                                                             // uint32_t                                     signalSemaphoreCount
1608                         DE_NULL                                                                 // const VkSemaphore*           pSignalSemaphores
1609                 };
1610
1611                 vk.resetFences(device, 1, &fence.get());
1612                 vk.queueSubmit(queue, 1, &submitInfo, *fence);
1613                 vk.waitForFences(device, 1, &fence.get(), true, ~(0ull));
1614
1615                 invalidateMappedMemoryRange(vk, device, sampleLocationBufferAllocation->getMemory(), sampleLocationBufferAllocation->getOffset(), VK_WHOLE_SIZE);
1616         }
1617
1618         // Validate result
1619         {
1620                 bool status;
1621
1622                 ConstPixelBufferAccess sampleLocationPixelBuffer(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT), m_sampleCount * m_renderSize.x(),
1623                                 m_renderSize.y(), 1u, sampleLocationBufferAllocation->getHostPtr());
1624
1625                 status = validateSampleLocations(sampleLocationPixelBuffer);
1626                 if (status)
1627                         return TestStatus::pass("FragCoordMsaa passed");
1628                 else
1629                         return TestStatus::fail("FragCoordMsaa failed");
1630         }
1631 }
1632
1633 static bool pixelOffsetCompare (const Vec2& a, const Vec2& b)
1634 {
1635         return a.x() < b.x();
1636 }
1637
1638 bool BuiltinFragCoordMsaaCaseInstance::validateSampleLocations (const ConstPixelBufferAccess& sampleLocationBuffer) const
1639 {
1640         const InstanceInterface&        vki                                     = m_context.getInstanceInterface();
1641         TestLog&                                        log                                     = m_context.getTestContext().getLog();
1642         const VkPhysicalDevice          physicalDevice          = m_context.getPhysicalDevice();
1643         deUint32                                        logSampleCount          = deLog2Floor32(m_sampleCount);
1644         VkPhysicalDeviceProperties      physicalDeviceProperties;
1645
1646         static const Vec2 sampleCount1Bit[] =
1647         {
1648                 Vec2(0.5f, 0.5f)
1649         };
1650
1651         static const Vec2 sampleCount2Bit[] =
1652         {
1653                 Vec2(0.25f, 0.25f), Vec2(0.75f, 0.75f)
1654         };
1655
1656         static const Vec2 sampleCount4Bit[] =
1657         {
1658                 Vec2(0.375f, 0.125f), Vec2(0.875f, 0.375f), Vec2(0.125f, 0.625f), Vec2(0.625f, 0.875f)
1659         };
1660
1661         static const Vec2 sampleCount8Bit[] =
1662         {
1663                 Vec2(0.5625f, 0.3125f), Vec2(0.4375f, 0.6875f), Vec2(0.8125f,0.5625f), Vec2(0.3125f, 0.1875f),
1664                 Vec2(0.1875f, 0.8125f), Vec2(0.0625f, 0.4375f), Vec2(0.6875f,0.9375f), Vec2(0.9375f, 0.0625f)
1665         };
1666
1667         static const Vec2 sampleCount16Bit[] =
1668         {
1669                 Vec2(0.5625f, 0.5625f), Vec2(0.4375f, 0.3125f), Vec2(0.3125f,0.6250f), Vec2(0.7500f, 0.4375f),
1670                 Vec2(0.1875f, 0.3750f), Vec2(0.6250f, 0.8125f), Vec2(0.8125f,0.6875f), Vec2(0.6875f, 0.1875f),
1671                 Vec2(0.3750f, 0.8750f), Vec2(0.5000f, 0.0625f), Vec2(0.2500f,0.1250f), Vec2(0.1250f, 0.7500f),
1672                 Vec2(0.0000f, 0.5000f), Vec2(0.9375f, 0.2500f), Vec2(0.8750f,0.9375f), Vec2(0.0625f, 0.0000f)
1673         };
1674
1675         static const Vec2* standardSampleLocationTable[] =
1676         {
1677                 sampleCount1Bit,
1678                 sampleCount2Bit,
1679                 sampleCount4Bit,
1680                 sampleCount8Bit,
1681                 sampleCount16Bit
1682         };
1683
1684         vki.getPhysicalDeviceProperties(physicalDevice, &physicalDeviceProperties);
1685
1686         for (deInt32 rowNdx = 0; rowNdx < (deInt32)m_renderSize.y(); rowNdx++)
1687         {
1688                 for (deInt32 colNdx = 0; colNdx < (deInt32)m_renderSize.x(); colNdx++)
1689                 {
1690                         std::vector<Vec2> locations;
1691
1692                         for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_sampleCount; sampleNdx++)
1693                         {
1694                                 const UVec2 pixelAddress        = UVec2(sampleNdx + m_sampleCount * colNdx, rowNdx);
1695                                 const Vec4  pixelData           = sampleLocationBuffer.getPixel(pixelAddress.x(), pixelAddress.y());
1696
1697                                 locations.push_back(Vec2(pixelData.x(), pixelData.y()));
1698                         }
1699
1700                         std::sort(locations.begin(), locations.end(), pixelOffsetCompare);
1701                         for (std::vector<Vec2>::const_iterator sampleIt = locations.begin(); sampleIt != locations.end(); sampleIt++)
1702                         {
1703                                 IVec2   sampleFloor(deFloorFloatToInt32((*sampleIt).x()), deFloorFloatToInt32((*sampleIt).y()));
1704                                 IVec2   sampleCeil(deCeilFloatToInt32((*sampleIt).x()), deCeilFloatToInt32((*sampleIt).y()));
1705
1706                                 if ( (sampleFloor.x() < colNdx) || (sampleCeil.x() > colNdx + 1) || (sampleFloor.y() < rowNdx) || (sampleCeil.y() > rowNdx + 1) )
1707                                 {
1708                                         log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): " << *sampleIt << TestLog::EndMessage;
1709                                         return false;
1710                                 }
1711                         }
1712
1713                         std::vector<Vec2>::iterator last = std::unique(locations.begin(), locations.end());
1714                         if (last != locations.end())
1715                         {
1716                                 log << TestLog::Message << "Fail: Sample locations contains non-unique entry" << TestLog::EndMessage;
1717                                 return false;
1718                         }
1719
1720                         // Check standard sample locations
1721                         if (logSampleCount < DE_LENGTH_OF_ARRAY(standardSampleLocationTable))
1722                         {
1723                                 if (physicalDeviceProperties.limits.standardSampleLocations)
1724                                 {
1725                                         for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_sampleCount; sampleNdx++)
1726                                         {
1727                                                 if (!de::contains(locations.begin(), locations.end(), standardSampleLocationTable[logSampleCount][sampleNdx] + Vec2(float(colNdx), float(rowNdx))))
1728                                                 {
1729                                                         log << TestLog::Message << "Didn't match sample locations " << standardSampleLocationTable[logSampleCount][sampleNdx] << TestLog::EndMessage;
1730                                                         return false;
1731                                                 }
1732                                         }
1733                                 }
1734                         }
1735                 }
1736         }
1737
1738         return true;
1739 }
1740
1741 class BuiltinFragCoordMsaaTestCase : public TestCase
1742 {
1743 public:
1744                                         BuiltinFragCoordMsaaTestCase    (TestContext& testCtx, const char* name, const char* description, VkSampleCountFlagBits sampleCount);
1745         virtual                 ~BuiltinFragCoordMsaaTestCase   (void);
1746         void                    initPrograms                                    (SourceCollections& sourceCollections) const;
1747         TestInstance*   createInstance                                  (Context& context) const;
1748 private:
1749         const VkSampleCountFlagBits                     m_sampleCount;
1750 };
1751
1752 BuiltinFragCoordMsaaTestCase::BuiltinFragCoordMsaaTestCase (TestContext& testCtx, const char* name, const char* description, VkSampleCountFlagBits sampleCount)
1753         : TestCase                      (testCtx, name, description)
1754         , m_sampleCount         (sampleCount)
1755 {
1756 }
1757
1758 BuiltinFragCoordMsaaTestCase::~BuiltinFragCoordMsaaTestCase (void)
1759 {
1760 }
1761
1762 void BuiltinFragCoordMsaaTestCase::initPrograms (SourceCollections& programCollection) const
1763 {
1764         {
1765                 std::ostringstream vertexSource;
1766                 vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1767                         << "\n"
1768                         <<  "layout (location = 0) in vec4 position;\n"
1769                         << "void main()\n"
1770                         << "{\n"
1771                         << "    gl_Position = position;\n"
1772                         << "}\n";
1773                 programCollection.glslSources.add("FragCoordMsaaVert") << glu::VertexSource(vertexSource.str());
1774         }
1775
1776         {
1777                 std::ostringstream fragmentSource;
1778                 fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1779                         << "\n"
1780                         << "layout(location = 0) out mediump vec4 color;\n"
1781                         << "layout (set = 0, binding = 0, rgba32f) writeonly uniform image2D storageImage;\n"
1782                         << "void main()\n"
1783                         << "{\n"
1784                         << "    const int sampleNdx = int(gl_SampleID);\n"
1785                         << "    ivec2 imageCoord = ivec2(sampleNdx + int(gl_FragCoord.x) * " << m_sampleCount << ", int(gl_FragCoord.y));\n"
1786                         << "    imageStore(storageImage, imageCoord, vec4(gl_FragCoord.xy,vec2(0)));\n"
1787                         << "    color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1788                         << "}\n";
1789                 programCollection.glslSources.add("FragCoordMsaaFrag") << glu::FragmentSource(fragmentSource.str());
1790         }
1791 }
1792
1793 TestInstance* BuiltinFragCoordMsaaTestCase::createInstance (Context& context) const
1794 {
1795         return new BuiltinFragCoordMsaaCaseInstance(context, m_sampleCount);
1796 }
1797
1798 class BuiltinFragDepthCase : public TestCase
1799 {
1800 public:
1801                                         BuiltinFragDepthCase            (TestContext& testCtx, const char* name, const char* description, VkPrimitiveTopology topology,  VkFormat format, bool largeDepthEnable, bool depthClampEnable, const VkSampleCountFlagBits samples);
1802         virtual                 ~BuiltinFragDepthCase           (void);
1803
1804         void                    initPrograms                            (SourceCollections& dst) const;
1805         TestInstance*   createInstance                          (Context& context) const;
1806
1807 private:
1808         const VkPrimitiveTopology               m_topology;
1809         const VkFormat                                  m_format;
1810         const bool                                              m_largeDepthEnable;
1811         const float                                             m_defaultDepth;
1812         const bool                                              m_depthClampEnable;
1813         const VkSampleCountFlagBits             m_samples;
1814 };
1815
1816 BuiltinFragDepthCase::BuiltinFragDepthCase (TestContext& testCtx, const char* name, const char* description, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, bool depthClampEnable, const VkSampleCountFlagBits  samples)
1817         : TestCase                              (testCtx, name, description)
1818         , m_topology                    (topology)
1819         , m_format                              (format)
1820         , m_largeDepthEnable    (largeDepthEnable)
1821         , m_defaultDepth                (0.0f)
1822         , m_depthClampEnable    (depthClampEnable)
1823         , m_samples                             (samples)
1824 {
1825 }
1826
1827 BuiltinFragDepthCase::~BuiltinFragDepthCase(void)
1828 {
1829 }
1830
1831 void BuiltinFragDepthCase::initPrograms (SourceCollections& programCollection) const
1832 {
1833         // Vertex
1834         {
1835                 // Pass 1
1836                 {
1837                         std::ostringstream vertexSource;
1838                         vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1839                                 << "\n"
1840                                 <<  "layout (location = 0) in vec4 position;\n"
1841                                 << "void main()\n"
1842                                 << "{\n"
1843                                 << "    gl_Position = position;\n"
1844                                 << "}\n";
1845                         programCollection.glslSources.add("FragDepthVert") << glu::VertexSource(vertexSource.str());
1846                 }
1847
1848                 // Pass 2
1849                 {
1850                         std::ostringstream vertexSource;
1851                         vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1852                                 << "\n"
1853                                 <<  "layout (location = 0) in vec4 position;\n"
1854                                 <<  "layout (location = 1) out vec2 texCoord;\n"
1855                                 << "void main()\n"
1856                                 << "{\n"
1857                                 << "    gl_Position = position;\n"
1858                                 << "    texCoord = position.xy/2 + vec2(0.5);\n"
1859                                 << "}\n";
1860                         programCollection.glslSources.add("FragDepthVertPass2") << glu::VertexSource(vertexSource.str());
1861                 }
1862         }
1863
1864         // Fragment
1865         {
1866                 // Pass 1
1867                 {
1868                         std::ostringstream      fragmentSource;
1869                         fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1870                                 << "\n"
1871                                 << "layout(location = 0) out mediump vec4 color;\n"
1872                                 << "layout (std140, set = 0, binding = 0) uniform control_buffer_t\n"
1873                                 << "{\n"
1874                                 << "    float data[256];\n"
1875                                 << "} control_buffer;\n"
1876                                 << "layout (set = 0, binding = 1, rgba8ui) writeonly uniform uimage2D storageImage;\n"
1877                                 << "float controlDepthValue;\n"
1878                                 << "void recheck(float controlDepthValue)\n"
1879                                 << "{\n"
1880                                 << "    if (gl_FragDepth != controlDepthValue)\n"
1881                                 << "            gl_FragDepth = 1.0;\n"
1882                                 << "}\n"
1883                                 << "void main()\n"
1884                                 << "{\n"
1885                                 << "    const int numSamples = " << m_samples << ";\n"
1886                                 << "    if (int(gl_FragCoord.x) == " << BuiltinFragDepthCaseInstance::RENDERWIDTH/4 << ")\n"
1887                                 << "            discard;\n"
1888                                 << "    highp int index =int(gl_FragCoord.y) * " << BuiltinFragDepthCaseInstance::RENDERHEIGHT << " + int(gl_FragCoord.x);\n"
1889                                 << "    controlDepthValue = control_buffer.data[index];\n"
1890                                 << "    gl_FragDepth = controlDepthValue;\n"
1891                                 << "    const int sampleNdx = int(gl_SampleID);\n"
1892                                 << "    ivec2 imageCoord = ivec2(sampleNdx + int(gl_FragCoord.x) * " << m_samples << ", int(gl_FragCoord.y));\n"
1893                                 << "    imageStore(storageImage, imageCoord, uvec4(1));\n"
1894                                 << "    recheck(controlDepthValue);\n"
1895                                 << "    color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1896                                 << "}\n";
1897                         programCollection.glslSources.add("FragDepthFrag") << glu::FragmentSource(fragmentSource.str());
1898                 }
1899
1900                 // Pass 2
1901                 {
1902                         const char* multisampleDecoration = m_samples != VK_SAMPLE_COUNT_1_BIT ? "MS" : "";
1903                         std::ostringstream fragmentSource;
1904                         fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1905                                 << "\n"
1906                                 << "layout (location = 0) out mediump vec4 color;\n"
1907                                 << "layout (location = 1) in vec2 texCoord;\n"
1908                                 << "layout (binding = 0, set = 0) uniform sampler2D" << multisampleDecoration << " u_depthTex;\n"
1909                                 << "layout (binding = 1, set = 0, r32f) writeonly uniform image2D u_outImage;\n"
1910                                 << "void main (void)\n"
1911                                 << "{\n"
1912                                 << "    const int numSamples = " << m_samples << ";\n"
1913                                 << "    const int sampleNdx = int(gl_SampleID);\n"
1914                                 << "    ivec2 renderSize = ivec2(" << BuiltinFragDepthCaseInstance::RENDERWIDTH << "," << BuiltinFragDepthCaseInstance::RENDERHEIGHT << ");\n"
1915                                 << "    ivec2 imageCoord = ivec2(int(texCoord.x * renderSize.x), int(texCoord.y * renderSize.y));\n"
1916                                 << "    vec4 depthVal = texelFetch(u_depthTex, imageCoord, sampleNdx);\n"
1917                                 << "    imageStore(u_outImage, ivec2(sampleNdx + int(texCoord.x * renderSize.x) * numSamples, int(texCoord.y * renderSize.y)), depthVal);\n"
1918                                 << "    color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1919                                 << "}\n";
1920                         programCollection.glslSources.add("FragDepthFragPass2") << glu::FragmentSource(fragmentSource.str());
1921                 }
1922         }
1923 }
1924
1925 TestInstance* BuiltinFragDepthCase::createInstance (Context& context) const
1926 {
1927         return new BuiltinFragDepthCaseInstance(context, m_topology, m_format, m_largeDepthEnable, m_defaultDepth, m_depthClampEnable, m_samples);
1928 }
1929
1930 class BuiltinGlFragCoordXYZCaseInstance : public ShaderRenderCaseInstance
1931 {
1932 public:
1933                                         BuiltinGlFragCoordXYZCaseInstance       (Context& context);
1934
1935         TestStatus              iterate                                                         (void);
1936         virtual void    setupDefaultInputs                                      (void);
1937 };
1938
1939 BuiltinGlFragCoordXYZCaseInstance::BuiltinGlFragCoordXYZCaseInstance (Context& context)
1940         : ShaderRenderCaseInstance      (context)
1941 {
1942         m_colorFormat = VK_FORMAT_R16G16B16A16_UNORM;
1943 }
1944
1945 TestStatus BuiltinGlFragCoordXYZCaseInstance::iterate (void)
1946 {
1947         const UVec2             viewportSize    = getViewportSize();
1948         const int               width                   = viewportSize.x();
1949         const int               height                  = viewportSize.y();
1950         const tcu::Vec3 scale                   (1.f / float(width), 1.f / float(height), 1.0f);
1951         const float             precision               = 0.00001f;
1952         const deUint16  indices[6]              =
1953         {
1954                 2, 1, 3,
1955                 0, 1, 2,
1956         };
1957
1958         setup();
1959         addUniform(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, scale);
1960
1961         render(4, 2, indices);
1962
1963         // Reference image
1964         for (int y = 0; y < height; y++)
1965         {
1966                 for (int x = 0; x < width; x++)
1967                 {
1968                         const float     xf                      = (float(x) + .5f) / float(width);
1969                         const float     yf                      = (float(height - y - 1) + .5f) / float(height);
1970                         const float     z                       = (xf + yf) / 2.0f;
1971                         const Vec3      fragCoord       (float(x) + .5f, float(y) + .5f, z);
1972                         const Vec3      scaledFC        = fragCoord*scale;
1973                         const Vec4      color           (scaledFC.x(), scaledFC.y(), scaledFC.z(), 1.0f);
1974                         const Vec4      resultColor     = getResultImage().getAccess().getPixel(x, y);
1975
1976                         if (de::abs(color.x() - resultColor.x()) > precision ||
1977                                 de::abs(color.y() - resultColor.y()) > precision ||
1978                                 de::abs(color.z() - resultColor.z()) > precision)
1979                         return TestStatus::fail("Image mismatch");
1980                 }
1981         }
1982
1983         return TestStatus::pass("Result image matches reference");
1984 }
1985
1986 void BuiltinGlFragCoordXYZCaseInstance::setupDefaultInputs (void)
1987 {
1988         const float             vertices[]              =
1989         {
1990                 -1.0f,  1.0f,  0.0f, 1.0f,
1991                 -1.0f, -1.0f,  0.5f, 1.0f,
1992                  1.0f,  1.0f,  0.5f, 1.0f,
1993                  1.0f, -1.0f,  1.0f, 1.0f,
1994         };
1995
1996         addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
1997 }
1998
1999 class BuiltinGlFragCoordXYZCase : public TestCase
2000 {
2001 public:
2002                                                                 BuiltinGlFragCoordXYZCase       (TestContext& testCtx, const string& name, const string& description);
2003         virtual                                         ~BuiltinGlFragCoordXYZCase      (void);
2004
2005         void                                            initPrograms                            (SourceCollections& dst) const;
2006         TestInstance*                           createInstance                          (Context& context) const;
2007
2008 private:
2009                                                                 BuiltinGlFragCoordXYZCase       (const BuiltinGlFragCoordXYZCase&);     // not allowed!
2010         BuiltinGlFragCoordXYZCase&      operator=                                       (const BuiltinGlFragCoordXYZCase&);     // not allowed!
2011 };
2012
2013 BuiltinGlFragCoordXYZCase::BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description)
2014         : TestCase(testCtx, name, description)
2015 {
2016 }
2017
2018 BuiltinGlFragCoordXYZCase::~BuiltinGlFragCoordXYZCase (void)
2019 {
2020 }
2021
2022 void BuiltinGlFragCoordXYZCase::initPrograms (SourceCollections& dst) const
2023 {
2024         dst.glslSources.add("vert") << glu::VertexSource(
2025                 "#version 310 es\n"
2026                 "layout(location = 0) in highp vec4 a_position;\n"
2027                 "void main (void)\n"
2028                 "{\n"
2029                 "       gl_Position = a_position;\n"
2030                 "}\n");
2031
2032         dst.glslSources.add("frag") << glu::FragmentSource(
2033                 "#version 310 es\n"
2034                 "layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n"
2035                 "layout(location = 0) out highp vec4 o_color;\n"
2036                 "void main (void)\n"
2037                 "{\n"
2038                 "       o_color = vec4(gl_FragCoord.xyz * u_scale, 1.0);\n"
2039                 "}\n");
2040 }
2041
2042 TestInstance* BuiltinGlFragCoordXYZCase::createInstance (Context& context) const
2043 {
2044         return new BuiltinGlFragCoordXYZCaseInstance(context);
2045 }
2046
2047 inline float projectedTriInterpolate (const Vec3& s, const Vec3& w, float nx, float ny)
2048 {
2049         return (s[0]*(1.0f-nx-ny)/w[0] + s[1]*ny/w[1] + s[2]*nx/w[2]) / ((1.0f-nx-ny)/w[0] + ny/w[1] + nx/w[2]);
2050 }
2051
2052 class BuiltinGlFragCoordWCaseInstance : public ShaderRenderCaseInstance
2053 {
2054 public:
2055                                         BuiltinGlFragCoordWCaseInstance (Context& context);
2056
2057         TestStatus              iterate                                                 (void);
2058         virtual void    setupDefaultInputs                              (void);
2059
2060 private:
2061
2062         const Vec4              m_w;
2063
2064 };
2065
2066 BuiltinGlFragCoordWCaseInstance::BuiltinGlFragCoordWCaseInstance (Context& context)
2067         : ShaderRenderCaseInstance      (context)
2068         , m_w                                           (1.7f, 2.0f, 1.2f, 1.0f)
2069 {
2070         m_colorFormat = VK_FORMAT_R16G16B16A16_UNORM;
2071 }
2072
2073 TestStatus BuiltinGlFragCoordWCaseInstance::iterate (void)
2074 {
2075         const UVec2             viewportSize    = getViewportSize();
2076         const int               width                   = viewportSize.x();
2077         const int               height                  = viewportSize.y();
2078         const float             precision               = 0.00001f;
2079         const deUint16  indices[6]              =
2080         {
2081                 2, 1, 3,
2082                 0, 1, 2,
2083         };
2084
2085         setup();
2086         render(4, 2, indices);
2087
2088         // Reference image
2089         for (int y = 0; y < height; y++)
2090         {
2091                 for (int x = 0; x < width; x++)
2092                 {
2093                         const float     xf                      = (float(x) + .5f) / float(width);
2094                         const float     yf                      = (float(height - y - 1) +.5f) / float(height);
2095                         const float     oow                     = ((xf + yf) < 1.0f)
2096                                                                                 ? projectedTriInterpolate(Vec3(m_w[0], m_w[1], m_w[2]), Vec3(m_w[0], m_w[1], m_w[2]), xf, yf)
2097                                                                                 : projectedTriInterpolate(Vec3(m_w[3], m_w[2], m_w[1]), Vec3(m_w[3], m_w[2], m_w[1]), 1.0f - xf, 1.0f - yf);
2098                         const Vec4      color           (0.0f, oow - 1.0f, 0.0f, 1.0f);
2099                         const Vec4      resultColor     = getResultImage().getAccess().getPixel(x, y);
2100
2101                         if (de::abs(color.x() - resultColor.x()) > precision ||
2102                                 de::abs(color.y() - resultColor.y()) > precision ||
2103                                 de::abs(color.z() - resultColor.z()) > precision)
2104                         return TestStatus::fail("Image mismatch");
2105                 }
2106         }
2107
2108         return TestStatus::pass("Result image matches reference");
2109 }
2110
2111 void BuiltinGlFragCoordWCaseInstance::setupDefaultInputs (void)
2112 {
2113         const float vertices[] =
2114         {
2115                 -m_w[0],  m_w[0], 0.0f, m_w[0],
2116                 -m_w[1], -m_w[1], 0.0f, m_w[1],
2117                  m_w[2],  m_w[2], 0.0f, m_w[2],
2118                  m_w[3], -m_w[3], 0.0f, m_w[3]
2119         };
2120
2121         addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
2122 }
2123
2124 class BuiltinGlFragCoordWCase : public TestCase
2125 {
2126 public:
2127                                                                 BuiltinGlFragCoordWCase         (TestContext& testCtx, const string& name, const string& description);
2128         virtual                                         ~BuiltinGlFragCoordWCase        (void);
2129
2130         void                                            initPrograms                            (SourceCollections& dst) const;
2131         TestInstance*                           createInstance                          (Context& context) const;
2132
2133 private:
2134                                                                 BuiltinGlFragCoordWCase         (const BuiltinGlFragCoordWCase&);       // not allowed!
2135         BuiltinGlFragCoordWCase&        operator=                                       (const BuiltinGlFragCoordWCase&);       // not allowed!
2136 };
2137
2138 BuiltinGlFragCoordWCase::BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description)
2139         : TestCase(testCtx, name, description)
2140 {
2141 }
2142
2143 BuiltinGlFragCoordWCase::~BuiltinGlFragCoordWCase (void)
2144 {
2145 }
2146
2147 void BuiltinGlFragCoordWCase::initPrograms (SourceCollections& dst) const
2148 {
2149         dst.glslSources.add("vert") << glu::VertexSource(
2150                 "#version 310 es\n"
2151                 "layout(location = 0) in highp vec4 a_position;\n"
2152                 "void main (void)\n"
2153                 "{\n"
2154                 "       gl_Position = a_position;\n"
2155                 "}\n");
2156
2157         dst.glslSources.add("frag") << glu::FragmentSource(
2158                 "#version 310 es\n"
2159                 "layout(location = 0) out highp vec4 o_color;\n"
2160                 "void main (void)\n"
2161                 "{\n"
2162                 "       o_color = vec4(0.0, 1.0 / gl_FragCoord.w - 1.0, 0.0, 1.0);\n"
2163                 "}\n");
2164 }
2165
2166 TestInstance* BuiltinGlFragCoordWCase::createInstance (Context& context) const
2167 {
2168         return new BuiltinGlFragCoordWCaseInstance(context);
2169 }
2170
2171 class BuiltinGlPointCoordCaseInstance : public ShaderRenderCaseInstance
2172 {
2173 public:
2174                                         BuiltinGlPointCoordCaseInstance (Context& context);
2175
2176         TestStatus              iterate                                                         (void);
2177         virtual void    setupDefaultInputs                                      (void);
2178 };
2179
2180 BuiltinGlPointCoordCaseInstance::BuiltinGlPointCoordCaseInstance (Context& context)
2181         : ShaderRenderCaseInstance      (context)
2182 {
2183 }
2184
2185 TestStatus BuiltinGlPointCoordCaseInstance::iterate (void)
2186 {
2187         const UVec2                             viewportSize    = getViewportSize();
2188         const int                               width                   = viewportSize.x();
2189         const int                               height                  = viewportSize.y();
2190         const float                             threshold               = 0.02f;
2191         const int                               numPoints               = 16;
2192         vector<Vec3>                    coords                  (numPoints);
2193         de::Random                              rnd                             (0x145fa);
2194         Surface                                 resImage                (width, height);
2195         Surface                                 refImage                (width, height);
2196         bool                                    compareOk               = false;
2197
2198         // Compute coordinates.
2199         {
2200                 const VkPhysicalDeviceLimits&   limits                                  = m_context.getDeviceProperties().limits;
2201                 const float                                             minPointSize                    = limits.pointSizeRange[0];
2202                 const float                                             maxPointSize                    = limits.pointSizeRange[1];
2203                 const int                                               pointSizeDeltaMultiples = de::max(1, deCeilFloatToInt32((maxPointSize - minPointSize) / limits.pointSizeGranularity));
2204
2205                 TCU_CHECK(minPointSize <= maxPointSize);
2206
2207                 for (vector<Vec3>::iterator coord = coords.begin(); coord != coords.end(); ++coord)
2208                 {
2209                         coord->x() = rnd.getFloat(-0.9f, 0.9f);
2210                         coord->y() = rnd.getFloat(-0.9f, 0.9f);
2211                         coord->z() = de::min(maxPointSize, minPointSize + float(rnd.getInt(0, pointSizeDeltaMultiples)) * limits.pointSizeGranularity);
2212                 }
2213         }
2214
2215         setup();
2216         addAttribute(0u, VK_FORMAT_R32G32B32_SFLOAT, deUint32(sizeof(Vec3)), numPoints, &coords[0]);
2217         render(numPoints, 0, DE_NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
2218         copy(resImage.getAccess(), getResultImage().getAccess());
2219
2220         // Draw reference
2221         clear(refImage.getAccess(), m_clearColor);
2222
2223         for (vector<Vec3>::const_iterator pointIter = coords.begin(); pointIter != coords.end(); ++pointIter)
2224         {
2225                 const float     centerX = float(width) *(pointIter->x()*0.5f + 0.5f);
2226                 const float     centerY = float(height)*(pointIter->y()*0.5f + 0.5f);
2227                 const float     size    = pointIter->z();
2228                 const int       x0              = deRoundFloatToInt32(centerX - size*0.5f);
2229                 const int       y0              = deRoundFloatToInt32(centerY - size*0.5f);
2230                 const int       x1              = deRoundFloatToInt32(centerX + size*0.5f);
2231                 const int       y1              = deRoundFloatToInt32(centerY + size*0.5f);
2232                 const int       w               = x1-x0;
2233                 const int       h               = y1-y0;
2234
2235                 for (int yo = 0; yo < h; yo++)
2236                 {
2237                         for (int xo = 0; xo < w; xo++)
2238                         {
2239                                 const int               dx              = x0+xo;
2240                                 const int               dy              = y0+yo;
2241                                 const float             fragX   = float(dx) + 0.5f;
2242                                 const float             fragY   = float(dy) + 0.5f;
2243                                 const float             s               = 0.5f + (fragX - centerX) / size;
2244                                 const float             t               = 0.5f + (fragY - centerY) / size;
2245                                 const Vec4              color   (s, t, 0.0f, 1.0f);
2246
2247                                 if (de::inBounds(dx, 0, refImage.getWidth()) && de::inBounds(dy, 0, refImage.getHeight()))
2248                                         refImage.setPixel(dx, dy, RGBA(color));
2249                         }
2250                 }
2251         }
2252
2253         compareOk = fuzzyCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
2254
2255         if (compareOk)
2256                 return TestStatus::pass("Result image matches reference");
2257         else
2258                 return TestStatus::fail("Image mismatch");
2259 }
2260
2261 void BuiltinGlPointCoordCaseInstance::setupDefaultInputs (void)
2262 {
2263 }
2264
2265 class BuiltinGlPointCoordCase : public TestCase
2266 {
2267 public:
2268                                                                 BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description);
2269         virtual                                         ~BuiltinGlPointCoordCase        (void);
2270
2271         void                                            initPrograms                            (SourceCollections& dst) const;
2272         TestInstance*                           createInstance                          (Context& context) const;
2273
2274 private:
2275                                                                 BuiltinGlPointCoordCase (const BuiltinGlPointCoordCase&);       // not allowed!
2276         BuiltinGlPointCoordCase&        operator=                                       (const BuiltinGlPointCoordCase&);       // not allowed!
2277 };
2278
2279 BuiltinGlPointCoordCase::BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description)
2280         : TestCase(testCtx, name, description)
2281 {
2282 }
2283
2284 BuiltinGlPointCoordCase::~BuiltinGlPointCoordCase (void)
2285 {
2286 }
2287
2288 void BuiltinGlPointCoordCase::initPrograms (SourceCollections& dst) const
2289 {
2290         dst.glslSources.add("vert") << glu::VertexSource(
2291                 "#version 310 es\n"
2292                 "layout(location = 0) in highp vec3 a_position;\n"
2293                 "void main (void)\n"
2294                 "{\n"
2295                 "    gl_Position = vec4(a_position.xy, 0.0, 1.0);\n"
2296                 "    gl_PointSize = a_position.z;\n"
2297                 "}\n");
2298
2299         dst.glslSources.add("frag") << glu::FragmentSource(
2300                 "#version 310 es\n"
2301                 "layout(location = 0) out lowp vec4 o_color;\n"
2302                 "void main (void)\n"
2303                 "{\n"
2304                 "    o_color = vec4(gl_PointCoord, 0.0, 1.0);\n"
2305                 "}\n");
2306 }
2307
2308 TestInstance* BuiltinGlPointCoordCase::createInstance (Context& context) const
2309 {
2310         return new BuiltinGlPointCoordCaseInstance(context);
2311 }
2312
2313 enum ShaderInputTypeBits
2314 {
2315         SHADER_INPUT_BUILTIN_BIT        = 0x01,
2316         SHADER_INPUT_VARYING_BIT        = 0x02,
2317         SHADER_INPUT_CONSTANT_BIT       = 0x04
2318 };
2319
2320 typedef deUint16 ShaderInputTypes;
2321
2322 string shaderInputTypeToString (ShaderInputTypes type)
2323 {
2324         string typeString = "input";
2325
2326         if (type == 0)
2327                 return "input_none";
2328
2329         if (type & SHADER_INPUT_BUILTIN_BIT)
2330                 typeString += "_builtin";
2331
2332         if (type & SHADER_INPUT_VARYING_BIT)
2333                 typeString += "_varying";
2334
2335         if (type & SHADER_INPUT_CONSTANT_BIT)
2336                 typeString += "_constant";
2337
2338         return typeString;
2339 }
2340
2341 class BuiltinInputVariationsCaseInstance : public ShaderRenderCaseInstance
2342 {
2343 public:
2344                                                         BuiltinInputVariationsCaseInstance      (Context& context, const ShaderInputTypes shaderInputTypes);
2345
2346         TestStatus                              iterate                                                         (void);
2347         virtual void                    setupDefaultInputs                                      (void);
2348         virtual void                    updatePushConstants                                     (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout);
2349
2350 private:
2351         const ShaderInputTypes  m_shaderInputTypes;
2352         const Vec4                              m_constantColor;
2353 };
2354
2355 BuiltinInputVariationsCaseInstance::BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes)
2356         : ShaderRenderCaseInstance      (context)
2357         , m_shaderInputTypes            (shaderInputTypes)
2358         , m_constantColor                       (0.1f, 0.05f, 0.2f, 0.0f)
2359 {
2360 }
2361
2362 TestStatus BuiltinInputVariationsCaseInstance::iterate (void)
2363 {
2364         const UVec2                                     viewportSize    = getViewportSize();
2365         const int                                       width                   = viewportSize.x();
2366         const int                                       height                  = viewportSize.y();
2367         const tcu::RGBA                         threshold               (2, 2, 2, 2);
2368         Surface                                         resImage                (width, height);
2369         Surface                                         refImage                (width, height);
2370         bool                                            compareOk               = false;
2371         const VkPushConstantRange       pcRanges                =
2372         {
2373                 VK_SHADER_STAGE_FRAGMENT_BIT,   // VkShaderStageFlags   stageFlags;
2374                 0u,                                                             // deUint32                             offset;
2375                 sizeof(Vec4)                                    // deUint32                             size;
2376         };
2377         const deUint16                          indices[12]             =
2378         {
2379                 0, 4, 1,
2380                 0, 5, 4,
2381                 1, 2, 3,
2382                 1, 3, 4
2383         };
2384
2385         setup();
2386
2387         if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
2388                 setPushConstantRanges(1, &pcRanges);
2389
2390         render(6, 4, indices);
2391         copy(resImage.getAccess(), getResultImage().getAccess());
2392
2393         // Reference image
2394         for (int y = 0; y < refImage.getHeight(); y++)
2395         {
2396                 for (int x = 0; x < refImage.getWidth(); x++)
2397                 {
2398                         Vec4 color (0.1f, 0.2f, 0.3f, 1.0f);
2399
2400                         if (((m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT) && (x < refImage.getWidth() / 2)) ||
2401                                 !(m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT))
2402                         {
2403                                 if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
2404                                 {
2405                                         const float xf = (float(x)+.5f) / float(refImage.getWidth());
2406                                         color += Vec4(0.6f * (1 - xf), 0.6f * xf, 0.0f, 0.0f);
2407                                 }
2408                                 else
2409                                         color += Vec4(0.3f, 0.2f, 0.1f, 0.0f);
2410                         }
2411
2412                         if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
2413                                 color += m_constantColor;
2414
2415                         refImage.setPixel(x, y, RGBA(color));
2416                 }
2417         }
2418
2419         compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
2420
2421         if (compareOk)
2422                 return TestStatus::pass("Result image matches reference");
2423         else
2424                 return TestStatus::fail("Image mismatch");
2425 }
2426
2427 void BuiltinInputVariationsCaseInstance::setupDefaultInputs (void)
2428 {
2429         const float vertices[] =
2430         {
2431                 -1.0f, -1.0f, 0.0f, 1.0f,
2432                  0.0f, -1.0f, 0.0f, 1.0f,
2433                  1.0f, -1.0f, 0.0f, 1.0f,
2434                  1.0f,  1.0f, 0.0f, 1.0f,
2435                  0.0f,  1.0f, 0.0f, 1.0f,
2436                 -1.0f,  1.0f, 0.0f, 1.0f
2437         };
2438
2439         addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, vertices);
2440
2441         if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
2442         {
2443                 const float colors[] =
2444                 {
2445                          0.6f,  0.0f, 0.0f, 1.0f,
2446                          0.3f,  0.3f, 0.0f, 1.0f,
2447                          0.0f,  0.6f, 0.0f, 1.0f,
2448                          0.0f,  0.6f, 0.0f, 1.0f,
2449                          0.3f,  0.3f, 0.0f, 1.0f,
2450                          0.6f,  0.0f, 0.0f, 1.0f
2451                 };
2452                 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, colors);
2453         }
2454 }
2455
2456 void BuiltinInputVariationsCaseInstance::updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout)
2457 {
2458         if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
2459         {
2460                 const DeviceInterface& vk = m_context.getDeviceInterface();
2461                 vk.cmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4), &m_constantColor);
2462         }
2463 }
2464
2465 class BuiltinInputVariationsCase : public TestCase
2466 {
2467 public:
2468                                                                 BuiltinInputVariationsCase      (TestContext& testCtx, const string& name, const string& description, const ShaderInputTypes shaderInputTypes);
2469         virtual                                         ~BuiltinInputVariationsCase     (void);
2470
2471         void                                            initPrograms                            (SourceCollections& dst) const;
2472         TestInstance*                           createInstance                          (Context& context) const;
2473
2474 private:
2475                                                                 BuiltinInputVariationsCase      (const BuiltinInputVariationsCase&);    // not allowed!
2476         BuiltinInputVariationsCase&     operator=                                       (const BuiltinInputVariationsCase&);    // not allowed!
2477         const ShaderInputTypes          m_shaderInputTypes;
2478 };
2479
2480 BuiltinInputVariationsCase::BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, ShaderInputTypes shaderInputTypes)
2481         : TestCase                              (testCtx, name, description)
2482         , m_shaderInputTypes    (shaderInputTypes)
2483 {
2484 }
2485
2486 BuiltinInputVariationsCase::~BuiltinInputVariationsCase (void)
2487 {
2488 }
2489
2490 void BuiltinInputVariationsCase::initPrograms (SourceCollections& dst) const
2491 {
2492         map<string, string>                     vertexParams;
2493         map<string, string>                     fragmentParams;
2494         const tcu::StringTemplate       vertexCodeTemplate              (
2495                 "#version 450\n"
2496                 "layout(location = 0) in highp vec4 a_position;\n"
2497                 "out gl_PerVertex {\n"
2498                 "       vec4 gl_Position;\n"
2499                 "};\n"
2500                 "${VARYING_DECL}"
2501                 "void main (void)\n"
2502                 "{\n"
2503                 "    gl_Position = a_position;\n"
2504                 "    ${VARYING_USAGE}"
2505                 "}\n");
2506
2507         const tcu::StringTemplate       fragmentCodeTemplate    (
2508                 "#version 450\n"
2509                 "${VARYING_DECL}"
2510                 "${CONSTANT_DECL}"
2511                 "layout(location = 0) out highp vec4 o_color;\n"
2512                 "void main (void)\n"
2513                 "{\n"
2514                 "    o_color = vec4(0.1, 0.2, 0.3, 1.0);\n"
2515                 "    ${BUILTIN_USAGE}"
2516                 "    ${VARYING_USAGE}"
2517                 "    ${CONSTANT_USAGE}"
2518                 "}\n");
2519
2520         vertexParams["VARYING_DECL"]            =
2521                 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT   ? "layout(location = 1) in highp vec4 a_color;\n"
2522                                                                                                                   "layout(location = 0) out highp vec4 v_color;\n"
2523                                                                                                                 : "";
2524
2525         vertexParams["VARYING_USAGE"]           =
2526                 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT   ? "v_color = a_color;\n"
2527                                                                                                                 : "";
2528
2529         fragmentParams["VARYING_DECL"]          =
2530                 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT   ? "layout(location = 0) in highp vec4 a_color;\n"
2531                                                                                                                 : "";
2532
2533         fragmentParams["CONSTANT_DECL"]         =
2534                 m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT  ? "layout(push_constant) uniform PCBlock {\n"
2535                                                                                                                   "  vec4 color;\n"
2536                                                                                                                   "} pc;\n"
2537                                                                                                                 : "";
2538
2539         fragmentParams["BUILTIN_USAGE"]         =
2540                 m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT   ? "if (gl_FrontFacing)\n"
2541                                                                                                                 : "";
2542
2543         fragmentParams["VARYING_USAGE"]         =
2544                 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT   ? "o_color += vec4(a_color.xyz, 0.0);\n"
2545                                                                                                                 : "o_color += vec4(0.3, 0.2, 0.1, 0.0);\n";
2546
2547
2548         fragmentParams["CONSTANT_USAGE"]        =
2549                 m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT  ? "o_color += pc.color;\n"
2550                                                                                                                 : "";
2551
2552         dst.glslSources.add("vert") << glu::VertexSource(vertexCodeTemplate.specialize(vertexParams));
2553         dst.glslSources.add("frag") << glu::FragmentSource(fragmentCodeTemplate.specialize(fragmentParams));
2554 }
2555
2556 TestInstance* BuiltinInputVariationsCase::createInstance (Context& context) const
2557 {
2558         return new BuiltinInputVariationsCaseInstance(context, m_shaderInputTypes);
2559 }
2560
2561 } // anonymous
2562
2563 TestCaseGroup* createBuiltinVarTests (TestContext& testCtx)
2564 {
2565         de::MovePtr<TestCaseGroup> builtinGroup                 (new TestCaseGroup(testCtx, "builtin_var", "Shader builtin variable tests."));
2566         de::MovePtr<TestCaseGroup> simpleGroup                  (new TestCaseGroup(testCtx, "simple", "Simple cases."));
2567         de::MovePtr<TestCaseGroup> inputVariationsGroup (new TestCaseGroup(testCtx, "input_variations", "Input type variation tests."));
2568         de::MovePtr<TestCaseGroup> frontFacingGroup             (new TestCaseGroup(testCtx, "frontfacing", "Test gl_Frontfacing keyword."));
2569         de::MovePtr<TestCaseGroup> fragDepthGroup               (new TestCaseGroup(testCtx, "fragdepth", "Test gl_FragDepth keyword."));
2570         de::MovePtr<TestCaseGroup> fragCoordMsaaGroup   (new TestCaseGroup(testCtx, "fragcoord_msaa", "Test interation between gl_FragCoord and msaa"));
2571
2572         simpleGroup->addChild(new BuiltinGlFragCoordXYZCase(testCtx, "fragcoord_xyz", "FragCoord xyz test"));
2573         simpleGroup->addChild(new BuiltinGlFragCoordWCase(testCtx, "fragcoord_w", "FragCoord w test"));
2574         simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord", "PointCoord test"));
2575
2576         // FragCoord_msaa
2577         {
2578                 static const struct FragCoordMsaaCaseList
2579                 {
2580                         const char*                             name;
2581                         const char*                             description;
2582                         VkSampleCountFlagBits   sampleCount;
2583                 } fragCoordMsaaCaseList[] =
2584                 {
2585                         { "1_bit",      "Test FragCoord locations with 2 samples", VK_SAMPLE_COUNT_1_BIT },
2586                         { "2_bit",      "Test FragCoord locations with 2 samples", VK_SAMPLE_COUNT_2_BIT },
2587                         { "4_bit",      "Test FragCoord locations with 4 samples", VK_SAMPLE_COUNT_4_BIT },
2588                         { "8_bit",      "Test FragCoord locations with 8 samples", VK_SAMPLE_COUNT_8_BIT },
2589                         { "16_bit",     "Test FragCoord locations with 16 samples", VK_SAMPLE_COUNT_16_BIT },
2590                         { "32_bit", "Test FragCoord locations with 32 samples", VK_SAMPLE_COUNT_32_BIT },
2591                         { "64-bit", "Test FragCoord locaitons with 64 samples", VK_SAMPLE_COUNT_64_BIT }
2592                 };
2593
2594                 for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(fragCoordMsaaCaseList); caseNdx++)
2595                         fragCoordMsaaGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, fragCoordMsaaCaseList[caseNdx].name, fragCoordMsaaCaseList[caseNdx].description, fragCoordMsaaCaseList[caseNdx].sampleCount));
2596         }
2597
2598         // gl_FrontFacing tests
2599         {
2600                 static const struct PrimitiveTable
2601                 {
2602                         const char*                             name;
2603                         const char*                             desc;
2604                         VkPrimitiveTopology             primitive;
2605                 } frontfacingCases[] =
2606                 {
2607                         { "point_list",         "Test that points are frontfacing",                                                     VK_PRIMITIVE_TOPOLOGY_POINT_LIST },
2608                         { "line_list",          "Test that lines are frontfacing",                                                      VK_PRIMITIVE_TOPOLOGY_LINE_LIST },
2609                         { "triangle_list",      "Test that triangles can be frontfacing or backfacing",         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST },
2610                         { "triangle_strip",     "Test that traiangle strips can be front or back facing",       VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP },
2611                         { "triangle_fan",       "Test that triangle fans can be front or back facing",          VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN },
2612                 };
2613
2614                 for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(frontfacingCases); ndx++)
2615                         frontFacingGroup->addChild(new BuiltinGlFrontFacingCase(testCtx, frontfacingCases[ndx].primitive, frontfacingCases[ndx].name, frontfacingCases[ndx].desc));
2616         }
2617
2618         // gl_FragDepth
2619         {
2620                 static const struct PrimitiveTopologyTable
2621                 {
2622                         std::string                     name;
2623                         std::string                     desc;
2624                         VkPrimitiveTopology     prim;
2625                 } primitiveTopologyTable[] =
2626                 {
2627                         { "point_list",         "test that points respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_POINT_LIST },
2628                         { "line_list",          "test taht lines respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_LINE_LIST },
2629                         { "triangle_list",      "test that triangles respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP },
2630                 };
2631
2632                 static const struct TestCaseTable
2633                 {
2634                         VkFormat                                format;
2635                         std::string                             name;
2636                         bool                                    largeDepthEnable;
2637                         bool                                    depthClampEnable;
2638                         VkSampleCountFlagBits   samples;
2639                 } testCaseTable[] =
2640                 {
2641                         { VK_FORMAT_D16_UNORM,                          "d16_unorm_no_depth_clamp",                             false,  false,  VK_SAMPLE_COUNT_1_BIT },
2642                         { VK_FORMAT_X8_D24_UNORM_PACK32,        "x8_d24_unorm_pack32_no_depth_clamp",   false,  false,  VK_SAMPLE_COUNT_1_BIT },
2643                         { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_no_depth_clamp",                    false,  false,  VK_SAMPLE_COUNT_1_BIT },
2644                         { VK_FORMAT_D16_UNORM_S8_UINT,          "d16_unorm_s8_uint_no_depth_clamp",             false,  false,  VK_SAMPLE_COUNT_1_BIT },
2645                         { VK_FORMAT_D24_UNORM_S8_UINT,          "d24_unorm_s8_uint_no_depth_clamp",             false,  false,  VK_SAMPLE_COUNT_1_BIT },
2646                         { VK_FORMAT_D32_SFLOAT_S8_UINT,         "d32_sfloat_s8_uint_no_depth_clamp",    false,  false,  VK_SAMPLE_COUNT_1_BIT },
2647                         { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_large_depth",                               true,   false,  VK_SAMPLE_COUNT_1_BIT },
2648                         { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat",                                                   false,  true,   VK_SAMPLE_COUNT_1_BIT },
2649                         { VK_FORMAT_D32_SFLOAT_S8_UINT,         "d32_sfloat_s8_uint",                                   false,  true,   VK_SAMPLE_COUNT_1_BIT },
2650                         { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_multisample_2",                             false,  false,  VK_SAMPLE_COUNT_2_BIT },
2651                         { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_multisample_4",                             false,  false,  VK_SAMPLE_COUNT_4_BIT },
2652                         { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_multisample_8",                             false,  false,  VK_SAMPLE_COUNT_8_BIT },
2653                         { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_multisample_16",                    false,  false,  VK_SAMPLE_COUNT_16_BIT },
2654                         { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_multisample_32",                    false,  false,  VK_SAMPLE_COUNT_32_BIT },
2655                         { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_multisample_64",                    false,  false,  VK_SAMPLE_COUNT_64_BIT },
2656                 };
2657
2658                 for (deUint32 primNdx = 0;  primNdx < DE_LENGTH_OF_ARRAY(primitiveTopologyTable); primNdx++)
2659                 {
2660                         for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(testCaseTable); caseNdx++)
2661                                 fragDepthGroup->addChild(new BuiltinFragDepthCase(testCtx, (primitiveTopologyTable[primNdx].name+"_" + testCaseTable[caseNdx].name).c_str(), primitiveTopologyTable[primNdx].desc.c_str(),
2662                                                         primitiveTopologyTable[primNdx].prim, testCaseTable[caseNdx].format, testCaseTable[caseNdx].largeDepthEnable, testCaseTable[caseNdx].depthClampEnable, testCaseTable[caseNdx].samples));
2663
2664                 }
2665         }
2666
2667         builtinGroup->addChild(frontFacingGroup.release());
2668         builtinGroup->addChild(fragDepthGroup.release());
2669         builtinGroup->addChild(fragCoordMsaaGroup.release());
2670         builtinGroup->addChild(simpleGroup.release());
2671
2672         for (deUint16 shaderType = 0; shaderType <= (SHADER_INPUT_BUILTIN_BIT | SHADER_INPUT_VARYING_BIT | SHADER_INPUT_CONSTANT_BIT); ++shaderType)
2673         {
2674                 inputVariationsGroup->addChild(new BuiltinInputVariationsCase(testCtx, shaderInputTypeToString(shaderType), "Input variation test", shaderType));
2675         }
2676
2677         builtinGroup->addChild(inputVariationsGroup.release());
2678         return builtinGroup.release();
2679 }
2680
2681 } // sr
2682 } // vkt