diff --git a/renderdoc/driver/d3d12/d3d12_command_list.h b/renderdoc/driver/d3d12/d3d12_command_list.h index 301cf5a31..16290db62 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list.h +++ b/renderdoc/driver/d3d12/d3d12_command_list.h @@ -30,6 +30,7 @@ #include "d3d12_device.h" #include "d3d12_resources.h" +struct IAmdExtD3DCommandListMarker; class WrappedID3D12GraphicsCommandList; struct WrappedID3D12DebugCommandList : public ID3D12DebugCommandList @@ -89,6 +90,8 @@ class WrappedID3D12GraphicsCommandList : public RefCounter12SetMarker(Metadata, pData, Size); + if(m_AMDMarkers && Metadata == PIX_EVENT_UNICODE_VERSION) + m_AMDMarkers->SetMarker(StringFormat::Wide2UTF8((const wchar_t *)pData).c_str()); + if(m_State >= WRITING) { SCOPED_SERIALISE_CONTEXT(SET_MARKER); @@ -2769,6 +2773,9 @@ void WrappedID3D12GraphicsCommandList::BeginEvent(UINT Metadata, const void *pDa { m_pReal->BeginEvent(Metadata, pData, Size); + if(m_AMDMarkers && Metadata == PIX_EVENT_UNICODE_VERSION) + m_AMDMarkers->PushMarker(StringFormat::Wide2UTF8((const wchar_t *)pData).c_str()); + if(m_State >= WRITING) { SCOPED_SERIALISE_CONTEXT(BEGIN_EVENT); @@ -2827,6 +2834,9 @@ void WrappedID3D12GraphicsCommandList::EndEvent() { m_pReal->EndEvent(); + if(m_AMDMarkers) + m_AMDMarkers->PopMarker(); + if(m_State >= WRITING) { SCOPED_SERIALISE_CONTEXT(END_EVENT); diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index 7e8c671d7..42a5fc299 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -24,6 +24,7 @@ #include #include "driver/dxgi/dxgi_common.h" +#include "driver/ihv/amd/official/DXExt/AmdExtD3DCommandListMarkerApi.h" #include "d3d12_command_list.h" #include "d3d12_command_queue.h" @@ -658,6 +659,8 @@ WrappedID3D12GraphicsCommandList::WrappedID3D12GraphicsCommandList(ID3D12Graphic WrappedID3D12GraphicsCommandList::~WrappedID3D12GraphicsCommandList() { + SAFE_RELEASE(m_AMDMarkers); + if(m_pReal) m_pDevice->GetResourceManager()->RemoveWrapper(m_pReal); diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 9ea771e6b..6d03ad498 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -26,6 +26,7 @@ #include "core/core.h" #include "driver/dxgi/dxgi_common.h" #include "driver/dxgi/dxgi_wrapped.h" +#include "driver/ihv/amd/official/DXExt/AmdExtD3D.h" #include "jpeg-compressor/jpge.h" #include "maths/formatpacking.h" #include "serialise/string_utils.h" @@ -2060,6 +2061,23 @@ Serialiser *WrappedID3D12Device::GetThreadSerialiser() void WrappedID3D12Device::CreateInternalResources() { + // Initialise AMD extension, if possible + HMODULE mod = GetModuleHandleA("amdxc64.dll"); + + m_pAMDExtObject = NULL; + + if(mod) + { + PFNAmdExtD3DCreateInterface pAmdExtD3dCreateFunc = + (PFNAmdExtD3DCreateInterface)GetProcAddress(mod, "AmdExtD3DCreateInterface"); + + if(pAmdExtD3dCreateFunc != NULL) + { + // Initialize extension object + pAmdExtD3dCreateFunc(m_pDevice, __uuidof(IAmdExtD3DFactory), (void **)&m_pAMDExtObject); + } + } + CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void **)&m_Alloc); CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(ID3D12Fence), (void **)&m_GPUSyncFence); @@ -2086,6 +2104,8 @@ void WrappedID3D12Device::DestroyInternalResources() if(m_GPUSyncHandle == NULL) return; + SAFE_RELEASE(m_pAMDExtObject); + ExecuteLists(); FlushLists(true); diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index a5e49808f..5d5736355 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -38,6 +38,8 @@ #include "d3d12_manager.h" #include "d3d12_replay.h" +struct IAmdExtD3DFactory; + struct D3D12InitParams : public RDCInitParams { D3D12InitParams(); @@ -241,6 +243,8 @@ private: void CreateInternalResources(); void DestroyInternalResources(); + IAmdExtD3DFactory *m_pAMDExtObject = NULL; + D3D12ResourceManager *m_ResourceManager; DummyID3D12InfoQueue m_DummyInfoQueue; DummyID3D12DebugDevice m_DummyDebug; diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp index 52362dcec..0fa3d25d2 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp @@ -24,6 +24,8 @@ #include "d3d12_device.h" #include "driver/dxgi/dxgi_common.h" +#include "driver/ihv/amd/official/DXExt/AmdExtD3D.h" +#include "driver/ihv/amd/official/DXExt/AmdExtD3DCommandListMarkerApi.h" #include "d3d12_command_list.h" #include "d3d12_command_queue.h" #include "d3d12_resources.h" @@ -220,6 +222,14 @@ HRESULT WrappedID3D12Device::CreateCommandList(UINT nodeMask, D3D12_COMMAND_LIST WrappedID3D12GraphicsCommandList *wrapped = new WrappedID3D12GraphicsCommandList(real, this, m_pSerialiser, m_State); + if(m_pAMDExtObject) + { + IAmdExtD3DCommandListMarker *markers = NULL; + m_pAMDExtObject->CreateInterface(real, __uuidof(IAmdExtD3DCommandListMarker), + (void **)&markers); + wrapped->SetAMDMarkerInterface(markers); + } + if(m_State >= WRITING) { // we just serialise out command allocator creation as a reset, since it's equivalent. diff --git a/renderdoc/driver/ihv/amd/AMD.vcxproj b/renderdoc/driver/ihv/amd/AMD.vcxproj index a7445569f..b8875c334 100644 --- a/renderdoc/driver/ihv/amd/AMD.vcxproj +++ b/renderdoc/driver/ihv/amd/AMD.vcxproj @@ -108,6 +108,8 @@ + + diff --git a/renderdoc/driver/ihv/amd/AMD.vcxproj.filters b/renderdoc/driver/ihv/amd/AMD.vcxproj.filters index 6bfa6d97a..3aa60315a 100644 --- a/renderdoc/driver/ihv/amd/AMD.vcxproj.filters +++ b/renderdoc/driver/ihv/amd/AMD.vcxproj.filters @@ -110,5 +110,11 @@ ISA + + official\DXExt + + + official\DXExt + \ No newline at end of file diff --git a/renderdoc/driver/ihv/amd/official/DXExt/AmdExtD3D.h b/renderdoc/driver/ihv/amd/official/DXExt/AmdExtD3D.h new file mode 100644 index 000000000..4e1e3913d --- /dev/null +++ b/renderdoc/driver/ihv/amd/official/DXExt/AmdExtD3D.h @@ -0,0 +1,69 @@ +/* +*********************************************************************************************************************** +* +* Copyright (c) 2016 Advanced Micro Devices, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +*********************************************************************************************************************** +*/ +/** +*********************************************************************************************************************** +* @file AmdExtD3D.h +* @brief AMD D3D Exension API factory include file. +*********************************************************************************************************************** +*/ +#pragma once + +#include + +/* All AMD extensions contain the standard IUnknown interface: + * virtual HRESULT STDMETHODCALLTYPE QueryInterface( + * REFIID riid, + * _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) = 0; + * virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0; + * virtual ULONG STDMETHODCALLTYPE Release( void) = 0; + */ + + +// The app must use GetProcAddress, etc. to retrive this exported function +// The associated typedef provides a convenient way to define the function pointer +HRESULT __cdecl AmdExtD3DCreateInterface( + IUnknown* pOuter, ///< [in] object on which to base this new interface; usually a D3D device + REFIID riid, ///< ID of the requested interface + void** ppvObject); ///< [out] The result interface object +typedef HRESULT (__cdecl *PFNAmdExtD3DCreateInterface)(IUnknown* pOuter, REFIID riid, void** ppvObject); + +/** +*********************************************************************************************************************** +* @brief Abstract factory for extension interfaces +* +* Each extension interface (e.g. tessellation) will derive from this class +*********************************************************************************************************************** +*/ +interface __declspec (uuid("014937EC-9288-446F-A9AC-D75A8E3A984F")) +IAmdExtD3DFactory : public IUnknown +{ +public: + virtual HRESULT CreateInterface( + IUnknown* pOuter, ///< [in] An object on which to base this new interface; the required object type + ///< is usually a device object but not always + REFIID riid, ///< The ID of the requested interface + void** ppvObject) = 0; ///< [out] The result interface object +}; diff --git a/renderdoc/driver/ihv/amd/official/DXExt/AmdExtD3DCommandListMarkerApi.h b/renderdoc/driver/ihv/amd/official/DXExt/AmdExtD3DCommandListMarkerApi.h new file mode 100644 index 000000000..c97f5528a --- /dev/null +++ b/renderdoc/driver/ihv/amd/official/DXExt/AmdExtD3DCommandListMarkerApi.h @@ -0,0 +1,54 @@ +/* +*********************************************************************************************************************** +* +* Copyright (c) 2017 Advanced Micro Devices, Inc. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +*********************************************************************************************************************** +*/ + +/** +*********************************************************************************************************************** +* @file AmdExtD3DCommandListMarkerApi.h +* @brief +* AMD D3D Command List Marker API include file. +*********************************************************************************************************************** +*/ + +#pragma once + +#include + +/** +*********************************************************************************************************************** +* @brief D3D Command List Marker extension API object +*********************************************************************************************************************** +*/ +interface __declspec(uuid("735F1F3A-555D-4F70-AB92-7DB4A3AB1D28")) +IAmdExtD3DCommandListMarker : public IUnknown +{ +public: + /// Set a command list marker to indicate the beginning of a rendering pass + virtual VOID PushMarker(const char* pMarker) = 0; + /// Set a command list marker to indicate the end of the current rendering pass + virtual VOID PopMarker() = 0; + /// Set a command list marker to indicate a rendering activity + virtual VOID SetMarker(const char* pMarker) = 0; +}; \ No newline at end of file