mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-07-08 16:50:44 +00:00
Add initial skeleton of D3D12 support
* This includes changes to DXGI to remove hard dependency on D3D11 code and support multiple D3D versions initialising through DXGI. * Basically all of the D3D12 interception is unimplemented/stubbed out and only the ID3D12Device interface is present.
This commit is contained in:
@@ -34,7 +34,7 @@ API Support
|
||||
| D3D11 | Well supported, all features. | :heavy_check_mark: | :heavy_multiplication_x: |
|
||||
| OpenGL 3.2 core+ | Well supported, most features.\* | :heavy_check_mark: | :heavy_check_mark: No UI\*\* |
|
||||
| Vulkan | Well supported, most features. | :heavy_check_mark: | :heavy_check_mark: No UI\*\* |
|
||||
| D3D12 | Planned for the future. | :heavy_multiplication_x: | :heavy_multiplication_x: |
|
||||
| D3D12 | In Progress. | :arrows_clockwise: | :heavy_multiplication_x: |
|
||||
| OpenGL Pre-3.2 | No immediate plans | :heavy_multiplication_x: | :heavy_multiplication_x: |
|
||||
| D3D10 | No immediate plans | :heavy_multiplication_x: | :heavy_multiplication_x: |
|
||||
| D3D9 | No immediate plans | :heavy_multiplication_x: | :heavy_multiplication_x: |
|
||||
|
||||
@@ -68,6 +68,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spirv", "renderdoc\driver\s
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vulkan", "renderdoc\driver\vulkan\renderdoc_vulkan.vcxproj", "{88C5DAC6-30A0-4CFD-AF51-540A977D1F3F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "d3d12", "renderdoc\driver\d3d12\renderdoc_d3d12.vcxproj", "{9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Development|Win32 = Development|Win32
|
||||
@@ -196,6 +198,14 @@ Global
|
||||
{88C5DAC6-30A0-4CFD-AF51-540A977D1F3F}.Release|Win32.Build.0 = Release|Win32
|
||||
{88C5DAC6-30A0-4CFD-AF51-540A977D1F3F}.Release|x64.ActiveCfg = Release|x64
|
||||
{88C5DAC6-30A0-4CFD-AF51-540A977D1F3F}.Release|x64.Build.0 = Release|x64
|
||||
{9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Development|Win32.ActiveCfg = Development|Win32
|
||||
{9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Development|Win32.Build.0 = Development|Win32
|
||||
{9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Development|x64.ActiveCfg = Development|x64
|
||||
{9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Development|x64.Build.0 = Development|x64
|
||||
{9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Release|Win32.Build.0 = Release|Win32
|
||||
{9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Release|x64.ActiveCfg = Release|x64
|
||||
{9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -220,5 +230,6 @@ Global
|
||||
{88C5DAC6-30A0-4CFD-AF51-540A977D1F3F} = {864A44B0-5612-451A-857F-41E3EF785EF6}
|
||||
{C43FF27E-A155-4852-88EC-5CE9334C07A8} = {DB2DDA74-A668-4AC7-A1D5-198C9F0BD242}
|
||||
{0AAE0AD1-371B-4A36-9ED1-80E10E960605} = {DB2DDA74-A668-4AC7-A1D5-198C9F0BD242}
|
||||
{9E6B10A2-84B4-434D-ABDB-43BE4EA650F4} = {864A44B0-5612-451A-857F-41E3EF785EF6}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -30,56 +30,6 @@
|
||||
#include "serialise/serialiser.h"
|
||||
#include "serialise/string_utils.h"
|
||||
|
||||
// gives us an address to identify this dll with
|
||||
static int dllLocator = 0;
|
||||
|
||||
HMODULE GetD3DCompiler()
|
||||
{
|
||||
static HMODULE ret = NULL;
|
||||
if(ret != NULL)
|
||||
return ret;
|
||||
|
||||
// dlls to try in priority order
|
||||
const char *dlls[] = {
|
||||
"d3dcompiler_47.dll", "d3dcompiler_46.dll", "d3dcompiler_45.dll",
|
||||
"d3dcompiler_44.dll", "d3dcompiler_43.dll",
|
||||
};
|
||||
|
||||
for(int i = 0; i < 2; i++)
|
||||
{
|
||||
for(int d = 0; d < ARRAY_COUNT(dlls); d++)
|
||||
{
|
||||
if(i == 0)
|
||||
ret = GetModuleHandleA(dlls[d]);
|
||||
else
|
||||
ret = LoadLibraryA(dlls[d]);
|
||||
|
||||
if(ret != NULL)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// all else failed, couldn't find d3dcompiler loaded,
|
||||
// and couldn't even loadlibrary any version!
|
||||
// we'll have to loadlibrary the version that ships with
|
||||
// RenderDoc.
|
||||
|
||||
HMODULE hModule = NULL;
|
||||
GetModuleHandleEx(
|
||||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
(LPCTSTR)&dllLocator, &hModule);
|
||||
wchar_t curFile[512] = {0};
|
||||
GetModuleFileNameW(hModule, curFile, 511);
|
||||
|
||||
wstring path = wstring(curFile);
|
||||
path = dirname(path);
|
||||
wstring dll = path + L"/d3dcompiler_47.dll";
|
||||
|
||||
ret = LoadLibraryW(dll.c_str());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
D3D11_PRIMITIVE_TOPOLOGY MakeD3D11PrimitiveTopology(PrimitiveTopology Topo)
|
||||
{
|
||||
switch(Topo)
|
||||
@@ -1679,17 +1629,6 @@ void Serialiser::Serialise(const char *name, D3D11_SUBRESOURCE_DATA &el)
|
||||
/////////////////////////////////////////////////////////////
|
||||
// Trivial structures
|
||||
|
||||
string ToStrHelper<false, IID>::Get(const IID &el)
|
||||
{
|
||||
char tostrBuf[256] = {0};
|
||||
StringFormat::snprintf(tostrBuf, 255, "GUID {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
|
||||
el.Data1, (unsigned int)el.Data2, (unsigned int)el.Data3, el.Data4[0],
|
||||
el.Data4[1], el.Data4[2], el.Data4[3], el.Data4[4], el.Data4[5],
|
||||
el.Data4[6], el.Data4[7]);
|
||||
|
||||
return tostrBuf;
|
||||
}
|
||||
|
||||
string ToStrHelper<false, D3D11_VIEWPORT>::Get(const D3D11_VIEWPORT &el)
|
||||
{
|
||||
char tostrBuf[256] = {0};
|
||||
|
||||
@@ -29,14 +29,13 @@
|
||||
|
||||
#include "api/replay/renderdoc_replay.h"
|
||||
#include "core/core.h"
|
||||
#include "official/d3d11_4.h"
|
||||
#include "official/dxgi1_3.h"
|
||||
#include "driver/dx/official/d3d11_4.h"
|
||||
#include "driver/dx/official/dxgi1_3.h"
|
||||
#include "driver/shaders/dxbc/dxbc_compile.h"
|
||||
|
||||
class WrappedID3D11Device;
|
||||
struct D3D11RenderState;
|
||||
|
||||
HMODULE GetD3DCompiler();
|
||||
|
||||
ResourceFormat MakeResourceFormat(DXGI_FORMAT fmt);
|
||||
DXGI_FORMAT MakeDXGIFormat(ResourceFormat fmt);
|
||||
PrimitiveTopology MakePrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY Topo);
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "driver/d3d11/d3d11_context.h"
|
||||
#include "driver/d3d11/d3d11_renderstate.h"
|
||||
#include "driver/d3d11/d3d11_resources.h"
|
||||
#include "official/dxgi1_3.h"
|
||||
#include "driver/dx/official/dxgi1_3.h"
|
||||
#include "serialise/string_utils.h"
|
||||
|
||||
#ifndef DXGI_ERROR_INVALID_CALL
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
#include "common/shader_cache.h"
|
||||
#include "data/resource.h"
|
||||
#include "driver/d3d11/d3d11_resources.h"
|
||||
#include "driver/dx/official/d3dcompiler.h"
|
||||
#include "driver/shaders/dxbc/dxbc_debug.h"
|
||||
#include "maths/camera.h"
|
||||
#include "maths/formatpacking.h"
|
||||
#include "maths/matrix.h"
|
||||
#include "official/d3dcompiler.h"
|
||||
#include "serialise/string_utils.h"
|
||||
#include "stb/stb_truetype.h"
|
||||
#include "d3d11_context.h"
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include "api/replay/renderdoc_replay.h"
|
||||
#include "driver/dx/official/d3d11_4.h"
|
||||
#include "driver/shaders/dxbc/dxbc_debug.h"
|
||||
#include "official/d3d11_4.h"
|
||||
|
||||
using std::map;
|
||||
using std::pair;
|
||||
|
||||
@@ -270,6 +270,28 @@ ReplayCreateStatus D3D11InitParams::Serialise()
|
||||
return eReplayCreate_Success;
|
||||
}
|
||||
|
||||
void WrappedID3D11Device::ShutdownSwapchain(WrappedIDXGISwapChain3 *swapChain)
|
||||
{
|
||||
for(int i = 0; i < swapChain->GetNumBackbuffers(); i++)
|
||||
{
|
||||
WrappedID3D11Texture2D1 *wrapped = (WrappedID3D11Texture2D1 *)swapChain->GetBackbuffers()[i];
|
||||
if(wrapped)
|
||||
wrapped->ViewRelease();
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedID3D11Device::NewSwapchainBuffer(IUnknown *backbuffer)
|
||||
{
|
||||
WrappedID3D11Texture2D1 *wrapped = (WrappedID3D11Texture2D1 *)backbuffer;
|
||||
|
||||
if(wrapped)
|
||||
{
|
||||
// keep ref as a 'view' (invisible to user)
|
||||
wrapped->ViewAddRef();
|
||||
wrapped->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedID3D11Device::SetLogFile(const char *logfile)
|
||||
{
|
||||
#if defined(RELEASE)
|
||||
@@ -932,7 +954,7 @@ void WrappedID3D11Device::ProcessChunk(uint64_t offset, D3D11ChunkType context)
|
||||
}
|
||||
case SET_RESOURCE_NAME: Serialise_SetResourceName(0x0, ""); break;
|
||||
case RELEASE_RESOURCE: Serialise_ReleaseResource(0x0); break;
|
||||
case CREATE_SWAP_BUFFER: Serialise_SetSwapChainTexture(0x0, 0x0, 0, 0x0); break;
|
||||
case CREATE_SWAP_BUFFER: Serialise_WrapSwapchainBuffer(0x0, 0x0, 0, 0x0); break;
|
||||
case CREATE_TEXTURE_1D: Serialise_CreateTexture1D(0x0, 0x0, 0x0); break;
|
||||
case CREATE_TEXTURE_2D: Serialise_CreateTexture2D(0x0, 0x0, 0x0); break;
|
||||
case CREATE_TEXTURE_2D1: Serialise_CreateTexture2D1(0x0, 0x0, 0x0); break;
|
||||
@@ -2390,8 +2412,24 @@ void WrappedID3D11Device::ReplayLog(uint32_t startEventID, uint32_t endEventID,
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedID3D11Device::ReleaseSwapchainResources(IDXGISwapChain *swap)
|
||||
void WrappedID3D11Device::ReleaseSwapchainResources(WrappedIDXGISwapChain3 *swap)
|
||||
{
|
||||
for(int i = 0; i < swap->GetNumBackbuffers(); i++)
|
||||
{
|
||||
WrappedID3D11Texture2D1 *wrapped11 = (WrappedID3D11Texture2D1 *)swap->GetBackbuffers()[i];
|
||||
if(wrapped11)
|
||||
{
|
||||
D3D11RenderState::ResourceRange range(wrapped11);
|
||||
|
||||
GetImmediateContext()->GetCurrentPipelineState()->UnbindIUnknownForWrite(range);
|
||||
GetImmediateContext()->GetCurrentPipelineState()->UnbindIUnknownForRead(range, false, false);
|
||||
|
||||
wrapped11->ViewRelease();
|
||||
}
|
||||
|
||||
wrapped11 = NULL;
|
||||
}
|
||||
|
||||
if(swap)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
@@ -2410,10 +2448,12 @@ void WrappedID3D11Device::ReleaseSwapchainResources(IDXGISwapChain *swap)
|
||||
}
|
||||
}
|
||||
|
||||
bool WrappedID3D11Device::Serialise_SetSwapChainTexture(IDXGISwapChain *swap,
|
||||
bool WrappedID3D11Device::Serialise_WrapSwapchainBuffer(WrappedIDXGISwapChain3 *swap,
|
||||
DXGI_SWAP_CHAIN_DESC *swapDesc, UINT buffer,
|
||||
ID3D11Texture2D *pTex)
|
||||
IUnknown *realSurface)
|
||||
{
|
||||
WrappedID3D11Texture2D1 *pTex = (WrappedID3D11Texture2D1 *)realSurface;
|
||||
|
||||
SERIALISE_ELEMENT(DXGI_FORMAT, swapFormat, swapDesc->BufferDesc.Format);
|
||||
SERIALISE_ELEMENT(uint32_t, BuffNum, buffer);
|
||||
SERIALISE_ELEMENT(ResourceId, pTexture, GetIDForResource(pTex));
|
||||
@@ -2462,9 +2502,26 @@ bool WrappedID3D11Device::Serialise_SetSwapChainTexture(IDXGISwapChain *swap,
|
||||
return true;
|
||||
}
|
||||
|
||||
void WrappedID3D11Device::SetSwapChainTexture(IDXGISwapChain *swap, DXGI_SWAP_CHAIN_DESC *swapDesc,
|
||||
UINT buffer, ID3D11Texture2D *pTex)
|
||||
IUnknown *WrappedID3D11Device::WrapSwapchainBuffer(WrappedIDXGISwapChain3 *swap,
|
||||
DXGI_SWAP_CHAIN_DESC *swapDesc, UINT buffer,
|
||||
IUnknown *realSurface)
|
||||
{
|
||||
if(GetResourceManager()->HasWrapper((ID3D11DeviceChild *)realSurface))
|
||||
{
|
||||
ID3D11Texture2D *tex =
|
||||
(ID3D11Texture2D *)GetResourceManager()->GetWrapper((ID3D11DeviceChild *)realSurface);
|
||||
tex->AddRef();
|
||||
|
||||
realSurface->Release();
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
WrappedID3D11Texture2D1 *pTex =
|
||||
new WrappedID3D11Texture2D1((ID3D11Texture2D *)realSurface, this, TEXDISPLAY_UNKNOWN);
|
||||
|
||||
SetDebugName(pTex, "Swap Chain Backbuffer");
|
||||
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
pTex->GetDesc(&desc);
|
||||
|
||||
@@ -2489,7 +2546,7 @@ void WrappedID3D11Device::SetSwapChainTexture(IDXGISwapChain *swap, DXGI_SWAP_CH
|
||||
|
||||
SCOPED_SERIALISE_CONTEXT(CREATE_SWAP_BUFFER);
|
||||
|
||||
Serialise_SetSwapChainTexture(swap, swapDesc, buffer, pTex);
|
||||
Serialise_WrapSwapchainBuffer(swap, swapDesc, buffer, pTex);
|
||||
|
||||
record->AddChunk(scope.Get());
|
||||
}
|
||||
@@ -2514,6 +2571,8 @@ void WrappedID3D11Device::SetSwapChainTexture(IDXGISwapChain *swap, DXGI_SWAP_CH
|
||||
|
||||
RenderDoc::Inst().AddFrameCapturer((ID3D11Device *)this, sdesc.OutputWindow, this);
|
||||
}
|
||||
|
||||
return pTex;
|
||||
}
|
||||
|
||||
void WrappedID3D11Device::SetMarker(uint32_t col, const wchar_t *name)
|
||||
@@ -2604,7 +2663,7 @@ bool WrappedID3D11Device::EndFrameCapture(void *dev, void *wnd)
|
||||
|
||||
CaptureFailReason reason;
|
||||
|
||||
IDXGISwapChain *swap = NULL;
|
||||
WrappedIDXGISwapChain3 *swap = NULL;
|
||||
|
||||
if(wnd)
|
||||
{
|
||||
@@ -3052,10 +3111,10 @@ bool WrappedID3D11Device::EndFrameCapture(void *dev, void *wnd)
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedID3D11Device::FirstFrame(IDXGISwapChain *swap)
|
||||
void WrappedID3D11Device::FirstFrame(WrappedIDXGISwapChain3 *swapChain)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC swapdesc;
|
||||
swap->GetDesc(&swapdesc);
|
||||
swapChain->GetDesc(&swapdesc);
|
||||
|
||||
// if we have to capture the first frame, begin capturing immediately
|
||||
if(m_State == WRITING_IDLE && RenderDoc::Inst().ShouldTriggerCapture(0))
|
||||
@@ -3066,7 +3125,7 @@ void WrappedID3D11Device::FirstFrame(IDXGISwapChain *swap)
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D11Device::Present(IDXGISwapChain *swap, UINT SyncInterval, UINT Flags)
|
||||
HRESULT WrappedID3D11Device::Present(WrappedIDXGISwapChain3 *swap, UINT SyncInterval, UINT Flags)
|
||||
{
|
||||
if((Flags & DXGI_PRESENT_TEST) != 0)
|
||||
return S_OK;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "common/threading.h"
|
||||
#include "common/timing.h"
|
||||
#include "core/core.h"
|
||||
#include "driver/dxgi/dxgi_wrapped.h"
|
||||
#include "d3d11_common.h"
|
||||
#include "d3d11_debug.h"
|
||||
#include "d3d11_manager.h"
|
||||
@@ -263,7 +264,7 @@ struct DummyID3D11Debug : public ID3D11Debug
|
||||
class WrappedID3D11ClassLinkage;
|
||||
enum CaptureFailReason;
|
||||
|
||||
class WrappedID3D11Device : public IFrameCapturer, public ID3D11Device4
|
||||
class WrappedID3D11Device : public IFrameCapturer, public ID3DDevice, public ID3D11Device4
|
||||
{
|
||||
private:
|
||||
// since enumeration creates a lot of devices, save
|
||||
@@ -341,7 +342,7 @@ private:
|
||||
|
||||
static WrappedID3D11Device *m_pCurrentWrappedDevice;
|
||||
|
||||
map<IDXGISwapChain *, ID3D11RenderTargetView *> m_SwapChains;
|
||||
map<WrappedIDXGISwapChain3 *, ID3D11RenderTargetView *> m_SwapChains;
|
||||
|
||||
uint32_t m_FrameCounter;
|
||||
uint32_t m_FailedFrame;
|
||||
@@ -393,7 +394,7 @@ public:
|
||||
FetchFrameStatistics &GetFrameStats() { return m_FrameRecord.frameInfo.stats; }
|
||||
const FetchDrawcall *GetDrawcall(uint32_t eventID);
|
||||
|
||||
void FirstFrame(IDXGISwapChain *swap);
|
||||
void FirstFrame(WrappedIDXGISwapChain3 *swapChain);
|
||||
|
||||
vector<DebugMessage> GetDebugMessages();
|
||||
void AddDebugMessage(DebugMessage msg);
|
||||
@@ -404,13 +405,16 @@ public:
|
||||
return m_LayoutDescs[layout];
|
||||
}
|
||||
|
||||
void ReleaseSwapchainResources(IDXGISwapChain *swap);
|
||||
|
||||
void Serialise_CaptureScope(uint64_t offset);
|
||||
|
||||
void StartFrameCapture(void *dev, void *wnd);
|
||||
bool EndFrameCapture(void *dev, void *wnd);
|
||||
|
||||
// interface for DXGI
|
||||
virtual IUnknown *GetRealIUnknown() { return GetReal(); }
|
||||
virtual IID GetBackbufferUUID() { return __uuidof(ID3D11Texture2D); }
|
||||
virtual IID GetDeviceUUID() { return __uuidof(ID3D11Device); }
|
||||
virtual IUnknown *GetDeviceInterface() { return (ID3D11Device *)this; }
|
||||
////////////////////////////////////////////////////////////////
|
||||
// log replaying
|
||||
|
||||
@@ -447,10 +451,15 @@ public:
|
||||
ID3D11ClassInstance *inst));
|
||||
|
||||
// Swap Chain
|
||||
IMPLEMENT_FUNCTION_SERIALISED(void, SetSwapChainTexture(IDXGISwapChain *swap,
|
||||
DXGI_SWAP_CHAIN_DESC *desc, UINT buffer,
|
||||
ID3D11Texture2D *pTex));
|
||||
HRESULT Present(IDXGISwapChain *swap, UINT SyncInterval, UINT Flags);
|
||||
IMPLEMENT_FUNCTION_SERIALISED(IUnknown *, WrapSwapchainBuffer(WrappedIDXGISwapChain3 *swap,
|
||||
DXGI_SWAP_CHAIN_DESC *desc,
|
||||
UINT buffer, IUnknown *realSurface));
|
||||
HRESULT Present(WrappedIDXGISwapChain3 *swap, UINT SyncInterval, UINT Flags);
|
||||
|
||||
void ShutdownSwapchain(WrappedIDXGISwapChain3 *swapChain);
|
||||
void NewSwapchainBuffer(IUnknown *backbuffer);
|
||||
|
||||
void ReleaseSwapchainResources(WrappedIDXGISwapChain3 *swap);
|
||||
|
||||
void InternalRef() { InterlockedIncrement(&m_InternalRefcount); }
|
||||
void InternalRelease() { InterlockedDecrement(&m_InternalRefcount); }
|
||||
|
||||
@@ -29,6 +29,14 @@
|
||||
|
||||
#define DLL_NAME "d3d11.dll"
|
||||
|
||||
ID3DDevice *GetD3D11DeviceIfAlloc(IUnknown *dev)
|
||||
{
|
||||
if(WrappedID3D11Device::IsAlloc(dev))
|
||||
return (ID3DDevice *)dev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
class D3D11Hook : LibraryHook
|
||||
{
|
||||
public:
|
||||
@@ -37,6 +45,8 @@ public:
|
||||
LibraryHooks::GetInstance().RegisterHook(DLL_NAME, this);
|
||||
m_EnabledHooks = true;
|
||||
m_InsideCreate = false;
|
||||
|
||||
WrappedIDXGISwapChain3::RegisterD3DDeviceCallback(GetD3D11DeviceIfAlloc);
|
||||
}
|
||||
|
||||
bool CreateHooks(const char *libName)
|
||||
@@ -84,7 +94,6 @@ private:
|
||||
bool m_HasHooks;
|
||||
bool m_EnabledHooks;
|
||||
|
||||
byte CreateDeviceAndSwapChain_ident[16];
|
||||
Hook<PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN> CreateDeviceAndSwapChain;
|
||||
Hook<PFN_D3D11_CREATE_DEVICE> CreateDevice;
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "d3d11_replay.h"
|
||||
#include "driver/dx/official/d3dcompiler.h"
|
||||
#include "driver/shaders/dxbc/dxbc_debug.h"
|
||||
#include "official/d3dcompiler.h"
|
||||
#include "serialise/string_utils.h"
|
||||
#include "d3d11_context.h"
|
||||
#include "d3d11_debug.h"
|
||||
|
||||
@@ -214,22 +214,14 @@
|
||||
<ClInclude Include="d3d11_renderstate.h" />
|
||||
<ClInclude Include="d3d11_replay.h" />
|
||||
<ClInclude Include="d3d11_resources.h" />
|
||||
<ClInclude Include="official\d3d11.h" />
|
||||
<ClInclude Include="official\d3d11sdklayers.h" />
|
||||
<ClInclude Include="official\d3d11_1.h" />
|
||||
<ClInclude Include="official\d3d11_2.h" />
|
||||
<ClInclude Include="official\d3d11_3.h" />
|
||||
<ClInclude Include="official\d3d11_4.h" />
|
||||
<ClInclude Include="official\d3dcommon.h" />
|
||||
<ClInclude Include="official\d3dcompiler.h" />
|
||||
<ClInclude Include="official\dxgi.h" />
|
||||
<ClInclude Include="official\dxgi1_2.h" />
|
||||
<ClInclude Include="official\dxgi1_3.h" />
|
||||
<ClInclude Include="official\dxgi1_4.h" />
|
||||
<ClInclude Include="official\dxgi1_5.h" />
|
||||
<ClInclude Include="official\dxgiformat.h" />
|
||||
<ClInclude Include="official\dxgitype.h" />
|
||||
<ClInclude Include="official\winapifamily.h" />
|
||||
<ClInclude Include="..\dx\official\d3d11.h" />
|
||||
<ClInclude Include="..\dx\official\d3d11_1.h" />
|
||||
<ClInclude Include="..\dx\official\d3d11_2.h" />
|
||||
<ClInclude Include="..\dx\official\d3d11_3.h" />
|
||||
<ClInclude Include="..\dx\official\d3d11_4.h" />
|
||||
<ClInclude Include="..\dx\official\d3d11sdklayers.h" />
|
||||
<ClInclude Include="..\dx\official\d3dcommon.h" />
|
||||
<ClInclude Include="..\dx\official\d3dcompiler.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\shaders\dxbc\renderdoc_dxbc.vcxproj">
|
||||
@@ -244,4 +236,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -107,53 +107,29 @@
|
||||
<ClInclude Include="d3d11_common.h">
|
||||
<Filter>Util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\d3d11_1.h">
|
||||
<ClInclude Include="..\dx\official\d3d11.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\d3d11_2.h">
|
||||
<ClInclude Include="..\dx\official\d3d11_1.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\d3d11sdklayers.h">
|
||||
<ClInclude Include="..\dx\official\d3d11_2.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\d3dcommon.h">
|
||||
<ClInclude Include="..\dx\official\d3d11_3.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\d3dcompiler.h">
|
||||
<ClInclude Include="..\dx\official\d3d11_4.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\dxgi.h">
|
||||
<ClInclude Include="..\dx\official\d3d11sdklayers.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\dxgi1_2.h">
|
||||
<ClInclude Include="..\dx\official\d3dcommon.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\dxgi1_3.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\winapifamily.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\d3d11.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\d3d11_3.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\d3d11_4.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\dxgi1_4.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\dxgi1_5.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\dxgiformat.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="official\dxgitype.h">
|
||||
<ClInclude Include="..\dx\official\d3dcompiler.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
#include "d3d12_common.h"
|
||||
#include "driver/dxgi/dxgi_wrapped.h"
|
||||
|
||||
HRESULT STDMETHODCALLTYPE RefCounter12::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
return RefCountDXGIObject::WrapQueryInterface(m_pReal, riid, ppvObject);
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define INITGUID
|
||||
|
||||
#include "api/replay/renderdoc_replay.h"
|
||||
#include "core/core.h"
|
||||
#include "driver/dx/official/d3d12.h"
|
||||
#include "driver/dx/official/dxgi1_4.h"
|
||||
#include "driver/shaders/dxbc/dxbc_compile.h"
|
||||
#include "serialise/serialiser.h"
|
||||
|
||||
class WrappedID3D12Device;
|
||||
|
||||
class RefCounter12
|
||||
{
|
||||
private:
|
||||
IUnknown *m_pReal;
|
||||
unsigned int m_iRefcount;
|
||||
bool m_SelfDeleting;
|
||||
|
||||
protected:
|
||||
void SetSelfDeleting(bool selfDelete) { m_SelfDeleting = selfDelete; }
|
||||
// used for derived classes that need to soft ref but are handling their
|
||||
// own self-deletion
|
||||
static void AddDeviceSoftref(WrappedID3D12Device *device);
|
||||
static void ReleaseDeviceSoftref(WrappedID3D12Device *device);
|
||||
|
||||
public:
|
||||
RefCounter12(IUnknown *real, bool selfDelete = true)
|
||||
: m_pReal(real), m_iRefcount(1), m_SelfDeleting(selfDelete)
|
||||
{
|
||||
}
|
||||
virtual ~RefCounter12() {}
|
||||
unsigned int GetRefCount() { return m_iRefcount; }
|
||||
//////////////////////////////
|
||||
// implement IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
InterlockedIncrement(&m_iRefcount);
|
||||
return m_iRefcount;
|
||||
}
|
||||
ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
unsigned int ret = InterlockedDecrement(&m_iRefcount);
|
||||
if(ret == 0 && m_SelfDeleting)
|
||||
delete this;
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int SoftRef(WrappedID3D12Device *device);
|
||||
unsigned int SoftRelease(WrappedID3D12Device *device);
|
||||
};
|
||||
|
||||
#define IMPLEMENT_IUNKNOWN_WITH_REFCOUNTER_CUSTOMQUERY \
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return RefCounter12::AddRef(); } \
|
||||
ULONG STDMETHODCALLTYPE Release() { return RefCounter12::Release(); }
|
||||
#define IMPLEMENT_FUNCTION_SERIALISED(ret, func) \
|
||||
ret func; \
|
||||
bool CONCAT(Serialise_, func);
|
||||
|
||||
#pragma region Chunks
|
||||
|
||||
enum D3D12ChunkType
|
||||
{
|
||||
DEVICE_INIT = FIRST_CHUNK_ID,
|
||||
SET_RESOURCE_NAME,
|
||||
RELEASE_RESOURCE,
|
||||
CREATE_SWAP_BUFFER,
|
||||
|
||||
CAPTURE_SCOPE,
|
||||
|
||||
PUSH_EVENT,
|
||||
SET_MARKER,
|
||||
POP_EVENT,
|
||||
|
||||
DEBUG_MESSAGES,
|
||||
|
||||
CONTEXT_CAPTURE_HEADER, // chunk at beginning of context's chunk stream
|
||||
CONTEXT_CAPTURE_FOOTER, // chunk at end of context's chunk stream
|
||||
|
||||
SET_SHADER_DEBUG_PATH,
|
||||
|
||||
NUM_D3D12_CHUNKS,
|
||||
};
|
||||
|
||||
#pragma endregion Chunks
|
||||
@@ -0,0 +1,507 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
#include "driver/d3d12/d3d12_device.h"
|
||||
#include "core/core.h"
|
||||
#include "driver/dxgi/dxgi_wrapped.h"
|
||||
#include "jpeg-compressor/jpge.h"
|
||||
#include "maths/formatpacking.h"
|
||||
#include "serialise/string_utils.h"
|
||||
|
||||
WRAPPED_POOL_INST(WrappedID3D12Device);
|
||||
|
||||
const char *D3D12ChunkNames[] = {
|
||||
"ID3D11Device::Initialisation",
|
||||
"ID3D12Object::SetName",
|
||||
"ID3D12Resource::Release",
|
||||
"IDXGISwapChain::GetBuffer",
|
||||
|
||||
"Capture",
|
||||
|
||||
"ID3D12CommandQueue::BeginEvent",
|
||||
"ID3D12CommandQueue::SetMarker",
|
||||
"ID3D12CommandQueue::EndEvent",
|
||||
|
||||
"DebugMessageList",
|
||||
|
||||
"ContextBegin",
|
||||
"ContextEnd",
|
||||
|
||||
"SetShaderDebugPath",
|
||||
};
|
||||
|
||||
D3D12InitParams::D3D12InitParams()
|
||||
{
|
||||
SerialiseVersion = D3D12_SERIALISE_VERSION;
|
||||
MinimumFeatureLevel = D3D_FEATURE_LEVEL_11_0;
|
||||
}
|
||||
|
||||
ReplayCreateStatus D3D12InitParams::Serialise()
|
||||
{
|
||||
SERIALISE_ELEMENT(uint32_t, ver, D3D12_SERIALISE_VERSION);
|
||||
SerialiseVersion = ver;
|
||||
|
||||
if(ver != D3D12_SERIALISE_VERSION)
|
||||
{
|
||||
RDCERR("Incompatible D3D12 serialise version, expected %d got %d", D3D12_SERIALISE_VERSION, ver);
|
||||
return eReplayCreate_APIIncompatibleVersion;
|
||||
}
|
||||
|
||||
m_pSerialiser->Serialise("MinimumFeatureLevel", MinimumFeatureLevel);
|
||||
|
||||
return eReplayCreate_Success;
|
||||
}
|
||||
|
||||
const char *WrappedID3D12Device::GetChunkName(uint32_t idx)
|
||||
{
|
||||
if(idx == CREATE_PARAMS)
|
||||
return "Create Params";
|
||||
if(idx == THUMBNAIL_DATA)
|
||||
return "Thumbnail Data";
|
||||
if(idx == DRIVER_INIT_PARAMS)
|
||||
return "Driver Init Params";
|
||||
if(idx == INITIAL_CONTENTS)
|
||||
return "Initial Contents";
|
||||
if(idx < FIRST_CHUNK_ID || idx >= NUM_D3D12_CHUNKS)
|
||||
return "<unknown>";
|
||||
return D3D12ChunkNames[idx - FIRST_CHUNK_ID];
|
||||
}
|
||||
|
||||
template <>
|
||||
string ToStrHelper<false, D3D12ChunkType>::Get(const D3D12ChunkType &el)
|
||||
{
|
||||
return WrappedID3D12Device::GetChunkName(el);
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE DummyID3D12InfoQueue::AddRef()
|
||||
{
|
||||
m_pDevice->AddRef();
|
||||
return 1;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE DummyID3D12InfoQueue::Release()
|
||||
{
|
||||
m_pDevice->Release();
|
||||
return 1;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE DummyID3D12DebugDevice::AddRef()
|
||||
{
|
||||
m_pDevice->AddRef();
|
||||
return 1;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE DummyID3D12DebugDevice::Release()
|
||||
{
|
||||
m_pDevice->Release();
|
||||
return 1;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE DummyID3D12DebugDevice::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if(riid == __uuidof(ID3D12InfoQueue) || riid == __uuidof(ID3D12DebugDevice) ||
|
||||
riid == __uuidof(ID3D12Device))
|
||||
return m_pDevice->QueryInterface(riid, ppvObject);
|
||||
|
||||
if(riid == __uuidof(IUnknown))
|
||||
{
|
||||
*ppvObject = (IUnknown *)(ID3D12DebugDevice *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
RDCWARN("Querying ID3D12DebugDevice for interface: %s", ToStr::Get(riid).c_str());
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE WrappedID3D12DebugDevice::AddRef()
|
||||
{
|
||||
m_pDevice->AddRef();
|
||||
return 1;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE WrappedID3D12DebugDevice::Release()
|
||||
{
|
||||
m_pDevice->Release();
|
||||
return 1;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedID3D12DebugDevice::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if(riid == __uuidof(ID3D12InfoQueue) || riid == __uuidof(ID3D12DebugDevice) ||
|
||||
riid == __uuidof(ID3D12Device))
|
||||
return m_pDevice->QueryInterface(riid, ppvObject);
|
||||
|
||||
if(riid == __uuidof(IUnknown))
|
||||
{
|
||||
*ppvObject = (IUnknown *)(ID3D12DebugDevice *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
string guid = ToStr::Get(riid);
|
||||
RDCWARN("Querying ID3D12DebugDevice for interface: %s", guid.c_str());
|
||||
|
||||
return m_pDebug->QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitParams *params)
|
||||
: m_RefCounter(realDevice, false), m_SoftRefCounter(NULL, false), m_pDevice(realDevice)
|
||||
{
|
||||
if(RenderDoc::Inst().GetCrashHandler())
|
||||
RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(WrappedID3D12Device));
|
||||
|
||||
// refcounters implicitly construct with one reference, but we don't start with any soft
|
||||
// references.
|
||||
m_SoftRefCounter.Release();
|
||||
m_InternalRefcount = 0;
|
||||
m_Alive = true;
|
||||
|
||||
m_DummyInfoQueue.m_pDevice = this;
|
||||
m_DummyDebug.m_pDevice = this;
|
||||
m_WrappedDebug.m_pDevice = this;
|
||||
|
||||
m_AppControlledCapture = false;
|
||||
|
||||
if(RenderDoc::Inst().IsReplayApp())
|
||||
{
|
||||
m_State = READING;
|
||||
m_pSerialiser = NULL;
|
||||
|
||||
ResourceIDGen::SetReplayResourceIDs();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_State = WRITING_IDLE;
|
||||
m_pSerialiser = new Serialiser(NULL, Serialiser::WRITING, true);
|
||||
}
|
||||
|
||||
m_ResourceManager = new D3D12ResourceManager(m_State, m_pSerialiser, this);
|
||||
|
||||
if(m_pSerialiser)
|
||||
m_pSerialiser->SetChunkNameLookup(&GetChunkName);
|
||||
|
||||
// create a temporary and grab its resource ID
|
||||
m_ResourceID = ResourceIDGen::GetNewUniqueID();
|
||||
|
||||
m_DeviceRecord = NULL;
|
||||
|
||||
if(!RenderDoc::Inst().IsReplayApp())
|
||||
{
|
||||
m_DeviceRecord = GetResourceManager()->AddResourceRecord(m_ResourceID);
|
||||
m_DeviceRecord->DataInSerialiser = false;
|
||||
m_DeviceRecord->SpecialResource = true;
|
||||
m_DeviceRecord->Length = 0;
|
||||
m_DeviceRecord->NumSubResources = 0;
|
||||
m_DeviceRecord->SubResources = NULL;
|
||||
|
||||
RenderDoc::Inst().AddDeviceFrameCapturer((ID3D12Device *)this, this);
|
||||
}
|
||||
|
||||
realDevice->QueryInterface(__uuidof(ID3D12InfoQueue), (void **)&m_pInfoQueue);
|
||||
realDevice->QueryInterface(__uuidof(ID3D12DebugDevice), (void **)&m_WrappedDebug.m_pDebug);
|
||||
|
||||
if(m_pInfoQueue)
|
||||
{
|
||||
if(RenderDoc::Inst().GetCaptureOptions().DebugOutputMute)
|
||||
m_pInfoQueue->SetMuteDebugOutput(true);
|
||||
|
||||
UINT size = m_pInfoQueue->GetStorageFilterStackSize();
|
||||
|
||||
while(size > 1)
|
||||
{
|
||||
m_pInfoQueue->ClearStorageFilter();
|
||||
size = m_pInfoQueue->GetStorageFilterStackSize();
|
||||
}
|
||||
|
||||
size = m_pInfoQueue->GetRetrievalFilterStackSize();
|
||||
|
||||
while(size > 1)
|
||||
{
|
||||
m_pInfoQueue->ClearRetrievalFilter();
|
||||
size = m_pInfoQueue->GetRetrievalFilterStackSize();
|
||||
}
|
||||
|
||||
m_pInfoQueue->ClearStoredMessages();
|
||||
|
||||
if(RenderDoc::Inst().IsReplayApp())
|
||||
m_pInfoQueue->SetMuteDebugOutput(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCDEBUG("Couldn't get ID3D12InfoQueue.");
|
||||
}
|
||||
|
||||
m_InitParams = *params;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Compile time asserts
|
||||
|
||||
RDCCOMPILE_ASSERT(ARRAY_COUNT(D3D12ChunkNames) == NUM_D3D12_CHUNKS - FIRST_CHUNK_ID,
|
||||
"Not right number of chunk names");
|
||||
}
|
||||
|
||||
WrappedID3D12Device::~WrappedID3D12Device()
|
||||
{
|
||||
RenderDoc::Inst().RemoveDeviceFrameCapturer((ID3D12Device *)this);
|
||||
|
||||
if(m_DeviceRecord)
|
||||
{
|
||||
RDCASSERT(m_DeviceRecord->GetRefCount() == 1);
|
||||
m_DeviceRecord->Delete(GetResourceManager());
|
||||
}
|
||||
|
||||
m_ResourceManager->Shutdown();
|
||||
|
||||
SAFE_DELETE(m_ResourceManager);
|
||||
|
||||
SAFE_RELEASE(m_pInfoQueue);
|
||||
SAFE_RELEASE(m_pDevice);
|
||||
|
||||
SAFE_DELETE(m_pSerialiser);
|
||||
|
||||
if(RenderDoc::Inst().GetCrashHandler())
|
||||
RenderDoc::Inst().GetCrashHandler()->UnregisterMemoryRegion(this);
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
// DEFINE_GUID(IID_IDirect3DDevice9, 0xd0223b96, 0xbf7a, 0x43fd, 0x92, 0xbd, 0xa4, 0x3b, 0xd,
|
||||
// 0x82, 0xb9, 0xeb);
|
||||
static const GUID IDirect3DDevice9_uuid = {
|
||||
0xd0223b96, 0xbf7a, 0x43fd, {0x92, 0xbd, 0xa4, 0x3b, 0xd, 0x82, 0xb9, 0xeb}};
|
||||
|
||||
// ID3D10Device UUID {9B7E4C0F-342C-4106-A19F-4F2704F689F0}
|
||||
static const GUID ID3D10Device_uuid = {
|
||||
0x9b7e4c0f, 0x342c, 0x4106, {0xa1, 0x9f, 0x4f, 0x27, 0x04, 0xf6, 0x89, 0xf0}};
|
||||
|
||||
// RenderDoc UUID {A7AA6116-9C8D-4BBA-9083-B4D816B71B78}
|
||||
static const GUID IRenderDoc_uuid = {
|
||||
0xa7aa6116, 0x9c8d, 0x4bba, {0x90, 0x83, 0xb4, 0xd8, 0x16, 0xb7, 0x1b, 0x78}};
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if(riid == __uuidof(IUnknown))
|
||||
{
|
||||
*ppvObject = (IUnknown *)(ID3D12Device *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(IDXGIDevice))
|
||||
{
|
||||
hr = m_pDevice->QueryInterface(riid, ppvObject);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
IDXGIDevice *real = (IDXGIDevice *)(*ppvObject);
|
||||
*ppvObject = new WrappedIDXGIDevice(real, this);
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
else if(riid == __uuidof(IDXGIDevice1))
|
||||
{
|
||||
hr = m_pDevice->QueryInterface(riid, ppvObject);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
IDXGIDevice1 *real = (IDXGIDevice1 *)(*ppvObject);
|
||||
*ppvObject = new WrappedIDXGIDevice1(real, this);
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
else if(riid == __uuidof(IDXGIDevice2))
|
||||
{
|
||||
hr = m_pDevice->QueryInterface(riid, ppvObject);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
IDXGIDevice2 *real = (IDXGIDevice2 *)(*ppvObject);
|
||||
*ppvObject = new WrappedIDXGIDevice2(real, this);
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
else if(riid == __uuidof(IDXGIDevice3))
|
||||
{
|
||||
hr = m_pDevice->QueryInterface(riid, ppvObject);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
IDXGIDevice3 *real = (IDXGIDevice3 *)(*ppvObject);
|
||||
*ppvObject = new WrappedIDXGIDevice3(real, this);
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
return hr;
|
||||
}
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12InfoQueue))
|
||||
{
|
||||
RDCWARN(
|
||||
"Returning a dummy ID3D12InfoQueue that does nothing. This ID3D12InfoQueue will not work!");
|
||||
*ppvObject = (ID3D12InfoQueue *)&m_DummyInfoQueue;
|
||||
m_DummyInfoQueue.AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(ID3D12DebugDevice))
|
||||
{
|
||||
// we queryinterface for this at startup, so if it's present we can
|
||||
// return our wrapper
|
||||
if(m_WrappedDebug.m_pDebug)
|
||||
{
|
||||
AddRef();
|
||||
*ppvObject = (ID3D12DebugDevice *)&m_WrappedDebug;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN(
|
||||
"Returning a dummy ID3D12DebugDevice that does nothing. This ID3D12DebugDevice will not "
|
||||
"work!");
|
||||
*ppvObject = (ID3D12DebugDevice *)&m_DummyDebug;
|
||||
m_DummyDebug.AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
else if(riid == IRenderDoc_uuid)
|
||||
{
|
||||
AddRef();
|
||||
*ppvObject = (IUnknown *)this;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
string guid = ToStr::Get(riid);
|
||||
RDCWARN("Querying ID3D12Device for interface: %s", guid.c_str());
|
||||
}
|
||||
|
||||
return m_RefCounter.QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::CheckForDeath()
|
||||
{
|
||||
if(!m_Alive)
|
||||
return;
|
||||
|
||||
if(m_RefCounter.GetRefCount() == 0)
|
||||
{
|
||||
RDCASSERT(m_SoftRefCounter.GetRefCount() >= m_InternalRefcount);
|
||||
|
||||
if(m_SoftRefCounter.GetRefCount() <= m_InternalRefcount || m_State < WRITING) // MEGA HACK
|
||||
{
|
||||
m_Alive = false;
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::FirstFrame(WrappedIDXGISwapChain3 *swap)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC swapdesc;
|
||||
swap->GetDesc(&swapdesc);
|
||||
|
||||
// if we have to capture the first frame, begin capturing immediately
|
||||
if(m_State == WRITING_IDLE && RenderDoc::Inst().ShouldTriggerCapture(0))
|
||||
{
|
||||
RenderDoc::Inst().StartFrameCapture((ID3D12Device *)this, swapdesc.OutputWindow);
|
||||
|
||||
m_AppControlledCapture = false;
|
||||
}
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::ReleaseSwapchainResources(WrappedIDXGISwapChain3 *swap)
|
||||
{
|
||||
if(swap)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
swap->GetDesc(&desc);
|
||||
|
||||
Keyboard::RemoveInputWindow(desc.OutputWindow);
|
||||
|
||||
RenderDoc::Inst().RemoveFrameCapturer((ID3D12Device *)this, desc.OutputWindow);
|
||||
}
|
||||
|
||||
auto it = m_SwapChains.find(swap);
|
||||
if(it != m_SwapChains.end())
|
||||
m_SwapChains.erase(it);
|
||||
}
|
||||
|
||||
IUnknown *WrappedID3D12Device::WrapSwapchainBuffer(WrappedIDXGISwapChain3 *swap,
|
||||
DXGI_SWAP_CHAIN_DESC *swapDesc, UINT buffer,
|
||||
IUnknown *realSurface)
|
||||
{
|
||||
if(GetResourceManager()->HasWrapper((ID3D12DeviceChild *)realSurface))
|
||||
{
|
||||
ID3D12Resource *tex =
|
||||
(ID3D12Resource *)GetResourceManager()->GetWrapper((ID3D12DeviceChild *)realSurface);
|
||||
tex->AddRef();
|
||||
|
||||
realSurface->Release();
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
RDCUNIMPLEMENTED("WrapSwapchainBuffer");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::Present(WrappedIDXGISwapChain3 *swap, UINT SyncInterval, UINT Flags)
|
||||
{
|
||||
if((Flags & DXGI_PRESENT_TEST) != 0)
|
||||
return S_OK;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::StartFrameCapture(void *dev, void *wnd)
|
||||
{
|
||||
if(m_State != WRITING_IDLE)
|
||||
return;
|
||||
}
|
||||
|
||||
bool WrappedID3D12Device::EndFrameCapture(void *dev, void *wnd)
|
||||
{
|
||||
if(m_State != WRITING_CAPFRAME)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,444 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <map>
|
||||
#include "api/replay/renderdoc_replay.h"
|
||||
#include "common/threading.h"
|
||||
#include "common/timing.h"
|
||||
#include "common/wrapped_pool.h"
|
||||
#include "core/core.h"
|
||||
#include "driver/dxgi/dxgi_wrapped.h"
|
||||
#include "d3d12_common.h"
|
||||
#include "d3d12_manager.h"
|
||||
|
||||
struct D3D12InitParams : public RDCInitParams
|
||||
{
|
||||
D3D12InitParams();
|
||||
ReplayCreateStatus Serialise();
|
||||
|
||||
D3D_FEATURE_LEVEL MinimumFeatureLevel;
|
||||
|
||||
static const uint32_t D3D12_SERIALISE_VERSION = 0x0000001;
|
||||
|
||||
// version number internal to d3d12 stream
|
||||
uint32_t SerialiseVersion;
|
||||
};
|
||||
|
||||
class WrappedID3D12Device;
|
||||
|
||||
// give every impression of working but do nothing.
|
||||
// Just allow the user to call functions so that they don't
|
||||
// have to check for E_NOINTERFACE when they expect an infoqueue to be there
|
||||
struct DummyID3D12InfoQueue : public ID3D12InfoQueue
|
||||
{
|
||||
WrappedID3D12Device *m_pDevice;
|
||||
|
||||
DummyID3D12InfoQueue() : m_pDevice(NULL) {}
|
||||
//////////////////////////////
|
||||
// implement IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) { return E_NOINTERFACE; }
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
|
||||
//////////////////////////////
|
||||
// implement ID3D12InfoQueue
|
||||
virtual HRESULT STDMETHODCALLTYPE SetMessageCountLimit(UINT64 MessageCountLimit) { return S_OK; }
|
||||
virtual void STDMETHODCALLTYPE ClearStoredMessages() {}
|
||||
virtual HRESULT STDMETHODCALLTYPE GetMessage(UINT64 MessageIndex, D3D12_MESSAGE *pMessage,
|
||||
SIZE_T *pMessageByteLength)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual UINT64 STDMETHODCALLTYPE GetNumMessagesAllowedByStorageFilter() { return 0; }
|
||||
virtual UINT64 STDMETHODCALLTYPE GetNumMessagesDeniedByStorageFilter() { return 0; }
|
||||
virtual UINT64 STDMETHODCALLTYPE GetNumStoredMessages() { return 0; }
|
||||
virtual UINT64 STDMETHODCALLTYPE GetNumStoredMessagesAllowedByRetrievalFilter() { return 0; }
|
||||
virtual UINT64 STDMETHODCALLTYPE GetNumMessagesDiscardedByMessageCountLimit() { return 0; }
|
||||
virtual UINT64 STDMETHODCALLTYPE GetMessageCountLimit() { return 0; }
|
||||
virtual HRESULT STDMETHODCALLTYPE AddStorageFilterEntries(D3D12_INFO_QUEUE_FILTER *pFilter)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual HRESULT STDMETHODCALLTYPE GetStorageFilter(D3D12_INFO_QUEUE_FILTER *pFilter,
|
||||
SIZE_T *pFilterByteLength)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual void STDMETHODCALLTYPE ClearStorageFilter() {}
|
||||
virtual HRESULT STDMETHODCALLTYPE PushEmptyStorageFilter() { return S_OK; }
|
||||
virtual HRESULT STDMETHODCALLTYPE PushCopyOfStorageFilter() { return S_OK; }
|
||||
virtual HRESULT STDMETHODCALLTYPE PushStorageFilter(D3D12_INFO_QUEUE_FILTER *pFilter)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual void STDMETHODCALLTYPE PopStorageFilter() {}
|
||||
virtual UINT STDMETHODCALLTYPE GetStorageFilterStackSize() { return 0; }
|
||||
virtual HRESULT STDMETHODCALLTYPE AddRetrievalFilterEntries(D3D12_INFO_QUEUE_FILTER *pFilter)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual HRESULT STDMETHODCALLTYPE GetRetrievalFilter(D3D12_INFO_QUEUE_FILTER *pFilter,
|
||||
SIZE_T *pFilterByteLength)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual void STDMETHODCALLTYPE ClearRetrievalFilter() {}
|
||||
virtual HRESULT STDMETHODCALLTYPE PushEmptyRetrievalFilter() { return S_OK; }
|
||||
virtual HRESULT STDMETHODCALLTYPE PushCopyOfRetrievalFilter() { return S_OK; }
|
||||
virtual HRESULT STDMETHODCALLTYPE PushRetrievalFilter(D3D12_INFO_QUEUE_FILTER *pFilter)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual void STDMETHODCALLTYPE PopRetrievalFilter() {}
|
||||
virtual UINT STDMETHODCALLTYPE GetRetrievalFilterStackSize() { return 0; }
|
||||
virtual HRESULT STDMETHODCALLTYPE AddMessage(D3D12_MESSAGE_CATEGORY Category,
|
||||
D3D12_MESSAGE_SEVERITY Severity, D3D12_MESSAGE_ID ID,
|
||||
LPCSTR pDescription)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual HRESULT STDMETHODCALLTYPE AddApplicationMessage(D3D12_MESSAGE_SEVERITY Severity,
|
||||
LPCSTR pDescription)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual HRESULT STDMETHODCALLTYPE SetBreakOnCategory(D3D12_MESSAGE_CATEGORY Category, BOOL bEnable)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual HRESULT STDMETHODCALLTYPE SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY Severity, BOOL bEnable)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
virtual HRESULT STDMETHODCALLTYPE SetBreakOnID(D3D12_MESSAGE_ID ID, BOOL bEnable) { return S_OK; }
|
||||
virtual BOOL STDMETHODCALLTYPE GetBreakOnCategory(D3D12_MESSAGE_CATEGORY Category)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
virtual BOOL STDMETHODCALLTYPE GetBreakOnSeverity(D3D12_MESSAGE_SEVERITY Severity)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
virtual BOOL STDMETHODCALLTYPE GetBreakOnID(D3D12_MESSAGE_ID ID) { return FALSE; }
|
||||
virtual void STDMETHODCALLTYPE SetMuteDebugOutput(BOOL bMute) {}
|
||||
virtual BOOL STDMETHODCALLTYPE GetMuteDebugOutput() { return TRUE; }
|
||||
};
|
||||
|
||||
class WrappedID3D12Device;
|
||||
|
||||
// We can pass through all calls to ID3D12DebugDevice without intercepting, this
|
||||
// struct isonly here so that we can intercept QueryInterface calls to return
|
||||
// ID3D11InfoQueue
|
||||
struct WrappedID3D12DebugDevice : public ID3D12DebugDevice
|
||||
{
|
||||
WrappedID3D12Device *m_pDevice;
|
||||
ID3D12DebugDevice *m_pDebug;
|
||||
|
||||
WrappedID3D12DebugDevice() {}
|
||||
//////////////////////////////
|
||||
// implement IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
|
||||
//////////////////////////////
|
||||
// implement ID3D12DebugDevice
|
||||
virtual HRESULT STDMETHODCALLTYPE SetFeatureMask(D3D12_DEBUG_FEATURE Mask)
|
||||
{
|
||||
return m_pDebug->SetFeatureMask(Mask);
|
||||
}
|
||||
|
||||
virtual D3D12_DEBUG_FEATURE STDMETHODCALLTYPE GetFeatureMask()
|
||||
{
|
||||
return m_pDebug->GetFeatureMask();
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE ReportLiveDeviceObjects(D3D12_RLDO_FLAGS Flags)
|
||||
{
|
||||
return m_pDebug->ReportLiveDeviceObjects(Flags);
|
||||
}
|
||||
};
|
||||
|
||||
// give every impression of working but do nothing.
|
||||
// Same idea as DummyID3D12InfoQueue above, a dummy interface so that users
|
||||
// expecting a ID3D12DebugDevice don't get confused if we have turned off the debug
|
||||
// layer and can't return the real one.
|
||||
struct DummyID3D12DebugDevice : public ID3D12DebugDevice
|
||||
{
|
||||
WrappedID3D12Device *m_pDevice;
|
||||
|
||||
DummyID3D12DebugDevice() {}
|
||||
//////////////////////////////
|
||||
// implement IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
ULONG STDMETHODCALLTYPE Release();
|
||||
|
||||
//////////////////////////////
|
||||
// implement ID3D12DebugDevice
|
||||
virtual HRESULT STDMETHODCALLTYPE SetFeatureMask(D3D12_DEBUG_FEATURE Mask) { return S_OK; }
|
||||
virtual D3D12_DEBUG_FEATURE STDMETHODCALLTYPE GetFeatureMask()
|
||||
{
|
||||
return D3D12_DEBUG_FEATURE_NONE;
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE ReportLiveDeviceObjects(D3D12_RLDO_FLAGS Flags) { return S_OK; }
|
||||
};
|
||||
|
||||
class WrappedID3D12Device : public IFrameCapturer, public ID3DDevice, public ID3D12Device
|
||||
{
|
||||
private:
|
||||
ID3D12Device *m_pDevice;
|
||||
|
||||
D3D12ResourceManager *m_ResourceManager;
|
||||
DummyID3D12InfoQueue m_DummyInfoQueue;
|
||||
DummyID3D12DebugDevice m_DummyDebug;
|
||||
WrappedID3D12DebugDevice m_WrappedDebug;
|
||||
|
||||
unsigned int m_InternalRefcount;
|
||||
RefCounter12 m_RefCounter;
|
||||
RefCounter12 m_SoftRefCounter;
|
||||
bool m_Alive;
|
||||
|
||||
Serialiser *m_pSerialiser;
|
||||
LogState m_State;
|
||||
bool m_AppControlledCapture;
|
||||
|
||||
D3D12InitParams m_InitParams;
|
||||
ID3D12InfoQueue *m_pInfoQueue;
|
||||
|
||||
// ensure all calls in via the D3D wrapped interface are thread safe
|
||||
// protects wrapped resource creation and serialiser access
|
||||
Threading::CriticalSection m_D3DLock;
|
||||
|
||||
ResourceId m_ResourceID;
|
||||
D3D12ResourceRecord *m_DeviceRecord;
|
||||
|
||||
map<WrappedIDXGISwapChain3 *, D3D12_CPU_DESCRIPTOR_HANDLE> m_SwapChains;
|
||||
|
||||
public:
|
||||
static const int AllocPoolCount = 4;
|
||||
ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D12Device, AllocPoolCount);
|
||||
|
||||
WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitParams *params);
|
||||
virtual ~WrappedID3D12Device();
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// non wrapping interface
|
||||
|
||||
ID3D12Device *GetReal() { return m_pDevice; }
|
||||
static const char *GetChunkName(uint32_t idx);
|
||||
D3D12ResourceManager *GetResourceManager() { return m_ResourceManager; }
|
||||
Serialiser *GetSerialiser() { return m_pSerialiser; }
|
||||
ResourceId GetResourceID() { return m_ResourceID; }
|
||||
void ReleaseSwapchainResources(IDXGISwapChain *swap, IUnknown **backbuffers, int numBackbuffers);
|
||||
void FirstFrame(WrappedIDXGISwapChain3 *swap);
|
||||
|
||||
void StartFrameCapture(void *dev, void *wnd);
|
||||
bool EndFrameCapture(void *dev, void *wnd);
|
||||
|
||||
// interface for DXGI
|
||||
virtual IUnknown *GetRealIUnknown() { return GetReal(); }
|
||||
virtual IID GetBackbufferUUID() { return __uuidof(ID3D12Resource); }
|
||||
virtual IID GetDeviceUUID() { return __uuidof(ID3D12Device); }
|
||||
virtual IUnknown *GetDeviceInterface() { return (ID3D12Device *)this; }
|
||||
// Swap Chain
|
||||
IMPLEMENT_FUNCTION_SERIALISED(IUnknown *, WrapSwapchainBuffer(WrappedIDXGISwapChain3 *swap,
|
||||
DXGI_SWAP_CHAIN_DESC *desc,
|
||||
UINT buffer, IUnknown *realSurface));
|
||||
HRESULT Present(WrappedIDXGISwapChain3 *swap, UINT SyncInterval, UINT Flags);
|
||||
|
||||
void ShutdownSwapchain(WrappedIDXGISwapChain3 *swapChain) {}
|
||||
void NewSwapchainBuffer(IUnknown *backbuffer) {}
|
||||
void ReleaseSwapchainResources(WrappedIDXGISwapChain3 *swap);
|
||||
|
||||
void InternalRef() { InterlockedIncrement(&m_InternalRefcount); }
|
||||
void InternalRelease() { InterlockedDecrement(&m_InternalRefcount); }
|
||||
void SoftRef() { m_SoftRefCounter.AddRef(); }
|
||||
void SoftRelease()
|
||||
{
|
||||
m_SoftRefCounter.Release();
|
||||
CheckForDeath();
|
||||
}
|
||||
void CheckForDeath();
|
||||
|
||||
//////////////////////////////
|
||||
// implement IUnknown
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return m_RefCounter.AddRef(); }
|
||||
ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
unsigned int ret = m_RefCounter.Release();
|
||||
CheckForDeath();
|
||||
return ret;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
|
||||
//////////////////////////////
|
||||
// implement ID3D12Object
|
||||
virtual HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID guid, UINT *pDataSize, void *pData);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID guid, UINT DataSize, const void *pData);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID guid, const IUnknown *pData);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetName(LPCWSTR Name);
|
||||
|
||||
//////////////////////////////
|
||||
// implement ID3D12Device
|
||||
virtual UINT STDMETHODCALLTYPE GetNodeCount();
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateCommandQueue(const D3D12_COMMAND_QUEUE_DESC *pDesc,
|
||||
REFIID riid, void **ppCommandQueue);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type,
|
||||
REFIID riid, void **ppCommandAllocator);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateGraphicsPipelineState(
|
||||
const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, REFIID riid, void **ppPipelineState);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateComputePipelineState(
|
||||
const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, REFIID riid, void **ppPipelineState);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateCommandList(UINT nodeMask, D3D12_COMMAND_LIST_TYPE type,
|
||||
ID3D12CommandAllocator *pCommandAllocator,
|
||||
ID3D12PipelineState *pInitialState,
|
||||
REFIID riid, void **ppCommandList);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CheckFeatureSupport(D3D12_FEATURE Feature,
|
||||
void *pFeatureSupportData,
|
||||
UINT FeatureSupportDataSize);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateDescriptorHeap(
|
||||
const D3D12_DESCRIPTOR_HEAP_DESC *pDescriptorHeapDesc, REFIID riid, void **ppvHeap);
|
||||
|
||||
virtual UINT STDMETHODCALLTYPE
|
||||
GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateRootSignature(UINT nodeMask,
|
||||
const void *pBlobWithRootSignature,
|
||||
SIZE_T blobLengthInBytes, REFIID riid,
|
||||
void **ppvRootSignature);
|
||||
|
||||
virtual void STDMETHODCALLTYPE CreateConstantBufferView(const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor);
|
||||
|
||||
virtual void STDMETHODCALLTYPE CreateShaderResourceView(ID3D12Resource *pResource,
|
||||
const D3D12_SHADER_RESOURCE_VIEW_DESC *pDesc,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor);
|
||||
|
||||
virtual void STDMETHODCALLTYPE CreateUnorderedAccessView(
|
||||
ID3D12Resource *pResource, ID3D12Resource *pCounterResource,
|
||||
const D3D12_UNORDERED_ACCESS_VIEW_DESC *pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor);
|
||||
|
||||
virtual void STDMETHODCALLTYPE CreateRenderTargetView(ID3D12Resource *pResource,
|
||||
const D3D12_RENDER_TARGET_VIEW_DESC *pDesc,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor);
|
||||
|
||||
virtual void STDMETHODCALLTYPE CreateDepthStencilView(ID3D12Resource *pResource,
|
||||
const D3D12_DEPTH_STENCIL_VIEW_DESC *pDesc,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor);
|
||||
|
||||
virtual void STDMETHODCALLTYPE CreateSampler(const D3D12_SAMPLER_DESC *pDesc,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor);
|
||||
|
||||
virtual void STDMETHODCALLTYPE CopyDescriptors(
|
||||
UINT NumDestDescriptorRanges, const D3D12_CPU_DESCRIPTOR_HANDLE *pDestDescriptorRangeStarts,
|
||||
const UINT *pDestDescriptorRangeSizes, UINT NumSrcDescriptorRanges,
|
||||
const D3D12_CPU_DESCRIPTOR_HANDLE *pSrcDescriptorRangeStarts,
|
||||
const UINT *pSrcDescriptorRangeSizes, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType);
|
||||
|
||||
virtual void STDMETHODCALLTYPE
|
||||
CopyDescriptorsSimple(UINT NumDescriptors, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType);
|
||||
|
||||
virtual D3D12_RESOURCE_ALLOCATION_INFO STDMETHODCALLTYPE GetResourceAllocationInfo(
|
||||
UINT visibleMask, UINT numResourceDescs, const D3D12_RESOURCE_DESC *pResourceDescs);
|
||||
|
||||
virtual D3D12_HEAP_PROPERTIES STDMETHODCALLTYPE GetCustomHeapProperties(UINT nodeMask,
|
||||
D3D12_HEAP_TYPE heapType);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateCommittedResource(
|
||||
const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags,
|
||||
const D3D12_RESOURCE_DESC *pResourceDesc, D3D12_RESOURCE_STATES InitialResourceState,
|
||||
const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riidResource, void **ppvResource);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateHeap(const D3D12_HEAP_DESC *pDesc, REFIID riid,
|
||||
void **ppvHeap);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreatePlacedResource(ID3D12Heap *pHeap, UINT64 HeapOffset,
|
||||
const D3D12_RESOURCE_DESC *pDesc,
|
||||
D3D12_RESOURCE_STATES InitialState,
|
||||
const D3D12_CLEAR_VALUE *pOptimizedClearValue,
|
||||
REFIID riid, void **ppvResource);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateReservedResource(
|
||||
const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialState,
|
||||
const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riid, void **ppvResource);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateSharedHandle(ID3D12DeviceChild *pObject,
|
||||
const SECURITY_ATTRIBUTES *pAttributes,
|
||||
DWORD Access, LPCWSTR Name, HANDLE *pHandle);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE OpenSharedHandle(HANDLE NTHandle, REFIID riid, void **ppvObj);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE OpenSharedHandleByName(LPCWSTR Name, DWORD Access,
|
||||
HANDLE *pNTHandle);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE MakeResident(UINT NumObjects, ID3D12Pageable *const *ppObjects);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE Evict(UINT NumObjects, ID3D12Pageable *const *ppObjects);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateFence(UINT64 InitialValue, D3D12_FENCE_FLAGS Flags,
|
||||
REFIID riid, void **ppFence);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetDeviceRemovedReason();
|
||||
|
||||
virtual void STDMETHODCALLTYPE GetCopyableFootprints(const D3D12_RESOURCE_DESC *pResourceDesc,
|
||||
UINT FirstSubresource, UINT NumSubresources,
|
||||
UINT64 BaseOffset,
|
||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT *pLayouts,
|
||||
UINT *pNumRows, UINT64 *pRowSizeInBytes,
|
||||
UINT64 *pTotalBytes);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateQueryHeap(const D3D12_QUERY_HEAP_DESC *pDesc, REFIID riid,
|
||||
void **ppvHeap);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetStablePowerState(BOOL Enable);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE CreateCommandSignature(const D3D12_COMMAND_SIGNATURE_DESC *pDesc,
|
||||
ID3D12RootSignature *pRootSignature,
|
||||
REFIID riid, void **ppvCommandSignature);
|
||||
|
||||
virtual void STDMETHODCALLTYPE GetResourceTiling(
|
||||
ID3D12Resource *pTiledResource, UINT *pNumTilesForEntireResource,
|
||||
D3D12_PACKED_MIP_INFO *pPackedMipDesc, D3D12_TILE_SHAPE *pStandardTileShapeForNonPackedMips,
|
||||
UINT *pNumSubresourceTilings, UINT FirstSubresourceTilingToGet,
|
||||
D3D12_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips);
|
||||
|
||||
virtual LUID STDMETHODCALLTYPE GetAdapterLuid();
|
||||
};
|
||||
@@ -0,0 +1,285 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
#include "driver/d3d12/d3d12_device.h"
|
||||
|
||||
HRESULT WrappedID3D12Device::CreateCommandQueue(const D3D12_COMMAND_QUEUE_DESC *pDesc, REFIID riid,
|
||||
void **ppCommandQueue)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type, REFIID riid,
|
||||
void **ppCommandAllocator)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CreateGraphicsPipelineState(const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc,
|
||||
REFIID riid, void **ppPipelineState)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CreateComputePipelineState(const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc,
|
||||
REFIID riid, void **ppPipelineState)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CreateCommandList(UINT nodeMask, D3D12_COMMAND_LIST_TYPE type,
|
||||
ID3D12CommandAllocator *pCommandAllocator,
|
||||
ID3D12PipelineState *pInitialState, REFIID riid,
|
||||
void **ppCommandList)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CreateDescriptorHeap(const D3D12_DESCRIPTOR_HEAP_DESC *pDescriptorHeapDesc,
|
||||
REFIID riid, void **ppvHeap)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CreateRootSignature(UINT nodeMask, const void *pBlobWithRootSignature,
|
||||
SIZE_T blobLengthInBytes, REFIID riid,
|
||||
void **ppvRootSignature)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::CreateConstantBufferView(const D3D12_CONSTANT_BUFFER_VIEW_DESC *pDesc,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
|
||||
{
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::CreateShaderResourceView(ID3D12Resource *pResource,
|
||||
const D3D12_SHADER_RESOURCE_VIEW_DESC *pDesc,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
|
||||
{
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::CreateUnorderedAccessView(ID3D12Resource *pResource,
|
||||
ID3D12Resource *pCounterResource,
|
||||
const D3D12_UNORDERED_ACCESS_VIEW_DESC *pDesc,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
|
||||
{
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::CreateRenderTargetView(ID3D12Resource *pResource,
|
||||
const D3D12_RENDER_TARGET_VIEW_DESC *pDesc,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
|
||||
{
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::CreateDepthStencilView(ID3D12Resource *pResource,
|
||||
const D3D12_DEPTH_STENCIL_VIEW_DESC *pDesc,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
|
||||
{
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::CreateSampler(const D3D12_SAMPLER_DESC *pDesc,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CreateCommittedResource(const D3D12_HEAP_PROPERTIES *pHeapProperties,
|
||||
D3D12_HEAP_FLAGS HeapFlags,
|
||||
const D3D12_RESOURCE_DESC *pResourceDesc,
|
||||
D3D12_RESOURCE_STATES InitialResourceState,
|
||||
const D3D12_CLEAR_VALUE *pOptimizedClearValue,
|
||||
REFIID riidResource, void **ppvResource)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CreateHeap(const D3D12_HEAP_DESC *pDesc, REFIID riid, void **ppvHeap)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CreatePlacedResource(ID3D12Heap *pHeap, UINT64 HeapOffset,
|
||||
const D3D12_RESOURCE_DESC *pDesc,
|
||||
D3D12_RESOURCE_STATES InitialState,
|
||||
const D3D12_CLEAR_VALUE *pOptimizedClearValue,
|
||||
REFIID riid, void **ppvResource)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CreateReservedResource(const D3D12_RESOURCE_DESC *pDesc,
|
||||
D3D12_RESOURCE_STATES InitialState,
|
||||
const D3D12_CLEAR_VALUE *pOptimizedClearValue,
|
||||
REFIID riid, void **ppvResource)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CreateFence(UINT64 InitialValue, D3D12_FENCE_FLAGS Flags, REFIID riid,
|
||||
void **ppFence)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CreateQueryHeap(const D3D12_QUERY_HEAP_DESC *pDesc, REFIID riid,
|
||||
void **ppvHeap)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CreateCommandSignature(const D3D12_COMMAND_SIGNATURE_DESC *pDesc,
|
||||
ID3D12RootSignature *pRootSignature,
|
||||
REFIID riid, void **ppvCommandSignature)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CreateSharedHandle(ID3D12DeviceChild *pObject,
|
||||
const SECURITY_ATTRIBUTES *pAttributes,
|
||||
DWORD Access, LPCWSTR Name, HANDLE *pHandle)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::CopyDescriptors(
|
||||
UINT NumDestDescriptorRanges, const D3D12_CPU_DESCRIPTOR_HANDLE *pDestDescriptorRangeStarts,
|
||||
const UINT *pDestDescriptorRangeSizes, UINT NumSrcDescriptorRanges,
|
||||
const D3D12_CPU_DESCRIPTOR_HANDLE *pSrcDescriptorRangeStarts,
|
||||
const UINT *pSrcDescriptorRangeSizes, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType)
|
||||
{
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::CopyDescriptorsSimple(UINT NumDescriptors,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart,
|
||||
D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType)
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::OpenSharedHandle(HANDLE NTHandle, REFIID riid, void **ppvObj)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::OpenSharedHandleByName(LPCWSTR Name, DWORD Access, HANDLE *pNTHandle)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::MakeResident(UINT NumObjects, ID3D12Pageable *const *ppObjects)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::Evict(UINT NumObjects, ID3D12Pageable *const *ppObjects)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
// we don't need to wrap any of these
|
||||
HRESULT WrappedID3D12Device::GetPrivateData(REFGUID guid, UINT *pDataSize, void *pData)
|
||||
{
|
||||
return m_pDevice->GetPrivateData(guid, pDataSize, pData);
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::SetPrivateData(REFGUID guid, UINT DataSize, const void *pData)
|
||||
{
|
||||
return m_pDevice->SetPrivateData(guid, DataSize, pData);
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::SetPrivateDataInterface(REFGUID guid, const IUnknown *pData)
|
||||
{
|
||||
return m_pDevice->SetPrivateDataInterface(guid, pData);
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::SetName(LPCWSTR Name)
|
||||
{
|
||||
return m_pDevice->SetName(Name);
|
||||
}
|
||||
|
||||
UINT WrappedID3D12Device::GetNodeCount()
|
||||
{
|
||||
return m_pDevice->GetNodeCount();
|
||||
}
|
||||
|
||||
LUID WrappedID3D12Device::GetAdapterLuid()
|
||||
{
|
||||
return m_pDevice->GetAdapterLuid();
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::GetResourceTiling(
|
||||
ID3D12Resource *pTiledResource, UINT *pNumTilesForEntireResource,
|
||||
D3D12_PACKED_MIP_INFO *pPackedMipDesc, D3D12_TILE_SHAPE *pStandardTileShapeForNonPackedMips,
|
||||
UINT *pNumSubresourceTilings, UINT FirstSubresourceTilingToGet,
|
||||
D3D12_SUBRESOURCE_TILING *pSubresourceTilingsForNonPackedMips)
|
||||
{
|
||||
return m_pDevice->GetResourceTiling(
|
||||
pTiledResource, pNumTilesForEntireResource, pPackedMipDesc, pStandardTileShapeForNonPackedMips,
|
||||
pNumSubresourceTilings, FirstSubresourceTilingToGet, pSubresourceTilingsForNonPackedMips);
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::SetStablePowerState(BOOL Enable)
|
||||
{
|
||||
return m_pDevice->SetStablePowerState(Enable);
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::CheckFeatureSupport(D3D12_FEATURE Feature, void *pFeatureSupportData,
|
||||
UINT FeatureSupportDataSize)
|
||||
{
|
||||
return m_pDevice->CheckFeatureSupport(Feature, pFeatureSupportData, FeatureSupportDataSize);
|
||||
}
|
||||
|
||||
UINT WrappedID3D12Device::GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType)
|
||||
{
|
||||
return m_pDevice->GetDescriptorHandleIncrementSize(DescriptorHeapType);
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_ALLOCATION_INFO WrappedID3D12Device::GetResourceAllocationInfo(
|
||||
UINT visibleMask, UINT numResourceDescs, const D3D12_RESOURCE_DESC *pResourceDescs)
|
||||
{
|
||||
return m_pDevice->GetResourceAllocationInfo(visibleMask, numResourceDescs, pResourceDescs);
|
||||
}
|
||||
|
||||
D3D12_HEAP_PROPERTIES WrappedID3D12Device::GetCustomHeapProperties(UINT nodeMask,
|
||||
D3D12_HEAP_TYPE heapType)
|
||||
{
|
||||
return m_pDevice->GetCustomHeapProperties(nodeMask, heapType);
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::GetDeviceRemovedReason()
|
||||
{
|
||||
return m_pDevice->GetDeviceRemovedReason();
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::GetCopyableFootprints(const D3D12_RESOURCE_DESC *pResourceDesc,
|
||||
UINT FirstSubresource, UINT NumSubresources,
|
||||
UINT64 BaseOffset,
|
||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT *pLayouts,
|
||||
UINT *pNumRows, UINT64 *pRowSizeInBytes,
|
||||
UINT64 *pTotalBytes)
|
||||
{
|
||||
return m_pDevice->GetCopyableFootprints(pResourceDesc, FirstSubresource, NumSubresources,
|
||||
BaseOffset, pLayouts, pNumRows, pRowSizeInBytes,
|
||||
pTotalBytes);
|
||||
}
|
||||
@@ -0,0 +1,287 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
#include "driver/d3d12/d3d12_device.h"
|
||||
#include "driver/dxgi/dxgi_wrapped.h"
|
||||
#include "hooks/hooks.h"
|
||||
#include "serialise/serialiser.h"
|
||||
|
||||
#define DLL_NAME "d3d12.dll"
|
||||
|
||||
ID3DDevice *GetD3D12DeviceIfAlloc(IUnknown *dev)
|
||||
{
|
||||
if(WrappedID3D12Device::IsAlloc(dev))
|
||||
return (ID3DDevice *)dev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// dummy class to present to the user, while we maintain control
|
||||
class WrappedID3D12Debug : public RefCounter12, public ID3D12Debug
|
||||
{
|
||||
public:
|
||||
WrappedID3D12Debug() : RefCounter12(NULL) {}
|
||||
virtual ~WrappedID3D12Debug() {}
|
||||
//////////////////////////////
|
||||
// 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 *)(ID3D12Debug *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
if(riid == __uuidof(ID3D12Debug))
|
||||
{
|
||||
*ppvObject = (ID3D12Debug *)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return RefCounter12::QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Implement ID3D12Debug
|
||||
virtual void STDMETHODCALLTYPE EnableDebugLayer() {}
|
||||
};
|
||||
|
||||
class D3D12Hook : LibraryHook
|
||||
{
|
||||
public:
|
||||
D3D12Hook()
|
||||
{
|
||||
LibraryHooks::GetInstance().RegisterHook(DLL_NAME, this);
|
||||
m_EnabledHooks = true;
|
||||
m_InsideCreate = false;
|
||||
|
||||
WrappedIDXGISwapChain3::RegisterD3DDeviceCallback(GetD3D12DeviceIfAlloc);
|
||||
}
|
||||
|
||||
bool CreateHooks(const char *libName)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
// also require d3dcompiler_??.dll
|
||||
if(GetD3DCompiler() == NULL)
|
||||
{
|
||||
RDCERR("Failed to load d3dcompiler_??.dll - not inserting D3D12 hooks.");
|
||||
return false;
|
||||
}
|
||||
|
||||
success &= CreateDevice.Initialize("D3D12CreateDevice", DLL_NAME, D3D12CreateDevice_hook);
|
||||
success &= GetDebugInterface.Initialize("D3D12GetDebugInterface", DLL_NAME,
|
||||
D3D12GetDebugInterface_hook);
|
||||
|
||||
if(!success)
|
||||
return false;
|
||||
|
||||
m_HasHooks = true;
|
||||
m_EnabledHooks = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EnableHooks(const char *libName, bool enable) { m_EnabledHooks = enable; }
|
||||
void OptionsUpdated(const char *libName) {}
|
||||
bool UseHooks() { return (d3d12hooks.m_HasHooks && d3d12hooks.m_EnabledHooks); }
|
||||
static HRESULT CreateWrappedDevice(IUnknown *pAdapter, D3D_FEATURE_LEVEL MinimumFeatureLevel,
|
||||
REFIID riid, void **ppDevice)
|
||||
{
|
||||
return d3d12hooks.Create_Internal(pAdapter, MinimumFeatureLevel, riid, ppDevice);
|
||||
}
|
||||
|
||||
private:
|
||||
static D3D12Hook d3d12hooks;
|
||||
|
||||
bool m_HasHooks;
|
||||
bool m_EnabledHooks;
|
||||
|
||||
Hook<PFN_D3D12_GET_DEBUG_INTERFACE> GetDebugInterface;
|
||||
Hook<PFN_D3D12_CREATE_DEVICE> CreateDevice;
|
||||
|
||||
// re-entrancy detection (can happen in rare cases with e.g. fraps)
|
||||
bool m_InsideCreate;
|
||||
|
||||
HRESULT Create_Internal(IUnknown *pAdapter, D3D_FEATURE_LEVEL MinimumFeatureLevel, REFIID riid,
|
||||
void **ppDevice)
|
||||
{
|
||||
// if we're already inside a wrapped create i.e. this function, then DON'T do anything
|
||||
// special. Just grab the trampolined function and call it.
|
||||
if(m_InsideCreate)
|
||||
{
|
||||
PFN_D3D12_CREATE_DEVICE createFunc = NULL;
|
||||
|
||||
// shouldn't ever get in here if we're in the case without hooks but let's be safe.
|
||||
if(m_HasHooks)
|
||||
{
|
||||
createFunc = CreateDevice();
|
||||
}
|
||||
else
|
||||
{
|
||||
HMODULE d3d12 = GetModuleHandleA("d3d12.dll");
|
||||
|
||||
if(d3d12)
|
||||
{
|
||||
createFunc = (PFN_D3D12_CREATE_DEVICE)GetProcAddress(d3d12, "D3D12CreateDevice");
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Something went seriously wrong, d3d12.dll couldn't be loaded!");
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
return createFunc(pAdapter, MinimumFeatureLevel, riid, ppDevice);
|
||||
}
|
||||
|
||||
m_InsideCreate = true;
|
||||
|
||||
if(riid != __uuidof(ID3D12Device))
|
||||
{
|
||||
RDCERR("Unsupported UUID %s for D3D12CreateDevice", ToStr::Get(riid).c_str());
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
RDCDEBUG("Call to Create_Internal Feature Level %x", MinimumFeatureLevel,
|
||||
ToStr::Get(riid).c_str());
|
||||
|
||||
bool reading = RenderDoc::Inst().IsReplayApp();
|
||||
|
||||
if(reading)
|
||||
{
|
||||
RDCDEBUG("In replay app");
|
||||
}
|
||||
|
||||
const bool EnableDebugLayer =
|
||||
(m_EnabledHooks && !reading && RenderDoc::Inst().GetCaptureOptions().APIValidation);
|
||||
|
||||
if(EnableDebugLayer)
|
||||
{
|
||||
ID3D12Debug *debug = NULL;
|
||||
HRESULT hr = GetDebugInterface()(__uuidof(ID3D12Debug), (void **)&debug);
|
||||
|
||||
if(SUCCEEDED(hr) && debug)
|
||||
debug->EnableDebugLayer();
|
||||
else
|
||||
RDCERR("Couldn't enable debug layer: %x", hr);
|
||||
|
||||
SAFE_RELEASE(debug);
|
||||
}
|
||||
|
||||
RDCDEBUG("Calling real createdevice...");
|
||||
|
||||
PFN_D3D12_CREATE_DEVICE createFunc =
|
||||
(PFN_D3D12_CREATE_DEVICE)GetProcAddress(GetModuleHandleA("d3d12.dll"), "D3D12CreateDevice");
|
||||
|
||||
if(createFunc == NULL)
|
||||
createFunc = CreateDevice();
|
||||
|
||||
// shouldn't ever get here, we should either have it from procaddress or the trampoline, but
|
||||
// let's be safe.
|
||||
if(createFunc == NULL)
|
||||
{
|
||||
RDCERR("Something went seriously wrong with the hooks!");
|
||||
|
||||
m_InsideCreate = false;
|
||||
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
HRESULT ret = createFunc(pAdapter, MinimumFeatureLevel, riid, ppDevice);
|
||||
|
||||
RDCDEBUG("Called real createdevice... 0x%08x", ret);
|
||||
|
||||
if(SUCCEEDED(ret) && m_EnabledHooks && ppDevice)
|
||||
{
|
||||
RDCDEBUG("succeeded and hooking.");
|
||||
|
||||
if(!WrappedID3D12Device::IsAlloc(*ppDevice))
|
||||
{
|
||||
D3D12InitParams params;
|
||||
params.MinimumFeatureLevel = MinimumFeatureLevel;
|
||||
|
||||
ID3D12Device *dev = (ID3D12Device *)*ppDevice;
|
||||
|
||||
WrappedID3D12Device *wrap = new WrappedID3D12Device(dev, ¶ms);
|
||||
|
||||
RDCDEBUG("created wrapped device.");
|
||||
|
||||
*ppDevice = wrap;
|
||||
}
|
||||
}
|
||||
else if(SUCCEEDED(ret))
|
||||
{
|
||||
RDCLOG("Created wrapped D3D12 device.");
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCDEBUG("failed. 0x%08x", ret);
|
||||
}
|
||||
|
||||
m_InsideCreate = false;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI D3D12CreateDevice_hook(IUnknown *pAdapter,
|
||||
D3D_FEATURE_LEVEL MinimumFeatureLevel, REFIID riid,
|
||||
void **ppDevice)
|
||||
{
|
||||
return d3d12hooks.Create_Internal(pAdapter, MinimumFeatureLevel, riid, ppDevice);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI D3D12GetDebugInterface_hook(REFIID riid, void **ppvDebug)
|
||||
{
|
||||
if(riid != __uuidof(ID3D12Debug))
|
||||
{
|
||||
IUnknown *releaseme = NULL;
|
||||
HRESULT real = d3d12hooks.GetDebugInterface()(riid, (void **)&releaseme);
|
||||
|
||||
if(releaseme)
|
||||
releaseme->Release();
|
||||
|
||||
RDCWARN("Unknown UUID passed to D3D12GetDebugInterface: %s. Real call %s succeed (%x).",
|
||||
ToStr::Get(riid).c_str(), SUCCEEDED(real) ? "did" : "did not", real);
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
*ppvDebug = new WrappedID3D12Debug();
|
||||
return S_OK;
|
||||
}
|
||||
};
|
||||
|
||||
D3D12Hook D3D12Hook::d3d12hooks;
|
||||
|
||||
extern "C" __declspec(dllexport) HRESULT
|
||||
__cdecl RENDERDOC_CreateWrappedD3D12Device(IUnknown *pAdapter,
|
||||
D3D_FEATURE_LEVEL MinimumFeatureLevel, REFIID riid,
|
||||
void **ppDevice)
|
||||
{
|
||||
return D3D12Hook::CreateWrappedDevice(pAdapter, MinimumFeatureLevel, riid, ppDevice);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
#include "d3d12_manager.h"
|
||||
#include "d3d12_device.h"
|
||||
|
||||
bool D3D12ResourceManager::SerialisableResource(ResourceId id, D3D12ResourceRecord *record)
|
||||
{
|
||||
if(id == m_Device->GetResourceID())
|
||||
return true;
|
||||
|
||||
if(record->ignoreSerialise)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ResourceId D3D12ResourceManager::GetID(ID3D12DeviceChild *res)
|
||||
{
|
||||
return GetID(res);
|
||||
}
|
||||
|
||||
bool D3D12ResourceManager::ResourceTypeRelease(ID3D12DeviceChild *res)
|
||||
{
|
||||
if(res)
|
||||
res->Release();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12ResourceManager::Force_InitialState(ID3D12DeviceChild *res)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool D3D12ResourceManager::Need_InitialStateChunk(ID3D12DeviceChild *res)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
{
|
||||
RDCUNIMPLEMENTED("init states");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool D3D12ResourceManager::Serialise_InitialState(ResourceId id, ID3D12DeviceChild *res)
|
||||
{
|
||||
RDCUNIMPLEMENTED("init states");
|
||||
return false;
|
||||
}
|
||||
|
||||
void D3D12ResourceManager::Create_InitialState(ResourceId id, ID3D12DeviceChild *live, bool hasData)
|
||||
{
|
||||
RDCUNIMPLEMENTED("init states");
|
||||
}
|
||||
|
||||
void D3D12ResourceManager::Apply_InitialState(ID3D12DeviceChild *live, InitialContentData data)
|
||||
{
|
||||
RDCUNIMPLEMENTED("init states");
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "api/replay/renderdoc_replay.h"
|
||||
#include "common/wrapped_pool.h"
|
||||
#include "core/core.h"
|
||||
#include "core/resource_manager.h"
|
||||
#include "driver/d3d12/d3d12_common.h"
|
||||
#include "serialise/serialiser.h"
|
||||
|
||||
struct D3D12ResourceRecord : public ResourceRecord
|
||||
{
|
||||
enum
|
||||
{
|
||||
NullResource = NULL
|
||||
};
|
||||
|
||||
static byte markerValue[32];
|
||||
|
||||
D3D12ResourceRecord(ResourceId id)
|
||||
: ResourceRecord(id, true), NumSubResources(0), SubResources(NULL)
|
||||
{
|
||||
RDCEraseEl(ShadowPtr);
|
||||
RDCEraseEl(contexts);
|
||||
ignoreSerialise = false;
|
||||
}
|
||||
|
||||
~D3D12ResourceRecord()
|
||||
{
|
||||
for(int i = 0; i < NumSubResources; i++)
|
||||
{
|
||||
SubResources[i]->DeleteChunks();
|
||||
SAFE_DELETE(SubResources[i]);
|
||||
}
|
||||
|
||||
SAFE_DELETE_ARRAY(SubResources);
|
||||
|
||||
FreeShadowStorage();
|
||||
}
|
||||
|
||||
void AllocShadowStorage(int ctx, size_t size)
|
||||
{
|
||||
if(ShadowPtr[ctx][0] == NULL)
|
||||
{
|
||||
ShadowPtr[ctx][0] = Serialiser::AllocAlignedBuffer(size + sizeof(markerValue));
|
||||
ShadowPtr[ctx][1] = Serialiser::AllocAlignedBuffer(size + sizeof(markerValue));
|
||||
|
||||
memcpy(ShadowPtr[ctx][0] + size, markerValue, sizeof(markerValue));
|
||||
memcpy(ShadowPtr[ctx][1] + size, markerValue, sizeof(markerValue));
|
||||
|
||||
ShadowSize[ctx] = size;
|
||||
}
|
||||
}
|
||||
|
||||
bool VerifyShadowStorage(int ctx)
|
||||
{
|
||||
if(ShadowPtr[ctx][0] &&
|
||||
memcmp(ShadowPtr[ctx][0] + ShadowSize[ctx], markerValue, sizeof(markerValue)))
|
||||
return false;
|
||||
|
||||
if(ShadowPtr[ctx][1] &&
|
||||
memcmp(ShadowPtr[ctx][1] + ShadowSize[ctx], markerValue, sizeof(markerValue)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FreeShadowStorage()
|
||||
{
|
||||
for(int i = 0; i < 32; i++)
|
||||
{
|
||||
if(ShadowPtr[i][0] != NULL)
|
||||
{
|
||||
Serialiser::FreeAlignedBuffer(ShadowPtr[i][0]);
|
||||
Serialiser::FreeAlignedBuffer(ShadowPtr[i][1]);
|
||||
}
|
||||
ShadowPtr[i][0] = ShadowPtr[i][1] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
byte *GetShadowPtr(int ctx, int p) { return ShadowPtr[ctx][p]; }
|
||||
int GetContextID()
|
||||
{
|
||||
// 0 is reserved for the immediate context
|
||||
for(int i = 1; i < 32; i++)
|
||||
{
|
||||
if(contexts[i] == false)
|
||||
{
|
||||
contexts[i] = true;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
RDCERR(
|
||||
"More than 32 deferred contexts wanted an ID! Either a leak, or many many contexts mapping "
|
||||
"the same buffer");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FreeContextID(int ctx) { contexts[ctx] = false; }
|
||||
void SetDataPtr(byte *ptr)
|
||||
{
|
||||
DataPtr = ptr;
|
||||
|
||||
for(int i = 0; i < NumSubResources; i++)
|
||||
SubResources[i]->SetDataPtr(ptr);
|
||||
}
|
||||
|
||||
void Insert(map<int32_t, Chunk *> &recordlist)
|
||||
{
|
||||
bool dataWritten = DataWritten;
|
||||
|
||||
DataWritten = true;
|
||||
|
||||
for(auto it = Parents.begin(); it != Parents.end(); ++it)
|
||||
{
|
||||
if(!(*it)->DataWritten)
|
||||
{
|
||||
(*it)->Insert(recordlist);
|
||||
}
|
||||
}
|
||||
|
||||
if(!dataWritten)
|
||||
{
|
||||
recordlist.insert(m_Chunks.begin(), m_Chunks.end());
|
||||
|
||||
for(int i = 0; i < NumSubResources; i++)
|
||||
SubResources[i]->Insert(recordlist);
|
||||
}
|
||||
}
|
||||
|
||||
bool ignoreSerialise;
|
||||
|
||||
int NumSubResources;
|
||||
ResourceRecord **SubResources;
|
||||
|
||||
private:
|
||||
byte *ShadowPtr[32][2];
|
||||
size_t ShadowSize[32];
|
||||
|
||||
bool contexts[32];
|
||||
};
|
||||
|
||||
class D3D12ResourceManager
|
||||
: public ResourceManager<ID3D12DeviceChild *, ID3D12DeviceChild *, D3D12ResourceRecord>
|
||||
{
|
||||
public:
|
||||
D3D12ResourceManager(LogState state, Serialiser *ser, WrappedID3D12Device *dev)
|
||||
: ResourceManager(state, ser), m_Device(dev)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
bool SerialisableResource(ResourceId id, D3D12ResourceRecord *record);
|
||||
ResourceId GetID(ID3D12DeviceChild *res);
|
||||
|
||||
bool ResourceTypeRelease(ID3D12DeviceChild *res);
|
||||
|
||||
bool Force_InitialState(ID3D12DeviceChild *res);
|
||||
bool Need_InitialStateChunk(ID3D12DeviceChild *res);
|
||||
bool Prepare_InitialState(ID3D12DeviceChild *res);
|
||||
bool Serialise_InitialState(ResourceId resid, ID3D12DeviceChild *res);
|
||||
void Create_InitialState(ResourceId id, ID3D12DeviceChild *live, bool hasData);
|
||||
void Apply_InitialState(ID3D12DeviceChild *live, InitialContentData data);
|
||||
|
||||
WrappedID3D12Device *m_Device;
|
||||
};
|
||||
@@ -0,0 +1,213 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Development|Win32">
|
||||
<Configuration>Development</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Development|x64">
|
||||
<Configuration>Development</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{9E6B10A2-84B4-434D-ABDB-43BE4EA650F4}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>renderdoc_d3d12</RootNamespace>
|
||||
<ProjectName>d3d12</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Development|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Development|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Development|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Development|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<ExecutablePath>$(ExecutablePath)</ExecutablePath>
|
||||
<IncludePath>$(VSInstallDir)\DIA SDK\include;$(SolutionDir)\breakpad;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
<ExcludePath>$(ExcludePath)</ExcludePath>
|
||||
<TargetName>driver_$(ProjectName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Development|x64'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<ExecutablePath>$(ExecutablePath)</ExecutablePath>
|
||||
<IncludePath>$(SolutionDir)\breakpad;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
<ExcludePath>$(ExcludePath)</ExcludePath>
|
||||
<TargetName>driver_$(ProjectName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<ExecutablePath>$(ExecutablePath)</ExecutablePath>
|
||||
<IncludePath>$(VSInstallDir)\DIA SDK\include;$(SolutionDir)\breakpad;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
<ExcludePath>$(ExcludePath)</ExcludePath>
|
||||
<TargetName>driver_$(ProjectName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Development|Win32'">
|
||||
<ExecutablePath>$(ExecutablePath)</ExecutablePath>
|
||||
<IncludePath>$(VSInstallDir)\DIA SDK\include;$(SolutionDir)\breakpad;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
<ExcludePath>$(ExcludePath)</ExcludePath>
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>driver_$(ProjectName)</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Development|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>RENDERDOC_EXPORTS;RENDERDOC_PLATFORM_WIN32;WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)renderdoc\;$(SolutionDir)renderdoc\3rdparty\</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalOptions>/wd4100 /wd4512</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Development|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>RENDERDOC_EXPORTS;RENDERDOC_PLATFORM_WIN32;WIN64;WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)renderdoc\;$(SolutionDir)renderdoc\3rdparty\</AdditionalIncludeDirectories>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalOptions>/wd4100 /wd4512</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>RENDERDOC_EXPORTS;RENDERDOC_PLATFORM_WIN32;WIN32;RELEASE;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)renderdoc\;$(SolutionDir)renderdoc\3rdparty\</AdditionalIncludeDirectories>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalOptions>/wd4100 /wd4512</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>RENDERDOC_EXPORTS;RENDERDOC_PLATFORM_WIN32;USE_BREAKPAD;WIN64;WIN32;RELEASE;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)renderdoc\;$(SolutionDir)renderdoc\3rdparty\</AdditionalIncludeDirectories>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalOptions>/wd4100 /wd4512</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="d3d12_common.cpp" />
|
||||
<ClCompile Include="d3d12_device.cpp" />
|
||||
<ClCompile Include="d3d12_device_wrap.cpp" />
|
||||
<ClCompile Include="d3d12_hooks.cpp" />
|
||||
<ClCompile Include="d3d12_manager.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="d3d12_common.h" />
|
||||
<ClInclude Include="d3d12_device.h" />
|
||||
<ClInclude Include="d3d12_manager.h" />
|
||||
<ClInclude Include="..\dx\official\d3d12.h" />
|
||||
<ClInclude Include="..\dx\official\d3d12sdklayers.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\shaders\dxbc\renderdoc_dxbc.vcxproj">
|
||||
<Project>{c43ff27e-a155-4852-88ec-5ce9334c07a8}</Project>
|
||||
<Private>false</Private>
|
||||
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
||||
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="official">
|
||||
<UniqueIdentifier>{069c5202-e850-427b-9353-250795a60436}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Hooks">
|
||||
<UniqueIdentifier>{289782b2-c6ba-41f5-b33d-762f96c89f3c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Util">
|
||||
<UniqueIdentifier>{7babebac-14e5-49cf-ad9e-7fec2beeb335}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Core IFaces">
|
||||
<UniqueIdentifier>{9064cb3c-1739-4405-8bea-11c5e2feb512}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Wrapped">
|
||||
<UniqueIdentifier>{b66407e3-297a-4a8d-bdae-09468c64ca18}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\dx\official\d3d12.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\dx\official\d3d12sdklayers.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="d3d12_common.h">
|
||||
<Filter>Util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="d3d12_device.h">
|
||||
<Filter>Core IFaces</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="d3d12_manager.h">
|
||||
<Filter>Util</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="d3d12_common.cpp">
|
||||
<Filter>Util</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="d3d12_hooks.cpp">
|
||||
<Filter>Hooks</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="d3d12_device.cpp">
|
||||
<Filter>Core IFaces</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="d3d12_manager.cpp">
|
||||
<Filter>Util</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="d3d12_device_wrap.cpp">
|
||||
<Filter>Wrapped</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -26,55 +26,75 @@
|
||||
#include "driver/dxgi/dxgi_wrapped.h"
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include "driver/d3d11/d3d11_context.h"
|
||||
#include "driver/d3d11/d3d11_renderstate.h"
|
||||
#include "driver/d3d11/d3d11_resources.h"
|
||||
#include "core/core.h"
|
||||
#include "serialise/serialiser.h"
|
||||
|
||||
string ToStrHelper<false, IID>::Get(const IID &el)
|
||||
{
|
||||
char tostrBuf[256] = {0};
|
||||
StringFormat::snprintf(tostrBuf, 255, "GUID {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
|
||||
el.Data1, (unsigned int)el.Data2, (unsigned int)el.Data3, el.Data4[0],
|
||||
el.Data4[1], el.Data4[2], el.Data4[3], el.Data4[4], el.Data4[5],
|
||||
el.Data4[6], el.Data4[7]);
|
||||
|
||||
return tostrBuf;
|
||||
}
|
||||
|
||||
WRAPPED_POOL_INST(WrappedIDXGIDevice);
|
||||
WRAPPED_POOL_INST(WrappedIDXGIDevice1);
|
||||
WRAPPED_POOL_INST(WrappedIDXGIDevice2);
|
||||
WRAPPED_POOL_INST(WrappedIDXGIDevice3);
|
||||
|
||||
std::vector<D3DDeviceCallback> WrappedIDXGISwapChain3::m_D3DCallbacks;
|
||||
|
||||
ID3DDevice *GetD3DDevice(IUnknown *pDevice)
|
||||
{
|
||||
ID3DDevice *wrapDevice = NULL;
|
||||
|
||||
if(WrappedIDXGIDevice::IsAlloc(pDevice) || WrappedIDXGIDevice1::IsAlloc(pDevice) ||
|
||||
WrappedIDXGIDevice2::IsAlloc(pDevice) || WrappedIDXGIDevice3::IsAlloc(pDevice))
|
||||
{
|
||||
if(WrappedIDXGIDevice::IsAlloc(pDevice))
|
||||
wrapDevice = ((WrappedIDXGIDevice *)(IDXGIDevice *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice1::IsAlloc(pDevice))
|
||||
wrapDevice = ((WrappedIDXGIDevice1 *)(IDXGIDevice1 *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice2::IsAlloc(pDevice))
|
||||
wrapDevice = ((WrappedIDXGIDevice2 *)(IDXGIDevice2 *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice3::IsAlloc(pDevice))
|
||||
wrapDevice = ((WrappedIDXGIDevice3 *)(IDXGIDevice3 *)pDevice)->GetD3DDevice();
|
||||
}
|
||||
|
||||
if(wrapDevice == NULL)
|
||||
wrapDevice = WrappedIDXGISwapChain3::GetD3DDevice(pDevice);
|
||||
|
||||
return wrapDevice;
|
||||
}
|
||||
|
||||
HRESULT WrappedIDXGIFactory::staticCreateSwapChain(IDXGIFactory *factory, IUnknown *pDevice,
|
||||
DXGI_SWAP_CHAIN_DESC *pDesc,
|
||||
IDXGISwapChain **ppSwapChain)
|
||||
{
|
||||
if(WrappedID3D11Device::IsAlloc(pDevice) || WrappedIDXGIDevice::IsAlloc(pDevice) ||
|
||||
WrappedIDXGIDevice1::IsAlloc(pDevice) || WrappedIDXGIDevice2::IsAlloc(pDevice) ||
|
||||
WrappedIDXGIDevice3::IsAlloc(pDevice))
|
||||
ID3DDevice *wrapDevice = GetD3DDevice(pDevice);
|
||||
|
||||
if(wrapDevice)
|
||||
{
|
||||
WrappedID3D11Device *wrapDevice = (WrappedID3D11Device *)pDevice;
|
||||
|
||||
if(WrappedIDXGIDevice::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice *)(IDXGIDevice *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice1::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice1 *)(IDXGIDevice1 *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice2::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice2 *)(IDXGIDevice2 *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice3::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice3 *)(IDXGIDevice3 *)pDevice)->GetD3DDevice();
|
||||
|
||||
if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen && pDesc)
|
||||
{
|
||||
pDesc->Windowed = TRUE;
|
||||
}
|
||||
|
||||
HRESULT ret = factory->CreateSwapChain(wrapDevice->GetReal(), pDesc, ppSwapChain);
|
||||
HRESULT ret = factory->CreateSwapChain(wrapDevice->GetRealIUnknown(), pDesc, ppSwapChain);
|
||||
|
||||
if(SUCCEEDED(ret))
|
||||
{
|
||||
*ppSwapChain =
|
||||
new WrappedIDXGISwapChain3(*ppSwapChain, pDesc ? pDesc->OutputWindow : NULL, wrapDevice);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Creating swap chain with non-hooked device!");
|
||||
}
|
||||
|
||||
RDCERR("Creating swap chain with non-hooked device!");
|
||||
|
||||
return factory->CreateSwapChain(pDevice, pDesc, ppSwapChain);
|
||||
}
|
||||
@@ -84,35 +104,22 @@ HRESULT WrappedIDXGIFactory2::staticCreateSwapChainForHwnd(
|
||||
const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, IDXGIOutput *pRestrictToOutput,
|
||||
IDXGISwapChain1 **ppSwapChain)
|
||||
{
|
||||
if(WrappedID3D11Device::IsAlloc(pDevice) || WrappedIDXGIDevice::IsAlloc(pDevice) ||
|
||||
WrappedIDXGIDevice1::IsAlloc(pDevice) || WrappedIDXGIDevice2::IsAlloc(pDevice) ||
|
||||
WrappedIDXGIDevice3::IsAlloc(pDevice))
|
||||
ID3DDevice *wrapDevice = GetD3DDevice(pDevice);
|
||||
|
||||
if(wrapDevice)
|
||||
{
|
||||
WrappedID3D11Device *wrapDevice = (WrappedID3D11Device *)pDevice;
|
||||
|
||||
if(WrappedIDXGIDevice::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice *)(IDXGIDevice *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice1::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice1 *)(IDXGIDevice1 *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice2::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice2 *)(IDXGIDevice2 *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice3::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice3 *)(IDXGIDevice3 *)pDevice)->GetD3DDevice();
|
||||
|
||||
if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen && pFullscreenDesc)
|
||||
{
|
||||
pFullscreenDesc = NULL;
|
||||
}
|
||||
|
||||
HRESULT ret = factory->CreateSwapChainForHwnd(wrapDevice->GetReal(), hWnd, pDesc,
|
||||
HRESULT ret = factory->CreateSwapChainForHwnd(wrapDevice->GetRealIUnknown(), hWnd, pDesc,
|
||||
pFullscreenDesc, pRestrictToOutput, ppSwapChain);
|
||||
|
||||
if(SUCCEEDED(ret))
|
||||
{
|
||||
*ppSwapChain = new WrappedIDXGISwapChain3(*ppSwapChain, hWnd, wrapDevice);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -131,32 +138,17 @@ HRESULT WrappedIDXGIFactory2::staticCreateSwapChainForCoreWindow(IDXGIFactory2 *
|
||||
IDXGIOutput *pRestrictToOutput,
|
||||
IDXGISwapChain1 **ppSwapChain)
|
||||
{
|
||||
if(WrappedID3D11Device::IsAlloc(pDevice) || WrappedIDXGIDevice::IsAlloc(pDevice) ||
|
||||
WrappedIDXGIDevice1::IsAlloc(pDevice) || WrappedIDXGIDevice2::IsAlloc(pDevice) ||
|
||||
WrappedIDXGIDevice3::IsAlloc(pDevice))
|
||||
ID3DDevice *wrapDevice = GetD3DDevice(pDevice);
|
||||
|
||||
if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen)
|
||||
{
|
||||
WrappedID3D11Device *wrapDevice = (WrappedID3D11Device *)pDevice;
|
||||
RDCWARN("Impossible to disallow fullscreen on call to CreateSwapChainForCoreWindow");
|
||||
}
|
||||
|
||||
if(WrappedIDXGIDevice::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice *)(IDXGIDevice *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice1::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice1 *)(IDXGIDevice1 *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice2::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice2 *)(IDXGIDevice2 *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice3::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice3 *)(IDXGIDevice3 *)pDevice)->GetD3DDevice();
|
||||
|
||||
if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen)
|
||||
{
|
||||
RDCWARN("Impossible to disallow fullscreen on call to CreateSwapChainForCoreWindow");
|
||||
}
|
||||
|
||||
HRESULT ret = factory->CreateSwapChainForCoreWindow(wrapDevice->GetReal(), pWindow, pDesc,
|
||||
pRestrictToOutput, ppSwapChain);
|
||||
if(wrapDevice)
|
||||
{
|
||||
HRESULT ret = factory->CreateSwapChainForCoreWindow(wrapDevice->GetRealIUnknown(), pWindow,
|
||||
pDesc, pRestrictToOutput, ppSwapChain);
|
||||
|
||||
if(SUCCEEDED(ret))
|
||||
{
|
||||
@@ -182,31 +174,16 @@ HRESULT WrappedIDXGIFactory2::staticCreateSwapChainForComposition(IDXGIFactory2
|
||||
IDXGIOutput *pRestrictToOutput,
|
||||
IDXGISwapChain1 **ppSwapChain)
|
||||
{
|
||||
if(WrappedID3D11Device::IsAlloc(pDevice) || WrappedIDXGIDevice::IsAlloc(pDevice) ||
|
||||
WrappedIDXGIDevice1::IsAlloc(pDevice) || WrappedIDXGIDevice2::IsAlloc(pDevice) ||
|
||||
WrappedIDXGIDevice3::IsAlloc(pDevice))
|
||||
ID3DDevice *wrapDevice = GetD3DDevice(pDevice);
|
||||
|
||||
if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen)
|
||||
{
|
||||
WrappedID3D11Device *wrapDevice = (WrappedID3D11Device *)pDevice;
|
||||
RDCWARN("Impossible to disallow fullscreen on call to CreateSwapChainForComposition");
|
||||
}
|
||||
|
||||
if(WrappedIDXGIDevice::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice *)(IDXGIDevice *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice1::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice1 *)(IDXGIDevice1 *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice2::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice2 *)(IDXGIDevice2 *)pDevice)->GetD3DDevice();
|
||||
if(WrappedIDXGIDevice3::IsAlloc(pDevice))
|
||||
wrapDevice =
|
||||
(WrappedID3D11Device *)((WrappedIDXGIDevice3 *)(IDXGIDevice3 *)pDevice)->GetD3DDevice();
|
||||
|
||||
if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen)
|
||||
{
|
||||
RDCWARN("Impossible to disallow fullscreen on call to CreateSwapChainForComposition");
|
||||
}
|
||||
|
||||
HRESULT ret = factory->CreateSwapChainForComposition(wrapDevice->GetReal(), pDesc,
|
||||
if(wrapDevice)
|
||||
{
|
||||
HRESULT ret = factory->CreateSwapChainForComposition(wrapDevice->GetRealIUnknown(), pDesc,
|
||||
pRestrictToOutput, ppSwapChain);
|
||||
|
||||
if(SUCCEEDED(ret))
|
||||
@@ -226,13 +203,14 @@ HRESULT WrappedIDXGIFactory2::staticCreateSwapChainForComposition(IDXGIFactory2
|
||||
return factory->CreateSwapChainForComposition(pDevice, pDesc, pRestrictToOutput, ppSwapChain);
|
||||
}
|
||||
|
||||
WrappedIDXGISwapChain3::WrappedIDXGISwapChain3(IDXGISwapChain *real, HWND wnd,
|
||||
WrappedID3D11Device *device)
|
||||
WrappedIDXGISwapChain3::WrappedIDXGISwapChain3(IDXGISwapChain *real, HWND wnd, ID3DDevice *device)
|
||||
: RefCountDXGIObject(real), m_pReal(real), m_pDevice(device), m_iRefcount(1), m_Wnd(wnd)
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
real->GetDesc(&desc);
|
||||
|
||||
m_pDevice->AddRef();
|
||||
|
||||
m_pReal1 = NULL;
|
||||
real->QueryInterface(__uuidof(IDXGISwapChain1), (void **)&m_pReal1);
|
||||
m_pReal2 = NULL;
|
||||
@@ -240,33 +218,7 @@ WrappedIDXGISwapChain3::WrappedIDXGISwapChain3(IDXGISwapChain *real, HWND wnd,
|
||||
m_pReal3 = NULL;
|
||||
real->QueryInterface(__uuidof(IDXGISwapChain3), (void **)&m_pReal3);
|
||||
|
||||
int bufCount = desc.BufferCount;
|
||||
|
||||
if(desc.SwapEffect == DXGI_SWAP_EFFECT_DISCARD)
|
||||
bufCount = 1;
|
||||
|
||||
RDCASSERT(bufCount < MAX_NUM_BACKBUFFERS);
|
||||
|
||||
for(int i = 0; i < MAX_NUM_BACKBUFFERS; i++)
|
||||
{
|
||||
m_pBackBuffers[i] = NULL;
|
||||
|
||||
if(i < bufCount)
|
||||
{
|
||||
GetBuffer(i, __uuidof(ID3D11Texture2D), (void **)&m_pBackBuffers[i]);
|
||||
|
||||
WrappedID3D11Texture2D1 *wrapped = (WrappedID3D11Texture2D1 *)m_pBackBuffers[i];
|
||||
|
||||
if(wrapped)
|
||||
{
|
||||
// keep ref as a 'view' (invisible to user)
|
||||
wrapped->ViewAddRef();
|
||||
wrapped->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_ADDREF(m_pDevice);
|
||||
WrapBuffersAfterResize();
|
||||
|
||||
// we do a 'fake' present right at the start, so that we can capture frame 1, by
|
||||
// going from this fake present to the first present.
|
||||
@@ -275,42 +227,20 @@ WrappedIDXGISwapChain3::WrappedIDXGISwapChain3(IDXGISwapChain *real, HWND wnd,
|
||||
|
||||
WrappedIDXGISwapChain3::~WrappedIDXGISwapChain3()
|
||||
{
|
||||
m_pDevice->ReleaseSwapchainResources(this);
|
||||
RDCLOG("~WrappedIDXGISwapChain3");
|
||||
|
||||
m_pDevice->ShutdownSwapchain(this);
|
||||
|
||||
SAFE_RELEASE(m_pDevice);
|
||||
|
||||
for(int i = 0; i < MAX_NUM_BACKBUFFERS; i++)
|
||||
{
|
||||
WrappedID3D11Texture2D1 *wrapped = (WrappedID3D11Texture2D1 *)m_pBackBuffers[i];
|
||||
if(wrapped)
|
||||
wrapped->ViewRelease();
|
||||
m_pBackBuffers[i] = NULL;
|
||||
}
|
||||
SAFE_RELEASE(m_pReal1);
|
||||
SAFE_RELEASE(m_pReal2);
|
||||
SAFE_RELEASE(m_pReal3);
|
||||
SAFE_RELEASE(m_pReal);
|
||||
|
||||
SAFE_RELEASE(m_pDevice);
|
||||
}
|
||||
|
||||
void WrappedIDXGISwapChain3::ReleaseBuffersForResize()
|
||||
{
|
||||
for(int i = 0; i < MAX_NUM_BACKBUFFERS; i++)
|
||||
{
|
||||
WrappedID3D11Texture2D1 *wrapped = (WrappedID3D11Texture2D1 *)m_pBackBuffers[i];
|
||||
if(wrapped)
|
||||
{
|
||||
D3D11RenderState::ResourceRange range(wrapped);
|
||||
|
||||
m_pDevice->GetImmediateContext()->GetCurrentPipelineState()->UnbindIUnknownForWrite(range);
|
||||
m_pDevice->GetImmediateContext()->GetCurrentPipelineState()->UnbindIUnknownForRead(
|
||||
range, false, false);
|
||||
|
||||
wrapped->ViewRelease();
|
||||
}
|
||||
|
||||
wrapped = NULL;
|
||||
}
|
||||
|
||||
m_pDevice->ReleaseSwapchainResources(this);
|
||||
}
|
||||
|
||||
@@ -332,16 +262,8 @@ void WrappedIDXGISwapChain3::WrapBuffersAfterResize()
|
||||
|
||||
if(i < bufCount)
|
||||
{
|
||||
GetBuffer(i, __uuidof(ID3D11Texture2D), (void **)&m_pBackBuffers[i]);
|
||||
|
||||
WrappedID3D11Texture2D1 *wrapped = (WrappedID3D11Texture2D1 *)m_pBackBuffers[i];
|
||||
|
||||
if(wrapped)
|
||||
{
|
||||
// keep ref as a 'view' (invisible to user)
|
||||
wrapped->ViewAddRef();
|
||||
wrapped->Release();
|
||||
}
|
||||
GetBuffer(i, m_pDevice->GetBackbufferUUID(), (void **)&m_pBackBuffers[i]);
|
||||
m_pDevice->NewSwapchainBuffer(m_pBackBuffers[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -417,45 +339,38 @@ HRESULT WrappedIDXGISwapChain3::GetBuffer(
|
||||
RDCERR("Querying swapchain buffers via D3D10 interface UUIDs is not supported");
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
else if(riid != __uuidof(ID3D11Texture2D) && riid != __uuidof(ID3D11Resource))
|
||||
else if(riid != __uuidof(ID3D11Texture2D) && riid != __uuidof(ID3D11Resource) &&
|
||||
riid != __uuidof(ID3D12Resource))
|
||||
{
|
||||
RDCERR("Unsupported or unrecognised UUID passed to IDXGISwapChain::GetBuffer - %s",
|
||||
ToStr::Get(riid).c_str());
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
RDCASSERT(riid == __uuidof(ID3D11Texture2D) || riid == __uuidof(ID3D11Resource));
|
||||
RDCASSERT(riid == __uuidof(ID3D11Texture2D) || riid == __uuidof(ID3D11Resource) ||
|
||||
riid == __uuidof(ID3D12Resource));
|
||||
|
||||
HRESULT ret = m_pReal->GetBuffer(Buffer, riid, ppSurface);
|
||||
|
||||
ID3D11Texture2D *realSurface = (ID3D11Texture2D *)*ppSurface;
|
||||
ID3D11Texture2D *tex = realSurface;
|
||||
if(FAILED(ret))
|
||||
{
|
||||
RDCERR("Failed to get swapchain backbuffer %d: %08x", Buffer, ret);
|
||||
SAFE_RELEASE(realSurface);
|
||||
tex = NULL;
|
||||
IUnknown *realSurface = (IUnknown *)*ppSurface;
|
||||
IUnknown *tex = realSurface;
|
||||
|
||||
if(FAILED(ret))
|
||||
{
|
||||
RDCERR("Failed to get swapchain backbuffer %d: %08x", Buffer, ret);
|
||||
SAFE_RELEASE(realSurface);
|
||||
tex = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
GetDesc(&desc);
|
||||
tex = m_pDevice->WrapSwapchainBuffer(this, &desc, Buffer, realSurface);
|
||||
}
|
||||
|
||||
*ppSurface = tex;
|
||||
}
|
||||
else if(m_pDevice->GetResourceManager()->HasWrapper(realSurface))
|
||||
{
|
||||
tex = (ID3D11Texture2D *)m_pDevice->GetResourceManager()->GetWrapper(realSurface);
|
||||
tex->AddRef();
|
||||
|
||||
realSurface->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
tex = new WrappedID3D11Texture2D1(realSurface, m_pDevice, TEXDISPLAY_UNKNOWN);
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC desc;
|
||||
m_pReal->GetDesc(&desc);
|
||||
|
||||
m_pDevice->SetSwapChainTexture(this, &desc, Buffer, tex);
|
||||
|
||||
SetDebugName(tex, "Swap Chain Backbuffer");
|
||||
}
|
||||
|
||||
*ppSurface = tex;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -469,10 +384,10 @@ HRESULT WrappedIDXGISwapChain3::GetDevice(
|
||||
if(SUCCEEDED(ret))
|
||||
{
|
||||
// try one of the trivial wraps, we don't mind making a new one of those
|
||||
if(riid == __uuidof(ID3D11Device))
|
||||
if(riid == m_pDevice->GetDeviceUUID())
|
||||
{
|
||||
// probably they're asking for the device device.
|
||||
*ppDevice = m_pDevice;
|
||||
*ppDevice = m_pDevice->GetDeviceInterface();
|
||||
m_pDevice->AddRef();
|
||||
}
|
||||
else if(riid == __uuidof(IDXGISwapChain))
|
||||
@@ -542,14 +457,10 @@ bool RefCountDXGIObject::HandleWrap(REFIID riid, void **ppvObject)
|
||||
else if(riid == __uuidof(IDXGIFactory))
|
||||
{
|
||||
// yes I know PRECISELY how fucked up this is. Speak to microsoft - after KB2670838 the internal
|
||||
// D3D11
|
||||
// device creation function will pass in __uuidof(IDXGIFactory) then attempt to call
|
||||
// EnumDevices1 (which
|
||||
// is in the IDXGIFactory1 vtable). Doing this *should* be safe as using a IDXGIFactory1 like a
|
||||
// IDXGIFactory
|
||||
// should all just work by definition, but there's no way to know now if someone trying to
|
||||
// create a IDXGIFactory
|
||||
// really means it or not.
|
||||
// D3D11 device creation function will pass in __uuidof(IDXGIFactory) then attempt to call
|
||||
// EnumDevices1 (which is in the IDXGIFactory1 vtable). Doing this *should* be safe as using a
|
||||
// IDXGIFactory1 like a IDXGIFactory should all just work by definition, but there's no way to
|
||||
// know now if someone trying to create a IDXGIFactory really means it or not.
|
||||
IDXGIFactory1 *real = (IDXGIFactory1 *)(*ppvObject);
|
||||
*ppvObject = new WrappedIDXGIFactory1(real);
|
||||
return true;
|
||||
@@ -692,10 +603,10 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain3::QueryInterface(REFIID riid, vo
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if(riid == __uuidof(ID3D11Device))
|
||||
if(riid == m_pD3DDevice->GetDeviceUUID())
|
||||
{
|
||||
m_pD3DDevice->AddRef();
|
||||
*ppvObject = m_pD3DDevice;
|
||||
*ppvObject = m_pD3DDevice->GetDeviceInterface();
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
@@ -711,10 +622,10 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice1::QueryInterface(REFIID riid, void
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if(riid == __uuidof(ID3D11Device))
|
||||
if(riid == m_pD3DDevice->GetDeviceUUID())
|
||||
{
|
||||
m_pD3DDevice->AddRef();
|
||||
*ppvObject = m_pD3DDevice;
|
||||
*ppvObject = m_pD3DDevice->GetDeviceInterface();
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(IDXGIDevice1))
|
||||
@@ -764,10 +675,10 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice1::QueryInterface(REFIID riid, void
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice2::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if(riid == __uuidof(ID3D11Device))
|
||||
if(riid == m_pD3DDevice->GetDeviceUUID())
|
||||
{
|
||||
m_pD3DDevice->AddRef();
|
||||
*ppvObject = m_pD3DDevice;
|
||||
*ppvObject = m_pD3DDevice->GetDeviceInterface();
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(IDXGIDevice1))
|
||||
@@ -808,10 +719,10 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice2::QueryInterface(REFIID riid, void
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice3::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if(riid == __uuidof(ID3D11Device))
|
||||
if(riid == m_pD3DDevice->GetDeviceUUID())
|
||||
{
|
||||
m_pD3DDevice->AddRef();
|
||||
*ppvObject = m_pD3DDevice;
|
||||
*ppvObject = m_pD3DDevice->GetDeviceInterface();
|
||||
return S_OK;
|
||||
}
|
||||
else if(riid == __uuidof(IDXGIDevice1))
|
||||
|
||||
@@ -25,10 +25,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../d3d11/official/d3d11_4.h"
|
||||
#include "../d3d11/official/dxgi1_5.h"
|
||||
#include "common/common.h"
|
||||
#include "common/wrapped_pool.h"
|
||||
#include "driver/dx/official/dxgi1_5.h"
|
||||
|
||||
MIDL_INTERFACE("6f15aaf2-d208-4e89-9ab4-489535d34f9c") ID3D11Texture2D;
|
||||
MIDL_INTERFACE("dc8e63f3-d12b-4952-b47b-5e45026a862d") ID3D11Resource;
|
||||
MIDL_INTERFACE("db6f6ddb-ac77-4e88-8253-819df9bbf140") ID3D11Device;
|
||||
MIDL_INTERFACE("696442be-a72e-4059-bc79-5b5c98040fad") ID3D12Resource;
|
||||
MIDL_INTERFACE("189819f1-1db6-4b57-be54-1821339b85f7") ID3D12Device;
|
||||
|
||||
class RefCountDXGIObject : public IDXGIObject
|
||||
{
|
||||
@@ -58,11 +63,15 @@ public:
|
||||
return WrapQueryInterface(m_pReal, riid, ppvObject);
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return ++m_iRefcount; }
|
||||
ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
InterlockedIncrement(&m_iRefcount);
|
||||
return m_iRefcount;
|
||||
}
|
||||
ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
ULONG ret = --m_iRefcount;
|
||||
if(m_iRefcount == 0)
|
||||
unsigned int ret = InterlockedDecrement(&m_iRefcount);
|
||||
if(ret == 0)
|
||||
delete this;
|
||||
return ret;
|
||||
}
|
||||
@@ -142,8 +151,31 @@ public:
|
||||
return RefCountDXGIObject::GetParent(riid, ppvObject); \
|
||||
}
|
||||
|
||||
class WrappedID3D11Device;
|
||||
struct ID3D11Resource;
|
||||
class WrappedIDXGISwapChain3;
|
||||
|
||||
struct ID3DDevice
|
||||
{
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef() = 0;
|
||||
virtual ULONG STDMETHODCALLTYPE Release() = 0;
|
||||
virtual IUnknown *GetRealIUnknown() = 0;
|
||||
|
||||
virtual IID GetBackbufferUUID() = 0;
|
||||
|
||||
virtual IID GetDeviceUUID() = 0;
|
||||
virtual IUnknown *GetDeviceInterface() = 0;
|
||||
|
||||
virtual void FirstFrame(WrappedIDXGISwapChain3 *swapChain) = 0;
|
||||
virtual void ShutdownSwapchain(WrappedIDXGISwapChain3 *swapChain) = 0;
|
||||
|
||||
virtual void NewSwapchainBuffer(IUnknown *backbuffer) = 0;
|
||||
virtual void ReleaseSwapchainResources(WrappedIDXGISwapChain3 *swapChain) = 0;
|
||||
virtual IUnknown *WrapSwapchainBuffer(WrappedIDXGISwapChain3 *swap, DXGI_SWAP_CHAIN_DESC *swapDesc,
|
||||
UINT buffer, IUnknown *realSurface) = 0;
|
||||
|
||||
virtual HRESULT Present(WrappedIDXGISwapChain3 *swapChain, UINT SyncInterval, UINT Flags) = 0;
|
||||
};
|
||||
|
||||
typedef ID3DDevice *(*D3DDeviceCallback)(IUnknown *dev);
|
||||
|
||||
class WrappedIDXGISwapChain3 : public IDXGISwapChain3, public RefCountDXGIObject
|
||||
{
|
||||
@@ -151,22 +183,43 @@ class WrappedIDXGISwapChain3 : public IDXGISwapChain3, public RefCountDXGIObject
|
||||
IDXGISwapChain1 *m_pReal1;
|
||||
IDXGISwapChain2 *m_pReal2;
|
||||
IDXGISwapChain3 *m_pReal3;
|
||||
WrappedID3D11Device *m_pDevice;
|
||||
ID3DDevice *m_pDevice;
|
||||
unsigned int m_iRefcount;
|
||||
|
||||
static std::vector<D3DDeviceCallback> m_D3DCallbacks;
|
||||
|
||||
HWND m_Wnd;
|
||||
|
||||
static const int MAX_NUM_BACKBUFFERS = 4;
|
||||
|
||||
ID3D11Resource *m_pBackBuffers[MAX_NUM_BACKBUFFERS];
|
||||
IUnknown *m_pBackBuffers[MAX_NUM_BACKBUFFERS];
|
||||
|
||||
void ReleaseBuffersForResize();
|
||||
void WrapBuffersAfterResize();
|
||||
|
||||
public:
|
||||
WrappedIDXGISwapChain3(IDXGISwapChain *real, HWND wnd, WrappedID3D11Device *device);
|
||||
WrappedIDXGISwapChain3(IDXGISwapChain *real, HWND wnd, ID3DDevice *device);
|
||||
virtual ~WrappedIDXGISwapChain3();
|
||||
|
||||
static void RegisterD3DDeviceCallback(D3DDeviceCallback callback)
|
||||
{
|
||||
m_D3DCallbacks.push_back(callback);
|
||||
}
|
||||
|
||||
static ID3DDevice *GetD3DDevice(IUnknown *dev)
|
||||
{
|
||||
for(size_t i = 0; i < m_D3DCallbacks.size(); i++)
|
||||
{
|
||||
ID3DDevice *d3d = m_D3DCallbacks[i](dev);
|
||||
if(d3d)
|
||||
return d3d;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int GetNumBackbuffers() { return MAX_NUM_BACKBUFFERS; }
|
||||
IUnknown **GetBackbuffers() { return m_pBackBuffers; }
|
||||
IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY;
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
|
||||
@@ -445,10 +498,10 @@ public:
|
||||
class WrappedIDXGIDevice : public IDXGIDevice, public RefCountDXGIObject
|
||||
{
|
||||
IDXGIDevice *m_pReal;
|
||||
ID3D11Device *m_pD3DDevice;
|
||||
ID3DDevice *m_pD3DDevice;
|
||||
|
||||
public:
|
||||
WrappedIDXGIDevice(IDXGIDevice *real, ID3D11Device *d3d)
|
||||
WrappedIDXGIDevice(IDXGIDevice *real, ID3DDevice *d3d)
|
||||
: RefCountDXGIObject(real), m_pReal(real), m_pD3DDevice(d3d)
|
||||
{
|
||||
m_pD3DDevice->AddRef();
|
||||
@@ -466,7 +519,7 @@ public:
|
||||
IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY;
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
|
||||
ID3D11Device *GetD3DDevice() { return m_pD3DDevice; }
|
||||
ID3DDevice *GetD3DDevice() { return m_pD3DDevice; }
|
||||
//////////////////////////////
|
||||
// implement IDXGIDevice
|
||||
|
||||
@@ -636,10 +689,10 @@ public:
|
||||
class WrappedIDXGIDevice1 : public IDXGIDevice1, public RefCountDXGIObject
|
||||
{
|
||||
IDXGIDevice1 *m_pReal;
|
||||
ID3D11Device *m_pD3DDevice;
|
||||
ID3DDevice *m_pD3DDevice;
|
||||
|
||||
public:
|
||||
WrappedIDXGIDevice1(IDXGIDevice1 *real, ID3D11Device *d3d)
|
||||
WrappedIDXGIDevice1(IDXGIDevice1 *real, ID3DDevice *d3d)
|
||||
: RefCountDXGIObject(real), m_pReal(real), m_pD3DDevice(d3d)
|
||||
{
|
||||
m_pD3DDevice->AddRef();
|
||||
@@ -656,7 +709,7 @@ public:
|
||||
IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY;
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
|
||||
ID3D11Device *GetD3DDevice() { return m_pD3DDevice; }
|
||||
ID3DDevice *GetD3DDevice() { return m_pD3DDevice; }
|
||||
//////////////////////////////
|
||||
// implement IDXGIDevice
|
||||
|
||||
@@ -804,10 +857,10 @@ public:
|
||||
class WrappedIDXGIDevice2 : public IDXGIDevice2, public RefCountDXGIObject
|
||||
{
|
||||
IDXGIDevice2 *m_pReal;
|
||||
ID3D11Device *m_pD3DDevice;
|
||||
ID3DDevice *m_pD3DDevice;
|
||||
|
||||
public:
|
||||
WrappedIDXGIDevice2(IDXGIDevice2 *real, ID3D11Device *d3d)
|
||||
WrappedIDXGIDevice2(IDXGIDevice2 *real, ID3DDevice *d3d)
|
||||
: RefCountDXGIObject(real), m_pReal(real), m_pD3DDevice(d3d)
|
||||
{
|
||||
m_pD3DDevice->AddRef();
|
||||
@@ -824,7 +877,7 @@ public:
|
||||
IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY;
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
|
||||
ID3D11Device *GetD3DDevice() { return m_pD3DDevice; }
|
||||
ID3DDevice *GetD3DDevice() { return m_pD3DDevice; }
|
||||
//////////////////////////////
|
||||
// implement IDXGIDevice
|
||||
|
||||
@@ -924,10 +977,10 @@ public:
|
||||
class WrappedIDXGIDevice3 : public IDXGIDevice3, public RefCountDXGIObject
|
||||
{
|
||||
IDXGIDevice3 *m_pReal;
|
||||
ID3D11Device *m_pD3DDevice;
|
||||
ID3DDevice *m_pD3DDevice;
|
||||
|
||||
public:
|
||||
WrappedIDXGIDevice3(IDXGIDevice3 *real, ID3D11Device *d3d)
|
||||
WrappedIDXGIDevice3(IDXGIDevice3 *real, ID3DDevice *d3d)
|
||||
: RefCountDXGIObject(real), m_pReal(real), m_pD3DDevice(d3d)
|
||||
{
|
||||
m_pD3DDevice->AddRef();
|
||||
@@ -944,7 +997,7 @@ public:
|
||||
IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY;
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
|
||||
ID3D11Device *GetD3DDevice() { return m_pD3DDevice; }
|
||||
ID3DDevice *GetD3DDevice() { return m_pD3DDevice; }
|
||||
//////////////////////////////
|
||||
// implement IDXGIDevice
|
||||
|
||||
|
||||
@@ -188,9 +188,16 @@
|
||||
<ClCompile Include="dxgi_wrapped.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\dx\official\dxgi.h" />
|
||||
<ClInclude Include="..\dx\official\dxgi1_2.h" />
|
||||
<ClInclude Include="..\dx\official\dxgi1_3.h" />
|
||||
<ClInclude Include="..\dx\official\dxgi1_4.h" />
|
||||
<ClInclude Include="..\dx\official\dxgi1_5.h" />
|
||||
<ClInclude Include="..\dx\official\dxgiformat.h" />
|
||||
<ClInclude Include="..\dx\official\dxgitype.h" />
|
||||
<ClInclude Include="dxgi_wrapped.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -6,5 +6,31 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="dxgi_wrapped.h" />
|
||||
<ClInclude Include="..\dx\official\dxgi.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\dx\official\dxgi1_2.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\dx\official\dxgi1_3.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\dx\official\dxgi1_4.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\dx\official\dxgi1_5.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\dx\official\dxgiformat.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\dx\official\dxgitype.h">
|
||||
<Filter>official</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="official">
|
||||
<UniqueIdentifier>{285b6e05-2a6b-4161-9d67-e24933eebb28}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,77 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
#include "dxbc_compile.h"
|
||||
#include "common/common.h"
|
||||
#include "serialise/string_utils.h"
|
||||
|
||||
// gives us an address to identify this dll with
|
||||
static int dllLocator = 0;
|
||||
|
||||
HMODULE GetD3DCompiler()
|
||||
{
|
||||
static HMODULE ret = NULL;
|
||||
if(ret != NULL)
|
||||
return ret;
|
||||
|
||||
// dlls to try in priority order
|
||||
const char *dlls[] = {
|
||||
"d3dcompiler_47.dll", "d3dcompiler_46.dll", "d3dcompiler_45.dll",
|
||||
"d3dcompiler_44.dll", "d3dcompiler_43.dll",
|
||||
};
|
||||
|
||||
for(int i = 0; i < 2; i++)
|
||||
{
|
||||
for(int d = 0; d < ARRAY_COUNT(dlls); d++)
|
||||
{
|
||||
if(i == 0)
|
||||
ret = GetModuleHandleA(dlls[d]);
|
||||
else
|
||||
ret = LoadLibraryA(dlls[d]);
|
||||
|
||||
if(ret != NULL)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// all else failed, couldn't find d3dcompiler loaded,
|
||||
// and couldn't even loadlibrary any version!
|
||||
// we'll have to loadlibrary the version that ships with
|
||||
// RenderDoc.
|
||||
|
||||
HMODULE hModule = NULL;
|
||||
GetModuleHandleEx(
|
||||
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
(LPCTSTR)&dllLocator, &hModule);
|
||||
wchar_t curFile[512] = {0};
|
||||
GetModuleFileNameW(hModule, curFile, 511);
|
||||
|
||||
std::wstring path = std::wstring(curFile);
|
||||
path = dirname(path);
|
||||
std::wstring dll = path + L"/d3dcompiler_47.dll";
|
||||
|
||||
ret = LoadLibraryW(dll.c_str());
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Baldur Karlsson
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
HMODULE GetD3DCompiler();
|
||||
@@ -19,11 +19,13 @@
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dxbc_compile.cpp" />
|
||||
<ClCompile Include="dxbc_debug.cpp" />
|
||||
<ClCompile Include="dxbc_disassemble.cpp" />
|
||||
<ClCompile Include="dxbc_inspect.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="dxbc_compile.h" />
|
||||
<ClInclude Include="dxbc_debug.h" />
|
||||
<ClInclude Include="dxbc_disassemble.h" />
|
||||
<ClInclude Include="dxbc_inspect.h" />
|
||||
@@ -198,4 +200,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -4,6 +4,7 @@
|
||||
<ClCompile Include="dxbc_debug.cpp" />
|
||||
<ClCompile Include="dxbc_disassemble.cpp" />
|
||||
<ClCompile Include="dxbc_inspect.cpp" />
|
||||
<ClCompile Include="dxbc_compile.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="dxbc_debug.h" />
|
||||
@@ -11,5 +12,6 @@
|
||||
<ClInclude Include="dxbc_inspect.h" />
|
||||
<ClInclude Include="dxbc_sdbg.h" />
|
||||
<ClInclude Include="dxbc_spdb.h" />
|
||||
<ClInclude Include="dxbc_compile.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -426,6 +426,14 @@
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="driver\d3d12\renderdoc_d3d12.vcxproj">
|
||||
<Project>{9e6b10a2-84b4-434d-abdb-43be4ea650f4}</Project>
|
||||
<Private>false</Private>
|
||||
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="driver\dxgi\renderdoc_dxgi.vcxproj">
|
||||
<Project>{2a793574-bd3c-46d4-9788-c339d9550ce1}</Project>
|
||||
<Private>false</Private>
|
||||
@@ -454,4 +462,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user