Add test for FragDepth shader built-in
authorDavid Sodman <dsodman@google.com>
Fri, 24 Feb 2017 18:41:59 +0000 (10:41 -0800)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Thu, 31 Aug 2017 18:19:15 +0000 (14:19 -0400)
Components: Vulkan

VK-GL-CTS issue: 93

Test: fragdepth, frontface, clipping
Change-Id: I531e39a58dd6b577108bff14b2206d7bf9d9cd4f
(cherry picked from commit 3aeb0c565fe64441466247fe381fc815209d46e4)

android/cts/master/src/vk-excluded-tests.txt
external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderBuiltinVarTests.cpp
external/vulkancts/modules/vulkan/vktDrawUtil.cpp
external/vulkancts/modules/vulkan/vktDrawUtil.hpp
external/vulkancts/mustpass/1.0.2/src/excluded-tests.txt

index 6c97232..6ce5b49 100644 (file)
@@ -325,3 +325,6 @@ dEQP-VK.pipeline.render_to_image.*.small.r8g8b8a8_unorm_d32_sfloat_s8_uint
 dEQP-VK.pipeline.render_to_image.*.small.r32_uint_d32_sfloat_s8_uint
 dEQP-VK.pipeline.render_to_image.*.small.r16g16_sint_d32_sfloat_s8_uint
 dEQP-VK.pipeline.render_to_image.*.small.r32g32b32a32_sfloat_d32_sfloat_s8_uint
+
+#VK-GL-CTS 655
+dEQP-VK.glsl.builtin_var.fragdepth.*
index bc69299..bad106d 100644 (file)
@@ -25,6 +25,8 @@
 
 #include "vktShaderRenderBuiltinVarTests.hpp"
 
+#include "tcuFloat.hpp"
+#include "deUniquePtr.hpp"
 #include "vkDefs.hpp"
 #include "vktShaderRender.hpp"
 #include "gluShaderUtil.hpp"
@@ -32,6 +34,9 @@
 #include "tcuStringTemplate.hpp"
 #include "tcuTextureUtil.hpp"
 #include "vktDrawUtil.hpp"
+#include "vkImageUtil.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkMemUtil.hpp"
 #include "tcuTestLog.hpp"
 
 #include "deMath.h"
@@ -42,6 +47,7 @@
 using namespace std;
 using namespace tcu;
 using namespace vk;
+using namespace de;
 
 namespace vkt
 {
@@ -253,6 +259,1139 @@ TestInstance* BuiltinGlFrontFacingCase::createInstance (Context& context) const
        return new BuiltinGlFrontFacingCaseInstance(context, m_topology);
 }
 
