From 9522ef742de9afa939b75baeb418d6e7aedc123d 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 c3ad1396558..7d259b6b784 100644 --- a/src/d3d8/d3d8_device.cpp +++ b/src/d3d8/d3d8_device.cpp @@ -573,6 +573,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 6bc2c8b487a..5d17e2713b5 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) inline constexpr UINT getFormatStride(D3DFORMAT fmt) { switch (fmt) {