diff --git a/src/d3d8/d3d8_device.cpp b/src/d3d8/d3d8_device.cpp index bb4f12b4897..e11634c9e8a 100644 --- a/src/d3d8/d3d8_device.cpp +++ b/src/d3d8/d3d8_device.cpp @@ -592,6 +592,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 f1a1e95d8ec..3aea400df57 100644 --- a/src/d3d8/d3d8_format.h +++ b/src/d3d8/d3d8_format.h @@ -37,6 +37,16 @@ namespace dxvk { || fmt == D3DFMT_D24X8; } + 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) {