From b8180aa315596f738778c9aebae5efd45899ba75 Mon Sep 17 00:00:00 2001 From: Winter Snowfall Date: Fri, 8 Mar 2024 00:52:48 +0200 Subject: [PATCH] [d3d8] Validate depth stencil format use with CopyRects --- src/d3d8/d3d8_device.cpp | 7 +++++++ src/d3d8/d3d8_format.h | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/d3d8/d3d8_device.cpp b/src/d3d8/d3d8_device.cpp index b2651b0f7234..504dc87f9b84 100644 --- a/src/d3d8/d3d8_device.cpp +++ b/src/d3d8/d3d8_device.cpp @@ -570,6 +570,13 @@ namespace dxvk { src->GetD3D9()->GetDesc(&srcDesc); dst->GetD3D9()->GetDesc(&dstDesc); + // This method cannot be applied to surfaces whose formats + // are classified as depth stencil formats. + if (unlikely(isDepthStencilFormat(D3DFORMAT(srcDesc.Format)) || + isDepthStencilFormat(D3DFORMAT(dstDesc.Format)))) { + return D3DERR_INVALIDCALL; + } + StateChange(); // If pSourceRectsArray is NULL, then the entire surface is copied diff --git a/src/d3d8/d3d8_format.h b/src/d3d8/d3d8_format.h index f085cd8f1ea6..c0b521ee8d06 100644 --- a/src/d3d8/d3d8_format.h +++ b/src/d3d8/d3d8_format.h @@ -26,6 +26,16 @@ namespace dxvk { || fmt == D3DFMT_D24X8; } + inline constexpr bool isDepthStencilFormat(D3DFORMAT fmt) { + return fmt == D3DFMT_D16_LOCKABLE + || fmt == D3DFMT_D16 + || fmt == D3DFMT_D32 + || fmt == D3DFMT_D15S1 + || fmt == D3DFMT_D24X4S4 + || fmt == D3DFMT_D24S8 + || fmt == D3DFMT_D24X8; + } + // Get bytes per pixel (or 4x4 block for DXT) constexpr UINT getFormatStride(D3DFORMAT fmt) { switch (fmt) {