diff options
| author | Jason Maskell <[email protected]> | 2016-05-09 10:39:54 +0200 |
|---|---|---|
| committer | Jason Maskell <[email protected]> | 2016-05-09 10:39:54 +0200 |
| commit | 79b3462799c28af8ba586349bd671b1b56e72353 (patch) | |
| tree | 3b06e36c390254c0dc7f3733a0d32af213d87293 /src/GFX_Timer.cpp | |
| download | waveworks_archive-79b3462799c28af8ba586349bd671b1b56e72353.tar.xz waveworks_archive-79b3462799c28af8ba586349bd671b1b56e72353.zip | |
Initial commit with PS4 and XBone stuff trimmed.
Diffstat (limited to 'src/GFX_Timer.cpp')
| -rw-r--r-- | src/GFX_Timer.cpp | 1138 |
1 files changed, 1138 insertions, 0 deletions
diff --git a/src/GFX_Timer.cpp b/src/GFX_Timer.cpp new file mode 100644 index 0000000..acc5ad9 --- /dev/null +++ b/src/GFX_Timer.cpp @@ -0,0 +1,1138 @@ +// This code contains NVIDIA Confidential Information and is disclosed +// under the Mutual Non-Disclosure Agreement. +// +// Notice +// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES +// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. +// +// NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless +// expressly authorized by NVIDIA. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright � 2008- 2013 NVIDIA Corporation. All rights reserved. +// +// NVIDIA Corporation and its licensors retain all intellectual property and proprietary +// rights in and to this software and related documentation and any modifications thereto. +// Any use, reproduction, disclosure or distribution of this software and related +// documentation without an express license agreement from NVIDIA Corporation is +// strictly prohibited. +// + +#include "Internal.h" +#include "GFX_Timer_impl.h" +#include "Graphics_Context.h" + +#if defined(TARGET_PLATFORM_NIXLIKE) +#include <unistd.h> +#include <string.h> +void Sleep(DWORD dwMilliseconds) +{ + assert(!dwMilliseconds); + sleep(dwMilliseconds); +} +#endif + + +/* + * ******************************************************************************** + * Utility class for managing a pool of queries + * ******************************************************************************** +*/ +namespace +{ + template<class QueryDataType> + class GFSDK_WaveWorks_GFX_Query_Pool_Impl + { + public: + GFSDK_WaveWorks_GFX_Query_Pool_Impl(); + ~GFSDK_WaveWorks_GFX_Query_Pool_Impl(); + + int getNumQueries() const { return m_NumQueries; } + int getNumInactiveQueries() const { return m_NumInactiveQueries; } + + QueryDataType& addInactiveQuery(); + int activateQuery(); + + void releaseQuery(int ix); + void addRefQuery(int ix); + + QueryDataType& getQueryData(int ix); + + private: + + void releaseAll(); + + QueryDataType* m_pQueriesData; + int m_NumQueries; + + int* m_pInactiveQueries; + int m_NumInactiveQueries; + }; + + template<class QueryDataType> + GFSDK_WaveWorks_GFX_Query_Pool_Impl<QueryDataType>::GFSDK_WaveWorks_GFX_Query_Pool_Impl() + { + m_pQueriesData = 0; + m_NumQueries = 0; + m_pInactiveQueries = 0; + m_NumInactiveQueries = 0; + } + + template<class QueryDataType> + GFSDK_WaveWorks_GFX_Query_Pool_Impl<QueryDataType>::~GFSDK_WaveWorks_GFX_Query_Pool_Impl() + { + releaseAll(); + } + + template<class QueryDataType> + void GFSDK_WaveWorks_GFX_Query_Pool_Impl<QueryDataType>::releaseAll() + { + SAFE_DELETE_ARRAY(m_pQueriesData); + SAFE_DELETE_ARRAY(m_pInactiveQueries); + + m_NumQueries = 0; + m_NumInactiveQueries = 0; + } + + template<class QueryDataType> + QueryDataType& GFSDK_WaveWorks_GFX_Query_Pool_Impl<QueryDataType>::addInactiveQuery() + { + int newQueryIndex = m_NumQueries; + int newNumQueries = m_NumQueries + 1; + QueryDataType* pNewDatas = new QueryDataType[newNumQueries]; + int* pNewInactiveQueries = new int[newNumQueries]; + + memcpy(pNewDatas, m_pQueriesData, m_NumQueries * sizeof(m_pQueriesData[0])); + memcpy(pNewInactiveQueries, m_pInactiveQueries, m_NumInactiveQueries * sizeof(m_pInactiveQueries[0])); + + SAFE_DELETE_ARRAY(m_pQueriesData); + SAFE_DELETE_ARRAY(m_pInactiveQueries); + + m_pQueriesData = pNewDatas; + m_pInactiveQueries = pNewInactiveQueries; + + // Fixup newbies + m_pQueriesData[newQueryIndex].m_refCount = 0; + m_pInactiveQueries[m_NumInactiveQueries] = newQueryIndex; + ++m_NumInactiveQueries; + + m_NumQueries = newNumQueries; + + return m_pQueriesData[newQueryIndex]; + } + + template<class QueryDataType> + int GFSDK_WaveWorks_GFX_Query_Pool_Impl<QueryDataType>::activateQuery() + { + assert(m_NumInactiveQueries > 0); + + --m_NumInactiveQueries; + + int result = m_pInactiveQueries[m_NumInactiveQueries]; + m_pQueriesData[result].m_status = S_FALSE; + m_pQueriesData[result].m_refCount = 1; + + return result; + } + + template<class QueryDataType> + void GFSDK_WaveWorks_GFX_Query_Pool_Impl<QueryDataType>::releaseQuery(int ix) + { + assert(ix < m_NumQueries); + assert(m_pQueriesData[ix].m_refCount > 0); + + --m_pQueriesData[ix].m_refCount; + if(0 == m_pQueriesData[ix].m_refCount) + { + // return to inactive pool + assert(m_NumInactiveQueries < m_NumQueries); + m_pInactiveQueries[m_NumInactiveQueries] = ix; + ++m_NumInactiveQueries; + } + } + + template<class QueryDataType> + void GFSDK_WaveWorks_GFX_Query_Pool_Impl<QueryDataType>::addRefQuery(int ix) + { + assert(ix < m_NumQueries); + assert(m_pQueriesData[ix].m_refCount > 0); // Because it is invalid to use a zero-ref'd query + + ++m_pQueriesData[ix].m_refCount; + } + + template<class QueryDataType> + QueryDataType& GFSDK_WaveWorks_GFX_Query_Pool_Impl<QueryDataType>::getQueryData(int ix) + { + assert(ix < m_NumQueries); + + return m_pQueriesData[ix]; + } + + struct DisjointQueryData + { + int m_refCount; + UINT64 m_freqResult; + HRESULT m_status; + +#if WAVEWORKS_ENABLE_D3D9 + struct D3D9Objects + { + IDirect3DQuery9* m_pDisjointTimerQuery; + IDirect3DQuery9* m_pTimerFreqQuery; + }; +#endif + +#if WAVEWORKS_ENABLE_D3D10 + struct D3D10Objects + { + ID3D10Query* m_pDisjointTimerQuery; + }; +#endif + +#if WAVEWORKS_ENABLE_D3D11 + struct D3D11Objects + { + ID3D11Query* m_pDisjointTimerQuery; + }; +#endif + + union + { +#if WAVEWORKS_ENABLE_D3D9 + D3D9Objects _9; +#endif +#if WAVEWORKS_ENABLE_D3D10 + D3D10Objects _10; +#endif +#if WAVEWORKS_ENABLE_D3D11 + D3D11Objects _11; +#endif + } m_d3d; + }; + + struct TimerQueryData + { + int m_refCount; + UINT64 m_timestampResult; + HRESULT m_status; + +#if WAVEWORKS_ENABLE_D3D9 + struct D3D9Objects + { + IDirect3DQuery9* m_pTimerQuery; + }; +#endif + +#if WAVEWORKS_ENABLE_D3D10 + struct D3D10Objects + { + ID3D10Query* m_pTimerQuery; + }; +#endif + +#if WAVEWORKS_ENABLE_D3D11 + struct D3D11Objects + { + ID3D11Query* m_pTimerQuery; + }; +#endif +#if WAVEWORKS_ENABLE_GL + struct GL2Objects + { + GLuint m_GLTimerQuery; + }; +#endif + union + { +#if WAVEWORKS_ENABLE_D3D9 + D3D9Objects _9; +#endif +#if WAVEWORKS_ENABLE_D3D10 + D3D10Objects _10; +#endif +#if WAVEWORKS_ENABLE_D3D11 + D3D11Objects _11; +#endif +#if WAVEWORKS_ENABLE_GL + GL2Objects _GL2; +#endif + } m_d3d; + }; +} + +class GFSDK_WaveWorks_GFX_DisjointQuery_Pool_Impl : public GFSDK_WaveWorks_GFX_Query_Pool_Impl<DisjointQueryData> {}; +class GFSDK_WaveWorks_GFX_TimerQuery_Pool_Impl : public GFSDK_WaveWorks_GFX_Query_Pool_Impl<TimerQueryData> {}; + +/* + * ******************************************************************************** +*/ + +NVWaveWorks_GFX_Timer_Impl::NVWaveWorks_GFX_Timer_Impl() +{ + memset(&m_d3d, 0, sizeof(m_d3d)); + m_d3dAPI = nv_water_d3d_api_undefined; + + m_pDisjointTimersPool = 0; + m_pTimersPool = 0; + + m_CurrentDisjointTimerQuery = -1; +} + +NVWaveWorks_GFX_Timer_Impl::~NVWaveWorks_GFX_Timer_Impl() +{ + releaseAll(); +} + +HRESULT NVWaveWorks_GFX_Timer_Impl::initD3D9(IDirect3DDevice9* D3D9_ONLY(pD3DDevice)) +{ +#if WAVEWORKS_ENABLE_D3D9 + HRESULT hr; + + if(nv_water_d3d_api_d3d9 != m_d3dAPI) + { + releaseAll(); + } + else if(m_d3d._9.m_pd3d9Device != pD3DDevice) + { + releaseAll(); + } + + if(nv_water_d3d_api_undefined == m_d3dAPI) + { + m_d3dAPI = nv_water_d3d_api_d3d9; + m_d3d._9.m_pd3d9Device = pD3DDevice; + m_d3d._9.m_pd3d9Device->AddRef(); + + V_RETURN(allocateAllResources()); + } + + return S_OK; +#else + return E_FAIL; +#endif +} + + +HRESULT NVWaveWorks_GFX_Timer_Impl::initD3D10(ID3D10Device* D3D10_ONLY(pD3DDevice)) +{ +#if WAVEWORKS_ENABLE_D3D10 + HRESULT hr; + + if(nv_water_d3d_api_d3d10 != m_d3dAPI) + { + releaseAll(); + } + else if(m_d3d._10.m_pd3d10Device != pD3DDevice) + { + releaseAll(); + } + + if(nv_water_d3d_api_undefined == m_d3dAPI) + { + m_d3dAPI = nv_water_d3d_api_d3d10; + m_d3d._10.m_pd3d10Device = pD3DDevice; + m_d3d._10.m_pd3d10Device->AddRef(); + + V_RETURN(allocateAllResources()); + } + + return S_OK; +#else + return E_FAIL; +#endif +} + +HRESULT NVWaveWorks_GFX_Timer_Impl::initD3D11(ID3D11Device* D3D11_ONLY(pD3DDevice)) +{ +#if WAVEWORKS_ENABLE_D3D11 + HRESULT hr; + + if(nv_water_d3d_api_d3d11 != m_d3dAPI) + { + releaseAll(); + } + else if(m_d3d._11.m_pd3d11Device != pD3DDevice) + { + releaseAll(); + } + + if(nv_water_d3d_api_undefined == m_d3dAPI) + { + m_d3dAPI = nv_water_d3d_api_d3d11; + m_d3d._11.m_pd3d11Device = pD3DDevice; + m_d3d._11.m_pd3d11Device->AddRef(); + + V_RETURN(allocateAllResources()); + } + + return S_OK; +#else + return E_FAIL; +#endif +} + +HRESULT NVWaveWorks_GFX_Timer_Impl::initGnm() +{ + // No timers on PS4 +#if WAVEWORKS_ENABLE_GNM + return S_OK; +#else + return E_FAIL; +#endif +} + +HRESULT NVWaveWorks_GFX_Timer_Impl::initGL2(void* GL_ONLY(pGLContext)) +{ +#if WAVEWORKS_ENABLE_GL + HRESULT hr; + if(nv_water_d3d_api_gl2 != m_d3dAPI) + { + releaseAll(); + } + else if(m_d3d._GL2.m_pGLContext != pGLContext) + { + releaseAll(); + } + + if(nv_water_d3d_api_undefined == m_d3dAPI) + { + m_d3dAPI = nv_water_d3d_api_gl2; + m_d3d._GL2.m_pGLContext = pGLContext; + V_RETURN(allocateAllResources()); + } + return S_OK; +#else + return S_FALSE; +#endif +} + +HRESULT NVWaveWorks_GFX_Timer_Impl::allocateAllResources() +{ + SAFE_DELETE(m_pDisjointTimersPool); + m_pDisjointTimersPool = new GFSDK_WaveWorks_GFX_DisjointQuery_Pool_Impl(); + + SAFE_DELETE(m_pTimersPool); + m_pTimersPool = new GFSDK_WaveWorks_GFX_TimerQuery_Pool_Impl(); + + return S_OK; +} + +void NVWaveWorks_GFX_Timer_Impl::releaseAll() +{ + releaseAllResources(); + +#if WAVEWORKS_ENABLE_GRAPHICS + switch(m_d3dAPI) + { +#if WAVEWORKS_ENABLE_D3D9 + case nv_water_d3d_api_d3d9: + { + SAFE_RELEASE(m_d3d._9.m_pd3d9Device); + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D10 + case nv_water_d3d_api_d3d10: + { + SAFE_RELEASE(m_d3d._10.m_pd3d10Device); + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D11 + case nv_water_d3d_api_d3d11: + { + SAFE_RELEASE(m_d3d._11.m_pd3d11Device); + } + break; +#endif + +#if WAVEWORKS_ENABLE_GL + case nv_water_d3d_api_gl2: + { + // do nothing + } + break; +#endif + default: + break; + } +#endif // WAVEWORKS_ENABLE_GRAPHICS + + m_d3dAPI = nv_water_d3d_api_undefined; +} + +void NVWaveWorks_GFX_Timer_Impl::releaseAllResources() +{ +#if WAVEWORKS_ENABLE_GRAPHICS + switch(m_d3dAPI) + { +#if WAVEWORKS_ENABLE_D3D9 + case nv_water_d3d_api_d3d9: + { + for(int i = 0; i != m_pDisjointTimersPool->getNumQueries(); ++i) + { + DisjointQueryData& dqd = m_pDisjointTimersPool->getQueryData(i); + SAFE_RELEASE(dqd.m_d3d._9.m_pDisjointTimerQuery); + SAFE_RELEASE(dqd.m_d3d._9.m_pTimerFreqQuery); + } + for(int i = 0; i != m_pTimersPool->getNumQueries(); ++i) + { + TimerQueryData& tqd = m_pTimersPool->getQueryData(i); + SAFE_RELEASE(tqd.m_d3d._9.m_pTimerQuery); + } + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D10 + case nv_water_d3d_api_d3d10: + { + for(int i = 0; i != m_pDisjointTimersPool->getNumQueries(); ++i) + { + DisjointQueryData& dqd = m_pDisjointTimersPool->getQueryData(i); + SAFE_RELEASE(dqd.m_d3d._10.m_pDisjointTimerQuery); + } + for(int i = 0; i != m_pTimersPool->getNumQueries(); ++i) + { + TimerQueryData& tqd = m_pTimersPool->getQueryData(i); + SAFE_RELEASE(tqd.m_d3d._10.m_pTimerQuery); + } + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D11 + case nv_water_d3d_api_d3d11: + { + for(int i = 0; i != m_pDisjointTimersPool->getNumQueries(); ++i) + { + DisjointQueryData& dqd = m_pDisjointTimersPool->getQueryData(i); + SAFE_RELEASE(dqd.m_d3d._11.m_pDisjointTimerQuery); + } + for(int i = 0; i != m_pTimersPool->getNumQueries(); ++i) + { + TimerQueryData& tqd = m_pTimersPool->getQueryData(i); + SAFE_RELEASE(tqd.m_d3d._11.m_pTimerQuery); + } + } + break; +#endif +#if WAVEWORKS_ENABLE_GNM + case nv_water_d3d_api_gnm: + { + // Nothin doin + } + break; +#endif + +#if WAVEWORKS_ENABLE_GL + case nv_water_d3d_api_gl2: + { + for(int i = 0; i != m_pTimersPool->getNumQueries(); ++i) + { + TimerQueryData& tqd = m_pTimersPool->getQueryData(i); + if(tqd.m_d3d._GL2.m_GLTimerQuery > 0) NVSDK_GLFunctions.glDeleteQueries(1, &tqd.m_d3d._GL2.m_GLTimerQuery); CHECK_GL_ERRORS; + } + } + break; +#endif + default: + break; + } +#endif // WAVEWORKS_ENABLE_GRAPHICS + + SAFE_DELETE(m_pDisjointTimersPool); + SAFE_DELETE(m_pTimersPool); +} + +HRESULT NVWaveWorks_GFX_Timer_Impl::issueTimerQuery(Graphics_Context* pGC, int& ix) +{ + if(0 == m_pTimersPool->getNumInactiveQueries()) + { + // Add D3D resources +#if WAVEWORKS_ENABLE_GRAPHICS + switch(m_d3dAPI) + { +#if WAVEWORKS_ENABLE_D3D9 + case nv_water_d3d_api_d3d9: + { + HRESULT hr; + TimerQueryData& tqd = m_pTimersPool->addInactiveQuery(); + V_RETURN(m_d3d._9.m_pd3d9Device->CreateQuery(D3DQUERYTYPE_TIMESTAMP , &tqd.m_d3d._9.m_pTimerQuery)); + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D10 + case nv_water_d3d_api_d3d10: + { + HRESULT hr; + TimerQueryData& tqd = m_pTimersPool->addInactiveQuery(); + + D3D10_QUERY_DESC query_desc; + query_desc.Query = D3D10_QUERY_TIMESTAMP; + query_desc.MiscFlags = 0; + V_RETURN(m_d3d._10.m_pd3d10Device->CreateQuery(&query_desc, &tqd.m_d3d._10.m_pTimerQuery)); + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D11 + case nv_water_d3d_api_d3d11: + { + HRESULT hr; + TimerQueryData& tqd = m_pTimersPool->addInactiveQuery(); + + D3D11_QUERY_DESC query_desc; + query_desc.Query = D3D11_QUERY_TIMESTAMP; + query_desc.MiscFlags = 0; + V_RETURN(m_d3d._11.m_pd3d11Device->CreateQuery(&query_desc, &tqd.m_d3d._11.m_pTimerQuery)); + } + break; +#endif +#if WAVEWORKS_ENABLE_GNM + case nv_water_d3d_api_gnm: + { + /*TimerQueryData& tqd =*/ m_pTimersPool->addInactiveQuery(); + } + break; +#endif + +#if WAVEWORKS_ENABLE_GL + case nv_water_d3d_api_gl2: + { + TimerQueryData& tqd = m_pTimersPool->addInactiveQuery(); + NVSDK_GLFunctions.glGenQueries(1, &tqd.m_d3d._GL2.m_GLTimerQuery); CHECK_GL_ERRORS; + } + break; +#endif + + default: + // Unexpected API + return E_FAIL; + } +#endif // WAVEWORKS_ENABLE_GRAPHICS + } + + ix = m_pTimersPool->activateQuery(); + + // Begin the query +#if WAVEWORKS_ENABLE_GRAPHICS + switch(m_d3dAPI) + { +#if WAVEWORKS_ENABLE_D3D9 + case nv_water_d3d_api_d3d9: + { + const TimerQueryData& tqd = m_pTimersPool->getQueryData(ix); + tqd.m_d3d._9.m_pTimerQuery->Issue(D3DISSUE_END); + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D10 + case nv_water_d3d_api_d3d10: + { + const TimerQueryData& tqd = m_pTimersPool->getQueryData(ix); + tqd.m_d3d._10.m_pTimerQuery->End(); + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D11 + case nv_water_d3d_api_d3d11: + { + const TimerQueryData& tqd = m_pTimersPool->getQueryData(ix); + + ID3D11DeviceContext* pDC_d3d11 = pGC->d3d11(); + pDC_d3d11->End(tqd.m_d3d._11.m_pTimerQuery); + } + break; +#endif +#if WAVEWORKS_ENABLE_GNM + case nv_water_d3d_api_gnm: + { + const TimerQueryData& tqd = m_pTimersPool->getQueryData(ix); + // Nothin doin + } + break; +#endif + +#if WAVEWORKS_ENABLE_GL + case nv_water_d3d_api_gl2: + { + const TimerQueryData& tqd = m_pTimersPool->getQueryData(ix); + NVSDK_GLFunctions.glQueryCounter(tqd.m_d3d._GL2.m_GLTimerQuery, GL_TIMESTAMP); CHECK_GL_ERRORS; + } + break; +#endif + + default: + // Unexpected API + return E_FAIL; + } +#endif // WAVEWORKS_ENABLE_GRAPHICS + + return S_OK; +} + +void NVWaveWorks_GFX_Timer_Impl::releaseTimerQuery(int ix) +{ + m_pTimersPool->releaseQuery(ix); +} + +HRESULT NVWaveWorks_GFX_Timer_Impl::getTimerQuery(Graphics_Context* pGC, int ix, UINT64& t) +{ + TimerQueryData& tqd = m_pTimersPool->getQueryData(ix); + if(S_FALSE == tqd.m_status) + { + HRESULT hr = E_FAIL; + UINT64 result = 0; + +#if WAVEWORKS_ENABLE_GRAPHICS + switch(m_d3dAPI) + { +#if WAVEWORKS_ENABLE_D3D9 + case nv_water_d3d_api_d3d9: + hr = tqd.m_d3d._9.m_pTimerQuery->GetData(&result, sizeof(result), 0); + break; +#endif +#if WAVEWORKS_ENABLE_D3D10 + case nv_water_d3d_api_d3d10: + hr = tqd.m_d3d._10.m_pTimerQuery->GetData(&result, sizeof(result), 0); + break; +#endif +#if WAVEWORKS_ENABLE_D3D11 + case nv_water_d3d_api_d3d11: + { + ID3D11DeviceContext* pDC_d3d11 = pGC->d3d11(); + hr = pDC_d3d11->GetData(tqd.m_d3d._11.m_pTimerQuery, &result, sizeof(result), 0); + } + break; +#endif +#if WAVEWORKS_ENABLE_GNM + case nv_water_d3d_api_gnm: + { + hr = S_OK; + } + break; +#endif + +#if WAVEWORKS_ENABLE_GL + case nv_water_d3d_api_gl2: + { + NVSDK_GLFunctions.glGetQueryObjectui64v(tqd.m_d3d._GL2.m_GLTimerQuery, GL_QUERY_RESULT_AVAILABLE, &result); CHECK_GL_ERRORS; + if(result == GL_FALSE) + { + hr = S_FALSE; + } + else + { + NVSDK_GLFunctions.glGetQueryObjectui64v(tqd.m_d3d._GL2.m_GLTimerQuery, GL_QUERY_RESULT, &result); CHECK_GL_ERRORS; + hr = S_OK; + } + } + break; +#endif + + default: + { + // Unexpected API + hr = E_FAIL; + } + break; + } +#endif // WAVEWORKS_ENABLE_GRAPHICS + + switch(hr) + { + case S_FALSE: + break; + case S_OK: + tqd.m_timestampResult = result; + tqd.m_status = S_OK; + break; + default: + tqd.m_timestampResult = 0; + tqd.m_status = hr; + break; + } + } + + if(S_FALSE != tqd.m_status) + { + t = tqd.m_timestampResult; + } + + return tqd.m_status; +} + +HRESULT NVWaveWorks_GFX_Timer_Impl::getTimerQueries(Graphics_Context* pGC, int ix1, int ix2, UINT64& tdiff) +{ + UINT64 stamp1; + HRESULT hr1 = getTimerQuery(pGC, ix1, stamp1); + if(S_FALSE == hr1) + return S_FALSE; + UINT64 stamp2; + HRESULT hr2 = getTimerQuery(pGC, ix2, stamp2); + if(S_FALSE == hr2) + return S_FALSE; + + if(S_OK == hr1 && S_OK ==hr2) + { + tdiff = stamp2 - stamp1; + return S_OK; + } + else if(S_OK == hr1) + { + return hr2; + } + else + { + return hr1; + } +} + +HRESULT NVWaveWorks_GFX_Timer_Impl::waitTimerQuery(Graphics_Context* pGC, int ix, UINT64& t) +{ + // No built-in sync in DX, roll our own as best we can... + HRESULT status = S_FALSE; + do + { + status = getTimerQuery(pGC, ix, t); + if(S_FALSE == status) + { + Sleep(0); + } + } + while(S_FALSE == status); + + return status; +} + +HRESULT NVWaveWorks_GFX_Timer_Impl::waitTimerQueries(Graphics_Context* pGC, int ix1, int ix2, UINT64& tdiff) +{ + // No built-in sync in DX, roll our own as best we can... + HRESULT status = S_FALSE; + do + { + status = getTimerQueries(pGC, ix1, ix2, tdiff); + if(S_FALSE == status) + { + Sleep(0); + } + } + while(S_FALSE == status); + + return status; +} + +HRESULT NVWaveWorks_GFX_Timer_Impl::beginDisjoint(Graphics_Context* pGC) +{ + if(0 == m_pDisjointTimersPool->getNumInactiveQueries()) + { + // Add D3D resources +#if WAVEWORKS_ENABLE_GRAPHICS + switch(m_d3dAPI) + { +#if WAVEWORKS_ENABLE_D3D9 + case nv_water_d3d_api_d3d9: + { + HRESULT hr; + DisjointQueryData& dqd = m_pDisjointTimersPool->addInactiveQuery(); + V_RETURN(m_d3d._9.m_pd3d9Device->CreateQuery(D3DQUERYTYPE_TIMESTAMPDISJOINT , &dqd.m_d3d._9.m_pDisjointTimerQuery)); + V_RETURN(m_d3d._9.m_pd3d9Device->CreateQuery(D3DQUERYTYPE_TIMESTAMPFREQ , &dqd.m_d3d._9.m_pTimerFreqQuery)); + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D10 + case nv_water_d3d_api_d3d10: + { + HRESULT hr; + DisjointQueryData& dqd = m_pDisjointTimersPool->addInactiveQuery(); + D3D10_QUERY_DESC query_desc; + query_desc.Query = D3D10_QUERY_TIMESTAMP_DISJOINT; + query_desc.MiscFlags = 0; + V_RETURN(m_d3d._10.m_pd3d10Device->CreateQuery(&query_desc, &dqd.m_d3d._10.m_pDisjointTimerQuery)); + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D11 + case nv_water_d3d_api_d3d11: + { + HRESULT hr; + DisjointQueryData& dqd = m_pDisjointTimersPool->addInactiveQuery(); + D3D11_QUERY_DESC query_desc; + query_desc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT; + query_desc.MiscFlags = 0; + V_RETURN(m_d3d._11.m_pd3d11Device->CreateQuery(&query_desc, &dqd.m_d3d._11.m_pDisjointTimerQuery)); + } + break; +#endif +#if WAVEWORKS_ENABLE_GNM + case nv_water_d3d_api_gnm: + { + /*DisjointQueryData& dqd = */ m_pDisjointTimersPool->addInactiveQuery(); + } + break; +#endif + +#if WAVEWORKS_ENABLE_GL + case nv_water_d3d_api_gl2: + { + /*DisjointQueryData& dqd =*/ m_pDisjointTimersPool->addInactiveQuery(); + // GL doesn't have disjoint queries atm, so doing nothing + } + break; +#endif + + default: + // Unexpected API + return E_FAIL; + } +#endif // WAVEWORKS_ENABLE_GRAPHICS + } + + // Make an inactive query current + assert(m_CurrentDisjointTimerQuery == -1); + m_CurrentDisjointTimerQuery = m_pDisjointTimersPool->activateQuery(); + + // Begin the disjoint query +#if WAVEWORKS_ENABLE_GRAPHICS + switch(m_d3dAPI) + { +#if WAVEWORKS_ENABLE_D3D9 + case nv_water_d3d_api_d3d9: + { + const DisjointQueryData& dqd = m_pDisjointTimersPool->getQueryData(m_CurrentDisjointTimerQuery); + dqd.m_d3d._9.m_pDisjointTimerQuery->Issue(D3DISSUE_BEGIN); + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D10 + case nv_water_d3d_api_d3d10: + { + const DisjointQueryData& dqd = m_pDisjointTimersPool->getQueryData(m_CurrentDisjointTimerQuery); + dqd.m_d3d._10.m_pDisjointTimerQuery->Begin(); + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D11 + case nv_water_d3d_api_d3d11: + { + ID3D11DeviceContext* pDC_d3d11 = pGC->d3d11(); + const DisjointQueryData& dqd = m_pDisjointTimersPool->getQueryData(m_CurrentDisjointTimerQuery); + pDC_d3d11->Begin(dqd.m_d3d._11.m_pDisjointTimerQuery); + } + break; +#endif +#if WAVEWORKS_ENABLE_GNM + case nv_water_d3d_api_gnm: + { + /*const DisjointQueryData& dqd =*/ m_pDisjointTimersPool->getQueryData(m_CurrentDisjointTimerQuery); + } + break; +#endif + +#if WAVEWORKS_ENABLE_GL + case nv_water_d3d_api_gl2: + { + // GL doesn't have disjoint queries atm, so doing nothing + } + break; +#endif + default: + // Unexpected API + return E_FAIL; + } +#endif // WAVEWORKS_ENABLE_GRAPHICS + + return S_OK; +} + +HRESULT NVWaveWorks_GFX_Timer_Impl::endDisjoint(Graphics_Context* pGC) +{ + assert(m_CurrentDisjointTimerQuery != -1); + + // End the disjoint query +#if WAVEWORKS_ENABLE_GRAPHICS + switch(m_d3dAPI) + { +#if WAVEWORKS_ENABLE_D3D9 + case nv_water_d3d_api_d3d9: + { + const DisjointQueryData& dqd = m_pDisjointTimersPool->getQueryData(m_CurrentDisjointTimerQuery); + dqd.m_d3d._9.m_pTimerFreqQuery->Issue(D3DISSUE_END); + dqd.m_d3d._9.m_pDisjointTimerQuery->Issue(D3DISSUE_END); + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D10 + case nv_water_d3d_api_d3d10: + { + const DisjointQueryData& dqd = m_pDisjointTimersPool->getQueryData(m_CurrentDisjointTimerQuery); + dqd.m_d3d._10.m_pDisjointTimerQuery->End(); + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D11 + case nv_water_d3d_api_d3d11: + { + ID3D11DeviceContext* pDC_d3d11 = pGC->d3d11(); + const DisjointQueryData& dqd = m_pDisjointTimersPool->getQueryData(m_CurrentDisjointTimerQuery); + pDC_d3d11->End(dqd.m_d3d._11.m_pDisjointTimerQuery); + } + break; +#endif +#if WAVEWORKS_ENABLE_GNM + case nv_water_d3d_api_gnm: + { + /*const DisjointQueryData& dqd =*/ m_pDisjointTimersPool->getQueryData(m_CurrentDisjointTimerQuery); + } + break; +#endif + +#if WAVEWORKS_ENABLE_GL + case nv_water_d3d_api_gl2: + { + // GL doesn't have disjoint queries atm, so doing nothing + } + break; +#endif + + default: + // Unexpected API + return E_FAIL; + } +#endif // WAVEWORKS_ENABLE_GRAPHICS + + // Release the query (but others may have referenced it by now...) + m_pDisjointTimersPool->releaseQuery(m_CurrentDisjointTimerQuery); + m_CurrentDisjointTimerQuery = -1; + + return S_OK; +} + +int NVWaveWorks_GFX_Timer_Impl::getCurrentDisjointQuery() +{ + assert(m_CurrentDisjointTimerQuery != -1); + + m_pDisjointTimersPool->addRefQuery(m_CurrentDisjointTimerQuery); // udpate ref-count + return m_CurrentDisjointTimerQuery; +} + +void NVWaveWorks_GFX_Timer_Impl::releaseDisjointQuery(int ix) +{ + m_pDisjointTimersPool->releaseQuery(ix); +} + +HRESULT NVWaveWorks_GFX_Timer_Impl::getDisjointQuery(Graphics_Context* pGC, int ix, UINT64& f) +{ + DisjointQueryData& dqd = m_pDisjointTimersPool->getQueryData(ix); + if(S_FALSE == dqd.m_status) + { + HRESULT hr = E_FAIL; + BOOL WasDisjoint = FALSE; + UINT64 RawF = 0; + +#if WAVEWORKS_ENABLE_GRAPHICS + switch(m_d3dAPI) + { +#if WAVEWORKS_ENABLE_D3D9 + case nv_water_d3d_api_d3d9: + { + hr = dqd.m_d3d._9.m_pDisjointTimerQuery->GetData(&WasDisjoint, sizeof(WasDisjoint), 0); + if(S_OK == hr) + { + hr = dqd.m_d3d._9.m_pTimerFreqQuery->GetData(&RawF, sizeof(RawF), 0); + } + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D10 + case nv_water_d3d_api_d3d10: + { + D3D10_QUERY_DATA_TIMESTAMP_DISJOINT result; + hr = dqd.m_d3d._10.m_pDisjointTimerQuery->GetData(&result, sizeof(result), 0); + + RawF = result.Frequency; + WasDisjoint = result.Disjoint; + } + break; +#endif +#if WAVEWORKS_ENABLE_D3D11 + case nv_water_d3d_api_d3d11: + { + ID3D11DeviceContext* pDC_d3d11 = pGC->d3d11(); + + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT result; + hr = pDC_d3d11->GetData(dqd.m_d3d._11.m_pDisjointTimerQuery, &result, sizeof(result), 0); + + RawF = result.Frequency; + WasDisjoint = result.Disjoint; + } + break; +#endif +#if WAVEWORKS_ENABLE_GNM + case nv_water_d3d_api_gnm: + { + hr = S_OK; + } + break; +#endif +#if WAVEWORKS_ENABLE_GL + case nv_water_d3d_api_gl2: + { + // GL doesn't have disjoint queries atm, so assuming the queries are not disjoint + hr = S_OK; + RawF = 1000000000; + WasDisjoint = false; + } + break; +#endif + default: + // Unexpected API + return E_FAIL; + } +#endif // WAVEWORKS_ENABLE_GRAPHICS + + switch(hr) + { + case S_FALSE: + break; + case S_OK: + dqd.m_freqResult = WasDisjoint ? 0 : RawF; + dqd.m_status = WasDisjoint ? E_FAIL : S_OK; + break; + default: + dqd.m_freqResult = 0; + dqd.m_status = hr; + break; + } + } + + if(S_FALSE != dqd.m_status) + { + f = dqd.m_freqResult; + } + + return dqd.m_status; +} + +HRESULT NVWaveWorks_GFX_Timer_Impl::waitDisjointQuery(Graphics_Context* pGC, int ix, UINT64& f) +{ + // No built-in sync in DX, roll our own as best we can... + HRESULT status = S_FALSE; + do + { + status = getDisjointQuery(pGC, ix, f); + if(S_FALSE == status) + { + Sleep(0); + } + } + while(S_FALSE == status); + + return status; +} |