1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-05 01:24:14 +01:00

[d3d9] Use DxvkFormatInfo for video formats

And fix UYUY and YUY2 in the process.
This commit is contained in:
Robin Kertels 2023-04-08 03:15:39 +02:00 committed by Joshie
parent 31af522cbc
commit af0009c5de
5 changed files with 68 additions and 37 deletions

View File

@ -238,13 +238,21 @@ namespace dxvk {
const VkExtent3D mipExtent = util::computeMipLevelExtent(
GetExtent(), MipLevel);
VkExtent3D blockSize = formatInfo->blockSize;
uint32_t elementSize = formatInfo->elementSize;
if (unlikely(formatInfo->flags.test(DxvkFormatFlag::MultiPlane))) {
// D3D9 doesn't allow specifying the plane when locking a texture.
// So the subsampled planes inherit the pitch of the first plane.
// That means the size is the size of plane 0 * plane count
elementSize = formatInfo->planes[0].elementSize;
blockSize = { formatInfo->planes[0].blockSize.width, formatInfo->planes[0].blockSize.height, 1u };
}
const VkExtent3D blockCount = util::computeBlockCount(
mipExtent, formatInfo->blockSize);
mipExtent, blockSize);
const uint32_t planeCount = m_mapping.ConversionFormatInfo.PlaneCount;
return std::min(planeCount, 2u)
* align(formatInfo->elementSize * blockCount.width, 4)
return std::min(GetPlaneCount(), 2u)
* align(elementSize * blockCount.width, 4)
* blockCount.height
* blockCount.depth;
}
@ -675,4 +683,13 @@ namespace dxvk {
return DxvkBufferSlice(GetBuffer(), m_memoryOffset[Subresource], GetMipSize(Subresource));
}
uint32_t D3D9CommonTexture::GetPlaneCount() const {
const DxvkFormatInfo* formatInfo = m_mapping.FormatColor != VK_FORMAT_UNDEFINED
? lookupFormatInfo(m_mapping.FormatColor)
: m_device->UnsupportedFormatInfo(m_desc.Format);
return vk::getPlaneCount(formatInfo->aspectMask);
}
}

View File

@ -315,6 +315,8 @@ namespace dxvk {
return m_type;
}
uint32_t GetPlaneCount() const;
const D3D9_VK_FORMAT_MAPPING& GetMapping() { return m_mapping; }
void SetLocked(UINT Subresource, bool value) { m_locked.set(Subresource, value); }

View File

