Update dirty shader constants only
And try to minimize D3D9 calls Constants are synced every draw, but titles may only use a few constants so we can potentially save a lot of work Increases performance a little (at least on certain titles like Buffy)
This commit is contained in:
parent
0cb849a3f8
commit
7d672600bb
|
@ -7555,8 +7555,34 @@ void CxbxUpdateHostTextureScaling()
|
||||||
g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_TEXTURES_SCALE_BASE, (float*)texcoordScales.data(), CXBX_D3DVS_TEXTURES_SCALE_SIZE);
|
g_pD3DDevice->SetVertexShaderConstantF(CXBX_D3DVS_TEXTURES_SCALE_BASE, (float*)texcoordScales.data(), CXBX_D3DVS_TEXTURES_SCALE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern float* HLE_get_NV2A_vertex_constant_float4_ptr(unsigned const_index); // TMP glue
|
void CxbxUpdateDirtyVertexShaderConstants(const float* constants, bool* dirty) {
|
||||||
|
// Reduce the number of calls to D3D9 by updating contiguous "batches"
|
||||||
|
// of dirty states
|
||||||
|
int batchStartIndex = -1; // -1 means we aren't in a batch
|
||||||
|
|
||||||
|
for (int i = 0; i < X_D3DVS_CONSTREG_COUNT; i++) {
|
||||||
|
if (batchStartIndex == -1 && dirty[i]) {
|
||||||
|
batchStartIndex = i; // Start a batch
|
||||||
|
}
|
||||||
|
else if (batchStartIndex != -1 && !dirty[i]) {
|
||||||
|
// Finish the batch
|
||||||
|
int count = i - batchStartIndex;
|
||||||
|
g_pD3DDevice->SetVertexShaderConstantF(batchStartIndex, &constants[batchStartIndex * 4], count);
|
||||||
|
batchStartIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constant is no longer dirty
|
||||||
|
dirty[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the final batch
|
||||||
|
if (batchStartIndex != -1) {
|
||||||
|
int count = X_D3DVS_CONSTREG_COUNT - batchStartIndex + 1;
|
||||||
|
g_pD3DDevice->SetVertexShaderConstantF(batchStartIndex, &constants[batchStartIndex * 4], count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern float* HLE_get_NV2A_vertex_constant_float4_ptr(unsigned const_index); // TMP glue
|
||||||
// TODO : Once we're able to flush the NV2A push buffer
|
// TODO : Once we're able to flush the NV2A push buffer
|
||||||
// remove our patches on D3DDevice_SetVertexShaderConstant (and CxbxImpl_SetVertexShaderConstant)
|
// remove our patches on D3DDevice_SetVertexShaderConstant (and CxbxImpl_SetVertexShaderConstant)
|
||||||
void CxbxUpdateHostVertexShaderConstants()
|
void CxbxUpdateHostVertexShaderConstants()
|
||||||
|
@ -7565,14 +7591,33 @@ void CxbxUpdateHostVertexShaderConstants()
|
||||||
// are mirrored on the host.
|
// are mirrored on the host.
|
||||||
// Otherwise, the same set of constants is used for the fixed function vertex shader
|
// Otherwise, the same set of constants is used for the fixed function vertex shader
|
||||||
// implementation instead
|
// implementation instead
|
||||||
|
|
||||||
|
// Track which constants are currently written
|
||||||
|
// So we can skip updates
|
||||||
|
static bool isXboxConstants = false;
|
||||||
|
|
||||||
if (g_Xbox_VertexShaderMode == VertexShaderMode::FixedFunction && g_UseFixedFunctionVertexShader) {
|
if (g_Xbox_VertexShaderMode == VertexShaderMode::FixedFunction && g_UseFixedFunctionVertexShader) {
|
||||||
|
// Write host FF shader state
|
||||||
|
// TODO dirty tracking like for Xbox constants?
|
||||||
UpdateFixedFunctionVertexShaderState();
|
UpdateFixedFunctionVertexShaderState();
|
||||||
|
isXboxConstants = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Copy all constants (as they may have been overwritten with fixed-function mode)
|
// Write Xbox constants
|
||||||
// Though we should only have to copy overwritten or dirty constants
|
auto pg = &(g_NV2A->GetDeviceState()->pgraph);
|
||||||
float* constant_floats = HLE_get_NV2A_vertex_constant_float4_ptr(0);
|
auto constant_floats = (float*)pg->vsh_constants;
|
||||||
g_pD3DDevice->SetVertexShaderConstantF(0, constant_floats, X_D3DVS_CONSTREG_COUNT);
|
|
||||||
|
if (isXboxConstants) {
|
||||||
|
// Only need to overwrite what's changed
|
||||||
|
CxbxUpdateDirtyVertexShaderConstants(constant_floats, pg->vsh_constants_dirty);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// We need to update everything
|
||||||
|
g_pD3DDevice->SetVertexShaderConstantF(0, constant_floats, X_D3DVS_CONSTREG_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We've written the Xbox constants
|
||||||
|
isXboxConstants = true;
|
||||||
|
|
||||||
// FIXME our viewport constants don't match Xbox values
|
// FIXME our viewport constants don't match Xbox values
|
||||||
// If we write them to pgraph constants, like we do with constants set by the title,
|
// If we write them to pgraph constants, like we do with constants set by the title,
|
||||||
|
|
Loading…
Reference in New Issue