Skip to content

Commit 4914b3c

Browse files
committed
D3D fix-ups #4 (Performance)
1 parent 5229ad4 commit 4914b3c

File tree

2 files changed

+81
-48
lines changed

2 files changed

+81
-48
lines changed

Client/core/DXHook/CDirect3DEvents9.cpp

Lines changed: 61 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class BorderlessToneMapPass
9494
LPD3DXCONSTANTTABLE m_constantTable = nullptr;
9595
D3DXHANDLE m_toneParamsHandle = nullptr;
9696
IDirect3DStateBlock9* m_restoreStateBlock = nullptr;
97+
IDirect3DStateBlock9* m_applyStateBlock = nullptr;
9798
UINT m_width = 0;
9899
UINT m_height = 0;
99100
D3DFORMAT m_format = D3DFMT_UNKNOWN;
@@ -216,22 +217,59 @@ bool BorderlessToneMapPass::EnsureStateBlock(IDirect3DDevice9* device)
216217
if (!device)
217218
return false;
218219

219-
if (m_restoreStateBlock)
220+
if (m_restoreStateBlock && m_applyStateBlock)
220221
return true;
221222

222-
// Create and capture state block once on initialization
223-
IDirect3DStateBlock9* stateBlock = nullptr;
224-
if (FAILED(device->CreateStateBlock(D3DSBT_ALL, &stateBlock)) || !stateBlock)
225-
return false;
226-
227-
// Capture current state immediately after creation
228-
if (FAILED(stateBlock->Capture()))
223+
// Create restore state block (captures current state for restoration)
224+
if (!m_restoreStateBlock)
229225
{
230-
stateBlock->Release();
231-
return false;
226+
IDirect3DStateBlock9* restoreBlock = nullptr;
227+
if (FAILED(device->CreateStateBlock(D3DSBT_ALL, &restoreBlock)) || !restoreBlock)
228+
return false;
229+
230+
if (FAILED(restoreBlock->Capture()))
231+
{
232+
restoreBlock->Release();
233+
return false;
234+
}
235+
m_restoreStateBlock = restoreBlock;
236+
}
237+
238+
// Create apply state block (captures our desired rendering state)
239+
if (!m_applyStateBlock)
240+
{
241+
device->BeginStateBlock();
242+
243+
// Configure all render states for tone mapping pass
244+
device->SetRenderState(D3DRS_ZENABLE, FALSE);
245+
device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
246+
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
247+
device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
248+
device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
249+
device->SetRenderState(D3DRS_FOGENABLE, FALSE);
250+
device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
251+
device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
252+
253+
device->SetPixelShader(m_pixelShader);
254+
device->SetVertexShader(nullptr);
255+
device->SetFVF(SToneMapVertex::FVF);
256+
257+
device->SetTexture(0, m_sourceTexture);
258+
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
259+
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
260+
device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
261+
device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
262+
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
263+
device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
264+
265+
IDirect3DStateBlock9* applyBlock = nullptr;
266+
if (FAILED(device->EndStateBlock(&applyBlock)) || !applyBlock)
267+
{
268+
return false;
269+
}
270+
m_applyStateBlock = applyBlock;
232271
}
233272

234-
m_restoreStateBlock = stateBlock;
235273
return true;
236274
}
237275

@@ -304,40 +342,22 @@ bool BorderlessToneMapPass::Apply(IDirect3DDevice9* device, float gammaPower, fl
304342
return false;
305343
}
306344

307-
// State block is already captured during creation, just apply before drawing
308-
device->SetRenderState(D3DRS_ZENABLE, FALSE);
309-
device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
310-
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
311-
device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
312-
device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
313-
device->SetRenderState(D3DRS_FOGENABLE, FALSE);
314-
device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
315-
device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
316-
317-
device->SetPixelShader(m_pixelShader);
318-
device->SetVertexShader(nullptr);
319-
device->SetFVF(SToneMapVertex::FVF);
320-
321-
device->SetTexture(0, m_sourceTexture);
322-
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
323-
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
324-
device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
325-
device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
326-
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
327-
device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
345+
// Apply all rendering state in one call using cached state block
346+
m_applyStateBlock->Apply();
328347

329348
if (m_constantTable && m_toneParamsHandle)
330349
{
331350
const float toneParams[4] = {gammaPower, brightnessScale, contrastScale, saturationScale};
332351
m_constantTable->SetFloatArray(device, m_toneParamsHandle, toneParams, NUMELMS(toneParams));
333352
}
334353

354+
// Pre-compute vertices to avoid per-frame allocation
335355
const float left = -0.5f;
336356
const float top = -0.5f;
337357
const float right = static_cast<float>(m_width) - 0.5f;
338358
const float bottom = static_cast<float>(m_height) - 0.5f;
339359

