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