Add tests for uploading depth/stencil
authorCourtney Goeltzenleuchter <courtneygo@google.com>
Tue, 13 Aug 2019 00:10:39 +0000 (18:10 -0600)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Wed, 23 Oct 2019 07:52:35 +0000 (03:52 -0400)
Components: Vulkan

Affects:
dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.*
dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.*

VK-GL-CTS issue: 1888
Change-Id: Id2153ef90014175f5b52811c80a905164e491735

android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/api/vktApiCopiesAndBlittingTests.cpp
external/vulkancts/mustpass/master/vk-default-no-waivers.txt
external/vulkancts/mustpass/master/vk-default.txt
framework/common/tcuImageCompare.cpp
framework/common/tcuImageCompare.hpp
framework/common/tcuTextureUtil.cpp
framework/common/tcuTextureUtil.hpp

index 4900278..a77b7b9 100644 (file)
@@ -24369,6 +24369,27 @@ dEQP-VK.api.copy_and_blit.core.buffer_to_image.regions
 dEQP-VK.api.copy_and_blit.core.buffer_to_image.buffer_offset
 dEQP-VK.api.copy_and_blit.core.buffer_to_image.tightly_sized_buffer
 dEQP-VK.api.copy_and_blit.core.buffer_to_image.tightly_sized_buffer_offset
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.x8_d24_unorm_pack32_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_DS
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_SD
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_DS
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_SD
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_DS
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_SD
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_D
 dEQP-VK.api.copy_and_blit.core.buffer_to_buffer.whole
 dEQP-VK.api.copy_and_blit.core.buffer_to_buffer.partial
 dEQP-VK.api.copy_and_blit.core.buffer_to_buffer.regions
@@ -78426,6 +78447,27 @@ dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_image.regions
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_image.buffer_offset
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_image.tightly_sized_buffer
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_image.tightly_sized_buffer_offset
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.x8_d24_unorm_pack32_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_DS
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_SD
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_DS
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_SD
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_DS
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_SD
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_D
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_buffer.whole
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_buffer.partial
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_buffer.regions
index 9668657..f17d6e9 100644 (file)
@@ -274,6 +274,7 @@ const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFor
        tcu::TextureFormat format;
        switch (combinedFormat.type)
        {
+               case tcu::TextureFormat::UNORM_INT16:
                case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
                        format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
                        break;
@@ -281,6 +282,7 @@ const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFor
                        format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
                        break;
                case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
+               case tcu::TextureFormat::FLOAT:
                        format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
                        break;
                default:
@@ -624,8 +626,16 @@ tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelB
        else
        {
                const tcu::UVec4 threshold (0u);
-               if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
-                       return tcu::TestStatus::fail("CopiesAndBlitting test");
+               if (tcu::hasDepthComponent(result.getFormat().order) || tcu::hasStencilComponent(result.getFormat().order))
+               {
+                       if (!tcu::dsThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, 0.1f, tcu::COMPARE_LOG_RESULT))
+                               return tcu::TestStatus::fail("CopiesAndBlitting test");
+               }
+               else
+               {
+                       if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
+                               return tcu::TestStatus::fail("CopiesAndBlitting test");
+               }
        }
 
        return tcu::TestStatus::pass("CopiesAndBlitting test");
@@ -1776,6 +1786,314 @@ void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess sr
        }
 }
 
