1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-07 07:54:15 +01:00

[d3d11] Introduce ComputeMappedOffset for image resources

Modifies GetSubresourceLayout slightly in case only a partial aspect
mask is being passed to the function. This way we can conveniently
compute the offset of a given pixel within the mapped buffer of an
image subresource.
This commit is contained in:
Philip Rebohle 2021-06-22 06:45:37 +02:00
parent 7c0ee272c3
commit 1a6f4456d8
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 46 additions and 13 deletions

View File

@ -220,6 +220,30 @@ namespace dxvk {
} }
VkDeviceSize D3D11CommonTexture::ComputeMappedOffset(UINT Subresource, UINT Plane, VkOffset3D Offset) const {
auto packedFormatInfo = imageFormatInfo(m_packedFormat);
VkImageAspectFlags aspectMask = packedFormatInfo->aspectMask;
VkDeviceSize elementSize = packedFormatInfo->elementSize;
if (packedFormatInfo->flags.test(DxvkFormatFlag::MultiPlane)) {
auto plane = &packedFormatInfo->planes[Plane];
elementSize = plane->elementSize;
Offset.x /= plane->blockSize.width;
Offset.y /= plane->blockSize.height;
aspectMask = vk::getPlaneAspect(Plane);
}
auto layout = GetSubresourceLayout(aspectMask, Subresource);
auto blockOffset = util::computeBlockOffset(Offset, packedFormatInfo->blockSize);
return VkDeviceSize(blockOffset.z) * layout.DepthPitch
+ VkDeviceSize(blockOffset.y) * layout.RowPitch
+ VkDeviceSize(blockOffset.x) * elementSize
+ VkDeviceSize(layout.Offset);
}
VkImageSubresource D3D11CommonTexture::GetSubresourceFromIndex( VkImageSubresource D3D11CommonTexture::GetSubresourceFromIndex(
VkImageAspectFlags Aspect, VkImageAspectFlags Aspect,
UINT Subresource) const { UINT Subresource) const {
@ -232,9 +256,9 @@ namespace dxvk {
D3D11_COMMON_TEXTURE_SUBRESOURCE_LAYOUT D3D11CommonTexture::GetSubresourceLayout( D3D11_COMMON_TEXTURE_SUBRESOURCE_LAYOUT D3D11CommonTexture::GetSubresourceLayout(
VkImageAspectFlags Aspect, VkImageAspectFlags AspectMask,
UINT Subresource) const { UINT Subresource) const {
VkImageSubresource subresource = GetSubresourceFromIndex(Aspect, Subresource); VkImageSubresource subresource = GetSubresourceFromIndex(AspectMask, Subresource);
D3D11_COMMON_TEXTURE_SUBRESOURCE_LAYOUT layout = { }; D3D11_COMMON_TEXTURE_SUBRESOURCE_LAYOUT layout = { };
switch (m_mapMode) { switch (m_mapMode) {
@ -248,18 +272,12 @@ namespace dxvk {
case D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER: case D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER:
case D3D11_COMMON_TEXTURE_MAP_MODE_STAGING: { case D3D11_COMMON_TEXTURE_MAP_MODE_STAGING: {
auto aspects = Aspect; auto packedFormatInfo = imageFormatInfo(m_packedFormat);
// The exact aspect mask only matters for multi-plane formats,
// but depth-stencil is assumed to be packed in memory
if (aspects == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
aspects = VK_IMAGE_ASPECT_DEPTH_BIT;
VkImageAspectFlags aspects = packedFormatInfo->aspectMask;
VkExtent3D mipExtent = MipLevelExtent(subresource.mipLevel); VkExtent3D mipExtent = MipLevelExtent(subresource.mipLevel);
while (aspects) { while (aspects) {
auto packedFormatInfo = imageFormatInfo(m_packedFormat);
auto aspect = vk::getNextAspect(aspects); auto aspect = vk::getNextAspect(aspects);
auto extent = mipExtent; auto extent = mipExtent;
auto elementSize = packedFormatInfo->elementSize; auto elementSize = packedFormatInfo->elementSize;
@ -278,7 +296,12 @@ namespace dxvk {
layout.DepthPitch = elementSize * blockCount.width * blockCount.height; layout.DepthPitch = elementSize * blockCount.width * blockCount.height;
} }
layout.Size += elementSize * blockCount.width * blockCount.height * blockCount.depth; VkDeviceSize size = elementSize * blockCount.width * blockCount.height * blockCount.depth;
if (aspect & AspectMask)
layout.Size += size;
else if (!layout.Size)
layout.Offset += size;
} }
} break; } break;

View File

@ -237,6 +237,16 @@ namespace dxvk {
&& (m_desc.Usage == D3D11_USAGE_STAGING); && (m_desc.Usage == D3D11_USAGE_STAGING);
} }
/**
* \brief Computes pixel offset into mapped buffer
*
* \param [in] Subresource Subresource index
* \param [in] Subresource Plane index
* \param [in] Offset Pixel coordinate to compute offset for
* \returns Offset into mapped subresource buffer, in pixels
*/
VkDeviceSize ComputeMappedOffset(UINT Subresource, UINT Plane, VkOffset3D Offset) const;
/** /**
* \brief Computes subresource from the subresource index * \brief Computes subresource from the subresource index
* *
@ -253,12 +263,12 @@ namespace dxvk {
/** /**
* \brief Computes subresource layout for the given subresource * \brief Computes subresource layout for the given subresource
* *
* \param [in] Aspect The image aspect * \param [in] AspectMask The image aspect
* \param [in] Subresource Subresource index * \param [in] Subresource Subresource index
* \returns Memory layout of the mapped subresource * \returns Memory layout of the mapped subresource
*/ */
D3D11_COMMON_TEXTURE_SUBRESOURCE_LAYOUT GetSubresourceLayout( D3D11_COMMON_TEXTURE_SUBRESOURCE_LAYOUT GetSubresourceLayout(
VkImageAspectFlags Aspect, VkImageAspectFlags AspectMask,
UINT Subresource) const; UINT Subresource) const;
/** /**