mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-02 01:24:11 +01:00
[d3d11] Implement depth-stencil mapping on the immediate context
This commit is contained in:
parent
c38b1802a2
commit
97d77fa508
@ -405,8 +405,11 @@ namespace dxvk {
|
||||
Logger::err("D3D11: Cannot map a device-local image");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
VkFormat packedFormat = m_parent->LookupPackedFormat(
|
||||
pResource->Desc()->Format, pResource->GetFormatMode()).Format;
|
||||
|
||||
auto formatInfo = imageFormatInfo(mappedImage->info().format);
|
||||
auto formatInfo = imageFormatInfo(packedFormat);
|
||||
auto subresource = pResource->GetSubresourceFromIndex(
|
||||
formatInfo->aspectMask, Subresource);
|
||||
|
||||
@ -426,44 +429,6 @@ namespace dxvk {
|
||||
pMappedResource->RowPitch = imageType >= VK_IMAGE_TYPE_2D ? layout.rowPitch : layout.size;
|
||||
pMappedResource->DepthPitch = imageType >= VK_IMAGE_TYPE_3D ? layout.depthPitch : layout.size;
|
||||
return S_OK;
|
||||
} else if (formatInfo->aspectMask == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
||||
VkExtent3D levelExtent = mappedImage->mipLevelExtent(subresource.mipLevel);
|
||||
|
||||
if (MapType != D3D11_MAP_READ) {
|
||||
Logger::err(str::format("D3D11: Map type ", MapType, " not supported for depth-stencil images"));
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// The actual Vulkan image format may differ
|
||||
// from the format requested by the application
|
||||
VkFormat packFormat = GetPackedDepthStencilFormat(pResource->Desc()->Format);
|
||||
auto packFormatInfo = imageFormatInfo(packFormat);
|
||||
|
||||
// This is slow, but we have to dispatch a pack
|
||||
// operation and then immediately synchronize.
|
||||
EmitCs([
|
||||
cImageBuffer = mappedBuffer,
|
||||
cImage = mappedImage,
|
||||
cSubresource = subresource,
|
||||
cFormat = packFormat
|
||||
] (DxvkContext* ctx) {
|
||||
auto layers = vk::makeSubresourceLayers(cSubresource);
|
||||
auto x = cImage->mipLevelExtent(cSubresource.mipLevel);
|
||||
|
||||
VkOffset2D offset = { 0, 0 };
|
||||
VkExtent2D extent = { x.width, x.height };
|
||||
|
||||
ctx->copyDepthStencilImageToPackedBuffer(
|
||||
cImageBuffer, 0, cImage, layers, offset, extent, cFormat);
|
||||
});
|
||||
|
||||
WaitForResource(mappedBuffer, 0);
|
||||
|
||||
DxvkBufferSliceHandle physSlice = mappedBuffer->getSliceHandle();
|
||||
pMappedResource->pData = physSlice.mapPtr;
|
||||
pMappedResource->RowPitch = packFormatInfo->elementSize * levelExtent.width;
|
||||
pMappedResource->DepthPitch = packFormatInfo->elementSize * levelExtent.width * levelExtent.height;
|
||||
return S_OK;
|
||||
} else {
|
||||
VkExtent3D levelExtent = mappedImage->mipLevelExtent(subresource.mipLevel);
|
||||
VkExtent3D blockCount = util::computeBlockCount(levelExtent, formatInfo->blockSize);
|
||||
@ -485,21 +450,28 @@ namespace dxvk {
|
||||
// When using any map mode which requires the image contents
|
||||
// to be preserved, and if the GPU has write access to the
|
||||
// image, copy the current image contents into the buffer.
|
||||
const bool copyExistingData = pResource->Desc()->Usage == D3D11_USAGE_STAGING;
|
||||
|
||||
if (copyExistingData) {
|
||||
if (pResource->Desc()->Usage == D3D11_USAGE_STAGING) {
|
||||
auto subresourceLayers = vk::makeSubresourceLayers(subresource);
|
||||
|
||||
EmitCs([
|
||||
cImageBuffer = mappedBuffer,
|
||||
cImage = mappedImage,
|
||||
cSubresources = subresourceLayers,
|
||||
cLevelExtent = levelExtent
|
||||
cLevelExtent = levelExtent,
|
||||
cPackedFormat = packedFormat
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->copyImageToBuffer(
|
||||
cImageBuffer, 0, VkExtent2D { 0u, 0u },
|
||||
cImage, cSubresources, VkOffset3D { 0, 0, 0 },
|
||||
cLevelExtent);
|
||||
if (cSubresources.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
||||
ctx->copyImageToBuffer(
|
||||
cImageBuffer, 0, VkExtent2D { 0u, 0u },
|
||||
cImage, cSubresources, VkOffset3D { 0, 0, 0 },
|
||||
cLevelExtent);
|
||||
} else {
|
||||
ctx->copyDepthStencilImageToPackedBuffer(
|
||||
cImageBuffer, 0, cImage, cSubresources,
|
||||
VkOffset2D { 0, 0 },
|
||||
VkExtent2D { cLevelExtent.width, cLevelExtent.height },
|
||||
cPackedFormat);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -542,11 +514,20 @@ namespace dxvk {
|
||||
cSrcBuffer = mappedBuffer,
|
||||
cDstImage = mappedImage,
|
||||
cDstLayers = subresourceLayers,
|
||||
cDstLevelExtent = levelExtent
|
||||
cDstLevelExtent = levelExtent,
|
||||
cPackedFormat = GetPackedDepthStencilFormat(pResource->Desc()->Format)
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->copyBufferToImage(cDstImage, cDstLayers,
|
||||
VkOffset3D { 0, 0, 0 }, cDstLevelExtent,
|
||||
cSrcBuffer, 0, { 0u, 0u });
|
||||
if (cPackedFormat == VK_FORMAT_UNDEFINED) {
|
||||
ctx->copyBufferToImage(cDstImage, cDstLayers,
|
||||
VkOffset3D { 0, 0, 0 }, cDstLevelExtent,
|
||||
cSrcBuffer, 0, { 0u, 0u });
|
||||
} else {
|
||||
ctx->copyPackedBufferToDepthStencilImage(
|
||||
cDstImage, cDstLayers,
|
||||
VkOffset2D { 0, 0 },
|
||||
VkExtent2D { cDstLevelExtent.width, cDstLevelExtent.height },
|
||||
cSrcBuffer, 0, cPackedFormat);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -418,7 +418,8 @@ namespace dxvk {
|
||||
* blockCount.height
|
||||
* blockCount.depth;
|
||||
info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT
|
||||
| VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
| VK_BUFFER_USAGE_TRANSFER_DST_BIT
|
||||
| VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||
info.stages = VK_PIPELINE_STAGE_TRANSFER_BIT;
|
||||
info.access = VK_ACCESS_TRANSFER_READ_BIT
|
||||
| VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
|
Loading…
Reference in New Issue
Block a user