@ -4229,10 +4229,15 @@ namespace dxvk {
if (FormatInfo != nullptr) {
elementSize = FormatInfo->elementSize;
VkExtent3D blockSize = FormatInfo->blockSize;
if (unlikely(FormatInfo->flags.test(DxvkFormatFlag::MultiPlane))) {
elementSize = FormatInfo->planes[0].elementSize;
blockSize = { FormatInfo->planes[0].blockSize.width, FormatInfo->planes[0].blockSize.height, 1u };
}
offsets[0] = offsets[0] / FormatInfo->blockSize.depth;
offsets[1] = offsets[1] / FormatInfo->blockSize.height;
offsets[2] = offsets[2] / FormatInfo->blockSize.width;
offsets[0] = offsets[0] / blockSize.depth;
offsets[1] = offsets[1] / blockSize.height;
offsets[2] = offsets[2] / blockSize.width;
}
return offsets[0] * SlicePitch +
@ -4419,10 +4424,16 @@ namespace dxvk {
pLockedBox->RowPitch = align(std::max(desc.Width >> MipLevel, 1u), 4);
pLockedBox->SlicePitch = pLockedBox->RowPitch * std::max(desc.Height >> MipLevel, 1u);
}
else {
// Data is tightly packed within the mapped buffer.
else if (likely(!formatInfo->flags.test(DxvkFormatFlag::MultiPlane))) {
pLockedBox->RowPitch = align(formatInfo->elementSize * blockCount.width, 4);
pLockedBox->SlicePitch = pLockedBox->RowPitch * blockCount.height;
} else {
auto plane = &formatInfo->planes[0];
uint32_t planeElementSize = plane->elementSize;
VkExtent3D planeBlockSize = { plane->blockSize.width, plane->blockSize.height, 1u };
VkExtent3D blockCount = util::computeBlockCount(levelExtent, planeBlockSize);
pLockedBox->RowPitch = align(planeElementSize * blockCount.width, 4);
pLockedBox->SlicePitch = pLockedBox->RowPitch * blockCount.height;
}
pResource->SetLocked(Subresource, true);
@ -4555,7 +4566,7 @@ namespace dxvk {
// Now that data has been written into the buffer,
// we need to copy its contents into the image
auto formatInfo = lookupFormatInfo(image->info().format);
auto formatInfo = lookupFormatInfo(pDestTexture->GetFormatMapping().FormatColor);
auto srcSubresource = pSrcTexture->GetSubresourceFromIndex(
formatInfo->aspectMask, SrcSubresource);
@ -4565,7 +4576,6 @@ namespace dxvk {
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;
@ -4613,8 +4623,7 @@ namespace dxvk {
slice.mapPtr, srcData, extentBlockCount, formatInfo->elementSize,
pitch, pitch * srcTexLevelExtentBlockCount.height);
VkFormat packedFormat = GetPackedDepthStencilFormat(pDestTexture->Desc()->Format);
VkFormat packedDSFormat = GetPackedDepthStencilFormat(pDestTexture->Desc()->Format);
EmitCs([
cSrcSlice = slice.slice,
@ -4622,7 +4631,7 @@ namespace dxvk {
cDstLayers = dstLayers,
cDstLevelExtent = alignedExtent,
cOffset = alignedDestOffset,
cPackedFormat = packedFormat
cPackedDSFormat = packedDSFormat
] (DxvkContext* ctx) {
if (cDstLayers.aspectMask != (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
ctx->copyBufferToImage(
@ -4638,20 +4647,15 @@ namespace dxvk {
cSrcSlice.buffer(), cSrcSlice.offset(),
VkOffset2D { 0, 0 },
VkExtent2D { cDstLevelExtent.width, cDstLevelExtent.height },
cPackedFormat);
cPackedDSFormat);
}
});
TrackTextureMappingBufferSequenceNumber(pSrcTexture, SrcSubresource);
}
else {
const DxvkFormatInfo* formatInfo = lookupFormatInfo(pDestTexture->GetFormatMapping().FormatColor);
const void* mapPtr = MapTexture(pSrcTexture, SrcSubresource);
// Add more blocks for the other planes that we might have.
// TODO: PLEASE CLEAN ME
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)) {
@ -4663,13 +4667,22 @@ namespace dxvk {
return;
}
uint32_t formatElementSize = formatInfo->elementSize;
VkExtent3D srcBlockSize = formatInfo->blockSize;
if (formatInfo->flags.test(DxvkFormatFlag::MultiPlane)) {
formatElementSize = formatInfo->planes[0].elementSize;
srcBlockSize = { formatInfo->planes[0].blockSize.width, formatInfo->planes[0].blockSize.height, 1u };
}
VkExtent3D srcBlockCount = util::computeBlockCount(srcTexLevelExtent, srcBlockSize);
srcBlockCount.height *= std::min(pSrcTexture->GetPlaneCount(), 2u);
// the converter can not handle the 4 aligned pitch so we always repack into a staging buffer
D3D9BufferSlice slice = AllocStagingBuffer(pSrcTexture->GetMipSize(SrcSubresource));
VkDeviceSize pitch = align(srcTexLevelExtentBlockCount.width * formatInfo->elementSize, 4);
VkDeviceSize pitch = align(srcBlockCount.width * formatElementSize, 4);
util::packImageData(
slice.mapPtr, mapPtr, srcTexLevelExtentBlockCount, formatInfo->elementSize,
pitch, std::min(convertFormat.PlaneCount, 2u) * pitch * srcTexLevelExtentBlockCount.height);
slice.mapPtr, mapPtr, srcBlockCount, formatElementSize,
pitch, std::min(pSrcTexture->GetPlaneCount(), 2u) * pitch * srcBlockCount.height);
Flush();
SynchronizeCsThread(DxvkCsThread::SynchronizeAll);

View File

@ -132,7 +132,7 @@ namespace dxvk {
VK_IMAGE_ASPECT_COLOR_BIT,
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A },
{ D3D9ConversionFormat_L6V5U5, 1u,
{ D3D9ConversionFormat_L6V5U5,
// Convert -> float (this is a mixed snorm and unorm type)
VK_FORMAT_R16G16B16A16_SFLOAT } };
@ -142,7 +142,7 @@ namespace dxvk {
VK_IMAGE_ASPECT_COLOR_BIT,
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE },
{ D3D9ConversionFormat_X8L8V8U8, 1u,
{ D3D9ConversionFormat_X8L8V8U8,
// Convert -> float (this is a mixed snorm and unorm type)
VK_FORMAT_R16G16B16A16_SFLOAT } };
@ -164,7 +164,7 @@ namespace dxvk {
VK_IMAGE_ASPECT_COLOR_BIT,
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A },
{ D3D9ConversionFormat_A2W10V10U10, 1u,
{ D3D9ConversionFormat_A2W10V10U10,
// Convert -> float (this is a mixed snorm and unorm type)
VK_FORMAT_R16G16B16A16_SFLOAT } };
@ -174,17 +174,17 @@ namespace dxvk {
VK_IMAGE_ASPECT_COLOR_BIT,
{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE },
{ D3D9ConversionFormat_W11V11U10, 1u,
{ D3D9ConversionFormat_W11V11U10,
// can't use B10G11R11 bc this is a snorm type
VK_FORMAT_R16G16B16A16_SNORM } };
case D3D9Format::UYVY: return {
VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_G8B8G8R8_422_UNORM,
VK_FORMAT_UNDEFINED,
VK_IMAGE_ASPECT_COLOR_BIT,
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },
{ D3D9ConversionFormat_UYVY, 1u }
{ D3D9ConversionFormat_UYVY, VK_FORMAT_B8G8R8A8_UNORM }
};
case D3D9Format::R8G8_B8G8: return {
@ -193,12 +193,12 @@ namespace dxvk {
VK_IMAGE_ASPECT_COLOR_BIT };
case D3D9Format::YUY2: return {
VK_FORMAT_B8G8R8A8_UNORM,
VK_FORMAT_G8B8G8R8_422_UNORM,
VK_FORMAT_UNDEFINED,
VK_IMAGE_ASPECT_COLOR_BIT,
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },
{ D3D9ConversionFormat_YUY2, 1u }
{ D3D9ConversionFormat_YUY2, VK_FORMAT_B8G8R8A8_UNORM }
};
case D3D9Format::G8R8_G8B8: return {
@ -410,21 +410,21 @@ namespace dxvk {
VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R }};
case D3D9Format::NV12: return {
VK_FORMAT_R8_UNORM,
VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
VK_FORMAT_UNDEFINED,
VK_IMAGE_ASPECT_COLOR_BIT,
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },
{ D3D9ConversionFormat_NV12, 2u, VK_FORMAT_B8G8R8A8_UNORM }
{ D3D9ConversionFormat_NV12, VK_FORMAT_B8G8R8A8_UNORM }
};
case D3D9Format::YV12: return {
VK_FORMAT_R8_UNORM,
VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
VK_FORMAT_UNDEFINED,
VK_IMAGE_ASPECT_COLOR_BIT,
{ VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY },
{ D3D9ConversionFormat_YV12, 3u, VK_FORMAT_B8G8R8A8_UNORM }
{ D3D9ConversionFormat_YV12, VK_FORMAT_B8G8R8A8_UNORM }
};
case D3D9Format::RAWZ: return {}; // Unsupported

View File

@ -143,7 +143,6 @@ namespace dxvk {
struct D3D9_CONVERSION_FORMAT_INFO {
D3D9ConversionFormat FormatType = D3D9ConversionFormat_None;
uint32_t PlaneCount = 1;
VkFormat FormatColor = VK_FORMAT_UNDEFINED;
VkFormat FormatSrgb = VK_FORMAT_UNDEFINED;
};