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:
parent
31af522cbc
commit
af0009c5de
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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); }
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user