Skip to content
This repository has been archived by the owner on Jan 21, 2025. It is now read-only.

Commit

Permalink
[d3d9] Support unsupported formats for D3DPOOL_SCRATCH
Browse files Browse the repository at this point in the history
Impacts #417
  • Loading branch information
misyltoad committed Nov 20, 2019
1 parent 81a2425 commit 2fbf8a5
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 51 deletions.
5 changes: 5 additions & 0 deletions src/d3d9/d3d9_adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ namespace dxvk {
return m_d3d9Formats.GetFormatMapping(Format);
}

DxvkFormatInfo GetUnsupportedFormatInfo(
D3D9Format Format) const {
return m_d3d9Formats.GetUnsupportedFormatInfo(Format);
}

private:

HRESULT CheckDeviceVkFormat(
Expand Down
44 changes: 39 additions & 5 deletions src/d3d9/d3d9_common_texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,39 @@ namespace dxvk {
}


HRESULT D3D9CommonTexture::NormalizeTextureProperties(D3D9_COMMON_TEXTURE_DESC* pDesc) {
HRESULT D3D9CommonTexture::NormalizeTextureProperties(
D3D9DeviceEx* pDevice,
D3D9_COMMON_TEXTURE_DESC* pDesc,
D3D9_VK_FORMAT_MAPPING* pMapping) {
auto* options = pDevice->GetOptions();

//////////////////////
// Mapping Validation

*pMapping = pDevice->LookupFormat(pDesc->Format);

// Handle DisableA8RT hack for The Sims 2
if (pDesc->Format == D3D9Format::A8 &&
(pDesc->Usage & D3DUSAGE_RENDERTARGET) &&
options->disableA8RT)
return D3DERR_INVALIDCALL;

// If the mapping is invalid then lets return invalid
// Some edge cases:
// NULL format does not map to anything, but should succeed
// SCRATCH textures can still be made if the device does not support
// the format at all.

if (!pMapping->IsValid() && pDesc->Format != D3D9Format::NULL_FORMAT) {
auto info = pDevice->UnsupportedFormatInfo(pDesc->Format);

if (pDesc->Pool != D3DPOOL_SCRATCH || info.elementSize == 0)
return D3DERR_INVALIDCALL;
}

///////////////////
// Desc Validation

if (pDesc->Width == 0 || pDesc->Height == 0 || pDesc->Depth == 0)
return D3DERR_INVALIDCALL;

Expand Down Expand Up @@ -96,7 +128,7 @@ namespace dxvk {

if (pDesc->MipLevels == 0 || pDesc->MipLevels > maxMipLevelCount)
pDesc->MipLevels = maxMipLevelCount;

return D3D_OK;
}

Expand Down Expand Up @@ -135,15 +167,17 @@ namespace dxvk {
VkDeviceSize D3D9CommonTexture::GetMipSize(UINT Subresource) const {
const UINT MipLevel = Subresource % m_desc.MipLevels;

const DxvkFormatInfo* formatInfo = imageFormatInfo(m_mapping.FormatColor);
const DxvkFormatInfo formatInfo = m_mapping.FormatColor != VK_FORMAT_UNDEFINED
? *imageFormatInfo(m_mapping.FormatColor)
: m_device->UnsupportedFormatInfo(m_desc.Format);

const VkExtent3D mipExtent = util::computeMipLevelExtent(
m_adjustedExtent, MipLevel);

const VkExtent3D blockCount = util::computeBlockCount(
mipExtent, formatInfo->blockSize);
mipExtent, formatInfo.blockSize);

return formatInfo->elementSize
return formatInfo.elementSize
* blockCount.width
* blockCount.height
* blockCount.depth;
Expand Down
4 changes: 3 additions & 1 deletion src/d3d9/d3d9_common_texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@ namespace dxvk {
* \returns \c S_OK if the parameters are valid
*/
static HRESULT NormalizeTextureProperties(
D3D9_COMMON_TEXTURE_DESC* pDesc);
D3D9DeviceEx* pDevice,
D3D9_COMMON_TEXTURE_DESC* pDesc,
D3D9_VK_FORMAT_MAPPING* pMapping);

/**
* \brief Lock Flags
Expand Down
62 changes: 17 additions & 45 deletions src/d3d9/d3d9_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,16 +405,8 @@ namespace dxvk {
desc.MultiSample = D3DMULTISAMPLE_NONE;
desc.MultisampleQuality = 0;

if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(&desc)))
return D3DERR_INVALIDCALL;

if (desc.Format == D3D9Format::A8 &&
(desc.Usage & D3DUSAGE_RENDERTARGET) &&
m_d3d9Options.disableA8RT)
return D3DERR_INVALIDCALL;

auto mapping = LookupFormat(desc.Format);
if (!mapping.IsValid() && desc.Format != D3D9Format::NULL_FORMAT)
D3D9_VK_FORMAT_MAPPING mapping;
if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc, &mapping)))
return D3DERR_INVALIDCALL;

try {
Expand Down Expand Up @@ -469,11 +461,8 @@ namespace dxvk {
desc.MultiSample = D3DMULTISAMPLE_NONE;
desc.MultisampleQuality = 0;

if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(&desc)))
return D3DERR_INVALIDCALL;

auto mapping = LookupFormat(desc.Format);
if (!mapping.IsValid() && desc.Format != D3D9Format::NULL_FORMAT)
D3D9_VK_FORMAT_MAPPING mapping;
if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc, &mapping)))
return D3DERR_INVALIDCALL;

try {
Expand Down Expand Up @@ -518,11 +507,8 @@ namespace dxvk {
desc.MultiSample = D3DMULTISAMPLE_NONE;
desc.MultisampleQuality = 0;

if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(&desc)))
return D3DERR_INVALIDCALL;

auto mapping = LookupFormat(desc.Format);
if (!mapping.IsValid() && desc.Format != D3D9Format::NULL_FORMAT)
D3D9_VK_FORMAT_MAPPING mapping;
if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc, &mapping)))
return D3DERR_INVALIDCALL;

try {
Expand Down Expand Up @@ -3278,16 +3264,8 @@ namespace dxvk {
desc.MultiSample = MultiSample;
desc.MultisampleQuality = MultisampleQuality;

if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(&desc)))
return D3DERR_INVALIDCALL;

if (desc.Format == D3D9Format::A8 &&
(desc.Usage & D3DUSAGE_RENDERTARGET) &&
m_d3d9Options.disableA8RT)
return D3DERR_INVALIDCALL;

auto mapping = LookupFormat(desc.Format);
if (!mapping.IsValid() && desc.Format != D3D9Format::NULL_FORMAT)
D3D9_VK_FORMAT_MAPPING mapping;
if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc, &mapping)))
return D3DERR_INVALIDCALL;

try {
Expand Down Expand Up @@ -3330,16 +3308,8 @@ namespace dxvk {
desc.MultiSample = D3DMULTISAMPLE_NONE;
desc.MultisampleQuality = 0;

if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(&desc)))
return D3DERR_INVALIDCALL;

if (desc.Format == D3D9Format::A8 &&
(desc.Usage & D3DUSAGE_RENDERTARGET) &&
m_d3d9Options.disableA8RT)
return D3DERR_INVALIDCALL;

auto mapping = LookupFormat(desc.Format);
if (!mapping.IsValid() && desc.Format != D3D9Format::NULL_FORMAT)
D3D9_VK_FORMAT_MAPPING mapping;
if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc, &mapping)))
return D3DERR_INVALIDCALL;

try {
Expand Down Expand Up @@ -3384,11 +3354,8 @@ namespace dxvk {
desc.MultiSample = MultiSample;
desc.MultisampleQuality = MultisampleQuality;

if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(&desc)))
return D3DERR_INVALIDCALL;

auto mapping = LookupFormat(desc.Format);
if (!mapping.IsValid() && desc.Format != D3D9Format::NULL_FORMAT)
D3D9_VK_FORMAT_MAPPING mapping;
if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, &desc, &mapping)))
return D3DERR_INVALIDCALL;

try {
Expand Down Expand Up @@ -4000,6 +3967,11 @@ namespace dxvk {
return m_adapter->GetFormatMapping(Format);
}

DxvkFormatInfo D3D9DeviceEx::UnsupportedFormatInfo(
D3D9Format Format) const {
return m_adapter->GetUnsupportedFormatInfo(Format);
}

bool D3D9DeviceEx::WaitForResource(
const Rc<DxvkResource>& Resource,
DWORD MapFlags) {
Expand Down
3 changes: 3 additions & 0 deletions src/d3d9/d3d9_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,9 @@ namespace dxvk {
D3D9_VK_FORMAT_MAPPING LookupFormat(
D3D9Format Format) const;

DxvkFormatInfo UnsupportedFormatInfo(
D3D9Format Format) const;

bool WaitForResource(
const Rc<DxvkResource>& Resource,
DWORD MapFlags);
Expand Down
42 changes: 42 additions & 0 deletions src/d3d9/d3d9_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,48 @@ namespace dxvk {

return mapping;
}


DxvkFormatInfo D3D9VkFormatTable::GetUnsupportedFormatInfo(
D3D9Format Format) const {
switch (Format) {
case D3D9Format::R8G8B8:
return { 3, VK_IMAGE_ASPECT_COLOR_BIT };

case D3D9Format::R3G3B2:
return { 1, VK_IMAGE_ASPECT_COLOR_BIT };

case D3D9Format::A8R3G3B2:
return { 2, VK_IMAGE_ASPECT_COLOR_BIT };

case D3D9Format::A8P8:
return { 2, VK_IMAGE_ASPECT_COLOR_BIT };

case D3D9Format::P8:
return { 1, VK_IMAGE_ASPECT_COLOR_BIT };

case D3D9Format::L6V5U5:
return { 2, VK_IMAGE_ASPECT_COLOR_BIT };

case D3D9Format::X8L8V8U8:
return { 4, VK_IMAGE_ASPECT_COLOR_BIT };

case D3D9Format::A2W10V10U10:
return { 4, VK_IMAGE_ASPECT_COLOR_BIT };

// MULTI2_ARGB8 -> Don't have a clue what this is.

case D3D9Format::CxV8U8:
return { 2, VK_IMAGE_ASPECT_COLOR_BIT };

// A1 -> Doesn't map nicely here cause it's not byte aligned.
// Gonna just pretend that doesn't exist until something
// depends on that.

default:
return {};
}
}


bool D3D9VkFormatTable::CheckImageFormatSupport(
Expand Down
9 changes: 9 additions & 0 deletions src/d3d9/d3d9_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,15 @@ namespace dxvk {
D3D9_VK_FORMAT_MAPPING GetFormatMapping(
D3D9Format Format) const;

/**
* \brief Retrieves format info for unsupported
* formats.
*
* \param [in] Format The D3D9 format to look up
*/
DxvkFormatInfo GetUnsupportedFormatInfo(
D3D9Format Format) const;

private:

bool CheckImageFormatSupport(
Expand Down

0 comments on commit 2fbf8a5

Please sign in to comment.