+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);
+}
+