Skip to content

Commit

Permalink
Validate state block calls during state recording (#186)
Browse files Browse the repository at this point in the history
  • Loading branch information
WinterSnowfall authored Oct 17, 2024
1 parent 2a81c4e commit f7012c9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
1 change: 1 addition & 0 deletions source/d3d8to9.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ class Direct3DDevice8 : public IDirect3DDevice8
DWORD CurrentVertexShaderHandle = 0, CurrentPixelShaderHandle = 0;
IDirect3DSurface9 *pCurrentRenderTarget = nullptr;
bool PaletteFlag = false;
bool IsRecordingState = false;

static constexpr size_t MAX_CLIP_PLANES = 6;
float StoredClipPlanes[MAX_CLIP_PLANES][4] = {};
Expand Down
28 changes: 27 additions & 1 deletion source/d3d8to9_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -801,17 +801,31 @@ HRESULT STDMETHODCALLTYPE Direct3DDevice8::GetRenderState(D3DRENDERSTATETYPE Sta
}
HRESULT STDMETHODCALLTYPE Direct3DDevice8::BeginStateBlock()
{
return ProxyInterface->BeginStateBlock();
if (IsRecordingState)
return D3DERR_INVALIDCALL;

HRESULT hr = ProxyInterface->BeginStateBlock();

if (SUCCEEDED(hr))
IsRecordingState = true;

return hr;
}
HRESULT STDMETHODCALLTYPE Direct3DDevice8::EndStateBlock(DWORD *pToken)
{
if (pToken == nullptr)
return D3DERR_INVALIDCALL;

if (!IsRecordingState)
return D3DERR_INVALIDCALL;

HRESULT hr = ProxyInterface->EndStateBlock(reinterpret_cast<IDirect3DStateBlock9**>(pToken));

if (SUCCEEDED(hr))
{
StateBlockTokens.insert(*pToken);
IsRecordingState = false;
}

return hr;
}
Expand All @@ -820,20 +834,29 @@ HRESULT STDMETHODCALLTYPE Direct3DDevice8::ApplyStateBlock(DWORD Token)
if (Token == 0)
return D3DERR_INVALIDCALL;

if (IsRecordingState)
return D3DERR_INVALIDCALL;

return reinterpret_cast<IDirect3DStateBlock9 *>(Token)->Apply();
}
HRESULT STDMETHODCALLTYPE Direct3DDevice8::CaptureStateBlock(DWORD Token)
{
if (Token == 0)
return D3DERR_INVALIDCALL;

if (IsRecordingState)
return D3DERR_INVALIDCALL;

return reinterpret_cast<IDirect3DStateBlock9 *>(Token)->Capture();
}
HRESULT STDMETHODCALLTYPE Direct3DDevice8::DeleteStateBlock(DWORD Token)
{
if (Token == 0)
return D3DERR_INVALIDCALL;

if (IsRecordingState)
return D3DERR_INVALIDCALL;

reinterpret_cast<IDirect3DStateBlock9 *>(Token)->Release();

StateBlockTokens.erase(Token);
Expand All @@ -849,6 +872,9 @@ HRESULT STDMETHODCALLTYPE Direct3DDevice8::CreateStateBlock(D3DSTATEBLOCKTYPE Ty
if (pToken == nullptr)
return D3DERR_INVALIDCALL;

if (IsRecordingState)
return D3DERR_INVALIDCALL;

HRESULT hr = ProxyInterface->CreateStateBlock(Type, reinterpret_cast<IDirect3DStateBlock9 **>(pToken));

if (SUCCEEDED(hr))
Expand Down

0 comments on commit f7012c9

Please sign in to comment.