Fix vertex conversion when skip tokens are present in the Xbox vertex declaration.
This commit is contained in:
parent
e5dc2e5e13
commit
6ef5b21144
|
@ -437,7 +437,7 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
for (UINT uiElement = 0; uiElement < pVertexShaderStreamInfo->NumberOfVertexElements; uiElement++) {
|
||||
FLOAT *pXboxVertexAsFloat = (FLOAT*)pXboxVertexAsByte;
|
||||
SHORT *pXboxVertexAsShort = (SHORT*)pXboxVertexAsByte;
|
||||
int XboxElementByteSize = pVertexShaderStreamInfo->VertexElements[uiElement].HostByteSize;
|
||||
const int XboxElementByteSize = pVertexShaderStreamInfo->VertexElements[uiElement].XboxByteSize;
|
||||
FLOAT *pHostVertexAsFloat = (FLOAT*)pHostVertexAsByte;
|
||||
SHORT *pHostVertexAsShort = (SHORT*)pHostVertexAsByte;
|
||||
// Dxbx note : The following code handles only the D3DVSDT enums that need conversion;
|
||||
|
@ -445,7 +445,6 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
switch (pVertexShaderStreamInfo->VertexElements[uiElement].XboxType) {
|
||||
case XTL::X_D3DVSDT_NORMSHORT1: { // 0x11:
|
||||
// Test-cases : Halo - Combat Evolved
|
||||
XboxElementByteSize = 1 * sizeof(SHORT);
|
||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) {
|
||||
// Make it SHORT2N
|
||||
pHostVertexAsShort[0] = pXboxVertexAsShort[0];
|
||||
|
@ -461,11 +460,9 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
}
|
||||
case XTL::X_D3DVSDT_NORMSHORT2: { // 0x21:
|
||||
// Test-cases : Baldur's Gate: Dark Alliance 2, F1 2002, Gun, Halo - Combat Evolved, Scrapland
|
||||
XboxElementByteSize = 2 * sizeof(SHORT);
|
||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT2N) {
|
||||
// No need for patching when D3D9 supports D3DDECLTYPE_SHORT2N
|
||||
// TODO : goto default; // ??
|
||||
//assert(XboxElementByteSize == 2 * sizeof(SHORT));
|
||||
//memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize);
|
||||
// Make it SHORT2N
|
||||
pHostVertexAsShort[0] = pXboxVertexAsShort[0];
|
||||
|
@ -481,7 +478,6 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
}
|
||||
case XTL::X_D3DVSDT_NORMSHORT3: { // 0x31:
|
||||
// Test-cases : Cel Damage, Constantine, Destroy All Humans!
|
||||
XboxElementByteSize = 3 * sizeof(SHORT);
|
||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) {
|
||||
// Make it SHORT4N
|
||||
pHostVertexAsShort[0] = pXboxVertexAsShort[0];
|
||||
|
@ -500,11 +496,9 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
}
|
||||
case XTL::X_D3DVSDT_NORMSHORT4: { // 0x41:
|
||||
// Test-cases : Judge Dredd: Dredd vs Death, NHL Hitz 2002, Silent Hill 2, Sneakers, Tony Hawk Pro Skater 4
|
||||
XboxElementByteSize = 4 * sizeof(SHORT);
|
||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_SHORT4N) {
|
||||
// No need for patching when D3D9 supports D3DDECLTYPE_SHORT4N
|
||||
// TODO : goto default; // ??
|
||||
//assert(XboxElementByteSize == 4 * sizeof(SHORT));
|
||||
//memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize);
|
||||
// Make it SHORT4N
|
||||
pHostVertexAsShort[0] = pXboxVertexAsShort[0];
|
||||
|
@ -524,7 +518,6 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
}
|
||||
case XTL::X_D3DVSDT_NORMPACKED3: { // 0x16:
|
||||
// Test-cases : Dashboard
|
||||
XboxElementByteSize = 1 * sizeof(int32_t);
|
||||
// Make it FLOAT3
|
||||
union {
|
||||
int32_t value;
|
||||
|
@ -543,7 +536,6 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
break;
|
||||
}
|
||||
case XTL::X_D3DVSDT_SHORT1: { // 0x15:
|
||||
XboxElementByteSize = 1 * sizeof(SHORT);
|
||||
// Make it SHORT2 and set the second short to 0
|
||||
pHostVertexAsShort[0] = pXboxVertexAsShort[0];
|
||||
pHostVertexAsShort[1] = 0;
|
||||
|
@ -551,7 +543,6 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
}
|
||||
case XTL::X_D3DVSDT_SHORT3: { // 0x35:
|
||||
// Test-cases : Turok
|
||||
XboxElementByteSize = 3 * sizeof(SHORT);
|
||||
// Make it a SHORT4 and set the fourth short to 1
|
||||
pHostVertexAsShort[0] = pXboxVertexAsShort[0];
|
||||
pHostVertexAsShort[1] = pXboxVertexAsShort[1];
|
||||
|
@ -560,7 +551,6 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
break;
|
||||
}
|
||||
case XTL::X_D3DVSDT_PBYTE1: { // 0x14:
|
||||
XboxElementByteSize = 1 * sizeof(BYTE);
|
||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
|
||||
// Make it UBYTE4N
|
||||
pHostVertexAsByte[0] = pXboxVertexAsByte[0];
|
||||
|
@ -576,7 +566,6 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
break;
|
||||
}
|
||||
case XTL::X_D3DVSDT_PBYTE2: { // 0x24:
|
||||
XboxElementByteSize = 2 * sizeof(BYTE);
|
||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
|
||||
// Make it UBYTE4N
|
||||
pHostVertexAsByte[0] = pXboxVertexAsByte[0];
|
||||
|
@ -594,7 +583,6 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
}
|
||||
case XTL::X_D3DVSDT_PBYTE3: { // 0x34:
|
||||
// Test-cases : Turok
|
||||
XboxElementByteSize = 3 * sizeof(BYTE);
|
||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
|
||||
// Make it UBYTE4N
|
||||
pHostVertexAsByte[0] = pXboxVertexAsByte[0];
|
||||
|
@ -613,11 +601,9 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
}
|
||||
case XTL::X_D3DVSDT_PBYTE4: { // 0x44:
|
||||
// Test-case : Jet Set Radio Future
|
||||
XboxElementByteSize = 4 * sizeof(BYTE);
|
||||
if (g_D3DCaps.DeclTypes & D3DDTCAPS_UBYTE4N) {
|
||||
// No need for patching when D3D9 supports D3DDECLTYPE_UBYTE4N
|
||||
// TODO : goto default; // ??
|
||||
//assert(XboxElementByteSize == 4 * sizeof(BYTE));
|
||||
//memcpy(pHostVertexAsByte, pXboxVertexAsByte, XboxElementByteSize);
|
||||
// Make it UBYTE4N
|
||||
pHostVertexAsByte[0] = pXboxVertexAsByte[0];
|
||||
|
@ -636,7 +622,6 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
break;
|
||||
}
|
||||
case XTL::X_D3DVSDT_FLOAT2H: { // 0x72:
|
||||
XboxElementByteSize = 3 * sizeof(FLOAT);
|
||||
// Make it FLOAT4 and set the third float to 0.0
|
||||
pHostVertexAsFloat[0] = pXboxVertexAsFloat[0];
|
||||
pHostVertexAsFloat[1] = pXboxVertexAsFloat[1];
|
||||
|
@ -644,9 +629,10 @@ void CxbxVertexBufferConverter::ConvertStream
|
|||
pHostVertexAsFloat[3] = pXboxVertexAsFloat[2];
|
||||
break;
|
||||
}
|
||||
case XTL::X_D3DVSDT_NONE: { // 0x02: // Skip it
|
||||
case XTL::X_D3DVSDT_NONE: { // 0x02:
|
||||
// Test-case : WWE RAW2
|
||||
LOG_TEST_CASE("X_D3DVSDT_NONE");
|
||||
// No host element data (but Xbox size can be above zero, when used for X_D3DVSD_MASK_SKIP*
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
|
@ -1899,11 +1899,48 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
void VshConvert_RegisterVertexElement(
|
||||
UINT XboxVertexElementDataType,
|
||||
UINT XboxVertexElementByteSize,
|
||||
UINT HostVertexElementByteSize,
|
||||
BOOL NeedPatching)
|
||||
{
|
||||
CxbxVertexShaderStreamElement* pCurrentElement = &(pCurrentVertexShaderStreamInfo->VertexElements[pCurrentVertexShaderStreamInfo->NumberOfVertexElements]);
|
||||
pCurrentElement->XboxType = XboxVertexElementDataType;
|
||||
pCurrentElement->XboxByteSize = XboxVertexElementByteSize;
|
||||
pCurrentElement->HostByteSize = HostVertexElementByteSize;
|
||||
pCurrentVertexShaderStreamInfo->NumberOfVertexElements++;
|
||||
pCurrentVertexShaderStreamInfo->NeedPatch |= NeedPatching;
|
||||
}
|
||||
|
||||
void VshConvert_SkipBytes(int SkipBytesCount)
|
||||
{
|
||||
if (SkipBytesCount % sizeof(DWORD)) {
|
||||
LOG_TEST_CASE("D3DVSD_SKIPBYTES not divisble by 4!");
|
||||
}
|
||||
#if 0 // Potential optimization, for now disabled for simplicity :
|
||||
else {
|
||||
// Skip size is a whole multiple of 4 bytes;
|
||||
// Is stream patching not needed up until this element?
|
||||
if (!pCurrentVertexShaderStreamInfo->NeedPatch) {
|
||||
// Then we can get away with increasing the host stride,
|
||||
// which avoids otherwise needless vertex buffer patching :
|
||||
pCurrentVertexShaderStreamInfo->HostVertexStride += SkipBytesCount;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Register a 'skip' element, so that Xbox data will be skipped
|
||||
// without increasing host stride - this does require patching :
|
||||
VshConvert_RegisterVertexElement(XTL::X_D3DVSDT_NONE, SkipBytesCount, /*HostSize=*/0, /*NeedPatching=*/TRUE);
|
||||
}
|
||||
|
||||
void VshConvertToken_STREAMDATA_SKIP(DWORD *pXboxToken)
|
||||
{
|
||||
WORD SkipCount = (*pXboxToken & X_D3DVSD_SKIPCOUNTMASK) >> X_D3DVSD_SKIPCOUNTSHIFT;
|
||||
DbgVshPrintf("\tD3DVSD_SKIP(%d),\n", SkipCount);
|
||||
pCurrentVertexShaderStreamInfo->HostVertexStride += (SkipCount * sizeof(DWORD));
|
||||
VshConvert_SkipBytes(SkipCount * sizeof(DWORD));
|
||||
}
|
||||
|
||||
void VshConvertToken_STREAMDATA_SKIPBYTES(DWORD* pXboxToken)
|
||||
|
@ -1911,11 +1948,7 @@ private:
|
|||
WORD SkipBytesCount = (*pXboxToken & X_D3DVSD_SKIPCOUNTMASK) >> X_D3DVSD_SKIPCOUNTSHIFT;
|
||||
|
||||
DbgVshPrintf("\tD3DVSD_SKIPBYTES(%d), /* xbox ext. */\n", SkipBytesCount);
|
||||
if (SkipBytesCount % sizeof(DWORD)) {
|
||||
EmuLog(LOG_LEVEL::WARNING, "D3DVSD_SKIPBYTES can't be converted to D3DVSD_SKIP, not divisble by 4.");
|
||||
}
|
||||
|
||||
pCurrentVertexShaderStreamInfo->HostVertexStride += SkipBytesCount;
|
||||
VshConvert_SkipBytes(SkipBytesCount);
|
||||
}
|
||||
|
||||
void VshConvertToken_STREAMDATA_REG(DWORD *pXboxToken)
|
||||
|
@ -1945,6 +1978,7 @@ private:
|
|||
RegVIsPresentInDeclaration[VertexRegister] = true;
|
||||
|
||||
DWORD XboxVertexElementDataType = (*pXboxToken & X_D3DVSD_DATATYPEMASK) >> X_D3DVSD_DATATYPESHIFT;
|
||||
WORD XboxVertexElementByteSize = 0;
|
||||
BYTE HostVertexElementDataType = 0;
|
||||
WORD HostVertexElementByteSize = 0;
|
||||
|
||||
|
@ -1996,6 +2030,7 @@ private:
|
|||
HostVertexElementDataType = D3DDECLTYPE_FLOAT1;
|
||||
HostVertexElementByteSize = 1 * sizeof(FLOAT);
|
||||
}
|
||||
XboxVertexElementByteSize = 1 * sizeof(XTL::SHORT);
|
||||
NeedPatching = TRUE;
|
||||
break;
|
||||
case XTL::X_D3DVSDT_NORMSHORT2: // 0x21:
|
||||
|
@ -2010,6 +2045,7 @@ private:
|
|||
DbgVshPrintf("D3DVSDT_NORMSHORT2 /* xbox ext. */");
|
||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT2;
|
||||
HostVertexElementByteSize = 2 * sizeof(FLOAT);
|
||||
XboxVertexElementByteSize = 2 * sizeof(XTL::SHORT);
|
||||
NeedPatching = TRUE;
|
||||
}
|
||||
break;
|
||||
|
@ -2024,6 +2060,7 @@ private:
|
|||
HostVertexElementDataType = D3DDECLTYPE_FLOAT3;
|
||||
HostVertexElementByteSize = 3 * sizeof(FLOAT);
|
||||
}
|
||||
XboxVertexElementByteSize = 3 * sizeof(XTL::SHORT);
|
||||
NeedPatching = TRUE;
|
||||
break;
|
||||
case XTL::X_D3DVSDT_NORMSHORT4: // 0x41:
|
||||
|
@ -2038,6 +2075,7 @@ private:
|
|||
DbgVshPrintf("D3DVSDT_NORMSHORT4 /* xbox ext. */");
|
||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
|
||||
HostVertexElementByteSize = 4 * sizeof(FLOAT);
|
||||
XboxVertexElementByteSize = 4 * sizeof(XTL::SHORT);
|
||||
NeedPatching = TRUE;
|
||||
}
|
||||
break;
|
||||
|
@ -2045,18 +2083,21 @@ private:
|
|||
DbgVshPrintf("D3DVSDT_NORMPACKED3 /* xbox ext. */");
|
||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT3;
|
||||
HostVertexElementByteSize = 3 * sizeof(FLOAT);
|
||||
XboxVertexElementByteSize = 1 * sizeof(XTL::DWORD);
|
||||
NeedPatching = TRUE;
|
||||
break;
|
||||
case XTL::X_D3DVSDT_SHORT1: // 0x15:
|
||||
DbgVshPrintf("D3DVSDT_SHORT1 /* xbox ext. */");
|
||||
HostVertexElementDataType = D3DDECLTYPE_SHORT2;
|
||||
HostVertexElementByteSize = 2 * sizeof(SHORT);
|
||||
XboxVertexElementByteSize = 1 * sizeof(XTL::SHORT);
|
||||
NeedPatching = TRUE;
|
||||
break;
|
||||
case XTL::X_D3DVSDT_SHORT3: // 0x35:
|
||||
DbgVshPrintf("D3DVSDT_SHORT3 /* xbox ext. */");
|
||||
HostVertexElementDataType = D3DDECLTYPE_SHORT4;
|
||||
HostVertexElementByteSize = 4 * sizeof(SHORT);
|
||||
XboxVertexElementByteSize = 3 * sizeof(XTL::SHORT);
|
||||
NeedPatching = TRUE;
|
||||
break;
|
||||
case XTL::X_D3DVSDT_PBYTE1: // 0x14:
|
||||
|
@ -2070,6 +2111,7 @@ private:
|
|||
HostVertexElementDataType = D3DDECLTYPE_FLOAT1;
|
||||
HostVertexElementByteSize = 1 * sizeof(FLOAT);
|
||||
}
|
||||
XboxVertexElementByteSize = 1 * sizeof(XTL::BYTE);
|
||||
NeedPatching = TRUE;
|
||||
break;
|
||||
case XTL::X_D3DVSDT_PBYTE2: // 0x24:
|
||||
|
@ -2083,6 +2125,7 @@ private:
|
|||
HostVertexElementDataType = D3DDECLTYPE_FLOAT2;
|
||||
HostVertexElementByteSize = 2 * sizeof(FLOAT);
|
||||
}
|
||||
XboxVertexElementByteSize = 2 * sizeof(XTL::BYTE);
|
||||
NeedPatching = TRUE;
|
||||
break;
|
||||
case XTL::X_D3DVSDT_PBYTE3: // 0x34:
|
||||
|
@ -2096,6 +2139,7 @@ private:
|
|||
HostVertexElementDataType = D3DDECLTYPE_FLOAT3;
|
||||
HostVertexElementByteSize = 3 * sizeof(FLOAT);
|
||||
}
|
||||
XboxVertexElementByteSize = 3 * sizeof(XTL::BYTE);
|
||||
NeedPatching = TRUE;
|
||||
break;
|
||||
case XTL::X_D3DVSDT_PBYTE4: // 0x44:
|
||||
|
@ -2111,6 +2155,7 @@ private:
|
|||
DbgVshPrintf("D3DVSDT_PBYTE4 /* xbox ext. */");
|
||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
|
||||
HostVertexElementByteSize = 4 * sizeof(FLOAT);
|
||||
XboxVertexElementByteSize = 4 * sizeof(XTL::BYTE);
|
||||
NeedPatching = TRUE;
|
||||
}
|
||||
break;
|
||||
|
@ -2118,11 +2163,12 @@ private:
|
|||
DbgVshPrintf("D3DVSDT_FLOAT2H /* xbox ext. */");
|
||||
HostVertexElementDataType = D3DDECLTYPE_FLOAT4;
|
||||
HostVertexElementByteSize = 4 * sizeof(FLOAT);
|
||||
XboxVertexElementByteSize = 3 * sizeof(FLOAT);
|
||||
NeedPatching = TRUE;
|
||||
break;
|
||||
case XTL::X_D3DVSDT_NONE: // 0x02:
|
||||
DbgVshPrintf("D3DVSDT_NONE /* xbox ext. */");
|
||||
// Ignore token
|
||||
// No host element data, so no patching
|
||||
break;
|
||||
default:
|
||||
DbgVshPrintf("Unknown data type for D3DVSD_REG: 0x%02X\n", XboxVertexElementDataType);
|
||||
|
@ -2134,15 +2180,17 @@ private:
|
|||
// On X_D3DVSDT_NONE skip this token
|
||||
if (XboxVertexElementDataType == XTL::X_D3DVSDT_NONE)
|
||||
{
|
||||
// Xbox elements with X_D3DVSDT_NONE have size zero, so there's no need to register those.
|
||||
// Note, that for skip tokens, we DO call VshConvert_RegisterVertexElement with a X_D3DVSDT_NONE!
|
||||
return;
|
||||
}
|
||||
|
||||
// save patching information
|
||||
CxbxVertexShaderStreamElement *pCurrentElement = &(pCurrentVertexShaderStreamInfo->VertexElements[pCurrentVertexShaderStreamInfo->NumberOfVertexElements]);
|
||||
pCurrentElement->XboxType = XboxVertexElementDataType;
|
||||
pCurrentElement->HostByteSize = HostVertexElementByteSize;
|
||||
pCurrentVertexShaderStreamInfo->NumberOfVertexElements++;
|
||||
pCurrentVertexShaderStreamInfo->NeedPatch |= NeedPatching;
|
||||
VshConvert_RegisterVertexElement(
|
||||
XboxVertexElementDataType,
|
||||
NeedPatching ? XboxVertexElementByteSize : HostVertexElementByteSize,
|
||||
HostVertexElementByteSize,
|
||||
NeedPatching);
|
||||
|
||||
pRecompiled->Stream = pCurrentVertexShaderStreamInfo->CurrentStreamNumber;
|
||||
pRecompiled->Offset = pCurrentVertexShaderStreamInfo->HostVertexStride;
|
||||
|
@ -2154,7 +2202,6 @@ private:
|
|||
pRecompiled++;
|
||||
|
||||
pCurrentVertexShaderStreamInfo->HostVertexStride += HostVertexElementByteSize;
|
||||
|
||||
}
|
||||
|
||||
void VshConvertToken_STREAMDATA(DWORD *pXboxToken)
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
typedef struct _CxbxVertexShaderStreamElement
|
||||
{
|
||||
UINT XboxType; // The stream element data types (xbox)
|
||||
UINT XboxByteSize; // The stream element data sizes (xbox)
|
||||
UINT HostByteSize; // The stream element data sizes (pc)
|
||||
}
|
||||
CxbxVertexShaderStreamElement;
|
||||
|
@ -59,7 +60,7 @@ typedef struct _CxbxVertexShaderStreamInfo
|
|||
WORD HostVertexStride;
|
||||
DWORD NumberOfVertexElements; // Number of the stream data types
|
||||
WORD CurrentStreamNumber;
|
||||
CxbxVertexShaderStreamElement VertexElements[X_VSH_MAX_ATTRIBUTES + 16]; // TODO : Why 16 extrahost additions?)
|
||||
CxbxVertexShaderStreamElement VertexElements[X_VSH_MAX_ATTRIBUTES + 16]; // TODO : Why 16 extra host additions?)
|
||||
}
|
||||
CxbxVertexShaderStreamInfo;
|
||||
|
||||
|
|
Loading…
Reference in New Issue