mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 10:54:16 +01:00
[d3d9] Use staging buffer for managed copies
This commit is contained in:
parent
bb11d7dee8
commit
4261ff6ec1
@ -656,6 +656,8 @@ namespace dxvk {
|
||||
|
||||
VkOffset3D srcBlockOffset = { 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());
|
||||
|
||||
@ -678,7 +680,11 @@ namespace dxvk {
|
||||
const auto dstSubresource = vk::makeSubresourceLayers(
|
||||
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();
|
||||
|
||||
VkExtent3D levelExtent = srcTextureInfo->GetExtentMip(src->GetSubresource());
|
||||
@ -692,7 +698,7 @@ namespace dxvk {
|
||||
|
||||
EmitCs([
|
||||
cDstImage = std::move(dstImage),
|
||||
cSrcBuffer = std::move(srcBuffer),
|
||||
cSrcSlice = slice.slice,
|
||||
cDstLayers = dstSubresource,
|
||||
cDstOffset = dstOffset,
|
||||
cSrcOffset = srcByteOffset,
|
||||
@ -701,7 +707,7 @@ namespace dxvk {
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->copyBufferToImage(
|
||||
cDstImage, cDstLayers, cDstOffset, cCopyExtent,
|
||||
cSrcBuffer, cSrcOffset,
|
||||
cSrcSlice.buffer(), cSrcSlice.offset() + cSrcOffset,
|
||||
cSrcExtent);
|
||||
});
|
||||
|
||||
@ -745,7 +751,6 @@ namespace dxvk {
|
||||
continue;
|
||||
|
||||
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 };
|
||||
|
||||
VkOffset3D scaledBoxOffset = {
|
||||
@ -770,9 +775,19 @@ namespace dxvk {
|
||||
VkExtent2D srcExtent = VkExtent2D{ texLevelExtentBlockCount.width * formatInfo->blockSize.width,
|
||||
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([
|
||||
cDstImage = dstImage,
|
||||
cSrcBuffer = srcBuffer,
|
||||
cSrcSlice = slice.slice,
|
||||
cDstLayers = dstLayers,
|
||||
cExtent = scaledAlignedBoxExtent,
|
||||
cOffset = scaledBoxOffset,
|
||||
@ -782,7 +797,7 @@ namespace dxvk {
|
||||
ctx->copyBufferToImage(
|
||||
cDstImage, cDstLayers,
|
||||
cOffset, cExtent,
|
||||
cSrcBuffer, cSrcOffset,
|
||||
cSrcSlice.buffer(), cSrcSlice.offset() + cSrcOffset,
|
||||
cSrcExtent);
|
||||
});
|
||||
|
||||
@ -4276,11 +4291,11 @@ namespace dxvk {
|
||||
HRESULT D3D9DeviceEx::FlushImage(
|
||||
D3D9CommonTexture* pResource,
|
||||
UINT Subresource) {
|
||||
const Rc<DxvkImage> image = pResource->GetImage();
|
||||
const Rc<DxvkImage> image = pResource->GetImage();
|
||||
|
||||
// Now that data has been written into the buffer,
|
||||
// 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 subresource = pResource->GetSubresourceFromIndex(
|
||||
@ -4297,25 +4312,35 @@ namespace dxvk {
|
||||
auto convertFormat = pResource->GetFormatMapping().ConversionFormatInfo;
|
||||
|
||||
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([
|
||||
cSrcBuffer = copyBuffer,
|
||||
cSrcSlice = slice.slice,
|
||||
cDstImage = image,
|
||||
cDstLayers = subresourceLayers,
|
||||
cDstLevelExtent = levelExtent
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->copyBufferToImage(cDstImage, cDstLayers,
|
||||
VkOffset3D{ 0, 0, 0 }, cDstLevelExtent,
|
||||
cSrcBuffer, 0, { 0u, 0u });
|
||||
cSrcSlice.buffer(), cSrcSlice.offset(),
|
||||
{ 0u, 0u });
|
||||
});
|
||||
}
|
||||
else {
|
||||
D3D9BufferSlice slice = AllocTempBuffer<false>(srcSlice.length);
|
||||
memcpy(slice.mapPtr, srcSlice.mapPtr, srcSlice.length);
|
||||
|
||||
Flush();
|
||||
SynchronizeCsThread();
|
||||
|
||||
m_converter->ConvertFormat(
|
||||
convertFormat,
|
||||
image, subresourceLayers,
|
||||
copyBuffer);
|
||||
slice.slice.buffer(),
|
||||
slice.slice.offset());
|
||||
}
|
||||
|
||||
if (pResource->IsAutomaticMip())
|
||||
|
@ -28,33 +28,34 @@ namespace dxvk {
|
||||
D3D9_CONVERSION_FORMAT_INFO conversionFormat,
|
||||
const Rc<DxvkImage>& dstImage,
|
||||
VkImageSubresourceLayers dstSubresource,
|
||||
const Rc<DxvkBuffer>& srcBuffer) {
|
||||
const Rc<DxvkBuffer>& srcBuffer,
|
||||
uint32_t srcBufferOffset) {
|
||||
switch (conversionFormat.FormatType) {
|
||||
case D3D9ConversionFormat_YUY2:
|
||||
case D3D9ConversionFormat_UYVY: {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
default:
|
||||
@ -68,6 +69,7 @@ namespace dxvk {
|
||||
const Rc<DxvkImage>& dstImage,
|
||||
VkImageSubresourceLayers dstSubresource,
|
||||
const Rc<DxvkBuffer>& srcBuffer,
|
||||
uint32_t srcBufferOffset,
|
||||
VkFormat bufferFormat,
|
||||
uint32_t specConstantValue,
|
||||
VkExtent2D macroPixelRun) {
|
||||
@ -89,7 +91,7 @@ namespace dxvk {
|
||||
|
||||
DxvkBufferViewCreateInfo bufferViewInfo;
|
||||
bufferViewInfo.format = bufferFormat;
|
||||
bufferViewInfo.rangeOffset = 0;
|
||||
bufferViewInfo.rangeOffset = srcBufferOffset;
|
||||
bufferViewInfo.rangeLength = srcBuffer->info().size;
|
||||
auto tmpBufferView = m_device->createBufferView(srcBuffer, bufferViewInfo);
|
||||
|
||||
|
@ -19,7 +19,8 @@ namespace dxvk {
|
||||
D3D9_CONVERSION_FORMAT_INFO conversionFormat,
|
||||
const Rc<DxvkImage>& dstImage,
|
||||
VkImageSubresourceLayers dstSubresource,
|
||||
const Rc<DxvkBuffer>& srcBuffer);
|
||||
const Rc<DxvkBuffer>& srcBuffer,
|
||||
uint32_t srcBufferOffset);
|
||||
|
||||
private:
|
||||
|
||||
@ -28,6 +29,7 @@ namespace dxvk {
|
||||
const Rc<DxvkImage>& dstImage,
|
||||
VkImageSubresourceLayers dstSubresource,
|
||||
const Rc<DxvkBuffer>& srcBuffer,
|
||||
uint32_t srcBufferOffset,
|
||||
VkFormat bufferFormat,
|
||||
uint32_t specConstantValue,
|
||||
VkExtent2D macroPixelRun);
|
||||
|
Loading…
x
Reference in New Issue
Block a user