mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[d3d11] Re-implement direct image mapping (disabled by default)
We cannot enable this by default yet because it may break some games.
This commit is contained in:
parent
155bd32e22
commit
3b20c71894
@ -189,70 +189,89 @@ namespace dxvk {
|
|||||||
if (pMappedResource == nullptr)
|
if (pMappedResource == nullptr)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
|
// Parameter validation was successful
|
||||||
VkImageSubresource subresource =
|
VkImageSubresource subresource =
|
||||||
pResource->GetSubresourceFromIndex(
|
pResource->GetSubresourceFromIndex(
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT, Subresource);
|
VK_IMAGE_ASPECT_COLOR_BIT, Subresource);
|
||||||
|
|
||||||
pResource->SetMappedSubresource(subresource);
|
pResource->SetMappedSubresource(subresource);
|
||||||
|
|
||||||
// Query format info in order to compute
|
if (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) {
|
||||||
// the row pitch and layer pitch properly.
|
const VkImageType imageType = mappedImage->info().type;
|
||||||
const DxvkFormatInfo* formatInfo = imageFormatInfo(mappedImage->info().format);
|
|
||||||
|
|
||||||
const VkExtent3D levelExtent = mappedImage->mipLevelExtent(subresource.mipLevel);
|
|
||||||
const VkExtent3D blockCount = util::computeBlockCount(
|
|
||||||
levelExtent, formatInfo->blockSize);
|
|
||||||
|
|
||||||
DxvkPhysicalBufferSlice physicalSlice;
|
|
||||||
|
|
||||||
// When using any map mode which requires the image contents
|
|
||||||
// to be preserved, copy the image's contents into the buffer.
|
|
||||||
if (MapType == D3D11_MAP_WRITE_DISCARD) {
|
|
||||||
physicalSlice = mappedBuffer->allocPhysicalSlice();
|
|
||||||
physicalSlice.resource()->acquire();
|
|
||||||
|
|
||||||
EmitCs([
|
// Wait for the resource to become available
|
||||||
cImageBuffer = mappedBuffer,
|
if (!WaitForResource(mappedImage, MapFlags))
|
||||||
cPhysicalSlice = physicalSlice
|
|
||||||
] (DxvkContext* ctx) {
|
|
||||||
ctx->invalidateBuffer(cImageBuffer, cPhysicalSlice);
|
|
||||||
cPhysicalSlice.resource()->release();
|
|
||||||
});
|
|
||||||
} 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 = pResource->Desc()->Usage == D3D11_USAGE_STAGING;
|
|
||||||
|
|
||||||
if (copyExistingData) {
|
|
||||||
const VkImageSubresourceLayers subresourceLayers = {
|
|
||||||
subresource.aspectMask,
|
|
||||||
subresource.mipLevel,
|
|
||||||
subresource.arrayLayer, 1 };
|
|
||||||
|
|
||||||
EmitCs([
|
|
||||||
cImageBuffer = mappedBuffer,
|
|
||||||
cImage = mappedImage,
|
|
||||||
cSubresources = subresourceLayers,
|
|
||||||
cLevelExtent = levelExtent
|
|
||||||
] (DxvkContext* ctx) {
|
|
||||||
ctx->copyImageToBuffer(
|
|
||||||
cImageBuffer, 0, VkExtent2D { 0u, 0u },
|
|
||||||
cImage, cSubresources, VkOffset3D { 0, 0, 0 },
|
|
||||||
cLevelExtent);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!WaitForResource(mappedBuffer->resource(), MapFlags))
|
|
||||||
return DXGI_ERROR_WAS_STILL_DRAWING;
|
return DXGI_ERROR_WAS_STILL_DRAWING;
|
||||||
|
|
||||||
physicalSlice = mappedBuffer->slice();
|
// Query the subresource's memory layout and hope that
|
||||||
|
// the application respects the returned pitch values.
|
||||||
|
VkSubresourceLayout layout = mappedImage->querySubresourceLayout(subresource);
|
||||||
|
|
||||||
|
pMappedResource->pData = mappedImage->mapPtr(layout.offset);
|
||||||
|
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 {
|
||||||
|
// Query format info which we need to compute
|
||||||
|
// the row pitch and layer pitch properly.
|
||||||
|
const DxvkFormatInfo* formatInfo = imageFormatInfo(mappedImage->info().format);
|
||||||
|
|
||||||
|
const VkExtent3D levelExtent = mappedImage->mipLevelExtent(subresource.mipLevel);
|
||||||
|
const VkExtent3D blockCount = util::computeBlockCount(
|
||||||
|
levelExtent, formatInfo->blockSize);
|
||||||
|
|
||||||
|
DxvkPhysicalBufferSlice physicalSlice;
|
||||||
|
|
||||||
|
if (MapType == D3D11_MAP_WRITE_DISCARD) {
|
||||||
|
// We do not have to preserve the contents of the
|
||||||
|
// buffer if the entire image gets discarded.
|
||||||
|
physicalSlice = mappedBuffer->allocPhysicalSlice();
|
||||||
|
physicalSlice.resource()->acquire();
|
||||||
|
|
||||||
|
EmitCs([
|
||||||
|
cImageBuffer = mappedBuffer,
|
||||||
|
cPhysicalSlice = physicalSlice
|
||||||
|
] (DxvkContext* ctx) {
|
||||||
|
ctx->invalidateBuffer(cImageBuffer, cPhysicalSlice);
|
||||||
|
cPhysicalSlice.resource()->release();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 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) {
|
||||||
|
const VkImageSubresourceLayers subresourceLayers = {
|
||||||
|
subresource.aspectMask,
|
||||||
|
subresource.mipLevel,
|
||||||
|
subresource.arrayLayer, 1 };
|
||||||
|
|
||||||
|
EmitCs([
|
||||||
|
cImageBuffer = mappedBuffer,
|
||||||
|
cImage = mappedImage,
|
||||||
|
cSubresources = subresourceLayers,
|
||||||
|
cLevelExtent = levelExtent
|
||||||
|
] (DxvkContext* ctx) {
|
||||||
|
ctx->copyImageToBuffer(
|
||||||
|
cImageBuffer, 0, VkExtent2D { 0u, 0u },
|
||||||
|
cImage, cSubresources, VkOffset3D { 0, 0, 0 },
|
||||||
|
cLevelExtent);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WaitForResource(mappedBuffer->resource(), MapFlags))
|
||||||
|
return DXGI_ERROR_WAS_STILL_DRAWING;
|
||||||
|
|
||||||
|
physicalSlice = mappedBuffer->slice();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up map pointer. Data is tightly packed within the mapped buffer.
|
||||||
|
pMappedResource->pData = physicalSlice.mapPtr(0);
|
||||||
|
pMappedResource->RowPitch = formatInfo->elementSize * blockCount.width;
|
||||||
|
pMappedResource->DepthPitch = formatInfo->elementSize * blockCount.width * blockCount.height;
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up map pointer. Data is tightly packed within the mapped buffer.
|
|
||||||
pMappedResource->pData = physicalSlice.mapPtr(0);
|
|
||||||
pMappedResource->RowPitch = formatInfo->elementSize * blockCount.width;
|
|
||||||
pMappedResource->DepthPitch = formatInfo->elementSize * blockCount.width * blockCount.height;
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -286,6 +305,8 @@ namespace dxvk {
|
|||||||
cSrcBuffer, 0, { 0u, 0u });
|
cSrcBuffer, 0, { 0u, 0u });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pResource->ClearMappedSubresource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ namespace dxvk {
|
|||||||
// 2. Since the image will most likely be read for rendering by the GPU,
|
// 2. Since the image will most likely be read for rendering by the GPU,
|
||||||
// writing the image to device-local image may be more efficient than
|
// writing the image to device-local image may be more efficient than
|
||||||
// reading its contents from host-visible memory.
|
// reading its contents from host-visible memory.
|
||||||
if ((m_desc.CPUAccessFlags & D3D11_CPU_ACCESS_READ) == 0)
|
if (m_desc.Usage == D3D11_USAGE_DYNAMIC)
|
||||||
return D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER;
|
return D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER;
|
||||||
|
|
||||||
// Images that can be read by the host should be mapped directly in
|
// Images that can be read by the host should be mapped directly in
|
||||||
|
Loading…
x
Reference in New Issue
Block a user