Merge pull request #1458 from LukeUsher/d3d-tweaks

Various fixes/improvements to D3D HLE
This commit is contained in:
PatrickvL 2018-10-02 13:23:39 +02:00 committed by GitHub
commit 78a49202f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1303 additions and 1173 deletions

@ -1 +1 @@
Subproject commit e562d10d4d88f85a8b5475139c68696dfc6bf231
Subproject commit 5073ab41a88a07eba42877d9285601d319b14067

File diff suppressed because it is too large Load Diff

View File

@ -3439,12 +3439,14 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader)
DWORD *pRecompiledDeclaration = NULL;
DWORD *pRecompiledFunction = NULL;
DWORD VertexShaderSize = 0;
DWORD DeclarationSize = 0;
DWORD OriginalDeclarationSize = 0;
DWORD HostDeclarationSize = 0;
DWORD Handle = 0;
HRESULT hRet = XTL::EmuRecompileVshDeclaration((DWORD*)pDeclaration,
(XTL::D3DVERTEXELEMENT9**)&pRecompiledDeclaration,
&DeclarationSize,
&OriginalDeclarationSize,
&HostDeclarationSize,
pFunction == NULL,
&pVertexShader->VertexShaderInfo);
@ -3470,7 +3472,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader)
g_VertexShaderConstantMode == X_D3DSCM_NORESERVEDCONSTANTS,
&bUseDeclarationOnly,
pRecompiledDeclaration,
DeclarationSize);
HostDeclarationSize);
if (SUCCEEDED(hRet))
{
if (!bUseDeclarationOnly)
@ -3540,14 +3542,15 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader)
free(pRecompiledDeclaration);
pVertexShader->pDeclaration = (DWORD*)g_VMManager.Allocate(DeclarationSize);
memcpy(pVertexShader->pDeclaration, pDeclaration, DeclarationSize);
pVertexShader->pDeclaration = (DWORD*)g_VMManager.Allocate(HostDeclarationSize);
memcpy(pVertexShader->pDeclaration, pDeclaration, HostDeclarationSize);
pVertexShader->FunctionSize = 0;
pVertexShader->pFunction = NULL;
pVertexShader->Type = X_VST_NORMAL;
pVertexShader->Size = (VertexShaderSize - sizeof(VSH_SHADER_HEADER)) / VSH_INSTRUCTION_SIZE_BYTES;
pVertexShader->DeclarationSize = DeclarationSize;
pVertexShader->OriginalDeclarationSize = OriginalDeclarationSize;
pVertexShader->HostDeclarationSize = HostDeclarationSize;
if(SUCCEEDED(hRet))
{
@ -5549,7 +5552,18 @@ VOID __stdcall XTL::EMUPATCH(D3DDevice_SetTextureState_TexCoordIndex_0)
mov Value, eax
}
return EMUPATCH(D3DDevice_SetTextureState_TexCoordIndex)(Stage, Value);
LOG_FUNC_BEGIN
LOG_FUNC_ARG(Stage)
LOG_FUNC_ARG(Value)
LOG_FUNC_END;
if (Value >= 0x00040000) {
EmuLog(LOG_PREFIX, LOG_LEVEL::WARNING, "EmuD3DDevice_SetTextureState_TexCoordIndex: Unknown TexCoordIndex Value (0x%.08X)", Value);
return;
}
HRESULT hRet = g_pD3DDevice->SetTextureStageState(Stage, D3DTSS_TEXCOORDINDEX, Value);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetTextureStageState");
}
// This uses a custom calling convention where parameter is passed in ESI
@ -5595,6 +5609,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTextureState_TexCoordIndex)
LOG_FUNC_ARG(Value)
LOG_FUNC_END;
XB_trampoline(VOID, WINAPI, D3DDevice_SetTextureState_TexCoordIndex, (DWORD, DWORD));
XB_D3DDevice_SetTextureState_TexCoordIndex(Stage, Value);
// TODO: Xbox Direct3D supports sphere mapping OpenGL style.
// BUG FIX: The lower 16 bits were causing false Unknown TexCoordIndex errors.
@ -5619,6 +5636,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_TwoSidedLighting)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_TwoSidedLighting, (DWORD));
XB_D3DDevice_SetRenderState_TwoSidedLighting(Value);
LOG_NOT_SUPPORTED();
}
@ -5642,6 +5662,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_BackFillMode)
// of Direct3D was specifically created to take advantage of certain NVIDIA
// GPU registers and provide more OpenGL-like features IHMO.
LOG_NOT_SUPPORTED();
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_BackFillMode, (DWORD));
XB_D3DDevice_SetRenderState_BackFillMode(Value);
}
// LTCG specific D3DDevice_SetTextureState_BorderColor function...
@ -5659,6 +5682,7 @@ VOID XTL::EMUPATCH(D3DDevice_SetTextureState_BorderColor_0)
mov Value, ebx
}
return EMUPATCH(D3DDevice_SetTextureState_BorderColor)(Stage, Value);
}
@ -5698,6 +5722,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTextureState_BorderColor)
LOG_FUNC_ARG(Value)
LOG_FUNC_END;
XB_trampoline(VOID, WINAPI, D3DDevice_SetTextureState_BorderColor, (DWORD, DWORD));
XB_D3DDevice_SetTextureState_BorderColor(Stage, Value);
HRESULT hRet;
hRet = g_pD3DDevice->SetSamplerState(Stage, D3DSAMP_BORDERCOLOR, Value);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetTextureStageState");
@ -5718,7 +5745,7 @@ VOID XTL::EMUPATCH(D3DDevice_SetTextureState_ColorKeyColor_0)
mov Value, ebx
}
return EMUPATCH(D3DDevice_SetTextureState_ColorKeyColor)(Stage, Value);
LOG_NOT_SUPPORTED();
}
// This uses a custom calling convention where parameter is passed in EAX
@ -5731,7 +5758,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTextureState_ColorKeyColor_4)
DWORD Stage;
__asm mov Stage, eax;
return EMUPATCH(D3DDevice_SetTextureState_ColorKeyColor)(Stage, Value);
LOG_NOT_SUPPORTED();
}
// ******************************************************************
@ -5748,6 +5775,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTextureState_ColorKeyColor)
LOG_FUNC_ARG(Value)
LOG_FUNC_END;
XB_trampoline(VOID, WINAPI, D3DDevice_SetTextureState_ColorKeyColor, (DWORD, DWORD));
XB_D3DDevice_SetTextureState_ColorKeyColor(Stage, Value);
LOG_NOT_SUPPORTED();
}
@ -5814,6 +5844,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTextureState_BumpEnv)
LOG_FUNC_ARG(Value)
LOG_FUNC_END;
XB_trampoline(VOID, WINAPI, D3DDevice_SetTextureState_BumpEnv, (DWORD, X_D3DTEXTURESTAGESTATETYPE, DWORD));
XB_D3DDevice_SetTextureState_BumpEnv(Stage, Type, Value);
HRESULT hRet = D3D_OK;
switch(Type)
@ -5851,6 +5884,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_FrontFace)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_FrontFace, (DWORD));
XB_D3DDevice_SetRenderState_FrontFace(Value);
LOG_NOT_SUPPORTED();
}
@ -5864,6 +5900,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_LogicOp)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_LogicOp, (DWORD));
XB_D3DDevice_SetRenderState_LogicOp(Value);
LOG_NOT_SUPPORTED();
}
@ -5877,6 +5916,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_NormalizeNormals)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_NormalizeNormals, (DWORD));
XB_D3DDevice_SetRenderState_NormalizeNormals(Value);
HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, Value);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState");
}
@ -5891,6 +5933,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_TextureFactor)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_TextureFactor, (DWORD));
XB_D3DDevice_SetRenderState_TextureFactor(Value);
HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_TEXTUREFACTOR, Value);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState");
}
@ -5907,6 +5952,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_ZBias)
HRESULT hRet;
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_ZBias, (DWORD));
XB_D3DDevice_SetRenderState_ZBias(Value);
FLOAT Biased = static_cast<FLOAT>(Value) * -0.000005f;
Value = *reinterpret_cast<const DWORD *>(&Biased);
@ -5924,6 +5972,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_EdgeAntiAlias)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_EdgeAntiAlias, (DWORD));
XB_D3DDevice_SetRenderState_EdgeAntiAlias(Value);
// TODO: Analyze performance and compatibility (undefined behavior on PC with triangles or points)
// HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_EDGEANTIALIAS, Value);
// DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState");
@ -5941,6 +5992,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_FillMode)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_FillMode, (DWORD));
XB_D3DDevice_SetRenderState_FillMode(Value);
DWORD dwFillMode;
if(Value != 0)
@ -5967,6 +6021,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_FogColor)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_FogColor, (DWORD));
XB_D3DDevice_SetRenderState_FogColor(Value);
HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_FOGCOLOR, Value);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState");
}
@ -5981,6 +6038,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_Dxt1NoiseEnable)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_Dxt1NoiseEnable, (DWORD));
XB_D3DDevice_SetRenderState_Dxt1NoiseEnable(Value);
LOG_UNIMPLEMENTED();
}
@ -5998,6 +6058,9 @@ VOID __fastcall XTL::EMUPATCH(D3DDevice_SetRenderState_Simple)
LOG_FUNC_ARG(Value)
LOG_FUNC_END;
XB_trampoline(VOID, __fastcall, D3DDevice_SetRenderState_Simple, (DWORD, DWORD));
XB_D3DDevice_SetRenderState_Simple(Method, Value);
// Special Case: Handle PixelShader related Render States
// TODO: Port over EmuMappedD3DRenderState and related code from Dxbx or Wip_LessVertexPatching
// After this, we don't need to do this part anymore
@ -6207,6 +6270,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_VertexBlend)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_VertexBlend, (DWORD));
XB_D3DDevice_SetRenderState_VertexBlend(Value);
// convert from Xbox direct3d to PC direct3d enumeration
if(Value <= 1) {
Value = Value;
@ -6233,6 +6299,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_PSTextureModes)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_PSTextureModes, (DWORD));
XB_D3DDevice_SetRenderState_PSTextureModes(Value);
XTL::TemporaryPixelShaderRenderStates[XTL::X_D3DRS_PSTEXTUREMODES] = Value;
}
@ -6246,6 +6315,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_CullMode)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_CullMode, (DWORD));
XB_D3DDevice_SetRenderState_CullMode(Value);
// convert from Xbox D3D to PC D3D enumeration
// TODO: XDK-Specific Tables? So far they are the same
switch(Value)
@ -6277,6 +6349,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_LineWidth)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_LineWidth, (DWORD));
XB_D3DDevice_SetRenderState_LineWidth(Value);
// TODO: Convert to PC format??
// g_pD3DDevice->SetRenderState(D3DRS_LINEPATTERN, Value);
LOG_NOT_SUPPORTED();
@ -6292,6 +6367,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_StencilFail)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_StencilFail, (DWORD));
XB_D3DDevice_SetRenderState_StencilFail(Value);
HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_STENCILFAIL, Value);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState");
}
@ -6306,6 +6384,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_OcclusionCullEnable)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_OcclusionCullEnable, (DWORD));
XB_D3DDevice_SetRenderState_OcclusionCullEnable(Value);
LOG_NOT_SUPPORTED();
}
@ -6319,6 +6400,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_StencilCullEnable)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_StencilCullEnable, (DWORD));
XB_D3DDevice_SetRenderState_StencilCullEnable(Value);
LOG_NOT_SUPPORTED();
}
@ -6332,6 +6416,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_RopZCmpAlwaysRead)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_RopZCmpAlwaysRead, (DWORD));
XB_D3DDevice_SetRenderState_RopZCmpAlwaysRead(Value);
LOG_NOT_SUPPORTED();
}
@ -6345,6 +6432,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_RopZRead)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_RopZRead, (DWORD));
XB_D3DDevice_SetRenderState_RopZRead(Value);
LOG_NOT_SUPPORTED();
}
@ -6358,6 +6448,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_DoNotCullUncompressed)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_DoNotCullUncompressed, (DWORD));
XB_D3DDevice_SetRenderState_DoNotCullUncompressed(Value);
LOG_NOT_SUPPORTED();
}
@ -6388,6 +6481,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_StencilEnable)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_StencilEnable, (DWORD));
XB_D3DDevice_SetRenderState_StencilEnable(Value);
HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_STENCILENABLE, Value);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState");
}
@ -6402,6 +6498,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_MultiSampleAntiAlias)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_MultiSampleAntiAlias, (DWORD));
XB_D3DDevice_SetRenderState_MultiSampleAntiAlias(Value);
HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, Value);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState");
}
@ -6416,6 +6515,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_MultiSampleMask)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_MultiSampleMask, (DWORD));
XB_D3DDevice_SetRenderState_MultiSampleMask(Value);
HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, Value);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState");
}
@ -6430,6 +6532,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_MultiSampleMode)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_MultiSampleMode, (DWORD));
XB_D3DDevice_SetRenderState_MultiSampleMode(Value);
LOG_NOT_SUPPORTED();
}
@ -6443,6 +6548,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_MultiSampleRenderTargetMode)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_MultiSampleRenderTargetMode, (DWORD));
XB_D3DDevice_SetRenderState_MultiSampleRenderTargetMode(Value);
LOG_NOT_SUPPORTED();
}
@ -6456,6 +6564,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_ShadowFunc)
{
LOG_FUNC_ONE_ARG(Value);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_ShadowFunc, (DWORD));
XB_D3DDevice_SetRenderState_ShadowFunc(Value);
// ShadowFunc reflects the following Xbox-only extension
//
// typedef enum _D3DRENDERSTATETYPE {
@ -7561,24 +7672,6 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_DrawIndexedVerticesUP)
}
}
// ******************************************************************
// * patch: D3DDevice_GetLight
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_GetLight)
(
DWORD Index,
X_D3DLIGHT8 *pLight
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG(Index)
LOG_FUNC_ARG(pLight)
LOG_FUNC_END;
HRESULT hRet = g_pD3DDevice->GetLight(Index, pLight);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetLight");
}
// ******************************************************************
// * patch: D3DDevice_SetLight
// ******************************************************************
@ -7593,6 +7686,9 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_SetLight)
LOG_FUNC_ARG(pLight)
LOG_FUNC_END;
XB_trampoline(HRESULT, WINAPI, D3DDevice_SetLight, (DWORD, CONST X_D3DLIGHT8*));
XB_D3DDevice_SetLight(Index, pLight);
HRESULT hRet = g_pD3DDevice->SetLight(Index, pLight);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetLight");
@ -7627,6 +7723,9 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_LightEnable)
LOG_FUNC_ARG(bEnable)
LOG_FUNC_END;
XB_trampoline(HRESULT, WINAPI, D3DDevice_LightEnable, (DWORD, BOOL));
XB_D3DDevice_LightEnable(Index, bEnable);
HRESULT hRet = g_pD3DDevice->LightEnable(Index, bEnable);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->LightEnable");
@ -8243,9 +8342,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_LoadVertexShaderProgram)
{
DWORD hNewShader = 0;
// Save the contents of the existing vertex shader programLOG_TEST_CASE(LOG_PREFIX,
DWORD* pDeclaration = (DWORD*) malloc( pVertexShader->DeclarationSize );
memmove( pDeclaration, pVertexShader->pDeclaration, pVertexShader->DeclarationSize );
// Save the contents of the existing vertex shader program
DWORD* pDeclaration = (DWORD*) malloc( pVertexShader->OriginalDeclarationSize );
memmove( pDeclaration, pVertexShader->pDeclaration, pVertexShader->OriginalDeclarationSize);
// Create a new vertex shader with the new
HRESULT hr = EMUPATCH(D3DDevice_CreateVertexShader)( pDeclaration, pFunction, &hNewShader, 0 );
@ -8319,12 +8418,13 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_GetVertexShaderDeclaration)
if (pSizeOfData) {
CxbxVertexShader *pVertexShader = MapXboxVertexShaderHandleToCxbxVertexShader(Handle);
if (pVertexShader) {
if (*pSizeOfData < pVertexShader->DeclarationSize || !pData) {
*pSizeOfData = pVertexShader->DeclarationSize;
DWORD sizeOfData = pVertexShader->OriginalDeclarationSize * sizeof(DWORD);
if (*pSizeOfData < sizeOfData || !pData) {
*pSizeOfData = sizeOfData;
hRet = !pData ? D3D_OK : D3DERR_MOREDATA;
}
else {
memcpy(pData, pVertexShader->pDeclaration, pVertexShader->DeclarationSize);
memcpy(pData, pVertexShader->pDeclaration, pVertexShader->OriginalDeclarationSize);
hRet = D3D_OK;
}
}
@ -8756,6 +8856,9 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_SampleAlpha)
{
LOG_FUNC_ONE_ARG(dwSampleAlpha);
XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_SampleAlpha, (DWORD));
XB_D3DDevice_SetRenderState_SampleAlpha(dwSampleAlpha);
// TODO: Implement?
LOG_UNIMPLEMENTED();

View File

@ -2811,207 +2811,225 @@ VOID __fastcall XTL::EMUPATCH(D3DDevice_SetRenderState_Deferred)
}
// ******************************************************************
// * patch: D3DDevice_GetViewport
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_GetViewport)
(
X_D3DVIEWPORT8 *pViewport
)
{
FUNC_EXPORTS
LOG_FUNC_ONE_ARG(pViewport);
D3DVIEWPORT HostViewPort;
HRESULT hRet = g_pD3DDevice->GetViewport(&HostViewPort);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetViewport");
if (!g_ScaleViewport) {
*pViewport = HostViewPort;
}
else {
// Note : We cannot return the Xbox viewport as set in EMUPATCH(D3DDevice_SetViewport)
// because various Xbox D3D functions reset the Xbox viewport. Since we call comparable
// functions on host D3D, the host viewport is better suited as a return value;
// We just need to scale the host viewport back to Xbox dimensions - the exact opposite
// operation from the up-scaling that happens in EMUPATCH(D3DDevice_SetViewport).
// Get current host render target dimensions
DWORD HostRenderTarget_Width;
DWORD HostRenderTarget_Height;
if (GetHostRenderTargetDimensions(&HostRenderTarget_Width, &HostRenderTarget_Height)) {
// Get current Xbox render target dimensions
DWORD XboxRenderTarget_Width = GetPixelContainerWidth(g_pXboxRenderTarget);
DWORD XboxRenderTarget_Height = GetPixelContainerHeigth(g_pXboxRenderTarget);
// Scale host back to Xbox dimensions (avoiding hard-coding 640 x 480)
pViewport->X = ScaleDWORD(HostViewPort.X, HostRenderTarget_Width, XboxRenderTarget_Width);
pViewport->Y = ScaleDWORD(HostViewPort.Y, HostRenderTarget_Height, XboxRenderTarget_Height);
pViewport->Width = ScaleDWORD(HostViewPort.Width, HostRenderTarget_Width, XboxRenderTarget_Width);
pViewport->Height = ScaleDWORD(HostViewPort.Height, HostRenderTarget_Height, XboxRenderTarget_Height);
pViewport->MinZ = HostViewPort.MinZ; // No need scale Z for now
pViewport->MaxZ = HostViewPort.MaxZ;
}
else {
*pViewport = HostViewPort;
EmuWarning("GetHostRenderTargetDimensions failed - GetViewport returns host viewport instead!");
}
}
}
// ******************************************************************
// * patch: D3D_BlockOnResource
// ******************************************************************
void WINAPI XTL::EMUPATCH(D3D_BlockOnResource)( X_D3DResource* pResource )
{
FUNC_EXPORTS
LOG_FUNC_ONE_ARG(pResource);
// TODO: Implement
// NOTE: Azurik appears to call this directly from numerous points
LOG_UNIMPLEMENTED();
}
// ******************************************************************
// * patch: IDirect3DResource8_IsBusy
// ******************************************************************
BOOL WINAPI XTL::EMUPATCH(D3DResource_IsBusy)
(
X_D3DResource *pThis
)
{
FUNC_EXPORTS
/* too much output
LOG_FUNC_ONE_ARG(pThis);
//*/
return FALSE;
}
// ******************************************************************
// * patch: D3DDevice_SetScissors
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_SetScissors)
(
DWORD Count,
BOOL Exclusive,
CONST D3DRECT *pRects
)
{
FUNC_EXPORTS
LOG_FUNC_BEGIN
LOG_FUNC_ARG(Count)
LOG_FUNC_ARG(Exclusive)
LOG_FUNC_ARG(pRects)
LOG_FUNC_END;
// TODO: Implement
LOG_UNIMPLEMENTED();
}
// ******************************************************************
// * patch: D3DDevice_GetScissors
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_GetScissors)
(
DWORD *pCount,
BOOL *pExclusive,
D3DRECT *pRects
)
{
FUNC_EXPORTS
LOG_FUNC_BEGIN
LOG_FUNC_ARG(pCount)
LOG_FUNC_ARG(pExclusive)
LOG_FUNC_ARG(pRects)
LOG_FUNC_END;
// TODO: Save a copy of each scissor rect in case this function is called
// in conjunction with D3DDevice::SetScissors. So far, only Outrun2 uses
// this function. For now, just return the values within the current
// viewport.
D3DVIEWPORT vp;
HRESULT hRet = g_pD3DDevice->GetViewport( &vp );
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetViewport");
pRects->x1 = pRects->y1 = 0;
pRects->x2 = vp.Width;
pRects->y2 = vp.Height;
pExclusive[0] = FALSE;
}
// ******************************************************************
// * patch: D3DDevice_SetBackMaterial
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_SetBackMaterial)
(
X_D3DMATERIAL8* pMaterial
)
{
FUNC_EXPORTS
LOG_FUNC_ONE_ARG(pMaterial);
LOG_NOT_SUPPORTED();
}
// ******************************************************************
// * patch: D3DDevice_GetBackMaterial
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_GetBackMaterial)
(
X_D3DMATERIAL8* pMaterial
)
{
FUNC_EXPORTS
LOG_FUNC_ONE_ARG(pMaterial);
LOG_NOT_SUPPORTED();
HRESULT hRet = D3D_OK;
// TODO: HACK: This is wrong, but better than nothing, right?
if (pMaterial)
{
hRet = g_pD3DDevice->GetMaterial(pMaterial);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetMaterial");
}
if (FAILED(hRet))
{
EmuWarning("We're lying about getting a back material!");
hRet = D3D_OK;
}
}
// ******************************************************************
// * patch: D3DDevice_SetRenderState_YuvEnable
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_YuvEnable)
(
BOOL Enable
)
{
LOG_FUNC_ONE_ARG(Enable);
g_bColorSpaceConvertYuvToRgb = (Enable != FALSE);
}
// ******************************************************************
// * patch: D3DDevice_GetViewport
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_GetViewport)
(
X_D3DVIEWPORT8 *pViewport
)
{
FUNC_EXPORTS
LOG_FUNC_ONE_ARG(pViewport);
D3DVIEWPORT HostViewPort;
HRESULT hRet = g_pD3DDevice->GetViewport(&HostViewPort);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetViewport");
if (!g_ScaleViewport) {
*pViewport = HostViewPort;
}
else {
// Note : We cannot return the Xbox viewport as set in EMUPATCH(D3DDevice_SetViewport)
// because various Xbox D3D functions reset the Xbox viewport. Since we call comparable
// functions on host D3D, the host viewport is better suited as a return value;
// We just need to scale the host viewport back to Xbox dimensions - the exact opposite
// operation from the up-scaling that happens in EMUPATCH(D3DDevice_SetViewport).
// Get current host render target dimensions
DWORD HostRenderTarget_Width;
DWORD HostRenderTarget_Height;
if (GetHostRenderTargetDimensions(&HostRenderTarget_Width, &HostRenderTarget_Height)) {
// Get current Xbox render target dimensions
DWORD XboxRenderTarget_Width = GetPixelContainerWidth(g_pXboxRenderTarget);
DWORD XboxRenderTarget_Height = GetPixelContainerHeigth(g_pXboxRenderTarget);
// Scale host back to Xbox dimensions (avoiding hard-coding 640 x 480)
pViewport->X = ScaleDWORD(HostViewPort.X, HostRenderTarget_Width, XboxRenderTarget_Width);
pViewport->Y = ScaleDWORD(HostViewPort.Y, HostRenderTarget_Height, XboxRenderTarget_Height);
pViewport->Width = ScaleDWORD(HostViewPort.Width, HostRenderTarget_Width, XboxRenderTarget_Width);
pViewport->Height = ScaleDWORD(HostViewPort.Height, HostRenderTarget_Height, XboxRenderTarget_Height);
pViewport->MinZ = HostViewPort.MinZ; // No need scale Z for now
pViewport->MaxZ = HostViewPort.MaxZ;
}
else {
*pViewport = HostViewPort;
EmuWarning("GetHostRenderTargetDimensions failed - GetViewport returns host viewport instead!");
}
}
}
// ******************************************************************
// * patch: D3D_BlockOnResource
// ******************************************************************
void WINAPI XTL::EMUPATCH(D3D_BlockOnResource)( X_D3DResource* pResource )
{
FUNC_EXPORTS
LOG_FUNC_ONE_ARG(pResource);
// TODO: Implement
// NOTE: Azurik appears to call this directly from numerous points
LOG_UNIMPLEMENTED();
}
// ******************************************************************
// * patch: IDirect3DResource8_IsBusy
// ******************************************************************
BOOL WINAPI XTL::EMUPATCH(D3DResource_IsBusy)
(
X_D3DResource *pThis
)
{
FUNC_EXPORTS
/* too much output
LOG_FUNC_ONE_ARG(pThis);
//*/
return FALSE;
}
// ******************************************************************
// * patch: D3DDevice_SetScissors
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_SetScissors)
(
DWORD Count,
BOOL Exclusive,
CONST D3DRECT *pRects
)
{
FUNC_EXPORTS
LOG_FUNC_BEGIN
LOG_FUNC_ARG(Count)
LOG_FUNC_ARG(Exclusive)
LOG_FUNC_ARG(pRects)
LOG_FUNC_END;
// TODO: Implement
LOG_UNIMPLEMENTED();
}
// ******************************************************************
// * patch: D3DDevice_GetScissors
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_GetScissors)
(
DWORD *pCount,
BOOL *pExclusive,
D3DRECT *pRects
)
{
FUNC_EXPORTS
LOG_FUNC_BEGIN
LOG_FUNC_ARG(pCount)
LOG_FUNC_ARG(pExclusive)
LOG_FUNC_ARG(pRects)
LOG_FUNC_END;
// TODO: Save a copy of each scissor rect in case this function is called
// in conjunction with D3DDevice::SetScissors. So far, only Outrun2 uses
// this function. For now, just return the values within the current
// viewport.
D3DVIEWPORT vp;
HRESULT hRet = g_pD3DDevice->GetViewport( &vp );
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetViewport");
pRects->x1 = pRects->y1 = 0;
pRects->x2 = vp.Width;
pRects->y2 = vp.Height;
pExclusive[0] = FALSE;
}
// ******************************************************************
// * patch: D3DDevice_SetBackMaterial
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_SetBackMaterial)
(
X_D3DMATERIAL8* pMaterial
)
{
FUNC_EXPORTS
LOG_FUNC_ONE_ARG(pMaterial);
LOG_NOT_SUPPORTED();
}
// ******************************************************************
// * patch: D3DDevice_GetBackMaterial
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_GetBackMaterial)
(
X_D3DMATERIAL8* pMaterial
)
{
FUNC_EXPORTS
LOG_FUNC_ONE_ARG(pMaterial);
LOG_NOT_SUPPORTED();
HRESULT hRet = D3D_OK;
// TODO: HACK: This is wrong, but better than nothing, right?
if (pMaterial)
{
hRet = g_pD3DDevice->GetMaterial(pMaterial);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetMaterial");
}
if (FAILED(hRet))
{
EmuWarning("We're lying about getting a back material!");
hRet = D3D_OK;
}
}
// ******************************************************************
// * patch: D3DDevice_SetRenderState_YuvEnable
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_YuvEnable)
(
BOOL Enable
)
{
LOG_FUNC_ONE_ARG(Enable);
g_bColorSpaceConvertYuvToRgb = (Enable != FALSE);
}
// ******************************************************************
// * patch: D3DDevice_GetLight
// ******************************************************************
VOID WINAPI XTL::EMUPATCH(D3DDevice_GetLight)
(
DWORD Index,
X_D3DLIGHT8 *pLight
)
{
LOG_FUNC_BEGIN
LOG_FUNC_ARG(Index)
LOG_FUNC_ARG(pLight)
LOG_FUNC_END;
HRESULT hRet = g_pD3DDevice->GetLight(Index, pLight);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetLight");
}

