//----------------------------------------------------------------------------- /// Wrapped_ID3D12DescriptorHeap::SetPrivateData //----------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE Wrapped_ID3D12DescriptorHeap::SetPrivateData(REFGUID guid, UINT DataSize, const void* pData) { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif HRESULT result = {}; DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor && interceptor->ShouldCollectTrace()) { ParameterEntry parameters[] = { { PARAMETER_GUID, &guid }, { PARAMETER_UNSIGNED_INT, &DataSize }, { PARAMETER_POINTER, pData }, }; int numParameters = (sizeof(parameters) / sizeof(parameters[0])); DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_ID3D12Object_SetPrivateData, numParameters, parameters); result = mRealDescriptorHeap->SetPrivateData(guid, DataSize, pData); interceptor->PostCall(pNewEntry, result); } else { result = mRealDescriptorHeap->SetPrivateData(guid, DataSize, pData); } return result; }
//----------------------------------------------------------------------------- /// Wrapped_ID3D12CommandQueue::Release //----------------------------------------------------------------------------- ULONG STDMETHODCALLTYPE Wrapped_ID3D12CommandQueue::Release() { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif ULONG result = {}; DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor && interceptor->ShouldCollectTrace()) { DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_IUnknown_Release, 0, nullptr); result = mRealCommandQueue->Release(); interceptor->PostCall(pNewEntry, result); } else { result = mRealCommandQueue->Release(); } if (result == 0) { DX12WrappedObjectDatabase* objectDatabase = (DX12WrappedObjectDatabase*)DX12ObjectDatabaseProcessor::Instance()->GetObjectDatabase(); IDX12InstanceBase* objectMetadata = objectDatabase->GetMetadataObject(this); if (objectMetadata != nullptr) { objectMetadata->FlagAsDestroyed(); } } return result; }
//----------------------------------------------------------------------------- /// Wrapped_ID3D12CommandAllocator::SetName //----------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE Wrapped_ID3D12CommandAllocator::SetName(LPCWSTR Name) { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif HRESULT result = {}; DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor->ShouldCollectTrace()) { ParameterEntry parameters[] = { { PARAMETER_WIDE_STRING, Name }, }; int numParameters = (sizeof(parameters) / sizeof(parameters[0])); DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_ID3D12Object_SetName, numParameters, parameters); result = mRealCommandAllocator->SetName(Name); interceptor->PostCall(pNewEntry, result); } else { result = mRealCommandAllocator->SetName(Name); } return result; }
//----------------------------------------------------------------------------- /// Wrapped_ID3D12CommandQueue::SetPrivateDataInterface //----------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE Wrapped_ID3D12CommandQueue::SetPrivateDataInterface(REFGUID guid, const IUnknown* pData) { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif HRESULT result = {}; DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor && interceptor->ShouldCollectTrace()) { ParameterEntry parameters[] = { { PARAMETER_GUID, &guid }, { PARAMETER_POINTER_SPECIAL, pData }, }; int numParameters = (sizeof(parameters) / sizeof(parameters[0])); DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_ID3D12Object_SetPrivateDataInterface, numParameters, parameters); result = mRealCommandQueue->SetPrivateDataInterface(guid, pData); interceptor->PostCall(pNewEntry, result); } else { result = mRealCommandQueue->SetPrivateDataInterface(guid, pData); } return result; }
//----------------------------------------------------------------------------- /// Wrapped_ID3D12CommandQueue::UpdateTileMappings //----------------------------------------------------------------------------- void STDMETHODCALLTYPE Wrapped_ID3D12CommandQueue::UpdateTileMappings(ID3D12Resource* pResource, UINT NumResourceRegions, const D3D12_TILED_RESOURCE_COORDINATE* pResourceRegionStartCoordinates, const D3D12_TILE_REGION_SIZE* pResourceRegionSizes, ID3D12Heap* pHeap, UINT NumRanges, const D3D12_TILE_RANGE_FLAGS* pRangeFlags, const UINT* pHeapRangeStartOffsets, const UINT* pRangeTileCounts, D3D12_TILE_MAPPING_FLAGS Flags) { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif ID3D12Resource* pResourceUnwrapped; DX12CoreDeepCopy::UnwrapInterface(pResource, &(pResourceUnwrapped)); ID3D12Heap* pHeapUnwrapped; DX12CoreDeepCopy::UnwrapInterface(pHeap, &(pHeapUnwrapped)); DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor && interceptor->ShouldCollectTrace()) { // print variables with nullptr pointer check UINT heapRangeStartOffsets = 0; if (pHeapRangeStartOffsets != nullptr) { heapRangeStartOffsets = *pHeapRangeStartOffsets; } UINT rangeTileCounts = 0; if (pRangeTileCounts != nullptr) { rangeTileCounts = *pRangeTileCounts; } ParameterEntry parameters[] = { { PARAMETER_POINTER_SPECIAL, pResource }, { PARAMETER_UNSIGNED_INT, &NumResourceRegions }, { PARAMETER_POINTER, pResourceRegionStartCoordinates }, { PARAMETER_POINTER, pResourceRegionSizes }, { PARAMETER_POINTER_SPECIAL, pHeap }, { PARAMETER_UNSIGNED_INT, &NumRanges }, { PARAMETER_POINTER, pRangeFlags }, { PARAMETER_UNSIGNED_INT, &heapRangeStartOffsets }, { PARAMETER_UNSIGNED_INT, &rangeTileCounts }, { PARAMETER_UNSIGNED_INT, &Flags }, }; int numParameters = (sizeof(parameters) / sizeof(parameters[0])); DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_ID3D12CommandQueue_UpdateTileMappings, numParameters, parameters); mRealCommandQueue->UpdateTileMappings(pResourceUnwrapped, NumResourceRegions, pResourceRegionStartCoordinates, pResourceRegionSizes, pHeapUnwrapped, NumRanges, pRangeFlags, pHeapRangeStartOffsets, pRangeTileCounts, Flags); interceptor->PostCall(pNewEntry); } else { mRealCommandQueue->UpdateTileMappings(pResourceUnwrapped, NumResourceRegions, pResourceRegionStartCoordinates, pResourceRegionSizes, pHeapUnwrapped, NumRanges, pRangeFlags, pHeapRangeStartOffsets, pRangeTileCounts, Flags); } }
//----------------------------------------------------------------------------- /// Function which causes all necessary entrypoints to be hooked. /// \return true if hooking was successful; false will unload the wrapper //----------------------------------------------------------------------------- GPS_PLUGIN_API bool UpdateHooks() { Log(logTRACE, "DX12Server2's UpdateHooks.\n"); if (s_bInitialized == false) { if (InitPlugin() == false) { return false; } s_bInitialized = true; #ifdef DLL_REPLACEMENT // Load the real D3D12.dll and get a handle to it so that the real functions can // be obtained later if (s_hRealD3D12 == 0) { s_hRealD3D12 = DllReplacement::LoadRealLibrary("D3D12.dll"); if (!s_hRealD3D12) { Log(logERROR, "failed to load D3D12.dll\n"); return false; } } #endif // DLL_REPLACEMENT } DX12LayerManager* dx12LayerManager = GetDX12LayerManager(); #ifndef USE_OLD_DXGI_HOOKING ConnectWithDXGI(dx12LayerManager); #endif if (!dx12LayerManager->HasBeenInitialized()) { if (!dx12LayerManager->InitializeLayerManager()) { Log(logWARNING, "The DX12LayerManager was not initialized successfully.\n"); } } return true; }
//----------------------------------------------------------------------------- /// Wrapped_ID3D12QueryHeap::QueryInterface //----------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE Wrapped_ID3D12QueryHeap::QueryInterface(REFIID riid, void** ppvObject) { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif HRESULT result = {}; if (riid == IID_IWrappedObject) { *ppvObject = mRealQueryHeap; result = S_OK; } else { DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor->ShouldCollectTrace()) { ParameterEntry parameters[] = { { PARAMETER_REFIID, &riid }, { PARAMETER_POINTER, ppvObject }, }; int numParameters = (sizeof(parameters) / sizeof(parameters[0])); DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_IUnknown_QueryInterface, numParameters, parameters); result = mRealQueryHeap->QueryInterface(riid, ppvObject); interceptor->PostCall(pNewEntry, result); } else { result = mRealQueryHeap->QueryInterface(riid, ppvObject); } if (result == S_OK) { if (riid == __uuidof(ID3D12QueryHeap)) { WrapD3D12QueryHeap(nullptr, (ID3D12QueryHeap**)ppvObject); } } } return result; }
//----------------------------------------------------------------------------- /// Wrapped_ID3D12CommandQueue::ExecuteCommandLists //----------------------------------------------------------------------------- void STDMETHODCALLTYPE Wrapped_ID3D12CommandQueue::ExecuteCommandLists(UINT NumCommandLists, ID3D12CommandList* const* ppCommandLists) { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif ID3D12CommandList** ppCommandListsCopy = nullptr; if (NumCommandLists > 0) { ppCommandListsCopy = new ID3D12CommandList*[NumCommandLists]; for (UINT index = 0; index < NumCommandLists; index++) { DX12CoreDeepCopy::UnwrapInterface(ppCommandLists[index], &(ppCommandListsCopy[index])); } } DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor && interceptor->ShouldCollectTrace()) { int numParameters = NumCommandLists + 1; ParameterEntry* parameters = new ParameterEntry[numParameters]; parameters[0].mType = PARAMETER_UNSIGNED_INT; parameters[0].mData = &NumCommandLists; for (UINT loop = 0; loop < NumCommandLists; loop++) { parameters[loop + 1].mType = PARAMETER_POINTER; parameters[loop + 1].mData = ppCommandLists[loop]; } DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_ID3D12CommandQueue_ExecuteCommandLists, numParameters, parameters); mRealCommandQueue->ExecuteCommandLists(NumCommandLists, ppCommandListsCopy); interceptor->PostCall(pNewEntry); delete[] parameters; } else { mRealCommandQueue->ExecuteCommandLists(NumCommandLists, ppCommandListsCopy); } SAFE_DELETE_ARRAY(ppCommandListsCopy); }
//-------------------------------------------------------------------------- /// Entrypoint for the DX12Server plugin. Short rundown: /// On DLL_PROCESS_ATTACH, initialize the DX12LayerManager. /// On DLL_PROCESS_DETACH, kill and destroy the DX12LayerManager. /// \param hModule The module associated with this invocation of *this* DllMain. /// \param dwReason The reason that this function is being invoked. /// \param pReserved Reserved mystery pointer. /// \returns See http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx to understand this. //-------------------------------------------------------------------------- BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD dwReason, VOID* pReserved) { UNREFERENCED_PARAMETER(hModule); UNREFERENCED_PARAMETER(pReserved); Log(logTRACE, "DX12Server2's DllMain hit with reason '%d'\n", dwReason); switch (dwReason) { case DLL_PROCESS_ATTACH: { s_bHooked = s_bInitialized = false; } break; case DLL_PROCESS_DETACH: { #ifdef DLL_REPLACEMENT FreeLibrary(s_hRealD3D12); #endif // DLL_REPLACEMENT // Only shutdown the DX12LayerManager if it was initialized. DX12LayerManager* layerManager = GetDX12LayerManager(); if (layerManager->HasBeenInitialized()) { if (layerManager->ShutdownLayerManager() == false) { Log(logWARNING, "The DX12LayerManager was not shutdown successfully.\n"); } // Disconnect from the running DXGI server before we kill the plugin. #ifndef USE_OLD_DXGI_HOOKING DisconnectFromDXGI(layerManager); #endif } else { Log(logERROR, "DX12Server shutdown: The DX12LayerManager was not initialized.\n"); } } break; } return true; }
//----------------------------------------------------------------------------- /// Wrapped_ID3D12CommandQueue::EndEvent //----------------------------------------------------------------------------- void STDMETHODCALLTYPE Wrapped_ID3D12CommandQueue::EndEvent() { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor && interceptor->ShouldCollectTrace()) { DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_ID3D12CommandQueue_EndEvent, 0); mRealCommandQueue->EndEvent(); interceptor->PostCall(pNewEntry); } else { mRealCommandQueue->EndEvent(); } }
//----------------------------------------------------------------------------- /// Wrapped_ID3D12CommandAllocator::Reset //----------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE Wrapped_ID3D12CommandAllocator::Reset() { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif HRESULT result = {}; DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor->ShouldCollectTrace()) { DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_ID3D12CommandAllocator_Reset, 0, nullptr); result = mRealCommandAllocator->Reset(); interceptor->PostCall(pNewEntry, result); } else { result = mRealCommandAllocator->Reset(); } return result; }
//----------------------------------------------------------------------------- /// Wrapped_ID3D12DescriptorHeap::GetGPUDescriptorHandleForHeapStart //----------------------------------------------------------------------------- D3D12_GPU_DESCRIPTOR_HANDLE STDMETHODCALLTYPE Wrapped_ID3D12DescriptorHeap::GetGPUDescriptorHandleForHeapStart() { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif D3D12_GPU_DESCRIPTOR_HANDLE result = {}; DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor && interceptor->ShouldCollectTrace()) { DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart, 0, nullptr); result = mRealDescriptorHeap->GetGPUDescriptorHandleForHeapStart(); interceptor->PostCall(pNewEntry, static_cast<INT64>(result.ptr), RETURN_VALUE_HEX); } else { result = mRealDescriptorHeap->GetGPUDescriptorHandleForHeapStart(); } return result; }
//----------------------------------------------------------------------------- /// Wrapped_ID3D12QueryHeap::AddRef //----------------------------------------------------------------------------- ULONG STDMETHODCALLTYPE Wrapped_ID3D12QueryHeap::AddRef() { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif ULONG result = {}; DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor->ShouldCollectTrace()) { DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_IUnknown_AddRef, 0, nullptr); result = mRealQueryHeap->AddRef(); interceptor->PostCall(pNewEntry, result); } else { result = mRealQueryHeap->AddRef(); } return result; }
//----------------------------------------------------------------------------- /// Wrapped_ID3D12CommandList::GetType //----------------------------------------------------------------------------- D3D12_COMMAND_LIST_TYPE STDMETHODCALLTYPE Wrapped_ID3D12CommandList::GetType() { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif D3D12_COMMAND_LIST_TYPE result = {}; DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor && interceptor->ShouldCollectTrace()) { DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_ID3D12CommandList_GetType, 0, nullptr); result = mRealCommandList->GetType(); interceptor->PostCall(pNewEntry, result); } else { result = mRealCommandList->GetType(); } return result; }
//----------------------------------------------------------------------------- /// Wrapped_ID3D12CommandQueue::BeginEvent //----------------------------------------------------------------------------- void STDMETHODCALLTYPE Wrapped_ID3D12CommandQueue::BeginEvent(UINT Metadata, const void* pData, UINT Size) { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor && interceptor->ShouldCollectTrace()) { ParameterEntry parameters[] = { { PARAMETER_UNSIGNED_INT, &Metadata }, { PARAMETER_STRING, pData }, { PARAMETER_UNSIGNED_INT, &Size }, }; int numParameters = (sizeof(parameters) / sizeof(parameters[0])); if (Metadata == DirectX::Detail::PIX_EVENT_UNICODE_VERSION) { parameters[1].mType = PARAMETER_WIDE_STRING; } else if (Metadata != DirectX::Detail::PIX_EVENT_ANSI_VERSION) { numParameters = 0; } DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_ID3D12CommandQueue_BeginEvent, numParameters, parameters); mRealCommandQueue->BeginEvent(Metadata, pData, Size); interceptor->PostCall(pNewEntry); } else { mRealCommandQueue->BeginEvent(Metadata, pData, Size); } }
//----------------------------------------------------------------------------- /// Wrapped_ID3D12QueryHeap::GetDevice //----------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE Wrapped_ID3D12QueryHeap::GetDevice(REFIID riid, void** ppvDevice) { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif HRESULT result = {}; DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor->ShouldCollectTrace()) { ParameterEntry parameters[] = { { PARAMETER_REFIID, &riid }, { PARAMETER_POINTER, ppvDevice }, }; int numParameters = (sizeof(parameters) / sizeof(parameters[0])); DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_ID3D12DeviceChild_GetDevice, numParameters, parameters); result = mRealQueryHeap->GetDevice(riid, ppvDevice); interceptor->PostCall(pNewEntry, result); } else { result = mRealQueryHeap->GetDevice(riid, ppvDevice); } if (ppvDevice != nullptr && *ppvDevice != nullptr) { DX12WrappedObjectDatabase* objectDatabase = (DX12WrappedObjectDatabase*)DX12ObjectDatabaseProcessor::Instance()->GetObjectDatabase(); objectDatabase->WrappedObject((IUnknown**)ppvDevice); } return result; }
//----------------------------------------------------------------------------- /// Wrapped_ID3D12CommandQueue::GetDesc //----------------------------------------------------------------------------- D3D12_COMMAND_QUEUE_DESC STDMETHODCALLTYPE Wrapped_ID3D12CommandQueue::GetDesc() { #if SERIALIZE_DX12_ENTRY_POINTS ScopeLock lock(&s_mutex); #endif D3D12_COMMAND_QUEUE_DESC result = {}; DX12Interceptor* interceptor = GetDX12LayerManager()->GetInterceptor(); if (interceptor && interceptor->ShouldCollectTrace()) { DX12APIEntry* pNewEntry = interceptor->PreCall(this, FuncId_ID3D12CommandQueue_GetDesc, 0); result = mRealCommandQueue->GetDesc(); // TODO: get return value interceptor->PostCall(pNewEntry); } else { result = mRealCommandQueue->GetDesc(); } return result; }
//-------------------------------------------------------------------------- /// Exported function used in stepping the message pump for the server plugin. /// \param requestID The ID of a request that is in waiting to be processed. /// This ID can be used to query the contents of an incoming request. /// \return true if the request could be processed; false otherwise //-------------------------------------------------------------------------- GPS_PLUGIN_API bool ProcessRequest(CommunicationID requestID) { DX12LayerManager* dx12LayerManager = GetDX12LayerManager(); return dx12LayerManager->ProcessRequestFromCommId(requestID); }