vector<byte> GLReplay::GetBufferData(ResourceId buff, uint32_t offset, uint32_t len) { vector<byte> ret; if(m_pDriver->m_Buffers.find(buff) == m_pDriver->m_Buffers.end()) { RDCWARN("Requesting data for non-existant buffer %llu", buff); return ret; } auto &buf = m_pDriver->m_Buffers[buff]; if(len > 0 && offset+len > buf.size) { RDCWARN("Attempting to read off the end of the array. Will be clamped"); len = RDCMIN(len, uint32_t(buf.size-offset)); } else if(len == 0) { len = (uint32_t)buf.size; } ret.resize(len); WrappedOpenGL &gl = *m_pDriver; MakeCurrentReplayContext(m_DebugCtx); gl.glBindBuffer(eGL_COPY_READ_BUFFER, buf.resource.name); gl.glGetBufferSubData(eGL_COPY_READ_BUFFER, (GLintptr)offset, (GLsizeiptr)len, &ret[0]); return ret; }
Socket *CreateServerSocket(const char *bindaddr, uint16_t port, int queuesize) { SOCKET s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT); if(s == INVALID_SOCKET) return NULL; sockaddr_in addr; RDCEraseEl(addr); addr.sin_family = AF_INET; inet_pton(AF_INET, bindaddr, &addr.sin_addr); addr.sin_port = htons(port); int result = bind(s, (SOCKADDR *)&addr, sizeof(addr)); if(result == SOCKET_ERROR) { RDCWARN("Failed to bind to %s:%d - %d", bindaddr, port, WSAGetLastError()); closesocket(s); return NULL; } result = listen(s, queuesize); if(result == SOCKET_ERROR) { RDCWARN("Failed to listen on %s:%d - %d", bindaddr, port, WSAGetLastError()); closesocket(s); return NULL; } u_long nonblock = 1; ioctlsocket(s, FIONBIO, &nonblock); return new Socket((ptrdiff_t)s); }
HRESULT STDMETHODCALLTYPE WrappedID3D11DeviceContext::QueryInterface( REFIID riid, void **ppvObject ) { HRESULT hr = S_OK; if(riid == __uuidof(ID3D11DeviceContext)) { *ppvObject = (ID3D11DeviceContext *)this; AddRef(); return S_OK; } else if(riid == __uuidof(ID3D11DeviceChild)) { *ppvObject = (ID3D11DeviceChild *)this; AddRef(); return S_OK; } #if defined(INCLUDE_D3D_11_1) else if(riid == __uuidof(ID3D11DeviceContext1)) { if(m_pRealContext1) { *ppvObject = (ID3D11DeviceContext1 *)this; AddRef(); return S_OK; } else { return E_NOINTERFACE; } } else if(riid == __uuidof(ID3D11DeviceContext2)) { if(m_pRealContext2) { *ppvObject = (ID3D11DeviceContext2 *)this; AddRef(); RDCWARN("Trying to get ID3D11DeviceContext2. DX11.2 tiled resources are not supported at this time."); return S_OK; } else { return E_NOINTERFACE; } } else if(riid == __uuidof(ID3DUserDefinedAnnotation)) { *ppvObject = (ID3DUserDefinedAnnotation *)&m_UserAnnotation; m_UserAnnotation.AddRef(); return S_OK; } #endif else { string guid = ToStr::Get(riid); RDCWARN("Querying ID3D11DeviceContext for interface: %s", guid.c_str()); } return RefCounter::QueryInterface(riid, ppvObject); }
wstring UTF82Wide(const string &s) { int chars_required = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0); if(chars_required == 0) return L""; wstring ret; ret.resize(chars_required); int res = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, &ret[0], chars_required); if(ret.back() == 0) ret.pop_back(); if(res == 0) { #if !defined(_RELEASE) RDCWARN("Failed to convert utf-8 string"); // can't pass string through as this would // infinitely recurse #endif return L""; } return ret; }
HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice3::QueryInterface( REFIID riid, void **ppvObject ) { if(riid == __uuidof(ID3D11Device)) { m_pD3DDevice->AddRef(); *ppvObject = m_pD3DDevice; return S_OK; } else if(riid == __uuidof(IDXGIDevice1)) { AddRef(); *ppvObject = (IDXGIDevice1 *)this; return S_OK; } else if(riid == __uuidof(IDXGIDevice2)) { AddRef(); *ppvObject = (IDXGIDevice2 *)this; return S_OK; } else if(riid == __uuidof(IDXGIDevice3)) { AddRef(); *ppvObject = (IDXGIDevice3 *)this; return S_OK; } else { string guid = ToStr::Get(riid); RDCWARN("Querying IDXGIDevice3 for interface: %s", guid.c_str()); } return RefCountDXGIObject::QueryInterface(riid, ppvObject); }
string Wide2UTF8(const wstring &s) { int bytes_required = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, NULL, 0, NULL, NULL); if(bytes_required == 0) return ""; string ret; ret.resize(bytes_required); int res = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, &ret[0], bytes_required, NULL, NULL); if(ret.back() == 0) ret.pop_back(); if(res == 0) { #if !defined(_RELEASE) RDCWARN("Failed to convert wstring"); // can't pass string through as this would infinitely // recurse #endif return ""; } return ret; }
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); }
bool Socket::IsRecvDataWaiting() { char dummy; int ret = recv(socket, &dummy, 1, MSG_PEEK); if(ret == 0) { Shutdown(); return false; } else if(ret <= 0) { int err = WSAGetLastError(); if(err == WSAEWOULDBLOCK) { ret = 0; } else { RDCWARN("recv: %d", err); Shutdown(); return false; } } return ret > 0; }
void VulkanCreationInfo::ShaderModule::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkShaderModuleCreateInfo* pCreateInfo) { const uint32_t SPIRVMagic = 0x07230203; if(pCreateInfo->codeSize < 4 || memcmp(pCreateInfo->pCode, &SPIRVMagic, sizeof(SPIRVMagic))) { RDCWARN("Shader not provided with SPIR-V"); } else { static const unsigned int MagicNumber = 0x07230203; // SPIR-V magic number // is the SPIR-V version 0? assume GLSL if(pCreateInfo->pCode[0] == MagicNumber && pCreateInfo->pCode[1] == 0) { // GLSL - compile to SPIR-V ourselves const char *src = (const char *)(pCreateInfo->pCode+3); vector<string> srcs; srcs.push_back(src); vector<uint32_t> spirv_code; string ret = CompileSPIRV((SPIRVShaderStage)StageIndex((VkShaderStageFlagBits)pCreateInfo->pCode[2]), srcs, spirv_code); ParseSPIRV(&spirv_code[0], spirv_code.size(), spirv); } else { RDCASSERT(pCreateInfo->codeSize % sizeof(uint32_t) == 0); ParseSPIRV((uint32_t *)pCreateInfo->pCode, pCreateInfo->codeSize/sizeof(uint32_t), spirv); } } }
void CacheDebuggerPresent() { FILE *f = FileIO::fopen("/proc/self/status", "r"); int ret = 0; if(f == NULL) { RDCWARN("Couldn't open /proc/self/status"); return; } // read through the proc file to check for TracerPid while(ret == 0 && !feof(f)) { const size_t sz = 512; char line[sz]; line[sz - 1] = 0; fgets(line, sz - 1, f); int tracerpid = 0; int num = sscanf(line, "TracerPid: %d", &tracerpid); // found TracerPid line if(num == 1) { debuggerPresent = (tracerpid != 0); break; } } FileIO::fclose(f); }
Socket *Socket::AcceptClient(bool wait) { do { int s = accept(socket, NULL, NULL); if(s != -1) { int flags = fcntl(s, F_GETFL, 0); fcntl(s, F_SETFL, flags | O_NONBLOCK); int nodelay = 1; setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, sizeof(nodelay)); return new Socket((ptrdiff_t)s); } int err = errno; if(err != EWOULDBLOCK) { RDCWARN("accept: %d", err); Shutdown(); } Threading::Sleep(4); } while(wait); return NULL; }
Socket *Socket::AcceptClient(bool wait) { do { SOCKET s = accept(socket, NULL, NULL); if(s != INVALID_SOCKET) { u_long enable = 1; ioctlsocket(s, FIONBIO, &enable); BOOL nodelay = TRUE; setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay)); return new Socket((ptrdiff_t)s); } int err = WSAGetLastError(); if(err != WSAEWOULDBLOCK) { RDCWARN("accept: %d", err); Shutdown(); } Threading::Sleep(4); } while(wait); return NULL; }
HRESULT STDMETHODCALLTYPE WrappedID3D11DeviceContext::QueryInterface( REFIID riid, void **ppvObject ) { //DEFINE_GUID(IID_ID3D11DeviceContext2,0x420d5b32,0xb90c,0x4da4,0xbe,0xf0,0x35,0x9f,0x6a,0x24,0xa8,0x3a); static const GUID ID3D11DeviceContext2_uuid = { 0x420d5b32, 0xb90c, 0x4da4, { 0xbe, 0xf0, 0x35, 0x9f, 0x6a, 0x24, 0xa8, 0x3a } }; if(riid == __uuidof(ID3D11DeviceContext)) { *ppvObject = (ID3D11DeviceContext *)this; AddRef(); return S_OK; } else if(riid == __uuidof(ID3D11DeviceChild)) { *ppvObject = (ID3D11DeviceChild *)this; AddRef(); return S_OK; } #if defined(INCLUDE_D3D_11_1) else if(riid == __uuidof(ID3D11DeviceContext1)) { *ppvObject = (ID3D11DeviceContext1 *)this; AddRef(); return S_OK; } else if(riid == __uuidof(ID3DUserDefinedAnnotation)) { *ppvObject = (ID3DUserDefinedAnnotation *)&m_UserAnnotation; m_UserAnnotation.AddRef(); return S_OK; } #endif else if(riid == ID3D11DeviceContext2_uuid) { RDCWARN("Trying to get ID3D11DeviceContext2. DX11.2 not supported at this time."); *ppvObject = NULL; return E_NOINTERFACE; } else { string guid = ToStr::Get(riid); RDCWARN("Querying ID3D11DeviceContext for interface: %hs", guid.c_str()); } return RefCounter::QueryInterface(riid, ppvObject); }
unsigned int RefCounter8::SoftRelease(WrappedD3DDevice8 *device) { unsigned int ret = Release(); if(device) device->SoftRelease(); else RDCWARN("No device pointer, is a deleted resource being Release()d?"); return ret; }
void logfile_close(const char *filename) { if(logfileFD >= 0) { // release our shared lock int err = flock(logfileFD, LOCK_UN | LOCK_NB); if(err == 0 && filename) { // now try to acquire an exclusive lock. If this succeeds, no other processes are using the // file (since no other shared locks exist), so we can delete it. If it fails, some other // shared lock still exists so we can just close our fd and exit. // NOTE: there is a race here between acquiring the exclusive lock and unlinking, but we // aren't interested in this kind of race - we're interested in whether an application is // still running when the UI closes, or vice versa, or similar cases. err = flock(logfileFD, LOCK_EX | LOCK_NB); if(err == 0) { // we got the exclusive lock. Now release it, close fd, and unlink the file err = flock(logfileFD, LOCK_UN | LOCK_NB); // can't really error handle here apart from retrying if(err != 0) RDCWARN("Couldn't release exclusive lock to %s: %d", filename, (int)errno); close(logfileFD); unlink(filename); // return immediately so we don't close again below. return; } } else { RDCWARN("Couldn't release shared lock to %s: %d", filename, (int)errno); // nothing to do, we won't try again, just exit. The log might lie around, but that's // relatively harmless. } close(logfileFD); } }
HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice1::QueryInterface( REFIID riid, void **ppvObject ) { HRESULT hr = S_OK; if(riid == __uuidof(ID3D11Device)) { m_pD3DDevice->AddRef(); *ppvObject = m_pD3DDevice; return S_OK; } else if(riid == __uuidof(IDXGIDevice1)) { AddRef(); *ppvObject = (IDXGIDevice1 *)this; return S_OK; } #if defined(INCLUDE_DXGI_1_2) else if(riid == __uuidof(IDXGIDevice2)) { hr = m_pReal->QueryInterface(riid, ppvObject); if(SUCCEEDED(hr)) { IDXGIDevice2 *real = (IDXGIDevice2 *)(*ppvObject); *ppvObject = new WrappedIDXGIDevice2(real, m_pD3DDevice); return S_OK; } else { return E_NOINTERFACE; } } else if(riid == __uuidof(IDXGIDevice3)) { hr = m_pReal->QueryInterface(riid, ppvObject); if(SUCCEEDED(hr)) { IDXGIDevice3 *real = (IDXGIDevice3 *)(*ppvObject); *ppvObject = new WrappedIDXGIDevice3(real, m_pD3DDevice); return S_OK; } else { return E_NOINTERFACE; } } #endif else { string guid = ToStr::Get(riid); RDCWARN("Querying IDXGIDevice1 for interface: %s", guid.c_str()); } return RefCountDXGIObject::QueryInterface(riid, ppvObject); }
static void GPA_LoggingCallback(GPA_Logging_Type messageType, const char *pMessage) { if(messageType == GPA_LOGGING_ERROR) { RDCWARN(pMessage); } else { RDCLOG(pMessage); } }
bool Socket::RecvDataBlocking(void *buf, uint32_t length) { if(length == 0) return true; uint32_t received = 0; char *dst = (char *)buf; u_long enable = 0; ioctlsocket(socket, FIONBIO, &enable); DWORD timeout = 3000; setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)); while(received < length) { int ret = recv(socket, dst, length-received, 0); if(ret == 0) { Shutdown(); return false; } else if(ret <= 0) { int err = WSAGetLastError(); if(err == WSAEWOULDBLOCK) { ret = 0; } else { RDCWARN("recv: %d", err); Shutdown(); return false; } } received += ret; dst += ret; } enable = 1; ioctlsocket(socket, FIONBIO, &enable); timeout = 600000; setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)); RDCASSERT(received == length); return true; }
bool logfile_open(const char *filename) { logfileFD = open(filename, O_APPEND | O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // acquire a shared lock. Every process acquires a shared lock to the common logfile. Each time a // process shuts down and wants to close the logfile, it releases its shared lock and tries to // acquire an exclusive lock, to see if it can delete the file. See logfile_close. int err = flock(logfileFD, LOCK_SH | LOCK_NB); if(err < 0) RDCWARN("Couldn't acquire shared lock to %s: %d", filename, (int)errno); return logfileFD >= 0; }
Socket *CreateServerSocket(const char *bindaddr, uint16_t port, int queuesize) { int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(s == -1) return NULL; sockaddr_in addr; RDCEraseEl(addr); hostent *hp = gethostbyname(bindaddr); addr.sin_family = AF_INET; memcpy(&addr.sin_addr, hp->h_addr, hp->h_length); addr.sin_port = htons(port); int result = bind(s, (sockaddr *)&addr, sizeof(addr)); if(result == -1) { RDCWARN("Failed to bind to %s:%d - %d", bindaddr, port, errno); close(s); return NULL; } result = listen(s, queuesize); if(result == -1) { RDCWARN("Failed to listen on %s:%d - %d", bindaddr, port, errno); close(s); return NULL; } int flags = fcntl(s, F_GETFL, 0); fcntl(s, F_SETFL, flags | O_NONBLOCK); return new Socket((ptrdiff_t)s); }
VkResult WrappedVulkan::vkCreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkPipelineCache *pPipelineCache) { // pretend the user didn't provide any cache data VkPipelineCacheCreateInfo createInfo = *pCreateInfo; createInfo.initialDataSize = 0; createInfo.pInitialData = NULL; if(pCreateInfo->initialDataSize > 0) { RDCWARN( "Application provided pipeline cache data! This is invalid, as RenderDoc reports " "incompatibility with previous caches"); } VkResult ret = ObjDisp(device)->CreatePipelineCache(Unwrap(device), &createInfo, pAllocator, pPipelineCache); if(ret == VK_SUCCESS) { ResourceId id = GetResourceManager()->WrapResource(Unwrap(device), *pPipelineCache); if(m_State >= WRITING) { Chunk *chunk = NULL; { CACHE_THREAD_SERIALISER(); SCOPED_SERIALISE_CONTEXT(CREATE_PIPE_CACHE); Serialise_vkCreatePipelineCache(localSerialiser, device, &createInfo, NULL, pPipelineCache); chunk = scope.Get(); } VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pPipelineCache); record->AddChunk(chunk); } else { GetResourceManager()->AddLiveResource(id, *pPipelineCache); } } return ret; }
void VulkanCreationInfo::ShaderModule::Init(VulkanResourceManager *resourceMan, VulkanCreationInfo &info, const VkShaderModuleCreateInfo *pCreateInfo) { const uint32_t SPIRVMagic = 0x07230203; if(pCreateInfo->codeSize < 4 || memcmp(pCreateInfo->pCode, &SPIRVMagic, sizeof(SPIRVMagic))) { RDCWARN("Shader not provided with SPIR-V"); } else { RDCASSERT(pCreateInfo->codeSize % sizeof(uint32_t) == 0); ParseSPIRV((uint32_t *)pCreateInfo->pCode, pCreateInfo->codeSize / sizeof(uint32_t), spirv); } }
bool Socket::SendDataBlocking(const void *buf, uint32_t length) { if(length == 0) return true; uint32_t sent = 0; char *src = (char *)buf; u_long enable = 0; ioctlsocket(socket, FIONBIO, &enable); DWORD timeout = 3000; setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)); while(sent < length) { int ret = send(socket, src, length-sent, 0); if(ret <= 0) { int err = WSAGetLastError(); if(err == WSAEWOULDBLOCK) { ret = 0; } else { RDCWARN("send: %d", err); Shutdown(); return false; } } sent += ret; src += ret; } enable = 1; ioctlsocket(socket, FIONBIO, &enable); timeout = 600000; setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)); RDCASSERT(sent == length); return true; }
HRESULT WrappedIDXGIFactory2::staticCreateSwapChainForCoreWindow( IDXGIFactory2 *factory, IUnknown *pDevice, IUnknown *pWindow, const DXGI_SWAP_CHAIN_DESC1 *pDesc, IDXGIOutput *pRestrictToOutput, IDXGISwapChain1 **ppSwapChain) { if(WrappedID3D11Device::IsAlloc(pDevice) || WrappedIDXGIDevice::IsAlloc(pDevice) || WrappedIDXGIDevice1::IsAlloc(pDevice) || WrappedIDXGIDevice2::IsAlloc(pDevice) || WrappedIDXGIDevice3::IsAlloc(pDevice) ) { 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) { RDCWARN("Impossible to disallow fullscreen on call to CreateSwapChainForCoreWindow"); } HRESULT ret = factory->CreateSwapChainForCoreWindow(wrapDevice->GetReal(), pWindow, pDesc, pRestrictToOutput, ppSwapChain); if(SUCCEEDED(ret)) { HWND wnd = NULL; (*ppSwapChain)->GetHwnd(&wnd); *ppSwapChain = new WrappedIDXGISwapChain2(*ppSwapChain, wnd, wrapDevice); } return ret; } else { RDCERR("Creating swap chain with non-hooked device!"); } return factory->CreateSwapChainForCoreWindow(pDevice, pWindow, pDesc, pRestrictToOutput, ppSwapChain); }
static TextureSwizzle Convert(VkComponentSwizzle s, int i) { switch(s) { default: RDCWARN("Unexpected component swizzle value %d", (int)s); case VK_COMPONENT_SWIZZLE_IDENTITY: break; case VK_COMPONENT_SWIZZLE_ZERO: return TextureSwizzle::Zero; case VK_COMPONENT_SWIZZLE_ONE: return TextureSwizzle::One; case VK_COMPONENT_SWIZZLE_R: return TextureSwizzle::Red; case VK_COMPONENT_SWIZZLE_G: return TextureSwizzle::Green; case VK_COMPONENT_SWIZZLE_B: return TextureSwizzle::Blue; case VK_COMPONENT_SWIZZLE_A: return TextureSwizzle::Alpha; } return TextureSwizzle(uint32_t(TextureSwizzle::Red) + i); }
bool Socket::RecvDataBlocking(void *buf, uint32_t length) { if(length == 0) return true; uint32_t received = 0; char *dst = (char *)buf; int flags = fcntl(socket, F_GETFL, 0); fcntl(socket, F_SETFL, flags & ~O_NONBLOCK); while(received < length) { int ret = recv(socket, dst, length-received, 0); if(ret == 0) { Shutdown(); return false; } else if(ret <= 0) { int err = errno; if(err == EWOULDBLOCK) { ret = 0; } else { RDCWARN("recv: %d", err); Shutdown(); return false; } } received += ret; dst += ret; } flags = fcntl(socket, F_GETFL, 0); fcntl(socket, F_SETFL, flags | O_NONBLOCK); RDCASSERT(received == length); return true; }
HRESULT STDMETHODCALLTYPE WrappedID3D12GraphicsCommandList::QueryInterface(REFIID riid, void **ppvObject) { if(riid == __uuidof(IUnknown)) { *ppvObject = (IUnknown *)(ID3D12GraphicsCommandList *)this; AddRef(); return S_OK; } else if(riid == __uuidof(ID3D12GraphicsCommandList)) { *ppvObject = (ID3D12GraphicsCommandList *)this; AddRef(); return S_OK; } else if(riid == __uuidof(ID3D12CommandList)) { *ppvObject = (ID3D12CommandList *)this; AddRef(); return S_OK; } else if(riid == __uuidof(ID3D12Pageable)) { *ppvObject = (ID3D12Pageable *)this; AddRef(); return S_OK; } else if(riid == __uuidof(ID3D12DeviceChild)) { *ppvObject = (ID3D12DeviceChild *)this; AddRef(); return S_OK; } else if(riid == __uuidof(ID3D12Object)) { *ppvObject = (ID3D12DeviceChild *)this; AddRef(); return S_OK; } else { string guid = ToStr::Get(riid); RDCWARN("Querying ID3D12GraphicsCommandList for interface: %s", guid.c_str()); } return RefCounter12::QueryInterface(riid, ppvObject); }
string Wide2UTF8(const std::wstring &s) { // include room for null terminator, assuming unicode input (not ucs) // utf-8 characters can be max 4 bytes. size_t len = (s.length()+1)*4; vector<char> charBuffer; if(charBuffer.size() < len) charBuffer.resize(len); size_t ret; { SCOPED_LOCK(lockWide2UTF8); if(iconvWide2UTF8 == (iconv_t)-1) iconvWide2UTF8 = iconv_open("UTF-8", "WCHAR_T"); if(iconvWide2UTF8 == (iconv_t)-1) { RDCERR("Couldn't open iconv for WCHAR_T to UTF-8: %d", errno); return ""; } char *inbuf = (char *)s.c_str(); size_t insize = (s.length()+1)*sizeof(wchar_t); // include null terminator char *outbuf = &charBuffer[0]; size_t outsize = len; ret = iconv(iconvWide2UTF8, &inbuf, &insize, &outbuf, &outsize); } if(ret == (size_t)-1) { #if !defined(_RELEASE) RDCWARN("Failed to convert wstring"); #endif return ""; } // convert to string from null-terminated string - utf-8 never contains // 0 bytes before the null terminator, and this way we don't care if // charBuffer is larger than the string return string(&charBuffer[0]); }
HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain2::QueryInterface(REFIID riid, void **ppvObject) { if(riid == __uuidof(IDXGISwapChain)) { AddRef(); *ppvObject = (IDXGISwapChain *)this; return S_OK; } #if defined(INCLUDE_DXGI_1_2) else if(riid == __uuidof(IDXGISwapChain1)) { if(m_pReal1) { AddRef(); *ppvObject = (IDXGISwapChain1 *)this; return S_OK; } else { return E_NOINTERFACE; } } else if(riid == __uuidof(IDXGISwapChain2)) { if(m_pReal2) { AddRef(); *ppvObject = (IDXGISwapChain2 *)this; return S_OK; } else { return E_NOINTERFACE; } } #endif else { string guid = ToStr::Get(riid); RDCWARN("Querying IDXGISwapChain for interface: %s", guid.c_str()); } return RefCountDXGIObject::QueryInterface(riid, ppvObject); }
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 = (ID3D12Debug *)(new WrappedID3D12Debug()); return S_OK; }