View File

@ -201,7 +201,7 @@ inline D3DSTENCILOP EmuXB2PC_D3DSTENCILOP(X_D3DSTENCILOP Value)
return D3DSTENCILOP_DECR;
default:
CxbxKrnlCleanup(LOG_PREFIX_D3DCVT, "Unknown D3DSTENCILOP (0x%.08X)", Value);
EmuLog(LOG_PREFIX_D3DCVT, LOG_LEVEL::WARNING, "Unknown D3DSTENCILOP (0x%.08X)", Value);
}
return (D3DSTENCILOP) Value;

View File

@ -516,8 +516,9 @@ typedef struct _CxbxVertexShader
// we save them to be able to return them when necessary.
UINT Size;
DWORD *pDeclaration;
DWORD OriginalDeclarationSize;
XTL::LPDIRECT3DVERTEXDECLARATION9 pHostDeclaration;
DWORD DeclarationSize;
DWORD HostDeclarationSize;
DWORD *pFunction;
DWORD FunctionSize;
DWORD Type;

View File

@ -2361,7 +2361,8 @@ DWORD XTL::EmuRecompileVshDeclaration
(
DWORD *pDeclaration,
D3DVERTEXELEMENT **ppRecompiledDeclaration,
DWORD *pDeclarationSize,
DWORD *pOriginalDeclarationSize,
DWORD *pHostDeclarationSize,
boolean IsFixedFunction,
CxbxVertexShaderInfo *pVertexShaderInfo
)
@ -2378,6 +2379,8 @@ DWORD XTL::EmuRecompileVshDeclaration
// Calculate size of declaration
DWORD DeclarationSize = VshGetDeclarationSize(pDeclaration);
*pOriginalDeclarationSize = DeclarationSize;
// For Direct3D9, we need to reserve at least twice the number of elements, as one token can generate two registers (in and out) :
DeclarationSize *= sizeof(D3DVERTEXELEMENT) * 2;
@ -2386,7 +2389,7 @@ DWORD XTL::EmuRecompileVshDeclaration
uint8_t *pRecompiledBufferOverflow = ((uint8_t*)pRecompiled) + DeclarationSize;
*ppRecompiledDeclaration = pRecompiled;
*pDeclarationSize = DeclarationSize;
*pHostDeclarationSize = DeclarationSize;
CxbxVertexShaderPatch PatchData = { 0 };
PatchData.pVertexShaderInfoToSet = pVertexShaderInfo;

View File

@ -54,7 +54,8 @@ extern DWORD EmuRecompileVshDeclaration
(
DWORD *pDeclaration,
D3DVERTEXELEMENT **ppRecompiledDeclaration,
DWORD *pDeclarationSize,
DWORD *pOriginalDeclarationSize,
DWORD *pHostDeclarationSize,
boolean IsFixedFunction,
XTL::CxbxVertexShaderInfo *pVertexShaderInfo
);

View File

@ -91,7 +91,6 @@ std::map<const std::string, const xbox_patch_t> g_PatchTable = {
PATCH_ENTRY("D3DDevice_GetBackBuffer2", XTL::EMUPATCH(D3DDevice_GetBackBuffer2), PATCH_HLE_D3D),
PATCH_ENTRY("D3DDevice_GetDisplayFieldStatus", XTL::EMUPATCH(D3DDevice_GetDisplayFieldStatus), PATCH_HLE_D3D),
PATCH_ENTRY("D3DDevice_GetGammaRamp", XTL::EMUPATCH(D3DDevice_GetGammaRamp), PATCH_HLE_D3D),
PATCH_ENTRY("D3DDevice_GetLight", XTL::EMUPATCH(D3DDevice_GetLight), PATCH_HLE_D3D),
PATCH_ENTRY("D3DDevice_GetMaterial", XTL::EMUPATCH(D3DDevice_GetMaterial), PATCH_HLE_D3D),
PATCH_ENTRY("D3DDevice_GetModelView", XTL::EMUPATCH(D3DDevice_GetModelView), PATCH_HLE_D3D),
PATCH_ENTRY("D3DDevice_GetOverlayUpdateStatus", XTL::EMUPATCH(D3DDevice_GetOverlayUpdateStatus), PATCH_HLE_D3D),
@ -438,7 +437,12 @@ void EmuInstallPatches()
void* GetPatchedFunctionTrampoline(std::string functionName)
{
if (g_FunctionHooks.find(functionName) != g_FunctionHooks.end()) {
return g_FunctionHooks[functionName].GetTrampoline();
auto trampoline = g_FunctionHooks[functionName].GetTrampoline();
if (trampoline == nullptr) {
EmuLog(CXBXR_MODULE::HLE, LOG_LEVEL::WARNING, "Failed to get XB_Trampoline for %s", functionName.c_str());
}
return trampoline;
}
return nullptr;