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

[d3d9] Handle remaining edge cases of Discard & Lockable

This commit is contained in:
Robin Kertels 2024-07-30 10:04:05 +02:00 committed by Joshie
parent 2c23e462b3
commit 11efd5092e
7 changed files with 43 additions and 18 deletions

View File

@ -134,7 +134,7 @@ namespace dxvk {
if (rt && CheckFormat == D3D9Format::A8 && m_parent->GetOptions().disableA8RT) if (rt && CheckFormat == D3D9Format::A8 && m_parent->GetOptions().disableA8RT)
return D3DERR_NOTAVAILABLE; return D3DERR_NOTAVAILABLE;
if (ds && !IsDepthFormat(CheckFormat)) if (ds && !IsDepthStencilFormat(CheckFormat))
return D3DERR_NOTAVAILABLE; return D3DERR_NOTAVAILABLE;
if (rt && CheckFormat == D3D9Format::NULL_FORMAT && twoDimensional) if (rt && CheckFormat == D3D9Format::NULL_FORMAT && twoDimensional)
@ -228,7 +228,7 @@ namespace dxvk {
D3D9Format AdapterFormat, D3D9Format AdapterFormat,
D3D9Format RenderTargetFormat, D3D9Format RenderTargetFormat,
D3D9Format DepthStencilFormat) { D3D9Format DepthStencilFormat) {
if (!IsDepthFormat(DepthStencilFormat)) if (!IsDepthStencilFormat(DepthStencilFormat))
return D3DERR_NOTAVAILABLE; return D3DERR_NOTAVAILABLE;
auto dsfMapping = GetFormatMapping(DepthStencilFormat); auto dsfMapping = GetFormatMapping(DepthStencilFormat);

View File

@ -184,6 +184,17 @@ namespace dxvk {
if (pDesc->MipLevels == 0 || pDesc->MipLevels > maxMipLevelCount) if (pDesc->MipLevels == 0 || pDesc->MipLevels > maxMipLevelCount)
pDesc->MipLevels = maxMipLevelCount; pDesc->MipLevels = maxMipLevelCount;
if (unlikely(pDesc->Discard)) {
if (!IsDepthStencilFormat(pDesc->Format))
return D3DERR_INVALIDCALL;
if (pDesc->Format == D3D9Format::D32_LOCKABLE
|| pDesc->Format == D3D9Format::D32F_LOCKABLE
|| pDesc->Format == D3D9Format::D16_LOCKABLE
|| pDesc->Format == D3D9Format::S8_LOCKABLE)
return D3DERR_INVALIDCALL;
}
return D3D_OK; return D3D_OK;
} }

View File

@ -1225,10 +1225,10 @@ namespace dxvk {
uint32_t(blitInfo.dstOffsets[1].y - blitInfo.dstOffsets[0].y), uint32_t(blitInfo.dstOffsets[1].y - blitInfo.dstOffsets[0].y),
uint32_t(blitInfo.dstOffsets[1].z - blitInfo.dstOffsets[0].z) }; uint32_t(blitInfo.dstOffsets[1].z - blitInfo.dstOffsets[0].z) };
bool srcIsDepth = IsDepthFormat(srcFormat); bool srcIsDS = IsDepthStencilFormat(srcFormat);
bool dstIsDepth = IsDepthFormat(dstFormat); bool dstIsDS = IsDepthStencilFormat(dstFormat);
if (unlikely(srcIsDepth || dstIsDepth)) { if (unlikely(srcIsDS || dstIsDS)) {
if (unlikely(!srcIsDepth || !dstIsDepth)) if (unlikely(!srcIsDS || !dstIsDS))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
if (unlikely(srcTextureInfo->Desc()->Discard || dstTextureInfo->Desc()->Discard)) if (unlikely(srcTextureInfo->Desc()->Discard || dstTextureInfo->Desc()->Discard))
@ -1250,7 +1250,7 @@ namespace dxvk {
if (unlikely(pSourceSurface == pDestSurface)) if (unlikely(pSourceSurface == pDestSurface))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
if (unlikely(dstIsDepth)) if (unlikely(dstIsDS))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
// The docs say that stretching is only allowed if the destination is either a render target surface or a render target texture. // The docs say that stretching is only allowed if the destination is either a render target surface or a render target texture.
@ -3950,8 +3950,7 @@ namespace dxvk {
desc.MultisampleQuality = MultisampleQuality; desc.MultisampleQuality = MultisampleQuality;
desc.IsBackBuffer = FALSE; desc.IsBackBuffer = FALSE;
desc.IsAttachmentOnly = TRUE; desc.IsAttachmentOnly = TRUE;
// Docs don't say anything, so just assume it's lockable. desc.IsLockable = IsLockableDepthStencilFormat(desc.Format);
desc.IsLockable = TRUE;
if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, D3DRTYPE_TEXTURE, &desc))) if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, D3DRTYPE_TEXTURE, &desc)))
return D3DERR_INVALIDCALL; return D3DERR_INVALIDCALL;
@ -7977,13 +7976,12 @@ namespace dxvk {
desc.Usage = D3DUSAGE_DEPTHSTENCIL; desc.Usage = D3DUSAGE_DEPTHSTENCIL;
desc.Format = EnumerateFormat(pPresentationParameters->AutoDepthStencilFormat); desc.Format = EnumerateFormat(pPresentationParameters->AutoDepthStencilFormat);
desc.Pool = D3DPOOL_DEFAULT; desc.Pool = D3DPOOL_DEFAULT;
desc.Discard = FALSE; desc.Discard = (pPresentationParameters->Flags & D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL) != 0;
desc.MultiSample = pPresentationParameters->MultiSampleType; desc.MultiSample = pPresentationParameters->MultiSampleType;
desc.MultisampleQuality = pPresentationParameters->MultiSampleQuality; desc.MultisampleQuality = pPresentationParameters->MultiSampleQuality;
desc.IsBackBuffer = FALSE; desc.IsBackBuffer = FALSE;
desc.IsAttachmentOnly = TRUE; desc.IsAttachmentOnly = TRUE;
// Docs: Also note that - unlike textures - swap chain back buffers, render targets [..] can be locked desc.IsLockable = IsLockableDepthStencilFormat(desc.Format);
desc.IsLockable = TRUE;
if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, D3DRTYPE_TEXTURE, &desc))) if (FAILED(D3D9CommonTexture::NormalizeTextureProperties(this, D3DRTYPE_TEXTURE, &desc)))
return D3DERR_NOTAVAILABLE; return D3DERR_NOTAVAILABLE;

