1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-01 16:24:12 +01:00

[d3d11] Introduce D3D11_COMMON_TEXTURE_MAP_MODE_STAGING

This map mode can be used when no Vulkan image is needed to back a
staging resource, which can save a significant amount of memory.
This commit is contained in:
Philip Rebohle 2021-06-21 22:53:13 +02:00
parent b384f5372e
commit 11aa2a703a
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 38 additions and 18 deletions

View File

@ -10,7 +10,7 @@ namespace dxvk {
D3D11_RESOURCE_DIMENSION Dimension,
DXGI_USAGE DxgiUsage,
VkImage vkImage)
: m_device(pDevice), m_desc(*pDesc), m_dxgiUsage(DxgiUsage) {
: m_device(pDevice), m_dimension(Dimension), m_desc(*pDesc), m_dxgiUsage(DxgiUsage) {
DXGI_VK_FORMAT_MODE formatMode = GetFormatMode();
DXGI_VK_FORMAT_INFO formatInfo = m_device->LookupFormat(m_desc.Format, formatMode);
DXGI_VK_FORMAT_FAMILY formatFamily = m_device->LookupFamily(m_desc.Format, formatMode);
@ -153,6 +153,22 @@ namespace dxvk {
imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
}
// If necessary, create the mapped linear buffer
if (m_mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_NONE) {
for (uint32_t i = 0; i < m_desc.ArraySize; i++) {
for (uint32_t j = 0; j < m_desc.MipLevels; j++) {
if (m_mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT)
m_buffers.push_back(CreateMappedBuffer(j));
m_mapTypes.push_back(D3D11_MAP(~0u));
}
}
}
// Skip image creation if possible
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_STAGING)
return;
// We must keep LINEAR images in GENERAL layout, but we
// can choose a better layout for the image based on how
// it is going to be used by the game.
@ -194,16 +210,6 @@ namespace dxvk {
m_image = m_device->GetDXVKDevice()->createImage(imageInfo, memoryProperties);
else
m_image = m_device->GetDXVKDevice()->createImageFromVkImage(imageInfo, vkImage);
// If necessary, create the mapped linear buffer
for (uint32_t i = 0; i < m_desc.ArraySize; i++) {
for (uint32_t j = 0; j < m_desc.MipLevels; j++) {
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER)
m_buffers.push_back(CreateMappedBuffer(j));
if (m_mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_NONE)
m_mapTypes.push_back(D3D11_MAP(~0u));
}
}
}
@ -238,7 +244,8 @@ namespace dxvk {
layout.DepthPitch = vkLayout.depthPitch;
} break;
case D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER: {
case D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER:
case D3D11_COMMON_TEXTURE_MAP_MODE_STAGING: {
auto formatInfo = imageFormatInfo(m_device->LookupPackedFormat(m_desc.Format, GetFormatMode()).Format);
auto aspects = Aspect;
@ -247,7 +254,7 @@ namespace dxvk {
if (aspects == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
aspects = VK_IMAGE_ASPECT_DEPTH_BIT;
VkExtent3D mipExtent = m_image->mipLevelExtent(subresource.mipLevel);
VkExtent3D mipExtent = MipLevelExtent(subresource.mipLevel);
while (aspects) {
auto aspect = vk::getNextAspect(aspects);
@ -277,8 +284,8 @@ namespace dxvk {
}
// D3D wants us to return the total subresource size in some instances
if (m_image->info().type < VK_IMAGE_TYPE_2D) layout.RowPitch = layout.Size;
if (m_image->info().type < VK_IMAGE_TYPE_3D) layout.DepthPitch = layout.Size;
if (m_dimension < D3D11_RESOURCE_DIMENSION_TEXTURE2D) layout.RowPitch = layout.Size;
if (m_dimension < D3D11_RESOURCE_DIMENSION_TEXTURE3D) layout.DepthPitch = layout.Size;
return layout;
}

View File

@ -20,9 +20,10 @@ namespace dxvk {
* behave when mapping an image.
*/
enum D3D11_COMMON_TEXTURE_MAP_MODE {
D3D11_COMMON_TEXTURE_MAP_MODE_NONE, ///< Not mapped
D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER, ///< Mapped through buffer
D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT, ///< Directly mapped to host mem
D3D11_COMMON_TEXTURE_MAP_MODE_NONE, ///< Not mapped
D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER, ///< Mapped through buffer
D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT, ///< Directly mapped to host mem
D3D11_COMMON_TEXTURE_MAP_MODE_STAGING, ///< Buffer only, no image
};
@ -90,6 +91,17 @@ namespace dxvk {
return &m_desc;
}
/**
* \brief Computes extent of a given mip level
*
* This also works for staging resources that have no image.
* \param [in] Level Mip level to compute the size of
*/
VkExtent3D MipLevelExtent(uint32_t Level) const {
return util::computeMipLevelExtent(
VkExtent3D { m_desc.Width, m_desc.Height, m_desc.Depth }, Level);
}
/**
* \brief Special DXGI usage flags
*
@ -247,6 +259,7 @@ namespace dxvk {
private:
D3D11Device* const m_device;
D3D11_RESOURCE_DIMENSION m_dimension;
D3D11_COMMON_TEXTURE_DESC m_desc;
D3D11_COMMON_TEXTURE_MAP_MODE m_mapMode;
DXGI_USAGE m_dxgiUsage;