Hide vertex slots behind GetCxbxVertexShaderSlotPtr (which also logs out of range test cases)
This commit is contained in:
parent
c1b58dafb9
commit
848f4eeee3
|
@ -195,7 +195,6 @@ static XTL::DWORD *g_Xbox_D3DDevice; // TODO: This should be a
|
||||||
static DWORD g_dwVertexShaderUsage = 0; // Unused. If needed, move to XbVertexShader.cpp
|
static DWORD g_dwVertexShaderUsage = 0; // Unused. If needed, move to XbVertexShader.cpp
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static std::array<DWORD[X_VSH_INSTRUCTION_SIZE], X_VSH_MAX_INSTRUCTION_COUNT> g_VertexShaderSlots = { 0 };
|
|
||||||
XTL::DWORD g_Xbox_VertexShader_Handle = 0;
|
XTL::DWORD g_Xbox_VertexShader_Handle = 0;
|
||||||
|
|
||||||
// Static Function(s)
|
// Static Function(s)
|
||||||
|
@ -3532,28 +3531,24 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_LoadVertexShader)
|
||||||
// Handle is always address of an X_D3DVertexShader struct, thus always or-ed with 1 (X_D3DFVF_RESERVED0)
|
// Handle is always address of an X_D3DVertexShader struct, thus always or-ed with 1 (X_D3DFVF_RESERVED0)
|
||||||
// Address is the slot (offset) from which the program must be written onwards (as whole DWORDS)
|
// Address is the slot (offset) from which the program must be written onwards (as whole DWORDS)
|
||||||
// D3DDevice_LoadVertexShader pushes the program contained in the Xbox VertexShader struct to the NV2A
|
// D3DDevice_LoadVertexShader pushes the program contained in the Xbox VertexShader struct to the NV2A
|
||||||
if(Address < g_VertexShaderSlots.size()) {
|
auto CxbxVertexShaderSlotPtr = GetCxbxVertexShaderSlotPtr(Address);
|
||||||
|
if(CxbxVertexShaderSlotPtr) {
|
||||||
CxbxVertexShader * pCxbxVertexShader = GetCxbxVertexShader(Handle);
|
CxbxVertexShader * pCxbxVertexShader = GetCxbxVertexShader(Handle);
|
||||||
if (pCxbxVertexShader) {
|
if (pCxbxVertexShader) {
|
||||||
int upToSlot = Address + pCxbxVertexShader->XboxNrAddressSlots;
|
int upToSlot = Address + pCxbxVertexShader->XboxNrAddressSlots;
|
||||||
if (upToSlot > g_VertexShaderSlots.size()) {
|
if (upToSlot > X_VSH_MAX_INSTRUCTION_COUNT) {
|
||||||
LOG_TEST_CASE("Shader does not fit in vertex shader slots");
|
LOG_TEST_CASE("Shader does not fit in vertex shader slots");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip the header DWORD at the beginning
|
// Skip the header DWORD at the beginning
|
||||||
auto pTokens = &pCxbxVertexShader->pXboxFunctionCopy[1];
|
auto pTokens = &pCxbxVertexShader->pXboxFunctionCopy[1];
|
||||||
for (DWORD i = 0; i < pCxbxVertexShader->XboxNrAddressSlots * X_VSH_INSTRUCTION_SIZE; i++) {
|
memcpy(CxbxVertexShaderSlotPtr, pTokens, pCxbxVertexShader->XboxNrAddressSlots * X_VSH_INSTRUCTION_SIZE_BYTES);
|
||||||
g_VertexShaderSlots[Address][i] = pTokens[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG_TEST_CASE("LoadVertexShader called with unrecognized handle %d", Handle);
|
LOG_TEST_CASE("LoadVertexShader called with unrecognized handle %d", Handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
LOG_TEST_CASE("LoadVertexShader address %d out of range", Address);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LTCG specific D3DDevice_SelectVertexShader function...
|
// LTCG specific D3DDevice_SelectVertexShader function...
|
||||||
|
@ -3625,16 +3620,13 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SelectVertexShader)
|
||||||
SetCxbxVertexShader(pCxbxVertexShader);
|
SetCxbxVertexShader(pCxbxVertexShader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Address < g_VertexShaderSlots.size()) {
|
auto pTokens = GetCxbxVertexShaderSlotPtr(Address);
|
||||||
|
if (pTokens) {
|
||||||
// Create a vertex shader from the tokens
|
// Create a vertex shader from the tokens
|
||||||
auto pTokens = &g_VertexShaderSlots[Address][0];
|
|
||||||
DWORD shaderSize;
|
DWORD shaderSize;
|
||||||
auto shaderKey = g_VertexShaderSource.CreateShader(pTokens, &shaderSize);
|
auto shaderKey = g_VertexShaderSource.CreateShader(pTokens, &shaderSize);
|
||||||
g_pD3DDevice->SetVertexShader(g_VertexShaderSource.GetShader(shaderKey));
|
g_pD3DDevice->SetVertexShader(g_VertexShaderSource.GetShader(shaderKey));
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
LOG_TEST_CASE("SelectVertexShader address %d out of range", Address);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(hRet))
|
if (FAILED(hRet))
|
||||||
{
|
{
|
||||||
|
@ -8144,11 +8136,13 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_LoadVertexShaderProgram)
|
||||||
// D3DDevice_LoadVertexShaderProgram splits the given function buffer into batch-wise pushes to the NV2A
|
// D3DDevice_LoadVertexShaderProgram splits the given function buffer into batch-wise pushes to the NV2A
|
||||||
|
|
||||||
// Copy shader instructions to shader slots
|
// Copy shader instructions to shader slots
|
||||||
|
auto CxbxVertexShaderSlotPtr = GetCxbxVertexShaderSlotPtr(Address);
|
||||||
|
if (CxbxVertexShaderSlotPtr == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
auto shaderHeader = *((XTL::X_VSH_SHADER_HEADER*) pFunction);
|
auto shaderHeader = *((XTL::X_VSH_SHADER_HEADER*) pFunction);
|
||||||
auto tokens = &pFunction[1];
|
auto tokens = &pFunction[1];
|
||||||
for (int i = 0; i < shaderHeader.NumInst * X_VSH_INSTRUCTION_SIZE; i++) {
|
memcpy(CxbxVertexShaderSlotPtr, tokens, shaderHeader.NumInst * X_VSH_INSTRUCTION_SIZE_BYTES);
|
||||||
g_VertexShaderSlots[Address][i] = tokens[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
|
|
@ -1247,6 +1247,18 @@ extern boolean IsValidCurrentShader(void)
|
||||||
// XTL_EmuIDirect3DDevice_GetVertexShader, just check g_Xbox_VertexShader_Handle :
|
// XTL_EmuIDirect3DDevice_GetVertexShader, just check g_Xbox_VertexShader_Handle :
|
||||||
return VshHandleIsValidShader(g_Xbox_VertexShader_Handle);
|
return VshHandleIsValidShader(g_Xbox_VertexShader_Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD g_CxbxVertexShaderSlots[X_VSH_MAX_INSTRUCTION_COUNT * X_VSH_INSTRUCTION_SIZE] = { 0 };
|
||||||
|
|
||||||
|
DWORD* GetCxbxVertexShaderSlotPtr(const DWORD SlotIndexAddress)
|
||||||
|
{
|
||||||
|
if (SlotIndexAddress < X_VSH_MAX_INSTRUCTION_COUNT) {
|
||||||
|
return &g_CxbxVertexShaderSlots[SlotIndexAddress * X_VSH_INSTRUCTION_SIZE];
|
||||||
|
} else {
|
||||||
|
LOG_TEST_CASE("SlotIndexAddress %d out of range", SlotIndexAddress);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CxbxVertexDeclaration *GetCxbxVertexDeclaration(DWORD XboxVertexShaderHandle)
|
CxbxVertexDeclaration *GetCxbxVertexDeclaration(DWORD XboxVertexShaderHandle)
|
||||||
{
|
{
|
||||||
|
|
|
@ -232,7 +232,8 @@ extern boolean IsValidCurrentShader(void);
|
||||||
inline boolean VshHandleIsVertexShader(DWORD Handle) { return (Handle & X_D3DFVF_RESERVED0) ? TRUE : FALSE; }
|
inline boolean VshHandleIsVertexShader(DWORD Handle) { return (Handle & X_D3DFVF_RESERVED0) ? TRUE : FALSE; }
|
||||||
inline boolean VshHandleIsFVF(DWORD Handle) { return !VshHandleIsVertexShader(Handle); }
|
inline boolean VshHandleIsFVF(DWORD Handle) { return !VshHandleIsVertexShader(Handle); }
|
||||||
inline XTL::X_D3DVertexShader *VshHandleToXboxVertexShader(DWORD Handle) { return (XTL::X_D3DVertexShader *)(Handle & ~X_D3DFVF_RESERVED0);}
|
inline XTL::X_D3DVertexShader *VshHandleToXboxVertexShader(DWORD Handle) { return (XTL::X_D3DVertexShader *)(Handle & ~X_D3DFVF_RESERVED0);}
|
||||||
|
|
||||||
|
extern DWORD* GetCxbxVertexShaderSlotPtr(const DWORD SlotIndexAddress);
|
||||||
extern CxbxVertexShader* GetCxbxVertexShader(DWORD XboxVertexShaderHandle);
|
extern CxbxVertexShader* GetCxbxVertexShader(DWORD XboxVertexShaderHandle);
|
||||||
extern void SetCxbxVertexShader(DWORD XboxVertexShaderHandle, CxbxVertexShader* shader);
|
extern void SetCxbxVertexShader(DWORD XboxVertexShaderHandle, CxbxVertexShader* shader);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue