Merge pull request #1809 from PatrickvL/d3d-visibility-test_pvl
Implement BeginVisibilityTest, EndVisibilityTest and GetVisibilityTestResult
This commit is contained in:
commit
8fd6253ad1
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "common\util\hasher.h"
|
||||
#include <condition_variable>
|
||||
#include <stack>
|
||||
|
||||
// prevent name collisions
|
||||
namespace xboxkrnl
|
||||
|
@ -114,6 +115,10 @@ static IDirect3DIndexBuffer *g_pClosingLineLoopHostIndexBuffer = nullptr;
|
|||
static IDirect3DIndexBuffer *g_pQuadToTriangleHostIndexBuffer = nullptr;
|
||||
static IDirect3DSurface *g_pDefaultHostDepthBufferSurface = nullptr;
|
||||
|
||||
static bool g_bEnableHostQueryVisibilityTest = true;
|
||||
static std::stack<IDirect3DQuery*> g_HostQueryVisibilityTests;
|
||||
static std::map<int, IDirect3DQuery*> g_HostVisibilityTestMap;
|
||||
|
||||
// cached Direct3D state variable(s)
|
||||
static size_t g_QuadToTriangleHostIndexBuffer_Size = 0; // = NrOfQuadIndices
|
||||
static INDEX16 *g_pQuadToTriangleIndexData = nullptr;
|
||||
|
@ -2448,7 +2453,20 @@ static DWORD WINAPI EmuCreateDeviceProxy(LPVOID)
|
|||
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateQuery (callback event)");
|
||||
}
|
||||
} else {
|
||||
LOG_TEST_CASE("Can't CreateQuery on host!");
|
||||
LOG_TEST_CASE("Can't CreateQuery(D3DQUERYTYPE_EVENT) on host!");
|
||||
}
|
||||
|
||||
// Can host driver create occlusion queries?
|
||||
g_bEnableHostQueryVisibilityTest = false;
|
||||
if (SUCCEEDED(g_pD3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, nullptr))) {
|
||||
// Is host GPU query creation enabled?
|
||||
if (!g_bHack_DisableHostGPUQueries) {
|
||||
g_bEnableHostQueryVisibilityTest = true;
|
||||
} else {
|
||||
LOG_TEST_CASE("Disabled D3DQUERYTYPE_OCCLUSION on host!");
|
||||
}
|
||||
} else {
|
||||
LOG_TEST_CASE("Can't CreateQuery(D3DQUERYTYPE_OCCLUSION) on host!");
|
||||
}
|
||||
|
||||
hRet = g_pD3DDevice->CreateVertexBuffer
|
||||
|
@ -3234,11 +3252,30 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_EndPush)(DWORD *pPush)
|
|||
// ******************************************************************
|
||||
// * patch: D3DDevice_BeginVisibilityTest
|
||||
// ******************************************************************
|
||||
VOID WINAPI XTL::EMUPATCH(D3DDevice_BeginVisibilityTest)()
|
||||
HRESULT WINAPI XTL::EMUPATCH(D3DDevice_BeginVisibilityTest)()
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
LOG_UNIMPLEMENTED();
|
||||
if (g_bEnableHostQueryVisibilityTest) {
|
||||
// Create a D3D occlusion query to handle "visibility test" with
|
||||
IDirect3DQuery* pHostQueryVisibilityTest = nullptr;
|
||||
HRESULT hRet = g_pD3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &pHostQueryVisibilityTest);
|
||||
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateQuery (visibility test)");
|
||||
if (pHostQueryVisibilityTest != nullptr) {
|
||||
hRet = pHostQueryVisibilityTest->Issue(D3DISSUE_BEGIN);
|
||||
DEBUG_D3DRESULT(hRet, "g_pHostQueryVisibilityTest->Issue(D3DISSUE_BEGIN)");
|
||||
if (SUCCEEDED(hRet)) {
|
||||
g_HostQueryVisibilityTests.push(pHostQueryVisibilityTest);
|
||||
} else {
|
||||
LOG_TEST_CASE("Failed to issue query");
|
||||
pHostQueryVisibilityTest->Release();
|
||||
}
|
||||
|
||||
pHostQueryVisibilityTest = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return D3D_OK;
|
||||
}
|
||||
|
||||
// LTCG specific D3DDevice_EndVisibilityTest function...
|
||||
|
@ -3267,7 +3304,30 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_EndVisibilityTest)
|
|||
{
|
||||
LOG_FUNC_ONE_ARG(Index);
|
||||
|
||||
LOG_UNIMPLEMENTED();
|
||||
if (g_bEnableHostQueryVisibilityTest) {
|
||||
// Check that the dedicated storage for the given Index isn't in use
|
||||
if (g_HostVisibilityTestMap[Index] != nullptr) {
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if (g_HostQueryVisibilityTests.empty()) {
|
||||
return 2088; // visibility test incomplete (a prior BeginVisibilityTest call is needed)
|
||||
}
|
||||
|
||||
IDirect3DQuery* pHostQueryVisibilityTest = g_HostQueryVisibilityTests.top();
|
||||
g_HostQueryVisibilityTests.pop();
|
||||
assert(pHostQueryVisibilityTest != nullptr);
|
||||
|
||||
HRESULT hRet = pHostQueryVisibilityTest->Issue(D3DISSUE_END);
|
||||
DEBUG_D3DRESULT(hRet, "g_pHostQueryVisibilityTest->Issue(D3DISSUE_END)");
|
||||
if (hRet == D3D_OK) {
|
||||
// Associate the result of this call with the given Index
|
||||
g_HostVisibilityTestMap[Index] = pHostQueryVisibilityTest;
|
||||
} else {
|
||||
LOG_TEST_CASE("Failed to issue query");
|
||||
pHostQueryVisibilityTest->Release();
|
||||
}
|
||||
}
|
||||
|
||||
return D3D_OK;
|
||||
}
|
||||
|
@ -3301,13 +3361,32 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_GetVisibilityTestResult)
|
|||
LOG_FUNC_ARG(pTimeStamp)
|
||||
LOG_FUNC_END;
|
||||
|
||||
// TODO: actually emulate this!?
|
||||
if (g_bEnableHostQueryVisibilityTest) {
|
||||
IDirect3DQuery* pHostQueryVisibilityTest = g_HostVisibilityTestMap[Index];
|
||||
if (pHostQueryVisibilityTest == nullptr) {
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
if(pResult != 0)
|
||||
*pResult = 640*480;
|
||||
// In order to prevent an endless loop if the D3D device becomes lost, we pass
|
||||
// the D3DGETDATA_FLUSH flag. This tells GetData to return D3DERR_DEVICELOST if
|
||||
// such a situation occurs, and break out of the loop as a result.
|
||||
// Note: By Cxbx's design, we cannot do drawing within this while loop in order
|
||||
// to further prevent any other endless loop situations.
|
||||
while (S_FALSE == pHostQueryVisibilityTest->GetData(pResult, sizeof(DWORD), D3DGETDATA_FLUSH));
|
||||
|
||||
if(pTimeStamp != 0)
|
||||
*pTimeStamp = 0;
|
||||
g_HostVisibilityTestMap[Index] = nullptr;
|
||||
pHostQueryVisibilityTest->Release();
|
||||
} else {
|
||||
// Fallback to old faked result when there's no host occlusion query :
|
||||
if (pResult != xbnullptr) {
|
||||
*pResult = 640 * 480; // TODO : Use actual backbuffer dimensions
|
||||
}
|
||||
}
|
||||
|
||||
if (pTimeStamp != xbnullptr) {
|
||||
LOG_TEST_CASE("requested value for pTimeStamp");
|
||||
*pTimeStamp = sizeof(DWORD); // TODO : This should be an incrementing GPU-memory based DWORD-aligned memory address
|
||||
}
|
||||
|
||||
return D3D_OK;
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ VOID WINAPI EMUPATCH(D3DDevice_EndPush)(DWORD *pPush);
|
|||
// ******************************************************************
|
||||
// * patch: D3DDevice_BeginVisibilityTest
|
||||
// ******************************************************************
|
||||
VOID WINAPI EMUPATCH(D3DDevice_BeginVisibilityTest)();
|
||||
HRESULT WINAPI EMUPATCH(D3DDevice_BeginVisibilityTest)();
|
||||
|
||||
// ******************************************************************
|
||||
// * patch: D3DDevice_EndVisibilityTest
|
||||
|
|
Loading…
Reference in New Issue