mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[d3d9] Unify texture uploads
This commit is contained in:
parent
8b9db26536
commit
40444c1f50
@ -677,15 +677,17 @@ namespace dxvk {
|
|||||||
|
|
||||||
const DxvkFormatInfo* formatInfo = imageFormatInfo(dstTextureInfo->GetFormatMapping().FormatColor);
|
const DxvkFormatInfo* formatInfo = imageFormatInfo(dstTextureInfo->GetFormatMapping().FormatColor);
|
||||||
|
|
||||||
VkOffset3D srcBlockOffset = { 0u, 0u, 0u };
|
VkOffset3D srcOffset = { 0u, 0u, 0u };
|
||||||
VkOffset3D dstOffset = { 0u, 0u, 0u };
|
VkOffset3D dstOffset = { 0u, 0u, 0u };
|
||||||
VkExtent3D texLevelExtent = srcTextureInfo->GetExtentMip(src->GetSubresource());
|
VkExtent3D texLevelExtent = srcTextureInfo->GetExtentMip(src->GetSubresource());
|
||||||
VkExtent3D texLevelBlockCount = util::computeBlockCount(texLevelExtent, formatInfo->blockSize);
|
VkExtent3D extent = texLevelExtent;
|
||||||
|
|
||||||
VkExtent3D copyExtent = texLevelExtent;
|
|
||||||
|
|
||||||
if (pSourceRect != nullptr) {
|
if (pSourceRect != nullptr) {
|
||||||
const VkExtent3D extent = { uint32_t(pSourceRect->right - pSourceRect->left), uint32_t(pSourceRect->bottom - pSourceRect->top), 1 };
|
srcOffset = { pSourceRect->left,
|
||||||
|
pSourceRect->top,
|
||||||
|
0u };
|
||||||
|
|
||||||
|
extent = { uint32_t(pSourceRect->right - pSourceRect->left), uint32_t(pSourceRect->bottom - pSourceRect->top), 1 };
|
||||||
|
|
||||||
const bool extentAligned = extent.width % formatInfo->blockSize.width == 0
|
const bool extentAligned = extent.width % formatInfo->blockSize.width == 0
|
||||||
&& extent.height % formatInfo->blockSize.height == 0;
|
&& extent.height % formatInfo->blockSize.height == 0;
|
||||||
@ -698,14 +700,6 @@ namespace dxvk {
|
|||||||
|| pSourceRect->top % formatInfo->blockSize.height != 0
|
|| pSourceRect->top % formatInfo->blockSize.height != 0
|
||||||
|| (extent != texLevelExtent && !extentAligned))
|
|| (extent != texLevelExtent && !extentAligned))
|
||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
srcBlockOffset = { pSourceRect->left / int32_t(formatInfo->blockSize.width),
|
|
||||||
pSourceRect->top / int32_t(formatInfo->blockSize.height),
|
|
||||||
0u };
|
|
||||||
|
|
||||||
copyExtent = { extent.width,
|
|
||||||
extent.height,
|
|
||||||
1u };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDestPoint != nullptr) {
|
if (pDestPoint != nullptr) {
|
||||||
@ -720,37 +714,7 @@ namespace dxvk {
|
|||||||
0u };
|
0u };
|
||||||
}
|
}
|
||||||
|
|
||||||
VkExtent3D copyBlockCount = util::computeBlockCount(copyExtent, formatInfo->blockSize);
|
UpdateTextureFromBuffer(dstTextureInfo, srcTextureInfo, dst->GetSubresource(), src->GetSubresource(), srcOffset, extent, dstOffset);
|
||||||
|
|
||||||
const auto dstSubresource = vk::makeSubresourceLayers(
|
|
||||||
dstTextureInfo->GetSubresourceFromIndex(VK_IMAGE_ASPECT_COLOR_BIT, dst->GetSubresource()));
|
|
||||||
|
|
||||||
DxvkBufferSliceHandle srcSlice = srcTextureInfo->GetMappedSlice(src->GetSubresource());
|
|
||||||
VkDeviceSize dirtySize = copyBlockCount.width * copyBlockCount.height * formatInfo->elementSize;
|
|
||||||
D3D9BufferSlice slice = AllocTempBuffer<false>(dirtySize);
|
|
||||||
VkDeviceSize pitch = align(texLevelBlockCount.width * formatInfo->elementSize, 4);
|
|
||||||
VkDeviceSize copySrcOffset = srcBlockOffset.z * texLevelBlockCount.height * pitch
|
|
||||||
+ srcBlockOffset.y * pitch
|
|
||||||
+ srcBlockOffset.x * formatInfo->elementSize;
|
|
||||||
|
|
||||||
void* srcData = reinterpret_cast<uint8_t*>(srcSlice.mapPtr) + copySrcOffset;
|
|
||||||
util::packImageData(
|
|
||||||
slice.mapPtr, srcData, copyBlockCount, formatInfo->elementSize,
|
|
||||||
pitch, pitch * texLevelBlockCount.height);
|
|
||||||
|
|
||||||
Rc<DxvkImage> dstImage = dstTextureInfo->GetImage();
|
|
||||||
|
|
||||||
EmitCs([
|
|
||||||
cDstImage = std::move(dstImage),
|
|
||||||
cSrcSlice = slice.slice,
|
|
||||||
cDstLayers = dstSubresource,
|
|
||||||
cDstOffset = dstOffset,
|
|
||||||
cCopyExtent = copyExtent
|
|
||||||
] (DxvkContext* ctx) {
|
|
||||||
ctx->copyBufferToImage(
|
|
||||||
cDstImage, cDstLayers, cDstOffset, cCopyExtent,
|
|
||||||
cSrcSlice.buffer(), cSrcSlice.offset(), 0, 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
dstTextureInfo->SetWrittenByGPU(dst->GetSubresource(), true);
|
dstTextureInfo->SetWrittenByGPU(dst->GetSubresource(), true);
|
||||||
|
|
||||||
@ -782,7 +746,6 @@ namespace dxvk {
|
|||||||
return D3DERR_INVALIDCALL;
|
return D3DERR_INVALIDCALL;
|
||||||
|
|
||||||
const Rc<DxvkImage> dstImage = dstTexInfo->GetImage();
|
const Rc<DxvkImage> dstImage = dstTexInfo->GetImage();
|
||||||
const DxvkFormatInfo* formatInfo = imageFormatInfo(dstTexInfo->GetFormatMapping().FormatColor);
|
|
||||||
uint32_t mipLevels = dstTexInfo->Desc()->MipLevels;
|
uint32_t mipLevels = dstTexInfo->Desc()->MipLevels;
|
||||||
uint32_t arraySlices = std::min(srcTexInfo->Desc()->ArraySize, dstTexInfo->Desc()->ArraySize);
|
uint32_t arraySlices = std::min(srcTexInfo->Desc()->ArraySize, dstTexInfo->Desc()->ArraySize);
|
||||||
|
|
||||||
@ -803,61 +766,22 @@ namespace dxvk {
|
|||||||
if (box.Left >= box.Right || box.Top >= box.Bottom || box.Front >= box.Back)
|
if (box.Left >= box.Right || box.Top >= box.Bottom || box.Front >= box.Back)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
VkExtent3D mip0Extent = {
|
||||||
|
uint32_t(box.Right - box.Left),
|
||||||
|
uint32_t(box.Bottom - box.Top),
|
||||||
|
uint32_t(box.Back - box.Front)
|
||||||
|
};
|
||||||
|
VkOffset3D mip0Offset = { int32_t(box.Left), int32_t(box.Top), int32_t(box.Front) };
|
||||||
|
|
||||||
for (uint32_t dstMip = 0; dstMip < mipLevels; dstMip++) {
|
for (uint32_t dstMip = 0; dstMip < mipLevels; dstMip++) {
|
||||||
uint32_t srcMip = dstMip + srcMipOffset;
|
uint32_t srcMip = dstMip + srcMipOffset;
|
||||||
VkImageSubresourceLayers dstLayers = { VK_IMAGE_ASPECT_COLOR_BIT, dstMip, a, 1 };
|
uint32_t srcSubresource = srcTexInfo->CalcSubresource(a, srcMip);
|
||||||
|
uint32_t dstSubresource = dstTexInfo->CalcSubresource(a, dstMip);
|
||||||
|
VkExtent3D extent = util::computeMipLevelExtent(mip0Extent, srcMip);
|
||||||
|
VkOffset3D offset = util::computeMipLevelOffset(mip0Offset, srcMip);
|
||||||
|
|
||||||
VkOffset3D scaledBoxOffset = {
|
UpdateTextureFromBuffer(dstTexInfo, srcTexInfo, dstSubresource, srcSubresource, offset, extent, offset);
|
||||||
int32_t(alignDown(box.Left >> srcMip, formatInfo->blockSize.width)),
|
dstTexInfo->SetWrittenByGPU(dstSubresource, true);
|
||||||
int32_t(alignDown(box.Top >> srcMip, formatInfo->blockSize.height)),
|
|
||||||
int32_t(alignDown(box.Front >> srcMip, formatInfo->blockSize.depth))
|
|
||||||
};
|
|
||||||
VkExtent3D scaledBoxExtent = util::computeMipLevelExtent({
|
|
||||||
uint32_t(box.Right - int32_t(alignDown(box.Left, formatInfo->blockSize.width))),
|
|
||||||
uint32_t(box.Bottom - int32_t(alignDown(box.Top, formatInfo->blockSize.height))),
|
|
||||||
uint32_t(box.Back - int32_t(alignDown(box.Front, formatInfo->blockSize.depth)))
|
|
||||||
}, srcMip);
|
|
||||||
VkExtent3D scaledBoxExtentBlockCount = util::computeBlockCount(scaledBoxExtent, formatInfo->blockSize);
|
|
||||||
VkExtent3D scaledAlignedBoxExtent = util::computeBlockExtent(scaledBoxExtentBlockCount, formatInfo->blockSize);
|
|
||||||
|
|
||||||
VkExtent3D texLevelExtent = dstImage->mipLevelExtent(dstMip);
|
|
||||||
VkExtent3D texLevelExtentBlockCount = util::computeBlockCount(texLevelExtent, formatInfo->blockSize);
|
|
||||||
|
|
||||||
scaledAlignedBoxExtent.width = std::min<uint32_t>(texLevelExtent.width - scaledBoxOffset.x, scaledAlignedBoxExtent.width);
|
|
||||||
scaledAlignedBoxExtent.height = std::min<uint32_t>(texLevelExtent.height - scaledBoxOffset.y, scaledAlignedBoxExtent.height);
|
|
||||||
scaledAlignedBoxExtent.depth = std::min<uint32_t>(texLevelExtent.depth - scaledBoxOffset.z, scaledAlignedBoxExtent.depth);
|
|
||||||
|
|
||||||
VkDeviceSize dirtySize = scaledBoxExtentBlockCount.width * scaledBoxExtentBlockCount.height * scaledBoxExtentBlockCount.depth * formatInfo->elementSize;
|
|
||||||
D3D9BufferSlice slice = AllocTempBuffer<false>(dirtySize);
|
|
||||||
VkOffset3D boxOffsetBlockCount = util::computeBlockOffset(scaledBoxOffset, formatInfo->blockSize);
|
|
||||||
VkDeviceSize pitch = align(texLevelExtentBlockCount.width * formatInfo->elementSize, 4);
|
|
||||||
VkDeviceSize copySrcOffset = boxOffsetBlockCount.z * texLevelExtentBlockCount.height * pitch
|
|
||||||
+ boxOffsetBlockCount.y * pitch
|
|
||||||
+ boxOffsetBlockCount.x * formatInfo->elementSize;
|
|
||||||
|
|
||||||
void* srcData = reinterpret_cast<uint8_t*>(srcTexInfo->GetMappedSlice(srcTexInfo->CalcSubresource(a, srcMip)).mapPtr) + copySrcOffset;
|
|
||||||
util::packImageData(
|
|
||||||
slice.mapPtr, srcData, scaledBoxExtentBlockCount, formatInfo->elementSize,
|
|
||||||
pitch, pitch * texLevelExtentBlockCount.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);
|
|
||||||
|
|
||||||
EmitCs([
|
|
||||||
cDstImage = dstImage,
|
|
||||||
cSrcSlice = slice.slice,
|
|
||||||
cDstLayers = dstLayers,
|
|
||||||
cExtent = scaledAlignedBoxExtent,
|
|
||||||
cOffset = scaledBoxOffset
|
|
||||||
] (DxvkContext* ctx) {
|
|
||||||
ctx->copyBufferToImage(
|
|
||||||
cDstImage, cDstLayers,
|
|
||||||
cOffset, cExtent,
|
|
||||||
cSrcSlice.buffer(), cSrcSlice.offset(), 0, 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
dstTexInfo->SetWrittenByGPU(dstTexInfo->CalcSubresource(a, dstMip), true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4443,65 +4367,97 @@ 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,
|
|
||||||
// we need to copy its contents into the image
|
|
||||||
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(
|
||||||
formatInfo->aspectMask, Subresource);
|
formatInfo->aspectMask, Subresource);
|
||||||
|
|
||||||
VkImageSubresourceLayers subresourceLayers = {
|
const D3DBOX& box = pResource->GetDirtyBox(subresource.arrayLayer);
|
||||||
subresource.aspectMask,
|
|
||||||
subresource.mipLevel,
|
|
||||||
subresource.arrayLayer, 1 };
|
|
||||||
|
|
||||||
auto convertFormat = pResource->GetFormatMapping().ConversionFormatInfo;
|
VkExtent3D mip0Extent = { box.Right - box.Left, box.Bottom - box.Top, box.Back - box.Front };
|
||||||
|
VkExtent3D extent = util::computeMipLevelExtent(mip0Extent, subresource.mipLevel);
|
||||||
|
VkOffset3D mip0Offset = { int32_t(box.Left), int32_t(box.Top), int32_t(box.Front) };
|
||||||
|
VkOffset3D offset = util::computeMipLevelOffset(mip0Offset, subresource.mipLevel);
|
||||||
|
|
||||||
|
UpdateTextureFromBuffer(pResource, pResource, Subresource, Subresource, offset, extent, offset);
|
||||||
|
|
||||||
|
if (pResource->IsAutomaticMip())
|
||||||
|
MarkTextureMipsDirty(pResource);
|
||||||
|
|
||||||
|
return D3D_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void D3D9DeviceEx::UpdateTextureFromBuffer(
|
||||||
|
D3D9CommonTexture* pDestTexture,
|
||||||
|
D3D9CommonTexture* pSrcTexture,
|
||||||
|
UINT DestSubresource,
|
||||||
|
UINT SrcSubresource,
|
||||||
|
VkOffset3D SrcOffset,
|
||||||
|
VkExtent3D SrcExtent,
|
||||||
|
VkOffset3D DestOffset
|
||||||
|
) {
|
||||||
|
const Rc<DxvkImage> image = pDestTexture->GetImage();
|
||||||
|
|
||||||
|
// Now that data has been written into the buffer,
|
||||||
|
// we need to copy its contents into the image
|
||||||
|
const DxvkBufferSliceHandle srcSlice = pSrcTexture->GetMappedSlice(SrcSubresource);
|
||||||
|
|
||||||
|
auto formatInfo = imageFormatInfo(image->info().format);
|
||||||
|
auto srcSubresource = pSrcTexture->GetSubresourceFromIndex(
|
||||||
|
formatInfo->aspectMask, SrcSubresource);
|
||||||
|
|
||||||
|
auto dstSubresource = pDestTexture->GetSubresourceFromIndex(
|
||||||
|
formatInfo->aspectMask, DestSubresource);
|
||||||
|
VkImageSubresourceLayers dstLayers = { dstSubresource.aspectMask, dstSubresource.mipLevel, dstSubresource.arrayLayer, 1 };
|
||||||
|
|
||||||
|
VkExtent3D dstTexLevelExtent = image->mipLevelExtent(dstSubresource.mipLevel);
|
||||||
|
VkExtent3D srcTexLevelExtent = util::computeMipLevelExtent(pSrcTexture->GetExtent(), srcSubresource.mipLevel);
|
||||||
|
VkExtent3D srcTexLevelExtentBlockCount = util::computeBlockCount(srcTexLevelExtent, formatInfo->blockSize);
|
||||||
|
|
||||||
|
auto convertFormat = pDestTexture->GetFormatMapping().ConversionFormatInfo;
|
||||||
|
|
||||||
if (likely(convertFormat.FormatType == D3D9ConversionFormat_None)) {
|
if (likely(convertFormat.FormatType == D3D9ConversionFormat_None)) {
|
||||||
VkImageSubresourceLayers dstLayers = { VK_IMAGE_ASPECT_COLOR_BIT, subresource.mipLevel, subresource.arrayLayer, 1 };
|
VkOffset3D alignedDestOffset = {
|
||||||
|
int32_t(alignDown(DestOffset.x, formatInfo->blockSize.width)),
|
||||||
const D3DBOX& box = pResource->GetDirtyBox(subresource.arrayLayer);
|
int32_t(alignDown(DestOffset.y, formatInfo->blockSize.height)),
|
||||||
VkOffset3D scaledBoxOffset = {
|
int32_t(alignDown(DestOffset.z, formatInfo->blockSize.depth))
|
||||||
int32_t(alignDown(box.Left >> subresource.mipLevel, formatInfo->blockSize.width)),
|
|
||||||
int32_t(alignDown(box.Top >> subresource.mipLevel, formatInfo->blockSize.height)),
|
|
||||||
int32_t(alignDown(box.Front >> subresource.mipLevel, formatInfo->blockSize.depth))
|
|
||||||
};
|
};
|
||||||
VkExtent3D scaledBoxExtent = util::computeMipLevelExtent({
|
VkOffset3D alignedSrcOffset = {
|
||||||
uint32_t(box.Right - int32_t(alignDown(box.Left, formatInfo->blockSize.width))),
|
int32_t(alignDown(SrcOffset.x, formatInfo->blockSize.width)),
|
||||||
uint32_t(box.Bottom - int32_t(alignDown(box.Top, formatInfo->blockSize.height))),
|
int32_t(alignDown(SrcOffset.y, formatInfo->blockSize.height)),
|
||||||
uint32_t(box.Back - int32_t(alignDown(box.Front, formatInfo->blockSize.depth)))
|
int32_t(alignDown(SrcOffset.z, formatInfo->blockSize.depth))
|
||||||
}, subresource.mipLevel);
|
};
|
||||||
VkExtent3D scaledBoxExtentBlockCount = util::computeBlockCount(scaledBoxExtent, formatInfo->blockSize);
|
SrcExtent.width += SrcOffset.x - alignedSrcOffset.x;
|
||||||
VkExtent3D scaledAlignedBoxExtent = util::computeBlockExtent(scaledBoxExtentBlockCount, formatInfo->blockSize);
|
SrcExtent.height += SrcOffset.y - alignedSrcOffset.y;
|
||||||
|
SrcExtent.depth += SrcOffset.z - alignedSrcOffset.z;
|
||||||
|
VkExtent3D extentBlockCount = util::computeBlockCount(SrcExtent, formatInfo->blockSize);
|
||||||
|
VkExtent3D alignedExtent = util::computeBlockExtent(extentBlockCount, formatInfo->blockSize);
|
||||||
|
|
||||||
VkExtent3D texLevelExtent = image->mipLevelExtent(subresource.mipLevel);
|
alignedExtent = util::snapExtent3D(alignedDestOffset, alignedExtent, dstTexLevelExtent);
|
||||||
VkExtent3D texLevelExtentBlockCount = util::computeBlockCount(texLevelExtent, formatInfo->blockSize);
|
alignedExtent = util::snapExtent3D(alignedSrcOffset, alignedExtent, srcTexLevelExtent);
|
||||||
|
|
||||||
scaledAlignedBoxExtent.width = std::min<uint32_t>(texLevelExtent.width - scaledBoxOffset.x, scaledAlignedBoxExtent.width);
|
VkOffset3D srcOffsetBlockCount = util::computeBlockOffset(alignedSrcOffset, formatInfo->blockSize);
|
||||||
scaledAlignedBoxExtent.height = std::min<uint32_t>(texLevelExtent.height - scaledBoxOffset.y, scaledAlignedBoxExtent.height);
|
VkExtent3D srcTexLevelExtentBlockCount = util::computeBlockCount(srcTexLevelExtent, formatInfo->blockSize);
|
||||||
scaledAlignedBoxExtent.depth = std::min<uint32_t>(texLevelExtent.depth - scaledBoxOffset.z, scaledAlignedBoxExtent.depth);
|
VkDeviceSize pitch = align(srcTexLevelExtentBlockCount.width * formatInfo->elementSize, 4);
|
||||||
|
VkDeviceSize copySrcOffset = srcOffsetBlockCount.z * srcTexLevelExtentBlockCount.height * pitch
|
||||||
|
+ srcOffsetBlockCount.y * pitch
|
||||||
|
+ srcOffsetBlockCount.x * formatInfo->elementSize;
|
||||||
|
|
||||||
VkOffset3D boxOffsetBlockCount = util::computeBlockOffset(scaledBoxOffset, formatInfo->blockSize);
|
VkDeviceSize rowAlignment = 1;
|
||||||
VkDeviceSize pitch = align(texLevelExtentBlockCount.width * formatInfo->elementSize, 4);
|
|
||||||
VkDeviceSize copySrcOffset = boxOffsetBlockCount.z * texLevelExtentBlockCount.height * pitch
|
|
||||||
+ boxOffsetBlockCount.y * pitch
|
|
||||||
+ boxOffsetBlockCount.x * formatInfo->elementSize;
|
|
||||||
|
|
||||||
VkDeviceSize rowAlignment = 0;
|
|
||||||
DxvkBufferSlice copySrcSlice;
|
DxvkBufferSlice copySrcSlice;
|
||||||
if (pResource->DoesStagingBufferUploads(Subresource)) {
|
if (pSrcTexture->DoesStagingBufferUploads(SrcSubresource)) {
|
||||||
VkDeviceSize dirtySize = scaledBoxExtentBlockCount.width * scaledBoxExtentBlockCount.height * scaledBoxExtentBlockCount.depth * formatInfo->elementSize;
|
VkDeviceSize dirtySize = extentBlockCount.width * extentBlockCount.height * extentBlockCount.depth * formatInfo->elementSize;
|
||||||
D3D9BufferSlice slice = AllocTempBuffer<false>(dirtySize);
|
D3D9BufferSlice slice = AllocTempBuffer<false>(dirtySize);
|
||||||
copySrcSlice = slice.slice;
|
copySrcSlice = slice.slice;
|
||||||
void* srcData = reinterpret_cast<uint8_t*>(srcSlice.mapPtr) + copySrcOffset;
|
void* srcData = reinterpret_cast<uint8_t*>(srcSlice.mapPtr) + copySrcOffset;
|
||||||
util::packImageData(
|
util::packImageData(
|
||||||
slice.mapPtr, srcData, scaledBoxExtentBlockCount, formatInfo->elementSize,
|
slice.mapPtr, srcData, extentBlockCount, formatInfo->elementSize,
|
||||||
pitch, pitch * texLevelExtentBlockCount.height);
|
pitch, pitch * srcTexLevelExtentBlockCount.height);
|
||||||
} else {
|
} else {
|
||||||
copySrcSlice = DxvkBufferSlice(pResource->GetBuffer(Subresource), copySrcOffset, srcSlice.length);
|
TrackTextureMappingBufferSequenceNumber(pSrcTexture, SrcSubresource);
|
||||||
|
|
||||||
|
copySrcSlice = DxvkBufferSlice(pSrcTexture->GetBuffer(SrcSubresource), copySrcOffset, srcSlice.length);
|
||||||
rowAlignment = pitch; // row alignment can act as the pitch parameter
|
rowAlignment = pitch; // row alignment can act as the pitch parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4509,8 +4465,8 @@ namespace dxvk {
|
|||||||
cSrcSlice = std::move(copySrcSlice),
|
cSrcSlice = std::move(copySrcSlice),
|
||||||
cDstImage = image,
|
cDstImage = image,
|
||||||
cDstLayers = dstLayers,
|
cDstLayers = dstLayers,
|
||||||
cDstLevelExtent = scaledAlignedBoxExtent,
|
cDstLevelExtent = alignedExtent,
|
||||||
cOffset = scaledBoxOffset,
|
cOffset = alignedDestOffset,
|
||||||
cRowAlignment = rowAlignment
|
cRowAlignment = rowAlignment
|
||||||
] (DxvkContext* ctx) {
|
] (DxvkContext* ctx) {
|
||||||
ctx->copyBufferToImage(
|
ctx->copyBufferToImage(
|
||||||
@ -4521,39 +4477,41 @@ namespace dxvk {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const DxvkFormatInfo* formatInfo = imageFormatInfo(pResource->GetFormatMapping().FormatColor);
|
const DxvkFormatInfo* formatInfo = imageFormatInfo(pDestTexture->GetFormatMapping().FormatColor);
|
||||||
VkExtent3D texLevelExtent = image->mipLevelExtent(subresource.mipLevel);
|
|
||||||
VkExtent3D texLevelExtentBlockCount = util::computeBlockCount(texLevelExtent, formatInfo->blockSize);
|
|
||||||
// Add more blocks for the other planes that we might have.
|
// Add more blocks for the other planes that we might have.
|
||||||
// TODO: PLEASE CLEAN ME
|
// TODO: PLEASE CLEAN ME
|
||||||
texLevelExtentBlockCount.height *= std::min(convertFormat.PlaneCount, 2u);
|
srcTexLevelExtentBlockCount.height *= std::min(convertFormat.PlaneCount, 2u);
|
||||||
|
|
||||||
|
if (unlikely(SrcOffset.x != 0 || SrcOffset.y != 0 || SrcOffset.z != 0
|
||||||
|
|| DestOffset.x != 0 || DestOffset.y != 0 || DestOffset.z != 0
|
||||||
|
|| SrcExtent != srcTexLevelExtent)) {
|
||||||
|
Logger::warn("Offset and rect not supported with the texture converter.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(srcTexLevelExtent != dstTexLevelExtent)) {
|
||||||
|
Logger::err("Different extents are not supported with the texture converter.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// the converter can not handle the 4 aligned pitch so we always repack into a staging buffer
|
// the converter can not handle the 4 aligned pitch so we always repack into a staging buffer
|
||||||
D3D9BufferSlice slice = AllocTempBuffer<false>(srcSlice.length);
|
D3D9BufferSlice slice = AllocTempBuffer<false>(srcSlice.length);
|
||||||
VkDeviceSize pitch = align(texLevelExtentBlockCount.width * formatInfo->elementSize, 4);
|
VkDeviceSize pitch = align(srcTexLevelExtentBlockCount.width * formatInfo->elementSize, 4);
|
||||||
|
|
||||||
util::packImageData(
|
util::packImageData(
|
||||||
slice.mapPtr, srcSlice.mapPtr, texLevelExtentBlockCount, formatInfo->elementSize,
|
slice.mapPtr, srcSlice.mapPtr, srcTexLevelExtentBlockCount, formatInfo->elementSize,
|
||||||
pitch, std::min(convertFormat.PlaneCount, 2u) * pitch * texLevelExtentBlockCount.height);
|
pitch, std::min(convertFormat.PlaneCount, 2u) * pitch * srcTexLevelExtentBlockCount.height);
|
||||||
|
|
||||||
Flush();
|
Flush();
|
||||||
SynchronizeCsThread(DxvkCsThread::SynchronizeAll);
|
SynchronizeCsThread(DxvkCsThread::SynchronizeAll);
|
||||||
|
|
||||||
m_converter->ConvertFormat(
|
m_converter->ConvertFormat(
|
||||||
convertFormat,
|
convertFormat,
|
||||||
image, subresourceLayers,
|
image, dstLayers,
|
||||||
slice.slice);
|
slice.slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pResource->IsAutomaticMip())
|
|
||||||
MarkTextureMipsDirty(pResource);
|
|
||||||
|
|
||||||
TrackTextureMappingBufferSequenceNumber(pResource, Subresource);
|
|
||||||
|
|
||||||
return D3D_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void D3D9DeviceEx::EmitGenerateMips(
|
void D3D9DeviceEx::EmitGenerateMips(
|
||||||
D3D9CommonTexture* pResource) {
|
D3D9CommonTexture* pResource) {
|
||||||
if (pResource->IsManaged())
|
if (pResource->IsManaged())
|
||||||
|
@ -704,6 +704,15 @@ namespace dxvk {
|
|||||||
D3D9CommonTexture* pResource,
|
D3D9CommonTexture* pResource,
|
||||||
UINT Subresource);
|
UINT Subresource);
|
||||||
|
|
||||||
|
void UpdateTextureFromBuffer(
|
||||||
|
D3D9CommonTexture* pDestTexture,
|
||||||
|
D3D9CommonTexture* pSrcTexture,
|
||||||
|
UINT DestSubresource,
|
||||||
|
UINT SrcSubresource,
|
||||||
|
VkOffset3D SrcOffset,
|
||||||
|
VkExtent3D SrcExtent,
|
||||||
|
VkOffset3D DestOffset);
|
||||||
|
|
||||||
void EmitGenerateMips(
|
void EmitGenerateMips(
|
||||||
D3D9CommonTexture* pResource);
|
D3D9CommonTexture* pResource);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user