1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-02 19:24:12 +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)
return D3DERR_NOTAVAILABLE;
if (ds && !IsDepthFormat(CheckFormat))
if (ds && !IsDepthStencilFormat(CheckFormat))
return D3DERR_NOTAVAILABLE;
if (rt && CheckFormat == D3D9Format::NULL_FORMAT && twoDimensional)
@ -228,7 +228,7 @@ namespace dxvk {
D3D9Format AdapterFormat,
D3D9Format RenderTargetFormat,
D3D9Format DepthStencilFormat) {
if (!IsDepthFormat(DepthStencilFormat))
if (!IsDepthStencilFormat(DepthStencilFormat))
return D3DERR_NOTAVAILABLE;
auto dsfMapping = GetFormatMapping(DepthStencilFormat);

View File

@ -184,6 +184,17 @@ namespace dxvk {
if (pDesc->MipLevels == 0 || 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;
}

View File

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

View File

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

View File

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

View File

@ -420,4 +420,15 @@ namespace dxvk {
|| 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 IsDepthStencilFormat(D3D9Format Format);
bool IsLockableDepthStencilFormat(D3D9Format Format);
inline bool IsPoolManaged(D3DPOOL Pool) {
return Pool == D3DPOOL_MANAGED || Pool == D3DPOOL_MANAGED_EX;
}