From 39ad2eac87b83d18169667fdc9e3c45ac25d686c Mon Sep 17 00:00:00 2001 From: David Sodman Date: Fri, 24 Feb 2017 10:41:59 -0800 Subject: [PATCH] Add test for FragDepth shader built-in 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 | 3 + .../vktShaderRenderBuiltinVarTests.cpp | 1190 ++++++++++++++++++++ external/vulkancts/modules/vulkan/vktDrawUtil.cpp | 199 +++- external/vulkancts/modules/vulkan/vktDrawUtil.hpp | 26 +- .../mustpass/1.0.2/src/excluded-tests.txt | 3 + 5 files changed, 1371 insertions(+), 50 deletions(-) diff --git a/android/cts/master/src/vk-excluded-tests.txt b/android/cts/master/src/vk-excluded-tests.txt index 6c97232..6ce5b49 100644 --- a/android/cts/master/src/vk-excluded-tests.txt +++ b/android/cts/master/src/vk-excluded-tests.txt @@ -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.* diff --git a/external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderBuiltinVarTests.cpp b/external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderBuiltinVarTests.cpp index bc69299..bad106d 100644 --- a/external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderBuiltinVarTests.cpp +++ b/external/vulkancts/modules/vulkan/shaderrender/vktShaderRenderBuiltinVarTests.cpp @@ -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 depthResolveImage; + Move depthResolveImageView; + MovePtr depthResolveAllocation; + Move depthImage; + Move depthImageView; + MovePtr depthImageAllocation; + Move controlBuffer; + MovePtr controlBufferAllocation; + Move markerImage; + Move markerImageView; + MovePtr markerImageAllocation; + Move markerBuffer; + MovePtr markerBufferAllocation; + Move validationBuffer; + MovePtr validationAlloc; + MovePtr depthInitAllocation; + Move cmdPool; + Move transferCmdBuffer; + Move fence; + Move 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 vertices; + std::vector shaders; + Move descriptorSetLayout; + Move descriptorPool; + Move 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 vertices; + std::vector shaders; + Move descriptorSetLayout; + Move descriptorPool; + Move 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 simpleGroup (new TestCaseGroup(testCtx, "simple", "Simple cases.")); de::MovePtr inputVariationsGroup (new TestCaseGroup(testCtx, "input_variations", "Input type variation tests.")); de::MovePtr frontFacingGroup (new TestCaseGroup(testCtx, "frontfacing", "Test gl_Frontfacing keyword.")); + de::MovePtr 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) diff --git a/external/vulkancts/modules/vulkan/vktDrawUtil.cpp b/external/vulkancts/modules/vulkan/vktDrawUtil.cpp index 7eb0a21..1642299 100644 --- a/external/vulkancts/modules/vulkan/vktDrawUtil.cpp +++ b/external/vulkancts/modules/vulkan/vktDrawUtil.cpp @@ -28,9 +28,11 @@ #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 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 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 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(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, ©Region); + vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, ©Region); } // Barrier: copy to buffer -> host read diff --git a/external/vulkancts/modules/vulkan/vktDrawUtil.hpp b/external/vulkancts/modules/vulkan/vktDrawUtil.hpp index d6bd65f..8e64ac0 100644 --- a/external/vulkancts/modules/vulkan/vktDrawUtil.hpp +++ b/external/vulkancts/modules/vulkan/vktDrawUtil.hpp @@ -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& shaders; + const std::vector& shaders; + vk::Move depthImageView; + vk::Move descriptorSetLayout; + vk::Move descriptorSet; VulkanProgram (const std::vector& 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 m_colorImage; + de::MovePtr m_resolveImage; de::MovePtr m_colorAttachmentBuffer; vk::refdetails::Move m_colorImageView; vk::refdetails::Move m_renderPass; diff --git a/external/vulkancts/mustpass/1.0.2/src/excluded-tests.txt b/external/vulkancts/mustpass/1.0.2/src/excluded-tests.txt index 6c97232..6ce5b49 100644 --- a/external/vulkancts/mustpass/1.0.2/src/excluded-tests.txt +++ b/external/vulkancts/mustpass/1.0.2/src/excluded-tests.txt @@ -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.* -- 2.7.4