vector<ResourceId> D3D12RenderState::GetRTVIDs() const { vector<ResourceId> ret; if(rtSingle) { if(!rts.empty()) { const D3D12Descriptor *descs = DescriptorFromPortableHandle(GetResourceManager(), rts[0]); for(UINT i = 0; i < rts.size(); i++) { RDCASSERT(descs[i].GetType() == D3D12Descriptor::TypeRTV); ret.push_back(GetResID(descs[i].nonsamp.resource)); } } } else { for(UINT i = 0; i < rts.size(); i++) { WrappedID3D12DescriptorHeap *heap = GetResourceManager()->GetLiveAs<WrappedID3D12DescriptorHeap>(rts[0].heap); const D3D12Descriptor &desc = heap->GetDescriptors()[rts[i].index]; RDCASSERT(desc.GetType() == D3D12Descriptor::TypeRTV); ret.push_back(GetResID(desc.nonsamp.resource)); } } return ret; }
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 }
void WrappedOpenGL::glGenerateMipmap(GLenum target) { m_Real.glGenerateMipmap(target); ResourceRecord *record = m_TextureRecord[m_TextureUnit]; RDCASSERT(record); if(!record) return; GLuint texture = GetResourceManager()->GetCurrentResource(record->GetResourceID()).name; if(m_State == WRITING_CAPFRAME) { SCOPED_SERIALISE_CONTEXT(GENERATE_MIPMAP); Serialise_glGenerateTextureMipmapEXT(texture, target); m_ContextRecord->AddChunk(scope.Get()); } else if(m_State == WRITING_IDLE) { SCOPED_SERIALISE_CONTEXT(GENERATE_MIPMAP); Serialise_glGenerateTextureMipmapEXT(texture, target); RDCASSERT(record); if(record) record->AddChunk(scope.Get()); } }
VkResult WrappedVulkan::vkMapMemory( VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData) { void *realData = NULL; VkResult ret = ObjDisp(device)->MapMemory(Unwrap(device), Unwrap(mem), offset, size, flags, &realData); if(ret == VK_SUCCESS && realData) { ResourceId id = GetResID(mem); if(m_State >= WRITING) { VkResourceRecord *memrecord = GetRecord(mem); // must have map state, only non host visible memories have no map // state, and they can't be mapped! RDCASSERT(memrecord->memMapState); MemMapState &state = *memrecord->memMapState; // ensure size is valid RDCASSERT(size == VK_WHOLE_SIZE || (size > 0 && size <= memrecord->Length)); state.mappedPtr = (byte *)realData; state.refData = NULL; state.mapOffset = offset; state.mapSize = size == VK_WHOLE_SIZE ? memrecord->Length : size; state.mapFlushed = false; *ppData = realData; if(state.mapCoherent) { SCOPED_LOCK(m_CoherentMapsLock); m_CoherentMaps.push_back(memrecord); } } else { *ppData = realData; } } else { *ppData = NULL; } return ret; }
bool ReplayOutput::AddThumbnail(WindowingSystem system, void *data, ResourceId texID, FormatComponentType typeHint) { OutputPair p; RDCASSERT(data); bool depthMode = false; for(size_t t = 0; t < m_pRenderer->m_Textures.size(); t++) { if(m_pRenderer->m_Textures[t].ID == texID) { depthMode = (m_pRenderer->m_Textures[t].creationFlags & eTextureCreate_DSV) > 0; depthMode |= (m_pRenderer->m_Textures[t].format.compType == eCompType_Depth); break; } } for(size_t i = 0; i < m_Thumbnails.size(); i++) { if(m_Thumbnails[i].wndHandle == GetHandle(system, data)) { m_Thumbnails[i].texture = texID; m_Thumbnails[i].depthMode = depthMode; m_Thumbnails[i].typeHint = typeHint; m_Thumbnails[i].dirty = true; return true; } } p.wndHandle = GetHandle(system, data); p.outputID = m_pDevice->MakeOutputWindow(system, data, false); p.texture = texID; p.depthMode = depthMode; p.typeHint = typeHint; p.dirty = true; RDCASSERT(p.outputID > 0); m_Thumbnails.push_back(p); return true; }
void D3D12CommandData::InsertDrawsAndRefreshIDs(vector<D3D12DrawcallTreeNode> &cmdBufNodes) { // assign new drawcall IDs for(size_t i = 0; i < cmdBufNodes.size(); i++) { if(cmdBufNodes[i].draw.flags & eDraw_PopMarker) { RDCASSERT(GetDrawcallStack().size() > 1); if(GetDrawcallStack().size() > 1) GetDrawcallStack().pop_back(); // Skip - pop marker draws aren't processed otherwise, we just apply them to the drawcall // stack. continue; } D3D12DrawcallTreeNode n = cmdBufNodes[i]; n.draw.eventID += m_RootEventID; n.draw.drawcallID += m_RootDrawcallID; for(int32_t e = 0; e < n.draw.events.count; e++) { n.draw.events[e].eventID += m_RootEventID; m_Events.push_back(n.draw.events[e]); } DrawcallUse use(m_Events.back().fileOffset, n.draw.eventID); // insert in sorted location auto drawit = std::lower_bound(m_DrawcallUses.begin(), m_DrawcallUses.end(), use); m_DrawcallUses.insert(drawit, use); RDCASSERT(n.children.empty()); for(auto it = n.resourceUsage.begin(); it != n.resourceUsage.end(); ++it) { EventUsage u = it->second; u.eventID += m_RootEventID; m_ResourceUses[it->first].push_back(u); } GetDrawcallStack().back()->children.push_back(n); // if this is a push marker too, step down the drawcall stack if(cmdBufNodes[i].draw.flags & eDraw_PushMarker) GetDrawcallStack().push_back(&GetDrawcallStack().back()->children.back()); } }
bool WrappedVulkan::Serialise_vkGetSwapchainImagesKHR( Serialiser* localSerialiser, VkDevice device, VkSwapchainKHR swapchain, uint32_t* pCount, VkImage* pSwapchainImages) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(ResourceId, swapId, GetResID(swapchain)); SERIALISE_ELEMENT(uint32_t, idx, *pCount); SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSwapchainImages)); if(m_State == READING) { // use original ID because we don't create a live version of the swapchain auto &swapInfo = m_CreationInfo.m_SwapChain[swapId]; RDCASSERT(idx < swapInfo.images.size(), idx, swapInfo.images.size()); GetResourceManager()->AddLiveResource(id, swapInfo.images[idx].im); m_CreationInfo.m_Image[GetResID(swapInfo.images[idx].im)] = m_CreationInfo.m_Image[swapId]; } return true; }
FetchDrawcall *ReplayRenderer::SetupDrawcallPointers(FetchFrameInfo frame, rdctype::array<FetchDrawcall> &draws, FetchDrawcall *parent, FetchDrawcall *previous) { FetchDrawcall *ret = NULL; for(int32_t i=0; i < draws.count; i++) { FetchDrawcall *draw = &draws[i]; draw->parent = parent ? parent->drawcallID : 0; if(draw->children.count > 0) { ret = previous = SetupDrawcallPointers(frame, draw->children, draw, previous); } else if(draw->flags & (eDraw_PushMarker|eDraw_SetMarker|eDraw_Present)) { // don't want to set up previous/next links for markers } else { if(previous != NULL) previous->next = draw->drawcallID; draw->previous = previous ? previous->drawcallID : 0; RDCASSERT(m_Drawcalls.empty() || draw->eventID > m_Drawcalls.back()->eventID || draw->context != frame.immContextId); m_Drawcalls.resize(RDCMAX(m_Drawcalls.size(), size_t(draw->drawcallID+1))); m_Drawcalls[draw->drawcallID] = draw; ret = previous = draw; } } return ret; }
//----------------------------------------------------------------------------------------------------------------- GLenum GetInternalFormat(ovrTextureFormat ovr_format) { GLenum internalFormat = eGL_RGBA8; GLenum conversion_table[] = { eGL_RGBA8, // VRAPI_TEXTURE_FORMAT_NONE, eGL_RGB565, // VRAPI_TEXTURE_FORMAT_565, eGL_RGB5_A1, // VRAPI_TEXTURE_FORMAT_5551, eGL_RGBA4, // VRAPI_TEXTURE_FORMAT_4444, eGL_RGBA8, // VRAPI_TEXTURE_FORMAT_8888, eGL_SRGB8_ALPHA8, // VRAPI_TEXTURE_FORMAT_8888_sRGB, eGL_RGBA16F, // VRAPI_TEXTURE_FORMAT_RGBA16F, eGL_DEPTH_COMPONENT16, // VRAPI_TEXTURE_FORMAT_DEPTH_16, eGL_DEPTH_COMPONENT24, // VRAPI_TEXTURE_FORMAT_DEPTH_24, eGL_DEPTH24_STENCIL8 // VRAPI_TEXTURE_FORMAT_DEPTH_24_STENCIL_8, }; RDCASSERT(ovr_format < ARRAY_COUNT(conversion_table)); if(ovr_format < ARRAY_COUNT(conversion_table)) { internalFormat = conversion_table[ovr_format]; } return internalFormat; }
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; }
void WrappedOpenGL::glCreateProgramPipelines(GLsizei n, GLuint *pipelines) { m_Real.glCreateProgramPipelines(n, pipelines); for(GLsizei i = 0; i < n; i++) { GLResource res = ProgramPipeRes(GetCtx(), pipelines[i]); ResourceId id = GetResourceManager()->RegisterResource(res); if(m_State >= WRITING) { Chunk *chunk = NULL; { SCOPED_SERIALISE_CONTEXT(CREATE_PROGRAMPIPE); Serialise_glCreateProgramPipelines(1, pipelines + i); chunk = scope.Get(); } GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); RDCASSERT(record); record->AddChunk(chunk); } else { GetResourceManager()->AddLiveResource(id, res); } } }
VkResult WrappedVulkan::vkCreateDisplayPlaneSurfaceKHR(VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { // should not come in here at all on replay RDCASSERT(m_State >= WRITING); VkResult ret = ObjDisp(instance)->CreateDisplayPlaneSurfaceKHR(Unwrap(instance), pCreateInfo, pAllocator, pSurface); if(ret == VK_SUCCESS) { // we must wrap surfaces to be consistent with the rest of the code and surface handling, // but there's nothing actually to do here - no meaningful data we care about here. GetResourceManager()->WrapResource(Unwrap(instance), *pSurface); WrappedVkSurfaceKHR *wrapped = GetWrapped(*pSurface); // we don't have an actual OS handle to identify this window. Instead construct something // that should be unique and hopefully not clashing/overlapping with other window handles // in use. uintptr_t fakeWindowHandle; fakeWindowHandle = (uintptr_t)NON_DISP_TO_UINT64(pCreateInfo->displayMode); fakeWindowHandle += pCreateInfo->planeIndex; fakeWindowHandle += pCreateInfo->planeStackIndex << 4; // since there's no point in allocating a full resource record and storing the window // handle under there somewhere, we just cast. We won't use the resource record for anything wrapped->record = (VkResourceRecord *)fakeWindowHandle; } return ret; }
VkResult WrappedVulkan::vkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) { // should not come in here at all on replay RDCASSERT(m_State >= WRITING); VkResult ret = ObjDisp(instance)->CreateWin32SurfaceKHR(Unwrap(instance), pCreateInfo, pAllocator, pSurface); if(ret == VK_SUCCESS) { GetResourceManager()->WrapResource(Unwrap(instance), *pSurface); WrappedVkSurfaceKHR *wrapped = GetWrapped(*pSurface); // since there's no point in allocating a full resource record and storing the window // handle under there somewhere, we just cast. We won't use the resource record for anything wrapped->record = (VkResourceRecord *)pCreateInfo->hwnd; Keyboard::AddInputWindow((void *)pCreateInfo->hwnd); } return ret; }
void WrappedOpenGL::glGenTextures(GLsizei n, GLuint* textures) { m_Real.glGenTextures(n, textures); for(GLsizei i=0; i < n; i++) { GLResource res = TextureRes(textures[i]); ResourceId id = GetResourceManager()->RegisterResource(res); if(m_State >= WRITING) { Chunk *chunk = NULL; { SCOPED_SERIALISE_CONTEXT(GEN_TEXTURE); Serialise_glGenTextures(1, textures+i); chunk = scope.Get(); } GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); RDCASSERT(record); record->AddChunk(chunk); } else { GetResourceManager()->AddLiveResource(id, res); m_Textures[id].resource = res; m_Textures[id].curType = eGL_UNKNOWN_ENUM; } } }
void WrappedOpenGL::glLinkProgram(GLuint program) { m_Real.glLinkProgram(program); if(m_State >= WRITING) { GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); RDCASSERT(record); { SCOPED_SERIALISE_CONTEXT(LINKPROGRAM); Serialise_glLinkProgram(program); record->AddChunk(scope.Get()); } } else { ResourceId progid = GetResourceManager()->GetID(ProgramRes(GetCtx(), program)); ProgramData &progDetails = m_Programs[progid]; progDetails.linked = true; for(size_t s = 0; s < 6; s++) { for(size_t sh = 0; sh < progDetails.shaders.size(); sh++) { if(m_Shaders[progDetails.shaders[sh]].type == ShaderEnum(s)) progDetails.stageShaders[s] = progDetails.shaders[sh]; } } } }
GLuint WrappedOpenGL::glCreateProgram() { GLuint real = m_Real.glCreateProgram(); GLResource res = ProgramRes(GetCtx(), real); ResourceId id = GetResourceManager()->RegisterResource(res); if(m_State >= WRITING) { Chunk *chunk = NULL; { SCOPED_SERIALISE_CONTEXT(CREATE_PROGRAM); Serialise_glCreateProgram(real); chunk = scope.Get(); } GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); RDCASSERT(record); // we always want to mark programs as dirty so we can serialise their // locations as initial state (and form a remapping table) GetResourceManager()->MarkDirtyResource(id); record->AddChunk(chunk); } else { GetResourceManager()->AddLiveResource(id, res); } return real; }
void WrappedOpenGL::glAttachShader(GLuint program, GLuint shader) { m_Real.glAttachShader(program, shader); if(m_State >= WRITING && program != 0 && shader != 0) { GLResourceRecord *progRecord = GetResourceManager()->GetResourceRecord(ProgramRes(GetCtx(), program)); GLResourceRecord *shadRecord = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader)); RDCASSERT(progRecord && shadRecord); if(progRecord && shadRecord) { SCOPED_SERIALISE_CONTEXT(ATTACHSHADER); Serialise_glAttachShader(program, shader); progRecord->AddParent(shadRecord); progRecord->AddChunk(scope.Get()); } } else { ResourceId progid = GetResourceManager()->GetID(ProgramRes(GetCtx(), program)); ResourceId shadid = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader)); m_Programs[progid].shaders.push_back(shadid); } }
void WrappedOpenGL::glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length) { m_Real.glShaderSource(shader, count, string, length); if(m_State >= WRITING) { GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader)); RDCASSERT(record); { SCOPED_SERIALISE_CONTEXT(SHADERSOURCE); Serialise_glShaderSource(shader, count, string, length); record->AddChunk(scope.Get()); } } else { ResourceId id = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader)); m_Shaders[id].sources.clear(); m_Shaders[id].sources.reserve(count); for(GLsizei i = 0; i < count; i++) m_Shaders[id].sources.push_back(string[i]); } }
void WrappedOpenGL::glCompileShaderIncludeARB(GLuint shader, GLsizei count, const GLchar *const *path, const GLint *length) { m_Real.glCompileShaderIncludeARB(shader, count, path, length); if(m_State >= WRITING) { GLResourceRecord *record = GetResourceManager()->GetResourceRecord(ShaderRes(GetCtx(), shader)); RDCASSERT(record); { SCOPED_SERIALISE_CONTEXT(COMPILESHADERINCLUDE); Serialise_glCompileShaderIncludeARB(shader, count, path, length); record->AddChunk(scope.Get()); } } else { ResourceId id = GetResourceManager()->GetID(ShaderRes(GetCtx(), shader)); auto &shadDetails = m_Shaders[id]; shadDetails.includepaths.clear(); shadDetails.includepaths.reserve(count); for(int32_t i = 0; i < count; i++) shadDetails.includepaths.push_back(path[i]); shadDetails.Compile(*this); } }
void WrappedOpenGL::glGenQueries(GLsizei count, GLuint *ids) { m_Real.glGenSamplers(count, ids); for(GLsizei i=0; i < count; i++) { GLResource res = QueryRes(ids[i]); ResourceId id = GetResourceManager()->RegisterResource(res); if(m_State >= WRITING) { Chunk *chunk = NULL; { SCOPED_SERIALISE_CONTEXT(GEN_QUERIES); Serialise_glGenQueries(1, ids+i); chunk = scope.Get(); } GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); RDCASSERT(record); record->AddChunk(chunk); } else { GetResourceManager()->AddLiveResource(id, res); } } }
void WrappedOpenGL::glGetNamedBufferPointervEXT(GLuint buffer, GLenum pname, void **params) { CoherentMapImplicitBarrier(); // intercept GL_BUFFER_MAP_POINTER queries if(pname == eGL_BUFFER_MAP_POINTER) { GLResourceRecord *record = GetResourceManager()->GetResourceRecord(BufferRes(GetCtx(), buffer)); RDCASSERT(record); if(record) { if(record->Map.status == GLResourceRecord::Unmapped) *params = NULL; else *params = (void *)record->Map.ptr; } else { *params = NULL; } } else { m_Real.glGetNamedBufferPointervEXT(buffer, pname, params); } }
GLuint WrappedOpenGL::glCreateShader(GLenum type) { GLuint real = m_Real.glCreateShader(type); GLResource res = ShaderRes(GetCtx(), real); ResourceId id = GetResourceManager()->RegisterResource(res); if(m_State >= WRITING) { Chunk *chunk = NULL; { SCOPED_SERIALISE_CONTEXT(CREATE_SHADER); Serialise_glCreateShader(real, type); chunk = scope.Get(); } GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); RDCASSERT(record); record->AddChunk(chunk); } else { GetResourceManager()->AddLiveResource(id, res); m_Shaders[id].type = type; } return real; }
void WrappedOpenGL::glGenFramebuffers(GLsizei n, GLuint *framebuffers) { m_Real.glGenFramebuffers(n, framebuffers); for(GLsizei i=0; i < n; i++) { GLResource res = FramebufferRes(GetCtx(), framebuffers[i]); ResourceId id = GetResourceManager()->RegisterResource(res); if(m_State >= WRITING) { Chunk *chunk = NULL; { SCOPED_SERIALISE_CONTEXT(GEN_FRAMEBUFFERS); Serialise_glGenFramebuffers(1, framebuffers+i); chunk = scope.Get(); } GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); RDCASSERT(record); record->AddChunk(chunk); } else { GetResourceManager()->AddLiveResource(id, res); } } }
void WrappedOpenGL::glCreateSamplers(GLsizei count, GLuint *samplers) { m_Real.glCreateSamplers(count, samplers); for(GLsizei i = 0; i < count; i++) { GLResource res = SamplerRes(GetCtx(), samplers[i]); ResourceId id = GetResourceManager()->RegisterResource(res); if(m_State >= WRITING) { Chunk *chunk = NULL; { SCOPED_SERIALISE_CONTEXT(CREATE_SAMPLERS); Serialise_glCreateSamplers(1, samplers + i); chunk = scope.Get(); } GLResourceRecord *record = GetResourceManager()->AddResourceRecord(id); RDCASSERT(record); record->AddChunk(chunk); } else { GetResourceManager()->AddLiveResource(id, res); } } }
void WrappedOpenGL::glCopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) { m_Real.glCopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth); if(m_State >= WRITING) { GLResourceRecord *srcrecord = GetResourceManager()->GetResourceRecord(TextureRes(srcName)); GLResourceRecord *dstrecord = GetResourceManager()->GetResourceRecord(TextureRes(dstName)); RDCASSERT(srcrecord && dstrecord); SCOPED_SERIALISE_CONTEXT(COPY_SUBIMAGE); Serialise_glCopyImageSubData(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth); Chunk *chunk = scope.Get(); if(m_State == WRITING_CAPFRAME) { m_ContextRecord->AddChunk(chunk); } else { dstrecord->AddChunk(chunk); dstrecord->AddParent(srcrecord); } } }
void WrappedOpenGL::glGetBufferPointerv(GLenum target, GLenum pname, void **params) { CoherentMapImplicitBarrier(); // intercept GL_BUFFER_MAP_POINTER queries if(pname == eGL_BUFFER_MAP_POINTER) { GLResourceRecord *record = GetCtxData().m_BufferRecord[BufferIdx(target)]; RDCASSERT(record); if(record) { if(record->Map.status == GLResourceRecord::Unmapped) *params = NULL; else *params = (void *)record->Map.ptr; } else { *params = NULL; } } else { m_Real.glGetBufferPointerv(target, pname, params); } }
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); } } }
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 ReplayOutput::AddThumbnail(void *wnd, ResourceId texID) { OutputPair p; RDCASSERT(wnd); bool depthMode = false; for(size_t t = 0; t < m_pRenderer->m_Textures.size(); t++) { if(m_pRenderer->m_Textures[t].ID == texID) { depthMode = (m_pRenderer->m_Textures[t].creationFlags & eTextureCreate_DSV) > 0; depthMode |= (m_pRenderer->m_Textures[t].format.compType == eCompType_Depth); break; } } for(size_t i = 0; i < m_Thumbnails.size(); i++) { if(m_Thumbnails[i].wndHandle == wnd) { m_Thumbnails[i].texture = texID; m_Thumbnails[i].depthMode = depthMode; m_Thumbnails[i].dirty = true; return true; } } p.wndHandle = wnd; p.outputID = m_pDevice->MakeOutputWindow(p.wndHandle, false); p.texture = texID; p.depthMode = depthMode; p.dirty = true; RDCASSERT(p.outputID > 0); m_Thumbnails.push_back(p); return true; }
HRESULT WrappedIDXGISwapChain2::ResizeBuffers( /* [in] */ UINT BufferCount, /* [in] */ UINT Width, /* [in] */ UINT Height, /* [in] */ DXGI_FORMAT NewFormat, /* [in] */ UINT SwapChainFlags) { for(int i=0; i < MAX_NUM_BACKBUFFERS; i++) { WrappedID3D11Texture2D *wrapped = (WrappedID3D11Texture2D*)m_pBackBuffers[i]; if(wrapped) { m_pDevice->GetImmediateContext()->GetCurrentPipelineState()->UnbindIUnknownForWrite(wrapped); m_pDevice->GetImmediateContext()->GetCurrentPipelineState()->UnbindForRead(wrapped); wrapped->ViewRelease(); } wrapped = NULL; } m_pDevice->ReleaseSwapchainResources(this); HRESULT ret = m_pReal->ResizeBuffers(BufferCount, Width, Height, NewFormat, SwapChainFlags); DXGI_SWAP_CHAIN_DESC desc; m_pReal->GetDesc(&desc); 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]); WrappedID3D11Texture2D *wrapped = (WrappedID3D11Texture2D *)m_pBackBuffers[i]; if(wrapped) { // keep ref as a 'view' (invisible to user) wrapped->ViewAddRef(); wrapped->Release(); } } } return ret; }