1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00

[d3d9] Use staging buffer for managed copies

This commit is contained in:
Robin Kertels 2021-04-02 01:37:33 +02:00 committed by Joshie
parent bb11d7dee8
commit 4261ff6ec1
3 changed files with 89 additions and 60 deletions

View File

@ -656,6 +656,8 @@ namespace dxvk {
VkOffset3D srcBlockOffset = { 0u, 0u, 0u }; VkOffset3D srcBlockOffset = { 0u, 0u, 0u };
VkOffset3D dstOffset = { 0u, 0u, 0u }; VkOffset3D dstOffset = { 0u, 0u, 0u };
VkExtent3D texLevelExtent = srcTextureInfo->GetExtentMip(src->GetSubresource());
VkExtent3D texLevelBlockCount = util::computeBlockCount(texLevelExtent, formatInfo->blockSize);
VkExtent3D copyExtent = srcTextureInfo->GetExtentMip(src->GetSubresource()); VkExtent3D copyExtent = srcTextureInfo->GetExtentMip(src->GetSubresource());
@ -678,7 +680,11 @@ namespace dxvk {
const auto dstSubresource = vk::makeSubresourceLayers( const auto dstSubresource = vk::makeSubresourceLayers(
dstTextureInfo->GetSubresourceFromIndex(VK_IMAGE_ASPECT_COLOR_BIT, dst->GetSubresource())); dstTextureInfo->GetSubresourceFromIndex(VK_IMAGE_ASPECT_COLOR_BIT, dst->GetSubresource()));
Rc<DxvkBuffer> srcBuffer = srcTextureInfo->GetBuffer(src->GetSubresource()); DxvkBufferSliceHandle srcSlice = srcTextureInfo->GetMappedSlice(src->GetSubresource());
D3D9BufferSlice slice = AllocTempBuffer<false>(srcSlice.length);
util::packImageData(
slice.mapPtr, srcSlice.mapPtr, texLevelBlockCount, formatInfo->elementSize,
texLevelBlockCount.width * formatInfo->elementSize, texLevelBlockCount.width * texLevelBlockCount.height * formatInfo->elementSize);
Rc<DxvkImage> dstImage = dstTextureInfo->GetImage(); Rc<DxvkImage> dstImage = dstTextureInfo->GetImage();
VkExtent3D levelExtent = srcTextureInfo->GetExtentMip(src->GetSubresource()); VkExtent3D levelExtent = srcTextureInfo->GetExtentMip(src->GetSubresource());
@ -692,7 +698,7 @@ namespace dxvk {
EmitCs([ EmitCs([
cDstImage = std::move(dstImage), cDstImage = std::move(dstImage),
cSrcBuffer = std::move(srcBuffer), cSrcSlice = slice.slice,
cDstLayers = dstSubresource, cDstLayers = dstSubresource,
cDstOffset = dstOffset, cDstOffset = dstOffset,
cSrcOffset = srcByteOffset, cSrcOffset = srcByteOffset,
@ -701,7 +707,7 @@ namespace dxvk {
] (DxvkContext* ctx) { ] (DxvkContext* ctx) {
ctx->copyBufferToImage( ctx->copyBufferToImage(
cDstImage, cDstLayers, cDstOffset, cCopyExtent, cDstImage, cDstLayers, cDstOffset, cCopyExtent,
cSrcBuffer, cSrcOffset, cSrcSlice.buffer(), cSrcSlice.offset() + cSrcOffset,
cSrcExtent); cSrcExtent);
}); });
@ -745,7 +751,6 @@ namespace dxvk {
continue; continue;
for (uint32_t m = 0; m < mipLevels; m++) { for (uint32_t m = 0; m < mipLevels; m++) {
Rc<DxvkBuffer> srcBuffer = srcTexInfo->GetBuffer(srcTexInfo->CalcSubresource(a, m));
VkImageSubresourceLayers dstLayers = { VK_IMAGE_ASPECT_COLOR_BIT, m, a, 1 }; VkImageSubresourceLayers dstLayers = { VK_IMAGE_ASPECT_COLOR_BIT, m, a, 1 };
VkOffset3D scaledBoxOffset = { VkOffset3D scaledBoxOffset = {
@ -770,9 +775,19 @@ namespace dxvk {
VkExtent2D srcExtent = VkExtent2D{ texLevelExtentBlockCount.width * formatInfo->blockSize.width, VkExtent2D srcExtent = VkExtent2D{ texLevelExtentBlockCount.width * formatInfo->blockSize.width,
texLevelExtentBlockCount.height * formatInfo->blockSize.height }; texLevelExtentBlockCount.height * formatInfo->blockSize.height };
scaledAlignedBoxExtent.width = std::min<uint32_t>(texLevelExtent.width, scaledAlignedBoxExtent.width);
scaledAlignedBoxExtent.height = std::min<uint32_t>(texLevelExtent.height, scaledAlignedBoxExtent.height);
scaledAlignedBoxExtent.depth = std::min<uint32_t>(texLevelExtent.depth, scaledAlignedBoxExtent.depth);
DxvkBufferSliceHandle srcSlice = srcTexInfo->GetMappedSlice(srcTexInfo->CalcSubresource(a, m));
D3D9BufferSlice slice = AllocTempBuffer<false>(srcSlice.length);
util::packImageData(
slice.mapPtr, srcSlice.mapPtr, texLevelExtentBlockCount, formatInfo->elementSize,
texLevelExtentBlockCount.width * formatInfo->elementSize, texLevelExtentBlockCount.width * texLevelExtentBlockCount.height * formatInfo->elementSize);
EmitCs([ EmitCs([
cDstImage = dstImage, cDstImage = dstImage,
cSrcBuffer = srcBuffer, cSrcSlice = slice.slice,
cDstLayers = dstLayers, cDstLayers = dstLayers,
cExtent = scaledAlignedBoxExtent, cExtent = scaledAlignedBoxExtent,
cOffset = scaledBoxOffset, cOffset = scaledBoxOffset,
@ -782,7 +797,7 @@ namespace dxvk {
ctx->copyBufferToImage( ctx->copyBufferToImage(
cDstImage, cDstLayers, cDstImage, cDstLayers,
cOffset, cExtent, cOffset, cExtent,
cSrcBuffer, cSrcOffset, cSrcSlice.buffer(), cSrcSlice.offset() + cSrcOffset,
cSrcExtent); cSrcExtent);
}); });
@ -4276,11 +4291,11 @@ namespace dxvk {
HRESULT D3D9DeviceEx::FlushImage( HRESULT D3D9DeviceEx::FlushImage(
D3D9CommonTexture* pResource, D3D9CommonTexture* pResource,
UINT Subresource) { UINT Subresource) {
const Rc<DxvkImage> image = pResource->GetImage(); const Rc<DxvkImage> image = pResource->GetImage();
// Now that data has been written into the buffer, // Now that data has been written into the buffer,
// we need to copy its contents into the image // we need to copy its contents into the image
const Rc<DxvkBuffer> copyBuffer = pResource->GetBuffer(Subresource); const DxvkBufferSliceHandle srcSlice = pResource->GetMappedSlice(Subresource);
auto formatInfo = imageFormatInfo(image->info().format); auto formatInfo = imageFormatInfo(image->info().format);
auto subresource = pResource->GetSubresourceFromIndex( auto subresource = pResource->GetSubresourceFromIndex(
@ -4297,25 +4312,35 @@ namespace dxvk {
auto convertFormat = pResource->GetFormatMapping().ConversionFormatInfo; auto convertFormat = pResource->GetFormatMapping().ConversionFormatInfo;
if (likely(convertFormat.FormatType == D3D9ConversionFormat_None)) { if (likely(convertFormat.FormatType == D3D9ConversionFormat_None)) {
VkExtent3D texLevelExtentBlockCount = util::computeBlockCount(levelExtent, formatInfo->blockSize);
D3D9BufferSlice slice = AllocTempBuffer<false>(srcSlice.length);
util::packImageData(
slice.mapPtr, srcSlice.mapPtr, texLevelExtentBlockCount, formatInfo->elementSize,
texLevelExtentBlockCount.width * formatInfo->elementSize, texLevelExtentBlockCount.width * texLevelExtentBlockCount.height * formatInfo->elementSize);
EmitCs([ EmitCs([
cSrcBuffer = copyBuffer, cSrcSlice = slice.slice,
cDstImage = image, cDstImage = image,
cDstLayers = subresourceLayers, cDstLayers = subresourceLayers,
cDstLevelExtent = levelExtent cDstLevelExtent = levelExtent
] (DxvkContext* ctx) { ] (DxvkContext* ctx) {
ctx->copyBufferToImage(cDstImage, cDstLayers, ctx->copyBufferToImage(cDstImage, cDstLayers,
VkOffset3D{ 0, 0, 0 }, cDstLevelExtent, VkOffset3D{ 0, 0, 0 }, cDstLevelExtent,
cSrcBuffer, 0, { 0u, 0u }); cSrcSlice.buffer(), cSrcSlice.offset(),
{ 0u, 0u });
}); });
} }
else { else {
D3D9BufferSlice slice = AllocTempBuffer<false>(srcSlice.length);
memcpy(slice.mapPtr, srcSlice.mapPtr, srcSlice.length);
Flush(); Flush();
SynchronizeCsThread(); SynchronizeCsThread();
m_converter->ConvertFormat( m_converter->ConvertFormat(
convertFormat, convertFormat,
image, subresourceLayers, image, subresourceLayers,
copyBuffer); slice.slice.buffer(),
slice.slice.offset());
} }
if (pResource->IsAutomaticMip()) if (pResource->IsAutomaticMip())

View File

@ -28,33 +28,34 @@ namespace dxvk {
D3D9_CONVERSION_FORMAT_INFO conversionFormat, D3D9_CONVERSION_FORMAT_INFO conversionFormat,
const Rc<DxvkImage>& dstImage, const Rc<DxvkImage>& dstImage,
VkImageSubresourceLayers dstSubresource, VkImageSubresourceLayers dstSubresource,
const Rc<DxvkBuffer>& srcBuffer) { const Rc<DxvkBuffer>& srcBuffer,
uint32_t srcBufferOffset) {
switch (conversionFormat.FormatType) { switch (conversionFormat.FormatType) {
case D3D9ConversionFormat_YUY2: case D3D9ConversionFormat_YUY2:
case D3D9ConversionFormat_UYVY: { case D3D9ConversionFormat_UYVY: {
uint32_t specConstant = conversionFormat.FormatType == D3D9ConversionFormat_UYVY ? 1 : 0; uint32_t specConstant = conversionFormat.FormatType == D3D9ConversionFormat_UYVY ? 1 : 0;
ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, VK_FORMAT_R32_UINT, specConstant, { 2u, 1u }); ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, srcBufferOffset, VK_FORMAT_R32_UINT, specConstant, { 2u, 1u });
break; break;
} }
case D3D9ConversionFormat_NV12: case D3D9ConversionFormat_NV12:
ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, VK_FORMAT_R16_UINT, 0, { 2u, 1u }); ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, srcBufferOffset, VK_FORMAT_R16_UINT, 0, { 2u, 1u });
break; break;
case D3D9ConversionFormat_YV12: case D3D9ConversionFormat_YV12:
ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, VK_FORMAT_R8_UINT, 0, { 1u, 1u }); ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, srcBufferOffset, VK_FORMAT_R8_UINT, 0, { 1u, 1u });
break; break;
case D3D9ConversionFormat_L6V5U5: case D3D9ConversionFormat_L6V5U5:
ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, VK_FORMAT_R16_UINT, 0, { 1u, 1u }); ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, srcBufferOffset, VK_FORMAT_R16_UINT, 0, { 1u, 1u });
break; break;
case D3D9ConversionFormat_X8L8V8U8: case D3D9ConversionFormat_X8L8V8U8:
ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, VK_FORMAT_R32_UINT, 0, { 1u, 1u }); ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, srcBufferOffset, VK_FORMAT_R32_UINT, 0, { 1u, 1u });
break; break;
case D3D9ConversionFormat_A2W10V10U10: case D3D9ConversionFormat_A2W10V10U10:
ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, VK_FORMAT_R32_UINT, 0, { 1u, 1u }); ConvertGenericFormat(conversionFormat, dstImage, dstSubresource, srcBuffer, srcBufferOffset, VK_FORMAT_R32_UINT, 0, { 1u, 1u });
break; break;
default: default:
@ -68,6 +69,7 @@ namespace dxvk {
const Rc<DxvkImage>& dstImage, const Rc<DxvkImage>& dstImage,
VkImageSubresourceLayers dstSubresource, VkImageSubresourceLayers dstSubresource,
const Rc<DxvkBuffer>& srcBuffer, const Rc<DxvkBuffer>& srcBuffer,
uint32_t srcBufferOffset,
VkFormat bufferFormat, VkFormat bufferFormat,
uint32_t specConstantValue, uint32_t specConstantValue,
VkExtent2D macroPixelRun) { VkExtent2D macroPixelRun) {
@ -89,7 +91,7 @@ namespace dxvk {
DxvkBufferViewCreateInfo bufferViewInfo; DxvkBufferViewCreateInfo bufferViewInfo;
bufferViewInfo.format = bufferFormat; bufferViewInfo.format = bufferFormat;
bufferViewInfo.rangeOffset = 0; bufferViewInfo.rangeOffset = srcBufferOffset;
bufferViewInfo.rangeLength = srcBuffer->info().size; bufferViewInfo.rangeLength = srcBuffer->info().size;
auto tmpBufferView = m_device->createBufferView(srcBuffer, bufferViewInfo); auto tmpBufferView = m_device->createBufferView(srcBuffer, bufferViewInfo);

View File

@ -19,7 +19,8 @@ namespace dxvk {
D3D9_CONVERSION_FORMAT_INFO conversionFormat, D3D9_CONVERSION_FORMAT_INFO conversionFormat,
const Rc<DxvkImage>& dstImage, const Rc<DxvkImage>& dstImage,
VkImageSubresourceLayers dstSubresource, VkImageSubresourceLayers dstSubresource,
const Rc<DxvkBuffer>& srcBuffer); const Rc<DxvkBuffer>& srcBuffer,
uint32_t srcBufferOffset);
private: private:
@ -28,6 +29,7 @@ namespace dxvk {
const Rc<DxvkImage>& dstImage, const Rc<DxvkImage>& dstImage,
VkImageSubresourceLayers dstSubresource, VkImageSubresourceLayers dstSubresource,
const Rc<DxvkBuffer>& srcBuffer, const Rc<DxvkBuffer>& srcBuffer,
uint32_t srcBufferOffset,
VkFormat bufferFormat, VkFormat bufferFormat,
uint32_t specConstantValue, uint32_t specConstantValue,
VkExtent2D macroPixelRun); VkExtent2D macroPixelRun);