mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-12 21:10:42 +00:00
Add support for D3D12On7
This commit is contained in:
@@ -903,7 +903,8 @@ bool WrappedID3D11Device::ProcessChunk(ReadSerialiser &ser, D3D11Chunk context)
|
||||
return true;
|
||||
}
|
||||
case D3D11Chunk::SetResourceName: return Serialise_SetResourceName(ser, 0x0, "");
|
||||
case D3D11Chunk::CreateSwapBuffer: return Serialise_WrapSwapchainBuffer(ser, 0x0, 0x0, 0, 0x0);
|
||||
case D3D11Chunk::CreateSwapBuffer:
|
||||
return Serialise_WrapSwapchainBuffer(ser, 0x0, DXGI_FORMAT_UNKNOWN, 0, 0x0);
|
||||
|
||||
case D3D11Chunk::CreateTexture1D: return Serialise_CreateTexture1D(ser, 0x0, 0x0, 0x0);
|
||||
case D3D11Chunk::CreateTexture2D: return Serialise_CreateTexture2D(ser, 0x0, 0x0, 0x0);
|
||||
@@ -1254,7 +1255,7 @@ void WrappedID3D11Device::ReplayLog(uint32_t startEventID, uint32_t endEventID,
|
||||
D3D11MarkerRegion::Set("!!!!RenderDoc Internal: Done replay");
|
||||
}
|
||||
|
||||
void WrappedID3D11Device::ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swap, UINT QueueCount,
|
||||
void WrappedID3D11Device::ReleaseSwapchainResources(IDXGISwapper *swapper, UINT QueueCount,
|
||||
IUnknown *const *ppPresentQueue,
|
||||
IUnknown **unwrappedQueues)
|
||||
{
|
||||
@@ -1267,9 +1268,9 @@ void WrappedID3D11Device::ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swap
|
||||
unwrappedQueues[i] = ppPresentQueue[i];
|
||||
}
|
||||
|
||||
for(int i = 0; i < swap->GetNumBackbuffers(); i++)
|
||||
for(int i = 0; i < swapper->GetNumBackbuffers(); i++)
|
||||
{
|
||||
WrappedID3D11Texture2D1 *wrapped11 = (WrappedID3D11Texture2D1 *)swap->GetBackbuffers()[i];
|
||||
WrappedID3D11Texture2D1 *wrapped11 = (WrappedID3D11Texture2D1 *)swapper->GetBackbuffers()[i];
|
||||
if(wrapped11)
|
||||
{
|
||||
ResourceRange range(wrapped11);
|
||||
@@ -1292,16 +1293,16 @@ void WrappedID3D11Device::ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swap
|
||||
wrapped11 = NULL;
|
||||
}
|
||||
|
||||
if(swap)
|
||||
HWND wnd = swapper->GetHWND();
|
||||
|
||||
if(wnd)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc = swap->GetDescWithHWND();
|
||||
Keyboard::RemoveInputWindow(wnd);
|
||||
|
||||
Keyboard::RemoveInputWindow(desc.OutputWindow);
|
||||
|
||||
RenderDoc::Inst().RemoveFrameCapturer((ID3D11Device *)this, desc.OutputWindow);
|
||||
RenderDoc::Inst().RemoveFrameCapturer((ID3D11Device *)this, wnd);
|
||||
}
|
||||
|
||||
auto it = m_SwapChains.find(swap);
|
||||
auto it = m_SwapChains.find(swapper);
|
||||
if(it != m_SwapChains.end())
|
||||
{
|
||||
SAFE_RELEASE(it->second);
|
||||
@@ -1310,9 +1311,8 @@ void WrappedID3D11Device::ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swap
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool WrappedID3D11Device::Serialise_WrapSwapchainBuffer(SerialiserType &ser,
|
||||
WrappedIDXGISwapChain4 *swap,
|
||||
DXGI_SWAP_CHAIN_DESC *swapDesc, UINT Buffer,
|
||||
bool WrappedID3D11Device::Serialise_WrapSwapchainBuffer(SerialiserType &ser, IDXGISwapper *swapper,
|
||||
DXGI_FORMAT bufferFormat, UINT Buffer,
|
||||
IUnknown *realSurface)
|
||||
{
|
||||
WrappedID3D11Texture2D1 *pTex = (WrappedID3D11Texture2D1 *)realSurface;
|
||||
@@ -1367,9 +1367,8 @@ bool WrappedID3D11Device::Serialise_WrapSwapchainBuffer(SerialiserType &ser,
|
||||
return true;
|
||||
}
|
||||
|
||||
IUnknown *WrappedID3D11Device::WrapSwapchainBuffer(WrappedIDXGISwapChain4 *swap,
|
||||
DXGI_SWAP_CHAIN_DESC *swapDesc, UINT buffer,
|
||||
IUnknown *realSurface)
|
||||
IUnknown *WrappedID3D11Device::WrapSwapchainBuffer(IDXGISwapper *swapper, DXGI_FORMAT bufferFormat,
|
||||
UINT buffer, IUnknown *realSurface)
|
||||
{
|
||||
if(GetResourceManager()->HasWrapper((ID3D11DeviceChild *)realSurface))
|
||||
{
|
||||
@@ -1415,7 +1414,7 @@ IUnknown *WrappedID3D11Device::WrapSwapchainBuffer(WrappedIDXGISwapChain4 *swap,
|
||||
|
||||
SCOPED_SERIALISE_CHUNK(D3D11Chunk::CreateSwapBuffer);
|
||||
|
||||
Serialise_WrapSwapchainBuffer(ser, swap, swapDesc, buffer, pTex);
|
||||
Serialise_WrapSwapchainBuffer(ser, swapper, bufferFormat, buffer, pTex);
|
||||
|
||||
record->AddChunk(scope.Get());
|
||||
}
|
||||
@@ -1428,16 +1427,16 @@ IUnknown *WrappedID3D11Device::WrapSwapchainBuffer(WrappedIDXGISwapChain4 *swap,
|
||||
if(FAILED(hr))
|
||||
RDCERR("Couldn't create RTV for swapchain tex HRESULT: %s", ToStr(hr).c_str());
|
||||
|
||||
m_SwapChains[swap] = rtv;
|
||||
m_SwapChains[swapper] = rtv;
|
||||
}
|
||||
|
||||
if(swap)
|
||||
HWND wnd = swapper->GetHWND();
|
||||
|
||||
if(wnd)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC sdesc = swap->GetDescWithHWND();
|
||||
Keyboard::AddInputWindow(wnd);
|
||||
|
||||
Keyboard::AddInputWindow(sdesc.OutputWindow);
|
||||
|
||||
RenderDoc::Inst().AddFrameCapturer((ID3D11Device *)this, sdesc.OutputWindow, this);
|
||||
RenderDoc::Inst().AddFrameCapturer((ID3D11Device *)this, wnd, this);
|
||||
}
|
||||
|
||||
return pTex;
|
||||
@@ -1531,22 +1530,20 @@ bool WrappedID3D11Device::EndFrameCapture(void *dev, void *wnd)
|
||||
|
||||
CaptureFailReason reason;
|
||||
|
||||
WrappedIDXGISwapChain4 *swap = NULL;
|
||||
IDXGISwapper *swapper = NULL;
|
||||
|
||||
if(wnd)
|
||||
{
|
||||
for(auto it = m_SwapChains.begin(); it != m_SwapChains.end(); ++it)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC swapDesc = it->first->GetDescWithHWND();
|
||||
|
||||
if(swapDesc.OutputWindow == wnd)
|
||||
if(it->first->GetHWND() == wnd)
|
||||
{
|
||||
swap = it->first;
|
||||
swapper = it->first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(swap == NULL)
|
||||
if(swapper == NULL)
|
||||
{
|
||||
RDCERR("Output window %p provided for frame capture corresponds with no known swap chain", wnd);
|
||||
return false;
|
||||
@@ -1581,9 +1578,9 @@ bool WrappedID3D11Device::EndFrameCapture(void *dev, void *wnd)
|
||||
const uint32_t maxSize = 2048;
|
||||
RenderDoc::FramePixels fp;
|
||||
|
||||
if(swap != NULL)
|
||||
if(swapper != NULL)
|
||||
{
|
||||
ID3D11RenderTargetView *rtv = m_SwapChains[swap];
|
||||
ID3D11RenderTargetView *rtv = m_SwapChains[swapper];
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
|
||||
@@ -1828,19 +1825,18 @@ bool WrappedID3D11Device::EndFrameCapture(void *dev, void *wnd)
|
||||
|
||||
m_Failures++;
|
||||
|
||||
if((RenderDoc::Inst().GetOverlayBits() & eRENDERDOC_Overlay_Enabled) && swap != NULL)
|
||||
if((RenderDoc::Inst().GetOverlayBits() & eRENDERDOC_Overlay_Enabled) && swapper)
|
||||
{
|
||||
D3D11RenderState old = *m_pImmediateContext->GetCurrentPipelineState();
|
||||
|
||||
ID3D11RenderTargetView *rtv = m_SwapChains[swap];
|
||||
ID3D11RenderTargetView *rtv = m_SwapChains[swapper];
|
||||
|
||||
if(rtv)
|
||||
{
|
||||
m_pImmediateContext->GetReal()->OMSetRenderTargets(1, &rtv, NULL);
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC swapDesc = swap->GetDescWithHWND();
|
||||
m_TextRenderer->SetOutputDimensions(swapDesc.BufferDesc.Width, swapDesc.BufferDesc.Height);
|
||||
m_TextRenderer->SetOutputWindow(swapDesc.OutputWindow);
|
||||
m_TextRenderer->SetOutputDimensions(swapper->GetWidth(), swapper->GetHeight());
|
||||
m_TextRenderer->SetOutputWindow(swapper->GetHWND());
|
||||
|
||||
m_TextRenderer->RenderText(0.0f, 0.0f, "Failed to capture frame %u: %s", m_FrameCounter,
|
||||
reasonString);
|
||||
@@ -2091,20 +2087,18 @@ void WrappedID3D11Device::UnlockForChunkRemoval()
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedID3D11Device::FirstFrame(WrappedIDXGISwapChain4 *swapChain)
|
||||
void WrappedID3D11Device::FirstFrame(IDXGISwapper *swapper)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC swapdesc = swapChain->GetDescWithHWND();
|
||||
|
||||
// if we have to capture the first frame, begin capturing immediately
|
||||
if(IsBackgroundCapturing(m_State) && RenderDoc::Inst().ShouldTriggerCapture(0))
|
||||
{
|
||||
RenderDoc::Inst().StartFrameCapture((ID3D11Device *)this, swapdesc.OutputWindow);
|
||||
RenderDoc::Inst().StartFrameCapture((ID3D11Device *)this, swapper->GetHWND());
|
||||
|
||||
m_AppControlledCapture = false;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D11Device::Present(WrappedIDXGISwapChain4 *swap, UINT SyncInterval, UINT Flags)
|
||||
HRESULT WrappedID3D11Device::Present(IDXGISwapper *swapper, UINT SyncInterval, UINT Flags)
|
||||
{
|
||||
if((Flags & DXGI_PRESENT_TEST) != 0)
|
||||
return S_OK;
|
||||
@@ -2120,8 +2114,7 @@ HRESULT WrappedID3D11Device::Present(WrappedIDXGISwapChain4 *swap, UINT SyncInte
|
||||
|
||||
m_pImmediateContext->BeginFrame();
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC swapdesc = swap->GetDescWithHWND();
|
||||
bool activeWindow = RenderDoc::Inst().IsActiveWindow((ID3D11Device *)this, swapdesc.OutputWindow);
|
||||
bool activeWindow = RenderDoc::Inst().IsActiveWindow((ID3D11Device *)this, swapper->GetHWND());
|
||||
|
||||
if(IsBackgroundCapturing(m_State))
|
||||
{
|
||||
@@ -2131,14 +2124,12 @@ HRESULT WrappedID3D11Device::Present(WrappedIDXGISwapChain4 *swap, UINT SyncInte
|
||||
|
||||
if(overlay & eRENDERDOC_Overlay_Enabled)
|
||||
{
|
||||
ID3D11RenderTargetView *rtv = m_SwapChains[swap];
|
||||
ID3D11RenderTargetView *rtv = m_SwapChains[swapper];
|
||||
|
||||
m_pImmediateContext->GetReal()->OMSetRenderTargets(1, &rtv, NULL);
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC swapDesc = {0};
|
||||
swap->GetDesc(&swapDesc);
|
||||
m_TextRenderer->SetOutputDimensions(swapDesc.BufferDesc.Width, swapDesc.BufferDesc.Height);
|
||||
m_TextRenderer->SetOutputWindow(swapDesc.OutputWindow);
|
||||
m_TextRenderer->SetOutputDimensions(swapper->GetWidth(), swapper->GetHeight());
|
||||
m_TextRenderer->SetOutputWindow(swapper->GetHWND());
|
||||
|
||||
int flags = activeWindow ? RenderDoc::eOverlay_ActiveWindow : 0;
|
||||
std::string overlayText =
|
||||
@@ -2175,12 +2166,12 @@ HRESULT WrappedID3D11Device::Present(WrappedIDXGISwapChain4 *swap, UINT SyncInte
|
||||
{
|
||||
m_pImmediateContext->Present(SyncInterval, Flags);
|
||||
|
||||
RenderDoc::Inst().EndFrameCapture((ID3D11Device *)this, swapdesc.OutputWindow);
|
||||
RenderDoc::Inst().EndFrameCapture((ID3D11Device *)this, swapper->GetHWND());
|
||||
}
|
||||
|
||||
if(IsBackgroundCapturing(m_State) && RenderDoc::Inst().ShouldTriggerCapture(m_FrameCounter))
|
||||
{
|
||||
RenderDoc::Inst().StartFrameCapture((ID3D11Device *)this, swapdesc.OutputWindow);
|
||||
RenderDoc::Inst().StartFrameCapture((ID3D11Device *)this, swapper->GetHWND());
|
||||
|
||||
m_AppControlledCapture = false;
|
||||
}
|
||||
|
||||
@@ -371,7 +371,7 @@ private:
|
||||
|
||||
static WrappedID3D11Device *m_pCurrentWrappedDevice;
|
||||
|
||||
std::map<WrappedIDXGISwapChain4 *, ID3D11RenderTargetView *> m_SwapChains;
|
||||
std::map<IDXGISwapper *, ID3D11RenderTargetView *> m_SwapChains;
|
||||
|
||||
uint32_t m_FrameCounter;
|
||||
uint32_t m_FailedFrame;
|
||||
@@ -440,7 +440,7 @@ public:
|
||||
void UnlockForChunkRemoval();
|
||||
|
||||
SDFile &GetStructuredFile() { return *m_StructuredFile; }
|
||||
void FirstFrame(WrappedIDXGISwapChain4 *swapChain);
|
||||
void FirstFrame(IDXGISwapper *swapper);
|
||||
|
||||
std::vector<DebugMessage> GetDebugMessages();
|
||||
void AddDebugMessage(DebugMessage msg);
|
||||
@@ -519,8 +519,8 @@ public:
|
||||
const char *Path);
|
||||
|
||||
// Swap Chain
|
||||
IMPLEMENT_FUNCTION_SERIALISED(IUnknown *, WrapSwapchainBuffer, WrappedIDXGISwapChain4 *swap,
|
||||
DXGI_SWAP_CHAIN_DESC *desc, UINT buffer, IUnknown *realSurface);
|
||||
IMPLEMENT_FUNCTION_SERIALISED(IUnknown *, WrapSwapchainBuffer, IDXGISwapper *swapper,
|
||||
DXGI_FORMAT bufferFormat, UINT buffer, IUnknown *realSurface);
|
||||
|
||||
// this is defined as a macro so that we can re-use it to explicitly instantiate these functions as
|
||||
// templates in the wrapper definition file.
|
||||
@@ -536,11 +536,11 @@ public:
|
||||
|
||||
SERIALISED_ID3D11DEVICE_FAKE_FUNCTIONS();
|
||||
|
||||
HRESULT Present(WrappedIDXGISwapChain4 *swap, UINT SyncInterval, UINT Flags);
|
||||
HRESULT Present(IDXGISwapper *swapper, UINT SyncInterval, UINT Flags);
|
||||
|
||||
void NewSwapchainBuffer(IUnknown *backbuffer);
|
||||
|
||||
void ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swap, UINT QueueCount,
|
||||
void ReleaseSwapchainResources(IDXGISwapper *swapper, UINT QueueCount,
|
||||
IUnknown *const *ppPresentQueue, IUnknown **unwrappedQueues);
|
||||
|
||||
ResourceId GetBackbufferResourceID() { return m_BBID; }
|
||||
|
||||
@@ -68,18 +68,43 @@ struct WrappedID3D12DebugCommandQueue : public ID3D12DebugCommandQueue
|
||||
}
|
||||
};
|
||||
|
||||
struct WrappedDownlevelQueue : public ID3D12CommandQueueDownlevel
|
||||
{
|
||||
WrappedID3D12CommandQueue &m_pQueue;
|
||||
|
||||
WrappedDownlevelQueue(WrappedID3D12CommandQueue &q) : m_pQueue(q) {}
|
||||
//////////////////////////////
|
||||
// implement IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
//////////////////////////////
|
||||
// implement ID3D12CommandQueueDownlevel
|
||||
virtual HRESULT STDMETHODCALLTYPE Present(ID3D12GraphicsCommandList *pOpenCommandList,
|
||||
ID3D12Resource *pSourceTex2D, HWND hWindow,
|
||||
D3D12_DOWNLEVEL_PRESENT_FLAGS Flags);
|
||||
};
|
||||
|
||||
class WrappedID3D12GraphicsCommandList;
|
||||
|
||||
class WrappedID3D12CommandQueue : public ID3D12CommandQueue,
|
||||
public RefCounter12<ID3D12CommandQueue>,
|
||||
public ID3DDevice
|
||||
public ID3DDevice,
|
||||
public IDXGISwapper
|
||||
{
|
||||
friend class WrappedID3D12GraphicsCommandList;
|
||||
|
||||
ID3D12CommandQueueDownlevel *m_pDownlevel;
|
||||
|
||||
WrappedDownlevelQueue m_WrappedDownlevel;
|
||||
|
||||
WrappedID3D12Device *m_pDevice;
|
||||
|
||||
WrappedID3D12GraphicsCommandList *m_ReplayList;
|
||||
|
||||
ID3D12Resource *m_pPresentSource = NULL;
|
||||
HWND m_pPresentHWND = NULL;
|
||||
|
||||
ResourceId m_ResourceID;
|
||||
D3D12ResourceRecord *m_QueueRecord;
|
||||
|
||||
@@ -155,27 +180,48 @@ public:
|
||||
return NULL;
|
||||
}
|
||||
// the rest forward to the device
|
||||
virtual void FirstFrame(WrappedIDXGISwapChain4 *swapChain) { m_pDevice->FirstFrame(swapChain); }
|
||||
virtual void FirstFrame(IDXGISwapper *swapper) { m_pDevice->FirstFrame(swapper); }
|
||||
virtual void NewSwapchainBuffer(IUnknown *backbuffer)
|
||||
{
|
||||
m_pDevice->NewSwapchainBuffer(backbuffer);
|
||||
}
|
||||
virtual void ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swapChain, UINT QueueCount,
|
||||
virtual void ReleaseSwapchainResources(IDXGISwapper *swapper, UINT QueueCount,
|
||||
IUnknown *const *ppPresentQueue, IUnknown **unwrappedQueues)
|
||||
{
|
||||
m_pDevice->ReleaseSwapchainResources(swapChain, QueueCount, ppPresentQueue, unwrappedQueues);
|
||||
m_pDevice->ReleaseSwapchainResources(swapper, QueueCount, ppPresentQueue, unwrappedQueues);
|
||||
}
|
||||
virtual IUnknown *WrapSwapchainBuffer(WrappedIDXGISwapChain4 *swap, DXGI_SWAP_CHAIN_DESC *swapDesc,
|
||||
virtual IUnknown *WrapSwapchainBuffer(IDXGISwapper *swapper, DXGI_FORMAT bufferFormat,
|
||||
UINT buffer, IUnknown *realSurface)
|
||||
{
|
||||
return m_pDevice->WrapSwapchainBuffer(swap, swapDesc, buffer, realSurface);
|
||||
return m_pDevice->WrapSwapchainBuffer(swapper, bufferFormat, buffer, realSurface);
|
||||
}
|
||||
|
||||
virtual HRESULT Present(WrappedIDXGISwapChain4 *swapChain, UINT SyncInterval, UINT Flags)
|
||||
virtual HRESULT Present(IDXGISwapper *swapper, UINT SyncInterval, UINT Flags)
|
||||
{
|
||||
return m_pDevice->Present(swapChain, SyncInterval, Flags);
|
||||
return m_pDevice->Present(swapper, SyncInterval, Flags);
|
||||
}
|
||||
|
||||
// fake pretending to be a swapchain for when we're doing downlevel mega-hacky presents
|
||||
virtual ID3DDevice *GetD3DDevice() { return this; }
|
||||
virtual int GetNumBackbuffers() { return 1; }
|
||||
virtual IUnknown **GetBackbuffers() { return (IUnknown **)&m_pPresentSource; }
|
||||
virtual int GetLastPresentedBuffer() { return 0; }
|
||||
virtual UINT GetWidth()
|
||||
{
|
||||
D3D12_RESOURCE_DESC desc = m_pPresentSource->GetDesc();
|
||||
return (UINT)desc.Width;
|
||||
}
|
||||
virtual UINT GetHeight()
|
||||
{
|
||||
D3D12_RESOURCE_DESC desc = m_pPresentSource->GetDesc();
|
||||
return desc.Height;
|
||||
}
|
||||
virtual DXGI_FORMAT GetFormat()
|
||||
{
|
||||
D3D12_RESOURCE_DESC desc = m_pPresentSource->GetDesc();
|
||||
return desc.Format;
|
||||
}
|
||||
virtual HWND GetHWND() { return m_pPresentHWND; }
|
||||
//////////////////////////////
|
||||
// implement IUnknown
|
||||
|
||||
@@ -252,7 +298,7 @@ public:
|
||||
|
||||
virtual void ExecuteCommandListsInternal(UINT NumCommandLists,
|
||||
ID3D12CommandList *const *ppCommandLists,
|
||||
bool InFrameCaptureBoundary);
|
||||
bool InFrameCaptureBoundary, bool SkipRealExecute);
|
||||
|
||||
IMPLEMENT_FUNCTION_SERIALISED(virtual void STDMETHODCALLTYPE, SetMarker, UINT Metadata,
|
||||
const void *pData, UINT Size);
|
||||
@@ -275,6 +321,11 @@ public:
|
||||
UINT64 *pGpuTimestamp, UINT64 *pCpuTimestamp);
|
||||
|
||||
virtual D3D12_COMMAND_QUEUE_DESC STDMETHODCALLTYPE GetDesc() { return m_pReal->GetDesc(); }
|
||||
//////////////////////////////
|
||||
// implement ID3D12CommandQueueDownlevel
|
||||
virtual HRESULT STDMETHODCALLTYPE Present(ID3D12GraphicsCommandList *pOpenCommandList,
|
||||
ID3D12Resource *pSourceTex2D, HWND hWindow,
|
||||
D3D12_DOWNLEVEL_PRESENT_FLAGS Flags);
|
||||
};
|
||||
|
||||
template <>
|
||||
|
||||
@@ -324,12 +324,13 @@ bool WrappedID3D12CommandQueue::Serialise_ExecuteCommandLists(SerialiserType &se
|
||||
void WrappedID3D12CommandQueue::ExecuteCommandLists(UINT NumCommandLists,
|
||||
ID3D12CommandList *const *ppCommandLists)
|
||||
{
|
||||
ExecuteCommandListsInternal(NumCommandLists, ppCommandLists, false);
|
||||
ExecuteCommandListsInternal(NumCommandLists, ppCommandLists, false, false);
|
||||
}
|
||||
|
||||
void WrappedID3D12CommandQueue::ExecuteCommandListsInternal(UINT NumCommandLists,
|
||||
ID3D12CommandList *const *ppCommandLists,
|
||||
bool InFrameCaptureBoundary)
|
||||
bool InFrameCaptureBoundary,
|
||||
bool SkipRealExecute)
|
||||
{
|
||||
ID3D12CommandList **unwrapped = m_pDevice->GetTempArray<ID3D12CommandList *>(NumCommandLists);
|
||||
for(UINT i = 0; i < NumCommandLists; i++)
|
||||
@@ -344,7 +345,10 @@ void WrappedID3D12CommandQueue::ExecuteCommandListsInternal(UINT NumCommandLists
|
||||
if(IsActiveCapturing(m_State))
|
||||
m_pDevice->AddCaptureSubmission();
|
||||
|
||||
SERIALISE_TIME_CALL(m_pReal->ExecuteCommandLists(NumCommandLists, unwrapped));
|
||||
if(!SkipRealExecute)
|
||||
{
|
||||
SERIALISE_TIME_CALL(m_pReal->ExecuteCommandLists(NumCommandLists, unwrapped));
|
||||
}
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
@@ -766,6 +770,65 @@ HRESULT STDMETHODCALLTYPE WrappedID3D12CommandQueue::GetClockCalibration(UINT64
|
||||
return m_pReal->GetClockCalibration(pGpuTimestamp, pCpuTimestamp);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedID3D12CommandQueue::Present(
|
||||
_In_ ID3D12GraphicsCommandList *pOpenCommandList, _In_ ID3D12Resource *pSourceTex2D,
|
||||
_In_ HWND hWindow, D3D12_DOWNLEVEL_PRESENT_FLAGS Flags)
|
||||
{
|
||||
// D3D12 on windows 7
|
||||
if(!RenderDoc::Inst().GetCaptureOptions().allowVSync)
|
||||
{
|
||||
Flags = D3D12_DOWNLEVEL_PRESENT_FLAG_NONE;
|
||||
}
|
||||
|
||||
// store the timestamp, thread ID etc. Don't store the duration
|
||||
SERIALISE_TIME_CALL();
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
WrappedID3D12GraphicsCommandList *list = (WrappedID3D12GraphicsCommandList *)pOpenCommandList;
|
||||
|
||||
// add a marker
|
||||
const char str[] = "ID3D12CommandQueueDownlevel::Present()";
|
||||
list->SetMarker(PIX_EVENT_ANSI_VERSION, str, sizeof(str));
|
||||
|
||||
// the list is implicitly closed, serialise that
|
||||
D3D12ResourceRecord *listRecord = GetRecord(list);
|
||||
|
||||
{
|
||||
CACHE_THREAD_SERIALISER();
|
||||
ser.SetDrawChunk();
|
||||
SCOPED_SERIALISE_CHUNK(D3D12Chunk::List_Close);
|
||||
list->Serialise_Close(ser);
|
||||
|
||||
listRecord->AddChunk(scope.Get());
|
||||
}
|
||||
|
||||
listRecord->Bake();
|
||||
|
||||
// this queue implicitly submits the list, serialise that
|
||||
ID3D12CommandList *submitlist = list;
|
||||
ExecuteCommandListsInternal(1, &submitlist, false, true);
|
||||
}
|
||||
|
||||
if(m_pPresentHWND != NULL)
|
||||
{
|
||||
// don't let the device actually release any refs on the resource, just make it release internal
|
||||
// resources
|
||||
m_pPresentSource->AddRef();
|
||||
m_pDevice->ReleaseSwapchainResources(this, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
m_pPresentSource = pSourceTex2D;
|
||||
m_pPresentHWND = hWindow;
|
||||
|
||||
m_pDevice->WrapSwapchainBuffer(this, GetFormat(), 0, m_pPresentSource);
|
||||
|
||||
m_pDevice->Present(pOpenCommandList, this,
|
||||
Flags == D3D12_DOWNLEVEL_PRESENT_FLAG_WAIT_FOR_VBLANK ? 1 : 0, 0);
|
||||
|
||||
return m_pDownlevel->Present(Unwrap(pOpenCommandList), Unwrap(pSourceTex2D), hWindow, Flags);
|
||||
}
|
||||
|
||||
INSTANTIATE_FUNCTION_SERIALISED(
|
||||
void, WrappedID3D12CommandQueue, UpdateTileMappings, ID3D12Resource *pResource,
|
||||
UINT NumResourceRegions, const D3D12_TILED_RESOURCE_COORDINATE *pResourceRegionStartCoordinates,
|
||||
|
||||
@@ -256,17 +256,43 @@ ULONG STDMETHODCALLTYPE WrappedID3D12DebugCommandList::Release()
|
||||
return 1;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedDownlevelQueue::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
return m_pQueue.QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE WrappedDownlevelQueue::AddRef()
|
||||
{
|
||||
return m_pQueue.AddRef();
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE WrappedDownlevelQueue::Release()
|
||||
{
|
||||
return m_pQueue.Release();
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedDownlevelQueue::Present(ID3D12GraphicsCommandList *pOpenCommandList,
|
||||
ID3D12Resource *pSourceTex2D, HWND hWindow,
|
||||
D3D12_DOWNLEVEL_PRESENT_FLAGS Flags)
|
||||
{
|
||||
return m_pQueue.Present(pOpenCommandList, pSourceTex2D, hWindow, Flags);
|
||||
}
|
||||
|
||||
WrappedID3D12CommandQueue::WrappedID3D12CommandQueue(ID3D12CommandQueue *real,
|
||||
WrappedID3D12Device *device, CaptureState &state)
|
||||
: RefCounter12(real), m_pDevice(device), m_State(state)
|
||||
: RefCounter12(real), m_pDevice(device), m_State(state), m_WrappedDownlevel(*this)
|
||||
{
|
||||
if(RenderDoc::Inst().GetCrashHandler())
|
||||
RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this,
|
||||
sizeof(WrappedID3D12CommandQueue));
|
||||
|
||||
m_WrappedDebug.m_pReal = NULL;
|
||||
m_pDownlevel = NULL;
|
||||
if(m_pReal)
|
||||
{
|
||||
m_pReal->QueryInterface(__uuidof(ID3D12DebugCommandQueue), (void **)&m_WrappedDebug.m_pReal);
|
||||
m_pReal->QueryInterface(__uuidof(ID3D12CommandQueueDownlevel), (void **)&m_pDownlevel);
|
||||
}
|
||||
|
||||
if(RenderDoc::Inst().IsReplayApp())
|
||||
{
|
||||
@@ -305,6 +331,8 @@ WrappedID3D12CommandQueue::~WrappedID3D12CommandQueue()
|
||||
m_pDevice->GetResourceManager()->ReleaseCurrentResource(GetResourceID());
|
||||
m_pDevice->RemoveQueue(this);
|
||||
|
||||
SAFE_RELEASE(m_pDownlevel);
|
||||
|
||||
for(size_t i = 0; i < m_Cmd.m_IndirectBuffers.size(); i++)
|
||||
SAFE_RELEASE(m_Cmd.m_IndirectBuffers[i]);
|
||||
|
||||
@@ -357,6 +385,19 @@ HRESULT STDMETHODCALLTYPE WrappedID3D12CommandQueue::QueryInterface(REFIID riid,
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12CommandQueueDownlevel))
|
||||
{
|
||||
if(m_pDownlevel)
|
||||
{
|
||||
*ppvObject = &m_WrappedDownlevel;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WarnUnknownGUID("ID3D12CommandQueue", riid);
|
||||
|
||||
@@ -140,6 +140,10 @@ bool EnableD3D12DebugLayer(PFN_D3D12_GET_DEBUG_INTERFACE getDebugInterface)
|
||||
|
||||
return true;
|
||||
}
|
||||
else if(hr == DXGI_ERROR_SDK_COMPONENT_MISSING)
|
||||
{
|
||||
RDCWARN("Debug layer not available: DXGI_ERROR_SDK_COMPONENT_MISSING");
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Couldn't enable debug layer: %x", hr);
|
||||
@@ -148,6 +152,38 @@ bool EnableD3D12DebugLayer(PFN_D3D12_GET_DEBUG_INTERFACE getDebugInterface)
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT EnumAdapterByLuid(IDXGIFactory1 *factory, LUID luid, IDXGIAdapter **pAdapter)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
*pAdapter = NULL;
|
||||
|
||||
for(UINT i = 0; i < 10; i++)
|
||||
{
|
||||
IDXGIAdapter *adapter = NULL;
|
||||
hr = factory->EnumAdapters(i, &adapter);
|
||||
if(hr == S_OK && adapter)
|
||||
{
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
adapter->GetDesc(&desc);
|
||||
|
||||
if(desc.AdapterLuid.LowPart == luid.LowPart && desc.AdapterLuid.HighPart == luid.HighPart)
|
||||
{
|
||||
*pAdapter = adapter;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
adapter->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
D3D12InitParams::D3D12InitParams()
|
||||
{
|
||||
MinimumFeatureLevel = D3D_FEATURE_LEVEL_11_0;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "api/replay/renderdoc_replay.h"
|
||||
#include "core/core.h"
|
||||
#include "driver/dx/official/D3D12Downlevel.h"
|
||||
#include "driver/dx/official/d3d12.h"
|
||||
#include "driver/dx/official/dxgi1_4.h"
|
||||
#include "driver/shaders/dxbc/dxbc_compile.h"
|
||||
@@ -53,6 +54,7 @@ struct D3D12MarkerRegion
|
||||
};
|
||||
|
||||
bool EnableD3D12DebugLayer(PFN_D3D12_GET_DEBUG_INTERFACE getDebugInterface = NULL);
|
||||
HRESULT EnumAdapterByLuid(IDXGIFactory1 *factory, LUID luid, IDXGIAdapter **pAdapter);
|
||||
|
||||
inline void SetObjName(ID3D12Object *obj, const std::string &utf8name)
|
||||
{
|
||||
|
||||
@@ -134,12 +134,35 @@ HRESULT STDMETHODCALLTYPE WrappedID3D12DebugDevice::QueryInterface(REFIID riid,
|
||||
return m_pDebug->QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedDownlevelDevice::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
return m_pDevice.QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE WrappedDownlevelDevice::AddRef()
|
||||
{
|
||||
return m_pDevice.AddRef();
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE WrappedDownlevelDevice::Release()
|
||||
{
|
||||
return m_pDevice.Release();
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedDownlevelDevice::QueryVideoMemoryInfo(
|
||||
UINT NodeIndex, DXGI_MEMORY_SEGMENT_GROUP MemorySegmentGroup,
|
||||
_Out_ DXGI_QUERY_VIDEO_MEMORY_INFO *pVideoMemoryInfo)
|
||||
{
|
||||
return m_pDevice.QueryVideoMemoryInfo(NodeIndex, MemorySegmentGroup, pVideoMemoryInfo);
|
||||
}
|
||||
|
||||
WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitParams params,
|
||||
bool enabledDebugLayer)
|
||||
: m_RefCounter(realDevice, false),
|
||||
m_SoftRefCounter(NULL, false),
|
||||
m_pDevice(realDevice),
|
||||
m_debugLayerEnabled(enabledDebugLayer)
|
||||
m_debugLayerEnabled(enabledDebugLayer),
|
||||
m_WrappedDownlevel(*this)
|
||||
{
|
||||
if(RenderDoc::Inst().GetCrashHandler())
|
||||
RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(WrappedID3D12Device));
|
||||
@@ -158,6 +181,7 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara
|
||||
m_pDevice3 = NULL;
|
||||
m_pDevice4 = NULL;
|
||||
m_pDevice5 = NULL;
|
||||
m_pDownlevel = NULL;
|
||||
if(m_pDevice)
|
||||
{
|
||||
m_pDevice->QueryInterface(__uuidof(ID3D12Device1), (void **)&m_pDevice1);
|
||||
@@ -165,6 +189,7 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara
|
||||
m_pDevice->QueryInterface(__uuidof(ID3D12Device3), (void **)&m_pDevice3);
|
||||
m_pDevice->QueryInterface(__uuidof(ID3D12Device4), (void **)&m_pDevice4);
|
||||
m_pDevice->QueryInterface(__uuidof(ID3D12Device5), (void **)&m_pDevice5);
|
||||
m_pDevice->QueryInterface(__uuidof(ID3D12DeviceDownlevel), (void **)&m_pDownlevel);
|
||||
|
||||
for(size_t i = 0; i < ARRAY_COUNT(m_DescriptorIncrements); i++)
|
||||
m_DescriptorIncrements[i] =
|
||||
@@ -235,8 +260,8 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara
|
||||
PFN_CREATE_DXGI_FACTORY createFunc = (PFN_CREATE_DXGI_FACTORY)GetProcAddress(
|
||||
GetModuleHandleA("dxgi.dll"), "CreateDXGIFactory1");
|
||||
|
||||
IDXGIFactory4 *tmpFactory = NULL;
|
||||
HRESULT hr = createFunc(__uuidof(IDXGIFactory4), (void **)&tmpFactory);
|
||||
IDXGIFactory1 *tmpFactory = NULL;
|
||||
HRESULT hr = createFunc(__uuidof(IDXGIFactory1), (void **)&tmpFactory);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
@@ -246,8 +271,7 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara
|
||||
if(tmpFactory)
|
||||
{
|
||||
IDXGIAdapter *pDXGIAdapter = NULL;
|
||||
hr = tmpFactory->EnumAdapterByLuid(m_pDevice->GetAdapterLuid(), __uuidof(IDXGIAdapter),
|
||||
(void **)&pDXGIAdapter);
|
||||
hr = EnumAdapterByLuid(tmpFactory, m_pDevice->GetAdapterLuid(), &pDXGIAdapter);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
@@ -432,6 +456,7 @@ WrappedID3D12Device::~WrappedID3D12Device()
|
||||
|
||||
SAFE_DELETE(m_ResourceManager);
|
||||
|
||||
SAFE_RELEASE(m_pDownlevel);
|
||||
SAFE_RELEASE(m_pDevice5);
|
||||
SAFE_RELEASE(m_pDevice4);
|
||||
SAFE_RELEASE(m_pDevice3);
|
||||
@@ -614,6 +639,19 @@ HRESULT WrappedID3D12Device::QueryInterface(REFIID riid, void **ppvObject)
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12DeviceDownlevel))
|
||||
{
|
||||
if(m_pDownlevel)
|
||||
{
|
||||
*ppvObject = &m_WrappedDownlevel;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12InfoQueue))
|
||||
{
|
||||
RDCWARN(
|
||||
@@ -783,17 +821,12 @@ void WrappedID3D12Device::CheckForDeath()
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::FirstFrame(WrappedIDXGISwapChain4 *swap)
|
||||
void WrappedID3D12Device::FirstFrame(IDXGISwapper *swapper)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC swapdesc = {};
|
||||
|
||||
if(swap)
|
||||
swapdesc = swap->GetDescWithHWND();
|
||||
|
||||
// if we have to capture the first frame, begin capturing immediately
|
||||
if(IsBackgroundCapturing(m_State) && RenderDoc::Inst().ShouldTriggerCapture(0))
|
||||
{
|
||||
RenderDoc::Inst().StartFrameCapture((ID3D12Device *)this, swapdesc.OutputWindow);
|
||||
RenderDoc::Inst().StartFrameCapture((ID3D12Device *)this, swapper->GetHWND());
|
||||
|
||||
m_AppControlledCapture = false;
|
||||
}
|
||||
@@ -805,7 +838,7 @@ void WrappedID3D12Device::ApplyBarriers(std::vector<D3D12_RESOURCE_BARRIER> &bar
|
||||
GetResourceManager()->ApplyBarriers(barriers, m_ResourceStates);
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swap, UINT QueueCount,
|
||||
void WrappedID3D12Device::ReleaseSwapchainResources(IDXGISwapper *swapper, UINT QueueCount,
|
||||
IUnknown *const *ppPresentQueue,
|
||||
IUnknown **unwrappedQueues)
|
||||
{
|
||||
@@ -820,9 +853,9 @@ void WrappedID3D12Device::ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swap
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < swap->GetNumBackbuffers(); i++)
|
||||
for(int i = 0; i < swapper->GetNumBackbuffers(); i++)
|
||||
{
|
||||
ID3D12Resource *res = (ID3D12Resource *)swap->GetBackbuffers()[i];
|
||||
ID3D12Resource *res = (ID3D12Resource *)swapper->GetBackbuffers()[i];
|
||||
|
||||
if(!res)
|
||||
continue;
|
||||
@@ -832,19 +865,19 @@ void WrappedID3D12Device::ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swap
|
||||
SAFE_RELEASE(wrapped);
|
||||
}
|
||||
|
||||
if(swap)
|
||||
HWND wnd = swapper->GetHWND();
|
||||
|
||||
if(wnd)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc = swap->GetDescWithHWND();
|
||||
Keyboard::RemoveInputWindow(wnd);
|
||||
|
||||
Keyboard::RemoveInputWindow(desc.OutputWindow);
|
||||
|
||||
RenderDoc::Inst().RemoveFrameCapturer((ID3D12Device *)this, desc.OutputWindow);
|
||||
RenderDoc::Inst().RemoveFrameCapturer((ID3D12Device *)this, wnd);
|
||||
}
|
||||
|
||||
auto it = m_SwapChains.find(swap);
|
||||
auto it = m_SwapChains.find(swapper);
|
||||
if(it != m_SwapChains.end())
|
||||
{
|
||||
for(int i = 0; i < swap->GetNumBackbuffers(); i++)
|
||||
for(int i = 0; i < swapper->GetNumBackbuffers(); i++)
|
||||
FreeRTV(it->second.rtvs[i]);
|
||||
|
||||
m_SwapChains.erase(it);
|
||||
@@ -863,9 +896,8 @@ void WrappedID3D12Device::NewSwapchainBuffer(IUnknown *backbuffer)
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool WrappedID3D12Device::Serialise_WrapSwapchainBuffer(SerialiserType &ser,
|
||||
WrappedIDXGISwapChain4 *swap,
|
||||
DXGI_SWAP_CHAIN_DESC *swapDesc, UINT Buffer,
|
||||
bool WrappedID3D12Device::Serialise_WrapSwapchainBuffer(SerialiserType &ser, IDXGISwapper *swapper,
|
||||
DXGI_FORMAT bufferFormat, UINT Buffer,
|
||||
IUnknown *realSurface)
|
||||
{
|
||||
WrappedID3D12Resource1 *pRes = (WrappedID3D12Resource1 *)realSurface;
|
||||
@@ -928,60 +960,70 @@ bool WrappedID3D12Device::Serialise_WrapSwapchainBuffer(SerialiserType &ser,
|
||||
return true;
|
||||
}
|
||||
|
||||
IUnknown *WrappedID3D12Device::WrapSwapchainBuffer(WrappedIDXGISwapChain4 *swap,
|
||||
DXGI_SWAP_CHAIN_DESC *swapDesc, UINT buffer,
|
||||
IUnknown *realSurface)
|
||||
IUnknown *WrappedID3D12Device::WrapSwapchainBuffer(IDXGISwapper *swapper, DXGI_FORMAT bufferFormat,
|
||||
UINT buffer, IUnknown *realSurface)
|
||||
{
|
||||
if(GetResourceManager()->HasWrapper((ID3D12DeviceChild *)realSurface))
|
||||
ID3D12Resource *pRes = NULL;
|
||||
|
||||
ID3D12Resource *query = NULL;
|
||||
realSurface->QueryInterface(__uuidof(ID3D12Resource), (void **)&query);
|
||||
if(query)
|
||||
query->Release();
|
||||
|
||||
if(GetResourceManager()->HasWrapper(query))
|
||||
{
|
||||
ID3D12Resource *tex =
|
||||
(ID3D12Resource *)GetResourceManager()->GetWrapper((ID3D12DeviceChild *)realSurface);
|
||||
tex->AddRef();
|
||||
pRes = (ID3D12Resource *)GetResourceManager()->GetWrapper(query);
|
||||
pRes->AddRef();
|
||||
|
||||
realSurface->Release();
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
ID3D12Resource *pRes = new WrappedID3D12Resource1((ID3D12Resource *)realSurface, this);
|
||||
|
||||
ResourceId id = GetResID(pRes);
|
||||
|
||||
// there shouldn't be a resource record for this texture as it wasn't created via
|
||||
// Create*Resource
|
||||
RDCASSERT(id != ResourceId() && !GetResourceManager()->HasResourceRecord(id));
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
else if(WrappedID3D12Resource1::IsAlloc(query))
|
||||
{
|
||||
D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(id);
|
||||
record->type = Resource_Resource;
|
||||
record->DataInSerialiser = false;
|
||||
record->Length = 0;
|
||||
// this could be possible if we're doing downlevel presenting
|
||||
pRes = query;
|
||||
}
|
||||
else
|
||||
{
|
||||
pRes = new WrappedID3D12Resource1((ID3D12Resource *)realSurface, this);
|
||||
|
||||
WrappedID3D12Resource1 *wrapped = (WrappedID3D12Resource1 *)pRes;
|
||||
ResourceId id = GetResID(pRes);
|
||||
|
||||
wrapped->SetResourceRecord(record);
|
||||
|
||||
WriteSerialiser &ser = GetThreadSerialiser();
|
||||
|
||||
SCOPED_SERIALISE_CHUNK(D3D12Chunk::CreateSwapBuffer);
|
||||
|
||||
Serialise_WrapSwapchainBuffer(ser, swap, swapDesc, buffer, pRes);
|
||||
|
||||
record->AddChunk(scope.Get());
|
||||
// there shouldn't be a resource record for this texture as it wasn't created via
|
||||
// Create*Resource
|
||||
RDCASSERT(id != ResourceId() && !GetResourceManager()->HasResourceRecord(id));
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
SCOPED_LOCK(m_ResourceStatesLock);
|
||||
SubresourceStateVector &states = m_ResourceStates[id];
|
||||
D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(id);
|
||||
record->type = Resource_Resource;
|
||||
record->DataInSerialiser = false;
|
||||
record->Length = 0;
|
||||
|
||||
states.resize(1, D3D12_RESOURCE_STATE_PRESENT);
|
||||
WrappedID3D12Resource1 *wrapped = (WrappedID3D12Resource1 *)pRes;
|
||||
|
||||
wrapped->SetResourceRecord(record);
|
||||
|
||||
WriteSerialiser &ser = GetThreadSerialiser();
|
||||
|
||||
SCOPED_SERIALISE_CHUNK(D3D12Chunk::CreateSwapBuffer);
|
||||
|
||||
Serialise_WrapSwapchainBuffer(ser, swapper, bufferFormat, buffer, pRes);
|
||||
|
||||
record->AddChunk(scope.Get());
|
||||
|
||||
{
|
||||
SCOPED_LOCK(m_ResourceStatesLock);
|
||||
SubresourceStateVector &states = m_ResourceStates[id];
|
||||
|
||||
states.resize(1, D3D12_RESOURCE_STATE_PRESENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
{
|
||||
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
|
||||
rtvDesc.Format = GetSRGBFormat(swapDesc->BufferDesc.Format);
|
||||
rtvDesc.Format = GetSRGBFormat(bufferFormat);
|
||||
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
|
||||
rtvDesc.Texture2D.MipSlice = 0;
|
||||
rtvDesc.Texture2D.PlaneSlice = 0;
|
||||
@@ -991,23 +1033,20 @@ IUnknown *WrappedID3D12Device::WrapSwapchainBuffer(WrappedIDXGISwapChain4 *swap,
|
||||
if(rtv.ptr != 0)
|
||||
CreateRenderTargetView(pRes, NULL, rtv);
|
||||
|
||||
m_SwapChains[swap].rtvs[buffer] = rtv;
|
||||
m_SwapChains[swapper].rtvs[buffer] = rtv;
|
||||
|
||||
ID3DDevice *swapQ = swap->GetD3DDevice();
|
||||
ID3DDevice *swapQ = swapper->GetD3DDevice();
|
||||
RDCASSERT(WrappedID3D12CommandQueue::IsAlloc(swapQ));
|
||||
m_SwapChains[swap].queue = (WrappedID3D12CommandQueue *)swapQ;
|
||||
|
||||
// start at -1 so that we know we've never presented before
|
||||
m_SwapChains[swap].lastPresentedBuffer = -1;
|
||||
m_SwapChains[swapper].queue = (WrappedID3D12CommandQueue *)swapQ;
|
||||
}
|
||||
|
||||
if(swap)
|
||||
HWND wnd = swapper->GetHWND();
|
||||
|
||||
if(wnd)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC sdesc = swap->GetDescWithHWND();
|
||||
Keyboard::AddInputWindow(wnd);
|
||||
|
||||
Keyboard::AddInputWindow(sdesc.OutputWindow);
|
||||
|
||||
RenderDoc::Inst().AddFrameCapturer((ID3D12Device *)this, sdesc.OutputWindow, this);
|
||||
RenderDoc::Inst().AddFrameCapturer((ID3D12Device *)this, wnd, this);
|
||||
}
|
||||
|
||||
return pRes;
|
||||
@@ -1330,7 +1369,8 @@ void WrappedID3D12Device::WriteToSubresource(ID3D12Resource *Resource, UINT Subr
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::Present(WrappedIDXGISwapChain4 *swap, UINT SyncInterval, UINT Flags)
|
||||
HRESULT WrappedID3D12Device::Present(ID3D12GraphicsCommandList *pOverlayCommandList,
|
||||
IDXGISwapper *swapper, UINT SyncInterval, UINT Flags)
|
||||
{
|
||||
if((Flags & DXGI_PRESENT_TEST) != 0)
|
||||
return S_OK;
|
||||
@@ -1340,22 +1380,9 @@ HRESULT WrappedID3D12Device::Present(WrappedIDXGISwapChain4 *swap, UINT SyncInte
|
||||
|
||||
m_FrameCounter++; // first present becomes frame #1, this function is at the end of the frame
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC swapdesc = swap->GetDescWithHWND();
|
||||
bool activeWindow = RenderDoc::Inst().IsActiveWindow((ID3D12Device *)this, swapdesc.OutputWindow);
|
||||
bool activeWindow = RenderDoc::Inst().IsActiveWindow((ID3D12Device *)this, swapper->GetHWND());
|
||||
|
||||
m_LastSwap = swap;
|
||||
|
||||
if(swapdesc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD)
|
||||
{
|
||||
// discard always presents from 0
|
||||
m_SwapChains[swap].lastPresentedBuffer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// other modes use each buffer in turn
|
||||
m_SwapChains[swap].lastPresentedBuffer++;
|
||||
m_SwapChains[swap].lastPresentedBuffer %= swapdesc.BufferCount;
|
||||
}
|
||||
m_LastSwap = swapper;
|
||||
|
||||
if(IsBackgroundCapturing(m_State))
|
||||
{
|
||||
@@ -1363,20 +1390,27 @@ HRESULT WrappedID3D12Device::Present(WrappedIDXGISwapChain4 *swap, UINT SyncInte
|
||||
|
||||
if(overlay & eRENDERDOC_Overlay_Enabled)
|
||||
{
|
||||
SwapPresentInfo &swapInfo = m_SwapChains[swap];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtv = swapInfo.rtvs[swapInfo.lastPresentedBuffer];
|
||||
SwapPresentInfo &swapInfo = m_SwapChains[swapper];
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtv = swapInfo.rtvs[swapper->GetLastPresentedBuffer()];
|
||||
|
||||
if(rtv.ptr)
|
||||
{
|
||||
m_TextRenderer->SetOutputDimensions(swapdesc.BufferDesc.Width, swapdesc.BufferDesc.Height,
|
||||
swapdesc.BufferDesc.Format);
|
||||
m_TextRenderer->SetOutputDimensions(swapper->GetWidth(), swapper->GetHeight(),
|
||||
swapper->GetFormat());
|
||||
|
||||
ID3D12GraphicsCommandList *list = GetNewList();
|
||||
ID3D12GraphicsCommandList *list = pOverlayCommandList;
|
||||
bool submitlist = false;
|
||||
|
||||
if(!list)
|
||||
{
|
||||
list = GetNewList();
|
||||
submitlist = true;
|
||||
}
|
||||
|
||||
// buffer will be in common for presentation, transition to render target
|
||||
D3D12_RESOURCE_BARRIER barrier = {};
|
||||
barrier.Transition.pResource =
|
||||
(ID3D12Resource *)swap->GetBackbuffers()[swapInfo.lastPresentedBuffer];
|
||||
(ID3D12Resource *)swapper->GetBackbuffers()[swapper->GetLastPresentedBuffer()];
|
||||
barrier.Transition.Subresource = 0;
|
||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COMMON;
|
||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
@@ -1399,10 +1433,13 @@ HRESULT WrappedID3D12Device::Present(WrappedIDXGISwapChain4 *swap, UINT SyncInte
|
||||
std::swap(barrier.Transition.StateBefore, barrier.Transition.StateAfter);
|
||||
list->ResourceBarrier(1, &barrier);
|
||||
|
||||
list->Close();
|
||||
if(submitlist)
|
||||
{
|
||||
list->Close();
|
||||
|
||||
ExecuteLists(swapInfo.queue);
|
||||
FlushLists(false, swapInfo.queue);
|
||||
ExecuteLists(swapInfo.queue);
|
||||
FlushLists(false, swapInfo.queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1418,11 +1455,11 @@ HRESULT WrappedID3D12Device::Present(WrappedIDXGISwapChain4 *swap, UINT SyncInte
|
||||
|
||||
// kill any current capture that isn't application defined
|
||||
if(IsActiveCapturing(m_State) && !m_AppControlledCapture)
|
||||
RenderDoc::Inst().EndFrameCapture((ID3D12Device *)this, swapdesc.OutputWindow);
|
||||
RenderDoc::Inst().EndFrameCapture((ID3D12Device *)this, swapper->GetHWND());
|
||||
|
||||
if(IsBackgroundCapturing(m_State) && RenderDoc::Inst().ShouldTriggerCapture(m_FrameCounter))
|
||||
{
|
||||
RenderDoc::Inst().StartFrameCapture((ID3D12Device *)this, swapdesc.OutputWindow);
|
||||
RenderDoc::Inst().StartFrameCapture((ID3D12Device *)this, swapper->GetHWND());
|
||||
|
||||
m_AppControlledCapture = false;
|
||||
}
|
||||
@@ -1565,24 +1602,22 @@ bool WrappedID3D12Device::EndFrameCapture(void *dev, void *wnd)
|
||||
if(!IsActiveCapturing(m_State))
|
||||
return true;
|
||||
|
||||
WrappedIDXGISwapChain4 *swap = NULL;
|
||||
IDXGISwapper *swapper = NULL;
|
||||
SwapPresentInfo swapInfo = {};
|
||||
|
||||
if(wnd)
|
||||
{
|
||||
for(auto it = m_SwapChains.begin(); it != m_SwapChains.end(); ++it)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC swapDesc = it->first->GetDescWithHWND();
|
||||
|
||||
if(swapDesc.OutputWindow == wnd)
|
||||
if(it->first->GetHWND() == wnd)
|
||||
{
|
||||
swap = it->first;
|
||||
swapper = it->first;
|
||||
swapInfo = it->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(swap == NULL)
|
||||
if(swapper == NULL)
|
||||
{
|
||||
RDCERR("Output window %p provided for frame capture corresponds with no known swap chain", wnd);
|
||||
return false;
|
||||
@@ -1593,14 +1628,14 @@ bool WrappedID3D12Device::EndFrameCapture(void *dev, void *wnd)
|
||||
|
||||
ID3D12Resource *backbuffer = NULL;
|
||||
|
||||
if(swap == NULL)
|
||||
if(swapper == NULL)
|
||||
{
|
||||
swap = m_LastSwap;
|
||||
swapInfo = m_SwapChains[swap];
|
||||
swapper = m_LastSwap;
|
||||
swapInfo = m_SwapChains[swapper];
|
||||
}
|
||||
|
||||
if(swap != NULL)
|
||||
backbuffer = (ID3D12Resource *)swap->GetBackbuffers()[swapInfo.lastPresentedBuffer];
|
||||
if(swapper != NULL)
|
||||
backbuffer = (ID3D12Resource *)swapper->GetBackbuffers()[swapper->GetLastPresentedBuffer()];
|
||||
|
||||
std::vector<WrappedID3D12CommandQueue *> queues;
|
||||
RDCFile *rdc = NULL;
|
||||
@@ -2266,6 +2301,13 @@ void WrappedID3D12Device::SetName(ID3D12DeviceChild *pResource, const char *Name
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedID3D12Device::QueryVideoMemoryInfo(
|
||||
UINT NodeIndex, DXGI_MEMORY_SEGMENT_GROUP MemorySegmentGroup,
|
||||
_Out_ DXGI_QUERY_VIDEO_MEMORY_INFO *pVideoMemoryInfo)
|
||||
{
|
||||
return m_pDownlevel->QueryVideoMemoryInfo(NodeIndex, MemorySegmentGroup, pVideoMemoryInfo);
|
||||
}
|
||||
|
||||
byte *WrappedID3D12Device::GetTempMemory(size_t s)
|
||||
{
|
||||
TempMem *mem = (TempMem *)Threading::GetTLSValue(tempMemoryTLSSlot);
|
||||
@@ -2577,8 +2619,13 @@ void WrappedID3D12Device::ExecuteList(ID3D12GraphicsCommandList4 *list,
|
||||
queue = GetQueue();
|
||||
|
||||
ID3D12CommandList *l = list;
|
||||
queue->ExecuteCommandListsInternal(1, &l, InFrameCaptureBoundary);
|
||||
queue->ExecuteCommandListsInternal(1, &l, InFrameCaptureBoundary, false);
|
||||
|
||||
MarkListExecuted(list);
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::MarkListExecuted(ID3D12GraphicsCommandList4 *list)
|
||||
{
|
||||
for(auto it = m_InternalCmds.pendingcmds.begin(); it != m_InternalCmds.pendingcmds.end(); ++it)
|
||||
{
|
||||
if(list == *it)
|
||||
@@ -2605,7 +2652,7 @@ void WrappedID3D12Device::ExecuteLists(WrappedID3D12CommandQueue *queue, bool In
|
||||
if(queue == NULL)
|
||||
queue = GetQueue();
|
||||
|
||||
queue->ExecuteCommandListsInternal((UINT)cmds.size(), &cmds[0], InFrameCaptureBoundary);
|
||||
queue->ExecuteCommandListsInternal((UINT)cmds.size(), &cmds[0], InFrameCaptureBoundary, false);
|
||||
|
||||
m_InternalCmds.submittedcmds.insert(m_InternalCmds.submittedcmds.end(),
|
||||
m_InternalCmds.pendingcmds.begin(),
|
||||
@@ -2693,7 +2740,7 @@ bool WrappedID3D12Device::ProcessChunk(ReadSerialiser &ser, D3D12Chunk context)
|
||||
return Serialise_SetShaderDebugPath(ser, NULL, NULL);
|
||||
break;
|
||||
case D3D12Chunk::CreateSwapBuffer:
|
||||
return Serialise_WrapSwapchainBuffer(ser, NULL, NULL, 0, NULL);
|
||||
return Serialise_WrapSwapchainBuffer(ser, NULL, DXGI_FORMAT_UNKNOWN, 0, NULL);
|
||||
break;
|
||||
case D3D12Chunk::Device_CreatePipelineState:
|
||||
return Serialise_CreatePipelineState(ser, NULL, IID(), NULL);
|
||||
|
||||
@@ -268,6 +268,23 @@ struct DummyID3D12DebugDevice : public ID3D12DebugDevice2, public ID3D12DebugDev
|
||||
}
|
||||
};
|
||||
|
||||
struct WrappedDownlevelDevice : public ID3D12DeviceDownlevel
|
||||
{
|
||||
WrappedID3D12Device &m_pDevice;
|
||||
|
||||
WrappedDownlevelDevice(WrappedID3D12Device &dev) : m_pDevice(dev) {}
|
||||
//////////////////////////////
|
||||
// implement IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
//////////////////////////////
|
||||
// implement ID3D12DeviceDownlevel
|
||||
virtual HRESULT STDMETHODCALLTYPE
|
||||
QueryVideoMemoryInfo(UINT NodeIndex, DXGI_MEMORY_SEGMENT_GROUP MemorySegmentGroup,
|
||||
_Out_ DXGI_QUERY_VIDEO_MEMORY_INFO *pVideoMemoryInfo);
|
||||
};
|
||||
|
||||
class WrappedID3D12CommandQueue;
|
||||
|
||||
#define IMPLEMENT_FUNCTION_THREAD_SERIALISED(ret, func, ...) \
|
||||
@@ -284,6 +301,7 @@ private:
|
||||
ID3D12Device3 *m_pDevice3;
|
||||
ID3D12Device4 *m_pDevice4;
|
||||
ID3D12Device5 *m_pDevice5;
|
||||
ID3D12DeviceDownlevel *m_pDownlevel;
|
||||
|
||||
// list of all queues being captured
|
||||
std::vector<WrappedID3D12CommandQueue *> m_Queues;
|
||||
@@ -299,6 +317,8 @@ private:
|
||||
HANDLE m_GPUSyncHandle;
|
||||
UINT64 m_GPUSyncCounter;
|
||||
|
||||
WrappedDownlevelDevice m_WrappedDownlevel;
|
||||
|
||||
std::vector<ID3D12CommandAllocator *> m_CommandAllocators;
|
||||
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE AllocRTV();
|
||||
@@ -405,14 +425,12 @@ private:
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtvs[8];
|
||||
|
||||
WrappedID3D12CommandQueue *queue;
|
||||
|
||||
int32_t lastPresentedBuffer;
|
||||
};
|
||||
|
||||
std::map<WrappedIDXGISwapChain4 *, SwapPresentInfo> m_SwapChains;
|
||||
std::map<IDXGISwapper *, SwapPresentInfo> m_SwapChains;
|
||||
std::map<ResourceId, DXGI_FORMAT> m_BackbufferFormat;
|
||||
|
||||
WrappedIDXGISwapChain4 *m_LastSwap;
|
||||
IDXGISwapper *m_LastSwap;
|
||||
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS m_D3D12Opts;
|
||||
D3D12_FEATURE_DATA_D3D12_OPTIONS1 m_D3D12Opts1;
|
||||
@@ -460,7 +478,7 @@ public:
|
||||
ResourceId GetResourceID() { return m_ResourceID; }
|
||||
Threading::RWLock &GetCapTransitionLock() { return m_CapTransitionLock; }
|
||||
void ReleaseSwapchainResources(IDXGISwapChain *swap, IUnknown **backbuffers, int numBackbuffers);
|
||||
void FirstFrame(WrappedIDXGISwapChain4 *swap);
|
||||
void FirstFrame(IDXGISwapper *swapper);
|
||||
FrameRecord &GetFrameRecord() { return m_FrameRecord; }
|
||||
const DrawcallDescription *GetDrawcall(uint32_t eventId);
|
||||
|
||||
@@ -551,6 +569,7 @@ public:
|
||||
|
||||
void ExecuteList(ID3D12GraphicsCommandList4 *list, WrappedID3D12CommandQueue *queue = NULL,
|
||||
bool InFrameCaptureBoundary = false);
|
||||
void MarkListExecuted(ID3D12GraphicsCommandList4 *list);
|
||||
void ExecuteLists(WrappedID3D12CommandQueue *queue = NULL, bool InFrameCaptureBoundary = false);
|
||||
void FlushLists(bool forceSync = false, ID3D12CommandQueue *queue = NULL);
|
||||
|
||||
@@ -611,13 +630,17 @@ public:
|
||||
return NULL;
|
||||
}
|
||||
// Swap Chain
|
||||
IMPLEMENT_FUNCTION_THREAD_SERIALISED(IUnknown *, WrapSwapchainBuffer,
|
||||
WrappedIDXGISwapChain4 *swap, DXGI_SWAP_CHAIN_DESC *desc,
|
||||
UINT buffer, IUnknown *realSurface);
|
||||
HRESULT Present(WrappedIDXGISwapChain4 *swap, UINT SyncInterval, UINT Flags);
|
||||
IMPLEMENT_FUNCTION_THREAD_SERIALISED(IUnknown *, WrapSwapchainBuffer, IDXGISwapper *swapper,
|
||||
DXGI_FORMAT bufferFormat, UINT buffer, IUnknown *realSurface);
|
||||
HRESULT Present(ID3D12GraphicsCommandList *pOverlayCommandList, IDXGISwapper *swapper,
|
||||
UINT SyncInterval, UINT Flags);
|
||||
HRESULT Present(IDXGISwapper *swapper, UINT SyncInterval, UINT Flags)
|
||||
{
|
||||
return Present(NULL, swapper, SyncInterval, Flags);
|
||||
}
|
||||
|
||||
void NewSwapchainBuffer(IUnknown *backbuffer);
|
||||
void ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swap, UINT QueueCount,
|
||||
void ReleaseSwapchainResources(IDXGISwapper *swapper, UINT QueueCount,
|
||||
IUnknown *const *ppPresentQueue, IUnknown **unwrappedQueues);
|
||||
|
||||
void Map(ID3D12Resource *Resource, UINT Subresource);
|
||||
@@ -1015,4 +1038,10 @@ public:
|
||||
virtual D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS STDMETHODCALLTYPE CheckDriverMatchingIdentifier(
|
||||
_In_ D3D12_SERIALIZED_DATA_TYPE SerializedDataType,
|
||||
_In_ const D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER *pIdentifierToCheck);
|
||||
|
||||
//////////////////////////////
|
||||
// implement ID3D12DeviceDownlevel
|
||||
virtual HRESULT STDMETHODCALLTYPE
|
||||
QueryVideoMemoryInfo(UINT NodeIndex, DXGI_MEMORY_SEGMENT_GROUP MemorySegmentGroup,
|
||||
_Out_ DXGI_QUERY_VIDEO_MEMORY_INFO *pVideoMemoryInfo);
|
||||
};
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "d3d12_command_queue.h"
|
||||
#include "d3d12_device.h"
|
||||
|
||||
#include "driver/dx/official/D3D11On12On7.h"
|
||||
|
||||
#if ENABLED(RDOC_X64)
|
||||
|
||||
#define BIT_SPECIFIC_DLL(dll32, dll64) dll64
|
||||
@@ -52,6 +54,60 @@ ID3DDevice *GetD3D12DeviceIfAlloc(IUnknown *dev)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
class WrappedD3D11On12On7 : public RefCounter12<ID3D11On12On7>
|
||||
{
|
||||
public:
|
||||
WrappedD3D11On12On7(ID3D11On12On7 *real) : RefCounter12(real) {}
|
||||
virtual ~WrappedD3D11On12On7() {}
|
||||
//////////////////////////////
|
||||
// Implement IUnknown
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return RefCounter12::AddRef(); }
|
||||
ULONG STDMETHODCALLTYPE Release() { return RefCounter12::Release(); }
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if(riid == __uuidof(IUnknown))
|
||||
{
|
||||
*ppvObject = (IUnknown *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Implement ID3D11On12On7
|
||||
|
||||
// Enables usage similar to D3D11On12CreateDevice.
|
||||
void STDMETHODCALLTYPE SetThreadDeviceCreationParams(ID3D12Device *pDevice,
|
||||
ID3D12CommandQueue *pGraphicsQueue)
|
||||
{
|
||||
RDCASSERT(WrappedID3D12Device::IsAlloc(pDevice));
|
||||
m_pReal->SetThreadDeviceCreationParams(((WrappedID3D12Device *)pDevice)->GetReal(),
|
||||
Unwrap(pGraphicsQueue));
|
||||
}
|
||||
|
||||
// Enables usage similar to ID3D11On12Device::CreateWrappedResource.
|
||||
// Note that the D3D11 resource creation parameters should be similar to the D3D12 resource,
|
||||
// or else unexpected/undefined behavior may occur.
|
||||
void STDMETHODCALLTYPE SetThreadResourceCreationParams(ID3D12Resource *pResource)
|
||||
{
|
||||
m_pReal->SetThreadResourceCreationParams(Unwrap(pResource));
|
||||
}
|
||||
|
||||
ID3D11On12On7Device *STDMETHODCALLTYPE GetThreadLastCreatedDevice()
|
||||
{
|
||||
// don't need to wrap/unwrap, it only deals with ID3D11On12On7Resource
|
||||
return m_pReal->GetThreadLastCreatedDevice();
|
||||
}
|
||||
|
||||
ID3D11On12On7Resource *STDMETHODCALLTYPE GetThreadLastCreatedResource()
|
||||
{
|
||||
// don't need to wrap/unwrap
|
||||
return m_pReal->GetThreadLastCreatedResource();
|
||||
}
|
||||
};
|
||||
|
||||
// dummy class to present to the user, while we maintain control
|
||||
//
|
||||
// The inheritance is awful for these. See WrappedID3D12DebugDevice for why there are multiple
|
||||
@@ -145,6 +201,8 @@ public:
|
||||
GetDebugInterface.Register("d3d12.dll", "D3D12GetDebugInterface", D3D12GetDebugInterface_hook);
|
||||
EnableExperimentalFeatures.Register("d3d12.dll", "D3D12EnableExperimentalFeatures",
|
||||
D3D12EnableExperimentalFeatures_hook);
|
||||
GetD3D11On12On7.Register("d3d11on12.dll", "GetD3D11On12On7Interface",
|
||||
GetD3D11On12On7Interface_hook);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -165,6 +223,7 @@ private:
|
||||
HookedFunction<PFN_D3D12_GET_DEBUG_INTERFACE> GetDebugInterface;
|
||||
HookedFunction<PFN_D3D12_CREATE_DEVICE> CreateDevice;
|
||||
HookedFunction<PFN_D3D12_ENABLE_EXPERIMENTAL_FEATURES> EnableExperimentalFeatures;
|
||||
HookedFunction<PFNGetD3D11On12On7Interface> GetD3D11On12On7;
|
||||
|
||||
// re-entrancy detection (can happen in rare cases with e.g. fraps)
|
||||
bool m_InsideCreate = false;
|
||||
@@ -325,6 +384,14 @@ private:
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI GetD3D11On12On7Interface_hook(ID3D11On12On7 **ppIface)
|
||||
{
|
||||
ID3D11On12On7 *real = NULL;
|
||||
d3d12hooks.GetD3D11On12On7()(&real);
|
||||
*ppIface = (ID3D11On12On7 *)(new WrappedD3D11On12On7(real));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI D3D12GetDebugInterface_hook(REFIID riid, void **ppvDebug)
|
||||
{
|
||||
if(riid != __uuidof(ID3D12Debug))
|
||||
|
||||
@@ -33,9 +33,9 @@ void D3D12Replay::OutputWindow::MakeRTV(bool msaa)
|
||||
|
||||
D3D12_RESOURCE_DESC texDesc = {};
|
||||
|
||||
if(bb[0])
|
||||
if(bbDesc.Width)
|
||||
{
|
||||
texDesc = bb[0]->GetDesc();
|
||||
texDesc = bbDesc;
|
||||
|
||||
texDesc.SampleDesc.Count = msaa ? D3D12_MSAA_SAMPLECOUNT : 1;
|
||||
|
||||
@@ -46,16 +46,17 @@ void D3D12Replay::OutputWindow::MakeRTV(bool msaa)
|
||||
texDesc.DepthOrArraySize = 1;
|
||||
texDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||
texDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||
texDesc.Height = height;
|
||||
texDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||
texDesc.MipLevels = 1;
|
||||
texDesc.SampleDesc.Count = 1;
|
||||
texDesc.SampleDesc.Quality = 0;
|
||||
texDesc.Width = width;
|
||||
|
||||
multisampled = false;
|
||||
}
|
||||
|
||||
texDesc.Height = height;
|
||||
texDesc.Width = width;
|
||||
|
||||
texDesc.Alignment = 0;
|
||||
texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
|
||||
texDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||
@@ -191,7 +192,15 @@ uint64_t D3D12Replay::MakeOutputWindow(WindowingData window, bool depth)
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
hr = m_pFactory->CreateSwapChain(m_pDevice->GetQueue(), &swapDesc, &outw.swap);
|
||||
// on 12On7 just skip creating the swapchain
|
||||
if(m_D3D12On7)
|
||||
{
|
||||
outw.swap = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = m_pFactory->CreateSwapChain(m_pDevice->GetQueue(), &swapDesc, &outw.swap);
|
||||
}
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
@@ -199,8 +208,27 @@ uint64_t D3D12Replay::MakeOutputWindow(WindowingData window, bool depth)
|
||||
return 0;
|
||||
}
|
||||
|
||||
outw.swap->GetBuffer(0, __uuidof(ID3D12Resource), (void **)&outw.bb[0]);
|
||||
outw.swap->GetBuffer(1, __uuidof(ID3D12Resource), (void **)&outw.bb[1]);
|
||||
if(outw.swap)
|
||||
{
|
||||
outw.swap->GetBuffer(0, __uuidof(ID3D12Resource), (void **)&outw.bb[0]);
|
||||
outw.swap->GetBuffer(1, __uuidof(ID3D12Resource), (void **)&outw.bb[1]);
|
||||
outw.bbDesc = outw.bb[0]->GetDesc();
|
||||
}
|
||||
else
|
||||
{
|
||||
outw.bbDesc.DepthOrArraySize = 1;
|
||||
outw.bbDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
|
||||
outw.bbDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||
outw.bbDesc.Height = outw.height;
|
||||
outw.bbDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||
outw.bbDesc.MipLevels = 1;
|
||||
outw.bbDesc.SampleDesc.Count = 1;
|
||||
outw.bbDesc.SampleDesc.Quality = 0;
|
||||
outw.bbDesc.Width = outw.width;
|
||||
outw.bbDesc.Alignment = 0;
|
||||
outw.bbDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
outw.bbDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -262,7 +290,7 @@ bool D3D12Replay::CheckResizeOutputWindow(uint64_t id)
|
||||
|
||||
OutputWindow &outw = m_OutputWindows[id];
|
||||
|
||||
if(outw.wnd == NULL || outw.swap == NULL)
|
||||
if(outw.wnd == NULL || (outw.swap == NULL && !m_D3D12On7))
|
||||
return false;
|
||||
|
||||
RECT rect;
|
||||
@@ -283,20 +311,23 @@ bool D3D12Replay::CheckResizeOutputWindow(uint64_t id)
|
||||
SAFE_RELEASE(outw.bb[0]);
|
||||
SAFE_RELEASE(outw.bb[1]);
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
outw.swap->GetDesc(&desc);
|
||||
|
||||
HRESULT hr = outw.swap->ResizeBuffers(desc.BufferCount, outw.width, outw.height,
|
||||
desc.BufferDesc.Format, desc.Flags);
|
||||
|
||||
if(FAILED(hr))
|
||||
if(outw.swap)
|
||||
{
|
||||
RDCERR("Failed to resize swap chain, HRESULT: %s", ToStr(hr).c_str());
|
||||
return true;
|
||||
}
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
outw.swap->GetDesc(&desc);
|
||||
|
||||
outw.swap->GetBuffer(0, __uuidof(ID3D12Resource), (void **)&outw.bb[0]);
|
||||
outw.swap->GetBuffer(1, __uuidof(ID3D12Resource), (void **)&outw.bb[1]);
|
||||
HRESULT hr = outw.swap->ResizeBuffers(desc.BufferCount, outw.width, outw.height,
|
||||
desc.BufferDesc.Format, desc.Flags);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Failed to resize swap chain, HRESULT: %s", ToStr(hr).c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
outw.swap->GetBuffer(0, __uuidof(ID3D12Resource), (void **)&outw.bb[0]);
|
||||
outw.swap->GetBuffer(1, __uuidof(ID3D12Resource), (void **)&outw.bb[1]);
|
||||
}
|
||||
|
||||
outw.bbIdx = 0;
|
||||
|
||||
@@ -524,24 +555,26 @@ void D3D12Replay::FlipOutputWindow(uint64_t id)
|
||||
|
||||
OutputWindow &outw = m_OutputWindows[id];
|
||||
|
||||
if(m_OutputWindows[id].bb[0] == NULL || m_OutputWindows[id].swap == NULL)
|
||||
if(!m_D3D12On7 && (m_OutputWindows[id].bb[0] == NULL || m_OutputWindows[id].swap == NULL))
|
||||
return;
|
||||
|
||||
D3D12_RESOURCE_BARRIER barriers[3];
|
||||
RDCEraseEl(barriers);
|
||||
if(m_OutputWindows[id].col == NULL)
|
||||
return;
|
||||
|
||||
barriers[0].Transition.pResource = outw.col;
|
||||
barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
barriers[0].Transition.StateAfter =
|
||||
D3D12_RESOURCE_BARRIER colbarrier = {}, bbbarrier = {}, resolvebarrier = {};
|
||||
|
||||
colbarrier.Transition.pResource = outw.col;
|
||||
colbarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
colbarrier.Transition.StateAfter =
|
||||
outw.multisampled ? D3D12_RESOURCE_STATE_RESOLVE_SOURCE : D3D12_RESOURCE_STATE_COPY_SOURCE;
|
||||
|
||||
barriers[1].Transition.pResource = outw.bb[outw.bbIdx];
|
||||
barriers[1].Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
|
||||
barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
bbbarrier.Transition.pResource = outw.bb[outw.bbIdx];
|
||||
bbbarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
|
||||
bbbarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST;
|
||||
|
||||
barriers[2].Transition.pResource = outw.colResolve;
|
||||
barriers[2].Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE;
|
||||
barriers[2].Transition.StateAfter = D3D12_RESOURCE_STATE_RESOLVE_DEST;
|
||||
resolvebarrier.Transition.pResource = outw.colResolve;
|
||||
resolvebarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE;
|
||||
resolvebarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RESOLVE_DEST;
|
||||
|
||||
ID3D12GraphicsCommandList *list = m_pDevice->GetNewList();
|
||||
|
||||
@@ -549,39 +582,77 @@ void D3D12Replay::FlipOutputWindow(uint64_t id)
|
||||
if(outw.multisampled)
|
||||
{
|
||||
// transition colour to resolve source, resolve target to resolve dest, backbuffer to copy dest
|
||||
list->ResourceBarrier(3, barriers);
|
||||
list->ResourceBarrier(1, &colbarrier);
|
||||
list->ResourceBarrier(1, &resolvebarrier);
|
||||
|
||||
if(bbbarrier.Transition.pResource)
|
||||
list->ResourceBarrier(1, &bbbarrier);
|
||||
|
||||
// resolve then copy, as the resolve can't go from SRGB to non-SRGB target
|
||||
list->ResolveSubresource(barriers[2].Transition.pResource, 0, barriers[0].Transition.pResource,
|
||||
0, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
|
||||
list->ResolveSubresource(outw.colResolve, 0, outw.col, 0, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB);
|
||||
|
||||
std::swap(barriers[2].Transition.StateBefore, barriers[2].Transition.StateAfter);
|
||||
std::swap(resolvebarrier.Transition.StateBefore, resolvebarrier.Transition.StateAfter);
|
||||
|
||||
// now move the resolve target into copy source
|
||||
list->ResourceBarrier(1, &barriers[2]);
|
||||
list->ResourceBarrier(1, &resolvebarrier);
|
||||
|
||||
list->CopyResource(barriers[1].Transition.pResource, barriers[2].Transition.pResource);
|
||||
if(bbbarrier.Transition.pResource)
|
||||
list->CopyResource(bbbarrier.Transition.pResource, resolvebarrier.Transition.pResource);
|
||||
}
|
||||
else
|
||||
{
|
||||
// transition colour to copy source, backbuffer to copy dest
|
||||
list->ResourceBarrier(2, barriers);
|
||||
list->ResourceBarrier(1, &colbarrier);
|
||||
|
||||
list->CopyResource(barriers[1].Transition.pResource, barriers[0].Transition.pResource);
|
||||
if(bbbarrier.Transition.pResource)
|
||||
list->ResourceBarrier(1, &bbbarrier);
|
||||
|
||||
if(bbbarrier.Transition.pResource)
|
||||
list->CopyResource(bbbarrier.Transition.pResource, colbarrier.Transition.pResource);
|
||||
}
|
||||
|
||||
std::swap(barriers[0].Transition.StateBefore, barriers[0].Transition.StateAfter);
|
||||
std::swap(barriers[1].Transition.StateBefore, barriers[1].Transition.StateAfter);
|
||||
std::swap(colbarrier.Transition.StateBefore, colbarrier.Transition.StateAfter);
|
||||
std::swap(bbbarrier.Transition.StateBefore, bbbarrier.Transition.StateAfter);
|
||||
|
||||
// transition colour back to render target, and backbuffer back to present
|
||||
list->ResourceBarrier(2, barriers);
|
||||
list->ResourceBarrier(1, &colbarrier);
|
||||
|
||||
if(bbbarrier.Transition.pResource)
|
||||
list->ResourceBarrier(1, &bbbarrier);
|
||||
|
||||
if(m_D3D12On7)
|
||||
{
|
||||
ID3D12Resource *res = outw.multisampled ? outw.colResolve : outw.col;
|
||||
|
||||
D3D12_RESOURCE_BARRIER toPresent = {};
|
||||
|
||||
toPresent.Transition.pResource = res;
|
||||
toPresent.Transition.StateBefore =
|
||||
outw.multisampled ? D3D12_RESOURCE_STATE_COPY_SOURCE : D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||
toPresent.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
|
||||
|
||||
list->ResourceBarrier(1, &toPresent);
|
||||
|
||||
ID3D12CommandQueueDownlevel *downlevel = NULL;
|
||||
m_pDevice->GetQueue()->QueryInterface(__uuidof(ID3D12CommandQueueDownlevel), (void **)&downlevel);
|
||||
downlevel->Present(list, res, outw.wnd, D3D12_DOWNLEVEL_PRESENT_FLAG_NONE);
|
||||
SAFE_RELEASE(downlevel);
|
||||
m_pDevice->MarkListExecuted((ID3D12GraphicsCommandList4 *)list);
|
||||
|
||||
list = m_pDevice->GetNewList();
|
||||
|
||||
std::swap(toPresent.Transition.StateBefore, toPresent.Transition.StateAfter);
|
||||
|
||||
list->ResourceBarrier(1, &toPresent);
|
||||
}
|
||||
|
||||
list->Close();
|
||||
|
||||
m_pDevice->ExecuteLists();
|
||||
m_pDevice->FlushLists();
|
||||
|
||||
outw.swap->Present(0, 0);
|
||||
if(outw.swap)
|
||||
outw.swap->Present(0, 0);
|
||||
|
||||
outw.bbIdx++;
|
||||
outw.bbIdx %= 2;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "d3d12_replay.h"
|
||||
#include "core/plugins.h"
|
||||
#include "driver/dx/official/d3dcompiler.h"
|
||||
#include "driver/dxgi/dxgi_common.h"
|
||||
#include "driver/ihv/amd/amd_counters.h"
|
||||
@@ -108,7 +109,7 @@ void D3D12Replay::Initialise()
|
||||
PFN_CREATE_DXGI_FACTORY createFunc =
|
||||
(PFN_CREATE_DXGI_FACTORY)GetProcAddress(GetModuleHandleA("dxgi.dll"), "CreateDXGIFactory1");
|
||||
|
||||
HRESULT hr = createFunc(__uuidof(IDXGIFactory4), (void **)&m_pFactory);
|
||||
HRESULT hr = createFunc(__uuidof(IDXGIFactory1), (void **)&m_pFactory);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
@@ -119,12 +120,12 @@ void D3D12Replay::Initialise()
|
||||
|
||||
if(m_pFactory)
|
||||
{
|
||||
RefCountDXGIObject::HandleWrap(__uuidof(IDXGIFactory4), (void **)&m_pFactory);
|
||||
RefCountDXGIObject::HandleWrap(__uuidof(IDXGIFactory1), (void **)&m_pFactory);
|
||||
|
||||
LUID luid = m_pDevice->GetAdapterLuid();
|
||||
|
||||
IDXGIAdapter *pDXGIAdapter;
|
||||
hr = m_pFactory->EnumAdapterByLuid(luid, __uuidof(IDXGIAdapter), (void **)&pDXGIAdapter);
|
||||
IDXGIAdapter *pDXGIAdapter = NULL;
|
||||
hr = EnumAdapterByLuid(m_pFactory, luid, &pDXGIAdapter);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
@@ -3586,12 +3587,47 @@ ReplayStatus D3D12_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver)
|
||||
|
||||
WrappedIDXGISwapChain4::RegisterD3DDeviceCallback(GetD3D12DeviceIfAlloc);
|
||||
|
||||
bool d3d12on7 = false;
|
||||
|
||||
HMODULE lib = NULL;
|
||||
lib = LoadLibraryA("d3d12.dll");
|
||||
if(lib == NULL)
|
||||
{
|
||||
RDCERR("Failed to load d3d12.dll");
|
||||
return ReplayStatus::APIInitFailed;
|
||||
// if it fails try to find D3D12On7 DLLs
|
||||
d3d12on7 = true;
|
||||
|
||||
// if it fails, try in the plugin directory
|
||||
lib = (HMODULE)Process::LoadModule(LocatePluginFile("d3d12", "d3d12.dll").c_str());
|
||||
|
||||
// if that succeeded, also load dxilconv7.dll from there
|
||||
if(lib)
|
||||
{
|
||||
HMODULE dxilconv =
|
||||
(HMODULE)Process::LoadModule(LocatePluginFile("d3d12", "dxilconv7.dll").c_str());
|
||||
|
||||
if(!dxilconv)
|
||||
{
|
||||
RDCERR("Found d3d12.dll in plugin path, but couldn't load dxilconv7.dll");
|
||||
return ReplayStatus::APIInitFailed;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if it failed, try one more time in MS's subfolder convention
|
||||
lib = LoadLibraryA("12on7/d3d12.dll");
|
||||
|
||||
if(lib)
|
||||
{
|
||||
RDCWARN(
|
||||
"Loaded d3d12.dll from 12on7 subfolder."
|
||||
"Please use RenderDoc's plugins/d3d12/ subfolder instead");
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Failed to load d3d12.dll");
|
||||
return ReplayStatus::APIInitFailed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PFN_D3D12_CREATE_DEVICE createDevice =
|
||||
@@ -3693,6 +3729,7 @@ ReplayStatus D3D12_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver)
|
||||
RDCLOG("Created device.");
|
||||
D3D12Replay *replay = wrappedDev->GetReplay();
|
||||
|
||||
replay->Set12On7(d3d12on7);
|
||||
replay->SetProxy(rdc == NULL);
|
||||
replay->SetRGP(rgp);
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ public:
|
||||
|
||||
D3D12DebugManager *GetDebugManager() { return m_DebugManager; }
|
||||
void SetRGP(AMDRGPControl *rgp) { m_RGP = rgp; }
|
||||
void Set12On7(bool d3d12on7) { m_D3D12On7 = d3d12on7; }
|
||||
void SetProxy(bool proxy) { m_Proxy = proxy; }
|
||||
bool IsRemoteProxy() { return m_Proxy; }
|
||||
void Initialise();
|
||||
@@ -288,7 +289,7 @@ private:
|
||||
ID3D12Resource *m_SOPatchedIndexBuffer = NULL;
|
||||
ID3D12QueryHeap *m_SOQueryHeap = NULL;
|
||||
|
||||
bool m_Proxy;
|
||||
bool m_Proxy, m_D3D12On7;
|
||||
|
||||
std::vector<ID3D12Resource *> m_ProxyResources;
|
||||
|
||||
@@ -303,6 +304,7 @@ private:
|
||||
ID3D12Resource *depth;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE rtv;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE dsv;
|
||||
D3D12_RESOURCE_DESC bbDesc;
|
||||
|
||||
WrappedID3D12Device *dev;
|
||||
|
||||
@@ -419,7 +421,7 @@ private:
|
||||
|
||||
D3D12DebugManager *m_DebugManager = NULL;
|
||||
|
||||
IDXGIFactory4 *m_pFactory = NULL;
|
||||
IDXGIFactory1 *m_pFactory = NULL;
|
||||
|
||||
AMDCounters *m_pAMDCounters = NULL;
|
||||
AMDRGPControl *m_RGP = NULL;
|
||||
|
||||
@@ -137,6 +137,8 @@
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\dx\official\D3D11On12On7.h" />
|
||||
<ClInclude Include="..\dx\official\D3D12Downlevel.h" />
|
||||
<ClInclude Include="d3d12_commands.h" />
|
||||
<ClInclude Include="d3d12_command_list.h" />
|
||||
<ClInclude Include="d3d12_command_queue.h" />
|
||||
|
||||
@@ -69,6 +69,12 @@
|
||||
<ClInclude Include="d3d12_rendertext.h">
|
||||
<Filter>Util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\dx\official\D3D12Downlevel.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\dx\official\D3D11On12On7.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="d3d12_common.cpp">
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
// Just an identity interface, no functionality exposed, retrieved by ID3D11On12On7::GetThreadLastCreatedResource
|
||||
interface ID3D11On12On7Resource { };
|
||||
|
||||
// Per-device, retrieved by ID3D11On12On7::GetThreadLastCreatedDevice
|
||||
interface ID3D11On12On7Device
|
||||
{
|
||||
// Equivalent to ID3D11On12Device::AcquireWrappedResources:
|
||||
// From this point on, the resource should be used by D3D11, not by D3D12 directly.
|
||||
STDMETHOD(AcquireResource)(ID3D11On12On7Resource* pResource, D3D12_RESOURCE_STATES state) = 0;
|
||||
// Equivalent to ID3D11On12Device::ReleaseWrappedResources:
|
||||
// Note that this cannot unbind the resource from D3D11, that is the app's responsibility.
|
||||
// After calling this, the app should call Flush() on the D3D11 device.
|
||||
STDMETHOD(ReleaseResource)(ID3D11On12On7Resource* pResource, D3D12_RESOURCE_STATES state) = 0;
|
||||
};
|
||||
|
||||
// Global, retrieved by GetD3D11On12On7Interface
|
||||
interface ID3D11On12On7 : public IUnknown
|
||||
{
|
||||
// Enables usage similar to D3D11On12CreateDevice.
|
||||
STDMETHOD_(void, SetThreadDeviceCreationParams)(ID3D12Device* pDevice, ID3D12CommandQueue* pGraphicsQueue) = 0;
|
||||
// Enables usage similar to ID3D11On12Device::CreateWrappedResource.
|
||||
// Note that the D3D11 resource creation parameters should be similar to the D3D12 resource,
|
||||
// or else unexpected/undefined behavior may occur.
|
||||
STDMETHOD_(void, SetThreadResourceCreationParams)(ID3D12Resource* pResource) = 0;
|
||||
STDMETHOD_(ID3D11On12On7Device*, GetThreadLastCreatedDevice)() = 0;
|
||||
STDMETHOD_(ID3D11On12On7Resource*, GetThreadLastCreatedResource)() = 0;
|
||||
};
|
||||
|
||||
extern "C" HRESULT APIENTRY GetD3D11On12On7Interface(ID3D11On12On7** ppIface);
|
||||
typedef HRESULT(APIENTRY *PFNGetD3D11On12On7Interface)(ID3D11On12On7** ppIface);
|
||||
@@ -0,0 +1,280 @@
|
||||
/*-------------------------------------------------------------------------------------
|
||||
*
|
||||
* Copyright (c) Microsoft Corporation
|
||||
*
|
||||
*-------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
|
||||
|
||||
|
||||
/* File created by MIDL compiler version 8.01.0622 */
|
||||
|
||||
|
||||
|
||||
/* verify that the <rpcndr.h> version is high enough to compile this file*/
|
||||
#ifndef __REQUIRED_RPCNDR_H_VERSION__
|
||||
#define __REQUIRED_RPCNDR_H_VERSION__ 500
|
||||
#endif
|
||||
|
||||
/* verify that the <rpcsal.h> version is high enough to compile this file*/
|
||||
#ifndef __REQUIRED_RPCSAL_H_VERSION__
|
||||
#define __REQUIRED_RPCSAL_H_VERSION__ 100
|
||||
#endif
|
||||
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
#ifndef __RPCNDR_H_VERSION__
|
||||
#error this stub requires an updated version of <rpcndr.h>
|
||||
#endif /* __RPCNDR_H_VERSION__ */
|
||||
|
||||
#ifndef COM_NO_WINDOWS_H
|
||||
#include "windows.h"
|
||||
#include "ole2.h"
|
||||
#endif /*COM_NO_WINDOWS_H*/
|
||||
|
||||
#ifndef __d3d12downlevel_h__
|
||||
#define __d3d12downlevel_h__
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
/* Forward Declarations */
|
||||
|
||||
#ifndef __ID3D12CommandQueueDownlevel_FWD_DEFINED__
|
||||
#define __ID3D12CommandQueueDownlevel_FWD_DEFINED__
|
||||
typedef interface ID3D12CommandQueueDownlevel ID3D12CommandQueueDownlevel;
|
||||
|
||||
#endif /* __ID3D12CommandQueueDownlevel_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __ID3D12DeviceDownlevel_FWD_DEFINED__
|
||||
#define __ID3D12DeviceDownlevel_FWD_DEFINED__
|
||||
typedef interface ID3D12DeviceDownlevel ID3D12DeviceDownlevel;
|
||||
|
||||
#endif /* __ID3D12DeviceDownlevel_FWD_DEFINED__ */
|
||||
|
||||
|
||||
/* header files for imported files */
|
||||
#include "oaidl.h"
|
||||
#include "ocidl.h"
|
||||
#include "d3d12.h"
|
||||
#include "dxgi1_4.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
|
||||
/* interface __MIDL_itf_d3d12downlevel_0000_0000 */
|
||||
/* [local] */
|
||||
|
||||
#include "winapifamily.h"
|
||||
#pragma region Desktop Family
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
typedef
|
||||
enum D3D12_DOWNLEVEL_PRESENT_FLAGS
|
||||
{
|
||||
D3D12_DOWNLEVEL_PRESENT_FLAG_NONE = 0,
|
||||
D3D12_DOWNLEVEL_PRESENT_FLAG_WAIT_FOR_VBLANK = ( D3D12_DOWNLEVEL_PRESENT_FLAG_NONE + 1 )
|
||||
} D3D12_DOWNLEVEL_PRESENT_FLAGS;
|
||||
|
||||
DEFINE_ENUM_FLAG_OPERATORS( D3D12_DOWNLEVEL_PRESENT_FLAGS );
|
||||
|
||||
|
||||
extern RPC_IF_HANDLE __MIDL_itf_d3d12downlevel_0000_0000_v0_0_c_ifspec;
|
||||
extern RPC_IF_HANDLE __MIDL_itf_d3d12downlevel_0000_0000_v0_0_s_ifspec;
|
||||
|
||||
#ifndef __ID3D12CommandQueueDownlevel_INTERFACE_DEFINED__
|
||||
#define __ID3D12CommandQueueDownlevel_INTERFACE_DEFINED__
|
||||
|
||||
/* interface ID3D12CommandQueueDownlevel */
|
||||
/* [unique][local][object][uuid] */
|
||||
|
||||
|
||||
EXTERN_C const IID IID_ID3D12CommandQueueDownlevel;
|
||||
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
|
||||
MIDL_INTERFACE("38a8c5ef-7ccb-4e81-914f-a6e9d072c494")
|
||||
ID3D12CommandQueueDownlevel : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE Present(
|
||||
_In_ ID3D12GraphicsCommandList *pOpenCommandList,
|
||||
_In_ ID3D12Resource *pSourceTex2D,
|
||||
_In_ HWND hWindow,
|
||||
D3D12_DOWNLEVEL_PRESENT_FLAGS Flags) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#else /* C style interface */
|
||||
|
||||
typedef struct ID3D12CommandQueueDownlevelVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
ID3D12CommandQueueDownlevel * This,
|
||||
REFIID riid,
|
||||
_COM_Outptr_ void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
ID3D12CommandQueueDownlevel * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
ID3D12CommandQueueDownlevel * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *Present )(
|
||||
ID3D12CommandQueueDownlevel * This,
|
||||
_In_ ID3D12GraphicsCommandList *pOpenCommandList,
|
||||
_In_ ID3D12Resource *pSourceTex2D,
|
||||
_In_ HWND hWindow,
|
||||
D3D12_DOWNLEVEL_PRESENT_FLAGS Flags);
|
||||
|
||||
END_INTERFACE
|
||||
} ID3D12CommandQueueDownlevelVtbl;
|
||||
|
||||
interface ID3D12CommandQueueDownlevel
|
||||
{
|
||||
CONST_VTBL struct ID3D12CommandQueueDownlevelVtbl *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef COBJMACROS
|
||||
|
||||
|
||||
#define ID3D12CommandQueueDownlevel_QueryInterface(This,riid,ppvObject) \
|
||||
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||
|
||||
#define ID3D12CommandQueueDownlevel_AddRef(This) \
|
||||
( (This)->lpVtbl -> AddRef(This) )
|
||||
|
||||
#define ID3D12CommandQueueDownlevel_Release(This) \
|
||||
( (This)->lpVtbl -> Release(This) )
|
||||
|
||||
|
||||
#define ID3D12CommandQueueDownlevel_Present(This,pOpenCommandList,pSourceTex2D,hWindow,Flags) \
|
||||
( (This)->lpVtbl -> Present(This,pOpenCommandList,pSourceTex2D,hWindow,Flags) )
|
||||
|
||||
#endif /* COBJMACROS */
|
||||
|
||||
|
||||
#endif /* C style interface */
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __ID3D12CommandQueueDownlevel_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __ID3D12DeviceDownlevel_INTERFACE_DEFINED__
|
||||
#define __ID3D12DeviceDownlevel_INTERFACE_DEFINED__
|
||||
|
||||
/* interface ID3D12DeviceDownlevel */
|
||||
/* [unique][local][object][uuid] */
|
||||
|
||||
|
||||
EXTERN_C const IID IID_ID3D12DeviceDownlevel;
|
||||
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
|
||||
MIDL_INTERFACE("74eaee3f-2f4b-476d-82ba-2b85cb49e310")
|
||||
ID3D12DeviceDownlevel : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryVideoMemoryInfo(
|
||||
UINT NodeIndex,
|
||||
DXGI_MEMORY_SEGMENT_GROUP MemorySegmentGroup,
|
||||
_Out_ DXGI_QUERY_VIDEO_MEMORY_INFO *pVideoMemoryInfo) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#else /* C style interface */
|
||||
|
||||
typedef struct ID3D12DeviceDownlevelVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
ID3D12DeviceDownlevel * This,
|
||||
REFIID riid,
|
||||
_COM_Outptr_ void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
ID3D12DeviceDownlevel * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
ID3D12DeviceDownlevel * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryVideoMemoryInfo )(
|
||||
ID3D12DeviceDownlevel * This,
|
||||
UINT NodeIndex,
|
||||
DXGI_MEMORY_SEGMENT_GROUP MemorySegmentGroup,
|
||||
_Out_ DXGI_QUERY_VIDEO_MEMORY_INFO *pVideoMemoryInfo);
|
||||
|
||||
END_INTERFACE
|
||||
} ID3D12DeviceDownlevelVtbl;
|
||||
|
||||
interface ID3D12DeviceDownlevel
|
||||
{
|
||||
CONST_VTBL struct ID3D12DeviceDownlevelVtbl *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef COBJMACROS
|
||||
|
||||
|
||||
#define ID3D12DeviceDownlevel_QueryInterface(This,riid,ppvObject) \
|
||||
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||
|
||||
#define ID3D12DeviceDownlevel_AddRef(This) \
|
||||
( (This)->lpVtbl -> AddRef(This) )
|
||||
|
||||
#define ID3D12DeviceDownlevel_Release(This) \
|
||||
( (This)->lpVtbl -> Release(This) )
|
||||
|
||||
|
||||
#define ID3D12DeviceDownlevel_QueryVideoMemoryInfo(This,NodeIndex,MemorySegmentGroup,pVideoMemoryInfo) \
|
||||
( (This)->lpVtbl -> QueryVideoMemoryInfo(This,NodeIndex,MemorySegmentGroup,pVideoMemoryInfo) )
|
||||
|
||||
#endif /* COBJMACROS */
|
||||
|
||||
|
||||
#endif /* C style interface */
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __ID3D12DeviceDownlevel_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
/* interface __MIDL_itf_d3d12downlevel_0000_0002 */
|
||||
/* [local] */
|
||||
|
||||
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
|
||||
#pragma endregion
|
||||
DEFINE_GUID(IID_ID3D12CommandQueueDownlevel,0x38a8c5ef,0x7ccb,0x4e81,0x91,0x4f,0xa6,0xe9,0xd0,0x72,0xc4,0x94);
|
||||
DEFINE_GUID(IID_ID3D12DeviceDownlevel,0x74eaee3f,0x2f4b,0x476d,0x82,0xba,0x2b,0x85,0xcb,0x49,0xe3,0x10);
|
||||
|
||||
|
||||
extern RPC_IF_HANDLE __MIDL_itf_d3d12downlevel_0000_0002_v0_0_c_ifspec;
|
||||
extern RPC_IF_HANDLE __MIDL_itf_d3d12downlevel_0000_0002_v0_0_s_ifspec;
|
||||
|
||||
/* Additional Prototypes for ALL interfaces */
|
||||
|
||||
/* end of Additional Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -473,7 +473,7 @@ HRESULT WrappedIDXGISwapChain4::GetBuffer(
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
GetDesc(&desc);
|
||||
tex = m_pDevice->WrapSwapchainBuffer(this, &desc, Buffer, realSurface);
|
||||
tex = m_pDevice->WrapSwapchainBuffer(this, desc.BufferDesc.Format, Buffer, realSurface);
|
||||
}
|
||||
|
||||
// if the original UUID was IDXGISurface, fixup for the expected interface being returned
|
||||
@@ -534,6 +534,7 @@ HRESULT WrappedIDXGISwapChain4::Present(
|
||||
SyncInterval = 0;
|
||||
}
|
||||
|
||||
TickLastPresentedBuffer();
|
||||
m_pDevice->Present(this, SyncInterval, Flags);
|
||||
|
||||
return m_pReal->Present(SyncInterval, Flags);
|
||||
@@ -547,6 +548,7 @@ HRESULT WrappedIDXGISwapChain4::Present1(UINT SyncInterval, UINT Flags,
|
||||
SyncInterval = 0;
|
||||
}
|
||||
|
||||
TickLastPresentedBuffer();
|
||||
m_pDevice->Present(this, SyncInterval, Flags);
|
||||
|
||||
return m_pReal1->Present1(SyncInterval, Flags, pPresentParameters);
|
||||
|
||||
@@ -155,7 +155,19 @@ public:
|
||||
return RefCountDXGIObject::GetParent(riid, ppvObject); \
|
||||
}
|
||||
|
||||
class WrappedIDXGISwapChain4;
|
||||
struct ID3DDevice;
|
||||
|
||||
struct IDXGISwapper
|
||||
{
|
||||
virtual ID3DDevice *GetD3DDevice() = 0;
|
||||
virtual int GetNumBackbuffers() = 0;
|
||||
virtual IUnknown **GetBackbuffers() = 0;
|
||||
virtual int GetLastPresentedBuffer() = 0;
|
||||
virtual UINT GetWidth() = 0;
|
||||
virtual UINT GetHeight() = 0;
|
||||
virtual DXGI_FORMAT GetFormat() = 0;
|
||||
virtual HWND GetHWND() = 0;
|
||||
};
|
||||
|
||||
struct ID3DDevice
|
||||
{
|
||||
@@ -171,16 +183,16 @@ struct ID3DDevice
|
||||
virtual bool IsDeviceUUID(REFIID guid) = 0;
|
||||
virtual IUnknown *GetDeviceInterface(REFIID guid) = 0;
|
||||
|
||||
virtual void FirstFrame(WrappedIDXGISwapChain4 *swapChain) = 0;
|
||||
virtual void FirstFrame(IDXGISwapper *swapper) = 0;
|
||||
|
||||
virtual void NewSwapchainBuffer(IUnknown *backbuffer) = 0;
|
||||
virtual void ReleaseSwapchainResources(WrappedIDXGISwapChain4 *swapChain, UINT QueueCount,
|
||||
virtual void ReleaseSwapchainResources(IDXGISwapper *swapper, UINT QueueCount,
|
||||
IUnknown *const *ppPresentQueue,
|
||||
IUnknown **unwrappedQueues) = 0;
|
||||
virtual IUnknown *WrapSwapchainBuffer(WrappedIDXGISwapChain4 *swap, DXGI_SWAP_CHAIN_DESC *swapDesc,
|
||||
virtual IUnknown *WrapSwapchainBuffer(IDXGISwapper *swapper, DXGI_FORMAT bufferFormat,
|
||||
UINT buffer, IUnknown *realSurface) = 0;
|
||||
|
||||
virtual HRESULT Present(WrappedIDXGISwapChain4 *swapChain, UINT SyncInterval, UINT Flags) = 0;
|
||||
virtual HRESULT Present(IDXGISwapper *swapper, UINT SyncInterval, UINT Flags) = 0;
|
||||
};
|
||||
|
||||
typedef ID3DDevice *(*D3DDeviceCallback)(IUnknown *dev);
|
||||
@@ -545,7 +557,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class WrappedIDXGISwapChain4 : public IDXGISwapChain4, public RefCountDXGIObject
|
||||
class WrappedIDXGISwapChain4 : public IDXGISwapChain4, public RefCountDXGIObject, public IDXGISwapper
|
||||
{
|
||||
IDXGISwapChain *m_pReal;
|
||||
IDXGISwapChain1 *m_pReal1;
|
||||
@@ -561,11 +573,31 @@ class WrappedIDXGISwapChain4 : public IDXGISwapChain4, public RefCountDXGIObject
|
||||
static const int MAX_NUM_BACKBUFFERS = 8;
|
||||
|
||||
IUnknown *m_pBackBuffers[MAX_NUM_BACKBUFFERS];
|
||||
int32_t m_LastPresentedBuffer = -1;
|
||||
|
||||
void ReleaseBuffersForResize(UINT QueueCount, IUnknown *const *ppPresentQueue,
|
||||
IUnknown **unwrappedQueues);
|
||||
void WrapBuffersAfterResize();
|
||||
|
||||
void TickLastPresentedBuffer()
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc = {};
|
||||
|
||||
m_pReal->GetDesc(&desc);
|
||||
|
||||
if(desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD)
|
||||
{
|
||||
// discard always presents from 0
|
||||
m_LastPresentedBuffer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// other modes use each buffer in turn
|
||||
m_LastPresentedBuffer++;
|
||||
m_LastPresentedBuffer %= desc.BufferCount;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
WrappedIDXGISwapChain4(IDXGISwapChain *real, HWND wnd, ID3DDevice *device);
|
||||
virtual ~WrappedIDXGISwapChain4();
|
||||
@@ -591,19 +623,47 @@ public:
|
||||
ID3DDevice *GetD3DDevice() { return m_pDevice; }
|
||||
int GetNumBackbuffers() { return MAX_NUM_BACKBUFFERS; }
|
||||
IUnknown **GetBackbuffers() { return m_pBackBuffers; }
|
||||
int GetLastPresentedBuffer() { return RDCMAX(m_LastPresentedBuffer, 0); }
|
||||
IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY;
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC GetDescWithHWND()
|
||||
HWND GetHWND()
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC ret = {};
|
||||
DXGI_SWAP_CHAIN_DESC desc = {};
|
||||
|
||||
m_pReal->GetDesc(&ret);
|
||||
m_pReal->GetDesc(&desc);
|
||||
|
||||
if(ret.OutputWindow == NULL)
|
||||
ret.OutputWindow = m_Wnd;
|
||||
if(desc.OutputWindow != NULL)
|
||||
return desc.OutputWindow;
|
||||
|
||||
return ret;
|
||||
return m_Wnd;
|
||||
}
|
||||
|
||||
UINT GetWidth()
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc = {};
|
||||
|
||||
m_pReal->GetDesc(&desc);
|
||||
|
||||
return desc.BufferDesc.Width;
|
||||
}
|
||||
|
||||
UINT GetHeight()
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc = {};
|
||||
|
||||
m_pReal->GetDesc(&desc);
|
||||
|
||||
return desc.BufferDesc.Height;
|
||||
}
|
||||
|
||||
DXGI_FORMAT GetFormat()
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc = {};
|
||||
|
||||
m_pReal->GetDesc(&desc);
|
||||
|
||||
return desc.BufferDesc.Format;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user