Skip to content
This repository has been archived by the owner on Nov 19, 2019. It is now read-only.

Commit

Permalink
[d3d9] Implement UpdateSurface more correctly.
Browse files Browse the repository at this point in the history
  • Loading branch information
misyltoad committed Jan 21, 2019
1 parent 0850bbf commit f077edb
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 4 deletions.
57 changes: 53 additions & 4 deletions src/d3d9/d3d9_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -891,11 +891,60 @@ namespace dxup {
HRESULT STDMETHODCALLTYPE Direct3DDevice9Ex::UpdateSurface(IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestinationSurface, CONST POINT* pDestPoint) {
CriticalSection cs(this);

RECT destRect;
destRect.left = pDestPoint ? pDestPoint->x : 0;
destRect.top = pDestPoint ? pDestPoint->y : 0;
Direct3DSurface9* src = reinterpret_cast<Direct3DSurface9*>(pSourceSurface);
Direct3DSurface9* dst = reinterpret_cast<Direct3DSurface9*>(pDestinationSurface);

if (src == nullptr)
return log::d3derr(D3DERR_INVALIDCALL, "UpdateSurface: src was nullptr.");

if (dst == nullptr)
return log::d3derr(D3DERR_INVALIDCALL, "UpdateSurface: dst was nullptr.");

D3DSURFACE_DESC srcDesc;
D3DSURFACE_DESC dstDesc;
pSourceSurface->GetDesc(&srcDesc);
pDestinationSurface->GetDesc(&dstDesc);

D3D11_BOX srcBox;
srcBox.front = 0;
srcBox.back = 1;

UINT dstX = 0;
UINT dstY = 0;

if (pSourceRect != nullptr) {
srcBox.left = pSourceRect->left;
srcBox.top = pSourceRect->top;
srcBox.right = pSourceRect->right;
srcBox.bottom = pSourceRect->bottom;

}
else {
srcBox.left = 0;
srcBox.top = 0;
srcBox.right = srcDesc.Width;
srcBox.bottom = srcDesc.Height;
}

if (pDestPoint != nullptr) {
dstX = pDestPoint->x;
dstY = pDestPoint->y;
}

if (!src->isBoxValid(&srcBox))
return log::d3derr(D3DERR_INVALIDCALL, "UpdateSurface: box was invalid.");

if (srcDesc.MultiSampleType != D3DMULTISAMPLE_NONE)
return log::d3derr(D3DERR_INVALIDCALL, "UpdateSurface: src has multisampling.");

if (dstDesc.MultiSampleType != D3DMULTISAMPLE_NONE)
return log::d3derr(D3DERR_INVALIDCALL, "UpdateSurface: dst has multisampling.");

if (srcDesc.Format != dstDesc.Format)
return log::d3derr(D3DERR_INVALIDCALL, "UpdateSurface: src format is not the same as dst format.");

StretchRect(pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint ? &destRect : nullptr, D3DTEXF_NONE);
// TODO: do we need to do staging here too? Look into this.
m_context->CopySubresourceRegion(dst->GetDXUPResource()->GetResource(), dst->GetSubresource(), dstX, dstY, 0, src->GetDXUPResource()->GetResource(), src->GetSubresource(), &srcBox);

return D3D_OK;
}
Expand Down
31 changes: 31 additions & 0 deletions src/d3d9/d3d9_surface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,5 +185,36 @@ namespace dxup {
if (config::getBool(config::GDICompatible))
resource->GetResource()->QueryInterface(__uuidof(IDXGISurface1), (void**)&m_surface);
}
bool Direct3DSurface9::isRectValid(const RECT* rect) {
if (rect == nullptr)
return true;

if (rect->right <= rect->left || rect->bottom <= rect->top)
return false;

if (rect->left < 0 || rect->top < 0)
return false;

D3DSURFACE_DESC desc;
this->GetDesc(&desc);
if (rect->right > (int)desc.Width || rect->bottom > desc.Height)
return false;

return true;
}

bool Direct3DSurface9::isBoxValid(const D3D11_BOX* box) {
if (box == nullptr)
return true;

if (box->front != 0 || box->back != 1)
return false;

RECT rect;
rect.left = box->left;
rect.top = box->top;
rect.right = box->right;
rect.bottom = box->bottom;
return this->isRectValid(&rect);
}
}
3 changes: 3 additions & 0 deletions src/d3d9/d3d9_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ namespace dxup {
void ClearResource();
void SetResource(DXUPResource* resource);

bool isRectValid(const RECT* rect);
bool isBoxValid(const D3D11_BOX* box);

private:

IUnknown* m_container;
Expand Down

0 comments on commit f077edb

Please sign in to comment.