ReplayCreateStatus ReplayRenderer::CreateDevice(const wchar_t *logfile) { RDCLOG("Creating replay device for %ls", logfile); RDCDriver driverType = RDC_Unknown; wstring driverName = L""; auto status = RenderDoc::Inst().FillInitParams(logfile, driverType, driverName, NULL); if(driverType == RDC_Unknown || driverName == L"" || status != eReplayCreate_Success) { RDCERR("Couldn't get device type from log"); return status; } IReplayDriver *driver = NULL; status = RenderDoc::Inst().CreateReplayDriver(driverType, logfile, &driver); if(driver && status == eReplayCreate_Success) { RDCLOG("Created replay driver."); return PostCreateInit(driver); } RDCERR("Couldn't create a replay device :(."); return status; }
static HRESULT CreateWrappedFactory2(UINT Flags, REFIID riid, void **ppFactory) { if(dxgihooks.m_HasHooks) return dxgihooks.CreateDXGIFactory2_hook(Flags, riid, ppFactory); HMODULE dxgi = GetModuleHandleA("dxgi.dll"); if(dxgi) { PFN_CREATE_DXGI_FACTORY2 createFunc = (PFN_CREATE_DXGI_FACTORY2)GetProcAddress(dxgi, "CreateDXGIFactory2"); if(!createFunc) { RDCERR("Trying to create hooked dxgi factory without dxgi loaded"); return E_INVALIDARG; } HRESULT ret = createFunc(Flags, riid, ppFactory); if(SUCCEEDED(ret)) RefCountDXGIObject::HandleWrap(riid, ppFactory); return ret; } else { RDCERR("Something went seriously wrong, dxgi.dll couldn't be loaded!"); return E_UNEXPECTED; } }
bool WrappedID3D11Device::Serialise_CreateQuery1(const D3D11_QUERY_DESC1 *pQueryDesc, ID3D11Query1 **ppQuery) { SERIALISE_ELEMENT_PTR(D3D11_QUERY_DESC1, Descriptor, pQueryDesc); SERIALISE_ELEMENT(ResourceId, Query, GetIDForResource(*ppQuery)); if(m_State == READING) { ID3D11Query1 *ret = NULL; HRESULT hr = E_NOINTERFACE; if(m_pDevice3) hr = m_pDevice3->CreateQuery1(&Descriptor, &ret); else RDCERR("Replaying a D3D11.3 device without D3D11.3 available"); if(FAILED(hr)) { RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); } else { ret = new WrappedID3D11Query1(ret, this); GetResourceManager()->AddLiveResource(Query, ret); } } return true; }
bool WrappedID3D11Device::Serialise_CreateRasterizerState1( const D3D11_RASTERIZER_DESC1 *pRasterizerDesc, ID3D11RasterizerState1 **ppRasterizerState) { SERIALISE_ELEMENT_PTR(D3D11_RASTERIZER_DESC1, Descriptor, pRasterizerDesc); SERIALISE_ELEMENT(ResourceId, State, GetIDForResource(*ppRasterizerState)); if(m_State == READING) { ID3D11RasterizerState1 *ret = NULL; HRESULT hr = E_NOINTERFACE; if(m_pDevice1) hr = m_pDevice1->CreateRasterizerState1(&Descriptor, &ret); else RDCERR("Replaying a D3D11.1 device without D3D11.1 available"); if(FAILED(hr)) { RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); } else { ret = new WrappedID3D11RasterizerState2(ret, this); GetResourceManager()->AddLiveResource(State, ret); } } return true; }
extern "C" RENDERDOC_API int RENDERDOC_CC RENDERDOC_GetAPI(RENDERDOC_Version version, void **outAPIPointers) { if(outAPIPointers == NULL) { RDCERR("Invalid call to RENDERDOC_GetAPI with NULL outAPIPointers"); return 0; } int ret = 0; int major = 0, minor = 0, patch = 0; #define API_VERSION_HANDLE(enumver, actualver) \ if(version == CONCAT(eRENDERDOC_API_Version_, enumver)) \ { \ CONCAT(Init_, actualver)(); \ *outAPIPointers = &CONCAT(api_, actualver); \ CONCAT(api_, actualver).GetAPIVersion(&major, &minor, &patch); \ ret = 1; \ } API_VERSION_HANDLE(1_0_0, 1_0_1); API_VERSION_HANDLE(1_0_1, 1_0_1); #undef API_VERSION_HANDLE if(ret) { RDCLOG("Initialising RenderDoc API version %d.%d.%d for requested version %d", major, minor, patch, version); return 1; } RDCERR("Unrecognised API version '%d'", version); return 0; }
HRESULT WrappedIDXGISwapChain2::GetBuffer( /* [in] */ UINT Buffer, /* [in] */ REFIID riid, /* [out][in] */ void **ppSurface) { if(ppSurface == NULL) return E_INVALIDARG; // ID3D10Texture2D UUID {9B7E4C04-342C-4106-A19F-4F2704F689F0} static const GUID ID3D10Texture2D_uuid = { 0x9b7e4c04, 0x342c, 0x4106, { 0xa1, 0x9f, 0x4f, 0x27, 0x04, 0xf6, 0x89, 0xf0 } }; // ID3D10Resource UUID {9B7E4C01-342C-4106-A19F-4F2704F689F0} static const GUID ID3D10Resource_uuid = { 0x9b7e4c01, 0x342c, 0x4106, { 0xa1, 0x9f, 0x4f, 0x27, 0x04, 0xf6, 0x89, 0xf0 } }; if(riid == ID3D10Texture2D_uuid || riid == ID3D10Resource_uuid) { RDCERR("Querying swapchain buffers via D3D10 interface UUIDs is not supported"); return E_NOINTERFACE; } else if(riid != __uuidof(ID3D11Texture2D) && riid != __uuidof(ID3D11Resource)) { 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)); 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; } else if(m_pDevice->GetResourceManager()->HasWrapper(realSurface)) { tex = (ID3D11Texture2D *)m_pDevice->GetResourceManager()->GetWrapper(realSurface); tex->AddRef(); realSurface->Release(); } else { tex = new WrappedID3D11Texture2D(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; }
bool WrappedID3D11Device::Serialise_CreateTexture2D1(const D3D11_TEXTURE2D_DESC1 *pDesc, const D3D11_SUBRESOURCE_DATA *pInitialData, ID3D11Texture2D1 **ppTexture2D) { SERIALISE_ELEMENT_PTR(D3D11_TEXTURE2D_DESC1, Descriptor, pDesc); SERIALISE_ELEMENT(ResourceId, pTexture, GetIDForResource(*ppTexture2D)); SERIALISE_ELEMENT(bool, HasInitialData, pInitialData != NULL); vector<D3D11_SUBRESOURCE_DATA> descs = Serialise_CreateTextureData( ppTexture2D ? *ppTexture2D : NULL, pTexture, pInitialData, Descriptor.Width, Descriptor.Height, 1, Descriptor.Format, Descriptor.MipLevels, Descriptor.ArraySize, HasInitialData); if(m_State == READING) { ID3D11Texture2D1 *ret = NULL; HRESULT hr = E_NOINTERFACE; TextureDisplayType dispType = DispTypeForTexture(Descriptor); // unset flags that are unimportant/problematic in replay Descriptor.MiscFlags &= ~(D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_GDI_COMPATIBLE | D3D11_RESOURCE_MISC_SHARED_NTHANDLE); if(m_pDevice3) { if(HasInitialData) hr = m_pDevice3->CreateTexture2D1(&Descriptor, &descs[0], &ret); else hr = m_pDevice3->CreateTexture2D1(&Descriptor, NULL, &ret); } else { RDCERR("Replaying a D3D11.3 device without D3D11.3 available"); } if(FAILED(hr)) { RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); } else { ret = new WrappedID3D11Texture2D1((ID3D11Texture2D1 *)ret, this, dispType); GetResourceManager()->AddLiveResource(pTexture, ret); } } for(size_t i = 0; i < descs.size(); i++) SAFE_DELETE_ARRAY(descs[i].pSysMem); return true; }
GLuint GLReplay::CreateShaderProgram(const char *vsSrc, const char *psSrc) { if(m_pDriver == NULL) return 0; MakeCurrentReplayContext(m_DebugCtx); WrappedOpenGL &gl = *m_pDriver; GLuint vs = gl.glCreateShader(eGL_VERTEX_SHADER); GLuint fs = gl.glCreateShader(eGL_FRAGMENT_SHADER); const char *src = vsSrc; gl.glShaderSource(vs, 1, &src, NULL); src = psSrc; gl.glShaderSource(fs, 1, &src, NULL); gl.glCompileShader(vs); gl.glCompileShader(fs); char buffer[4096]; GLint status = 0; gl.glGetShaderiv(vs, eGL_COMPILE_STATUS, &status); if(status == 0) { gl.glGetShaderInfoLog(vs, 4096, NULL, buffer); RDCERR("Shader error: %hs", buffer); } gl.glGetShaderiv(fs, eGL_COMPILE_STATUS, &status); if(status == 0) { gl.glGetShaderInfoLog(fs, 4096, NULL, buffer); RDCERR("Shader error: %hs", buffer); } GLuint ret = gl.glCreateProgram(); gl.glAttachShader(ret, vs); gl.glAttachShader(ret, fs); gl.glLinkProgram(ret); gl.glDeleteShader(vs); gl.glDeleteShader(fs); return ret; }
bool Copy(const char *from, const char *to, bool allowOverwrite) { if(from[0] == 0 || to[0] == 0) return false; FILE *ff = ::fopen(from, "r"); if(!ff) { RDCERR("Can't open source file for copy '%s'", from); return false; } FILE *tf = ::fopen(to, "r"); if(tf && !allowOverwrite) { RDCERR("Destination file for non-overwriting copy '%s' already exists", from); ::fclose(ff); ::fclose(tf); return false; } if(tf) ::fclose(tf); tf = ::fopen(to, "w"); if(!tf) { ::fclose(ff); RDCERR("Can't open destination file for copy '%s'", to); return false; } char buffer[BUFSIZ]; while(!::feof(ff)) { size_t nread = ::fread(buffer, 1, BUFSIZ, ff); ::fwrite(buffer, 1, nread, tf); } ::fclose(ff); ::fclose(tf); return true; }
HRESULT WrappedIDXGIFactory2::staticCreateSwapChainForComposition(IDXGIFactory2 *factory, IUnknown *pDevice, const DXGI_SWAP_CHAIN_DESC1 *pDesc, IDXGIOutput *pRestrictToOutput, IDXGISwapChain1 **ppSwapChain) { ID3DDevice *wrapDevice = GetD3DDevice(pDevice); if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen) { RDCWARN("Impossible to disallow fullscreen on call to CreateSwapChainForComposition"); } if(wrapDevice) { HRESULT ret = factory->CreateSwapChainForComposition(wrapDevice->GetRealIUnknown(), pDesc, pRestrictToOutput, ppSwapChain); if(SUCCEEDED(ret)) { HWND wnd = NULL; (*ppSwapChain)->GetHwnd(&wnd); *ppSwapChain = new WrappedIDXGISwapChain3(*ppSwapChain, wnd, wrapDevice); } return ret; } else { RDCERR("Creating swap chain with non-hooked device!"); } return factory->CreateSwapChainForComposition(pDevice, pDesc, pRestrictToOutput, ppSwapChain); }
HRESULT WrappedIDXGIFactory2::staticCreateSwapChainForHwnd( IDXGIFactory2 *factory, IUnknown *pDevice, HWND hWnd, const DXGI_SWAP_CHAIN_DESC1 *pDesc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *pFullscreenDesc, IDXGIOutput *pRestrictToOutput, IDXGISwapChain1 **ppSwapChain) { ID3DDevice *wrapDevice = GetD3DDevice(pDevice); if(wrapDevice) { if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen && pFullscreenDesc) { pFullscreenDesc = NULL; } HRESULT ret = factory->CreateSwapChainForHwnd(wrapDevice->GetRealIUnknown(), hWnd, pDesc, pFullscreenDesc, pRestrictToOutput, ppSwapChain); if(SUCCEEDED(ret)) { *ppSwapChain = new WrappedIDXGISwapChain3(*ppSwapChain, hWnd, wrapDevice); } return ret; } else { RDCERR("Creating swap chain with non-hooked device!"); } return factory->CreateSwapChainForHwnd(pDevice, hWnd, pDesc, pFullscreenDesc, pRestrictToOutput, ppSwapChain); }
bool WrappedVulkan::Serialise_vkCreateFence( Serialiser* localSerialiser, VkDevice device, const VkFenceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(VkFenceCreateInfo, info, *pCreateInfo); SERIALISE_ELEMENT(ResourceId, id, GetResID(*pFence)); if(m_State == READING) { device = GetResourceManager()->GetLiveHandle<VkDevice>(devId); VkFence fence = VK_NULL_HANDLE; VkResult ret = ObjDisp(device)->CreateFence(Unwrap(device), &info, NULL, &fence); if(ret != VK_SUCCESS) { RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); } else { ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), fence); GetResourceManager()->AddLiveResource(id, fence); } } return true; }
bool WrappedVulkan::Serialise_vkCreateEvent( Serialiser* localSerialiser, VkDevice device, const VkEventCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkEvent* pEvent) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(VkEventCreateInfo, info, *pCreateInfo); SERIALISE_ELEMENT(ResourceId, id, GetResID(*pEvent)); if(m_State == READING) { device = GetResourceManager()->GetLiveHandle<VkDevice>(devId); VkEvent ev = VK_NULL_HANDLE; VkResult ret = ObjDisp(device)->CreateEvent(Unwrap(device), &info, NULL, &ev); // see top of this file for current event/fence handling ObjDisp(device)->SetEvent(Unwrap(device), ev); if(ret != VK_SUCCESS) { RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); } else { ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), ev); GetResourceManager()->AddLiveResource(id, ev); } } return true; }
bool LZ4Compressor::FlushPage0() { // if we encountered a stream error this will be NULL if(!m_CompressBuffer) return false; // m_PageOffset is the amount written, usually equal to lz4BlockSize except the last block. int32_t compSize = LZ4_compress_fast_continue(&m_LZ4Comp, (const char *)m_Page[0], (char *)m_CompressBuffer, (int)m_PageOffset, (int)LZ4_COMPRESSBOUND(lz4BlockSize), 1); if(compSize < 0) { RDCERR("Error compressing: %i", compSize); FreeAlignedBuffer(m_Page[0]); FreeAlignedBuffer(m_Page[1]); FreeAlignedBuffer(m_CompressBuffer); m_Page[0] = m_Page[1] = m_CompressBuffer = NULL; return false; } bool success = true; success &= m_Write->Write(compSize); success &= m_Write->Write(m_CompressBuffer, compSize); // swap pages std::swap(m_Page[0], m_Page[1]); // start writing to the start of the page again m_PageOffset = 0; return success; }
bool WrappedID3D12Device::Serialise_CreateComputePipelineState( const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, REFIID riid, void **ppPipelineState) { SERIALISE_ELEMENT_PTR(D3D12_COMPUTE_PIPELINE_STATE_DESC, Descriptor, pDesc); SERIALISE_ELEMENT(IID, guid, riid); SERIALISE_ELEMENT(ResourceId, Pipe, ((WrappedID3D12PipelineState *)*ppPipelineState)->GetResourceID()); if(m_State == READING) { ID3D12PipelineState *ret = NULL; HRESULT hr = m_pDevice->CreateComputePipelineState(&Descriptor, guid, (void **)&ret); if(FAILED(hr)) { RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); } else { WrappedID3D12PipelineState *wrapped = new WrappedID3D12PipelineState(ret, this); ret = wrapped; wrapped->compute = new D3D12_COMPUTE_PIPELINE_STATE_DESC(Descriptor); wrapped->compute->CS.pShaderBytecode = WrappedID3D12PipelineState::AddShader(wrapped->compute->CS, this); GetResourceManager()->AddLiveResource(Pipe, ret); } } return true; }
bool WrappedVulkan::Serialise_vkAllocateMemory( Serialiser* localSerialiser, VkDevice device, const VkMemoryAllocateInfo* pAllocateInfo, const VkAllocationCallbacks* pAllocator, VkDeviceMemory* pMemory) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(VkMemoryAllocateInfo, info, *pAllocateInfo); SERIALISE_ELEMENT(ResourceId, id, GetResID(*pMemory)); if(m_State == READING) { VkDeviceMemory mem = VK_NULL_HANDLE; device = GetResourceManager()->GetLiveHandle<VkDevice>(devId); // serialised memory type index is non-remapped, so we remap now. // PORTABILITY may need to re-write info to change memory type index to the // appropriate index on replay info.memoryTypeIndex = m_PhysicalDeviceData.memIdxMap[info.memoryTypeIndex]; VkResult ret = ObjDisp(device)->AllocateMemory(Unwrap(device), &info, NULL, &mem); if(ret != VK_SUCCESS) { RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); } else { ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), mem); GetResourceManager()->AddLiveResource(id, mem); m_CreationInfo.m_Memory[live].Init(GetResourceManager(), m_CreationInfo, &info); // create a buffer with the whole memory range bound, for copying to and from // conveniently (for initial state data) VkBuffer buf = VK_NULL_HANDLE; VkBufferCreateInfo bufInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, NULL, 0, info.allocationSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, }; ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &bufInfo, NULL, &buf); RDCASSERTEQUAL(ret, VK_SUCCESS); ResourceId bufid = GetResourceManager()->WrapResource(Unwrap(device), buf); ObjDisp(device)->BindBufferMemory(Unwrap(device), Unwrap(buf), Unwrap(mem), 0); // register as a live-only resource, so it is cleaned up properly GetResourceManager()->AddLiveResource(bufid, buf); m_CreationInfo.m_Memory[live].wholeMemBuf = buf; } } return true; }
void DoSerialise(SerialiserType &ser, D3D12_DEPTH_STENCIL_VIEW_DESC &el) { SERIALISE_MEMBER(Format); SERIALISE_MEMBER(Flags); SERIALISE_MEMBER(ViewDimension); switch(el.ViewDimension) { case D3D12_DSV_DIMENSION_UNKNOWN: // indicates an empty descriptor, which comes from a NULL parameter to Create. break; case D3D12_DSV_DIMENSION_TEXTURE1D: SERIALISE_MEMBER(Texture1D.MipSlice); break; case D3D12_DSV_DIMENSION_TEXTURE1DARRAY: SERIALISE_MEMBER(Texture1DArray.MipSlice); SERIALISE_MEMBER(Texture1DArray.FirstArraySlice); SERIALISE_MEMBER(Texture1DArray.ArraySize); break; case D3D12_DSV_DIMENSION_TEXTURE2D: SERIALISE_MEMBER(Texture2D.MipSlice); break; case D3D12_DSV_DIMENSION_TEXTURE2DARRAY: SERIALISE_MEMBER(Texture2DArray.MipSlice); SERIALISE_MEMBER(Texture2DArray.FirstArraySlice); SERIALISE_MEMBER(Texture2DArray.ArraySize); break; case D3D12_DSV_DIMENSION_TEXTURE2DMS: // el.Texture2DMS.UnusedField_NothingToDefine break; case D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY: SERIALISE_MEMBER(Texture2DMSArray.FirstArraySlice); SERIALISE_MEMBER(Texture2DMSArray.ArraySize); break; default: RDCERR("Unrecognised DSV Dimension %d", el.ViewDimension); break; } }
bool WrappedID3D12Device::Serialise_CreateRootSignature(UINT nodeMask, const void *pBlobWithRootSignature, SIZE_T blobLengthInBytes, REFIID riid, void **ppvRootSignature) { SERIALISE_ELEMENT(UINT, mask, nodeMask); SERIALISE_ELEMENT(uint32_t, blobLen, (uint32_t)blobLengthInBytes); SERIALISE_ELEMENT_BUF(byte *, blobBytes, pBlobWithRootSignature, blobLen); SERIALISE_ELEMENT(IID, guid, riid); SERIALISE_ELEMENT(ResourceId, Sig, ((WrappedID3D12RootSignature *)*ppvRootSignature)->GetResourceID()); if(m_State == READING) { ID3D12RootSignature *ret = NULL; HRESULT hr = m_pDevice->CreateRootSignature(mask, blobBytes, blobLen, guid, (void **)&ret); if(FAILED(hr)) { RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); } else { ret = new WrappedID3D12RootSignature(ret, this); WrappedID3D12RootSignature *wrapped = (WrappedID3D12RootSignature *)ret; wrapped->sig = D3D12DebugManager::GetRootSig(blobBytes, blobLen); GetResourceManager()->AddLiveResource(Sig, ret); } } return true; }
bool WrappedID3D12Device::Serialise_CreateFence(UINT64 InitialValue, D3D12_FENCE_FLAGS Flags, REFIID riid, void **ppFence) { SERIALISE_ELEMENT(UINT64, val, InitialValue); SERIALISE_ELEMENT(D3D12_FENCE_FLAGS, flags, Flags); SERIALISE_ELEMENT(IID, guid, riid); SERIALISE_ELEMENT(ResourceId, Fence, ((WrappedID3D12Fence *)*ppFence)->GetResourceID()); if(m_State == READING) { ID3D12Fence *ret = NULL; HRESULT hr = m_pDevice->CreateFence(val, flags, guid, (void **)&ret); if(FAILED(hr)) { RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); } else { ret = new WrappedID3D12Fence(ret, this); GetResourceManager()->AddLiveResource(Fence, ret); } } return true; }
ResourceId ReplayRenderer::BuildCustomShader(const wchar_t *entry, const wchar_t *source, const uint32_t compileFlags, ShaderStageType type, rdctype::wstr *errors) { ResourceId id; string errs; switch(type) { case eShaderStage_Vertex: case eShaderStage_Hull: case eShaderStage_Domain: case eShaderStage_Geometry: case eShaderStage_Pixel: case eShaderStage_Compute: break; default: RDCERR("Unexpected type in BuildShader!"); return ResourceId(); } m_pDevice->BuildCustomShader(narrow(source), narrow(entry), compileFlags, type, &id, &errs); if(id != ResourceId()) m_CustomShaders.insert(id); if(errors) *errors = widen(errs); return id; }
bool WrappedID3D12Device::Serialise_CreateQueryHeap(const D3D12_QUERY_HEAP_DESC *pDesc, REFIID riid, void **ppvHeap) { SERIALISE_ELEMENT(D3D12_QUERY_HEAP_DESC, desc, *pDesc); SERIALISE_ELEMENT(IID, guid, riid); SERIALISE_ELEMENT(ResourceId, QueryHeap, ((WrappedID3D12QueryHeap *)*ppvHeap)->GetResourceID()); if(m_State == READING) { ID3D12QueryHeap *ret = NULL; HRESULT hr = m_pDevice->CreateQueryHeap(&desc, guid, (void **)&ret); if(FAILED(hr)) { RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); } else { ret = new WrappedID3D12QueryHeap(ret, this); GetResourceManager()->AddLiveResource(QueryHeap, ret); } } return true; }
ID3D12GraphicsCommandList *D3D12CommandData::RerecordCmdList(ResourceId cmdid, PartialReplayIndex partialType) { if(m_Partial[Primary].outsideCmdList != NULL) return m_Partial[Primary].outsideCmdList; if(m_DrawcallCallback && m_DrawcallCallback->RecordAllCmds()) { auto it = m_RerecordCmds.find(cmdid); RDCASSERT(it != m_RerecordCmds.end()); return it->second; } if(partialType != ePartialNum) return m_Partial[partialType].resultPartialCmdList; for(int p = 0; p < ePartialNum; p++) if(cmdid == m_Partial[p].partialParent) return m_Partial[p].resultPartialCmdList; RDCERR("Calling re-record for invalid command list id"); return NULL; }
bool CreateHooks(const char *libName) { bool success = true; WrappedIDXGISwapChain3::RegisterD3DDeviceCallback(GetD3D12DeviceIfAlloc); // 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; }
HRESULT WrappedIDXGIFactory::staticCreateSwapChain(IDXGIFactory *factory, IUnknown *pDevice, DXGI_SWAP_CHAIN_DESC *pDesc, IDXGISwapChain **ppSwapChain) { ID3DDevice *wrapDevice = GetD3DDevice(pDevice); if(wrapDevice) { if(!RenderDoc::Inst().GetCaptureOptions().AllowFullscreen && pDesc) { pDesc->Windowed = TRUE; } HRESULT ret = factory->CreateSwapChain(wrapDevice->GetRealIUnknown(), pDesc, ppSwapChain); if(SUCCEEDED(ret)) { *ppSwapChain = new WrappedIDXGISwapChain3(*ppSwapChain, pDesc ? pDesc->OutputWindow : NULL, wrapDevice); } return ret; } RDCERR("Creating swap chain with non-hooked device!"); return factory->CreateSwapChain(pDevice, pDesc, ppSwapChain); }
uint32_t WrappedVulkan::PhysicalDeviceData::GetMemoryIndex(uint32_t resourceRequiredBitmask, uint32_t allocRequiredProps, uint32_t allocUndesiredProps) { uint32_t best = memProps.memoryTypeCount; for(uint32_t memIndex = 0; memIndex < memProps.memoryTypeCount; memIndex++) { if(resourceRequiredBitmask & (1 << memIndex)) { uint32_t memTypeFlags = memProps.memoryTypes[memIndex].propertyFlags; if((memTypeFlags & allocRequiredProps) == allocRequiredProps) { if(memTypeFlags & allocUndesiredProps) best = memIndex; else return memIndex; } } } if(best == memProps.memoryTypeCount) { RDCERR("Couldn't find any matching heap! requirements %x / %x too strict", resourceRequiredBitmask, allocRequiredProps); return 0; } return best; }
static uint64_t GetHandle(WindowingSystem system, void *data) { #if defined(RENDERDOC_PLATFORM_LINUX) if(system == eWindowingSystem_Xlib) return (uint64_t)((XlibWindowData *)data)->window; if(system == eWindowingSystem_XCB) return (uint64_t)((XCBWindowData *)data)->window; RDCERR("Unrecognised window system %d", system); return 0; #elif defined(RENDERDOC_PLATFORM_WIN32) RDCASSERT(system == eWindowingSystem_Win32); return (uint64_t)data; // HWND #elif defined(RENDERDOC_PLATFORM_ANDROID) RDCASSERT(system == eWindowingSystem_Android); return (uint64_t)data; // ANativeWindow * #else RDCFATAL("No windowing data defined for this platform! Must be implemented for replay outputs"); #endif }
ImageViewer(IReplayDriver *proxy, const char *filename) : m_Proxy(proxy), m_Filename(filename), m_TextureID() { if(m_Proxy == NULL) RDCERR("Unexpectedly NULL proxy at creation of ImageViewer"); m_Props.pipelineType = ePipelineState_D3D11; m_Props.degraded = false; m_FrameRecord.frameInfo.fileOffset = 0; m_FrameRecord.frameInfo.firstEvent = 1; m_FrameRecord.frameInfo.frameNumber = 1; m_FrameRecord.frameInfo.immContextId = ResourceId(); RDCEraseEl(m_FrameRecord.frameInfo.stats); create_array_uninit(m_FrameRecord.drawcallList, 1); FetchDrawcall &d = m_FrameRecord.drawcallList[0]; d.context = ResourceId(); d.drawcallID = 1; d.eventID = 1; d.name = filename; RefreshFile(); create_array_uninit(m_PipelineState.m_OM.RenderTargets, 1); m_PipelineState.m_OM.RenderTargets[0].Resource = m_TextureID; }
static HKEY GetImplicitLayersKey(bool writeable, bool wow6432) { std::string basepath = "SOFTWARE\\"; if(wow6432) basepath += "Wow6432Node\\"; basepath += "Khronos\\Vulkan\\ImplicitLayers"; HKEY key = NULL; LSTATUS ret = ERROR_SUCCESS; if(writeable) ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, basepath.c_str(), 0, NULL, 0, KEY_READ | KEY_WRITE, NULL, &key, NULL); else ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, basepath.c_str(), 0, KEY_READ, &key); if(ret != ERROR_SUCCESS) { if(key) RegCloseKey(key); // find to fail to open for read, the key may not exist if(writeable) RDCERR("Couldn't open %s for write", basepath.c_str()); return NULL; } return key; }
void DoSerialise(SerialiserType &ser, D3D12_INDIRECT_ARGUMENT_DESC &el) { SERIALISE_MEMBER(Type); switch(el.Type) { case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW: case D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED: case D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH: case D3D12_INDIRECT_ARGUMENT_TYPE_INDEX_BUFFER_VIEW: // nothing to serialise break; case D3D12_INDIRECT_ARGUMENT_TYPE_VERTEX_BUFFER_VIEW: SERIALISE_MEMBER(VertexBuffer.Slot); break; case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT: SERIALISE_MEMBER(Constant.RootParameterIndex); SERIALISE_MEMBER(Constant.DestOffsetIn32BitValues); SERIALISE_MEMBER(Constant.Num32BitValuesToSet); break; case D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT_BUFFER_VIEW: SERIALISE_MEMBER(ConstantBufferView.RootParameterIndex); break; case D3D12_INDIRECT_ARGUMENT_TYPE_SHADER_RESOURCE_VIEW: SERIALISE_MEMBER(ShaderResourceView.RootParameterIndex); break; case D3D12_INDIRECT_ARGUMENT_TYPE_UNORDERED_ACCESS_VIEW: SERIALISE_MEMBER(UnorderedAccessView.RootParameterIndex); break; default: RDCERR("Unexpected indirect argument type: %u", el.Type); break; } }
void DoSerialise(SerialiserType &ser, D3D12_SHADER_RESOURCE_VIEW_DESC &el) { SERIALISE_MEMBER(Format); SERIALISE_MEMBER(ViewDimension); // cast to a special enum so we print nicely SERIALISE_MEMBER_TYPED(D3D12ComponentMapping, Shader4ComponentMapping); switch(el.ViewDimension) { case D3D12_SRV_DIMENSION_UNKNOWN: // indicates an empty descriptor, which comes from a NULL parameter to Create. break; case D3D12_SRV_DIMENSION_BUFFER: SERIALISE_MEMBER(Buffer); break; case D3D12_SRV_DIMENSION_TEXTURE1D: SERIALISE_MEMBER(Texture1D); break; case D3D12_SRV_DIMENSION_TEXTURE1DARRAY: SERIALISE_MEMBER(Texture1DArray); break; case D3D12_SRV_DIMENSION_TEXTURE2D: SERIALISE_MEMBER(Texture2D); break; case D3D12_SRV_DIMENSION_TEXTURE2DARRAY: SERIALISE_MEMBER(Texture2DArray); break; case D3D12_SRV_DIMENSION_TEXTURE2DMS: SERIALISE_MEMBER(Texture2DMS); break; case D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY: SERIALISE_MEMBER(Texture2DMSArray); break; case D3D12_SRV_DIMENSION_TEXTURE3D: SERIALISE_MEMBER(Texture3D); break; case D3D12_SRV_DIMENSION_TEXTURECUBE: SERIALISE_MEMBER(TextureCube); break; case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY: SERIALISE_MEMBER(TextureCubeArray); break; default: RDCERR("Unrecognised SRV Dimension %d", el.ViewDimension); break; } }