340-
const SToneMapVertex vertices[] = {
360+
const SToneMapVertex vertices[6] = {
341361
{left, top, 0.0f, 1.0f, 0.0f, 0.0f},
342362
{right, top, 0.0f, 1.0f, 1.0f, 0.0f},
343363
{left, bottom, 0.0f, 1.0f, 0.0f, 1.0f},
@@ -346,7 +366,7 @@ bool BorderlessToneMapPass::Apply(IDirect3DDevice9* device, float gammaPower, fl
346366
{left, bottom, 0.0f, 1.0f, 0.0f, 1.0f},
347367
};
348368

349-
device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, NUMELMS(vertices) / 3, vertices, sizeof(SToneMapVertex));
369+
device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, vertices, sizeof(SToneMapVertex));
350370

351371
device->SetPixelShader(nullptr);
352372
device->SetTexture(0, nullptr);
@@ -364,6 +384,9 @@ void BorderlessToneMapPass::ReleaseTexture()
364384
m_width = 0;
365385
m_height = 0;
366386
m_format = D3DFMT_UNKNOWN;
387+
388+
// Invalidate apply state block since it captured the old texture pointer
389+
SAFE_RELEASE(m_applyStateBlock);
367390
}
368391

369392
void BorderlessToneMapPass::ReleaseShader()
@@ -372,11 +395,15 @@ void BorderlessToneMapPass::ReleaseShader()
372395
SAFE_RELEASE(m_constantTable);
373396
m_toneParamsHandle = nullptr;
374397
m_shaderFailed = false;
398+
399+
// Invalidate apply state block since it captured the shader pointer
400+
SAFE_RELEASE(m_applyStateBlock);
375401
}
376402

377403
void BorderlessToneMapPass::ReleaseStateBlock()
378404
{
379405
SAFE_RELEASE(m_restoreStateBlock);
406+
SAFE_RELEASE(m_applyStateBlock);
380407
}
381408

382409
void BorderlessToneMapPass::Release()

Client/core/DXHook/CProxyDirect3DDevice9.cpp

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -322,26 +322,32 @@ CProxyDirect3DDevice9::CProxyDirect3DDevice9(IDirect3DDevice9* pDevice)
322322
if (pD3D9)
323323
{
324324
D3DADAPTER_IDENTIFIER9 adaptIdent;
325-
ZeroMemory(&adaptIdent, sizeof(D3DADAPTER_IDENTIFIER9));
326325
HRESULT hr = pD3D9->GetAdapterIdentifier(iAdapter, 0, &adaptIdent);
327-
if (FAILED(hr))
326+
327+
if (SUCCEEDED(hr))
328328
{
329-
// GetAdapterIdentifier failed - continue with defaults
330-
}
331-
332-
int iVideoCardMemoryKBTotal = GetWMIVideoAdapterMemorySize(adaptIdent.VendorId, adaptIdent.DeviceId) / 1024;
329+
// GetAdapterIdentifier succeeded - use adapter info
330+
int iVideoCardMemoryKBTotal = GetWMIVideoAdapterMemorySize(adaptIdent.VendorId, adaptIdent.DeviceId) / 1024;
333331

334-
// Just incase, fallback to using texture memory stats
335-
if (iVideoCardMemoryKBTotal < 16)
336-
iVideoCardMemoryKBTotal = m_pDevice->GetAvailableTextureMem() / 1024;
332+
// Just incase, fallback to using texture memory stats
333+
if (iVideoCardMemoryKBTotal < 16)
334+
iVideoCardMemoryKBTotal = m_pDevice->GetAvailableTextureMem() / 1024;
337335

338-
DeviceState.AdapterState.InstalledMemoryKB = iVideoCardMemoryKBTotal;
336+
DeviceState.AdapterState.InstalledMemoryKB = iVideoCardMemoryKBTotal;
339337

340-
// Get video card name
341-
DeviceState.AdapterState.Name = adaptIdent.Description;
338+
// Get video card name
339+
DeviceState.AdapterState.Name = adaptIdent.Description;
342340

343-
// Clipping is required for some graphic configurations
344-
DeviceState.AdapterState.bRequiresClipping = SStringX(adaptIdent.Description).Contains("Intel");
341+
// Clipping is required for some graphic configurations - use direct C-string search to avoid heap allocation
342+
DeviceState.AdapterState.bRequiresClipping = (strstr(adaptIdent.Description, "Intel") != nullptr);
343+
}
344+
else
345+
{
346+
// GetAdapterIdentifier failed - use defaults
347+
DeviceState.AdapterState.InstalledMemoryKB = m_pDevice->GetAvailableTextureMem() / 1024;
348+
DeviceState.AdapterState.Name = "Unknown";
349+
DeviceState.AdapterState.bRequiresClipping = false;
350+
}
345351

346352
// Release D3D9 interface if we obtained it via GetDirect3D
347353
if (bNeedRelease)

0 commit comments

Comments
 (0)