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