Merge pull request #1683 from LukeUsher/vertex-shader-register-tweaks
Vertex shader register tweaks
This commit is contained in:
commit
f62030a548
|
@ -4168,6 +4168,23 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexData4f)
|
|||
|
||||
HRESULT hRet = D3D_OK;
|
||||
|
||||
// Get the vertex shader flags (if any is active) :
|
||||
uint32_t ActiveVertexAttributeFlags = 0;
|
||||
if (VshHandleIsVertexShader(g_CurrentXboxVertexShaderHandle)) {
|
||||
LOG_TEST_CASE("D3DDevice_SetVertexData4f with active VertexShader");
|
||||
X_D3DVertexShader* pXboxVertexShader = VshHandleToXboxVertexShader(g_CurrentXboxVertexShaderHandle);
|
||||
if (!(pXboxVertexShader->Flags & 0x10/*=X_VERTEXSHADER_PROGRAM*/)) {
|
||||
ActiveVertexAttributeFlags = pXboxVertexShader->Flags;
|
||||
}
|
||||
|
||||
// If we have an active vertex shader, we also write the input to a vertex shader constant
|
||||
// This allows us to implement Xbox functionality where SetVertexData4f can be used to specify attributes
|
||||
// not present in the vertex declaration.
|
||||
// We use range 193 and up to store these values, as Xbox shaders stop at c192!
|
||||
FLOAT values[] = {a,b,c,d};
|
||||
g_pD3DDevice->SetVertexShaderConstantF(X_D3DVS_CONSTREG_VERTEXDATA4F_BASE + Register, values, 1);
|
||||
}
|
||||
|
||||
// Grow g_InlineVertexBuffer_Table to contain at least current, and a potentially next vertex
|
||||
if (g_InlineVertexBuffer_TableLength <= g_InlineVertexBuffer_TableOffset + 1) {
|
||||
if (g_InlineVertexBuffer_TableLength == 0) {
|
||||
|
@ -4185,16 +4202,6 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexData4f)
|
|||
// Set first vertex to zero (preventing leaks from prior Begin/End calls)
|
||||
g_InlineVertexBuffer_Table[0] = {};
|
||||
|
||||
// Get the vertex shader flags (if any is active) :
|
||||
uint32_t ActiveVertexAttributeFlags = 0;
|
||||
if (VshHandleIsVertexShader(g_CurrentXboxVertexShaderHandle)) {
|
||||
LOG_TEST_CASE("D3DDevice_SetVertexData4f with active VertexShader");
|
||||
X_D3DVertexShader *pXboxVertexShader = VshHandleToXboxVertexShader(g_CurrentXboxVertexShaderHandle);
|
||||
if (!(pXboxVertexShader->Flags & 0x10/*=X_VERTEXSHADER_PROGRAM*/)) {
|
||||
ActiveVertexAttributeFlags = pXboxVertexShader->Flags;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle persistent vertex attribute flags, by resetting non-persistent colors
|
||||
// to their default value (and leaving the persistent colors alone - see the
|
||||
// "Copy all attributes of the previous vertex" comment below) :
|
||||
|
@ -4313,6 +4320,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexData4f)
|
|||
{
|
||||
g_InlineVertexBuffer_Table[o].Diffuse = D3DCOLOR_COLORVALUE(a, b, c, d);
|
||||
g_InlineVertexBuffer_FVF |= D3DFVF_DIFFUSE;
|
||||
HLE_write_NV2A_vertex_attribute_slot(X_D3DVSDE_DIFFUSE, g_InlineVertexBuffer_Table[o].Diffuse);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4320,13 +4328,14 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexData4f)
|
|||
{
|
||||
g_InlineVertexBuffer_Table[o].Specular = D3DCOLOR_COLORVALUE(a, b, c, d);
|
||||
g_InlineVertexBuffer_FVF |= D3DFVF_SPECULAR;
|
||||
HLE_write_NV2A_vertex_attribute_slot(X_D3DVSDE_SPECULAR, g_InlineVertexBuffer_Table[o].Specular);
|
||||
break;
|
||||
}
|
||||
|
||||
case X_D3DVSDE_FOG: // Xbox extension
|
||||
{
|
||||
g_InlineVertexBuffer_Table[o].Fog = a; // TODO : What about the other (b, c and d) arguments?
|
||||
EmuLog(LOG_LEVEL::WARNING, "Host Direct3D8 doesn''t support FVF FOG");
|
||||
//EmuLog(LOG_LEVEL::WARNING, "Host Direct3D8 doesn''t support FVF FOG");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4335,14 +4344,16 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexData4f)
|
|||
case X_D3DVSDE_BACKDIFFUSE: // Xbox extension
|
||||
{
|
||||
g_InlineVertexBuffer_Table[o].BackDiffuse = D3DCOLOR_COLORVALUE(a, b, c, d);
|
||||
EmuLog(LOG_LEVEL::WARNING, "Host Direct3D8 doesn''t support FVF BACKDIFFUSE");
|
||||
//EmuLog(LOG_LEVEL::WARNING, "Host Direct3D8 doesn''t support FVF BACKDIFFUSE");
|
||||
HLE_write_NV2A_vertex_attribute_slot(X_D3DVSDE_BACKDIFFUSE, g_InlineVertexBuffer_Table[o].BackDiffuse);
|
||||
break;
|
||||
}
|
||||
|
||||
case X_D3DVSDE_BACKSPECULAR: // Xbox extension
|
||||
{
|
||||
g_InlineVertexBuffer_Table[o].BackSpecular = D3DCOLOR_COLORVALUE(a, b, c, d);
|
||||
EmuLog(LOG_LEVEL::WARNING, "Host Direct3D8 doesn''t support FVF BACKSPECULAR");
|
||||
//EmuLog(LOG_LEVEL::WARNING, "Host Direct3D8 doesn''t support FVF BACKSPECULAR");
|
||||
HLE_write_NV2A_vertex_attribute_slot(X_D3DVSDE_BACKSPECULAR, g_InlineVertexBuffer_Table[o].BackSpecular);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -6487,7 +6498,16 @@ VOID __fastcall XTL::EMUPATCH(D3DDevice_SetRenderState_Simple)
|
|||
// Just log and return
|
||||
EmuLog(LOG_LEVEL::DEBUG, "RenderState_Simple(0x%.08X (%s), 0x%.08X) was ignored!", Method, DxbxRenderStateInfo[XboxRenderStateIndex].S, Value);
|
||||
return;
|
||||
case X_D3DRS_ALPHATESTENABLE: case X_D3DRS_ALPHABLENDENABLE:
|
||||
case X_D3DRS_ALPHATESTENABLE:
|
||||
if (g_LibVersion_D3D8 == 3925) {
|
||||
// HACK: Many 3925 have missing polygons when this is true
|
||||
// Until we find out the true underlying cause, and carry on
|
||||
// Test Cases: Halo, Silent Hill 2.
|
||||
LOG_TEST_CASE("Applying 3925 alpha test disable hack");
|
||||
Value = false;
|
||||
}
|
||||
break;
|
||||
case X_D3DRS_ALPHABLENDENABLE:
|
||||
case X_D3DRS_ALPHAREF: case X_D3DRS_ZWRITEENABLE:
|
||||
case X_D3DRS_DITHERENABLE: case X_D3DRS_STENCILREF:
|
||||
case X_D3DRS_STENCILMASK: case X_D3DRS_STENCILWRITEMASK:
|
||||
|
@ -7119,6 +7139,15 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexShader)
|
|||
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexDeclaration");
|
||||
hRet = g_pD3DDevice->SetVertexShader((XTL::IDirect3DVertexShader9*)pVertexShader->Handle);
|
||||
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader(VshHandleIsVertexShader)");
|
||||
|
||||
// Set default constant values for specular, diffuse, etc
|
||||
static const float ColorBlack[4] = { 0,0,0,0 };
|
||||
static const float ColorWhite[4] = { 1,1,1,1 };
|
||||
|
||||
g_pD3DDevice->SetVertexShaderConstantF(X_D3DVS_CONSTREG_VERTEXDATA4F_BASE + X_D3DVSDE_DIFFUSE, ColorWhite, 1);
|
||||
g_pD3DDevice->SetVertexShaderConstantF(X_D3DVS_CONSTREG_VERTEXDATA4F_BASE + X_D3DVSDE_BACKDIFFUSE, ColorWhite, 1);
|
||||
g_pD3DDevice->SetVertexShaderConstantF(X_D3DVS_CONSTREG_VERTEXDATA4F_BASE + X_D3DVSDE_SPECULAR, ColorBlack, 1);
|
||||
g_pD3DDevice->SetVertexShaderConstantF(X_D3DVS_CONSTREG_VERTEXDATA4F_BASE + X_D3DVSDE_BACKSPECULAR, ColorBlack, 1);
|
||||
} else {
|
||||
hRet = g_pD3DDevice->SetVertexShader(nullptr);
|
||||
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader");
|
||||
|
@ -7499,7 +7528,12 @@ void XTL::CxbxUpdateNativeD3DResources()
|
|||
// Some titles set Vertex Shader constants directly via pushbuffers rather than through D3D
|
||||
// We handle that case by updating any constants that have the dirty flag set on the nv2a.
|
||||
auto nv2a = g_NV2A->GetDeviceState();
|
||||
for(int i = 0; i < 192; i++) {
|
||||
for(int i = 0; i < X_D3DVS_CONSTREG_COUNT; i++) {
|
||||
// Skip vOffset and vScale constants, we don't want our values to be overwritten by accident
|
||||
if (i == X_D3DSCM_RESERVED_CONSTANT1_CORRECTED || i == X_D3DSCM_RESERVED_CONSTANT2_CORRECTED) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nv2a->pgraph.vsh_constants_dirty[i]) {
|
||||
g_pD3DDevice->SetVertexShaderConstantF(i, (float*)&nv2a->pgraph.vsh_constants[i][0], 1);
|
||||
nv2a->pgraph.vsh_constants_dirty[i] = false;
|
||||
|
|
|
@ -1081,6 +1081,10 @@ typedef DWORD X_VERTEXSHADERCONSTANTMODE;
|
|||
#define X_D3DSCM_CORRECTION 96 // Add 96 to arrive at the range 0..191 (instead of 96..95)
|
||||
#define X_D3DVS_CONSTREG_COUNT 192
|
||||
|
||||
#define X_D3DSCM_RESERVED_CONSTANT1_CORRECTED (X_D3DSCM_RESERVED_CONSTANT1 + X_D3DSCM_CORRECTION)
|
||||
#define X_D3DSCM_RESERVED_CONSTANT2_CORRECTED (X_D3DSCM_RESERVED_CONSTANT2 + X_D3DSCM_CORRECTION)
|
||||
#define X_D3DVS_CONSTREG_VERTEXDATA4F_BASE (X_D3DVS_CONSTREG_COUNT + 1)
|
||||
|
||||
// Vertex shader types
|
||||
#define X_VST_NORMAL 1
|
||||
#define X_VST_READWRITE 2
|
||||
|
|
|
@ -103,7 +103,16 @@ void UpdateDeferredRenderStates()
|
|||
Value = *(DWORD*)&fogValue;
|
||||
}
|
||||
} break;
|
||||
case XTL::X_D3DRS_FOGENABLE:
|
||||
case XTL::X_D3DRS_FOGENABLE:
|
||||
if (g_LibVersion_D3D8 == 3925) {
|
||||
// HACK: Many 3925 games only show a black screen if fog is enabled
|
||||
// Initially, this was thought to be bad offsets, but it has been verified to be correct
|
||||
// Until we find out the true underlying cause, disable fog and carry on
|
||||
// Test Cases: Halo, Silent Hill 2.
|
||||
LOG_TEST_CASE("Applying 3925 fog disable hack");
|
||||
Value = false;
|
||||
}
|
||||
break;
|
||||
case XTL::X_D3DRS_FOGTABLEMODE:
|
||||
case XTL::X_D3DRS_FOGDENSITY:
|
||||
case XTL::X_D3DRS_RANGEFOGENABLE:
|
||||
|
|
|
@ -486,8 +486,8 @@ static const char* OReg_Name[] =
|
|||
"a0.x"
|
||||
};
|
||||
|
||||
std::array<bool, 16> RegVUsage;
|
||||
std::array<int, 16> RegVDeclUsage;
|
||||
std::array<bool, 16> RegVIsPresentInDeclaration;
|
||||
std::array<bool, 16> RegVIsUsedByShader;
|
||||
|
||||
/* TODO : map non-FVF Xbox vertex shader handle to CxbxVertexShader (a struct containing a host Xbox vertex shader handle and the original members)
|
||||
std::unordered_map<DWORD, CxbxVertexShader> g_CxbxVertexShaders;
|
||||
|
@ -790,28 +790,87 @@ static void VshWriteParameter(VSH_IMD_PARAMETER *pParameter,
|
|||
}
|
||||
|
||||
|
||||
// From D3D8to9
|
||||
static const BYTE DeclAddressUsages[][2] =
|
||||
{
|
||||
{ XTL::D3DDECLUSAGE_POSITION, 0 },
|
||||
{ XTL::D3DDECLUSAGE_BLENDWEIGHT, 0 },
|
||||
{ XTL::D3DDECLUSAGE_BLENDINDICES, 0 },
|
||||
{ XTL::D3DDECLUSAGE_NORMAL, 0 },
|
||||
{ XTL::D3DDECLUSAGE_PSIZE, 0 },
|
||||
{ XTL::D3DDECLUSAGE_COLOR, 0 },
|
||||
{ XTL::D3DDECLUSAGE_COLOR, 1 },
|
||||
{ XTL::D3DDECLUSAGE_TEXCOORD, 0 },
|
||||
{ XTL::D3DDECLUSAGE_TEXCOORD, 1 },
|
||||
{ XTL::D3DDECLUSAGE_TEXCOORD, 2 },
|
||||
{ XTL::D3DDECLUSAGE_TEXCOORD, 3 },
|
||||
{ XTL::D3DDECLUSAGE_TEXCOORD, 4 },
|
||||
{ XTL::D3DDECLUSAGE_TEXCOORD, 5 },
|
||||
{ XTL::D3DDECLUSAGE_TEXCOORD, 6 },
|
||||
{ XTL::D3DDECLUSAGE_TEXCOORD, 7 },
|
||||
{ XTL::D3DDECLUSAGE_POSITION, 1 },
|
||||
{ XTL::D3DDECLUSAGE_NORMAL, 1 }
|
||||
};
|
||||
#define D3DDECLUSAGE_UNSUPPORTED ((D3DDECLUSAGE)-1)
|
||||
|
||||
XTL::D3DDECLUSAGE Xb2PCRegisterType
|
||||
(
|
||||
DWORD VertexRegister,
|
||||
BYTE& PCUsageIndex
|
||||
)
|
||||
{
|
||||
using namespace XTL;
|
||||
|
||||
D3DDECLUSAGE PCRegisterType;
|
||||
PCUsageIndex = 0;
|
||||
|
||||
switch (VertexRegister)
|
||||
{
|
||||
case X_D3DVSDE_VERTEX: // -1
|
||||
DbgVshPrintf("D3DVSDE_VERTEX /* xbox ext. */");
|
||||
PCRegisterType = D3DDECLUSAGE_UNSUPPORTED;
|
||||
break;
|
||||
case X_D3DVSDE_POSITION: // 0
|
||||
DbgVshPrintf("D3DVSDE_POSITION");
|
||||
PCRegisterType = D3DDECLUSAGE_POSITION;
|
||||
break;
|
||||
case X_D3DVSDE_BLENDWEIGHT: // 1
|
||||
DbgVshPrintf("D3DVSDE_BLENDWEIGHT");
|
||||
PCRegisterType = D3DDECLUSAGE_BLENDWEIGHT;
|
||||
break;
|
||||
case X_D3DVSDE_NORMAL: // 2
|
||||
DbgVshPrintf("D3DVSDE_NORMAL");
|
||||
PCRegisterType = D3DDECLUSAGE_NORMAL;
|
||||
break;
|
||||
case X_D3DVSDE_DIFFUSE: // 3
|
||||
DbgVshPrintf("D3DVSDE_DIFFUSE");
|
||||
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 0;
|
||||
break;
|
||||
case X_D3DVSDE_SPECULAR: // 4
|
||||
DbgVshPrintf("D3DVSDE_SPECULAR");
|
||||
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 1;
|
||||
break;
|
||||
case X_D3DVSDE_FOG: // 5
|
||||
DbgVshPrintf("D3DVSDE_FOG");
|
||||
PCRegisterType = D3DDECLUSAGE_FOG;
|
||||
break;
|
||||
case X_D3DVSDE_POINTSIZE: // 6
|
||||
DbgVshPrintf("D3DVDSE_POINTSIZE");
|
||||
PCRegisterType = D3DDECLUSAGE_PSIZE;
|
||||
break;
|
||||
case X_D3DVSDE_BACKDIFFUSE: // 7
|
||||
DbgVshPrintf("D3DVSDE_BACKDIFFUSE /* xbox ext. */");
|
||||
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 2;
|
||||
break;
|
||||
case X_D3DVSDE_BACKSPECULAR: // 8
|
||||
DbgVshPrintf("D3DVSDE_BACKSPECULAR /* xbox ext. */");
|
||||
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 3;
|
||||
break;
|
||||
case X_D3DVSDE_TEXCOORD0: // 9
|
||||
DbgVshPrintf("D3DVSDE_TEXCOORD0");
|
||||
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 0;
|
||||
break;
|
||||
case X_D3DVSDE_TEXCOORD1: // 10
|
||||
DbgVshPrintf("D3DVSDE_TEXCOORD1");
|
||||
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 1;
|
||||
break;
|
||||
case X_D3DVSDE_TEXCOORD2: // 11
|
||||
DbgVshPrintf("D3DVSDE_TEXCOORD2");
|
||||
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 2;
|
||||
break;
|
||||
case X_D3DVSDE_TEXCOORD3: // 12
|
||||
DbgVshPrintf("D3DVSDE_TEXCOORD3");
|
||||
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 3;
|
||||
break;
|
||||
default:
|
||||
DbgVshPrintf("%d /* unknown register */", VertexRegister);
|
||||
PCRegisterType = D3DDECLUSAGE_UNSUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
return PCRegisterType;
|
||||
}
|
||||
|
||||
extern XTL::D3DCAPS g_D3DCaps;
|
||||
|
||||
static void VshWriteShader(VSH_XBOX_SHADER *pShader,
|
||||
std::stringstream& pDisassembly,
|
||||
|
@ -841,55 +900,36 @@ static void VshWriteShader(VSH_XBOX_SHADER *pShader,
|
|||
}
|
||||
|
||||
if (Truncate) {
|
||||
std::stringstream moveConstantsToTemporaries;
|
||||
|
||||
pDisassembly << "; Input usage declarations --\n";
|
||||
unsigned i = 0;
|
||||
do {
|
||||
if (RegVUsage[i]) {
|
||||
DWORD PCUsageIndex = DeclAddressUsages[i][1];
|
||||
DWORD usage = DeclAddressUsages[i][0];
|
||||
|
||||
// If an override exists, use it
|
||||
if (RegVDeclUsage[i] >= 0) {
|
||||
usage = RegVDeclUsage[i];
|
||||
if (RegVIsUsedByShader[i]) {
|
||||
if (!RegVIsPresentInDeclaration[i]) {
|
||||
// Log test case and skip
|
||||
// Any registers hitting this critera were already replaced with constant/temporary reads
|
||||
// To correctly use the values given in SetVertexData4f.
|
||||
// We need to move these constant values to temporaries so they can be used as input alongside other constants!
|
||||
// We count down from the highest available on the host because Xbox titles don't use values that high, and we read from c192 because Xbox uses 192 constants
|
||||
static int temporaryRegisterBase = g_D3DCaps.VS20Caps.NumTemps - 13;
|
||||
moveConstantsToTemporaries << "mov r" << (temporaryRegisterBase + i) << ", c" << (X_D3DVS_CONSTREG_VERTEXDATA4F_BASE + i) << "\n";
|
||||
LOG_TEST_CASE("Shader uses undeclared Vertex Input Registers");
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::stringstream dclStream;
|
||||
switch (usage) {
|
||||
case XTL::D3DDECLUSAGE_POSITION:
|
||||
dclStream << "dcl_position" << (int)PCUsageIndex;
|
||||
break;
|
||||
case XTL::D3DDECLUSAGE_BLENDWEIGHT:
|
||||
dclStream << "dcl_blendweight";
|
||||
break;
|
||||
case XTL::D3DDECLUSAGE_BLENDINDICES:
|
||||
dclStream << "dcl_blendindices";
|
||||
break;
|
||||
case XTL::D3DDECLUSAGE_NORMAL:
|
||||
dclStream << "dcl_normal";
|
||||
break;
|
||||
case XTL::D3DDECLUSAGE_COLOR:
|
||||
dclStream << "dcl_color" << (int)PCUsageIndex;
|
||||
break;
|
||||
case XTL::D3DDECLUSAGE_FOG:
|
||||
dclStream << "dcl_fog";
|
||||
break;
|
||||
case XTL::D3DDECLUSAGE_TEXCOORD:
|
||||
dclStream << "dcl_texcoord" << (int)PCUsageIndex;
|
||||
break;
|
||||
case XTL::D3DDECLUSAGE_PSIZE:
|
||||
dclStream << "dcl_psize";
|
||||
break;
|
||||
default:
|
||||
dclStream << "dcl_unknown ("<< (int)PCUsageIndex << ")";
|
||||
LOG_TEST_CASE("Encountered unknown declaration");
|
||||
break;
|
||||
}
|
||||
|
||||
pDisassembly << dclStream.str() << " v" << i << "\n";
|
||||
// dcl_texcoord can be useds for any user-defined data
|
||||
// We need this because there is no reliable way to detect the real usage
|
||||
// Xbox has no concept of 'usage types', it only requires a list of attribute register numbers.
|
||||
// So we treat them all as 'user-defined'
|
||||
pDisassembly << "dcl_texcoord" << i << " v" << i << "\n";
|
||||
}
|
||||
|
||||
i++;
|
||||
} while (i < RegVUsage.size());
|
||||
} while (i < RegVIsUsedByShader.size());
|
||||
|
||||
pDisassembly << moveConstantsToTemporaries.str();
|
||||
}
|
||||
|
||||
for (int i = 0; i < pShader->IntermediateCount && (i < VSH_MAX_INSTRUCTION_COUNT || !Truncate); i++)
|
||||
|
@ -1388,7 +1428,7 @@ static void VshRemoveScreenSpaceInstructions(VSH_XBOX_SHADER *pShader)
|
|||
// If we couldn't find the generic screen space transformation we're
|
||||
// assuming that the shader writes direct screen coordinates that must be
|
||||
// normalized. This hack will fail if (a) the shader uses custom screen
|
||||
// space transformation, (b) reads r10 or r11 after we have written to
|
||||
// space transformation, (b) reads r13 or r12 after we have written to
|
||||
// them, or (c) doesn't reserve c-38 and c-37 for scale and offset.
|
||||
if(deleted != 3)
|
||||
{
|
||||
|
@ -1401,17 +1441,17 @@ static void VshRemoveScreenSpaceInstructions(VSH_XBOX_SHADER *pShader)
|
|||
if( pIntermediate->Output.Type == IMD_OUTPUT_O &&
|
||||
pIntermediate->Output.Address == OREG_OPOS)
|
||||
{
|
||||
// Redirect output to r11.
|
||||
// Redirect output to r12.
|
||||
pIntermediate->Output.Type = IMD_OUTPUT_R;
|
||||
pIntermediate->Output.Address = 11;
|
||||
pIntermediate->Output.Address = 12;
|
||||
|
||||
// Scale r11 to r10. (mul r10.[mask], r11, c58)
|
||||
// Scale r12 to r13. (mul r13.[mask], r12, c58)
|
||||
VSH_INTERMEDIATE_FORMAT MulIntermediate;
|
||||
MulIntermediate.IsCombined = FALSE;
|
||||
MulIntermediate.InstructionType = IMD_MAC;
|
||||
MulIntermediate.MAC = MAC_MUL;
|
||||
MulIntermediate.Output.Type = IMD_OUTPUT_R;
|
||||
MulIntermediate.Output.Address = 10;
|
||||
MulIntermediate.Output.Address = 13;
|
||||
MulIntermediate.Output.Mask[0] = pIntermediate->Output.Mask[0];
|
||||
MulIntermediate.Output.Mask[1] = pIntermediate->Output.Mask[1];
|
||||
MulIntermediate.Output.Mask[2] = pIntermediate->Output.Mask[2];
|
||||
|
@ -1419,7 +1459,7 @@ static void VshRemoveScreenSpaceInstructions(VSH_XBOX_SHADER *pShader)
|
|||
MulIntermediate.Parameters[0].Active = TRUE;
|
||||
MulIntermediate.Parameters[0].IndexesWithA0_X = FALSE;
|
||||
MulIntermediate.Parameters[0].Parameter.ParameterType = PARAM_R;
|
||||
MulIntermediate.Parameters[0].Parameter.Address = 11;
|
||||
MulIntermediate.Parameters[0].Parameter.Address = 12;
|
||||
MulIntermediate.Parameters[0].Parameter.Neg = FALSE;
|
||||
VshSetSwizzle(&MulIntermediate.Parameters[0], SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
|
||||
MulIntermediate.Parameters[1].Active = TRUE;
|
||||
|
@ -1431,13 +1471,13 @@ static void VshRemoveScreenSpaceInstructions(VSH_XBOX_SHADER *pShader)
|
|||
MulIntermediate.Parameters[2].Active = FALSE;
|
||||
VshInsertIntermediate(pShader, &MulIntermediate, ++i);
|
||||
|
||||
// Add offset with r10 to oPos (add oPos.[mask], r10, c59)
|
||||
// Add offset with r13 to oPos (add oPos.[mask], r13, c59)
|
||||
VSH_INTERMEDIATE_FORMAT AddIntermediate = MulIntermediate;
|
||||
AddIntermediate.MAC = MAC_ADD;
|
||||
AddIntermediate.Output.Type = IMD_OUTPUT_O;
|
||||
AddIntermediate.Output.Address = OREG_OPOS;
|
||||
AddIntermediate.Parameters[0].Parameter.ParameterType = PARAM_R;
|
||||
AddIntermediate.Parameters[0].Parameter.Address = 10;
|
||||
AddIntermediate.Parameters[0].Parameter.Address = 13;
|
||||
AddIntermediate.Parameters[1].Parameter.Address = ConvertCRegister(59);
|
||||
VshInsertIntermediate(pShader, &AddIntermediate, ++i);
|
||||
}
|
||||
|
@ -1468,11 +1508,15 @@ static boolean VshConvertShader(VSH_XBOX_SHADER *pShader,
|
|||
{
|
||||
using namespace XTL;
|
||||
|
||||
extern XTL::D3DCAPS g_D3DCaps;
|
||||
|
||||
const DWORD temporaryCount = g_D3DCaps.VS20Caps.NumTemps;
|
||||
|
||||
boolean RUsage[VSH_MAX_TEMPORARY_REGISTERS] = { FALSE };
|
||||
// Set the last 13 register to used (they are used for SetVertexData4f Constants)
|
||||
for (int i = 1; i <= 13; i++) {
|
||||
RUsage[VSH_MAX_TEMPORARY_REGISTERS - i] = true;
|
||||
}
|
||||
|
||||
|
||||
// TODO: What about state shaders and such?
|
||||
pShader->ShaderHeader.Version = VERSION_VS;
|
||||
|
||||
|
@ -1569,7 +1613,16 @@ static boolean VshConvertShader(VSH_XBOX_SHADER *pShader,
|
|||
}
|
||||
|
||||
if (pIntermediate->Parameters[j].Parameter.ParameterType == PARAM_V) {
|
||||
RegVUsage[pIntermediate->Parameters[j].Parameter.Address] = TRUE;
|
||||
RegVIsUsedByShader[pIntermediate->Parameters[j].Parameter.Address] = TRUE;
|
||||
|
||||
if (!RegVIsPresentInDeclaration[pIntermediate->Parameters[j].Parameter.Address]) {
|
||||
// This vertex register was not declared and therefore is not present within the Vertex Data object
|
||||
// We read from temporary registers instead, that are set based on constants, in-turn, set by SetVertexData4f
|
||||
// We count down from the highest available on the host because Xbox titles don't use values that high, and we read from c192 because Xbox uses 192 constants
|
||||
static int temporaryRegisterBase = g_D3DCaps.VS20Caps.NumTemps - 13;
|
||||
pIntermediate->Parameters[j].Parameter.ParameterType = PARAM_R;
|
||||
pIntermediate->Parameters[j].Parameter.Address += temporaryRegisterBase;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1682,69 +1735,35 @@ static boolean VshConvertShader(VSH_XBOX_SHADER *pShader,
|
|||
i++;
|
||||
}
|
||||
}
|
||||
int16_t R12Replacement = -1;
|
||||
if(temporaryCount <= 12 && RUsage[12])
|
||||
{
|
||||
// Sigh, they absolutely had to use r12, didn't they?
|
||||
for (int i = temporaryCount - 1; i >= 0; i--)
|
||||
{
|
||||
if(!RUsage[i])
|
||||
{
|
||||
R12Replacement = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(R12Replacement == -1)
|
||||
{
|
||||
EmuLog(LOG_LEVEL::WARNING, "Vertex shader uses all r registers, including r12; impossible to convert!");
|
||||
return FALSE;
|
||||
}
|
||||
for (int j = 0; j < pShader->IntermediateCount; j++)
|
||||
{
|
||||
VSH_INTERMEDIATE_FORMAT* pIntermediate = &pShader->Intermediate[j];
|
||||
if(pIntermediate->Output.Type == IMD_OUTPUT_O &&
|
||||
pIntermediate->Output.Address == OREG_OPOS)
|
||||
{
|
||||
// Found instruction writing to oPos
|
||||
pIntermediate->Output.Type = IMD_OUTPUT_R;
|
||||
pIntermediate->Output.Address = R12Replacement;
|
||||
}
|
||||
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
if(pIntermediate->Parameters[k].Active)
|
||||
{
|
||||
if(pIntermediate->Parameters[k].Parameter.ParameterType == PARAM_R &&
|
||||
pIntermediate->Parameters[k].Parameter.Address == 12)
|
||||
{
|
||||
// Found a r12 used as a parameter; replace
|
||||
pIntermediate->Parameters[k].Parameter.Address = R12Replacement;
|
||||
}
|
||||
else if(pIntermediate->Parameters[k].Parameter.ParameterType == PARAM_C &&
|
||||
pIntermediate->Parameters[k].Parameter.Address == 58 &&
|
||||
!pIntermediate->Parameters[k].IndexesWithA0_X)
|
||||
{
|
||||
// Found c-38, replace it with r12.w
|
||||
pIntermediate->Parameters[k].Parameter.ParameterType = PARAM_R;
|
||||
pIntermediate->Parameters[k].Parameter.Address = R12Replacement;
|
||||
VshSetSwizzle(&pIntermediate->Parameters[k], SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Finally, iterate through the shader, replace all writes to oPos with writes to r12
|
||||
// This fixes shaders that read from r12 expecting to see oPos
|
||||
for (int i = 0; i < pShader->IntermediateCount; i++) {
|
||||
VSH_INTERMEDIATE_FORMAT* pIntermediate = &pShader->Intermediate[i];
|
||||
if (pIntermediate->Output.Type == IMD_OUTPUT_O && pIntermediate->Output.Address == OREG_OPOS) {
|
||||
pIntermediate->Output.Type = IMD_OUTPUT_R;
|
||||
pIntermediate->Output.Address = 12;
|
||||
}
|
||||
// Insert mov oPos, r## in the end
|
||||
VSH_INTERMEDIATE_FORMAT *pOPosWriteBack = VshNewIntermediate(pShader);
|
||||
pOPosWriteBack->InstructionType = IMD_ILU;
|
||||
pOPosWriteBack->ILU = ILU_MOV;
|
||||
pOPosWriteBack->MAC = MAC_NOP;
|
||||
pOPosWriteBack->Output.Type = IMD_OUTPUT_O;
|
||||
pOPosWriteBack->Output.Address = OREG_OPOS;
|
||||
VshSetOutputMask(&pOPosWriteBack->Output, TRUE, TRUE, TRUE, TRUE);
|
||||
pOPosWriteBack->Parameters[0].Active = TRUE;
|
||||
pOPosWriteBack->Parameters[0].Parameter.ParameterType = PARAM_R;
|
||||
pOPosWriteBack->Parameters[0].Parameter.Address = R12Replacement;
|
||||
VshSetSwizzle(&pOPosWriteBack->Parameters[0], SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
|
||||
}
|
||||
|
||||
// We append one additional instruction to mov oPos, r12
|
||||
VSH_INTERMEDIATE_FORMAT MovIntermediate = {0};
|
||||
MovIntermediate.MAC = MAC_MOV;
|
||||
MovIntermediate.Output.Type = IMD_OUTPUT_O;
|
||||
MovIntermediate.Output.Address = OREG_OPOS;
|
||||
MovIntermediate.Output.Mask[0] = true;
|
||||
MovIntermediate.Output.Mask[1] = true;
|
||||
MovIntermediate.Output.Mask[2] = true;
|
||||
MovIntermediate.Output.Mask[3] = true;
|
||||
MovIntermediate.Parameters[0].Active = true;
|
||||
MovIntermediate.Parameters[0].Parameter.ParameterType = PARAM_R;
|
||||
MovIntermediate.Parameters[0].Parameter.Address = 12;
|
||||
MovIntermediate.Parameters[0].Parameter.Swizzle[0] = SWIZZLE_X;
|
||||
MovIntermediate.Parameters[0].Parameter.Swizzle[1] = SWIZZLE_Y;
|
||||
MovIntermediate.Parameters[0].Parameter.Swizzle[2] = SWIZZLE_Z;
|
||||
MovIntermediate.Parameters[0].Parameter.Swizzle[3] = SWIZZLE_W;
|
||||
VshInsertIntermediate(pShader, &MovIntermediate, pShader->IntermediateCount);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1773,93 +1792,6 @@ static DWORD VshGetDeclarationCount(DWORD *pDeclaration)
|
|||
return Pos + 1;
|
||||
}
|
||||
|
||||
#define D3DDECLUSAGE_UNSUPPORTED ((D3DDECLUSAGE)-1)
|
||||
|
||||
XTL::D3DDECLUSAGE Xb2PCRegisterType
|
||||
(
|
||||
DWORD VertexRegister,
|
||||
boolean IsFixedFunction,
|
||||
BYTE& PCUsageIndex
|
||||
)
|
||||
{
|
||||
using namespace XTL;
|
||||
|
||||
D3DDECLUSAGE PCRegisterType;
|
||||
PCUsageIndex = 0;
|
||||
|
||||
if (!IsFixedFunction) {
|
||||
DbgVshPrintf("%d", VertexRegister);
|
||||
PCUsageIndex = DeclAddressUsages[VertexRegister][1];
|
||||
return (D3DDECLUSAGE)DeclAddressUsages[VertexRegister][0];
|
||||
}
|
||||
|
||||
switch (VertexRegister)
|
||||
{
|
||||
case X_D3DVSDE_VERTEX: // -1
|
||||
DbgVshPrintf("D3DVSDE_VERTEX /* xbox ext. */");
|
||||
PCRegisterType = D3DDECLUSAGE_UNSUPPORTED;
|
||||
break;
|
||||
case X_D3DVSDE_POSITION: // 0
|
||||
DbgVshPrintf("D3DVSDE_POSITION");
|
||||
PCRegisterType = D3DDECLUSAGE_POSITION;
|
||||
break;
|
||||
case X_D3DVSDE_BLENDWEIGHT: // 1
|
||||
DbgVshPrintf("D3DVSDE_BLENDWEIGHT");
|
||||
PCRegisterType = D3DDECLUSAGE_BLENDWEIGHT;
|
||||
break;
|
||||
case X_D3DVSDE_NORMAL: // 2
|
||||
DbgVshPrintf("D3DVSDE_NORMAL");
|
||||
PCRegisterType = D3DDECLUSAGE_NORMAL;
|
||||
break;
|
||||
case X_D3DVSDE_DIFFUSE: // 3
|
||||
DbgVshPrintf("D3DVSDE_DIFFUSE");
|
||||
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 0;
|
||||
break;
|
||||
case X_D3DVSDE_SPECULAR: // 4
|
||||
DbgVshPrintf("D3DVSDE_SPECULAR");
|
||||
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 1;
|
||||
break;
|
||||
case X_D3DVSDE_FOG: // 5
|
||||
DbgVshPrintf("D3DVSDE_FOG");
|
||||
PCRegisterType = D3DDECLUSAGE_FOG;
|
||||
break;
|
||||
case X_D3DVSDE_POINTSIZE: // 6
|
||||
DbgVshPrintf("D3DVDSE_POINTSIZE");
|
||||
PCRegisterType = D3DDECLUSAGE_PSIZE;
|
||||
break;
|
||||
case X_D3DVSDE_BACKDIFFUSE: // 7
|
||||
DbgVshPrintf("D3DVSDE_BACKDIFFUSE /* xbox ext. */");
|
||||
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 2;
|
||||
break;
|
||||
case X_D3DVSDE_BACKSPECULAR: // 8
|
||||
DbgVshPrintf("D3DVSDE_BACKSPECULAR /* xbox ext. */");
|
||||
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 3;
|
||||
break;
|
||||
case X_D3DVSDE_TEXCOORD0: // 9
|
||||
DbgVshPrintf("D3DVSDE_TEXCOORD0");
|
||||
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 0;
|
||||
break;
|
||||
case X_D3DVSDE_TEXCOORD1: // 10
|
||||
DbgVshPrintf("D3DVSDE_TEXCOORD1");
|
||||
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 1;
|
||||
break;
|
||||
case X_D3DVSDE_TEXCOORD2: // 11
|
||||
DbgVshPrintf("D3DVSDE_TEXCOORD2");
|
||||
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 2;
|
||||
break;
|
||||
case X_D3DVSDE_TEXCOORD3: // 12
|
||||
DbgVshPrintf("D3DVSDE_TEXCOORD3");
|
||||
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 3;
|
||||
break;
|
||||
default:
|
||||
DbgVshPrintf("%d /* unknown register */", VertexRegister);
|
||||
PCRegisterType = D3DDECLUSAGE_UNSUPPORTED;
|
||||
break;
|
||||
}
|
||||
|
||||
return PCRegisterType;
|
||||
}
|
||||
|
||||
static inline DWORD VshGetTokenType(DWORD Token)
|
||||
{
|
||||
return (Token & X_D3DVSD_TOKENTYPEMASK) >> X_D3DVSD_TOKENTYPESHIFT;
|
||||
|
@ -1921,19 +1853,18 @@ static void VshConvertToken_TESSELATOR(
|
|||
using namespace XTL;
|
||||
BYTE Index;
|
||||
|
||||
// TODO: Investigate why Xb2PCRegisterType is only used for fixed function vertex shaders
|
||||
if(*pToken & X_D3DVSD_MASK_TESSUV)
|
||||
{
|
||||
XTL::DWORD VertexRegister = VshGetVertexRegister(*pToken);
|
||||
XTL::DWORD NewVertexRegister = VertexRegister;
|
||||
|
||||
DbgVshPrintf("\tD3DVSD_TESSUV(");
|
||||
NewVertexRegister = Xb2PCRegisterType(VertexRegister, IsFixedFunction, Index);
|
||||
NewVertexRegister = Xb2PCRegisterType(VertexRegister, Index);
|
||||
DbgVshPrintf("),\n");
|
||||
|
||||
// TODO : Expand on the setting of this TESSUV register element :
|
||||
pRecompiled->Usage = D3DDECLUSAGE(NewVertexRegister);
|
||||
pRecompiled->UsageIndex = Xb2PCRegisterType(NewVertexRegister, IsFixedFunction, Index); // TODO : Get Index from Xb2PCRegisterType
|
||||
pRecompiled->UsageIndex =Index;
|
||||
}
|
||||
// D3DVSD_TESSNORMAL
|
||||
else
|
||||
|
@ -1945,18 +1876,18 @@ static void VshConvertToken_TESSELATOR(
|
|||
XTL::DWORD NewVertexRegisterOut = VertexRegisterOut;
|
||||
|
||||
DbgVshPrintf("\tD3DVSD_TESSNORMAL(");
|
||||
NewVertexRegisterIn = Xb2PCRegisterType(VertexRegisterIn, IsFixedFunction, Index);
|
||||
NewVertexRegisterIn = Xb2PCRegisterType(VertexRegisterIn, Index);
|
||||
DbgVshPrintf(", ");
|
||||
// TODO : Expand on the setting of this TESSNORMAL input register element :
|
||||
pRecompiled->Usage = D3DDECLUSAGE(NewVertexRegisterIn);
|
||||
pRecompiled->UsageIndex = 0; // TODO : Get Index from Xb2PCRegisterType
|
||||
NewVertexRegisterOut = Xb2PCRegisterType(VertexRegisterOut, IsFixedFunction, Index);
|
||||
NewVertexRegisterOut = Xb2PCRegisterType(VertexRegisterOut, Index);
|
||||
DbgVshPrintf("),\n");
|
||||
|
||||
// TODO : Expand on the setting of this TESSNORMAL output register element :
|
||||
pRecompiled++;
|
||||
pRecompiled->Usage = D3DDECLUSAGE(NewVertexRegisterOut);
|
||||
pRecompiled->UsageIndex = 0; // TODO : Get Index from Xb2PCRegisterType
|
||||
pRecompiled->UsageIndex = Index; // TODO : Get Index from Xb2PCRegisterType
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2045,18 +1976,30 @@ static void VshConvertToken_STREAMDATA_REG(
|
|||
{
|
||||
using namespace XTL;
|
||||
|
||||
extern XTL::D3DCAPS g_D3DCaps;
|
||||
|
||||
XTL::DWORD VertexRegister = VshGetVertexRegister(*pToken);
|
||||
XTL::BYTE HostVertexRegister;
|
||||
XTL::BOOL NeedPatching = FALSE;
|
||||
XTL::BYTE Index;
|
||||
|
||||
BYTE HostVertexRegisterType;
|
||||
// If this is a fixed-function shader, use Xb2PCRegisterType
|
||||
DbgVshPrintf("\t\tD3DVSD_REG(");
|
||||
BYTE XboxVertexRegister = Xb2PCRegisterType(VertexRegister, IsFixedFunction, Index);
|
||||
HostVertexRegister = XboxVertexRegister;
|
||||
if (IsFixedFunction) {
|
||||
HostVertexRegisterType = Xb2PCRegisterType(VertexRegister, Index);
|
||||
} else {
|
||||
// D3DDECLUSAGE_TEXCOORD can be useds for any user-defined data
|
||||
// We need this because there is no reliable way to detect the real usage
|
||||
// Xbox has no concept of 'usage types', it only requires a list of attribute register numbers.
|
||||
// So we treat them all as 'user-defined' with an Index of the Vertex Register Index
|
||||
// this prevents information loss in shaders due to non-matching dcl types!
|
||||
HostVertexRegisterType = D3DDECLUSAGE_TEXCOORD;
|
||||
Index = VertexRegister;
|
||||
DbgVshPrintf("%d", Index);
|
||||
}
|
||||
DbgVshPrintf(", ");
|
||||
|
||||
// Add this register to the list of declared registers
|
||||
RegVIsPresentInDeclaration[VertexRegister] = true;
|
||||
|
||||
XTL::DWORD XboxVertexElementDataType = (*pToken & X_D3DVSD_DATATYPEMASK) >> X_D3DVSD_DATATYPESHIFT;
|
||||
XTL::BYTE HostVertexElementDataType = 0;
|
||||
XTL::WORD HostVertexElementByteSize = 0;
|
||||
|
@ -2072,32 +2015,21 @@ static void VshConvertToken_STREAMDATA_REG(
|
|||
DbgVshPrintf("D3DVSDT_FLOAT2");
|
||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT2;
|
||||
HostVertexElementByteSize = 2 * sizeof(FLOAT);
|
||||
//HostVertexRegister = D3DDECLUSAGE_TEXCOORD;
|
||||
break;
|
||||
case X_D3DVSDT_FLOAT3: // 0x32:
|
||||
DbgVshPrintf("D3DVSDT_FLOAT3");
|
||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT3;
|
||||
HostVertexElementByteSize = 3 * sizeof(FLOAT);
|
||||
|
||||
/*
|
||||
if (pPatchData->pCurrentVertexShaderStreamInfo->DeclPosition) {
|
||||
pPatchData->pCurrentVertexShaderStreamInfo->DeclPosition = true;
|
||||
HostVertexRegister = D3DDECLUSAGE_POSITION;
|
||||
} else {
|
||||
HostVertexRegister = D3DDECLUSAGE_NORMAL;
|
||||
} */
|
||||
break;
|
||||
case X_D3DVSDT_FLOAT4: // 0x42:
|
||||
DbgVshPrintf("D3DVSDT_FLOAT4");
|
||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
|
||||
HostVertexElementByteSize = 4 * sizeof(FLOAT);
|
||||
//HostVertexRegister = D3DDECLUSAGE_COLOR;
|
||||
break;
|
||||
case X_D3DVSDT_D3DCOLOR: // 0x40:
|
||||
DbgVshPrintf("D3DVSDT_D3DCOLOR");
|
||||
HostVertexElementDataType = D3DDECLTYPE_D3DCOLOR;
|
||||
HostVertexElementByteSize = 1 * sizeof(D3DCOLOR);
|
||||
//HostVertexRegister = D3DDECLUSAGE_COLOR;
|
||||
break;
|
||||
case X_D3DVSDT_SHORT2: // 0x25:
|
||||
DbgVshPrintf("D3DVSDT_SHORT2");
|
||||
|
@ -2272,14 +2204,9 @@ static void VshConvertToken_STREAMDATA_REG(
|
|||
pRecompiled->Offset = pPatchData->pCurrentVertexShaderStreamInfo->HostVertexStride;
|
||||
pRecompiled->Type = HostVertexElementDataType;
|
||||
pRecompiled->Method = D3DDECLMETHOD_DEFAULT;
|
||||
pRecompiled->Usage = HostVertexRegister;
|
||||
pRecompiled->Usage = HostVertexRegisterType;
|
||||
pRecompiled->UsageIndex = Index;
|
||||
|
||||
// If the xbox and host register number and usage differ, store an override!
|
||||
if (XboxVertexRegister != HostVertexRegister) {
|
||||
RegVDeclUsage[XboxVertexRegister] = HostVertexRegister;
|
||||
}
|
||||
|
||||
pRecompiled++;
|
||||
|
||||
pPatchData->pCurrentVertexShaderStreamInfo->HostVertexStride += HostVertexElementByteSize;
|
||||
|
@ -2363,7 +2290,7 @@ DWORD XTL::EmuRecompileVshDeclaration
|
|||
CxbxVertexShaderInfo *pVertexShaderInfo
|
||||
)
|
||||
{
|
||||
RegVDeclUsage.fill(-1);
|
||||
RegVIsPresentInDeclaration.fill(false);
|
||||
|
||||
// First of all some info:
|
||||
// We have to figure out which flags are set and then
|
||||
|
@ -2413,8 +2340,6 @@ DWORD XTL::EmuRecompileVshDeclaration
|
|||
return D3D_OK;
|
||||
}
|
||||
|
||||
extern XTL::D3DCAPS g_D3DCaps;
|
||||
|
||||
// recompile xbox vertex shader function
|
||||
extern HRESULT XTL::EmuRecompileVshFunction
|
||||
(
|
||||
|
@ -2444,9 +2369,9 @@ extern HRESULT XTL::EmuRecompileVshFunction
|
|||
DWORD* pDeclEnd = (DWORD*)((BYTE*)pDeclToken + DeclarationSize);
|
||||
do {
|
||||
DWORD regNum = *pDeclToken & X_D3DVSD_VERTEXREGMASK;
|
||||
if (regNum >= temporaryCount /*12*/) {
|
||||
if (regNum >= temporaryCount /*12 for D3D8, D3D9 value depends on host GPU */) {
|
||||
// Lego Star Wars hits this
|
||||
LOG_TEST_CASE("RegNum > 12");
|
||||
LOG_TEST_CASE("RegNum > NumTemps");
|
||||
pDeclToken++;
|
||||
continue;
|
||||
}
|
||||
|
@ -2489,7 +2414,7 @@ extern HRESULT XTL::EmuRecompileVshFunction
|
|||
|
||||
if(SUCCEEDED(hRet))
|
||||
{
|
||||
RegVUsage.fill(false);
|
||||
RegVIsUsedByShader.fill(false);
|
||||
|
||||
for (pToken = (DWORD*)((uint8_t*)pFunction + sizeof(VSH_SHADER_HEADER)); !EOI; pToken += VSH_INSTRUCTION_SIZE)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue