Merge pull request #1783 from PatrickvL/impl

Introduce two CxbxImpl_*'s for as-yet unimplemented functions.
This commit is contained in:
Luke Usher 2019-11-20 15:56:40 +00:00 committed by GitHub
commit 8be7402227
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 88 additions and 47 deletions

View File

@ -141,6 +141,13 @@ static bool g_bHack_DisableHostGPUQueries = false; // TO
static IDirect3DQuery *g_pHostQueryWaitForIdle = nullptr;
static IDirect3DQuery *g_pHostQueryCallbackEvent = nullptr;
// Vertex shader symbols, declared in XbVertexShader.cpp :
extern void CxbxImpl_SelectVertexShaderDirect(XTL::X_VERTEXATTRIBUTEFORMAT* pVAF, DWORD Address);
extern void CxbxImpl_SetVertexShaderInput(DWORD Handle, UINT StreamCount, XTL::X_STREAMINPUT* pStreamInputs);
// Vertex buffer symbols, declared in XbVertexBuffer.cpp
extern void CxbxImpl_SetStreamSource(UINT StreamNumber, XTL::X_D3DVertexBuffer* pStreamData, UINT Stride);
static std::condition_variable g_VBConditionVariable; // Used in BlockUntilVerticalBlank
static std::mutex g_VBConditionMutex; // Used in BlockUntilVerticalBlank
static DWORD g_VBLastSwap = 0;
@ -173,9 +180,6 @@ static XTL::DWORD *g_Xbox_D3DDevice; // TODO: This should be a
static DWORD g_dwVertexShaderUsage = 0; // Unused. If needed, move to XbVertexShader.cpp
*/
// Active D3D Vertex Streams (and strides)
XTL::X_D3DVertexBuffer *g_D3DStreams[16];
XTL::UINT g_D3DStreamStrides[16];
static XTL::DWORD g_VertexShaderSlots[X_VSH_MAX_INSTRUCTION_COUNT];
XTL::DWORD g_Xbox_VertexShader_Handle = 0;
@ -3420,7 +3424,7 @@ XTL::X_D3DSurface* WINAPI XTL::EMUPATCH(D3DDevice_GetBackBuffer2)
/** unsafe, somehow
HRESULT hRet = D3D_OK;
X_D3DSurface *pBackBuffer = EmuNewD3DSurface();
X_D3DSurface *pXboxBackBuffer = EmuNewD3DSurface();
if(BackBuffer == -1) {
static IDirect3DSurface *pCachedPrimarySurface = nullptr;
@ -3432,21 +3436,21 @@ XTL::X_D3DSurface* WINAPI XTL::EMUPATCH(D3DDevice_GetBackBuffer2)
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateOffscreenPlainSurface");
}
SetHostSurface(pBackBuffer, pCachedPrimarySurface);
SetHostSurface(pXboxBackBuffer, pCachedPrimarySurface);
hRet = g_pD3DDevice->GetFrontBuffer(pCachedPrimarySurface);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetFrontBuffer");
if (FAILED(hRet)) {
EmuLog(LOG_LEVEL::WARNING, "Could not retrieve primary surface, using backbuffer");
SetHostSurface(pBackBuffer, nullptr);
SetHostSurface(pXboxBackBuffer, nullptr);
pCachedPrimarySurface->Release();
pCachedPrimarySurface = nullptr;
BackBuffer = 0;
}
// Debug: Save this image temporarily
//D3DXSaveSurfaceToFile("C:\\Aaron\\Textures\\FrontBuffer.bmp", D3DXIFF_BMP, GetHostSurface(pBackBuffer), nullptr, nullptr);
//D3DXSaveSurfaceToFile("C:\\Aaron\\Textures\\FrontBuffer.bmp", D3DXIFF_BMP, GetHostSurface(pXboxBackBuffer), nullptr, nullptr);
}
if(BackBuffer != -1) {
@ -3457,7 +3461,7 @@ XTL::X_D3DSurface* WINAPI XTL::EMUPATCH(D3DDevice_GetBackBuffer2)
}
//*/
static X_D3DSurface *pBackBuffer = EmuNewD3DSurface();
static X_D3DSurface *pXboxBackBuffer = EmuNewD3DSurface();
IDirect3DSurface *pCurrentHostBackBuffer = nullptr;
STATUS_SUCCESS;
@ -3474,12 +3478,12 @@ XTL::X_D3DSurface* WINAPI XTL::EMUPATCH(D3DDevice_GetBackBuffer2)
if (FAILED(hRet))
CxbxKrnlCleanup("Unable to retrieve back buffer");
SetHostSurface(pBackBuffer, pCurrentHostBackBuffer);
SetHostSurface(pXboxBackBuffer, pCurrentHostBackBuffer);
// Increment reference count
pBackBuffer->Common++; // EMUPATCH(D3DResource_AddRef)(pBackBuffer);
pXboxBackBuffer->Common++; // EMUPATCH(D3DResource_AddRef)(pXboxBackBuffer);
return pBackBuffer;
return pXboxBackBuffer;
#else // COPY_BACKBUFFER_TO_XBOX_SURFACE
// Rather than create a new surface, we should forward to the Xbox version of GetBackBuffer,
// This gives us the correct Xbox surface to update.
@ -3626,8 +3630,8 @@ void UpdateViewPortOffsetAndScaleConstants()
float vScale[] = { (2.0f / ViewPort.Width) * g_RenderScaleFactor, (-2.0f / ViewPort.Height) * g_RenderScaleFactor, 0.0f, 0.0f };
static float vOffset[] = { -1.0f, 1.0f, 0.0f, 1.0f };
g_pD3DDevice->SetVertexShaderConstantF(58, vScale, 1);
g_pD3DDevice->SetVertexShaderConstantF(59, vOffset, 1);
g_pD3DDevice->SetVertexShaderConstantF(X_D3DVS_RESERVED_CONSTANT1_CORRECTED, vScale, 1);
g_pD3DDevice->SetVertexShaderConstantF(X_D3DVS_RESERVED_CONSTANT2_CORRECTED, vOffset, 1);
}
}
@ -6396,15 +6400,12 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetStreamSource_4)
// LOG_FUNC_END;
EmuLog(LOG_LEVEL::DEBUG, "D3DDevice_SetStreamSource_4(StreamNumber : %08X pStreamData : %08X Stride : %08X);", StreamNumber, pStreamData, Stride);
// Forward to Xbox implementation
CxbxImpl_SetStreamSource(StreamNumber, pStreamData, Stride);
// TODO : Forward to Xbox implementation
// This should stop us having to patch GetStreamSource!
//XB_trampoline(VOID, WINAPI, D3DDevice_SetStreamSource_4, (UINT, X_D3DVertexBuffer*, UINT));
//XB_D3DDevice_SetStreamSource_4(StreamNumber, pStreamData, Stride);
if (StreamNumber < 16) {
g_D3DStreams[StreamNumber] = pStreamData;
g_D3DStreamStrides[StreamNumber] = Stride;
}
}
// This uses a custom calling convention where parameter is passed in EAX
@ -6429,15 +6430,12 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetStreamSource_8)
// LOG_FUNC_END;
EmuLog(LOG_LEVEL::DEBUG, "D3DDevice_SetStreamSource_8(StreamNumber : %08X pStreamData : %08X Stride : %08X);", StreamNumber, pStreamData, Stride);
CxbxImpl_SetStreamSource(StreamNumber, pStreamData, Stride);
// TODO : Forward to Xbox implementation
// This should stop us having to patch GetStreamSource!
//XB_trampoline(VOID, WINAPI, D3DDevice_SetStreamSource_8, (X_D3DVertexBuffer*, UINT));
//XB_D3DDevice_SetStreamSource_8(pStreamData, Stride);
if (StreamNumber < 16) {
g_D3DStreams[StreamNumber] = pStreamData;
g_D3DStreamStrides[StreamNumber] = Stride;
}
}
// ******************************************************************
@ -6456,19 +6454,12 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetStreamSource)
LOG_FUNC_ARG(Stride)
LOG_FUNC_END;
CxbxImpl_SetStreamSource(StreamNumber, pStreamData, Stride);
// Forward to Xbox implementation
// This should stop us having to patch GetStreamSource!
XB_trampoline(VOID, WINAPI, D3DDevice_SetStreamSource, (UINT, X_D3DVertexBuffer*, UINT));
XB_D3DDevice_SetStreamSource(StreamNumber, pStreamData, Stride);
if(pStreamData != xbnullptr && Stride == 0){
LOG_TEST_CASE("Stream stride set to 0");
}
if (StreamNumber < 16) {
g_D3DStreams[StreamNumber] = pStreamData;
g_D3DStreamStrides[StreamNumber] = Stride;
}
}
// ******************************************************************
@ -7799,7 +7790,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SelectVertexShaderDirect)
LOG_FUNC_ARG(Address)
LOG_FUNC_END;
LOG_UNIMPLEMENTED();
CxbxImpl_SelectVertexShaderDirect(pVAF, Address);
}
// ******************************************************************
@ -7924,16 +7915,19 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexShaderInput)
LOG_FUNC_ARG(pStreamInputs)
LOG_FUNC_END;
// If Handle is NULL, all VertexShader input state is cleared.
// When this API is in effect, VertexBuffers as set by Xbox SetStreamSource are disregarded,
// instead, the pStreamInputs[].VertexBuffer streams are used.
// If Handle is NULL, all VertexShader input state is cleared (after which the VertexBuffers as set by SetStreamSource are used once again).
// Otherwise, Handle is the address of an Xbox VertexShader struct, or-ed with 1 (X_D3DFVF_RESERVED0)
// The given pStreamInputs are stored in a global array, and the NV2A is programmed to read
// each vertex attribute (as defined in the given VertexShader.VertexAttribute.Slots[]) to read
// the attribute data from the pStreamInputs[slot].VertexBuffer + pStreamInputs[slot].Offset + VertexShader.VertexAttribute.Slots[slot].Offset
LOG_UNIMPLEMENTED();
return;
CxbxImpl_SetVertexShaderInput(Handle, StreamCount, pStreamInputs);
}
// ******************************************************************
// * patch: D3DDevice_RunVertexStateShader
// ******************************************************************
@ -7948,6 +7942,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_RunVertexStateShader)
LOG_FUNC_ARG(pData)
LOG_FUNC_END;
// If pData is assigned, pData[0..3] is pushed towards nv2a transform data registers
// then sends the nv2a a command to launch the vertex shader function located at Address
LOG_UNIMPLEMENTED();
}

View File

@ -55,8 +55,10 @@ FLOAT *g_InlineVertexBuffer_pData = nullptr;
UINT g_InlineVertexBuffer_DataSize = 0;
extern DWORD g_dwPrimPerFrame = 0;
extern XTL::X_D3DVertexBuffer*g_D3DStreams[X_VSH_MAX_STREAMS];
extern UINT g_D3DStreamStrides[X_VSH_MAX_STREAMS];
// Copy of active Xbox D3D Vertex Streams (and strides), set by [D3DDevice|CxbxImpl]_SetStreamSource*
XTL::X_STREAMINPUT g_Xbox_SetStreamSource[X_VSH_MAX_STREAMS] = { 0 }; // Note : .Offset member is never set (so always 0)
extern XTL::X_D3DSurface* g_pXbox_RenderTarget;
extern XTL::X_D3DSurface* g_pXbox_BackBufferSurface;
void *GetDataFromXboxResource(XTL::X_D3DResource *pXboxResource);
@ -118,7 +120,7 @@ int CountActiveD3DStreams()
{
int lastStreamIndex = 0;
for (int i = 0; i < X_VSH_MAX_STREAMS; i++) {
if (g_D3DStreams[i] != xbnullptr) {
if (g_Xbox_SetStreamSource[i].VertexBuffer != xbnullptr) {
lastStreamIndex = i + 1;
}
}
@ -292,7 +294,7 @@ void CxbxVertexBufferConverter::ConvertStream
uiHostVertexStride = (bNeedVertexPatching) ? pVertexShaderStreamInfo->HostVertexStride : uiXboxVertexStride;
dwHostVertexDataSize = uiVertexCount * uiHostVertexStride;
} else {
XTL::X_D3DVertexBuffer *pXboxVertexBuffer = g_D3DStreams[uiStream];
XTL::X_D3DVertexBuffer *pXboxVertexBuffer = g_Xbox_SetStreamSource[uiStream].VertexBuffer;
pXboxVertexData = (uint8_t*)GetDataFromXboxResource(pXboxVertexBuffer);
if (pXboxVertexData == xbnullptr) {
HRESULT hRet = g_pD3DDevice->SetStreamSource(
@ -308,7 +310,7 @@ void CxbxVertexBufferConverter::ConvertStream
return;
}
uiXboxVertexStride = g_D3DStreamStrides[uiStream];
uiXboxVertexStride = g_Xbox_SetStreamSource[uiStream].Stride;
// Set a new (exact) vertex count
uiVertexCount = pDrawContext->VerticesInBuffer;
// Dxbx note : Don't overwrite pDrawContext.dwVertexCount with uiVertexCount, because an indexed draw
@ -987,3 +989,15 @@ VOID EmuFlushIVB()
}
g_InlineVertexBuffer_TableOffset = 0; // Might not be needed (also cleared in D3DDevice_Begin)
}
void CxbxImpl_SetStreamSource(UINT StreamNumber, XTL::X_D3DVertexBuffer* pStreamData, UINT Stride)
{
if (pStreamData != xbnullptr && Stride == 0) {
LOG_TEST_CASE("CxbxImpl_SetStreamSource : Stream assigned, and stride set to 0 (might be okay)");
}
assert(StreamNumber < X_VSH_MAX_STREAMS);
g_Xbox_SetStreamSource[StreamNumber].VertexBuffer = pStreamData;
g_Xbox_SetStreamSource[StreamNumber].Stride = Stride;
}

View File

@ -1468,7 +1468,7 @@ static void VshRemoveScreenSpaceInstructions(VSH_XBOX_SHADER *pShader)
MulIntermediate.Parameters[1].Active = TRUE;
MulIntermediate.Parameters[1].IndexesWithA0_X = FALSE;
MulIntermediate.Parameters[1].Parameter.ParameterType = PARAM_C;
MulIntermediate.Parameters[1].Parameter.Address = ConvertCRegister(58);
MulIntermediate.Parameters[1].Parameter.Address = ConvertCRegister(X_D3DVS_RESERVED_CONSTANT1_CORRECTED);
MulIntermediate.Parameters[1].Parameter.Neg = FALSE;
VshSetSwizzle(&MulIntermediate.Parameters[1], SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
MulIntermediate.Parameters[2].Active = FALSE;
@ -1481,7 +1481,7 @@ static void VshRemoveScreenSpaceInstructions(VSH_XBOX_SHADER *pShader)
AddIntermediate.Output.Address = OREG_OPOS;
AddIntermediate.Parameters[0].Parameter.ParameterType = PARAM_R;
AddIntermediate.Parameters[0].Parameter.Address = 13;
AddIntermediate.Parameters[1].Parameter.Address = ConvertCRegister(59);
AddIntermediate.Parameters[1].Parameter.Address = ConvertCRegister(X_D3DVS_RESERVED_CONSTANT2_CORRECTED);
VshInsertIntermediate(pShader, &AddIntermediate, ++i);
}
}
@ -2797,3 +2797,33 @@ void SetCxbxVertexShader(DWORD XboxVertexShaderHandle, CxbxVertexShader* shader)
g_CxbxVertexShaders[XboxVertexShaderHandle] = shader;
}
void CxbxImpl_SetVertexShaderInput
(
DWORD Handle,
UINT StreamCount,
XTL::X_STREAMINPUT* pStreamInputs
)
{
LOG_INIT
// If Handle is NULL, all VertexShader input state is cleared.
// Otherwise, Handle is the address of an Xbox VertexShader struct, or-ed with 1 (X_D3DFVF_RESERVED0)
// (Thus, a FVF handle is an invalid argument.)
//
LOG_UNIMPLEMENTED();
}
void CxbxImpl_SelectVertexShaderDirect
(
XTL::X_VERTEXATTRIBUTEFORMAT* pVAF,
DWORD Address
)
{
LOG_INIT;
// When pVAF is non-null, this vertex attribute format takes precedence over the the one
LOG_UNIMPLEMENTED();
}