[d3d11] Introduce DiscardSlice and GetMappedSlice for image resources

These do the same as they do for buffer resources, but for a mapped
image subresource instead.
This commit is contained in:
Philip Rebohle 2021-06-22 00:17:02 +02:00
parent 11aa2a703a
commit f155b8a8b9
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 64 additions and 36 deletions

View File

@ -391,8 +391,10 @@ namespace dxvk {
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
const Rc<DxvkImage> mappedImage = pResource->GetImage();
const Rc<DxvkBuffer> mappedBuffer = pResource->GetMappedBuffer(Subresource);
auto mapMode = pResource->GetMapMode();
if (unlikely(pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_NONE)) {
if (unlikely(mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_NONE)) {
Logger::err("D3D11: Cannot map a device-local image");
return E_INVALIDARG;
}
@ -416,32 +418,21 @@ namespace dxvk {
auto formatInfo = imageFormatInfo(packedFormat);
auto subresource = pResource->GetSubresourceFromIndex(
formatInfo->aspectMask, Subresource);
if (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) {
void* mapPtr;
if (mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) {
// Wait for the resource to become available
if (!WaitForResource(mappedImage, MapType, MapFlags))
return DXGI_ERROR_WAS_STILL_DRAWING;
// Mark the given subresource as mapped
pResource->SetMapType(Subresource, MapType);
// Query the subresource's memory layout and hope that
// the application respects the returned pitch values.
if (pMappedResource) {
auto layout = pResource->GetSubresourceLayout(formatInfo->aspectMask, Subresource);
pMappedResource->pData = mappedImage->mapPtr(layout.Offset);
pMappedResource->RowPitch = layout.RowPitch;
pMappedResource->DepthPitch = layout.DepthPitch;
}
return S_OK;
mapPtr = mappedImage->mapPtr(0);
} else {
DxvkBufferSliceHandle physSlice;
if (MapType == D3D11_MAP_WRITE_DISCARD) {
// We do not have to preserve the contents of the
// buffer if the entire image gets discarded.
physSlice = mappedBuffer->allocSlice();
DxvkBufferSliceHandle physSlice = pResource->DiscardSlice(Subresource);
EmitCs([
cImageBuffer = mappedBuffer,
@ -449,6 +440,8 @@ namespace dxvk {
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cImageBuffer, cBufferSlice);
});
mapPtr = physSlice.mapPtr;
} else {
// When using any map mode which requires the image contents
// to be preserved, and if the GPU has write access to the
@ -463,22 +456,21 @@ namespace dxvk {
if (!WaitForResource(mappedBuffer, MapType, MapFlags))
return DXGI_ERROR_WAS_STILL_DRAWING;
physSlice = mappedBuffer->getSliceHandle();
mapPtr = pResource->GetMappedSlice(Subresource).mapPtr;
}
// Mark the given subresource as mapped
pResource->SetMapType(Subresource, MapType);
// Set up map pointer. Data is tightly packed within the mapped buffer.
if (pMappedResource) {
auto layout = pResource->GetSubresourceLayout(formatInfo->aspectMask, Subresource);
pMappedResource->pData = reinterpret_cast<char*>(physSlice.mapPtr) + layout.Offset;
pMappedResource->RowPitch = layout.RowPitch;
pMappedResource->DepthPitch = layout.DepthPitch;
}
return S_OK;
}
// Mark the given subresource as mapped
pResource->SetMapType(Subresource, MapType);
if (pMappedResource) {
auto layout = pResource->GetSubresourceLayout(formatInfo->aspectMask, Subresource);
pMappedResource->pData = reinterpret_cast<char*>(mapPtr) + layout.Offset;
pMappedResource->RowPitch = layout.RowPitch;
pMappedResource->DepthPitch = layout.DepthPitch;
}
return S_OK;
}

View File

@ -542,7 +542,7 @@ namespace dxvk {
}
Rc<DxvkBuffer> D3D11CommonTexture::CreateMappedBuffer(UINT MipLevel) const {
D3D11CommonTexture::MappedBuffer D3D11CommonTexture::CreateMappedBuffer(UINT MipLevel) const {
const DxvkFormatInfo* formatInfo = imageFormatInfo(
m_device->LookupPackedFormat(m_desc.Format, GetFormatMode()).Format);
@ -561,7 +561,10 @@ namespace dxvk {
if (m_desc.Usage == D3D11_USAGE_STAGING)
memType |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
return m_device->GetDXVKDevice()->createBuffer(info, memType);
MappedBuffer result;
result.buffer = m_device->GetDXVKDevice()->createBuffer(info, memType);
result.slice = result.buffer->getSliceHandle();
return result;
}

View File

@ -168,9 +168,37 @@ namespace dxvk {
*/
Rc<DxvkBuffer> GetMappedBuffer(UINT Subresource) const {
return Subresource < m_buffers.size()
? m_buffers[Subresource]
? m_buffers[Subresource].buffer
: Rc<DxvkBuffer>();
}
/**
* \brief Discards mapped buffer slice for a given subresource
*
* \param [in] Subresource Subresource to discard
* \returns Newly allocated mapped buffer slice
*/
DxvkBufferSliceHandle DiscardSlice(UINT Subresource) {
if (Subresource < m_buffers.size()) {
DxvkBufferSliceHandle slice = m_buffers[Subresource].buffer->allocSlice();
m_buffers[Subresource].slice = slice;
return slice;
} else {
return DxvkBufferSliceHandle();
}
}
/**
* \brief Retrieves mapped buffer slice for a given subresource
*
* \param [in] Subresource Subresource index to query
* \returns Currently mapped buffer slice
*/
DxvkBufferSliceHandle GetMappedSlice(UINT Subresource) const {
return Subresource < m_buffers.size()
? m_buffers[Subresource].slice
: DxvkBufferSliceHandle();
}
/**
* \brief Checks whether we can update the mapped buffer early
@ -258,6 +286,11 @@ namespace dxvk {
private:
struct MappedBuffer {
Rc<DxvkBuffer> buffer;
DxvkBufferSliceHandle slice;
};
D3D11Device* const m_device;
D3D11_RESOURCE_DIMENSION m_dimension;
D3D11_COMMON_TEXTURE_DESC m_desc;
@ -265,10 +298,10 @@ namespace dxvk {
DXGI_USAGE m_dxgiUsage;
Rc<DxvkImage> m_image;
std::vector<Rc<DxvkBuffer>> m_buffers;
std::vector<MappedBuffer> m_buffers;
std::vector<D3D11_MAP> m_mapTypes;
Rc<DxvkBuffer> CreateMappedBuffer(
MappedBuffer CreateMappedBuffer(
UINT MipLevel) const;
BOOL CheckImageSupport(