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

[d3d11] Refactored Map/Unmap methods

This commit is contained in:
Philip Rebohle 2018-03-14 14:40:09 +01:00
parent 91b82c05b2
commit 0ba3337289
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
4 changed files with 218 additions and 137 deletions

View File

@ -100,8 +100,35 @@ namespace dxvk {
pResource->GetType(&resourceDim);
if (resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER) {
D3D11Buffer* resource = static_cast<D3D11Buffer*>(pResource);
Rc<DxvkBuffer> buffer = resource->GetBufferSlice().buffer();
return MapBuffer(
static_cast<D3D11Buffer*>(pResource),
MapType, MapFlags, pMappedResource);
} else {
return MapImage(
GetCommonTexture(pResource),
Subresource, MapType, MapFlags,
pMappedResource);
}
}
void STDMETHODCALLTYPE D3D11ImmediateContext::Unmap(
ID3D11Resource* pResource,
UINT Subresource) {
D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
pResource->GetType(&resourceDim);
if (resourceDim != D3D11_RESOURCE_DIMENSION_BUFFER)
UnmapImage(GetCommonTexture(pResource), Subresource);
}
HRESULT D3D11ImmediateContext::MapBuffer(
D3D11Buffer* pResource,
D3D11_MAP MapType,
UINT MapFlags,
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
Rc<DxvkBuffer> buffer = pResource->GetBufferSlice().buffer();
if (!(buffer->memFlags() & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
Logger::err("D3D11: Cannot map a device-local buffer");
@ -118,7 +145,7 @@ namespace dxvk {
auto physicalSlice = buffer->allocPhysicalSlice();
physicalSlice.resource()->acquire();
resource->GetBufferInfo()->mappedSlice = physicalSlice;
pResource->GetBufferInfo()->mappedSlice = physicalSlice;
EmitCs([
cBuffer = buffer,
@ -136,19 +163,25 @@ namespace dxvk {
// way we don't have to synchronize with the CS thread
// if the map mode is D3D11_MAP_WRITE_NO_OVERWRITE.
const DxvkPhysicalBufferSlice physicalSlice
= resource->GetBufferInfo()->mappedSlice;
= pResource->GetBufferInfo()->mappedSlice;
pMappedResource->pData = physicalSlice.mapPtr(0);
pMappedResource->RowPitch = physicalSlice.length();
pMappedResource->DepthPitch = physicalSlice.length();
return S_OK;
} else {
D3D11CommonTexture* textureInfo = GetCommonTexture(pResource);
}
const Rc<DxvkImage> mappedImage = textureInfo->GetImage();
const Rc<DxvkBuffer> mappedBuffer = textureInfo->GetMappedBuffer();
if (mappedBuffer == nullptr) {
HRESULT D3D11ImmediateContext::MapImage(
D3D11CommonTexture* pResource,
UINT Subresource,
D3D11_MAP MapType,
UINT MapFlags,
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
const Rc<DxvkImage> mappedImage = pResource->GetImage();
const Rc<DxvkBuffer> mappedBuffer = pResource->GetMappedBuffer();
if (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_NONE) {
Logger::err("D3D11: Cannot map a device-local image");
return E_INVALIDARG;
}
@ -157,10 +190,10 @@ namespace dxvk {
return S_FALSE;
VkImageSubresource subresource =
textureInfo->GetSubresourceFromIndex(
pResource->GetSubresourceFromIndex(
VK_IMAGE_ASPECT_COLOR_BIT, Subresource);
textureInfo->SetMappedSubresource(subresource);
pResource->SetMappedSubresource(subresource);
// Query format info in order to compute
// the row pitch and layer pitch properly.
@ -188,7 +221,7 @@ namespace dxvk {
} else {
// We may have to copy the current image contents into the
// mapped buffer if the GPU has write access to the image.
const bool copyExistingData = textureInfo->Desc()->Usage == D3D11_USAGE_STAGING;
const bool copyExistingData = pResource->Desc()->Usage == D3D11_USAGE_STAGING;
if (copyExistingData) {
const VkImageSubresourceLayers subresourceLayers = {
@ -221,24 +254,18 @@ namespace dxvk {
pMappedResource->DepthPitch = formatInfo->elementSize * blockCount.width * blockCount.height;
return S_OK;
}
}
void STDMETHODCALLTYPE D3D11ImmediateContext::Unmap(
ID3D11Resource* pResource,
void D3D11ImmediateContext::UnmapImage(
D3D11CommonTexture* pResource,
UINT Subresource) {
D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
pResource->GetType(&resourceDim);
if (resourceDim != D3D11_RESOURCE_DIMENSION_BUFFER) {
if (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) {
// Now that data has been written into the buffer,
// we need to copy its contents into the image
D3D11CommonTexture* textureInfo = GetCommonTexture(pResource);
const Rc<DxvkImage> mappedImage = pResource->GetImage();
const Rc<DxvkBuffer> mappedBuffer = pResource->GetMappedBuffer();
const Rc<DxvkImage> mappedImage = textureInfo->GetImage();
const Rc<DxvkBuffer> mappedBuffer = textureInfo->GetMappedBuffer();
VkImageSubresource subresource = textureInfo->GetMappedSubresource();
VkImageSubresource subresource = pResource->GetMappedSubresource();
VkExtent3D levelExtent = mappedImage
->mipLevelExtent(subresource.mipLevel);

View File

@ -4,6 +4,9 @@
namespace dxvk {
class D3D11Buffer;
class D3D11CommonTexture;
class D3D11ImmediateContext : public D3D11DeviceContext {
public:
@ -48,6 +51,23 @@ namespace dxvk {
DxvkCsThread m_csThread;
HRESULT MapBuffer(
D3D11Buffer* pResource,
D3D11_MAP MapType,
UINT MapFlags,
D3D11_MAPPED_SUBRESOURCE* pMappedResource);
HRESULT MapImage(
D3D11CommonTexture* pResource,
UINT Subresource,
D3D11_MAP MapType,
UINT MapFlags,
D3D11_MAPPED_SUBRESOURCE* pMappedResource);
void UnmapImage(
D3D11CommonTexture* pResource,
UINT Subresource);
void SynchronizeDevice();
bool WaitForResource(

View File

@ -7,7 +7,7 @@ namespace dxvk {
D3D11Device* pDevice,
const D3D11_COMMON_TEXTURE_DESC* pDesc,
D3D11_RESOURCE_DIMENSION Dimension)
: m_device(pDevice), m_desc(*pDesc) {
: m_device(pDevice), m_desc(*pDesc), m_mapMode(DetermineMapMode()) {
DxgiFormatInfo formatInfo = m_device->LookupFormat(m_desc.Format, GetFormatMode());
DxvkImageCreateInfo imageInfo;
@ -56,8 +56,15 @@ namespace dxvk {
| VK_ACCESS_SHADER_WRITE_BIT;
}
if (m_desc.CPUAccessFlags != 0) {
if (m_desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE)
imageInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
if (FAILED(GetSampleCount(m_desc.SampleDesc.Count, &imageInfo.sampleCount)))
throw DxvkError(str::format("D3D11: Invalid sample count: ", m_desc.SampleDesc.Count));
if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) {
imageInfo.stages |= VK_PIPELINE_STAGE_HOST_BIT;
imageInfo.tiling = VK_IMAGE_TILING_LINEAR;
if (m_desc.CPUAccessFlags & D3D11_CPU_ACCESS_WRITE)
imageInfo.access |= VK_ACCESS_HOST_WRITE_BIT;
@ -66,15 +73,9 @@ namespace dxvk {
imageInfo.access |= VK_ACCESS_HOST_READ_BIT;
}
if (m_desc.MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE)
imageInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
if (imageInfo.tiling == VK_IMAGE_TILING_OPTIMAL)
imageInfo.layout = OptimizeLayout(imageInfo.usage);
if (FAILED(GetSampleCount(m_desc.SampleDesc.Count, &imageInfo.sampleCount)))
throw DxvkError(str::format("D3D11: Invalid sample count: ", m_desc.SampleDesc.Count));
m_image = m_device->GetDXVKDevice()->createImage(
imageInfo, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
@ -127,6 +128,15 @@ namespace dxvk {
}
D3D11_COMMON_TEXTURE_MAP_MODE D3D11CommonTexture::DetermineMapMode() const {
// TODO re-implement direct mapping. We'll have to check
// whether that is supported on a per-image basis though.
return m_desc.CPUAccessFlags == 0
? D3D11_COMMON_TEXTURE_MAP_MODE_NONE
: D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER;
}
Rc<DxvkBuffer> D3D11CommonTexture::CreateMappedBuffer() const {
const DxvkFormatInfo* formatInfo = imageFormatInfo(
m_device->LookupFormat(m_desc.Format, GetFormatMode()).format);

View File

@ -9,6 +9,19 @@ namespace dxvk {
class D3D11Device;
/**
* \brief Image memory mapping mode
*
* Determines how exactly \c Map will
* 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
};
/**
* \brief Common texture description
*
@ -59,6 +72,14 @@ namespace dxvk {
return &m_desc;
}
/**
* \brief Map mode
* \returns Map mode
*/
D3D11_COMMON_TEXTURE_MAP_MODE GetMapMode() const {
return m_mapMode;
}
/**
* \brief The DXVK image
* \returns The DXVK image
@ -143,6 +164,7 @@ namespace dxvk {
Com<D3D11Device> m_device;
D3D11_COMMON_TEXTURE_DESC m_desc;
D3D11_COMMON_TEXTURE_MAP_MODE m_mapMode;
Rc<DxvkImage> m_image;
Rc<DxvkBuffer> m_buffer;
@ -152,6 +174,8 @@ namespace dxvk {
Rc<DxvkBuffer> CreateMappedBuffer() const;
D3D11_COMMON_TEXTURE_MAP_MODE DetermineMapMode() const;
static VkImageType GetImageTypeFromResourceDim(
D3D11_RESOURCE_DIMENSION Dimension);