1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-20 19:54:19 +01:00

[d3d9] Check block alignment on texture creation with DXT formats

This commit is contained in:
WinterSnowfall 2024-10-06 13:47:58 +03:00 committed by Philip Rebohle
parent 1689cacc47
commit 559398f6a4
3 changed files with 47 additions and 0 deletions

View File

@ -156,6 +156,16 @@ namespace dxvk {
if (pDesc->Width == 0 || pDesc->Height == 0 || pDesc->Depth == 0)
return D3DERR_INVALIDCALL;
// Native drivers won't allow the creation of DXT format
// textures that aren't aligned to block dimensions.
if (IsDXTFormat(pDesc->Format)) {
D3D9_FORMAT_BLOCK_SIZE blockSize = GetFormatBlockSize(pDesc->Format);
if ((blockSize.Width && (pDesc->Width & (blockSize.Width - 1)))
|| (blockSize.Height && (pDesc->Height & (blockSize.Height - 1))))
return D3DERR_INVALIDCALL;
}
if (FAILED(DecodeMultiSampleType(pDevice->GetDXVKDevice(), pDesc->MultiSample, pDesc->MultisampleQuality, nullptr)))
return D3DERR_INVALIDCALL;

View File

@ -439,6 +439,27 @@ namespace dxvk {
}
}
// Block size of formats that require some form of alignment
D3D9_FORMAT_BLOCK_SIZE GetFormatBlockSize(D3D9Format Format) {
switch (Format) {
case D3D9Format::DXT1:
case D3D9Format::DXT2:
case D3D9Format::DXT3:
case D3D9Format::DXT4:
case D3D9Format::DXT5:
case D3D9Format::ATI1:
case D3D9Format::ATI2:
return { 4, 4, 1 };
case D3D9Format::YUY2:
case D3D9Format::UYVY:
return { 2, 1, 1 };
default:
return {}; // Irrelevant or unknown block size
}
}
D3D9VkFormatTable::D3D9VkFormatTable(
const Rc<DxvkAdapter>& adapter,
const D3D9Options& options) {

View File

@ -147,6 +147,12 @@ namespace dxvk {
VkFormat FormatSrgb = VK_FORMAT_UNDEFINED;
};
struct D3D9_FORMAT_BLOCK_SIZE {
uint8_t Width = 0;
uint8_t Height = 0;
uint8_t Depth = 0;
};
/**
* \brief Format mapping
*
@ -171,6 +177,8 @@ namespace dxvk {
D3D9_VK_FORMAT_MAPPING ConvertFormatUnfixed(D3D9Format Format);
D3D9_FORMAT_BLOCK_SIZE GetFormatBlockSize(D3D9Format Format);
/**
* \brief Format table
*
@ -239,4 +247,12 @@ namespace dxvk {
&& format != D3D9Format::DXT5;
}
inline bool IsDXTFormat(D3D9Format format) {
return format == D3D9Format::DXT1
|| format == D3D9Format::DXT2
|| format == D3D9Format::DXT3
|| format == D3D9Format::DXT4
|| format == D3D9Format::DXT5;
}
}