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