Merge pull request #1755 from PatrickvL/vsh_dump_separately
Dump vertex declaration separately from conversion
This commit is contained in:
commit
67b3924946
|
@ -2174,7 +2174,7 @@ void PSH_XBOX_SHADER::SetPSVersion(const uint32_t PSVersion)
|
||||||
else if (m_PSVersion >= D3DPS_VERSION(2, 0)) {
|
else if (m_PSVersion >= D3DPS_VERSION(2, 0)) {
|
||||||
// Source https://msdn.microsoft.com/en-us/library/windows/desktop/bb172918(v=vs.85).aspx
|
// Source https://msdn.microsoft.com/en-us/library/windows/desktop/bb172918(v=vs.85).aspx
|
||||||
MaxInputColorRegisters = 2;
|
MaxInputColorRegisters = 2;
|
||||||
MaxTemporaryRegisters = 12; // 12 min/32 max: The number of r# registers is determined by D3DPSHADERCAPS2_0.NumTemps (which ranges from 12 to 32).
|
MaxTemporaryRegisters = 12; // 12 min/32 max: The number of r# registers is determined by D3DCAPS9.D3DPSHADERCAPS2_0.NumTemps (which ranges from 12 to 32).
|
||||||
MaxConstantFloatRegisters = 32;
|
MaxConstantFloatRegisters = 32;
|
||||||
MaxSamplerRegisters = 16;
|
MaxSamplerRegisters = 16;
|
||||||
MaxTextureCoordinateRegisters = 8;
|
MaxTextureCoordinateRegisters = 8;
|
||||||
|
|
|
@ -761,6 +761,49 @@ static void VshWriteParameter(VSH_IMD_PARAMETER *pParameter,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* XboxVertexRegisterAsString(DWORD VertexRegister)
|
||||||
|
{
|
||||||
|
switch (VertexRegister)
|
||||||
|
{
|
||||||
|
case XTL::X_D3DVSDE_VERTEX: // -1
|
||||||
|
return "D3DVSDE_VERTEX /* xbox ext. */";
|
||||||
|
case XTL::X_D3DVSDE_POSITION: // 0
|
||||||
|
return "D3DVSDE_POSITION";
|
||||||
|
case XTL::X_D3DVSDE_BLENDWEIGHT: // 1
|
||||||
|
return "D3DVSDE_BLENDWEIGHT";
|
||||||
|
case XTL::X_D3DVSDE_NORMAL: // 2
|
||||||
|
return "D3DVSDE_NORMAL";
|
||||||
|
case XTL::X_D3DVSDE_DIFFUSE: // 3
|
||||||
|
return "D3DVSDE_DIFFUSE";
|
||||||
|
case XTL::X_D3DVSDE_SPECULAR: // 4
|
||||||
|
return "D3DVSDE_SPECULAR";
|
||||||
|
case XTL::X_D3DVSDE_FOG: // 5
|
||||||
|
return "D3DVSDE_FOG";
|
||||||
|
case XTL::X_D3DVSDE_POINTSIZE: // 6
|
||||||
|
return "D3DVDSE_POINTSIZE";
|
||||||
|
case XTL::X_D3DVSDE_BACKDIFFUSE: // 7
|
||||||
|
return "D3DVSDE_BACKDIFFUSE /* xbox ext. */";
|
||||||
|
case XTL::X_D3DVSDE_BACKSPECULAR: // 8
|
||||||
|
return "D3DVSDE_BACKSPECULAR /* xbox ext. */";
|
||||||
|
case XTL::X_D3DVSDE_TEXCOORD0: // 9
|
||||||
|
return "D3DVSDE_TEXCOORD0";
|
||||||
|
case XTL::X_D3DVSDE_TEXCOORD1: // 10
|
||||||
|
return "D3DVSDE_TEXCOORD1";
|
||||||
|
case XTL::X_D3DVSDE_TEXCOORD2: // 11
|
||||||
|
return "D3DVSDE_TEXCOORD2";
|
||||||
|
case XTL::X_D3DVSDE_TEXCOORD3: // 12
|
||||||
|
return "D3DVSDE_TEXCOORD3";
|
||||||
|
case 13:
|
||||||
|
return "13 /* unknown register */";
|
||||||
|
case 14:
|
||||||
|
return "14 /* unknown register */";
|
||||||
|
case 15:
|
||||||
|
return "15 /* unknown register */";
|
||||||
|
default:
|
||||||
|
return "16 /* or higher, unknown register */";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define D3DDECLUSAGE_UNSUPPORTED ((D3DDECLUSAGE)-1)
|
#define D3DDECLUSAGE_UNSUPPORTED ((D3DDECLUSAGE)-1)
|
||||||
|
|
||||||
D3DDECLUSAGE Xb2PCRegisterType
|
D3DDECLUSAGE Xb2PCRegisterType
|
||||||
|
@ -775,63 +818,48 @@ D3DDECLUSAGE Xb2PCRegisterType
|
||||||
switch (VertexRegister)
|
switch (VertexRegister)
|
||||||
{
|
{
|
||||||
case XTL::X_D3DVSDE_VERTEX: // -1
|
case XTL::X_D3DVSDE_VERTEX: // -1
|
||||||
DbgVshPrintf("D3DVSDE_VERTEX /* xbox ext. */");
|
|
||||||
PCRegisterType = D3DDECLUSAGE_UNSUPPORTED;
|
PCRegisterType = D3DDECLUSAGE_UNSUPPORTED;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDE_POSITION: // 0
|
case XTL::X_D3DVSDE_POSITION: // 0
|
||||||
DbgVshPrintf("D3DVSDE_POSITION");
|
|
||||||
PCRegisterType = D3DDECLUSAGE_POSITION;
|
PCRegisterType = D3DDECLUSAGE_POSITION;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDE_BLENDWEIGHT: // 1
|
case XTL::X_D3DVSDE_BLENDWEIGHT: // 1
|
||||||
DbgVshPrintf("D3DVSDE_BLENDWEIGHT");
|
|
||||||
PCRegisterType = D3DDECLUSAGE_BLENDWEIGHT;
|
PCRegisterType = D3DDECLUSAGE_BLENDWEIGHT;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDE_NORMAL: // 2
|
case XTL::X_D3DVSDE_NORMAL: // 2
|
||||||
DbgVshPrintf("D3DVSDE_NORMAL");
|
|
||||||
PCRegisterType = D3DDECLUSAGE_NORMAL;
|
PCRegisterType = D3DDECLUSAGE_NORMAL;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDE_DIFFUSE: // 3
|
case XTL::X_D3DVSDE_DIFFUSE: // 3
|
||||||
DbgVshPrintf("D3DVSDE_DIFFUSE");
|
|
||||||
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 0;
|
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 0;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDE_SPECULAR: // 4
|
case XTL::X_D3DVSDE_SPECULAR: // 4
|
||||||
DbgVshPrintf("D3DVSDE_SPECULAR");
|
|
||||||
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 1;
|
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 1;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDE_FOG: // 5
|
case XTL::X_D3DVSDE_FOG: // 5
|
||||||
DbgVshPrintf("D3DVSDE_FOG");
|
|
||||||
PCRegisterType = D3DDECLUSAGE_FOG;
|
PCRegisterType = D3DDECLUSAGE_FOG;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDE_POINTSIZE: // 6
|
case XTL::X_D3DVSDE_POINTSIZE: // 6
|
||||||
DbgVshPrintf("D3DVDSE_POINTSIZE");
|
|
||||||
PCRegisterType = D3DDECLUSAGE_PSIZE;
|
PCRegisterType = D3DDECLUSAGE_PSIZE;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDE_BACKDIFFUSE: // 7
|
case XTL::X_D3DVSDE_BACKDIFFUSE: // 7
|
||||||
DbgVshPrintf("D3DVSDE_BACKDIFFUSE /* xbox ext. */");
|
|
||||||
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 2;
|
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 2;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDE_BACKSPECULAR: // 8
|
case XTL::X_D3DVSDE_BACKSPECULAR: // 8
|
||||||
DbgVshPrintf("D3DVSDE_BACKSPECULAR /* xbox ext. */");
|
|
||||||
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 3;
|
PCRegisterType = D3DDECLUSAGE_COLOR; PCUsageIndex = 3;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDE_TEXCOORD0: // 9
|
case XTL::X_D3DVSDE_TEXCOORD0: // 9
|
||||||
DbgVshPrintf("D3DVSDE_TEXCOORD0");
|
|
||||||
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 0;
|
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 0;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDE_TEXCOORD1: // 10
|
case XTL::X_D3DVSDE_TEXCOORD1: // 10
|
||||||
DbgVshPrintf("D3DVSDE_TEXCOORD1");
|
|
||||||
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 1;
|
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 1;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDE_TEXCOORD2: // 11
|
case XTL::X_D3DVSDE_TEXCOORD2: // 11
|
||||||
DbgVshPrintf("D3DVSDE_TEXCOORD2");
|
|
||||||
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 2;
|
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 2;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDE_TEXCOORD3: // 12
|
case XTL::X_D3DVSDE_TEXCOORD3: // 12
|
||||||
DbgVshPrintf("D3DVSDE_TEXCOORD3");
|
|
||||||
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 3;
|
PCRegisterType = D3DDECLUSAGE_TEXCOORD; PCUsageIndex = 3;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DbgVshPrintf("%d /* unknown register */", VertexRegister);
|
|
||||||
PCRegisterType = D3DDECLUSAGE_UNSUPPORTED;
|
PCRegisterType = D3DDECLUSAGE_UNSUPPORTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1474,7 +1502,7 @@ static boolean VshConvertShader(VSH_XBOX_SHADER *pShader,
|
||||||
boolean bNoReservedConstants
|
boolean bNoReservedConstants
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const DWORD temporaryCount = g_D3DCaps.VS20Caps.NumTemps;
|
static const DWORD hostTemporaryRegisterCount = g_D3DCaps.VS20Caps.NumTemps;
|
||||||
|
|
||||||
boolean RUsage[VSH_MAX_TEMPORARY_REGISTERS] = { FALSE };
|
boolean RUsage[VSH_MAX_TEMPORARY_REGISTERS] = { FALSE };
|
||||||
// Set the last 13 register to used (they are used for SetVertexData4f Constants)
|
// Set the last 13 register to used (they are used for SetVertexData4f Constants)
|
||||||
|
@ -1618,8 +1646,10 @@ static boolean VshConvertShader(VSH_XBOX_SHADER *pShader,
|
||||||
|
|
||||||
// attempt to find unused register...
|
// attempt to find unused register...
|
||||||
int outRegister = -1;
|
int outRegister = -1;
|
||||||
for (int j = temporaryCount - 1; j >= 0; --j)
|
for (int j = hostTemporaryRegisterCount - 1; j >= 0; --j)
|
||||||
{
|
{
|
||||||
|
// Skip r12, which host uses as a replacement for all Xbox oPos reads & writes (except final write).
|
||||||
|
// (Xbox can read from the write-only oPos register through the special thirteenth r12 register as well.)
|
||||||
if (j == 12) continue;
|
if (j == 12) continue;
|
||||||
|
|
||||||
if(!RUsage[j])
|
if(!RUsage[j])
|
||||||
|
@ -1712,6 +1742,9 @@ static boolean VshConvertShader(VSH_XBOX_SHADER *pShader,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO : *IF* r12 is not read after the final write to oPos,
|
||||||
|
// it'd be more efficient to not-replace this oPos write by r12,
|
||||||
|
// so that we don't have to do the following :
|
||||||
// We append one additional instruction to mov oPos, r12
|
// We append one additional instruction to mov oPos, r12
|
||||||
VSH_INTERMEDIATE_FORMAT MovIntermediate = {0};
|
VSH_INTERMEDIATE_FORMAT MovIntermediate = {0};
|
||||||
MovIntermediate.MAC = MAC_MOV;
|
MovIntermediate.MAC = MAC_MOV;
|
||||||
|
@ -1743,7 +1776,7 @@ protected:
|
||||||
// Internal variables
|
// Internal variables
|
||||||
CxbxVertexShaderInfo* pVertexShaderInfoToSet;
|
CxbxVertexShaderInfo* pVertexShaderInfoToSet;
|
||||||
CxbxVertexShaderStreamInfo* pCurrentVertexShaderStreamInfo = nullptr;
|
CxbxVertexShaderStreamInfo* pCurrentVertexShaderStreamInfo = nullptr;
|
||||||
DWORD temporaryCount;
|
DWORD hostTemporaryRegisterCount;
|
||||||
bool IsFixedFunction;
|
bool IsFixedFunction;
|
||||||
D3DVERTEXELEMENT* pRecompiled;
|
D3DVERTEXELEMENT* pRecompiled;
|
||||||
|
|
||||||
|
@ -1779,7 +1812,7 @@ private:
|
||||||
inline DWORD VshGetVertexRegister(DWORD XboxToken)
|
inline DWORD VshGetVertexRegister(DWORD XboxToken)
|
||||||
{
|
{
|
||||||
DWORD regNum = (XboxToken & X_D3DVSD_VERTEXREGMASK) >> X_D3DVSD_VERTEXREGSHIFT;
|
DWORD regNum = (XboxToken & X_D3DVSD_VERTEXREGMASK) >> X_D3DVSD_VERTEXREGSHIFT;
|
||||||
if (regNum >= temporaryCount /*12 for D3D8, D3D9 value depends on host GPU */) {
|
if (regNum >= hostTemporaryRegisterCount /*12 for D3D8, D3D9 value depends on host GPU */) {
|
||||||
// Lego Star Wars hits this
|
// Lego Star Wars hits this
|
||||||
LOG_TEST_CASE("RegNum > NumTemps");
|
LOG_TEST_CASE("RegNum > NumTemps");
|
||||||
}
|
}
|
||||||
|
@ -1789,34 +1822,212 @@ private:
|
||||||
inline DWORD VshGetVertexRegisterIn(DWORD XboxToken)
|
inline DWORD VshGetVertexRegisterIn(DWORD XboxToken)
|
||||||
{
|
{
|
||||||
DWORD regNum = (XboxToken & X_D3DVSD_VERTEXREGINMASK) >> X_D3DVSD_VERTEXREGINSHIFT;
|
DWORD regNum = (XboxToken & X_D3DVSD_VERTEXREGINMASK) >> X_D3DVSD_VERTEXREGINSHIFT;
|
||||||
if (regNum >= temporaryCount /*12 for D3D8, D3D9 value depends on host GPU */) {
|
if (regNum >= hostTemporaryRegisterCount /*12 for D3D8, D3D9 value depends on host GPU */) {
|
||||||
// Lego Star Wars hits this
|
// Lego Star Wars hits this
|
||||||
LOG_TEST_CASE("RegNum > NumTemps");
|
LOG_TEST_CASE("RegNum > NumTemps");
|
||||||
}
|
}
|
||||||
return regNum;
|
return regNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VshDumpXboxDeclaration(DWORD* pXboxDeclaration)
|
||||||
|
{
|
||||||
|
DbgVshPrintf("DWORD dwVSHDecl[] =\n{\n");
|
||||||
|
unsigned iNumberOfVertexStreams = 0;
|
||||||
|
bool bStreamNeedsPatching = false;
|
||||||
|
auto pXboxToken = pXboxDeclaration;
|
||||||
|
while (*pXboxToken != X_D3DVSD_END()) // X_D3DVSD_TOKEN_END
|
||||||
|
{
|
||||||
|
DWORD Step = 1;
|
||||||
|
|
||||||
|
switch (VshGetTokenType(*pXboxToken)) {
|
||||||
|
case XTL::X_D3DVSD_TOKEN_NOP: {
|
||||||
|
DbgVshPrintf("\tD3DVSD_NOP(),\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XTL::X_D3DVSD_TOKEN_STREAM: {
|
||||||
|
if (*pXboxToken & X_D3DVSD_STREAMTESSMASK) {
|
||||||
|
DbgVshPrintf("\tD3DVSD_STREAM_TESS(),\n");
|
||||||
|
} else {
|
||||||
|
if (iNumberOfVertexStreams > 0) {
|
||||||
|
DbgVshPrintf("\t// NeedPatching: %d\n", bStreamNeedsPatching);
|
||||||
|
}
|
||||||
|
DWORD StreamNumber = VshGetVertexStream(*pXboxToken);
|
||||||
|
DbgVshPrintf("\tD3DVSD_STREAM(%u),\n", StreamNumber);
|
||||||
|
iNumberOfVertexStreams++;
|
||||||
|
bStreamNeedsPatching = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XTL::X_D3DVSD_TOKEN_STREAMDATA: {
|
||||||
|
if (*pXboxToken & X_D3DVSD_MASK_SKIP) {
|
||||||
|
WORD SkipCount = (*pXboxToken & X_D3DVSD_SKIPCOUNTMASK) >> X_D3DVSD_SKIPCOUNTSHIFT;
|
||||||
|
if (*pXboxToken & X_D3DVSD_MASK_SKIPBYTES) {
|
||||||
|
DbgVshPrintf("\tD3DVSD_SKIPBYTES(%d), /* xbox ext. */\n", SkipCount);
|
||||||
|
} else {
|
||||||
|
DbgVshPrintf("\tD3DVSD_SKIP(%d),\n", SkipCount);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DWORD VertexRegister = VshGetVertexRegister(*pXboxToken);
|
||||||
|
if (IsFixedFunction) {
|
||||||
|
DbgVshPrintf("\t\tD3DVSD_REG(%s, ", XboxVertexRegisterAsString(VertexRegister));
|
||||||
|
} else {
|
||||||
|
DbgVshPrintf("\t\tD3DVSD_REG(%d, ", (BYTE)VertexRegister);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD XboxVertexElementDataType = (*pXboxToken & X_D3DVSD_DATATYPEMASK) >> X_D3DVSD_DATATYPESHIFT;
|
||||||
|
switch (XboxVertexElementDataType) {
|
||||||
|
case XTL::X_D3DVSDT_FLOAT1: // 0x12:
|
||||||
|
DbgVshPrintf("D3DVSDT_FLOAT1");
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_FLOAT2: // 0x22:
|
||||||
|
DbgVshPrintf("D3DVSDT_FLOAT2");
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_FLOAT3: // 0x32:
|
||||||
|
DbgVshPrintf("D3DVSDT_FLOAT3");
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_FLOAT4: // 0x42:
|
||||||
|
DbgVshPrintf("D3DVSDT_FLOAT4");
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_D3DCOLOR: // 0x40:
|
||||||
|
DbgVshPrintf("D3DVSDT_D3DCOLOR");
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_SHORT2: // 0x25:
|
||||||
|
DbgVshPrintf("D3DVSDT_SHORT2");
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_SHORT4: // 0x45:
|
||||||
|
DbgVshPrintf("D3DVSDT_SHORT4");
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_NORMSHORT1: // 0x11:
|
||||||
|
DbgVshPrintf("D3DVSDT_NORMSHORT1 /* xbox ext. */");
|
||||||
|
bStreamNeedsPatching = true;
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_NORMSHORT2: // 0x21:
|
||||||
|
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) {
|
||||||
|
DbgVshPrintf("D3DVSDT_NORMSHORT2");
|
||||||
|
} else {
|
||||||
|
DbgVshPrintf("D3DVSDT_NORMSHORT2 /* xbox ext. */");
|
||||||
|
bStreamNeedsPatching = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_NORMSHORT3: // 0x31:
|
||||||
|
DbgVshPrintf("D3DVSDT_NORMSHORT3 /* xbox ext. */");
|
||||||
|
bStreamNeedsPatching = true;
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_NORMSHORT4: // 0x41:
|
||||||
|
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) {
|
||||||
|
DbgVshPrintf("D3DVSDT_NORMSHORT4");
|
||||||
|
// No need for patching in D3D9
|
||||||
|
} else {
|
||||||
|
DbgVshPrintf("D3DVSDT_NORMSHORT4 /* xbox ext. */");
|
||||||
|
bStreamNeedsPatching = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_NORMPACKED3: // 0x16:
|
||||||
|
DbgVshPrintf("D3DVSDT_NORMPACKED3 /* xbox ext. */");
|
||||||
|
bStreamNeedsPatching = true;
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_SHORT1: // 0x15:
|
||||||
|
DbgVshPrintf("D3DVSDT_SHORT1 /* xbox ext. */");
|
||||||
|
bStreamNeedsPatching = true;
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_SHORT3: // 0x35:
|
||||||
|
DbgVshPrintf("D3DVSDT_SHORT3 /* xbox ext. */");
|
||||||
|
bStreamNeedsPatching = true;
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_PBYTE1: // 0x14:
|
||||||
|
DbgVshPrintf("D3DVSDT_PBYTE1 /* xbox ext. */");
|
||||||
|
bStreamNeedsPatching = true;
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_PBYTE2: // 0x24:
|
||||||
|
DbgVshPrintf("D3DVSDT_PBYTE2 /* xbox ext. */");
|
||||||
|
bStreamNeedsPatching = true;
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_PBYTE3: // 0x34:
|
||||||
|
DbgVshPrintf("D3DVSDT_PBYTE3 /* xbox ext. */");
|
||||||
|
bStreamNeedsPatching = true;
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_PBYTE4: // 0x44:
|
||||||
|
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
|
||||||
|
DbgVshPrintf("D3DVSDT_PBYTE4");
|
||||||
|
} else {
|
||||||
|
DbgVshPrintf("D3DVSDT_PBYTE4 /* xbox ext. */");
|
||||||
|
bStreamNeedsPatching = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_FLOAT2H: // 0x72:
|
||||||
|
DbgVshPrintf("D3DVSDT_FLOAT2H /* xbox ext. */");
|
||||||
|
bStreamNeedsPatching = true;
|
||||||
|
break;
|
||||||
|
case XTL::X_D3DVSDT_NONE: // 0x02:
|
||||||
|
DbgVshPrintf("D3DVSDT_NONE /* xbox ext. */");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DbgVshPrintf("Unknown data type for D3DVSD_REG: 0x%02X\n", XboxVertexElementDataType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbgVshPrintf("),\n");
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XTL::X_D3DVSD_TOKEN_TESSELLATOR: {
|
||||||
|
DWORD VertexRegisterOut = VshGetVertexRegister(*pXboxToken);
|
||||||
|
if (*pXboxToken & X_D3DVSD_MASK_TESSUV) {
|
||||||
|
DbgVshPrintf("\tD3DVSD_TESSUV(%s),\n", XboxVertexRegisterAsString(VertexRegisterOut));
|
||||||
|
} else { // D3DVSD_TESSNORMAL
|
||||||
|
DWORD VertexRegisterIn = VshGetVertexRegisterIn(*pXboxToken);
|
||||||
|
DbgVshPrintf("\tD3DVSD_TESSNORMAL(%s, %s),\n",
|
||||||
|
XboxVertexRegisterAsString(VertexRegisterIn),
|
||||||
|
XboxVertexRegisterAsString(VertexRegisterOut));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XTL::X_D3DVSD_TOKEN_CONSTMEM: {
|
||||||
|
DWORD ConstantAddress = (*pXboxToken & X_D3DVSD_CONSTADDRESSMASK) >> X_D3DVSD_CONSTADDRESSSHIFT;
|
||||||
|
DWORD Count = (*pXboxToken & X_D3DVSD_CONSTCOUNTMASK) >> X_D3DVSD_CONSTCOUNTSHIFT;
|
||||||
|
DbgVshPrintf("\tD3DVSD_CONST(%d, %d),\n", ConstantAddress, Count);
|
||||||
|
LOG_TEST_CASE("X_D3DVSD_TOKEN_CONSTMEM");
|
||||||
|
Step = Count * 4 + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case XTL::X_D3DVSD_TOKEN_EXT: {
|
||||||
|
DWORD ExtInfo = (*pXboxToken & X_D3DVSD_EXTINFOMASK) >> X_D3DVSD_EXTINFOSHIFT;
|
||||||
|
DWORD Count = (*pXboxToken & X_D3DVSD_EXTCOUNTMASK) >> X_D3DVSD_EXTCOUNTSHIFT;
|
||||||
|
DbgVshPrintf("\tD3DVSD_EXT(%d, %d),\n", ExtInfo, Count);
|
||||||
|
LOG_TEST_CASE("X_D3DVSD_TOKEN_EXT");
|
||||||
|
Step = Count * 4 + 1; // TODO : Is this correct?
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
DbgVshPrintf("Unknown token type: %d\n", VshGetTokenType(*pXboxToken));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pXboxToken += Step;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iNumberOfVertexStreams > 0) {
|
||||||
|
DbgVshPrintf("\t// NeedPatching: %d\n", bStreamNeedsPatching);
|
||||||
|
}
|
||||||
|
|
||||||
|
DbgVshPrintf("\tD3DVSD_END()\n};\n");
|
||||||
|
|
||||||
|
DbgVshPrintf("// NbrStreams: %d\n", iNumberOfVertexStreams);
|
||||||
|
}
|
||||||
|
|
||||||
void VshConvertToken_NOP(DWORD *pXboxToken)
|
void VshConvertToken_NOP(DWORD *pXboxToken)
|
||||||
{
|
{
|
||||||
// D3DVSD_NOP
|
|
||||||
if(*pXboxToken != X_D3DVSD_NOP())
|
if(*pXboxToken != X_D3DVSD_NOP())
|
||||||
{
|
{
|
||||||
EmuLog(LOG_LEVEL::WARNING, "Token NOP found, but extra parameters are given!");
|
LOG_TEST_CASE("Token NOP found, but extra parameters are given!");
|
||||||
}
|
}
|
||||||
DbgVshPrintf("\tD3DVSD_NOP(),\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD VshConvertToken_CONSTMEM(DWORD *pXboxToken)
|
DWORD VshConvertToken_CONSTMEM(DWORD *pXboxToken)
|
||||||
{
|
{
|
||||||
// D3DVSD_CONST
|
// DWORD ConstantAddress = (*pXboxToken & X_D3DVSD_CONSTADDRESSMASK) >> X_D3DVSD_CONSTADDRESSSHIFT;
|
||||||
DbgVshPrintf("\tD3DVSD_CONST(");
|
|
||||||
|
|
||||||
DWORD ConstantAddress = (*pXboxToken & X_D3DVSD_CONSTADDRESSMASK) >> X_D3DVSD_CONSTADDRESSSHIFT;
|
|
||||||
DWORD Count = (*pXboxToken & X_D3DVSD_CONSTCOUNTMASK) >> X_D3DVSD_CONSTCOUNTSHIFT;
|
DWORD Count = (*pXboxToken & X_D3DVSD_CONSTCOUNTMASK) >> X_D3DVSD_CONSTCOUNTSHIFT;
|
||||||
DbgVshPrintf("%d, %d),\n", ConstantAddress, Count);
|
LOG_TEST_CASE("CONST"); // TODO : Implement
|
||||||
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
return Count * 4 + 1;
|
return Count * 4 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1829,10 +2040,7 @@ private:
|
||||||
DWORD VertexRegister = VshGetVertexRegister(*pXboxToken);
|
DWORD VertexRegister = VshGetVertexRegister(*pXboxToken);
|
||||||
DWORD NewVertexRegister = VertexRegister;
|
DWORD NewVertexRegister = VertexRegister;
|
||||||
|
|
||||||
DbgVshPrintf("\tD3DVSD_TESSUV(");
|
|
||||||
NewVertexRegister = Xb2PCRegisterType(VertexRegister, Index);
|
NewVertexRegister = Xb2PCRegisterType(VertexRegister, Index);
|
||||||
DbgVshPrintf("),\n");
|
|
||||||
|
|
||||||
// TODO : Expand on the setting of this TESSUV register element :
|
// TODO : Expand on the setting of this TESSUV register element :
|
||||||
pRecompiled->Usage = D3DDECLUSAGE(NewVertexRegister);
|
pRecompiled->Usage = D3DDECLUSAGE(NewVertexRegister);
|
||||||
pRecompiled->UsageIndex = Index;
|
pRecompiled->UsageIndex = Index;
|
||||||
|
@ -1845,26 +2053,16 @@ private:
|
||||||
DWORD NewVertexRegisterIn = VertexRegisterIn;
|
DWORD NewVertexRegisterIn = VertexRegisterIn;
|
||||||
DWORD NewVertexRegisterOut = VertexRegisterOut;
|
DWORD NewVertexRegisterOut = VertexRegisterOut;
|
||||||
|
|
||||||
DbgVshPrintf("\tD3DVSD_TESSNORMAL(");
|
|
||||||
NewVertexRegisterIn = Xb2PCRegisterType(VertexRegisterIn, Index);
|
NewVertexRegisterIn = Xb2PCRegisterType(VertexRegisterIn, Index);
|
||||||
// TODO : Expand on the setting of this TESSNORMAL input register element :
|
// TODO : Expand on the setting of this TESSNORMAL input register element :
|
||||||
pRecompiled->Usage = D3DDECLUSAGE(NewVertexRegisterIn);
|
pRecompiled->Usage = D3DDECLUSAGE(NewVertexRegisterIn);
|
||||||
pRecompiled->UsageIndex = Index;
|
pRecompiled->UsageIndex = Index;
|
||||||
DbgVshPrintf(", ");
|
|
||||||
|
|
||||||
NewVertexRegisterOut = Xb2PCRegisterType(VertexRegisterOut, Index);
|
NewVertexRegisterOut = Xb2PCRegisterType(VertexRegisterOut, Index);
|
||||||
// TODO : Expand on the setting of this TESSNORMAL output register element :
|
// TODO : Expand on the setting of this TESSNORMAL output register element :
|
||||||
pRecompiled++;
|
pRecompiled++;
|
||||||
pRecompiled->Usage = D3DDECLUSAGE(NewVertexRegisterOut);
|
pRecompiled->Usage = D3DDECLUSAGE(NewVertexRegisterOut);
|
||||||
pRecompiled->UsageIndex = Index;
|
pRecompiled->UsageIndex = Index;
|
||||||
DbgVshPrintf("),\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VshEndPreviousStreamPatch()
|
|
||||||
{
|
|
||||||
if(pCurrentVertexShaderStreamInfo) {
|
|
||||||
DbgVshPrintf("\t// NeedPatching: %d\n", pCurrentVertexShaderStreamInfo->NeedPatch);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1873,12 +2071,10 @@ private:
|
||||||
// D3DVSD_STREAM_TESS
|
// D3DVSD_STREAM_TESS
|
||||||
if(*pXboxToken & X_D3DVSD_STREAMTESSMASK)
|
if(*pXboxToken & X_D3DVSD_STREAMTESSMASK)
|
||||||
{
|
{
|
||||||
DbgVshPrintf("\tD3DVSD_STREAM_TESS(),\n");
|
// TODO
|
||||||
}
|
}
|
||||||
else // D3DVSD_STREAM
|
else // D3DVSD_STREAM
|
||||||
{
|
{
|
||||||
VshEndPreviousStreamPatch();
|
|
||||||
|
|
||||||
DWORD StreamNumber = VshGetVertexStream(*pXboxToken);
|
DWORD StreamNumber = VshGetVertexStream(*pXboxToken);
|
||||||
|
|
||||||
// new stream
|
// new stream
|
||||||
|
@ -1891,8 +2087,6 @@ private:
|
||||||
|
|
||||||
// Dxbx note : Use Dophin(s), FieldRender, MatrixPaletteSkinning and PersistDisplay as a testcase
|
// Dxbx note : Use Dophin(s), FieldRender, MatrixPaletteSkinning and PersistDisplay as a testcase
|
||||||
|
|
||||||
DbgVshPrintf("\tD3DVSD_STREAM(%u),\n", StreamNumber);
|
|
||||||
|
|
||||||
pCurrentVertexShaderStreamInfo->CurrentStreamNumber = VshGetVertexStream(*pXboxToken);
|
pCurrentVertexShaderStreamInfo->CurrentStreamNumber = VshGetVertexStream(*pXboxToken);
|
||||||
pVertexShaderInfoToSet->NumberOfVertexStreams++;
|
pVertexShaderInfoToSet->NumberOfVertexStreams++;
|
||||||
// TODO : Keep a bitmask for all StreamNumber's seen?
|
// TODO : Keep a bitmask for all StreamNumber's seen?
|
||||||
|
@ -1939,15 +2133,12 @@ private:
|
||||||
void VshConvertToken_STREAMDATA_SKIP(DWORD *pXboxToken)
|
void VshConvertToken_STREAMDATA_SKIP(DWORD *pXboxToken)
|
||||||
{
|
{
|
||||||
WORD SkipCount = (*pXboxToken & X_D3DVSD_SKIPCOUNTMASK) >> X_D3DVSD_SKIPCOUNTSHIFT;
|
WORD SkipCount = (*pXboxToken & X_D3DVSD_SKIPCOUNTMASK) >> X_D3DVSD_SKIPCOUNTSHIFT;
|
||||||
DbgVshPrintf("\tD3DVSD_SKIP(%d),\n", SkipCount);
|
|
||||||
VshConvert_SkipBytes(SkipCount * sizeof(DWORD));
|
VshConvert_SkipBytes(SkipCount * sizeof(DWORD));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VshConvertToken_STREAMDATA_SKIPBYTES(DWORD* pXboxToken)
|
void VshConvertToken_STREAMDATA_SKIPBYTES(DWORD* pXboxToken)
|
||||||
{
|
{
|
||||||
WORD SkipBytesCount = (*pXboxToken & X_D3DVSD_SKIPCOUNTMASK) >> X_D3DVSD_SKIPCOUNTSHIFT;
|
WORD SkipBytesCount = (*pXboxToken & X_D3DVSD_SKIPCOUNTMASK) >> X_D3DVSD_SKIPCOUNTSHIFT;
|
||||||
|
|
||||||
DbgVshPrintf("\tD3DVSD_SKIPBYTES(%d), /* xbox ext. */\n", SkipBytesCount);
|
|
||||||
VshConvert_SkipBytes(SkipBytesCount);
|
VshConvert_SkipBytes(SkipBytesCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1956,10 +2147,8 @@ private:
|
||||||
DWORD VertexRegister = VshGetVertexRegister(*pXboxToken);
|
DWORD VertexRegister = VshGetVertexRegister(*pXboxToken);
|
||||||
BOOL NeedPatching = FALSE;
|
BOOL NeedPatching = FALSE;
|
||||||
BYTE Index;
|
BYTE Index;
|
||||||
|
|
||||||
BYTE HostVertexRegisterType;
|
BYTE HostVertexRegisterType;
|
||||||
// If this is a fixed-function shader, use Xb2PCRegisterType
|
|
||||||
DbgVshPrintf("\t\tD3DVSD_REG(");
|
|
||||||
if (IsFixedFunction) {
|
if (IsFixedFunction) {
|
||||||
HostVertexRegisterType = Xb2PCRegisterType(VertexRegister, Index);
|
HostVertexRegisterType = Xb2PCRegisterType(VertexRegister, Index);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1970,9 +2159,7 @@ private:
|
||||||
// this prevents information loss in shaders due to non-matching dcl types!
|
// this prevents information loss in shaders due to non-matching dcl types!
|
||||||
HostVertexRegisterType = D3DDECLUSAGE_TEXCOORD;
|
HostVertexRegisterType = D3DDECLUSAGE_TEXCOORD;
|
||||||
Index = (BYTE)VertexRegister;
|
Index = (BYTE)VertexRegister;
|
||||||
DbgVshPrintf("%d", Index);
|
|
||||||
}
|
}
|
||||||
DbgVshPrintf(", ");
|
|
||||||
|
|
||||||
// Add this register to the list of declared registers
|
// Add this register to the list of declared registers
|
||||||
RegVIsPresentInDeclaration[VertexRegister] = true;
|
RegVIsPresentInDeclaration[VertexRegister] = true;
|
||||||
|
@ -1985,42 +2172,34 @@ private:
|
||||||
switch (XboxVertexElementDataType)
|
switch (XboxVertexElementDataType)
|
||||||
{
|
{
|
||||||
case XTL::X_D3DVSDT_FLOAT1: // 0x12:
|
case XTL::X_D3DVSDT_FLOAT1: // 0x12:
|
||||||
DbgVshPrintf("D3DVSDT_FLOAT1");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT1;
|
HostVertexElementDataType = D3DDECLTYPE_FLOAT1;
|
||||||
HostVertexElementByteSize = 1 * sizeof(FLOAT);
|
HostVertexElementByteSize = 1 * sizeof(FLOAT);
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_FLOAT2: // 0x22:
|
case XTL::X_D3DVSDT_FLOAT2: // 0x22:
|
||||||
DbgVshPrintf("D3DVSDT_FLOAT2");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT2;
|
HostVertexElementDataType = D3DDECLTYPE_FLOAT2;
|
||||||
HostVertexElementByteSize = 2 * sizeof(FLOAT);
|
HostVertexElementByteSize = 2 * sizeof(FLOAT);
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_FLOAT3: // 0x32:
|
case XTL::X_D3DVSDT_FLOAT3: // 0x32:
|
||||||
DbgVshPrintf("D3DVSDT_FLOAT3");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT3;
|
HostVertexElementDataType = D3DDECLTYPE_FLOAT3;
|
||||||
HostVertexElementByteSize = 3 * sizeof(FLOAT);
|
HostVertexElementByteSize = 3 * sizeof(FLOAT);
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_FLOAT4: // 0x42:
|
case XTL::X_D3DVSDT_FLOAT4: // 0x42:
|
||||||
DbgVshPrintf("D3DVSDT_FLOAT4");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
|
HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
|
||||||
HostVertexElementByteSize = 4 * sizeof(FLOAT);
|
HostVertexElementByteSize = 4 * sizeof(FLOAT);
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_D3DCOLOR: // 0x40:
|
case XTL::X_D3DVSDT_D3DCOLOR: // 0x40:
|
||||||
DbgVshPrintf("D3DVSDT_D3DCOLOR");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_D3DCOLOR;
|
HostVertexElementDataType = D3DDECLTYPE_D3DCOLOR;
|
||||||
HostVertexElementByteSize = 1 * sizeof(D3DCOLOR);
|
HostVertexElementByteSize = 1 * sizeof(D3DCOLOR);
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_SHORT2: // 0x25:
|
case XTL::X_D3DVSDT_SHORT2: // 0x25:
|
||||||
DbgVshPrintf("D3DVSDT_SHORT2");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_SHORT2;
|
HostVertexElementDataType = D3DDECLTYPE_SHORT2;
|
||||||
HostVertexElementByteSize = 2 * sizeof(SHORT);
|
HostVertexElementByteSize = 2 * sizeof(SHORT);
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_SHORT4: // 0x45:
|
case XTL::X_D3DVSDT_SHORT4: // 0x45:
|
||||||
DbgVshPrintf("D3DVSDT_SHORT4");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_SHORT4;
|
HostVertexElementDataType = D3DDECLTYPE_SHORT4;
|
||||||
HostVertexElementByteSize = 4 * sizeof(SHORT);
|
HostVertexElementByteSize = 4 * sizeof(SHORT);
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_NORMSHORT1: // 0x11:
|
case XTL::X_D3DVSDT_NORMSHORT1: // 0x11:
|
||||||
DbgVshPrintf("D3DVSDT_NORMSHORT1 /* xbox ext. */");
|
|
||||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) {
|
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) {
|
||||||
HostVertexElementDataType = D3DDECLTYPE_SHORT2N;
|
HostVertexElementDataType = D3DDECLTYPE_SHORT2N;
|
||||||
HostVertexElementByteSize = 2 * sizeof(SHORT);
|
HostVertexElementByteSize = 2 * sizeof(SHORT);
|
||||||
|
@ -2035,14 +2214,12 @@ private:
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_NORMSHORT2: // 0x21:
|
case XTL::X_D3DVSDT_NORMSHORT2: // 0x21:
|
||||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) {
|
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) {
|
||||||
DbgVshPrintf("D3DVSDT_NORMSHORT2");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_SHORT2N;
|
HostVertexElementDataType = D3DDECLTYPE_SHORT2N;
|
||||||
HostVertexElementByteSize = 2 * sizeof(SHORT);
|
HostVertexElementByteSize = 2 * sizeof(SHORT);
|
||||||
// No need for patching in D3D9
|
// No need for patching in D3D9
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgVshPrintf("D3DVSDT_NORMSHORT2 /* xbox ext. */");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT2;
|
HostVertexElementDataType = D3DDECLTYPE_FLOAT2;
|
||||||
HostVertexElementByteSize = 2 * sizeof(FLOAT);
|
HostVertexElementByteSize = 2 * sizeof(FLOAT);
|
||||||
XboxVertexElementByteSize = 2 * sizeof(XTL::SHORT);
|
XboxVertexElementByteSize = 2 * sizeof(XTL::SHORT);
|
||||||
|
@ -2050,7 +2227,6 @@ private:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_NORMSHORT3: // 0x31:
|
case XTL::X_D3DVSDT_NORMSHORT3: // 0x31:
|
||||||
DbgVshPrintf("D3DVSDT_NORMSHORT3 /* xbox ext. */");
|
|
||||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) {
|
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) {
|
||||||
HostVertexElementDataType = D3DDECLTYPE_SHORT4N;
|
HostVertexElementDataType = D3DDECLTYPE_SHORT4N;
|
||||||
HostVertexElementByteSize = 4 * sizeof(SHORT);
|
HostVertexElementByteSize = 4 * sizeof(SHORT);
|
||||||
|
@ -2065,14 +2241,12 @@ private:
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_NORMSHORT4: // 0x41:
|
case XTL::X_D3DVSDT_NORMSHORT4: // 0x41:
|
||||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) {
|
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) {
|
||||||
DbgVshPrintf("D3DVSDT_NORMSHORT4");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_SHORT4N;
|
HostVertexElementDataType = D3DDECLTYPE_SHORT4N;
|
||||||
HostVertexElementByteSize = 4 * sizeof(SHORT);
|
HostVertexElementByteSize = 4 * sizeof(SHORT);
|
||||||
// No need for patching in D3D9
|
// No need for patching in D3D9
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgVshPrintf("D3DVSDT_NORMSHORT4 /* xbox ext. */");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
|
HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
|
||||||
HostVertexElementByteSize = 4 * sizeof(FLOAT);
|
HostVertexElementByteSize = 4 * sizeof(FLOAT);
|
||||||
XboxVertexElementByteSize = 4 * sizeof(XTL::SHORT);
|
XboxVertexElementByteSize = 4 * sizeof(XTL::SHORT);
|
||||||
|
@ -2080,28 +2254,24 @@ private:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_NORMPACKED3: // 0x16:
|
case XTL::X_D3DVSDT_NORMPACKED3: // 0x16:
|
||||||
DbgVshPrintf("D3DVSDT_NORMPACKED3 /* xbox ext. */");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT3;
|
HostVertexElementDataType = D3DDECLTYPE_FLOAT3;
|
||||||
HostVertexElementByteSize = 3 * sizeof(FLOAT);
|
HostVertexElementByteSize = 3 * sizeof(FLOAT);
|
||||||
XboxVertexElementByteSize = 1 * sizeof(XTL::DWORD);
|
XboxVertexElementByteSize = 1 * sizeof(XTL::DWORD);
|
||||||
NeedPatching = TRUE;
|
NeedPatching = TRUE;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_SHORT1: // 0x15:
|
case XTL::X_D3DVSDT_SHORT1: // 0x15:
|
||||||
DbgVshPrintf("D3DVSDT_SHORT1 /* xbox ext. */");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_SHORT2;
|
HostVertexElementDataType = D3DDECLTYPE_SHORT2;
|
||||||
HostVertexElementByteSize = 2 * sizeof(SHORT);
|
HostVertexElementByteSize = 2 * sizeof(SHORT);
|
||||||
XboxVertexElementByteSize = 1 * sizeof(XTL::SHORT);
|
XboxVertexElementByteSize = 1 * sizeof(XTL::SHORT);
|
||||||
NeedPatching = TRUE;
|
NeedPatching = TRUE;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_SHORT3: // 0x35:
|
case XTL::X_D3DVSDT_SHORT3: // 0x35:
|
||||||
DbgVshPrintf("D3DVSDT_SHORT3 /* xbox ext. */");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_SHORT4;
|
HostVertexElementDataType = D3DDECLTYPE_SHORT4;
|
||||||
HostVertexElementByteSize = 4 * sizeof(SHORT);
|
HostVertexElementByteSize = 4 * sizeof(SHORT);
|
||||||
XboxVertexElementByteSize = 3 * sizeof(XTL::SHORT);
|
XboxVertexElementByteSize = 3 * sizeof(XTL::SHORT);
|
||||||
NeedPatching = TRUE;
|
NeedPatching = TRUE;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_PBYTE1: // 0x14:
|
case XTL::X_D3DVSDT_PBYTE1: // 0x14:
|
||||||
DbgVshPrintf("D3DVSDT_PBYTE1 /* xbox ext. */");
|
|
||||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
|
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
|
||||||
HostVertexElementDataType = D3DDECLTYPE_UBYTE4N;
|
HostVertexElementDataType = D3DDECLTYPE_UBYTE4N;
|
||||||
HostVertexElementByteSize = 4 * sizeof(BYTE);
|
HostVertexElementByteSize = 4 * sizeof(BYTE);
|
||||||
|
@ -2115,7 +2285,6 @@ private:
|
||||||
NeedPatching = TRUE;
|
NeedPatching = TRUE;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_PBYTE2: // 0x24:
|
case XTL::X_D3DVSDT_PBYTE2: // 0x24:
|
||||||
DbgVshPrintf("D3DVSDT_PBYTE2 /* xbox ext. */");
|
|
||||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
|
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
|
||||||
HostVertexElementDataType = D3DDECLTYPE_UBYTE4N;
|
HostVertexElementDataType = D3DDECLTYPE_UBYTE4N;
|
||||||
HostVertexElementByteSize = 4 * sizeof(BYTE);
|
HostVertexElementByteSize = 4 * sizeof(BYTE);
|
||||||
|
@ -2129,7 +2298,6 @@ private:
|
||||||
NeedPatching = TRUE;
|
NeedPatching = TRUE;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_PBYTE3: // 0x34:
|
case XTL::X_D3DVSDT_PBYTE3: // 0x34:
|
||||||
DbgVshPrintf("D3DVSDT_PBYTE3 /* xbox ext. */");
|
|
||||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
|
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
|
||||||
HostVertexElementDataType = D3DDECLTYPE_UBYTE4N;
|
HostVertexElementDataType = D3DDECLTYPE_UBYTE4N;
|
||||||
HostVertexElementByteSize = 4 * sizeof(BYTE);
|
HostVertexElementByteSize = 4 * sizeof(BYTE);
|
||||||
|
@ -2145,14 +2313,12 @@ private:
|
||||||
case XTL::X_D3DVSDT_PBYTE4: // 0x44:
|
case XTL::X_D3DVSDT_PBYTE4: // 0x44:
|
||||||
// Test-case : Panzer
|
// Test-case : Panzer
|
||||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
|
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
|
||||||
DbgVshPrintf("D3DVSDT_PBYTE4");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_UBYTE4N;
|
HostVertexElementDataType = D3DDECLTYPE_UBYTE4N;
|
||||||
HostVertexElementByteSize = 4 * sizeof(BYTE);
|
HostVertexElementByteSize = 4 * sizeof(BYTE);
|
||||||
// No need for patching when D3D9 supports D3DDECLTYPE_UBYTE4N
|
// No need for patching when D3D9 supports D3DDECLTYPE_UBYTE4N
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DbgVshPrintf("D3DVSDT_PBYTE4 /* xbox ext. */");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
|
HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
|
||||||
HostVertexElementByteSize = 4 * sizeof(FLOAT);
|
HostVertexElementByteSize = 4 * sizeof(FLOAT);
|
||||||
XboxVertexElementByteSize = 4 * sizeof(XTL::BYTE);
|
XboxVertexElementByteSize = 4 * sizeof(XTL::BYTE);
|
||||||
|
@ -2160,23 +2326,19 @@ private:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_FLOAT2H: // 0x72:
|
case XTL::X_D3DVSDT_FLOAT2H: // 0x72:
|
||||||
DbgVshPrintf("D3DVSDT_FLOAT2H /* xbox ext. */");
|
|
||||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
|
HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
|
||||||
HostVertexElementByteSize = 4 * sizeof(FLOAT);
|
HostVertexElementByteSize = 4 * sizeof(FLOAT);
|
||||||
XboxVertexElementByteSize = 3 * sizeof(FLOAT);
|
XboxVertexElementByteSize = 3 * sizeof(FLOAT);
|
||||||
NeedPatching = TRUE;
|
NeedPatching = TRUE;
|
||||||
break;
|
break;
|
||||||
case XTL::X_D3DVSDT_NONE: // 0x02:
|
case XTL::X_D3DVSDT_NONE: // 0x02:
|
||||||
DbgVshPrintf("D3DVSDT_NONE /* xbox ext. */");
|
|
||||||
// No host element data, so no patching
|
// No host element data, so no patching
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DbgVshPrintf("Unknown data type for D3DVSD_REG: 0x%02X\n", XboxVertexElementDataType);
|
//LOG_TEST_CASE("Unknown data type for D3DVSD_REG: 0x%02X\n", XboxVertexElementDataType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgVshPrintf("),\n");
|
|
||||||
|
|
||||||
// On X_D3DVSDT_NONE skip this token
|
// On X_D3DVSDT_NONE skip this token
|
||||||
if (XboxVertexElementDataType == XTL::X_D3DVSDT_NONE)
|
if (XboxVertexElementDataType == XTL::X_D3DVSDT_NONE)
|
||||||
{
|
{
|
||||||
|
@ -2251,7 +2413,7 @@ private:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
DbgVshPrintf("Unknown token type: %d\n", VshGetTokenType(*pXboxToken));
|
//LOG_TEST_CASE("Unknown token type: %d\n", VshGetTokenType(*pXboxToken));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2312,7 +2474,19 @@ public:
|
||||||
auto pXboxVertexDeclarationCopy = RemoveXboxDeclarationRedefinition(pXboxDeclaration);
|
auto pXboxVertexDeclarationCopy = RemoveXboxDeclarationRedefinition(pXboxDeclaration);
|
||||||
|
|
||||||
pVertexShaderInfoToSet = pCxbxVertexShaderInfo;
|
pVertexShaderInfoToSet = pCxbxVertexShaderInfo;
|
||||||
temporaryCount = g_D3DCaps.VS20Caps.NumTemps;
|
hostTemporaryRegisterCount = g_D3DCaps.VS20Caps.NumTemps;
|
||||||
|
if (hostTemporaryRegisterCount < VSH_MIN_TEMPORARY_REGISTERS) {
|
||||||
|
LOG_TEST_CASE("g_D3DCaps.VS20Caps.NumTemps < 12 (Host minimal vertex shader temporary register count)");
|
||||||
|
}
|
||||||
|
if (hostTemporaryRegisterCount < 12+1) { // TODO : Use a constant (see X_D3DVSD_REG)
|
||||||
|
LOG_TEST_CASE("g_D3DCaps.VS20Caps.NumTemps < 12+1 (Xbox vertex shader temporary register count + r12, reading oPos)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note, that some Direct3D 9 drivers return only the required minimum temporary register count of 12,
|
||||||
|
// but regardless, shaders that use temporary register numbers above r12 still seem to work correctly.
|
||||||
|
// So it seems we can't rely on VS20Caps.NumTemps indicating accurately what host hardware supports.
|
||||||
|
// (Although it could be that the driver switches to software vertex processing when a shader exceeds hardware limits.)
|
||||||
|
|
||||||
IsFixedFunction = bIsFixedFunction;
|
IsFixedFunction = bIsFixedFunction;
|
||||||
|
|
||||||
RegVIsPresentInDeclaration.fill(false);
|
RegVIsPresentInDeclaration.fill(false);
|
||||||
|
@ -2334,7 +2508,7 @@ public:
|
||||||
pRecompiled = Result;
|
pRecompiled = Result;
|
||||||
uint8_t *pRecompiledBufferOverflow = ((uint8_t*)pRecompiled) + HostDeclarationSize;
|
uint8_t *pRecompiledBufferOverflow = ((uint8_t*)pRecompiled) + HostDeclarationSize;
|
||||||
|
|
||||||
DbgVshPrintf("DWORD dwVSHDecl[] =\n{\n");
|
VshDumpXboxDeclaration(pXboxDeclaration);
|
||||||
|
|
||||||
auto pXboxToken = pXboxVertexDeclarationCopy;
|
auto pXboxToken = pXboxVertexDeclarationCopy;
|
||||||
while (*pXboxToken != X_D3DVSD_END())
|
while (*pXboxToken != X_D3DVSD_END())
|
||||||
|
@ -2356,11 +2530,6 @@ public:
|
||||||
std::sort(Result, pRecompiled, [] (const auto& x, const auto& y)
|
std::sort(Result, pRecompiled, [] (const auto& x, const auto& y)
|
||||||
{ return std::tie(x.Stream, x.Method, x.Offset) < std::tie(y.Stream, y.Method, y.Offset); });
|
{ return std::tie(x.Stream, x.Method, x.Offset) < std::tie(y.Stream, y.Method, y.Offset); });
|
||||||
|
|
||||||
VshEndPreviousStreamPatch();
|
|
||||||
DbgVshPrintf("\tD3DVSD_END()\n};\n");
|
|
||||||
|
|
||||||
DbgVshPrintf("// NbrStreams: %d\n", pVertexShaderInfoToSet->NumberOfVertexStreams);
|
|
||||||
|
|
||||||
// Free the preprocessed declaration copy
|
// Free the preprocessed declaration copy
|
||||||
free(pXboxVertexDeclarationCopy);
|
free(pXboxVertexDeclarationCopy);
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "core\hle\D3D8\XbD3D8Types.h" // for X_VSH_MAX_ATTRIBUTES
|
#include "core\hle\D3D8\XbD3D8Types.h" // for X_VSH_MAX_ATTRIBUTES
|
||||||
|
|
||||||
// Host vertex shader counts
|
// Host vertex shader counts
|
||||||
|
#define VSH_MIN_TEMPORARY_REGISTERS 12 // Equal to D3DCAPS9.VS20Caps.NumTemps (at least 12 for vs_2_x) - https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx9-graphics-reference-asm-vs-registers-vs-2-x
|
||||||
#define VSH_MAX_TEMPORARY_REGISTERS 32
|
#define VSH_MAX_TEMPORARY_REGISTERS 32
|
||||||
#define VSH_MAX_INTERMEDIATE_COUNT 1024 // The maximum number of intermediate format slots
|
#define VSH_MAX_INTERMEDIATE_COUNT 1024 // The maximum number of intermediate format slots
|
||||||
#define VSH_VS11_MAX_INSTRUCTION_COUNT 128
|
#define VSH_VS11_MAX_INSTRUCTION_COUNT 128
|
||||||
|
|
Loading…
Reference in New Issue