+class CopyBufferToDepthStencil : public CopiesAndBlittingTestInstance
+{
+public:
+                                                               CopyBufferToDepthStencil        (Context& context,
+                                                                                                                        TestParams     testParams);
+       virtual tcu::TestStatus         iterate                                         (void);
+private:
+       virtual void                            copyRegionToTextureLevel        (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
+
+       tcu::TextureFormat                      m_textureFormat;
+       VkDeviceSize                            m_bufferSize;
+
+       Move<VkBuffer>                          m_source;
+       de::MovePtr<Allocation>         m_sourceBufferAlloc;
+       Move<VkImage>                           m_destination;
+       de::MovePtr<Allocation>         m_destinationImageAlloc;
+};
+
+void CopyBufferToDepthStencil::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
+{
+       DE_UNREF(mipLevel);
+
+       deUint32                        rowLength       = region.bufferImageCopy.bufferRowLength;
+       if (!rowLength)
+               rowLength = region.bufferImageCopy.imageExtent.width;
+
+       deUint32                        imageHeight = region.bufferImageCopy.bufferImageHeight;
+       if (!imageHeight)
+               imageHeight = region.bufferImageCopy.imageExtent.height;
+
+       const int                       texelSize       = dst.getFormat().getPixelSize();
+       const VkExtent3D        extent          = region.bufferImageCopy.imageExtent;
+       const VkOffset3D        dstOffset       = region.bufferImageCopy.imageOffset;
+       const int                       texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;
+
+       for (deUint32 z = 0; z < extent.depth; z++)
+       {
+               for (deUint32 y = 0; y < extent.height; y++)
+               {
+                       int                                                                     texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
+                       const tcu::ConstPixelBufferAccess       srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
+                       const tcu::PixelBufferAccess            dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
+                               region.bufferImageCopy.imageExtent.width, 1, 1);
+
+                       if (region.bufferImageCopy.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
+                       {
+                               tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_DEPTH), DE_FALSE);
+                       }
+                       else
+                       {
+                               tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_STENCIL), DE_FALSE);
+                       }
+               }
+       }
+}
+
+bool isSupportedDepthStencilFormat(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
+{
+       VkFormatProperties formatProps;
+       vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
+       return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
+}
+
+CopyBufferToDepthStencil::CopyBufferToDepthStencil(Context& context, TestParams testParams)
+       : CopiesAndBlittingTestInstance(context, testParams)
+       , m_textureFormat(mapVkFormat(testParams.dst.image.format))
+       , m_bufferSize(0)
+{
+       const InstanceInterface&        vki                                     = context.getInstanceInterface();
+       const DeviceInterface&          vk                                      = context.getDeviceInterface();
+       const VkPhysicalDevice          vkPhysDevice            = context.getPhysicalDevice();
+       const VkDevice                          vkDevice                        = context.getDevice();
+       const deUint32                          queueFamilyIndex        = context.getUniversalQueueFamilyIndex();
+       Allocator&                                      memAlloc                        = context.getDefaultAllocator();
+       const bool                                      hasDepth                        = tcu::hasDepthComponent(mapVkFormat(m_params.dst.image.format).order);
+       const bool                                      hasStencil                      = tcu::hasStencilComponent(mapVkFormat(m_params.dst.image.format).order);
+
+       if (!isSupportedDepthStencilFormat(vki, vkPhysDevice, testParams.dst.image.format))
+       {
+               TCU_THROW(NotSupportedError, "Image format not supported.");
+       }
+
+       if (hasDepth)
+       {
+               glw::GLuint texelSize = m_textureFormat.getPixelSize();
+               if (texelSize > sizeof(float))
+               {
+                       // We must have D32F_S8 format, depth must be packed so we only need
+                       // to allocate space for the D32F part. Stencil will be separate
+                       texelSize = sizeof(float);
+               }
+               m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height) * static_cast<VkDeviceSize>(texelSize);
+       }
+       if (hasStencil)
+       {
+               // Stencil is always 8bits and packed.
+               m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height);
+       }
+
+       // Create source buffer, this is where the depth & stencil data will go that's used by test's regions.
+       {
+               const VkBufferCreateInfo        sourceBufferParams              =
+               {
+                       VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
+                       DE_NULL,                                                                        // const void*                  pNext;
+                       0u,                                                                                     // VkBufferCreateFlags  flags;
+                       m_bufferSize,                                                           // VkDeviceSize                 size;
+                       VK_BUFFER_USAGE_TRANSFER_SRC_BIT,                       // VkBufferUsageFlags   usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
+                       1u,                                                                                     // deUint32                             queueFamilyIndexCount;
+                       &queueFamilyIndex,                                                      // const deUint32*              pQueueFamilyIndices;
+               };
+
+               m_source                                = createBuffer(vk, vkDevice, &sourceBufferParams);
+               m_sourceBufferAlloc             = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
+               VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
+       }
+
+       // Create destination image
+       {
+               const VkImageCreateInfo         destinationImageParams  =
+               {
+                       VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType              sType;
+                       DE_NULL,                                                                // const void*                  pNext;
+                       getCreateFlags(m_params.dst.image),             // VkImageCreateFlags   flags;
+                       m_params.dst.image.imageType,                   // VkImageType                  imageType;
+                       m_params.dst.image.format,                              // VkFormat                             format;
+                       getExtent3D(m_params.dst.image),                // VkExtent3D                   extent;
+                       1u,                                                                             // deUint32                             mipLevels;
+                       getArraySize(m_params.dst.image),               // deUint32                             arraySize;
+                       VK_SAMPLE_COUNT_1_BIT,                                  // deUint32                             samples;
+                       VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                tiling;
+                       VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+                               VK_IMAGE_USAGE_TRANSFER_DST_BIT,        // VkImageUsageFlags    usage;
+                       VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
+                       1u,                                                                             // deUint32                             queueFamilyCount;
+                       &queueFamilyIndex,                                              // const deUint32*              pQueueFamilyIndices;
+                       VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                initialLayout;
+               };
+
+               m_destination                           = createImage(vk, vkDevice, &destinationImageParams);
+               m_destinationImageAlloc         = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
+               VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
+       }
+}
+
+tcu::TestStatus CopyBufferToDepthStencil::iterate(void)
+{
+       // Create source depth/stencil content. Treat as 1D texture to get different pattern
+       m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
+       // Fill buffer with linear gradiant
+       generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
+
+       // Create image layer for depth/stencil
+       m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
+               m_params.dst.image.extent.width,
+               m_params.dst.image.extent.height,
+               m_params.dst.image.extent.depth));
+
+       // Fill image layer with 2D gradiant
+       generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
+
+       // Fill m_extendedTextureLevel with copy of m_destinationTextureLevel
+       // Then iterate over each of the regions given in m_params.regions and copy m_sourceTextureLevel content to m_extendedTextureLevel
+       // This emulates what the HW will be doing.
+       generateExpectedResult();
+
+       // Upload our source depth/stencil content to the source buffer
+       // This is the buffer that will be used by region commands
+       std::vector<VkBufferImageCopy>  bufferImageCopies;
+       VkDeviceSize                                    bufferOffset    = 0;
+       const VkDevice                                  vkDevice                = m_context.getDevice();
+       const DeviceInterface&                  vk                              = m_context.getDeviceInterface();
+       const VkQueue                                   queue                   = m_context.getUniversalQueue();
+       char*                                                   dstPtr                  = reinterpret_cast<char*>(m_sourceBufferAlloc->getHostPtr());
+       bool                                                    depthLoaded             = DE_FALSE;
+       bool                                                    stencilLoaded   = DE_FALSE;
+       VkDeviceSize                                    depthOffset             = 0;
+       VkDeviceSize                                    stencilOffset   = 0;
+
+       // To be able to test ordering depth & stencil differently
+       // We take the given copy regions and use that as the desired order
+       // and copy the appropriate data into place and compute the appropriate
+       // data offsets to be used in the copy command.
+       for (deUint32 i = 0; i < m_params.regions.size(); i++)
+       {
+               tcu::ConstPixelBufferAccess bufferAccess        = m_sourceTextureLevel->getAccess();
+               deUint32                                        bufferSize              = bufferAccess.getWidth() * bufferAccess.getHeight() * bufferAccess.getDepth();
+               VkBufferImageCopy                       copyData                = m_params.regions[i].bufferImageCopy;
+               char*                                           srcPtr;
+
+               if (copyData.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT && !depthLoaded)
+               {
+                       if (!depthLoaded)
+                       {
+                               // Create level that is same component as depth buffer (e.g. D16, D24, D32F)
+                               tcu::TextureLevel       depthTexture(mapCombinedToDepthTransferFormat(bufferAccess.getFormat()), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
+                               bufferSize *= tcu::getPixelSize(depthTexture.getFormat());
+                               // Copy depth component only from source data. This gives us packed depth-only data.
+                               tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_DEPTH));
+                               srcPtr = (char*)depthTexture.getAccess().getDataPtr();
+                               // Copy packed depth-only data to output buffer
+                               deMemcpy(dstPtr, srcPtr, bufferSize);
+                               depthLoaded = DE_TRUE;
+                               depthOffset = bufferOffset;
+                               dstPtr += bufferSize;
+                               bufferOffset += bufferSize;
+                       }
+                       copyData.bufferOffset += depthOffset;
+               }
+               else if (!stencilLoaded)
+               {
+                       if (!stencilLoaded)
+                       {
+                               // Create level that is same component as stencil buffer (always 8-bits)
+                               tcu::TextureLevel       stencilTexture(tcu::getEffectiveDepthStencilTextureFormat(bufferAccess.getFormat(), tcu::Sampler::MODE_STENCIL), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
+                               // Copy stencil component only from source data. This gives us packed stencil-only data.
+                               tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_STENCIL));
+                               srcPtr = (char*)stencilTexture.getAccess().getDataPtr();
+                               // Copy packed stencil-only data to output buffer
+                               deMemcpy(dstPtr, srcPtr, bufferSize);
+                               stencilLoaded = DE_TRUE;
+                               stencilOffset = bufferOffset;
+                               dstPtr += bufferSize;
+                               bufferOffset += bufferSize;
+                       }
+                       copyData.bufferOffset += stencilOffset;
+               }
+
+               bufferImageCopies.push_back(copyData);
+       }
+
+       flushAlloc(vk, vkDevice, *m_sourceBufferAlloc);
+
+       // Upload the depth/stencil data from m_destinationTextureLevel to initialize
+       // depth and stencil to known values.
+       // Uses uploadImageAspect so makes its own buffers for depth and stencil
+       // aspects (as needed) and copies them with independent vkCmdCopyBufferToImage commands.
+       uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
+
+       const VkImageMemoryBarrier      imageBarrier    =
+       {
+               VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
+               DE_NULL,                                                                        // const void*                          pNext;
+               VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
+               VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        dstAccessMask;
+               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
+               VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        newLayout;
+               VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
+               VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
+               *m_destination,                                                         // VkImage                                      image;
+               {                                                                                       // VkImageSubresourceRange      subresourceRange;
+                       getAspectFlags(m_textureFormat),        // VkImageAspectFlags   aspectMask;
+                       0u,                                                             // deUint32                             baseMipLevel;
+                       1u,                                                             // deUint32                             mipLevels;
+                       0u,                                                             // deUint32                             baseArraySlice;
+                       1u                                                              // deUint32                             arraySize;
+               }
+       };
+
+       // Copy from buffer to depth/stencil image
+
+       beginCommandBuffer(vk, *m_cmdBuffer);
+       vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
+
+       if (m_params.singleCommand)
+       {
+               // Issue a single copy command with regions defined by the test.
+               vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
+       }
+       else
+       {
+               // Issue a a copy command per region defined by the test.
+               for (deUint32 i = 0; i < bufferImageCopies.size(); i++)
+               {
+                       vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopies[i]);
+               }
+       }
+       endCommandBuffer(vk, *m_cmdBuffer);
+
+       submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
+
+       de::MovePtr<tcu::TextureLevel>  resultLevel = readImage(*m_destination, m_params.dst.image);
+
+       return checkTestResult(resultLevel->getAccess());
+}
+
+class CopyBufferToDepthStencilTestCase : public vkt::TestCase
+{
+public:
+                                                       CopyBufferToDepthStencilTestCase        (tcu::TestContext&              testCtx,
+                                                                                                                                const std::string&             name,
+                                                                                                                                const std::string&             description,
+                                                                                                                                const TestParams               params)
+                                                               : vkt::TestCase(testCtx, name, description)
+                                                               , m_params(params)
+                                                       {}
+
+       virtual                                 ~CopyBufferToDepthStencilTestCase       (void) {}
+
+       virtual TestInstance*   createInstance                                          (Context&                               context) const
+                                                       {
+                                                               return new CopyBufferToDepthStencil(context, m_params);
+                                                       }
+private:
+       TestParams                              m_params;
+};
+
 // Copy from image to image with scaling.
 
 class BlittingImages : public CopiesAndBlittingTestInstance
@@ -5626,6 +5944,134 @@ void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocation
        }
 }
 
+void addBufferToDepthStencilTests(tcu::TestCaseGroup* group, AllocationKind allocationKind)
+{
+       tcu::TestContext& testCtx = group->getTestContext();
+
+       const struct
+       {
+               const char* name;
+               const VkFormat                                                  format;
+       } depthAndStencilFormats[] =
+       {
+               { "d16_unorm",                          VK_FORMAT_D16_UNORM                             },
+               { "x8_d24_unorm_pack32",        VK_FORMAT_X8_D24_UNORM_PACK32   },
+               { "d32_sfloat",                         VK_FORMAT_D32_SFLOAT                    },
+               { "d16_unorm_s8_uint",          VK_FORMAT_D16_UNORM_S8_UINT             },
+               { "d24_unorm_s8_uint",          VK_FORMAT_D24_UNORM_S8_UINT             },
+               { "d32_sfloat_s8_uint",         VK_FORMAT_D32_SFLOAT_S8_UINT    }
+       };
+
+       const VkImageSubresourceLayers  depthSourceLayer =
+       {
+               VK_IMAGE_ASPECT_DEPTH_BIT,              // VkImageAspectFlags   aspectMask;
+               0u,                                                     // deUint32                             mipLevel;
+               0u,                                                     // deUint32                             baseArrayLayer;
+               1u,                                                     // deUint32                             layerCount;
+       };
+
+       const VkBufferImageCopy bufferDepthCopy =
+       {
+               0u,                                                                                     // VkDeviceSize                         bufferOffset;
+               0u,                                                                                     // deUint32                                     bufferRowLength;
+               0u,                                                                                     // deUint32                                     bufferImageHeight;
+               depthSourceLayer,                                                       // VkImageSubresourceLayers     imageSubresource;
+               {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
+               defaultExtent                                                           // VkExtent3D                           imageExtent;
+       };
+       CopyRegion      copyDepthRegion;
+       copyDepthRegion.bufferImageCopy = bufferDepthCopy;
+
+       const VkImageSubresourceLayers  stencilSourceLayer =
+       {
+               VK_IMAGE_ASPECT_STENCIL_BIT,            // VkImageAspectFlags   aspectMask;
+               0u,                                                     // deUint32                             mipLevel;
+               0u,                                                     // deUint32                             baseArrayLayer;
+               1u,                                                     // deUint32                             layerCount;
+       };
+
+       const VkBufferImageCopy bufferStencilCopy =
+       {
+               0u,                                                                                     // VkDeviceSize                         bufferOffset;
+               0u,                                                                                     // deUint32                                     bufferRowLength;
+               0u,                                                                                     // deUint32                                     bufferImageHeight;
+               stencilSourceLayer,                                                     // VkImageSubresourceLayers     imageSubresource;
+               {0, 0, 0},                                                                      // VkOffset3D                           imageOffset;
+               defaultExtent                                                           // VkExtent3D                           imageExtent;
+       };
+
+       CopyRegion      copyStencilRegion;
+       copyStencilRegion.bufferImageCopy = bufferStencilCopy;
+
+       // Note: Depth stencil tests I want to do
+       // Formats: D16, D24S8, D32FS8
+       // Test writing each component with separate CopyBufferToImage commands
+       // Test writing both components in one CopyBufferToImage command
+       // Swap order of writes of Depth & Stencil
+       // whole surface, subimages?
+       // Similar tests as BufferToImage?
+       for (const auto config : depthAndStencilFormats)
+       {
+               // TODO: Check that this format is supported before creating tests?
+               //if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
+
+               const tcu::TextureFormat format = mapVkFormat(config.format);
+               const bool hasDepth = tcu::hasDepthComponent(format.order);
+               const bool hasStencil = tcu::hasStencilComponent(format.order);
+               std::string description = config.name;
+
+               TestParams      params;
+               params.src.buffer.size = defaultSize * defaultSize;
+               params.dst.image.imageType = VK_IMAGE_TYPE_2D;
+               params.dst.image.format = config.format;
+               params.dst.image.extent = defaultExtent;
+               params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
+               params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+               params.allocationKind = allocationKind;
+
+               if (hasDepth && hasStencil)
+               {
+                       params.singleCommand = DE_TRUE;
+
+                       params.regions.push_back(copyDepthRegion);
+                       params.regions.push_back(copyStencilRegion);
+
+                       group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_DS", "Copy from depth&stencil to image", params));
+
+                       params.singleCommand = DE_FALSE;
+
+                       group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D_S", "Copy from depth then stencil to image", params));
+
+                       params.regions.clear();
+                       params.regions.push_back(copyStencilRegion);
+                       params.regions.push_back(copyDepthRegion);
+
+                       group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S_D", "Copy from depth then stencil to image", params));
+
+                       params.singleCommand = DE_TRUE;
+                       group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_SD", "Copy from depth&stencil to image", params));
+
+               }
+
+               if (hasStencil)
+               {
+                       params.regions.clear();
+                       params.regions.push_back(copyStencilRegion);
+
+                       group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S", "Copy from stencil to image", params));
+               }
+
+
+               if (hasDepth)
+               {
+                       params.regions.clear();
+                       params.regions.push_back(copyDepthRegion);
+
+                       group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D", "Copy from depth to image", params));
+               }
+       }
+}
+
 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind)
 {
        tcu::TestContext& testCtx       = group->getTestContext();
@@ -8106,6 +8552,7 @@ void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind alloca
        addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind);
        addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind);
        addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind);
+       addTestGroup(group, "buffer_to_depthstencil", "Copy from buffer to depth/Stencil", addBufferToDepthStencilTests, allocationKind);
        addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind);
        addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind);
        addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind);
index 594fee4..1eda30e 100644 (file)
@@ -24367,6 +24367,27 @@ dEQP-VK.api.copy_and_blit.core.buffer_to_image.regions
 dEQP-VK.api.copy_and_blit.core.buffer_to_image.buffer_offset
 dEQP-VK.api.copy_and_blit.core.buffer_to_image.tightly_sized_buffer
 dEQP-VK.api.copy_and_blit.core.buffer_to_image.tightly_sized_buffer_offset
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.x8_d24_unorm_pack32_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_DS
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_SD
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_DS
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_SD
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_DS
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_SD
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_D
 dEQP-VK.api.copy_and_blit.core.buffer_to_buffer.whole
 dEQP-VK.api.copy_and_blit.core.buffer_to_buffer.partial
 dEQP-VK.api.copy_and_blit.core.buffer_to_buffer.regions
@@ -78425,6 +78446,27 @@ dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_image.regions
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_image.buffer_offset
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_image.tightly_sized_buffer
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_image.tightly_sized_buffer_offset
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.x8_d24_unorm_pack32_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_DS
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_SD
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_DS
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_SD
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_DS
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_SD
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_D
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_buffer.whole
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_buffer.partial
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_buffer.regions
index 6c56552..42d359e 100644 (file)
@@ -24367,6 +24367,27 @@ dEQP-VK.api.copy_and_blit.core.buffer_to_image.regions
 dEQP-VK.api.copy_and_blit.core.buffer_to_image.buffer_offset
 dEQP-VK.api.copy_and_blit.core.buffer_to_image.tightly_sized_buffer
 dEQP-VK.api.copy_and_blit.core.buffer_to_image.tightly_sized_buffer_offset
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.x8_d24_unorm_pack32_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_DS
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_SD
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d16_unorm_s8_uint_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_DS
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_SD
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d24_unorm_s8_uint_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_DS
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_SD
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_S
+dEQP-VK.api.copy_and_blit.core.buffer_to_depthstencil.d32_sfloat_s8_uint_D
 dEQP-VK.api.copy_and_blit.core.buffer_to_buffer.whole
 dEQP-VK.api.copy_and_blit.core.buffer_to_buffer.partial
 dEQP-VK.api.copy_and_blit.core.buffer_to_buffer.regions
@@ -78425,6 +78446,27 @@ dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_image.regions
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_image.buffer_offset
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_image.tightly_sized_buffer
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_image.tightly_sized_buffer_offset
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.x8_d24_unorm_pack32_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_DS
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_SD
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d16_unorm_s8_uint_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_DS
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_SD
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d24_unorm_s8_uint_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_DS
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_D_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_S_D
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_SD
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_S
+dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_depthstencil.d32_sfloat_s8_uint_D
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_buffer.whole
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_buffer.partial
 dEQP-VK.api.copy_and_blit.dedicated_allocation.buffer_to_buffer.regions
index fb2412d..b3907ef 100644 (file)
@@ -807,6 +807,108 @@ bool intThresholdCompare (TestLog& log, const char* imageSetName, const char* im
 }
 
 /*--------------------------------------------------------------------*//*!
+ * \brief Per-pixel depth/stencil threshold-based comparison
+ *
+ * This compare computes per-pixel differences between result and reference
+ * image. Comparison fails if any pixels exceed the given threshold value.
+ *
+ * This comparison can be used for depth and depth/stencil images.
+ * Difference is computed in integer space.
+ *
+ * On failure error image is generated that shows where the failing pixels
+ * are.
+ *
+ * \param log                  Test log for results
+ * \param imageSetName Name for image set when logging results
+ * \param imageSetDesc Description for image set
+ * \param reference            Reference image
+ * \param result               Result image
+ * \param threshold            Maximum allowed depth difference (stencil must be exact)
+ * \param logMode              Logging mode
+ * \return true if comparison passes, false otherwise
+ *//*--------------------------------------------------------------------*/
+bool dsThresholdCompare(TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const float threshold, CompareLogMode logMode)
+{
+       int                                     width = reference.getWidth();
+       int                                     height = reference.getHeight();
+       int                                     depth = reference.getDepth();
+       TextureLevel            errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8), width, height, depth);
+       PixelBufferAccess       errorMask = errorMaskStorage.getAccess();
+       float                           maxDiff = 0.0;
+       bool                            allStencilOk = true;
+       bool                            hasDepth = tcu::hasDepthComponent(result.getFormat().order);
+       bool                            hasStencil = tcu::hasStencilComponent(result.getFormat().order);
+
+       TCU_CHECK_INTERNAL(result.getWidth() == width && result.getHeight() == height && result.getDepth() == depth);
+
+       for (int z = 0; z < depth; z++)
+       {
+               for (int y = 0; y < height; y++)
+               {
+                       for (int x = 0; x < width; x++)
+                       {
+                               bool    isOk = true;
+
+                               if (hasDepth)
+                               {
+                                       float   refDepth = reference.getPixDepth(x, y, z);
+                                       float   cmpDepth = result.getPixDepth(x, y, z);
+
+                                       float   diff = refDepth - cmpDepth;
+                                       isOk = diff <= threshold;
+                                       maxDiff = (float) deMax(maxDiff, diff);
+                               }
+
+                               if (hasStencil)
+                               {
+                                       deUint8 refStencil = (deUint8) reference.getPixStencil(x, y, z);
+                                       deUint8 cmpStencil = (deUint8) result.getPixStencil(x, y, z);
+
+                                       bool isStencilOk = (refStencil == cmpStencil);
+                                       allStencilOk = allStencilOk && isStencilOk;
+                                       isOk = isOk && isStencilOk;
+                               }
+
+                               errorMask.setPixel(isOk ? IVec4(0, 0xff, 0, 0xff) : IVec4(0xff, 0, 0, 0xff), x, y, z);
+                       }
+               }
+       }
+
+       bool compareOk = (maxDiff <= threshold) && allStencilOk;
+
+       if (!compareOk || logMode == COMPARE_LOG_EVERYTHING)
+       {
+               if (!compareOk)
+               {
+                       if (maxDiff > threshold)
+                               log << TestLog::Message << "Depth comparison failed: max difference = " << maxDiff << ", threshold = " << threshold << TestLog::EndMessage;
+                       if (!allStencilOk)
+                               log << TestLog::Message << "Stencil comparison failed" << TestLog::EndMessage;
+               }
+
+               log << TestLog::ImageSet(imageSetName, imageSetDesc)
+                       // TODO: Convert depth/stencil buffers into separate depth & stencil for logging?
+//                     << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
+//                     << TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
+                       << TestLog::Image("ErrorMask", "Error mask", errorMask)
+                       << TestLog::EndImageSet;
+       }
+       else if (logMode == COMPARE_LOG_RESULT)
+       {
+#if 0
+               if (result.getFormat() != TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8))
+                       computePixelScaleBias(result, pixelScale, pixelBias);
+
+               log << TestLog::ImageSet(imageSetName, imageSetDesc)
+                       << TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
+                       << TestLog::EndImageSet;
+#endif
+       }
+
+       return compareOk;
+}
+
+/*--------------------------------------------------------------------*//*!
  * \brief Per-pixel threshold-based deviation-ignoring comparison
  *
  * This compare computes per-pixel differences between result and reference
index a16f30a..684cdf3 100644 (file)
@@ -55,6 +55,7 @@ bool  floatThresholdCompare                                                           (TestLog& log, const char* imageSetName, const
 bool   intThresholdCompare                                                                     (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, CompareLogMode logMode);
 bool   intThresholdPositionDeviationCompare                            (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, const tcu::IVec3& maxPositionDeviation, bool acceptOutOfBoundsAsAnyValue, CompareLogMode logMode);
 bool   intThresholdPositionDeviationErrorThresholdCompare      (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const UVec4& threshold, const tcu::IVec3& maxPositionDeviation, bool acceptOutOfBoundsAsAnyValue, int maxAllowedFailingPixels, CompareLogMode logMode);
+bool   dsThresholdCompare                                                                      (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const float threshold, CompareLogMode logMode);
 int            measurePixelDiffAccuracy                                                        (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, int bestScoreDiff, int worstScoreDiff, CompareLogMode logMode);
 bool   bilinearCompare                                                                         (TestLog& log, const char* imageSetName, const char* imageSetDesc, const ConstPixelBufferAccess& reference, const ConstPixelBufferAccess& result, const RGBA threshold, CompareLogMode logMode);
 
index 04d9bf4..a79c7d6 100644 (file)
@@ -1051,7 +1051,7 @@ void fillWithMetaballs (const PixelBufferAccess& dst, int numBalls, deUint32 see
        }
 }
 
-void copy (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src)
+void copy (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src, const bool clearUnused)
 {
        DE_ASSERT(src.getSize() == dst.getSize());
 
@@ -1097,7 +1097,7 @@ void copy (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src)
                        for (int x = 0; x < width; x++)
                                dst.setPixDepth(src.getPixDepth(x, y, z), x, y, z);
                }
-               else if (dstHasDepth && !srcHasDepth)
+               else if (dstHasDepth && !srcHasDepth && clearUnused)
                {
                        // consistency with color copies
                        tcu::clearDepth(dst, 0.0f);
@@ -1110,7 +1110,7 @@ void copy (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src)
                        for (int x = 0; x < width; x++)
                                dst.setPixStencil(src.getPixStencil(x, y, z), x, y, z);
                }
-               else if (dstHasStencil && !srcHasStencil)
+               else if (dstHasStencil && !srcHasStencil && clearUnused)
                {
                        // consistency with color copies
                        tcu::clearStencil(dst, 0u);
index 3df5466..3cc770a 100644 (file)
@@ -122,7 +122,7 @@ void        fillWithMetaballs                               (const PixelBufferAccess& access, int numMetaballs, de
 void   fillWithRGBAQuads                               (const PixelBufferAccess& access);
 
 //! Copies contents of src to dst. If formats of dst and src are equal, a bit-exact copy is made.
-void   copy                                                    (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src);
+void   copy                                                    (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src, const bool clearUnused = DE_TRUE);
 
 void   scale                                                   (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src, Sampler::FilterMode filter);