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 std::array<DWORD[X_VSH_INSTRUCTION_SIZE], X_VSH_MAX_INSTRUCTION_COUNT> g_VertexShaderSlots = { 0 };
|
||||
XTL::DWORD g_Xbox_VertexShader_Handle = 0;
|
||||
|
||||
// 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)
|
||||
// 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
|
||||
if(Address < g_VertexShaderSlots.size()) {
|
||||
auto CxbxVertexShaderSlotPtr = GetCxbxVertexShaderSlotPtr(Address);
|
||||
if(CxbxVertexShaderSlotPtr) {
|
||||
CxbxVertexShader * pCxbxVertexShader = GetCxbxVertexShader(Handle);
|
||||
if (pCxbxVertexShader) {
|
||||
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");
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip the header DWORD at the beginning
|
||||
auto pTokens = &pCxbxVertexShader->pXboxFunctionCopy[1];
|
||||
for (DWORD i = 0; i < pCxbxVertexShader->XboxNrAddressSlots * X_VSH_INSTRUCTION_SIZE; i++) {
|
||||
g_VertexShaderSlots[Address][i] = pTokens[i];
|
||||
}
|
||||
memcpy(CxbxVertexShaderSlotPtr, pTokens, pCxbxVertexShader->XboxNrAddressSlots * X_VSH_INSTRUCTION_SIZE_BYTES);
|
||||
}
|
||||
else {
|
||||
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...
|
||||
|
@ -3625,16 +3620,13 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SelectVertexShader)
|
|||
SetCxbxVertexShader(pCxbxVertexShader);
|
||||
}
|
||||
|
||||
if (Address < g_VertexShaderSlots.size()) {
|
||||
auto pTokens = GetCxbxVertexShaderSlotPtr(Address);
|
||||
if (pTokens) {
|
||||
// Create a vertex shader from the tokens
|
||||
auto pTokens = &g_VertexShaderSlots[Address][0];
|
||||
DWORD shaderSize;
|
||||
auto shaderKey = g_VertexShaderSource.CreateShader(pTokens, &shaderSize);
|
||||
g_pD3DDevice->SetVertexShader(g_VertexShaderSource.GetShader(shaderKey));
|
||||
}
|
||||
else {
|
||||
LOG_TEST_CASE("SelectVertexShader address %d out of range", Address);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// Copy shader instructions to shader slots
|
||||
auto CxbxVertexShaderSlotPtr = GetCxbxVertexShaderSlotPtr(Address);
|
||||
if (CxbxVertexShaderSlotPtr == nullptr)
|
||||
return;
|
||||
|
||||
auto shaderHeader = *((XTL::X_VSH_SHADER_HEADER*) pFunction);
|
||||
auto tokens = &pFunction[1];
|
||||
for (int i = 0; i < shaderHeader.NumInst * X_VSH_INSTRUCTION_SIZE; i++) {
|
||||
g_VertexShaderSlots[Address][i] = tokens[i];
|
||||
}
|
||||
memcpy(CxbxVertexShaderSlotPtr, tokens, shaderHeader.NumInst * X_VSH_INSTRUCTION_SIZE_BYTES);
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
|
|
@ -1247,6 +1247,18 @@ extern boolean IsValidCurrentShader(void)
|
|||
// XTL_EmuIDirect3DDevice_GetVertexShader, just check 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)
|
||||
{
|
||||
|
|
|
@ -232,7 +232,8 @@ extern boolean IsValidCurrentShader(void);
|
|||
inline boolean VshHandleIsVertexShader(DWORD Handle) { return (Handle & X_D3DFVF_RESERVED0) ? TRUE : FALSE; }
|
||||
inline boolean VshHandleIsFVF(DWORD Handle) { return !VshHandleIsVertexShader(Handle); }
|
||||
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 void SetCxbxVertexShader(DWORD XboxVertexShaderHandle, CxbxVertexShader* shader);
|
||||
|
||||
|
|
Loading…
Reference in New Issue