1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-19 05:52:11 +01:00

[d3d8] Slightly clean up CopyRects

This commit is contained in:
Robin Kertels 2024-07-08 23:55:44 +02:00 committed by Joshie
parent 5f9ca08071
commit a7ae5999a9
2 changed files with 56 additions and 70 deletions

View File

@ -618,8 +618,6 @@ namespace dxvk {
pDestPointsArray = &point;
}
HRESULT res = D3DERR_INVALIDCALL;
for (UINT i = 0; i < cRects; i++) {
RECT srcRect, dstRect;
@ -651,50 +649,54 @@ namespace dxvk {
POINT dstPt = { dstRect.left, dstRect.top };
res = D3DERR_INVALIDCALL;
auto unhandled = [&] {
Logger::debug(str::format("CopyRects: Hit unhandled case from src pool ", srcDesc.Pool, " to dst pool ", dstDesc.Pool));
Logger::warn(str::format("CopyRects: Hit unhandled case from src pool ", srcDesc.Pool, " to dst pool ", dstDesc.Pool));
return D3DERR_INVALIDCALL;
};
auto logError = [&] (HRESULT res) {
if (FAILED(res)) {
// Only a debug message because some games mess up CopyRects every frame in a way
// that fails on native too but are perfectly fine with it.
Logger::debug(str::format("CopyRects: FAILED to copy from src pool ", srcDesc.Pool, " to dst pool ", dstDesc.Pool));
}
return res;
};
switch (dstDesc.Pool) {
// Dest: DEFAULT
case D3DPOOL_DEFAULT:
case d3d9::D3DPOOL_DEFAULT:
switch (srcDesc.Pool) {
case D3DPOOL_DEFAULT: {
case d3d9::D3DPOOL_DEFAULT: {
// DEFAULT -> DEFAULT: use StretchRect
res = GetD3D9()->StretchRect(
return logError(GetD3D9()->StretchRect(
src->GetD3D9(),
&srcRect,
dst->GetD3D9(),
&dstRect,
d3d9::D3DTEXF_NONE
);
goto done;
));
}
case D3DPOOL_MANAGED: {
case d3d9::D3DPOOL_MANAGED: {
// MANAGED -> DEFAULT: UpdateTextureFromBuffer
res = m_bridge->UpdateTextureFromBuffer(
return logError(m_bridge->UpdateTextureFromBuffer(
src->GetD3D9(),
dst->GetD3D9(),
&srcRect,
&dstPt
);
goto done;
));
}
case D3DPOOL_SYSTEMMEM: {
case d3d9::D3DPOOL_SYSTEMMEM: {
// SYSTEMMEM -> DEFAULT: use UpdateSurface
res = GetD3D9()->UpdateSurface(
return logError(GetD3D9()->UpdateSurface(
src->GetD3D9(),
&srcRect,
dst->GetD3D9(),
&dstPt
);
goto done;
));
}
case D3DPOOL_SCRATCH:
case d3d9::D3DPOOL_SCRATCH:
default: {
// TODO: Unhandled case.
return unhandled();
@ -702,43 +704,40 @@ namespace dxvk {
} break;
// Dest: MANAGED
case D3DPOOL_MANAGED:
case d3d9::D3DPOOL_MANAGED:
switch (srcDesc.Pool) {
case D3DPOOL_DEFAULT: {
case d3d9::D3DPOOL_DEFAULT: {
// TODO: Copy on GPU (handle MANAGED similarly to SYSTEMMEM for now)
// Get temporary off-screen surface for stretching.
Com<d3d9::IDirect3DSurface9> pBlitImage = dst->GetBlitImage();
// Stretch the source RT to the temporary surface.
res = GetD3D9()->StretchRect(
HRESULT res = GetD3D9()->StretchRect(
src->GetD3D9(),
&srcRect,
pBlitImage.ptr(),
&dstRect,
d3d9::D3DTEXF_NONE);
if (FAILED(res)) {
goto done;
return logError(res);
}
// Now sync the rendertarget data into main memory.
res = GetD3D9()->GetRenderTargetData(pBlitImage.ptr(), dst->GetD3D9());
goto done;
return logError(GetD3D9()->GetRenderTargetData(pBlitImage.ptr(), dst->GetD3D9()));
}
case D3DPOOL_MANAGED:
case D3DPOOL_SYSTEMMEM: {
case d3d9::D3DPOOL_MANAGED:
case d3d9::D3DPOOL_SYSTEMMEM: {
// SYSTEMMEM -> MANAGED: LockRect / memcpy
if (stretch) {
res = D3DERR_INVALIDCALL;
goto done;
return logError(D3DERR_INVALIDCALL);
}
res = copyTextureBuffers(src.ptr(), dst.ptr(), srcDesc, dstDesc, srcRect, dstRect);
goto done;
return logError(copyTextureBuffers(src.ptr(), dst.ptr(), srcDesc, dstDesc, srcRect, dstRect));
}
case D3DPOOL_SCRATCH:
case d3d9::D3DPOOL_SCRATCH:
default: {
// TODO: Unhandled case.
return unhandled();
@ -746,7 +745,7 @@ namespace dxvk {
} break;
// DEST: SYSTEMMEM
case D3DPOOL_SYSTEMMEM: {
case d3d9::D3DPOOL_SYSTEMMEM: {
// RT (DEFAULT) -> SYSTEMMEM: Use GetRenderTargetData as fast path if possible
if ((srcDesc.Usage & D3DUSAGE_RENDERTARGET || m_renderTarget.ptr() == src.ptr())) {
@ -757,44 +756,40 @@ namespace dxvk {
&& srcDesc.Height == dstDesc.Height
&& srcDesc.Format == dstDesc.Format
&& !asymmetric) {
res = GetD3D9()->GetRenderTargetData(src->GetD3D9(), dst->GetD3D9());
goto done;
return logError(GetD3D9()->GetRenderTargetData(src->GetD3D9(), dst->GetD3D9()));
}
}
switch (srcDesc.Pool) {
case D3DPOOL_DEFAULT: {
case d3d9::D3DPOOL_DEFAULT: {
// Get temporary off-screen surface for stretching.
Com<d3d9::IDirect3DSurface9> pBlitImage = dst->GetBlitImage();
// Stretch the source RT to the temporary surface.
res = GetD3D9()->StretchRect(
HRESULT res = GetD3D9()->StretchRect(
src->GetD3D9(),
&srcRect,
pBlitImage.ptr(),
&dstRect,
d3d9::D3DTEXF_NONE);
if (FAILED(res)) {
goto done;
return logError(res);
}
// Now sync the rendertarget data into main memory.
res = GetD3D9()->GetRenderTargetData(pBlitImage.ptr(), dst->GetD3D9());
goto done;
return logError(GetD3D9()->GetRenderTargetData(pBlitImage.ptr(), dst->GetD3D9()));
}
// SYSMEM/MANAGED -> SYSMEM: LockRect / memcpy
case D3DPOOL_MANAGED:
case D3DPOOL_SYSTEMMEM: {
case d3d9::D3DPOOL_MANAGED:
case d3d9::D3DPOOL_SYSTEMMEM: {
if (stretch) {
res = D3DERR_INVALIDCALL;
goto done;
return logError(D3DERR_INVALIDCALL);
}
res = copyTextureBuffers(src.ptr(), dst.ptr(), srcDesc, dstDesc, srcRect, dstRect);
goto done;
return logError(copyTextureBuffers(src.ptr(), dst.ptr(), srcDesc, dstDesc, srcRect, dstRect));
}
case D3DPOOL_SCRATCH:
case d3d9::D3DPOOL_SCRATCH:
default: {
// TODO: Unhandled case.
return unhandled();
@ -803,22 +798,15 @@ namespace dxvk {
}
// DEST: SCRATCH
case D3DPOOL_SCRATCH:
case d3d9::D3DPOOL_SCRATCH:
default: {
// TODO: Unhandled case.
return unhandled();
}
}
done:
if (FAILED(res)) {
Logger::debug(str::format("CopyRects: FAILED to copy from src pool ", srcDesc.Pool, " to dst pool ", dstDesc.Pool));
return res;
}
}
return res;
return D3DERR_INVALIDCALL;
}
HRESULT STDMETHODCALLTYPE D3D8Device::UpdateTexture(

View File

@ -3,8 +3,6 @@
#include <windows.h>
#include "../util/config/config.h"
#include "../vulkan/vulkan_loader.h"
/**
* The D3D9 bridge allows D3D8 to access DXVK internals.
* For Vulkan interop without needing DXVK internals, see d3d9_interop.h.