Commit b934fd8b authored by Joshua Ashton's avatar Joshua Ashton 🐸

[d3d9] Use boxes for resource locking.

parent 10a8043e
......@@ -32,26 +32,28 @@ namespace dxup {
if (ppbData == nullptr)
return log::d3derr(D3DERR_INVALIDCALL, "ReturnPtr for buffer lock was null!");
D3DLOCKED_RECT lockedRect;
RECT rectToLock;
rectToLock.top = 0;
rectToLock.bottom = 1;
rectToLock.left = OffsetToLock;
rectToLock.right = OffsetToLock + SizeToLock;
D3DLOCKED_BOX lockedBox;
D3DBOX boxToLock;
boxToLock.Top = 0;
boxToLock.Bottom = 1;
boxToLock.Left = OffsetToLock;
boxToLock.Right = OffsetToLock + SizeToLock;
boxToLock.Front = 0;
boxToLock.Back = 1;
bool degenerate = OffsetToLock == 0 && SizeToLock == 0;
HRESULT result = this->GetDXUPResource()->D3D9LockRect(0, 0, &lockedRect, degenerate ? nullptr : &rectToLock, Flags, this->GetD3D9Desc().Usage);
HRESULT result = this->GetDXUPResource()->D3D9LockBox(0, 0, &lockedBox, degenerate ? nullptr : &boxToLock, Flags, this->GetD3D9Desc().Usage);
if (FAILED(result))
return result;
*ppbData = lockedRect.pBits;
*ppbData = lockedBox.pBits;
return D3D_OK;
}
HRESULT STDMETHODCALLTYPE Unlock() override {
return this->GetDXUPResource()->D3D9UnlockRect(0, 0);
return this->GetDXUPResource()->D3D9UnlockBox(0, 0);
}
};
......
......@@ -176,7 +176,7 @@ namespace dxup {
, m_mips{ mips }
, m_dxgiFormat{ dxgiFormat }
, m_dynamic{ dynamic } {
m_stagingRects.resize(GetSubresources());
m_stagingBoxes.resize(GetSubresources());
ResetMipMapTracking();
for (uint32_t i = 0; i < 6; i++)
m_dirtySubresources[i] = 0;
......
......@@ -54,8 +54,8 @@ namespace dxup {
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObj) override;
HRESULT D3D9LockRect(UINT slice, UINT mip, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags, DWORD Usage);
HRESULT D3D9UnlockRect(UINT slice, UINT mip);
HRESULT D3D9LockBox(UINT slice, UINT mip, D3DLOCKED_BOX* pLockedBox, CONST D3DBOX* pBox, DWORD Flags, DWORD Usage);
HRESULT D3D9UnlockBox(UINT slice, UINT mip);
DXGI_FORMAT GetDXGIFormat();
......@@ -87,8 +87,8 @@ namespace dxup {
Com<ID3D11Resource> m_staging;
Com<ID3D11Resource> m_fixup8888;
bool IsStagingRectDegenerate(UINT subresource);
std::vector<RECT> m_stagingRects;
bool IsStagingBoxDegenerate(UINT subresource);
std::vector<D3DBOX> m_stagingBoxes;
bool m_dynamic;
......
......@@ -3,8 +3,8 @@
namespace dxup {
bool DXUPResource::IsStagingRectDegenerate(UINT subresource) {
return isRectDegenerate(m_stagingRects[subresource]);
bool DXUPResource::IsStagingBoxDegenerate(UINT subresource) {
return isBoxDegenerate(m_stagingBoxes[subresource]);
}
UINT DXUPResource::CalcMapFlags(UINT d3d9LockFlags) {
......@@ -65,21 +65,22 @@ namespace dxup {
}
}
HRESULT DXUPResource::D3D9LockRect(UINT slice, UINT mip, D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags, DWORD Usage) {
HRESULT DXUPResource::D3D9LockBox(UINT slice, UINT mip, D3DLOCKED_BOX* pLockedBox, CONST D3DBOX* pBox, DWORD Flags, DWORD Usage) {
CriticalSection cs(m_device);
if (!pLockedRect)
return log::d3derr(D3DERR_INVALIDCALL, "Return value (locked rect) was null in D3D9LockRect.");
if (pLockedBox == nullptr)
return log::d3derr(D3DERR_INVALIDCALL, "D3D9LockBox: return value (locked box) was nullptr.");
pLockedRect->pBits = nullptr;
pLockedRect->Pitch = 0;
pLockedBox->pBits = nullptr;
pLockedBox->RowPitch = 0;
pLockedBox->SlicePitch = 0;
UINT subresource = D3D11CalcSubresource(mip, slice, m_mips);
if (pRect == nullptr)
std::memset(&m_stagingRects[subresource], 0, sizeof(RECT));
if (pBox == nullptr)
std::memset(&m_stagingBoxes[subresource], 0, sizeof(D3DBOX));
else
m_stagingRects[subresource] = *pRect;
m_stagingBoxes[subresource] = *pBox;
if (!(Flags & D3DLOCK_DISCARD) && !(Flags & D3DLOCK_NOOVERWRITE) && !(Usage & D3DUSAGE_WRITEONLY))
MakeClean();
......@@ -97,17 +98,18 @@ namespace dxup {
size_t offset = 0;
if (!IsStagingRectDegenerate(subresource))
offset = (m_stagingRects[subresource].top * res.RowPitch) + (m_stagingRects[subresource].left * bitsPerPixel(m_dxgiFormat) / 8);
if (!IsStagingBoxDegenerate(subresource))
offset = (m_stagingBoxes[subresource].Top * res.RowPitch) + (m_stagingBoxes[subresource].Left * bitsPerPixel(m_dxgiFormat) / 8);
uint8_t* data = (uint8_t*)res.pData;
pLockedRect->pBits = &data[offset];
pLockedRect->Pitch = res.RowPitch;
pLockedBox->pBits = &data[offset];
pLockedBox->RowPitch = res.RowPitch;
pLockedBox->SlicePitch = res.DepthPitch;
return D3D_OK;
}
HRESULT DXUPResource::D3D9UnlockRect(UINT slice, UINT mip) {
HRESULT DXUPResource::D3D9UnlockBox(UINT slice, UINT mip) {
CriticalSection cs(m_device);
UINT subresource = D3D11CalcSubresource(mip, slice, m_mips);
......@@ -160,14 +162,14 @@ namespace dxup {
for (uint64_t mip = 0; mip < m_mips; mip++) {
UINT subresource = D3D11CalcSubresource(mip, slice, m_mips);
bool useRect = !IsStagingRectDegenerate(subresource);
bool useRect = !IsStagingBoxDegenerate(subresource);
D3D11_BOX box = { 0 };
if (useRect) {
box.left = alignRectForFormat(true, m_dxgiFormat, m_stagingRects[subresource].left);
box.top = alignRectForFormat(true, m_dxgiFormat, m_stagingRects[subresource].top);
box.right = alignRectForFormat(false, m_dxgiFormat, m_stagingRects[subresource].right);
box.bottom = alignRectForFormat(false, m_dxgiFormat, m_stagingRects[subresource].bottom);
box.left = alignRectForFormat(true, m_dxgiFormat, m_stagingBoxes[subresource].Left);
box.top = alignRectForFormat(true, m_dxgiFormat, m_stagingBoxes[subresource].Top);
box.right = alignRectForFormat(false, m_dxgiFormat, m_stagingBoxes[subresource].Right);
box.bottom = alignRectForFormat(false, m_dxgiFormat, m_stagingBoxes[subresource].Bottom);
box.front = 0;
box.back = 1;
......
......@@ -38,18 +38,18 @@ namespace dxup {
HRESULT STDMETHODCALLTYPE FreePrivateData(REFGUID refguid) override {
return m_map.FreePrivateData(refguid);
}
DWORD STDMETHODCALLTYPE SetPriority(DWORD PriorityNew) override {
DWORD STDMETHODCALLTYPE SetPriority(DWORD PriorityNew) {
DWORD oldPriority = m_d3d9Desc.Priority;
m_d3d9Desc.Priority = PriorityNew;
return oldPriority;
}
DWORD STDMETHODCALLTYPE GetPriority() override {
DWORD STDMETHODCALLTYPE GetPriority() {
return m_d3d9Desc.Priority;
}
void STDMETHODCALLTYPE PreLoad() override {
void STDMETHODCALLTYPE PreLoad() {
log::stub("Direct3DResource9::PreLoad");
}
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() override {
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() {
return ResourceType;
}
......
......@@ -61,14 +61,28 @@ namespace dxup {
return D3D_OK;
}
HRESULT Direct3DSurface9::LockRect(D3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) {
return m_resource->D3D9LockRect(m_slice, m_mip, pLockedRect, pRect, Flags, m_d3d9Desc.Usage);
if (pLockedRect == nullptr)
return log::d3derr(D3DERR_INVALIDCALL, "Direct3DSurface9::LockRect: pLockedRect was nullptr.");
D3DLOCKED_BOX lockedBox;
D3DBOX box;
if (pRect != nullptr) {
box.Top = pRect->top;
box.Left = pRect->left;
box.Bottom = pRect->bottom;
box.Right = pRect->right;
box.Front = 0;
box.Back = 1;
}
HRESULT result = m_resource->D3D9LockBox(m_slice, m_mip, &lockedBox, pRect != nullptr ? &box : nullptr, Flags, m_d3d9Desc.Usage);
pLockedRect->pBits = lockedBox.pBits;
pLockedRect->Pitch = lockedBox.RowPitch;
return result;
}
HRESULT Direct3DSurface9::UnlockRect() {
return m_resource->D3D9UnlockRect(m_slice, m_mip);
}
D3DRESOURCETYPE STDMETHODCALLTYPE Direct3DSurface9::GetType() {
return D3DRTYPE_SURFACE;
return m_resource->D3D9UnlockBox(m_slice, m_mip);
}
HRESULT Direct3DSurface9::GetDC(HDC *phdc) {
......
......@@ -20,7 +20,6 @@ namespace dxup {
HRESULT WINAPI UnlockRect() override;
HRESULT WINAPI GetDC(HDC *phdc) override;
HRESULT WINAPI ReleaseDC(HDC hdc) override;
D3DRESOURCETYPE STDMETHODCALLTYPE GetType() override;
UINT GetMip();
UINT GetSlice();
......
......@@ -186,6 +186,10 @@ namespace dxup {
return rect.top == 0 && rect.right == 0 && rect.left == 0 && rect.bottom == 0;
}
inline bool isBoxDegenerate(const D3DBOX& box) {
return box.Top == 0 && box.Right == 0 && box.Left == 0 && box.Bottom == 0 && box.Front == 0 && box.Back == 0;
}
template <typename T, typename J>
T* useAs(J* obj) {
return reinterpret_cast<T*>(obj);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment