Vertex shader stuff

This commit is contained in:
sopskrutt 2004-03-16 18:47:34 +00:00
parent 10e8fddb1c
commit c9880b4287
5 changed files with 158 additions and 38 deletions

View File

@ -1103,6 +1103,15 @@ BYTE* WINAPI EmuIDirect3DVertexBuffer8_Lock2
DWORD Flags
);
// ******************************************************************
// * func: EmuIDirect3DDevice8_GetStreamSource2
// ******************************************************************
XTL::X_D3DVertexBuffer* WINAPI EmuIDirect3DDevice8_GetStreamSource2
(
UINT StreamNumber,
UINT *pStride
);
// ******************************************************************
// * func: EmuIDirect3DDevice8_SetStreamSource
// ******************************************************************

View File

@ -34,7 +34,7 @@
#ifndef VERTEXSHADER_H
#define VERTEXSHADER_H
//#define _DEBUG_VSH
#define _DEBUG_VSH
// nv2a microcode header
typedef struct
@ -68,6 +68,8 @@ extern HRESULT EmuRecompileVshFunction
boolean bNoReservedConstants
);
extern void FreeVertexDynamicPatch(VERTEX_SHADER *pVertexShader);
inline boolean VshHandleIsVertexShader(DWORD Handle) { return (Handle & 0x80000000) ? TRUE : FALSE; }
inline X_D3DVertexShader *VshHandleGetVertexShader(DWORD Handle) { return (X_D3DVertexShader *)(Handle & 0x7FFFFFFF); }

View File

@ -2095,7 +2095,7 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_CreateVertexShader
pFunction == NULL,
&pVertexShader->VertexDynamicPatch);
if(SUCCEEDED(hRet))
if(SUCCEEDED(hRet) && pFunction)
{
hRet = XTL::EmuRecompileVshFunction((DWORD*)pFunction,
&pRecompiledBuffer,
@ -2105,6 +2105,12 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_CreateVertexShader
{
pRecompiledFunction = (DWORD*)pRecompiledBuffer->GetBufferPointer();
}
else
{
pRecompiledFunction = NULL;
EmuWarning("Couldn't recompile vertex shader function.\n");
hRet = D3D_OK; // Try using a fixed function vertex shader instead
}
}
//DbgPrintf("MaxVertexShaderConst = %d\n", g_D3DCaps.MaxVertexShaderConst);
@ -2121,9 +2127,21 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_CreateVertexShader
if(pRecompiledBuffer)
{
pRecompiledBuffer->Release();
pRecompiledBuffer = NULL;
}
}
free(pRecompiledDeclaration);
pVertexShader->pDeclaration = (DWORD*)malloc(DeclarationSize);
memcpy(pVertexShader->pDeclaration, pDeclaration, DeclarationSize);
pVertexShader->FunctionSize = 0;
pVertexShader->pFunction = NULL;
pVertexShader->Type = X_D3DSMT_VERTEXSHADER;
pVertexShader->Size = (VertexShaderSize - sizeof(VSH_SHADER_HEADER)) / VSH_INSTRUCTION_SIZE_BYTES;
pVertexShader->DeclarationSize = DeclarationSize;
if(SUCCEEDED(hRet))
{
if(pFunction != NULL)
@ -2137,39 +2155,38 @@ HRESULT WINAPI XTL::EmuIDirect3DDevice8_CreateVertexShader
pVertexShader->pFunction = NULL;
pVertexShader->FunctionSize = 0;
}
pVertexShader->pDeclaration = (DWORD*)malloc(DeclarationSize);
memcpy(pVertexShader->pDeclaration, pDeclaration, DeclarationSize);
pVertexShader->Type = X_D3DSMT_VERTEXSHADER;
pVertexShader->Handle = Handle;
pVertexShader->Size = (VertexShaderSize - sizeof(VSH_SHADER_HEADER)) / VSH_INSTRUCTION_SIZE_BYTES;
pVertexShader->DeclarationSize = DeclarationSize;
}
else
{
pVertexShader->Handle = D3DFVF_XYZ/* | D3DFVF_TEX0*/;
pVertexShader->Handle = D3DFVF_XYZ | D3DFVF_TEX0;
}
pD3DVertexShader->Handle = (DWORD)pVertexShader;
*pHandle = ((DWORD)pD3DVertexShader) | 0x80000000;
#ifdef _DEBUG_VSH
if(FAILED(hRet))
{
char pFileName[30];
static int FailedShaderCount = 0;
VSH_SHADER_HEADER *pHeader = (VSH_SHADER_HEADER*)pFunction;
EmuWarning("Couldn't create vertex shader!");
sprintf(pFileName, "failed%05d.xvu", FailedShaderCount);
FILE *f = fopen(pFileName, "wb");
if(f)
#ifdef _DEBUG_VSH
if (pFunction)
{
fwrite(pFunction, sizeof(VSH_SHADER_HEADER) + pHeader->NumInst * 16, 1, f);
fclose(f);
char pFileName[30];
static int FailedShaderCount = 0;
VSH_SHADER_HEADER *pHeader = (VSH_SHADER_HEADER*)pFunction;
EmuWarning("Couldn't create vertex shader!");
sprintf(pFileName, "failed%05d.xvu", FailedShaderCount);
FILE *f = fopen(pFileName, "wb");
if(f)
{
fwrite(pFunction, sizeof(VSH_SHADER_HEADER) + pHeader->NumInst * 16, 1, f);
fclose(f);
}
FailedShaderCount++;
}
FailedShaderCount++;
//hRet = D3D_OK;
}
#endif // _DEBUG_VSH
hRet = D3D_OK;
}
EmuSwapFS(); // XBox FS
@ -6048,6 +6065,33 @@ BYTE* WINAPI XTL::EmuIDirect3DVertexBuffer8_Lock2
return pbData;
}
// ******************************************************************
// * func: EmuIDirect3DDevice8_GetStreamSource2
// ******************************************************************
XTL::X_D3DVertexBuffer* WINAPI XTL::EmuIDirect3DDevice8_GetStreamSource2
(
UINT StreamNumber,
UINT *pStride
)
{
EmuSwapFS();
// debug trace
DbgPrintf( "EmuD3D8 (0x%.08X): EmuIDirect3DDevice8_GetStreamSource2\n"
"(\n"
" StreamNumber : 0x%.08X\n"
" pStride : 0x%.08X\n"
");\n",
GetCurrentThreadId(), StreamNumber, pStride);
EmuWarning("Not correctly implemented yet!");
X_D3DVertexBuffer* pVertexBuffer;
g_pD3DDevice8->GetStreamSource(StreamNumber, (struct XTL::IDirect3DVertexBuffer8 **)&pVertexBuffer, pStride);
EmuSwapFS();
return pVertexBuffer;
}
// ******************************************************************
// * func: EmuIDirect3DDevice8_SetStreamSource
// ******************************************************************
@ -6764,13 +6808,8 @@ VOID WINAPI XTL::EmuIDirect3DDevice8_DeleteVertexShader
free(pVertexShader->pFunction);
}
// TODO: Also free the dynamic streams patches!
for(DWORD i = 0; i < pVertexShader->VertexDynamicPatch.NbrStreams; i++)
{
free(pVertexShader->VertexDynamicPatch.pStreamPatches[i].pTypes);
}
FreeVertexDynamicPatch(pVertexShader);
free(pVertexShader->VertexDynamicPatch.pStreamPatches);
free(pVertexShader);
free(pD3DVertexShader);
}

View File

@ -461,8 +461,8 @@ static inline boolean HasMACO(VSH_SHADER_INSTRUCTION *pInstruction)
static inline boolean HasMACARL(VSH_SHADER_INSTRUCTION *pInstruction)
{
return !IsInUse(pInstruction->Output.OutputMask) &&
pInstruction->Output.OutputMux == OMUX_MAC &&
return /*!IsInUse(pInstruction->Output.OutputMask) &&
pInstruction->Output.OutputMux == OMUX_MAC &&*/
pInstruction->MAC == MAC_ARL;
}
@ -852,6 +852,8 @@ static VSH_INTERMEDIATE_FORMAT *VshNewIntermediate(VSH_XBOX_SHADER *pShader)
{
VshVerifyBufferBounds(pShader);
ZeroMemory(&pShader->Intermediate[pShader->IntermediateCount], sizeof(VSH_INTERMEDIATE_FORMAT));
return &pShader->Intermediate[pShader->IntermediateCount++];
}
@ -1185,6 +1187,13 @@ static boolean VshConvertShader(VSH_XBOX_SHADER *pShader,
// Combining not supported in vs.1.1
pIntermediate->IsCombined = FALSE;
/*
if(pIntermediate->Output.Type == IMD_OUTPUT_O && pIntermediate->Output.Address == OREG_OFOG)
{
// The PC shader assembler doesn't like masks on scalar registers
VshSetOutputMask(&pIntermediate->Output, TRUE, TRUE, TRUE, TRUE);
}*/
if(pIntermediate->InstructionType == IMD_ILU && pIntermediate->ILU == ILU_RCC)
{
// Convert rcc to rcp
@ -1355,42 +1364,55 @@ DWORD Xb2PCRegisterType(DWORD VertexRegister)
case -1:
DbgVshPrintf("D3DVSDE_VERTEX /* xbox ext. */");
PCRegisterType = -1;
break;
case 0:
DbgVshPrintf("D3DVSDE_POSITION");
PCRegisterType = D3DVSDE_POSITION;
break;
case 1:
DbgVshPrintf("D3DVSDE_BLENDWEIGHT");
PCRegisterType = D3DVSDE_BLENDWEIGHT;
break;
case 2:
DbgVshPrintf("D3DVSDE_NORMAL");
PCRegisterType = D3DVSDE_NORMAL;
break;
case 3:
DbgVshPrintf("D3DVSDE_DIFFUSE");
PCRegisterType = D3DVSDE_DIFFUSE;
break;
case 4:
DbgVshPrintf("D3DVSDE_SPECULAR");
PCRegisterType = D3DVSDE_SPECULAR;
break;
case 5:
DbgVshPrintf("D3DVSDE_FOG /* xbox ext. */");
PCRegisterType = -1;
break;
case 7:
DbgVshPrintf("D3DVSDE_BACKDIFFUSE /* xbox ext. */");
PCRegisterType = -1;
break;
case 8:
DbgVshPrintf("D3DVSDE_BACKSPECULAR /* xbox ext. */");
PCRegisterType = -1;
break;
case 9:
DbgVshPrintf("D3DVSDE_TEXCOORD0");
PCRegisterType = D3DVSDE_TEXCOORD0;
break;
case 10:
DbgVshPrintf("D3DVSDE_TEXCOORD1");
PCRegisterType = D3DVSDE_TEXCOORD1;
break;
case 11:
DbgVshPrintf("D3DVSDE_TEXCOORD2");
PCRegisterType = D3DVSDE_TEXCOORD2;
break;
case 12:
DbgVshPrintf("D3DVSDE_TEXCOORD3");
PCRegisterType = D3DVSDE_TEXCOORD3;
break;
default:
DbgVshPrintf("%d /* unknown register */", VertexRegister);
PCRegisterType = -1;
@ -1523,9 +1545,9 @@ static boolean VshAddStreamPatch(VSH_PATCH_DATA *pPatchData)
pStreamPatch->ConversionStride = pPatchData->ConversionStride;
pStreamPatch->NbrTypes = pPatchData->TypePatchData.NbrTypes;
pStreamPatch->NeedPatch = pStreamPatch->NeedPatch;
pStreamPatch->pTypes = (UINT *)malloc(pPatchData->TypePatchData.NbrTypes);
memcpy(pStreamPatch->pTypes, pPatchData->TypePatchData.Types, pPatchData->TypePatchData.NbrTypes);
pStreamPatch->NeedPatch = pPatchData->NeedPatching;
pStreamPatch->pTypes = (UINT *)malloc(pPatchData->TypePatchData.NbrTypes * sizeof(VSH_TYPE_PATCH_DATA));
memcpy(pStreamPatch->pTypes, pPatchData->TypePatchData.Types, pPatchData->TypePatchData.NbrTypes * sizeof(VSH_TYPE_PATCH_DATA));
return TRUE;
}
@ -1927,12 +1949,17 @@ extern HRESULT XTL::EmuRecompileVshFunction
DbgVshPrintf("%s", pShaderDisassembly);
DbgVshPrintf("-----------------------\n");
HRESULT Result = D3DXAssembleShader(pShaderDisassembly,
strlen(pShaderDisassembly),
D3DXASM_SKIPVALIDATION,
NULL,
ppRecompiled,
NULL);
hRet = D3DXAssembleShader(pShaderDisassembly,
strlen(pShaderDisassembly),
D3DXASM_SKIPVALIDATION,
NULL,
ppRecompiled,
NULL);
if (FAILED(hRet))
{
EmuWarning("Couldn't assemble recompiled vertex shader\n");
}
free(pShaderDisassembly);
}
@ -1940,3 +1967,14 @@ extern HRESULT XTL::EmuRecompileVshFunction
return hRet;
}
extern void XTL::FreeVertexDynamicPatch(VERTEX_SHADER *pVertexShader)
{
for (DWORD i = 0; i < pVertexShader->VertexDynamicPatch.NbrStreams; i++)
{
free(pVertexShader->VertexDynamicPatch.pStreamPatches[i].pTypes);
}
free(pVertexShader->VertexDynamicPatch.pStreamPatches);
pVertexShader->VertexDynamicPatch.pStreamPatches = NULL;
pVertexShader->VertexDynamicPatch.NbrStreams = 0;
}

View File

@ -2440,6 +2440,28 @@ SOOVPA<8> X_D3DDevice_SetVertexShaderInput_1_0_4627 =
}
};
// ******************************************************************
// * D3DDevice_GetStreamSource2 (Maybe same in older versions)
// ******************************************************************
SOOVPA<7> X_D3DDevice_GetStreamSource2_1_0_4627 =
{
0, // Large == 0
7, // Count == 7
-1, // Xref Not Saved
0, // Xref Not Used
{
{ 0x06, 0x34 },
{ 0x12, 0x85 },
{ 0x16, 0x57 },
{ 0x22, 0x8B },
{ 0x26, 0x89 },
{ 0x2E, 0x00 },
{ 0x36, 0x89 },
}
};
// ******************************************************************
// * D3D8_1_0_4627
// ******************************************************************
@ -3131,6 +3153,16 @@ OOVPATable D3D8_1_0_4627[] =
"EmuIDirect3DDevice8_GetTransform"
#endif
},
// D3DDevice_GetStreamSource2
{
(OOVPA*)&X_D3DDevice_GetStreamSource2_1_0_4627,
XTL::EmuIDirect3DDevice8_GetStreamSource2,
#ifdef _DEBUG_TRACE
"D3DDevice_GetStreamSource2"
#endif
},
// IDirect3DDevice8::SetStreamSource (* unchanged since 4361 *)
{
(OOVPA*)&IDirect3DDevice8_SetStreamSource_1_0_4361,