+class BuiltinFragDepthCaseInstance : public TestInstance
+{
+public:
+       enum
+       {
+               RENDERWIDTH             = 16,
+               RENDERHEIGHT    = 16
+       };
+                                       BuiltinFragDepthCaseInstance            (Context& context, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, float defaultDepth, bool depthClampEnable, const VkSampleCountFlagBits samples);
+       TestStatus              iterate                                                         (void);
+
+       bool                    validateDepthBuffer                                     (const tcu::ConstPixelBufferAccess& validationBuffer, const tcu::ConstPixelBufferAccess& markerBuffer, const float tolerance) const;
+private:
+       const VkPrimitiveTopology               m_topology;
+       const VkFormat                                  m_format;
+       const bool                                              m_largeDepthEnable;
+       const float                                             m_defaultDepthValue;
+       const bool                                              m_depthClampEnable;
+       const VkSampleCountFlagBits             m_samples;
+       const tcu::UVec2                                m_renderSize;
+       const float                                             m_largeDepthBase;
+};
+
+BuiltinFragDepthCaseInstance::BuiltinFragDepthCaseInstance (Context& context, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, float defaultDepth, bool depthClampEnable, const VkSampleCountFlagBits samples)
+       : TestInstance                  (context)
+       , m_topology                    (topology)
+       , m_format                              (format)
+       , m_largeDepthEnable    (largeDepthEnable)
+       , m_defaultDepthValue   (defaultDepth)
+       , m_depthClampEnable    (depthClampEnable)
+       , m_samples                             (samples)
+       , m_renderSize                  (RENDERWIDTH, RENDERHEIGHT)
+       , m_largeDepthBase              (20.0f)
+{
+       const InstanceInterface&        vki                                     = m_context.getInstanceInterface();
+       const VkPhysicalDevice          physicalDevice          = m_context.getPhysicalDevice();
+
+       try
+       {
+               VkImageFormatProperties         imageFormatProperties;
+               VkFormatProperties                      formatProperties;
+
+               if (m_context.getDeviceFeatures().fragmentStoresAndAtomics == VK_FALSE)
+                       throw tcu::NotSupportedError("fragmentStoresAndAtomics not supported");
+
+               imageFormatProperties = getPhysicalDeviceImageFormatProperties(vki, physicalDevice, m_format, VK_IMAGE_TYPE_2D,
+                               VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, (VkImageCreateFlags)0);
+
+               if ((imageFormatProperties.sampleCounts & m_samples) == 0)
+                       throw tcu::NotSupportedError("Image format and sample count not supported");
+
+               formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, VK_FORMAT_R8G8B8A8_UINT);
+
+               if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
+                       throw tcu::NotSupportedError("MarkerImage format not supported as storage image");
+       }
+       catch (const vk::Error& e)
+       {
+               if (e.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
+                       throw tcu::NotSupportedError("Image format not supported");
+               else
+                       throw;
+
+       }
+}
+
+TestStatus BuiltinFragDepthCaseInstance::iterate (void)
+{
+       const VkDevice                                  device                          = m_context.getDevice();
+       const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
+       const VkQueue                                   queue                           = m_context.getUniversalQueue();
+       Allocator&                                              allocator                       = m_context.getDefaultAllocator();
+       const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
+       TestLog&                                                log                                     = m_context.getTestContext().getLog();
+       const deUint32                                  scale                           = 4;                                                                            // To account for std140 stride
+       const VkDeviceSize                              pixelCount                      = m_renderSize.x() * m_renderSize.y();
+       std::string                                             testDesc;
+       Move<VkImage>                                   depthResolveImage;
+       Move<VkImageView>                               depthResolveImageView;
+       MovePtr<Allocation>                             depthResolveAllocation;
+       Move<VkImage>                                   depthImage;
+       Move<VkImageView>                               depthImageView;
+       MovePtr<Allocation>                             depthImageAllocation;
+       Move<VkBuffer>                                  controlBuffer;
+       MovePtr<Allocation>                             controlBufferAllocation;
+       Move<VkImage>                                   markerImage;
+       Move<VkImageView>                               markerImageView;
+       MovePtr<Allocation>                             markerImageAllocation;
+       Move<VkBuffer>                                  markerBuffer;
+       MovePtr<Allocation>                             markerBufferAllocation;
+       Move<VkBuffer>                                  validationBuffer;
+       MovePtr<Allocation>                             validationAlloc;
+       MovePtr<Allocation>                             depthInitAllocation;
+       Move<VkCommandPool>                             cmdPool;
+       Move<VkCommandBuffer>                   transferCmdBuffer;
+       Move<VkFence>                                   fence;
+       Move<VkSampler>                                 depthSampler;
+
+       // Create Buffer/Image for validation
+       {
+               VkFormat        resolvedBufferFormat = VK_FORMAT_R32_SFLOAT;
+               const VkBufferCreateInfo validationBufferCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                                                           // VkStructureType              sType
+                       DE_NULL,                                                                                                                                        // const void*                  pNext
+                       (VkBufferCreateFlags)0,                                                                                                         // VkBufferCreateFlags  flags
+                       m_samples * pixelCount * getPixelSize(mapVkFormat(resolvedBufferFormat)),       // VkDeviceSize                 size
+                       VK_BUFFER_USAGE_TRANSFER_DST_BIT,                                                                                       // VkBufferUsageFlags   usage
+                       VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                sharingMode
+                       0u,                                                                                                                                                     // uint32_t                             queueFamilyIndexCount,
+                       DE_NULL                                                                                                                                         // const uint32_t*              pQueueFamilyIndices
+               };
+
+               validationBuffer = createBuffer(vk, device, &validationBufferCreateInfo);
+               validationAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *validationBuffer), MemoryRequirement::HostVisible);
+               VK_CHECK(vk.bindBufferMemory(device, *validationBuffer, validationAlloc->getMemory(), validationAlloc->getOffset()));
+
+               const VkImageCreateInfo depthResolveImageCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                            // VkStructureType                      sType
+                       DE_NULL,                                                                                                                        // const void*                          pNext
+                       (VkImageCreateFlags)0,                                                                                          // VkImageCreateFlags           flags
+                       VK_IMAGE_TYPE_2D,                                                                                                       // VkIMageType                          imageType
+                       resolvedBufferFormat,                                                                                           // VkFormat                                     format
+                       makeExtent3D(m_samples * m_renderSize.x(), m_renderSize.y(), 1u),       // VkExtent3D                           extent
+                       1u,                                                                                                                                     // uint32_t                                     mipLevels
+                       1u,                                                                                                                                     // uint32_t                                     arrayLayers
+                       VK_SAMPLE_COUNT_1_BIT,                                                                                          // VkSampleCountFlagsBits       samples
+                       VK_IMAGE_TILING_OPTIMAL,                                                                                        // VkImageTiling                        tiling
+                       VK_IMAGE_USAGE_TRANSFER_SRC_BIT |                                                                       // VkImageUsageFlags            usage
+                       VK_IMAGE_USAGE_STORAGE_BIT |
+                       VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+                       VK_SHARING_MODE_EXCLUSIVE,                                                                                      // VkSharingMode                        sharingMode
+                       0u,                                                                                                                                     // uint32_t                                     queueFamilyIndexCount
+                       DE_NULL,                                                                                                                        // const uint32_t                       pQueueFamilyIndices
+                       VK_IMAGE_LAYOUT_UNDEFINED                                                                                       // VkImageLayout                        initialLayout
+               };
+
+               depthResolveImage = createImage(vk, device, &depthResolveImageCreateInfo, DE_NULL);
+               depthResolveAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *depthResolveImage), MemoryRequirement::Any);
+               VK_CHECK(vk.bindImageMemory(device, *depthResolveImage, depthResolveAllocation->getMemory(), depthResolveAllocation->getOffset()));
+
+               const VkImageViewCreateInfo depthResolveImageViewCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                                                               // VkStructureType                      sType
+                       DE_NULL,                                                                                                                                // const void*                          pNext
+                       (VkImageViewCreateFlags)0,                                                                                              // VkImageViewCreateFlags       flags
+                       *depthResolveImage,                                                                                                             // VkImage                                      image
+                       VK_IMAGE_VIEW_TYPE_2D,                                                                                                  // VkImageViewType                      type
+                       resolvedBufferFormat,                                                                                                   // VkFormat                                     format
+                       makeComponentMappingRGBA(),                                                                                             // VkComponentMapping           componentMapping
+                       makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)    // VkImageSUbresourceRange      subresourceRange
+               };
+
+               depthResolveImageView = createImageView(vk, device, &depthResolveImageViewCreateInfo, DE_NULL);
+       }
+
+       // Marker Buffer
+       {
+               const VkDeviceSize      size                    = m_samples * m_renderSize.x() * m_renderSize.y() * getPixelSize(mapVkFormat(VK_FORMAT_R8G8B8A8_UINT));
+
+               const VkBufferCreateInfo markerBufferCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                   // VkStructureType                      sType
+                       DE_NULL,                                                                                // const void*                          pNext
+                       (VkBufferCreateFlags)0,                                                 // VkBufferCreateFlags          flags
+                       size,                                                                                   // VkDeviceSize                         size
+                       VK_BUFFER_USAGE_TRANSFER_DST_BIT,                               // VkBufferUsageFlags           usage
+                       VK_SHARING_MODE_EXCLUSIVE,                                              // VkSharingMode                        sharingMode
+                       0u,                                                                                             // uint32_t                                     queueFamilyIndexCount
+                       DE_NULL                                                                                 // const uint32_t*                      pQueueFamilyIndices
+               };
+
+               markerBuffer = createBuffer(vk, device, &markerBufferCreateInfo, DE_NULL);
+               markerBufferAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *markerBuffer), MemoryRequirement::HostVisible);
+               VK_CHECK(vk.bindBufferMemory(device, *markerBuffer, markerBufferAllocation->getMemory(), markerBufferAllocation->getOffset()));
+
+               const VkImageCreateInfo markerImageCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                    // VkStructureType                      sType
+                       DE_NULL,                                                                                                                // const void*                          pNext
+                       (VkImageCreateFlags)0,                                                                                  // VkImageCreateFlags           flags
+                       VK_IMAGE_TYPE_2D,                                                                                               // VkImageType                          imageType
+                       VK_FORMAT_R8G8B8A8_UINT,                                                                                // VkFormat                                     format
+                       makeExtent3D(m_samples * m_renderSize.x(), m_renderSize.y(), 1),// VkExtent3D                           extent
+                       1u,                                                                                                                             // uint32_t                                     mipLevels
+                       1u,                                                                                                                             // uint32_t                                     arrayLayers
+                       VK_SAMPLE_COUNT_1_BIT,                                                                                  // VkSampleCountFlagsBit        smaples
+                       VK_IMAGE_TILING_OPTIMAL,                                                                                // VkImageTiling                        tiling
+                       VK_IMAGE_USAGE_STORAGE_BIT |                                                                    // VkImageUsageFlags            usage
+                       VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+                       VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+                       VK_SHARING_MODE_EXCLUSIVE,                                                                              // VkSharingMode                        sharing
+                       0u,                                                                                                                             // uint32_t                                     queueFamilyIndexCount
+                       DE_NULL,                                                                                                                // const uint32_t*                      pQueueFamilyIndices
+                       VK_IMAGE_LAYOUT_UNDEFINED                                                                               // VkImageLayout                        initialLayout
+               };
+
+               markerImage = createImage(vk, device, &markerImageCreateInfo, DE_NULL);
+               markerImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *markerImage), MemoryRequirement::Any);
+               VK_CHECK(vk.bindImageMemory(device, *markerImage, markerImageAllocation->getMemory(), markerImageAllocation->getOffset()));
+
+               const VkImageViewCreateInfo markerViewCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                               // VkStructureType                      sType
+                       DE_NULL,                                                                                                // const void*                          pNext
+                       (VkImageViewCreateFlags)0,                                                              // VkImageViewCreateFlags       flags
+                       *markerImage,                                                                                   // VkImage                                      image
+                       VK_IMAGE_VIEW_TYPE_2D,                                                                  // VkImageViewType                      viewType
+                       VK_FORMAT_R8G8B8A8_UINT,                                                                // VkFormat                                     format
+                       makeComponentMappingRGBA(),                                                             // VkComponentMapping           components
+                       makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)
+               };
+
+               markerImageView = createImageView(vk, device, &markerViewCreateInfo, DE_NULL);
+       }
+
+       // Control Buffer
+       {
+               const VkBufferCreateInfo controlBufferCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                   // VkStructureType              sType
+                       DE_NULL,                                                                                                // const void*                  pNext
+                       (VkBufferCreateFlags)0,                                                                 // VkBufferCreateFlags  flags
+                       pixelCount * sizeof(float)* scale,                                              // VkDeviceSize                 size
+                       VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,                                             // VkBufferUsageFlags   usage
+                       VK_SHARING_MODE_EXCLUSIVE,                                                              // VkSharingMode                sharingMode
+                       0u,                                                                                                             // deUint32                             queueFamilyIndexCount
+
+                       DE_NULL                                                                                                 // pQueueFamilyIndices
+               };
+
+               controlBuffer = createBuffer(vk, device, &controlBufferCreateInfo, DE_NULL);
+               controlBufferAllocation = allocator.allocate( getBufferMemoryRequirements(vk, device, *controlBuffer), MemoryRequirement::HostVisible);
+               VK_CHECK(vk.bindBufferMemory(device, *controlBuffer, controlBufferAllocation->getMemory(), controlBufferAllocation->getOffset()));
+
+               {
+                       float* bufferData = (float*)(controlBufferAllocation->getHostPtr());
+                       float sign = m_depthClampEnable ? -1.0f : 1.0f;
+                       for (deUint32 ndx = 0; ndx < m_renderSize.x() * m_renderSize.y(); ndx++)
+                       {
+                               bufferData[ndx * scale] = (float)ndx / 256.0f * sign;
+                               if (m_largeDepthEnable)
+                                       bufferData[ndx * scale] += m_largeDepthBase;
+                       }
+
+                       const VkMappedMemoryRange range =
+                       {
+                               VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
+                               DE_NULL,
+                               controlBufferAllocation->getMemory(),
+                               0u,
+                               VK_WHOLE_SIZE
+                       };
+
+                       VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
+               }
+       }
+
+       // Depth Buffer
+       {
+               VkImageSubresourceRange depthSubresourceRange   = makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u);
+               const VkImageCreateInfo depthImageCreateInfo    =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                    // VkStructureType                      sType
+                       DE_NULL,                                                                                                // const void*                          pNext
+                       (VkImageCreateFlags)0,                                                                  // VkImageCreateFlags           flags
+                       VK_IMAGE_TYPE_2D,                                                                               // VkImageType                          imageType
+                       m_format,                                                                                               // VkFormat                                     format
+                       makeExtent3D(m_renderSize.x(), m_renderSize.y(), 1u),   // VkExtent3D                           extent
+                       1u,                                                                                                             // uint32_t                                     mipLevels
+                       1u,                                                                                                             // uint32_t                                     arrayLayers
+                       m_samples,                                                                                              // VkSampleCountFlagsBits       samples
+                       VK_IMAGE_TILING_OPTIMAL,                                                                // VkImageTiling                        tiling
+                       VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+                       VK_IMAGE_USAGE_TRANSFER_DST_BIT |
+                       VK_IMAGE_USAGE_SAMPLED_BIT      |
+                       VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,                    // VkImageUsageFlags            usage
+                       VK_SHARING_MODE_EXCLUSIVE,                                                              // VkShaderingMode                      sharingMode
+                       0u,                                                                                                             // uint32_t                                     queueFamilyIndexCount
+                       DE_NULL,                                                                                                // const uint32_t*                      pQueueFamilyIndices
+                       VK_IMAGE_LAYOUT_UNDEFINED                                                               // VkImageLayout                        initialLayout
+               };
+
+               depthImage = createImage(vk, device, &depthImageCreateInfo, DE_NULL);
+               depthImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *depthImage), MemoryRequirement::Any);
+               VK_CHECK(vk.bindImageMemory(device, *depthImage, depthImageAllocation->getMemory(), depthImageAllocation->getOffset()));
+
+               const VkImageViewCreateInfo imageViewParams =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
+                       DE_NULL,                                                                                // const void*                          pNext;
+                       (VkImageViewCreateFlags)0,                                              // VkImageViewCreateFlags       flags;
+                       *depthImage,                                                                    // VkImage                                      image;
+                       VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
+                       m_format,                                                                               // VkFormat                                     format;
+                       makeComponentMappingRGBA(),                                             // VkComponentMapping           components;
+                       depthSubresourceRange,                                                  // VkImageSubresourceRange      subresourceRange;
+               };
+               depthImageView = createImageView(vk, device, &imageViewParams);
+
+               const VkSamplerCreateInfo depthSamplerCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,                  // VkStructureType                      sType
+                       DE_NULL,                                                                                // const void*                          pNext
+                       (VkSamplerCreateFlags)0,                                                // VkSamplerCreateFlags         flags
+                       VK_FILTER_NEAREST,                                                              // VkFilter                                     minFilter
+                       VK_FILTER_NEAREST,                                                              // VkFilter                                     magFilter
+                       VK_SAMPLER_MIPMAP_MODE_NEAREST,                                 // VkSamplerMipMapMode          mipMapMode
+                       VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,                  // VkSamplerAddressMode         addressModeU
+                       VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,                  // VkSamplerAddressMode         addressModeV
+                       VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,                  // VkSamplerAddressMode         addressmodeW
+                       0.0f,                                                                                   // float                                        mipLodBias
+                       VK_FALSE,                                                                               // VkBool32                                     anisotropyEnable
+                       0.0f,                                                                                   // float                                        maxAnisotropy
+                       VK_FALSE,                                                                               // VkBool32                                     compareEnable
+                       VK_COMPARE_OP_NEVER,                                                    // VkCompareOp                          compareOp
+                       0.0f,                                                                                   // float                                        minLod
+                       0.0f,                                                                                   // float                                        maxLod
+                       VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,                // VkBorderColor                        borderColor
+                       VK_FALSE                                                                                // VkBool32                                     unnormalizedCoordinates
+               };
+
+               depthSampler = createSampler(vk, device, &depthSamplerCreateInfo, DE_NULL);
+       }
+
+       // Command Pool
+       {
+               const VkCommandPoolCreateInfo cmdPoolCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,                     // VkStructureType                      sType
+                       DE_NULL,                                                                                        // const void*                          pNext
+                       VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,        // VkCommandPoolCreateFlags     flags
+                       queueFamilyIndex                                                                        // uint32_t                                     queueFamilyIndex
+               };
+
+               cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
+       }
+
+       // Command buffer for data transfers
+       {
+               const VkCommandBufferAllocateInfo cmdBufferAllocInfo =
+               {
+                       VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType              sType,
+                       DE_NULL,                                                                                // const void*                  pNext
+                       *cmdPool,                                                                               // VkCommandPool                commandPool
+                       VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel level
+                       1u                                                                                              // uint32_t                             bufferCount
+               };
+
+               transferCmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocInfo);
+       }
+
+       // Fence for data transfer
+       {
+               const VkFenceCreateInfo fenceCreateInfo =
+               {
+                       VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType
+                       DE_NULL,                                                                // const void*                  pNext
+                       (VkFenceCreateFlags)0                                   // VkFenceCreateFlags   flags
+               };
+
+               fence = createFence(vk, device, &fenceCreateInfo);
+       }
+
+       // Initialize Depth Buffer and Marker Buffer
+       {
+               VkImageAspectFlags      depthImageAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT;
+               if (hasStencilComponent(mapVkFormat(m_format).order))
+                       depthImageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
+
+               const VkImageMemoryBarrier imageBarrier[] =
+               {
+                       {
+                               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType              sType
+                               DE_NULL,                                                                                // const void*                  pNext
+                               0,                                                                                              // VkAccessMask                 srcAccessMask
+                               VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessMask                 dstAccessMask
+                               VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                oldLayout
+                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                newLayout
+                               VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             srcQueueFamilyIndex
+                               VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             dstQueueFamilyIndex
+                               *markerImage,                                                                   // VkImage                              image
+                               {
+                                       VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask
+                                       0u,                                                                             // uint32_t                             baseMipLevel
+                                       1u,                                                                             // uint32_t                             mipLevels
+                                       0u,                                                                             // uint32_t                             baseArray
+                                       1u                                                                              // uint32_t                             arraySize
+                               }
+                       },
+                       {
+                               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType              sType
+                               DE_NULL,                                                                                // const void*                  pNext
+                               0,                                                                                              // VkAccessMask                 srcAccessMask
+                               VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessMask                 dstAccessMask
+                               VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                oldLayout
+                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                newLayout
+                               VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             srcQueueFamilyIndex
+                               VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             dstQueueFamilyIndex
+                               *depthImage,                                                                    // VkImage                              image
+                               {
+                                       depthImageAspectFlags,                                  // VkImageAspectFlags   aspectMask
+                                       0u,                                                                             // uint32_t                             baseMipLevel
+                                       1u,                                                                             // uint32_t                             mipLevels
+                                       0u,                                                                             // uint32_t                             baseArray
+                                       1u                                                                              // uint32_t                             arraySize
+                               }
+                       }
+               };
+
+               const VkImageMemoryBarrier imagePostBarrier[] =
+               {
+                       {
+                               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType              sType
+                               DE_NULL,                                                                                // const void*                  pNext
+                               VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlagBits             srcAccessMask
+                               VK_ACCESS_SHADER_WRITE_BIT,                                             // VkAccessFlagBits             dstAccessMask
+                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                   // VkImageLayout                oldLayout
+                               VK_IMAGE_LAYOUT_GENERAL,                                                // VkImageLayout                newLayout
+                               VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             srcQueueFamilyIndex
+                               VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             dstQueueFamilyIndex
+                               *markerImage,                                                                   // VkImage                              image
+                               {
+                                       VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask
+                                       0u,                                                                             // uint32_t                             baseMipLevel
+                                       1u,                                                                             // uint32_t                             mipLevels
+                                       0u,                                                                             // uint32_t                             baseArray
+                                       1u                                                                              // uint32_t                             arraySize
+                               }
+                       },
+                       {
+                               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType              sType
+                               DE_NULL,                                                                                        // cont void*                   pNext
+                               VK_ACCESS_TRANSFER_WRITE_BIT,                                           // VkAccessFlagBits             srcAccessMask
+                               VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,           // VkAccessFlagBits             dstAccessMask
+                               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                           // VkImageLayout                oldLayout
+                               VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,       // VkImageLayout                newLayout
+                               VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             srcQueueFamilyIndex
+                               VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             dstQueueFamilyIndex
+                               *depthImage,                                                                            // VkImage                              image
+                               {
+                                       depthImageAspectFlags,                                          // VkImageAspectFlags   aspectMask
+                                       0u,                                                                                     // uint32_t                             baseMipLevel
+                                       1u,                                                                                     // uint32_t                             mipLevels
+                                       0u,                                                                                     // uint32_t                             baseArray
+                                       1u                                                                                      // uint32_t                             arraySize
+                               }
+
+                       }
+               };
+
+               const VkCommandBufferBeginInfo  cmdBufferBeginInfo =
+               {
+                       VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType
+                       DE_NULL,                                                                                // const void*                                          pNext
+                       VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags
+                       (const VkCommandBufferInheritanceInfo*)DE_NULL  // VkCommandBufferInheritanceInfo       pInheritanceInfo
+               };
+
+               VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo));
+               vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                               (VkDependencyFlags)0,
+                               0, (const VkMemoryBarrier*)DE_NULL,
+                               0, (const VkBufferMemoryBarrier*)DE_NULL,
+                               DE_LENGTH_OF_ARRAY(imageBarrier), imageBarrier);
+
+               const VkClearValue                              colorClearValue = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
+               const VkImageSubresourceRange   colorClearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
+               const VkClearValue                              depthClearValue = makeClearValueDepthStencil(m_defaultDepthValue, 0);
+               const VkImageSubresourceRange   depthClearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u);
+
+               vk.cmdClearColorImage(*transferCmdBuffer, *markerImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &colorClearValue.color, 1u, &colorClearRange);
+               vk.cmdClearDepthStencilImage(*transferCmdBuffer, *depthImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depthClearValue.depthStencil, 1u, &depthClearRange);
+
+               vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
+                               (VkDependencyFlags)0,
+                               0, (const VkMemoryBarrier*)DE_NULL,
+                               0, (const VkBufferMemoryBarrier*)DE_NULL,
+                               DE_LENGTH_OF_ARRAY(imagePostBarrier), imagePostBarrier);
+
+               VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer));
+
+               const VkSubmitInfo submitInfo =
+               {
+                       VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                      sType
+                       DE_NULL,                                                                // const void*                          pNext
+                       0u,                                                                             // uint32_t                                     waitSemaphoreCount
+                       DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores
+                       (const VkPipelineStageFlags*)DE_NULL,   // const VkPipelineStageFlags*  pWaitDstStageMask
+                       1u,                                                                             // uint32_t                                     commandBufferCount
+                       &transferCmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers
+                       0u,                                                                             // uint32_t                                     signalSemaphoreCount
+                       DE_NULL                                                                 // const VkSemaphore*           pSignalSemaphores
+               };
+
+               VK_CHECK(vk.resetFences(device, 1, &fence.get()));
+               VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
+               VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull)));
+       }
+
+
+       // Perform Draw
+       {
+               std::vector<Vec4>                               vertices;
+               std::vector<Shader>                             shaders;
+               Move<VkDescriptorSetLayout>             descriptorSetLayout;
+               Move<VkDescriptorPool>                  descriptorPool;
+               Move<VkDescriptorSet>                   descriptorSet;
+
+               // Descriptors
+               {
+                       DescriptorSetLayoutBuilder      layoutBuilder;
+                       layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
+                       layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
+                       descriptorSetLayout = layoutBuilder.build(vk, device);
+                       descriptorPool = DescriptorPoolBuilder()
+                                       .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
+                                       .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
+                                       .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
+
+                       const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
+                       {
+                               VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
+                               DE_NULL,
+                               *descriptorPool,
+                               1u,
+                               &descriptorSetLayout.get()
+                       };
+
+                       descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo);
+
+                       const VkDescriptorBufferInfo bufferInfo =
+                       {
+                               *controlBuffer,
+                               0u,
+                               VK_WHOLE_SIZE
+                       };
+
+                       const VkDescriptorImageInfo imageInfo =
+                       {
+                               (VkSampler)DE_NULL,
+                               *markerImageView,
+                               VK_IMAGE_LAYOUT_GENERAL
+                       };
+
+                       DescriptorSetUpdateBuilder()
+                               .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferInfo)
+                               .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
+                               .update(vk, device);
+               }
+
+               vertices.push_back(Vec4( -0.70f,        0.5f,   0.0f,   1.0f));
+               vertices.push_back(Vec4(  0.45f,        -0.75f, 0.0f,   1.0f));
+               vertices.push_back(Vec4(  0.78f,        0.0f,   0.0f,   1.0f));
+               vertices.push_back(Vec4( -0.1f,         0.6f,   0.0f,   1.0f));
+
+               shaders.push_back(Shader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragDepthVert")));
+               shaders.push_back(Shader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragDepthFrag")));
+
+               DrawState                               drawState(m_topology, m_renderSize.x(), m_renderSize.y());
+               DrawCallData                    drawCallData(vertices);
+               VulkanProgram                   vulkanProgram(shaders);
+
+               drawState.depthClampEnable                      = m_depthClampEnable;
+               drawState.depthFormat                           = m_format;
+               drawState.numSamples                            = m_samples;
+               drawState.compareOp                                     = rr::TESTFUNC_ALWAYS;
+               drawState.depthTestEnable                       = true;
+               drawState.depthWriteEnable                      = true;
+               drawState.sampleShadingEnable           = true;
+               vulkanProgram.depthImageView            = depthImageView;
+               vulkanProgram.descriptorSetLayout       = descriptorSetLayout;
+               vulkanProgram.descriptorSet                     = descriptorSet;
+
+               VulkanDrawContext               vulkanDrawContext(m_context, drawState, drawCallData, vulkanProgram);
+               vulkanDrawContext.draw();
+
+               log << TestLog::Image(  "resultColor",
+                                                               "Result Color Buffer",
+                                                               tcu::ConstPixelBufferAccess(tcu::TextureFormat(
+                                                                               vulkanDrawContext.getColorPixels().getFormat()),
+                                                                               vulkanDrawContext.getColorPixels().getWidth(),
+                                                                               vulkanDrawContext.getColorPixels().getHeight(),
+                                                                               1,
+                                                                               vulkanDrawContext.getColorPixels().getDataPtr()));
+
+               depthImageView = vulkanProgram.depthImageView;
+       }
+
+       // Barrier to transition between first and second pass
+       {
+               VkImageAspectFlags      depthImageAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT;
+               if (hasStencilComponent(mapVkFormat(m_format).order))
+                       depthImageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
+
+               const VkImageMemoryBarrier imageBarrier[] =
+               {
+                       {
+                               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                         // VkStructureType              sType
+                               DE_NULL,                                                                                                        // const void*                  pNext
+                               VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,                           // VkAccessFlags                srcAccessMask
+                               VK_ACCESS_SHADER_READ_BIT,                                                                      // VkAccessFlags                dstAccessMask
+                               VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,                       // VkImageLayout                oldLayout
+                               VK_IMAGE_LAYOUT_GENERAL,                                                                        // VkImageLayout                newLayout
+                               0u,                                                                                                                     // deUint32                             srcQueueFamilyIndex
+                               0u,                                                                                                                     // deUint32                             dstQueueFamilyIndex
+                               *depthImage,                                                                                            // VkImage                              image
+                               {
+                                       depthImageAspectFlags,                                                  // VkImageAspectFlags           aspectMask
+                                       0u,                                                                                             // deUint32                                     baseMipLevel
+                                       1u,                                                                                             // deUint32                                     levelCount
+                                       0u,                                                                                             // deUint32                                     baseArrayLayer
+                                       1u                                                                                              // deUint32                                     layerCount
+                               }
+                       },
+                       {
+                               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                         // VkStructureType              sType
+                               DE_NULL,                                                                                                        // const void*                  pNext
+                               0u,                                                                                                                     // VkAccessFlags                srcAccessMask
+                               VK_ACCESS_HOST_READ_BIT,                                                                        // VkAccessFlags                dstAccessMask
+                               VK_IMAGE_LAYOUT_UNDEFINED,                                                                      // VkImageLayout                oldLayout
+                               VK_IMAGE_LAYOUT_GENERAL,                                                                        // VkImageLayout                newLayout
+                               0u,                                                                                                                     // deUint32                             srcQueueFamilyIndex
+                               0u,                                                                                                                     // deUint32                             dstQueueFamilyIndex
+                               *depthResolveImage,                                                                                     // VkImage                              image
+                               {
+                                       VK_IMAGE_ASPECT_COLOR_BIT,                                              // VkImageAspectFlags           aspectMask
+                                       0u,                                                                                             // deUint32                                     baseMipLevel
+                                       1u,                                                                                             // deUint32                                     levelCount
+                                       0u,                                                                                             // deUint32                                     baseArrayLayer
+                                       1u,                                                                                             // deUint32                                     layerCount
+
+                               }
+                       }
+               };
+
+               const VkCommandBufferBeginInfo  cmdBufferBeginInfo =
+               {
+                       VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType
+                       DE_NULL,                                                                                // const void*                                          pNext
+                       VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags
+                       (const VkCommandBufferInheritanceInfo*)DE_NULL  // VkCommandBufferInheritanceInfo       pInheritanceInfo
+               };
+
+               VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo));
+               vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                               (VkDependencyFlags)0,
+                               0, (const VkMemoryBarrier*)DE_NULL,
+                               0, (const VkBufferMemoryBarrier*)DE_NULL,
+                               DE_LENGTH_OF_ARRAY(imageBarrier), imageBarrier);
+               VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer));
+
+               const VkSubmitInfo submitInfo =
+               {
+                       VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                      sType
+                       DE_NULL,                                                                // const void*                          pNext
+                       0u,                                                                             // uint32_t                                     waitSemaphoreCount
+                       DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores
+                       (const VkPipelineStageFlags*)DE_NULL,   // const VkPipelineStageFlags*  pWaitDstStageMask
+                       1u,                                                                             // uint32_t                                     commandBufferCount
+                       &transferCmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers
+                       0u,                                                                             // uint32_t                                     signalSemaphoreCount
+                       DE_NULL                                                                 // const VkSemaphore*           pSignalSemaphores
+               };
+
+               VK_CHECK(vk.resetFences(device, 1, &fence.get()));
+               VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
+               VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull)));
+       }
+
+       // Resolve Depth Buffer
+       {
+               std::vector<Vec4>                               vertices;
+               std::vector<Shader>                             shaders;
+               Move<VkDescriptorSetLayout>             descriptorSetLayout;
+               Move<VkDescriptorPool>                  descriptorPool;
+               Move<VkDescriptorSet>                   descriptorSet;
+
+               // Descriptors
+               {
+                       DescriptorSetLayoutBuilder      layoutBuilder;
+                       layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
+                       layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
+                       descriptorSetLayout = layoutBuilder.build(vk, device);
+                       descriptorPool = DescriptorPoolBuilder()
+                                       .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
+                                       .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
+                                       .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
+
+                       const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
+                       {
+                               VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
+                               DE_NULL,
+                               *descriptorPool,
+                               1u,
+                               &descriptorSetLayout.get()
+                       };
+
+                       descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo);
+
+                       const VkDescriptorImageInfo depthImageInfo =
+                       {
+                               *depthSampler,
+                               *depthImageView,
+                               VK_IMAGE_LAYOUT_GENERAL
+                       };
+
+                       const VkDescriptorImageInfo imageInfo =
+                       {
+                               (VkSampler)DE_NULL,
+                               *depthResolveImageView,
+                               VK_IMAGE_LAYOUT_GENERAL
+                       };
+
+                       DescriptorSetUpdateBuilder()
+                               .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &depthImageInfo)
+                               .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
+                               .update(vk, device);
+               }
+
+               vertices.push_back(Vec4( -1.0f, -1.0f,  0.0f,   1.0f));
+               vertices.push_back(Vec4( -1.0f,  1.0f,  0.0f,   1.0f));
+               vertices.push_back(Vec4(  1.0f, -1.0f,  0.0f,   1.0f));
+               vertices.push_back(Vec4(  1.0f,  1.0f,  0.0f,   1.0f));
+
+               shaders.push_back(Shader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragDepthVertPass2")));
+               shaders.push_back(Shader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragDepthFragPass2")));
+
+               DrawState                               drawState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, m_renderSize.x(), m_renderSize.y());
+               DrawCallData                    drawCallData(vertices);
+               VulkanProgram                   vulkanProgram(shaders);
+
+               drawState.numSamples                            = m_samples;
+               drawState.sampleShadingEnable           = true;
+               vulkanProgram.descriptorSetLayout       = descriptorSetLayout;
+               vulkanProgram.descriptorSet                     = descriptorSet;
+
+               VulkanDrawContext               vulkanDrawContext(m_context, drawState, drawCallData, vulkanProgram);
+               vulkanDrawContext.draw();
+       }
+
+       // Transfer marker buffer
+       {
+               const UVec2 copySize            = UVec2(m_renderSize.x() * m_samples, m_renderSize.y());
+               const VkImageMemoryBarrier imageBarrier =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType              sType
+                       DE_NULL,                                                                                // const void*                  pNext
+                       VK_ACCESS_SHADER_WRITE_BIT,                                             // VkAccessFlags                srcAccessMask
+                       VK_ACCESS_TRANSFER_READ_BIT,                                    // VkAccessMask                 dstAccessMask
+                       VK_IMAGE_LAYOUT_GENERAL,                                                // VkImageLayout                oldLayout
+                       VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                   // VkImageLayout                newLayout
+                       VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             srcQueueFamilyIndex
+                       VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             dstQueueFamilyIndex
+                       *markerImage,                                                                   // VkImage                              image
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask
+                               0u,                                                                             // uint32_t                             baseMipLevel
+                               1u,                                                                             // uint32_t                             mipLevels
+                               0u,                                                                             // uint32_t                             baseArray
+                               1u                                                                              // uint32_t                             arraySize
+                       }
+               };
+
+               const VkBufferMemoryBarrier bufferBarrier =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                // VkStructureType              sType
+                       DE_NULL,                                                                                // const void*                  pNext
+                       VK_ACCESS_TRANSFER_WRITE_BIT,                                   // VkAccessFlags                srcAccessMask
+                       VK_ACCESS_HOST_READ_BIT,                                                // VkAccessFlags                dstAccessMask
+                       VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             srcQueueFamilyIndex
+                       VK_QUEUE_FAMILY_IGNORED,                                                // uint32_t                             dstQueueFamilyIndex
+                       *markerBuffer,                                                                  // VkBufer                              buffer
+                       0u,                                                                                             // VkDeviceSize                 offset
+                       VK_WHOLE_SIZE                                                                   // VkDeviceSize                 size
+               };
+
+               const VkBufferImageCopy bufferImageCopy =
+               {
+                       0u,                                                                     // VkDeviceSize         bufferOffset
+                       copySize.x(),                                           // uint32_t                     bufferRowLength
+                       copySize.y(),                                           // uint32_t                     bufferImageHeight
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,      // VkImageAspectFlags   aspect
+                               0u,                                                     // uint32_t                             mipLevel
+                               0u,                                                     // uint32_t                             baseArrayLayer
+                               1u                                                      // uint32_t                             layerCount
+                       },
+                       { 0, 0, 0 },                                            // VkOffset3D           imageOffset
+                       {
+                               copySize.x(),                           // uint32_t                             width
+                               copySize.y(),                           // uint32_t                             height,
+                               1u                                                      // uint32_t                             depth
+                       }
+               };
+
+               const VkCommandBufferBeginInfo  cmdBufferBeginInfo =
+               {
+                       VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType
+                       DE_NULL,                                                                                // const void*                                          pNext
+                       VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags
+                       (const VkCommandBufferInheritanceInfo*)DE_NULL  // VkCommandBufferInheritanceInfo       pInheritanceInfo
+               };
+
+               VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo));
+               vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                               (VkDependencyFlags)0,
+                               0, (const VkMemoryBarrier*)DE_NULL,
+                               0, (const VkBufferMemoryBarrier*)DE_NULL,
+                               1, &imageBarrier);
+               vk.cmdCopyImageToBuffer(*transferCmdBuffer, *markerImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *markerBuffer, 1u, &bufferImageCopy);
+               vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
+                               (VkDependencyFlags)0,
+                               0, (const VkMemoryBarrier*)DE_NULL,
+                               1, &bufferBarrier,
+                               0, (const VkImageMemoryBarrier*)DE_NULL);
+               VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer));
+
+               const VkSubmitInfo submitInfo =
+               {
+                       VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                      sType
+                       DE_NULL,                                                                // const void*                          pNext
+                       0u,                                                                             // uint32_t                                     waitSemaphoreCount
+                       DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores
+                       (const VkPipelineStageFlags*)DE_NULL,   // const VkPipelineStageFlags*  pWaitDstStageMask
+                       1u,                                                                             // uint32_t                                     commandBufferCount
+                       &transferCmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers
+                       0u,                                                                             // uint32_t                                     signalSemaphoreCount
+                       DE_NULL                                                                 // const VkSemaphore*           pSignalSemaphores
+               };
+
+               VK_CHECK(vk.resetFences(device, 1, &fence.get()));
+               VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
+               VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull)));
+       }
+
+       // Verify depth buffer
+       {
+               bool status;
+
+               const VkBufferMemoryBarrier bufferBarrier =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,                        // VkStructureType              sType
+                       DE_NULL,                                                                                        // const void*                  pNext
+                       VK_ACCESS_TRANSFER_WRITE_BIT,                                           // VkAccessFlags                srcAccessMask
+                       VK_ACCESS_HOST_READ_BIT,                                                        // VkAccessFlags                dstAccessMask
+                       VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             srcQueueFamilyIndex
+                       VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             dstQueueFamilyIndex
+                       *validationBuffer,                                                                      // VkBuffer                             buffer
+                       0u,                                                                                                     // VkDeviceSize                 offset
+                       VK_WHOLE_SIZE                                                                           // VkDeviceSize                 size
+               };
+
+               const VkImageMemoryBarrier imageBarrier =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType              sType
+                       DE_NULL,                                                                                        // const void*                  pNext
+                       VK_ACCESS_SHADER_WRITE_BIT,                                                     // VkAccessFlags                srcAccessMask
+                       VK_ACCESS_TRANSFER_READ_BIT,                                            // VkAccessFlags                dstAccessMask
+                       VK_IMAGE_LAYOUT_GENERAL,                                                        // VkImageLayout                oldLayout
+                       VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                           // VkImageLayout                newLayout
+                       VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             srcQueueFamilyIndex
+                       VK_QUEUE_FAMILY_IGNORED,                                                        // uint32_t                             dstQueueFamilyIndex
+                       *depthResolveImage,                                                                     // VkImage                              image
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspectMask
+                               0u,                                                                             // uint32_t                             baseMipLevel
+                               1u,                                                                             // uint32_t                             mipLevels,
+                               0u,                                                                             // uint32_t                             baseArray
+                               1u,                                                                             // uint32_t                             arraySize
+                       }
+               };
+
+               const VkBufferImageCopy bufferImageCopy =
+               {
+                       0u,                                                                                                     // VkDeviceSize                 bufferOffset
+                       m_samples * m_renderSize.x(),                                           // uint32_t                             bufferRowLength
+                       m_renderSize.y(),                                                                       // uint32_t                             bufferImageHeight
+                       {
+                               VK_IMAGE_ASPECT_COLOR_BIT,                              // VkImageAspectFlags   aspect
+                               0u,                                                                             // uint32_t                             mipLevel
+                               0u,                                                                             // uint32_t                             baseArrayLayer
+                               1u                                                                              // uint32_t                             layerCount
+                       },
+                       { 0, 0, 0 },                                                                            // VkOffset3D                   imageOffset
+                       {
+                               m_samples * m_renderSize.x(),                   // uint32_t                             width
+                               m_renderSize.y(),                                               // uint32_t                             height
+                               1u                                                                              // uint32_t                             depth
+                       }
+               };
+
+               const VkCommandBufferBeginInfo  cmdBufferBeginInfo =
+               {
+                       VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType
+                       DE_NULL,                                                                                // const void*                                          pNext
+                       VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,    // VkCommandBufferUsageFlags            flags
+                       (const VkCommandBufferInheritanceInfo*)DE_NULL  // VkCommandBufferInheritanceInfo       pInheritanceInfo
+               };
+
+               VK_CHECK(vk.beginCommandBuffer(*transferCmdBuffer, &cmdBufferBeginInfo));
+               vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
+                               (VkDependencyFlags)0,
+                               0, (const VkMemoryBarrier*)DE_NULL,
+                               0, (const VkBufferMemoryBarrier*)DE_NULL,
+                               1, &imageBarrier);
+               vk.cmdCopyImageToBuffer(*transferCmdBuffer, *depthResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *validationBuffer, 1u, &bufferImageCopy);
+               vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
+                               (VkDependencyFlags)0,
+                               0, (const VkMemoryBarrier*)DE_NULL,
+                               1, &bufferBarrier,
+                               0, (const VkImageMemoryBarrier*)DE_NULL);
+               VK_CHECK(vk.endCommandBuffer(*transferCmdBuffer));
+
+               const VkSubmitInfo submitInfo =
+               {
+                       VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                      sType
+                       DE_NULL,                                                                // const void*                          pNext
+                       0u,                                                                             // uint32_t                                     waitSemaphoreCount
+                       DE_NULL,                                                                // const VkSemaphore*           pWaitSemaphores
+                       (const VkPipelineStageFlags*)DE_NULL,   // const VkPipelineStageFlags*  pWaitDstStageMask
+                       1u,                                                                             // uint32_t                                     commandBufferCount
+                       &transferCmdBuffer.get(),                               // const VkCommandBuffer*       pCommandBuffers
+                       0u,                                                                             // uint32_t                                     signalSemaphoreCount
+                       DE_NULL                                                                 // const VkSemaphore*           pSignalSemaphores
+               };
+
+               VK_CHECK(vk.resetFences(device, 1, &fence.get()));
+               VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
+               VK_CHECK(vk.waitForFences(device, 1, &fence.get(), true, ~(0ull)));
+
+               invalidateMappedMemoryRange(vk, device, validationAlloc->getMemory(), validationAlloc->getOffset(), VK_WHOLE_SIZE);
+               invalidateMappedMemoryRange(vk, device, markerBufferAllocation->getMemory(), markerBufferAllocation->getOffset(), VK_WHOLE_SIZE);
+
+               tcu::ConstPixelBufferAccess resultPixelBuffer(mapVkFormat(VK_FORMAT_R32_SFLOAT), m_renderSize.x() * m_samples, m_renderSize.y(), 1u, validationAlloc->getHostPtr());
+               tcu::ConstPixelBufferAccess markerPixelBuffer(mapVkFormat(VK_FORMAT_R8G8B8A8_UINT), m_renderSize.x() * m_samples, m_renderSize.y(), 1u, markerBufferAllocation->getHostPtr());
+               status = validateDepthBuffer(resultPixelBuffer, markerPixelBuffer, 0.001f);
+               testDesc = "gl_FragDepth " + getPrimitiveTopologyShortName(m_topology) + " ";
+               if (status)
+               {
+                       testDesc += "passed";
+                       return tcu::TestStatus::pass(testDesc.c_str());
+               }
+               else
+               {
+                       log << TestLog::Image("resultDepth", "Result Depth Buffer", resultPixelBuffer);
+                       testDesc += "failed";
+                       return tcu::TestStatus::fail(testDesc.c_str());
+               }
+       }
+}
+
+bool BuiltinFragDepthCaseInstance::validateDepthBuffer (const tcu::ConstPixelBufferAccess& validationBuffer, const tcu::ConstPixelBufferAccess& markerBuffer, const float tolerance) const
+{
+       TestLog& log = m_context.getTestContext().getLog();
+
+       for (deUint32 rowNdx = 0; rowNdx < m_renderSize.y(); rowNdx++)
+       {
+               for (deUint32 colNdx = 0; colNdx < m_renderSize.x(); colNdx++)
+               {
+                       const float multiplier          = m_depthClampEnable ? 0.0f : 1.0f;
+                       float expectedValue     = (float)(rowNdx * m_renderSize.x() + colNdx)/256.0f * multiplier;
+
+                       if (m_largeDepthEnable)
+                               expectedValue += m_largeDepthBase;
+
+                       if (expectedValue > 1.0f)
+                               expectedValue = 1.0f;
+
+                       if (expectedValue < 0.0f)
+                               expectedValue = 0.0f;
+
+                       for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_samples; sampleNdx++)
+                       {
+                               const float     actualValue             = validationBuffer.getPixel(sampleNdx + m_samples * colNdx, rowNdx).x();
+                               const float     markerValue             = markerBuffer.getPixel(sampleNdx + m_samples * colNdx, rowNdx).x();
+
+                               if (markerValue != 0)
+                               {
+                                       if (de::abs(expectedValue - actualValue) > tolerance)
+                                       {
+                                               log << TestLog::Message << "Mismatch at pixel (" << colNdx << "," << rowNdx << "," << sampleNdx << "): expected " << expectedValue << " but got " << actualValue << TestLog::EndMessage;
+                                               return false;
+                                       }
+                               }
+                               else
+                               {
+                                       if (de::abs(actualValue - m_defaultDepthValue) > tolerance)
+                                       {
+                                               log << TestLog::Message << "Mismatch at pixel (" << colNdx << "," << rowNdx << "," << sampleNdx << "): expected " << expectedValue << " but got " << actualValue << TestLog::EndMessage;
+                                               return false;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return true;
+}
+
+class BuiltinFragDepthCase : public TestCase
+{
+public:
+                                       BuiltinFragDepthCase            (TestContext& testCtx, const char* name, const char* description, VkPrimitiveTopology topology,  VkFormat format, bool largeDepthEnable, bool depthClampEnable, const VkSampleCountFlagBits samples);
+       virtual                 ~BuiltinFragDepthCase           (void);
+
+       void                    initPrograms                            (SourceCollections& dst) const;
+       TestInstance*   createInstance                          (Context& context) const;
+
+private:
+       const VkPrimitiveTopology               m_topology;
+       const VkFormat                                  m_format;
+       const bool                                              m_largeDepthEnable;
+       const float                                             m_defaultDepth;
+       const bool                                              m_depthClampEnable;
+       const VkSampleCountFlagBits             m_samples;
+};
+
+BuiltinFragDepthCase::BuiltinFragDepthCase (TestContext& testCtx, const char* name, const char* description, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, bool depthClampEnable, const VkSampleCountFlagBits  samples)
+       : TestCase                              (testCtx, name, description)
+       , m_topology                    (topology)
+       , m_format                              (format)
+       , m_largeDepthEnable    (largeDepthEnable)
+       , m_defaultDepth                (0.0f)
+       , m_depthClampEnable    (depthClampEnable)
+       , m_samples                             (samples)
+{
+}
+
+BuiltinFragDepthCase::~BuiltinFragDepthCase(void)
+{
+}
+
+void BuiltinFragDepthCase::initPrograms (SourceCollections& programCollection) const
+{
+       // Vertex
+       {
+               // Pass 1
+               {
+                       std::ostringstream vertexSource;
+                       vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                               << "\n"
+                               <<  "layout (location = 0) in vec4 position;\n"
+                               << "void main()\n"
+                               << "{\n"
+                               << "    gl_Position = position;\n"
+                               << "}\n";
+                       programCollection.glslSources.add("FragDepthVert") << glu::VertexSource(vertexSource.str());
+               }
+
+               // Pass 2
+               {
+                       std::ostringstream vertexSource;
+                       vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                               << "\n"
+                               <<  "layout (location = 0) in vec4 position;\n"
+                               <<  "layout (location = 1) out vec2 texCoord;\n"
+                               << "void main()\n"
+                               << "{\n"
+                               << "    gl_Position = position;\n"
+                               << "    texCoord = position.xy/2 + vec2(0.5);\n"
+                               << "}\n";
+                       programCollection.glslSources.add("FragDepthVertPass2") << glu::VertexSource(vertexSource.str());
+               }
+       }
+
+       // Fragment
+       {
+               // Pass 1
+               {
+                       std::ostringstream      fragmentSource;
+                       fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                               << "\n"
+                               << "layout(location = 0) out mediump vec4 color;\n"
+                               << "layout (std140, set = 0, binding = 0) uniform control_buffer_t\n"
+                               << "{\n"
+                               << "    float data[256];\n"
+                               << "} control_buffer;\n"
+                               << "layout (set = 0, binding = 1, rgba8ui) writeonly uniform uimage2D storageImage;\n"
+                               << "float controlDepthValue;\n"
+                               << "void recheck(float controlDepthValue)\n"
+                               << "{\n"
+                               << "    if (gl_FragDepth != controlDepthValue)\n"
+                               << "            gl_FragDepth = 1.0;\n"
+                               << "}\n"
+                               << "void main()\n"
+                               << "{\n"
+                               << "    const int numSamples = " << m_samples << ";\n"
+                               << "    if (int(gl_FragCoord.x) == " << BuiltinFragDepthCaseInstance::RENDERWIDTH/4 << ")\n"
+                               << "            discard;\n"
+                               << "    highp int index =int(gl_FragCoord.y) * " << BuiltinFragDepthCaseInstance::RENDERHEIGHT << " + int(gl_FragCoord.x);\n"
+                               << "    controlDepthValue = control_buffer.data[index];\n"
+                               << "    gl_FragDepth = controlDepthValue;\n"
+                               << "    const int sampleNdx = int(gl_SampleID);\n"
+                               << "    ivec2 imageCoord = ivec2(sampleNdx + int(gl_FragCoord.x) * " << m_samples << ", int(gl_FragCoord.y));\n"
+                               << "    imageStore(storageImage, imageCoord, uvec4(1));\n"
+                               << "    recheck(controlDepthValue);\n"
+                               << "    color = vec4(1.0, 0.0, 0.0, 1.0);\n"
+                               << "}\n";
+                       programCollection.glslSources.add("FragDepthFrag") << glu::FragmentSource(fragmentSource.str());
+               }
+
+               // Pass 2
+               {
+                       const char* multisampleDecoration = m_samples != VK_SAMPLE_COUNT_1_BIT ? "MS" : "";
+                       std::ostringstream fragmentSource;
+                       fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                               << "\n"
+                               << "layout (location = 0) out mediump vec4 color;\n"
+                               << "layout (location = 1) in vec2 texCoord;\n"
+                               << "layout (binding = 0, set = 0) uniform sampler2D" << multisampleDecoration << " u_depthTex;\n"
+                               << "layout (binding = 1, set = 0, r32f) writeonly uniform image2D u_outImage;\n"
+                               << "void main (void)\n"
+                               << "{\n"
+                               << "    const int numSamples = " << m_samples << ";\n"
+                               << "    const int sampleNdx = int(gl_SampleID);\n"
+                               << "    ivec2 renderSize = ivec2(" << BuiltinFragDepthCaseInstance::RENDERWIDTH << "," << BuiltinFragDepthCaseInstance::RENDERHEIGHT << ");\n"
+                               << "    ivec2 imageCoord = ivec2(int(texCoord.x * renderSize.x), int(texCoord.y * renderSize.y));\n"
+                               << "    vec4 depthVal = texelFetch(u_depthTex, imageCoord, sampleNdx);\n"
+                               << "    imageStore(u_outImage, ivec2(sampleNdx + int(texCoord.x * renderSize.x) * numSamples, int(texCoord.y * renderSize.y)), depthVal);\n"
+                               << "    color = vec4(1.0, 0.0, 0.0, 1.0);\n"
+                               << "}\n";
+                       programCollection.glslSources.add("FragDepthFragPass2") << glu::FragmentSource(fragmentSource.str());
+               }
+       }
+}
+
+TestInstance* BuiltinFragDepthCase::createInstance (Context& context) const
+{
+       return new BuiltinFragDepthCaseInstance(context, m_topology, m_format, m_largeDepthEnable, m_defaultDepth, m_depthClampEnable, m_samples);
+}
+
 class BuiltinGlFragCoordXYZCaseInstance : public ShaderRenderCaseInstance
 {
 public:
@@ -900,6 +2039,7 @@ TestCaseGroup* createBuiltinVarTests (TestContext& testCtx)
        de::MovePtr<TestCaseGroup> simpleGroup                  (new TestCaseGroup(testCtx, "simple", "Simple cases."));
        de::MovePtr<TestCaseGroup> inputVariationsGroup (new TestCaseGroup(testCtx, "input_variations", "Input type variation tests."));
        de::MovePtr<TestCaseGroup> frontFacingGroup             (new TestCaseGroup(testCtx, "frontfacing", "Test gl_Frontfacing keyword."));
+       de::MovePtr<TestCaseGroup> fragDepthGroup               (new TestCaseGroup(testCtx, "fragdepth", "Test gl_FragDepth keyword."));
 
        simpleGroup->addChild(new BuiltinGlFragCoordXYZCase(testCtx, "fragcoord_xyz", "FragCoord xyz test"));
        simpleGroup->addChild(new BuiltinGlFragCoordWCase(testCtx, "fragcoord_w", "FragCoord w test"));
@@ -925,7 +2065,57 @@ TestCaseGroup* createBuiltinVarTests (TestContext& testCtx)
                        frontFacingGroup->addChild(new BuiltinGlFrontFacingCase(testCtx, frontfacingCases[ndx].primitive, frontfacingCases[ndx].name, frontfacingCases[ndx].desc));
        }
 
+       // gl_FragDepth
+       {
+               static const struct PrimitiveTopologyTable
+               {
+                       std::string                     name;
+                       std::string                     desc;
+                       VkPrimitiveTopology     prim;
+               } primitiveTopologyTable[] =
+               {
+                       { "point_list",         "test that points respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_POINT_LIST },
+                       { "line_list",          "test taht lines respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_LINE_LIST },
+                       { "triangle_list",      "test that triangles respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP },
+               };
+
+               static const struct TestCaseTable
+               {
+                       VkFormat                                format;
+                       std::string                             name;
+                       bool                                    largeDepthEnable;
+                       bool                                    depthClampEnable;
+                       VkSampleCountFlagBits   samples;
+               } testCaseTable[] =
+               {
+                       { VK_FORMAT_D16_UNORM,                          "d16_unorm_no_depth_clamp",                             false,  false,  VK_SAMPLE_COUNT_1_BIT },
+                       { VK_FORMAT_X8_D24_UNORM_PACK32,        "x8_d24_unorm_pack32_no_depth_clamp",   false,  false,  VK_SAMPLE_COUNT_1_BIT },
+                       { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_no_depth_clamp",                    false,  false,  VK_SAMPLE_COUNT_1_BIT },
+                       { VK_FORMAT_D16_UNORM_S8_UINT,          "d16_unorm_s8_uint_no_depth_clamp",             false,  false,  VK_SAMPLE_COUNT_1_BIT },
+                       { VK_FORMAT_D24_UNORM_S8_UINT,          "d24_unorm_s8_uint_no_depth_clamp",             false,  false,  VK_SAMPLE_COUNT_1_BIT },
+                       { VK_FORMAT_D32_SFLOAT_S8_UINT,         "d32_sfloat_s8_uint_no_depth_clamp",    false,  false,  VK_SAMPLE_COUNT_1_BIT },
+                       { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_large_depth",                               true,   false,  VK_SAMPLE_COUNT_1_BIT },
+                       { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat",                                                   false,  true,   VK_SAMPLE_COUNT_1_BIT },
+                       { VK_FORMAT_D32_SFLOAT_S8_UINT,         "d32_sfloat_s8_uint",                                   false,  true,   VK_SAMPLE_COUNT_1_BIT },
+                       { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_multisample_2",                             false,  false,  VK_SAMPLE_COUNT_2_BIT },
+                       { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_multisample_4",                             false,  false,  VK_SAMPLE_COUNT_4_BIT },
+                       { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_multisample_8",                             false,  false,  VK_SAMPLE_COUNT_8_BIT },
+                       { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_multisample_16",                    false,  false,  VK_SAMPLE_COUNT_16_BIT },
+                       { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_multisample_32",                    false,  false,  VK_SAMPLE_COUNT_32_BIT },
+                       { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat_multisample_64",                    false,  false,  VK_SAMPLE_COUNT_64_BIT },
+               };
+
+               for (deUint32 primNdx = 0;  primNdx < DE_LENGTH_OF_ARRAY(primitiveTopologyTable); primNdx++)
+               {
+                       for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(testCaseTable); caseNdx++)
+                               fragDepthGroup->addChild(new BuiltinFragDepthCase(testCtx, (primitiveTopologyTable[primNdx].name+"_" + testCaseTable[caseNdx].name).c_str(), primitiveTopologyTable[primNdx].desc.c_str(),
+                                                       primitiveTopologyTable[primNdx].prim, testCaseTable[caseNdx].format, testCaseTable[caseNdx].largeDepthEnable, testCaseTable[caseNdx].depthClampEnable, testCaseTable[caseNdx].samples));
+
+               }
+       }
+
        builtinGroup->addChild(frontFacingGroup.release());
+       builtinGroup->addChild(fragDepthGroup.release());
        builtinGroup->addChild(simpleGroup.release());
 
        for (deUint16 shaderType = 0; shaderType <= (SHADER_INPUT_BUILTIN_BIT | SHADER_INPUT_VARYING_BIT | SHADER_INPUT_CONSTANT_BIT); ++shaderType)
index 7eb0a21..1642299 100644 (file)
 #include "vkImageWithMemory.hpp"
 #include "vkTypeUtil.hpp"
 #include "rrRenderer.hpp"
+#include "rrRenderState.hpp"
 #include "rrPrimitiveTypes.hpp"
 #include "tcuTextureUtil.hpp"
 #include "deArrayUtil.hpp"
+#include "vkBuilderUtil.hpp"
 #include "tcuTestLog.hpp"
 
 namespace vkt
@@ -42,6 +44,24 @@ using namespace de;
 using namespace tcu;
 using namespace vk;
 
+static VkCompareOp mapCompareOp (rr::TestFunc compareFunc)
+{
+       switch (compareFunc)
+       {
+               case rr::TESTFUNC_NEVER:                                return VK_COMPARE_OP_NEVER;
+               case rr::TESTFUNC_LESS:                                 return VK_COMPARE_OP_LESS;
+               case rr::TESTFUNC_EQUAL:                                return VK_COMPARE_OP_EQUAL;
+               case rr::TESTFUNC_LEQUAL:                               return VK_COMPARE_OP_LESS_OR_EQUAL;
+               case rr::TESTFUNC_GREATER:                              return VK_COMPARE_OP_GREATER;
+               case rr::TESTFUNC_NOTEQUAL:                             return VK_COMPARE_OP_NOT_EQUAL;
+               case rr::TESTFUNC_GEQUAL:                               return VK_COMPARE_OP_GREATER_OR_EQUAL;
+               case rr::TESTFUNC_ALWAYS:                               return VK_COMPARE_OP_ALWAYS;
+               default:
+                       DE_ASSERT(false);
+       }
+       return VK_COMPARE_OP_LAST;
+}
+
 rr::PrimitiveType mapVkPrimitiveToRRPrimitive(const vk::VkPrimitiveTopology& primitiveTopology)
 {
        static const rr::PrimitiveType primitiveTypeTable[] =
@@ -289,9 +309,14 @@ DrawState::DrawState(const vk::VkPrimitiveTopology topology_, deUint32 renderWid
        , colorFormat                   (VK_FORMAT_R8G8B8A8_UNORM)
        , renderSize                    (tcu::UVec2(renderWidth_, renderHeight_))
        , depthClampEnable              (false)
+       , depthTestEnable               (false)
+       , depthWriteEnable              (false)
+       , compareOp                             (rr::TESTFUNC_LESS)
        , blendEnable                   (false)
        , lineWidth                             (1.0)
        , numPatchControlPoints (0)
+       , numSamples                    (VK_SAMPLE_COUNT_1_BIT)
+       , sampleShadingEnable   (false)
 {
        DE_ASSERT(renderSize.x() != 0 && renderSize.y() != 0);
 }
@@ -339,7 +364,7 @@ tcu::ConstPixelBufferAccess ReferenceDrawContext::getColorPixels (void) const
 VulkanDrawContext::VulkanDrawContext (  Context&                               context,
                                                                                const DrawState&                drawState,
                                                                                const DrawCallData&             drawCallData,
-                                                                               const VulkanProgram&    vulkanProgram)
+                                                                               VulkanProgram&  vulkanProgram)
        : DrawContext                                           (drawState, drawCallData)
        , m_context                                                     (context)
        , m_program                                                     (vulkanProgram)
@@ -348,6 +373,7 @@ VulkanDrawContext::VulkanDrawContext (  Context&                            context,
        const VkDevice                  device                                  = m_context.getDevice();
        Allocator&                              allocator                               = m_context.getDefaultAllocator();
        VkImageSubresourceRange colorSubresourceRange;
+       Move<VkSampler>                 sampler;
 
        // Command buffer
        {
@@ -369,11 +395,11 @@ VulkanDrawContext::VulkanDrawContext (  Context&                          context,
                        makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u),       // VkExtent3D                           extent;
                        1u,                                                                                                                                                     // uint32_t                                     mipLevels;
                        1u,                                                                                                                                                     // uint32_t                                     arrayLayers;
-                       VK_SAMPLE_COUNT_1_BIT,                                                                                                          // VkSampleCountFlagBits        samples;
+                       (VkSampleCountFlagBits)m_drawState.numSamples,                                                          // VkSampleCountFlagBits        samples;
                        VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
                        usage,                                                                                                                                          // VkImageUsageFlags            usage;
                        VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
-                       VK_QUEUE_FAMILY_IGNORED,                                                                                                        // uint32_t                                     queueFamilyIndexCount;
+                       0u,                                                                                                                                                     // uint32_t                                     queueFamilyIndexCount;
                        DE_NULL,                                                                                                                                        // const uint32_t*                      pQueueFamilyIndices;
                        VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                        initialLayout;
                };
@@ -405,38 +431,65 @@ VulkanDrawContext::VulkanDrawContext (  Context&                          context,
                flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bufferSize);
        }
 
-       // Pipeline layout
+       // bind descriptor sets
        {
-               m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
+               if (!vulkanProgram.descriptorSetLayout)
+                       m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device);
+               else
+                       m_pipelineLayout = makePipelineLayout(vk, device, vulkanProgram.descriptorSetLayout.get());
        }
 
        // Renderpass
        {
-               const VkAttachmentDescription colorAttachmentDescription =
+               std::vector<VkAttachmentDescription> attachmentDescriptions;
+               const VkAttachmentDescription attachDescriptors[] =
                {
-                       (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
-                       m_drawState.colorFormat,                                                        // VkFormat                                                     format;
-                       VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
-                       VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
-                       VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
-                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
-                       VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
-                       VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                        initialLayout;
-                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
+                       {
+                               (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
+                               m_drawState.colorFormat,                                                        // VkFormat                                                     format;
+                               (VkSampleCountFlagBits)m_drawState.numSamples,          // VkSampleCountFlagBits                        samples;
+                               VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
+                               VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
+                               VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
+                               VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
+                               VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                        initialLayout;
+                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        finalLayout;
+                       },
+                       {
+                               (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags
+                               m_drawState.depthFormat,                                                        // VkFormat                                                     format
+                               (VkSampleCountFlagBits)m_drawState.numSamples,          // VkSampleCountFlagBits                        samples
+                               VK_ATTACHMENT_LOAD_OP_LOAD,                                                     // VkAttachmentLoadOp                           loadOp
+                               VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp
+                               VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp
+                               VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp
+                               VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                        initialLayout
+                               VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        finalLayout
+
+                       }
                };
 
-               const VkAttachmentReference colorAttachmentReference =
+               const VkAttachmentReference attachmentReferences[] =
                {
-                       0u,                                                                                                     // deUint32                     attachment;
-                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
+                       {
+                               0u,                                                                                                     // uint32_t                     attachment
+                               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout
+                       },
+                       {
+                               1u,                                                                                                     // uint32_t                     attachment
+                               VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL        // VkImageLayout        layout
+                       },
+                       {
+                               VK_ATTACHMENT_UNUSED,                                                           // deUint32         attachment;
+                               VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout    layout;
+                       }
                };
 
-               const VkAttachmentReference depthAttachmentReference =
-               {
-                       VK_ATTACHMENT_UNUSED,                                                           // deUint32                     attachment;
-                       VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout        layout;
-               };
+               attachmentDescriptions.push_back(attachDescriptors[0]);
+               if (vulkanProgram.depthImageView)
+                       attachmentDescriptions.push_back(attachDescriptors[1]);
 
+               deUint32 depthReferenceNdx = vulkanProgram.depthImageView ? 1 : 2;
                const VkSubpassDescription subpassDescription =
                {
                        (VkSubpassDescriptionFlags)0,                                           // VkSubpassDescriptionFlags            flags;
@@ -444,9 +497,9 @@ VulkanDrawContext::VulkanDrawContext (  Context&                            context,
                        0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
                        DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
                        1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
-                       &colorAttachmentReference,                                                      // const VkAttachmentReference*         pColorAttachments;
+                       &attachmentReferences[0],                                                       // const VkAttachmentReference*         pColorAttachments;
                        DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
-                       &depthAttachmentReference,                                                      // const VkAttachmentReference*         pDepthStencilAttachment;
+                       &attachmentReferences[depthReferenceNdx],                       // const VkAttachmentReference*         pDepthStencilAttachment;
                        0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
                        DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
                };
@@ -456,8 +509,8 @@ VulkanDrawContext::VulkanDrawContext (  Context&                            context,
                        VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
                        DE_NULL,                                                                                        // const void*                                          pNext;
                        (VkRenderPassCreateFlags)0,                                                     // VkRenderPassCreateFlags                      flags;
-                       1u,                                                                                                     // deUint32                                                     attachmentCount;
-                       &colorAttachmentDescription,                                            // const VkAttachmentDescription*       pAttachments;
+                       (deUint32)attachmentDescriptions.size(),                        // deUint32                                                     attachmentCount;
+                       &attachmentDescriptions[0],                                                     // const VkAttachmentDescription*       pAttachments;
                        1u,                                                                                                     // deUint32                                                     subpassCount;
                        &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
                        0u,                                                                                                     // deUint32                                                     dependencyCount;
@@ -469,18 +522,20 @@ VulkanDrawContext::VulkanDrawContext (  Context&                          context,
 
        // Framebuffer
        {
-               const VkImageView attachmentBindInfos[] =
-               {
-                       m_colorImageView.get()
-               };
+               std::vector<VkImageView>        attachmentBindInfos;
+               deUint32                                        numAttachments;
+               attachmentBindInfos.push_back(*m_colorImageView);
+               if (vulkanProgram.depthImageView)
+                       attachmentBindInfos.push_back(*vulkanProgram.depthImageView);
 
+               numAttachments = (deUint32)(attachmentBindInfos.size());
                const VkFramebufferCreateInfo framebufferInfo = {
                        VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,              // VkStructureType                                              sType;
                        DE_NULL,                                                                                // const void*                                                  pNext;
                        (VkFramebufferCreateFlags)0,                                    // VkFramebufferCreateFlags                             flags;
                        *m_renderPass,                                                                  // VkRenderPass                                                 renderPass;
-                       DE_LENGTH_OF_ARRAY(attachmentBindInfos),                // uint32_t                                                             attachmentCount;
-                       attachmentBindInfos,                                                    // const VkImageView*                                   pAttachments;
+                       numAttachments,                                                                 // uint32_t                                                             attachmentCount;
+                       &attachmentBindInfos[0],                                                // const VkImageView*                                   pAttachments;
                        m_drawState.renderSize.x(),                                             // uint32_t                                                             width;
                        m_drawState.renderSize.y(),                                             // uint32_t                                                             height;
                        1u,                                                                                             // uint32_t                                                             layers;
@@ -581,9 +636,9 @@ VulkanDrawContext::VulkanDrawContext (  Context&                            context,
                        VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
                        DE_NULL,                                                                                                        // const void*                                                          pNext;
                        (VkPipelineMultisampleStateCreateFlags)0,                                       // VkPipelineMultisampleStateCreateFlags        flags;
-                       VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
-                       VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
-                       0.0f,                                                                                                           // float                                                                        minSampleShading;
+                       (VkSampleCountFlagBits)m_drawState.numSamples,                          // VkSampleCountFlagBits                                        rasterizationSamples;
+                       m_drawState.sampleShadingEnable ? VK_TRUE : VK_FALSE,           // VkBool32                                                                     sampleShadingEnable;
+                       m_drawState.sampleShadingEnable ? 1.0f : 0.0f,                          // float                                                                        minSampleShading;
                        DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
                        VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
                        VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
@@ -603,10 +658,10 @@ VulkanDrawContext::VulkanDrawContext (  Context&                          context,
                        VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
                        DE_NULL,                                                                                                        // const void*                                                          pNext;
                        (VkPipelineDepthStencilStateCreateFlags)0,                                      // VkPipelineDepthStencilStateCreateFlags       flags;
-                       VK_FALSE,                                                                                                       // VkBool32                                                                     depthTestEnable;
-                       VK_FALSE,                                                                                                       // VkBool32                                                                     depthWriteEnable;
-                       VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
-                       VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
+                       m_drawState.depthTestEnable,                                                            // VkBool32                                                                     depthTestEnable;
+                       m_drawState.depthWriteEnable,                                                           // VkBool32                                                                     depthWriteEnable;
+                       mapCompareOp(m_drawState.compareOp),                                            // VkCompareOp                                                          depthCompareOp;
+                       VK_TRUE,                                                                                                        // VkBool32                                                                     depthBoundsTestEnable;
                        VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
                        stencilOpState,                                                                                         // VkStencilOpState                                                     front;
                        stencilOpState,                                                                                         // VkStencilOpState                                                     back;
@@ -700,10 +755,13 @@ VulkanDrawContext::VulkanDrawContext (  Context&                          context,
                const VkDeviceSize zeroOffset = 0ull;
 
                beginCommandBuffer(vk, *m_cmdBuffer);
+               if (vulkanProgram.descriptorSet)
+                       vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &*vulkanProgram.descriptorSet, 0u, DE_NULL);
 
                // Begin render pass
                {
-                       const VkClearValue      clearValue = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+                       const VkClearValue      clearValue      = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+
                        const VkRect2D          renderArea =
                        {
                                makeOffset2D(0, 0),
@@ -740,10 +798,67 @@ VulkanDrawContext::VulkanDrawContext (  Context&                          context,
                                0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
                }
 
+               // Resolve multisample image
                {
+                       if (m_drawState.numSamples != VK_SAMPLE_COUNT_1_BIT)
+                       {
+                               const VkImageResolve imageResolve =
+                               {
+                                       makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
+                                       { 0, 0, 0},
+                                       makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
+                                       { 0, 0, 0},
+                                       makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u)
+                               };
+
+                               const VkImageCreateInfo resolveImageCreateInfo =
+                               {
+                                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                            // VkStructureType                      sType
+                                       DE_NULL,                                                                                        // const void*                          pNext
+                                       (VkImageCreateFlags)0,                                                          // VkImageCreateFlags           flags
+                                       VK_IMAGE_TYPE_2D,                                                                       // VkImageType                          imageType
+                                       m_drawState.colorFormat,                                                        // VkFormat                                     format
+                                       makeExtent3D(m_drawState.renderSize.x(),                        // VkExtent3D                           extent;
+                                                       m_drawState.renderSize.y(), 1u),
+                                       1u,                                                                                                     // uint32_t                                     mipLevels
+                                       1u,                                                                                                     // uint32_t                                     arrayLayers
+                                       VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits        samples
+                                       VK_IMAGE_TILING_OPTIMAL,                                                        // VkImaageTiling                       tiling
+                                       VK_IMAGE_USAGE_TRANSFER_DST_BIT |                                       // VkImageUsageFlags            usage
+                                       VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
+                                       VK_SHARING_MODE_EXCLUSIVE,                                                      // VkSharingModeExclusive       sharingMode
+                                       0u,                                                                                                     // uint32_t                                     queueFamilyIndexCount
+                                       DE_NULL,                                                                                        // const uint32_t*                      pQueueFamilyIndices
+                                       VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout                        initialLayout
+                               };
+
+                               m_resolveImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, resolveImageCreateInfo, MemoryRequirement::Any));
+
+                               const VkImageMemoryBarrier resolveBarrier = makeImageMemoryBarrier(
+                                               0u, VK_ACCESS_TRANSFER_READ_BIT,
+                                               VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                                               **m_resolveImage, colorSubresourceRange);
+
+                               vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
+                                               0u, DE_NULL, 0u, DE_NULL, 1u, &resolveBarrier);
+
+                               vk.cmdResolveImage(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                                               **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &imageResolve);
+
+                               const VkImageMemoryBarrier barrier = makeImageMemoryBarrier(
+                                       VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
+                                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                       **m_resolveImage, colorSubresourceRange);
+
+                               vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0,
+                                       0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
+                       }
+                       else
+                               m_resolveImage = m_colorImage;
+
                        const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u),
                                        makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u));
-                       vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, &copyRegion);
+                       vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, &copyRegion);
                }
 
                // Barrier: copy to buffer -> host read
index d6bd65f..8e64ac0 100644 (file)
@@ -54,13 +54,19 @@ struct Shader
 
 struct DrawState
 {
-       const vk::VkPrimitiveTopology   topology;
-       const vk::VkFormat                              colorFormat;
+       vk::VkPrimitiveTopology                 topology;
+       vk::VkFormat                                    colorFormat;
+       vk::VkFormat                                    depthFormat;
        tcu::UVec2                                              renderSize;
        bool                                                    depthClampEnable;
+       bool                                                    depthTestEnable;
+       bool                                                    depthWriteEnable;
+       rr::TestFunc                                    compareOp;
        bool                                                    blendEnable;
        float                                                   lineWidth;
        deUint32                                                numPatchControlPoints;
+       deUint32                                                numSamples;
+       bool                                                    sampleShadingEnable;
 
        DrawState (const vk::VkPrimitiveTopology topology_, deUint32 renderWidth_, deUint32 renderHeight_);
 };
@@ -94,8 +100,8 @@ public:
        virtual void                                                    draw                                    (void) = 0;
        virtual tcu::ConstPixelBufferAccess             getColorPixels                  (void) const = 0;
 protected:
-               const DrawState                                         m_drawState;
-               const DrawCallData                                      m_drawCallData;
+               const DrawState&                                        m_drawState;
+               const DrawCallData&                                     m_drawCallData;
 };
 
 class ReferenceDrawContext : public DrawContext
@@ -121,7 +127,10 @@ private:
 
 struct VulkanProgram
 {
-       const std::vector<Shader>&                              shaders;
+       const std::vector<Shader>&                      shaders;
+       vk::Move<vk::VkImageView>                       depthImageView;
+       vk::Move<vk::VkDescriptorSetLayout>     descriptorSetLayout;
+       vk::Move<vk::VkDescriptorSet>           descriptorSet;
 
        VulkanProgram           (const std::vector<Shader>&                     shaders_)
                : shaders               (shaders_)
@@ -135,18 +144,19 @@ public:
                                                                                        VulkanDrawContext       (Context&                               context,
                                                                                                                                 const DrawState&               drawState,
                                                                                                                                 const DrawCallData&    drawCallData,
-                                                                                                                                const VulkanProgram&   vulkanProgram);
+                                                                                                                                VulkanProgram&                 vulkanProgram);
        virtual                                                                 ~VulkanDrawContext      (void);
        virtual void                                                    draw                            (void);
        virtual tcu::ConstPixelBufferAccess             getColorPixels          (void) const;
 private:
-       enum Contants
+       enum VulkanContants
        {
                MAX_NUM_SHADER_MODULES                                  = 5,
        };
        Context&                                                                        m_context;
-       VulkanProgram                                                           m_program;
+       VulkanProgram&                                                          m_program;
        de::MovePtr<vk::ImageWithMemory>                        m_colorImage;
+       de::MovePtr<vk::ImageWithMemory>                        m_resolveImage;
        de::MovePtr<vk::BufferWithMemory>                       m_colorAttachmentBuffer;
        vk::refdetails::Move<vk::VkImageView>           m_colorImageView;
        vk::refdetails::Move<vk::VkRenderPass>          m_renderPass;
index 6c97232..6ce5b49 100644 (file)
@@ -325,3 +325,6 @@ dEQP-VK.pipeline.render_to_image.*.small.r8g8b8a8_unorm_d32_sfloat_s8_uint
 dEQP-VK.pipeline.render_to_image.*.small.r32_uint_d32_sfloat_s8_uint
 dEQP-VK.pipeline.render_to_image.*.small.r16g16_sint_d32_sfloat_s8_uint
 dEQP-VK.pipeline.render_to_image.*.small.r32g32b32a32_sfloat_d32_sfloat_s8_uint
+
+#VK-GL-CTS 655
+dEQP-VK.glsl.builtin_var.fragdepth.*