View File

@ -45,7 +45,7 @@ namespace dxvk {
RecreateSwapChain(); RecreateSwapChain();
} }
if (FAILED(CreateBackBuffers(m_presentParams.BackBufferCount))) if (FAILED(CreateBackBuffers(m_presentParams.BackBufferCount, m_presentParams.Flags)))
throw DxvkError("D3D9: Failed to create swapchain backbuffers"); throw DxvkError("D3D9: Failed to create swapchain backbuffers");
CreateBlitter(); CreateBlitter();
@ -627,7 +627,7 @@ namespace dxvk {
if (changeFullscreen) if (changeFullscreen)
SetGammaRamp(0, &m_ramp); SetGammaRamp(0, &m_ramp);
hr = CreateBackBuffers(m_presentParams.BackBufferCount); hr = CreateBackBuffers(m_presentParams.BackBufferCount, m_presentParams.Flags);
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
@ -1013,7 +1013,7 @@ namespace dxvk {
} }
HRESULT D3D9SwapChainEx::CreateBackBuffers(uint32_t NumBackBuffers) { HRESULT D3D9SwapChainEx::CreateBackBuffers(uint32_t NumBackBuffers, DWORD Flags) {
// Explicitly destroy current swap image before // Explicitly destroy current swap image before
// creating a new one to free up resources // creating a new one to free up resources
DestroyBackBuffers(); DestroyBackBuffers();
@ -1038,8 +1038,7 @@ namespace dxvk {
desc.Discard = FALSE; desc.Discard = FALSE;
desc.IsBackBuffer = TRUE; desc.IsBackBuffer = TRUE;
desc.IsAttachmentOnly = FALSE; desc.IsAttachmentOnly = FALSE;
// Docs: Also note that - unlike textures - swap chain back buffers, render targets [..] can be locked desc.IsLockable = (Flags & D3DPRESENTFLAG_LOCKABLE_BACKBUFFER) != 0;
desc.IsLockable = TRUE;
for (uint32_t i = 0; i < NumBuffers; i++) { for (uint32_t i = 0; i < NumBuffers; i++) {
D3D9Surface* surface; D3D9Surface* surface;

View File

@ -205,7 +205,8 @@ namespace dxvk {
void CreateRenderTargetViews(); void CreateRenderTargetViews();
HRESULT CreateBackBuffers( HRESULT CreateBackBuffers(
uint32_t NumBackBuffers); uint32_t NumBackBuffers,
DWORD Flags);
void CreateBlitter(); void CreateBlitter();

View File

@ -420,4 +420,15 @@ namespace dxvk {
|| Format == D3D9Format::INTZ; || Format == D3D9Format::INTZ;
} }
bool IsDepthStencilFormat(D3D9Format Format) {
return IsDepthFormat(Format) || Format == D3D9Format::S8_LOCKABLE;
}
bool IsLockableDepthStencilFormat(D3D9Format Format) {
return Format == D3D9Format::S8_LOCKABLE
|| Format == D3D9Format::D16_LOCKABLE
|| Format == D3D9Format::D32_LOCKABLE
|| Format == D3D9Format::D32F_LOCKABLE;
}
} }

View File

@ -204,6 +204,11 @@ namespace dxvk {
bool IsDepthFormat(D3D9Format Format); bool IsDepthFormat(D3D9Format Format);
bool IsDepthStencilFormat(D3D9Format Format);
bool IsLockableDepthStencilFormat(D3D9Format Format);
inline bool IsPoolManaged(D3DPOOL Pool) { inline bool IsPoolManaged(D3DPOOL Pool) {
return Pool == D3DPOOL_MANAGED || Pool == D3DPOOL_MANAGED_EX; return Pool == D3DPOOL_MANAGED || Pool == D3DPOOL_MANAGED_EX;
} }