bool WrappedOpenGL::Serialise_glEndQuery(GLenum target) { SERIALISE_ELEMENT(GLenum, Target, target); if(m_State < WRITING) { glEndQuery(Target); } return true; }
bool WrappedOpenGL::Serialise_glStencilMask(GLuint mask) { SERIALISE_ELEMENT(uint32_t, Mask, mask); if(m_State <= EXECUTING) { m_Real.glStencilMask(Mask); } return true; }
bool WrappedOpenGL::Serialise_glCreateShader(GLuint shader, GLenum type) { SERIALISE_ELEMENT(GLenum, Type, type); SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(ShaderRes(GetCtx(), shader))); if(m_State == READING) { GLuint real = m_Real.glCreateShader(Type); GLResource res = ShaderRes(GetCtx(), real); ResourceId liveId = GetResourceManager()->RegisterResource(res); m_Shaders[liveId].type = Type; GetResourceManager()->AddLiveResource(id, res); } return true; }
bool WrappedOpenGL::Serialise_glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { SERIALISE_ELEMENT(int32_t, sX0, srcX0); SERIALISE_ELEMENT(int32_t, sY0, srcY0); SERIALISE_ELEMENT(int32_t, sX1, srcX1); SERIALISE_ELEMENT(int32_t, sY1, srcY1); SERIALISE_ELEMENT(int32_t, dX0, dstX0); SERIALISE_ELEMENT(int32_t, dY0, dstY0); SERIALISE_ELEMENT(int32_t, dX1, dstX1); SERIALISE_ELEMENT(int32_t, dY1, dstY1); SERIALISE_ELEMENT(uint32_t, msk, mask); SERIALISE_ELEMENT(GLenum, flt, filter); if(m_State <= EXECUTING) { m_Real.glBlitFramebuffer(sX0, sY0, sX1, sY1, dX0, dY0, dX1, dY1, msk, flt); } return true; }
bool WrappedOpenGL::Serialise_glBindFramebuffer(GLenum target, GLuint framebuffer) { SERIALISE_ELEMENT(GLenum, Target, target); SERIALISE_ELEMENT(ResourceId, Id, (framebuffer ? GetResourceManager()->GetID(FramebufferRes(GetCtx(), framebuffer)) : ResourceId())); if(m_State <= EXECUTING) { if(Id == ResourceId()) { m_Real.glBindFramebuffer(Target, m_FakeBB_FBO); } else { GLResource res = GetResourceManager()->GetLiveResource(Id); m_Real.glBindFramebuffer(Target, res.name); } } return true; }
bool WrappedOpenGL::Serialise_glEnable(GLenum cap) { SERIALISE_ELEMENT(GLenum, c, cap); if(m_State <= EXECUTING) { m_Real.glEnable(c); } return true; }
bool WrappedOpenGL::Serialise_glTextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) { SERIALISE_ELEMENT(GLenum, Target, target); SERIALISE_ELEMENT(uint32_t, Levels, levels); SERIALISE_ELEMENT(GLenum, Format, internalformat); SERIALISE_ELEMENT(uint32_t, Width, width); SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetID(TextureRes(texture))); if(m_State == READING) { ResourceId liveId = GetResourceManager()->GetLiveID(id); m_Textures[liveId].width = Width; m_Textures[liveId].height = 1; m_Textures[liveId].depth = 1; m_Real.glTextureStorage1DEXT(GetResourceManager()->GetLiveResource(id).name, Target, Levels, Format, Width); } return true; }
bool WrappedOpenGL::Serialise_glPrimitiveRestartIndex(GLuint index) { SERIALISE_ELEMENT(GLuint, i, index); if(m_State <= EXECUTING) { m_Real.glPrimitiveRestartIndex(i); } return true; }
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; }
bool WrappedOpenGL::Serialise_glLineWidth(GLfloat width) { SERIALISE_ELEMENT(GLfloat, w, width); if(m_State <= EXECUTING) { m_Real.glLineWidth(w); } return true; }
bool WrappedOpenGL::Serialise_glLogicOp(GLenum opcode) { SERIALISE_ELEMENT(GLenum, Op, opcode); if(m_State <= EXECUTING) { m_Real.glLogicOp(Op); } return true; }
bool WrappedOpenGL::Serialise_glPointSize(GLfloat size) { SERIALISE_ELEMENT(GLfloat, s, size); if(m_State <= EXECUTING) { m_Real.glPointSize(s); } return true; }
bool WrappedOpenGL::Serialise_glDepthMask(GLboolean flag) { SERIALISE_ELEMENT(uint8_t, f, flag); if(m_State <= EXECUTING) { m_Real.glDepthMask(f); } return true; }
bool WrappedOpenGL::Serialise_glDepthFunc(GLenum func) { SERIALISE_ELEMENT(GLenum, f, func); if(m_State <= EXECUTING) { m_Real.glDepthFunc(f); } return true; }
bool WrappedOpenGL::Serialise_glProvokingVertex(GLenum mode) { SERIALISE_ELEMENT(GLenum, m, mode); if(m_State <= EXECUTING) { m_Real.glProvokingVertex(m); } return true; }
bool WrappedOpenGL::Serialise_glCullFace(GLenum mode) { SERIALISE_ELEMENT(GLenum, m, mode); if(m_State <= EXECUTING) { m_Real.glCullFace(m); } return true; }
bool WrappedOpenGL::Serialise_glClearStencil(GLint stencil) { SERIALISE_ELEMENT(uint32_t, s, (uint32_t)stencil); if(m_State <= EXECUTING) { m_Real.glClearStencil((GLint)s); } return true; }
bool WrappedID3D12Device::Serialise_CreateCommittedResource( const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riidResource, void **ppvResource) { SERIALISE_ELEMENT(D3D12_HEAP_PROPERTIES, props, *pHeapProperties); SERIALISE_ELEMENT(D3D12_HEAP_FLAGS, flags, HeapFlags); SERIALISE_ELEMENT(D3D12_RESOURCE_DESC, desc, *pDesc); SERIALISE_ELEMENT(D3D12_RESOURCE_STATES, state, InitialResourceState); SERIALISE_ELEMENT(bool, HasClearValue, pOptimizedClearValue != NULL); SERIALISE_ELEMENT_OPT(D3D12_CLEAR_VALUE, clearVal, *pOptimizedClearValue, HasClearValue); SERIALISE_ELEMENT(IID, guid, riidResource); SERIALISE_ELEMENT(ResourceId, Res, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()); if(m_State == READING) { pOptimizedClearValue = HasClearValue ? &clearVal : NULL; ID3D12Resource *ret = NULL; HRESULT hr = m_pDevice->CreateCommittedResource(&props, flags, &desc, state, pOptimizedClearValue, guid, (void **)&ret); if(FAILED(hr)) { RDCERR("Failed on resource serialise-creation, HRESULT: 0x%08x", hr); } else { ret = new WrappedID3D12Resource(ret, this); GetResourceManager()->AddLiveResource(Res, ret); SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; states.resize(GetNumSubresources(&desc), state); } } return true; }
bool WrappedOpenGL::Serialise_glPointParameterfv(GLenum pname, const GLfloat *params) { SERIALISE_ELEMENT(GLenum, PName, pname); SERIALISE_ELEMENT(float, Param, *params); if(m_State <= EXECUTING) { m_Real.glPointParameterfv(PName, &Param); } return true; }
bool WrappedVulkan::Serialise_vkDeviceWaitIdle(Serialiser* localSerialiser, VkDevice device) { SERIALISE_ELEMENT(ResourceId, id, GetResID(device)); if(m_State < WRITING) { device = GetResourceManager()->GetLiveHandle<VkDevice>(id); ObjDisp(device)->DeviceWaitIdle(Unwrap(device)); } return true; }
bool WrappedOpenGL::Serialise_glEndQuery(GLenum target) { SERIALISE_ELEMENT(GLenum, Target, target); if(m_State < WRITING) { m_ActiveQueries[QueryIdx(Target)][0] = false; m_Real.glEndQuery(Target); } return true; }
bool WrappedOpenGL::Serialise_glRasterSamplesEXT(GLuint samples, GLboolean fixedsamplelocations) { SERIALISE_ELEMENT(uint32_t, s, samples); SERIALISE_ELEMENT(bool, f, fixedsamplelocations != 0); if(m_State <= EXECUTING) { m_Real.glRasterSamplesEXT(s, f); } return true; }
bool WrappedVulkan::Serialise_vkCreateBuffer( Serialiser* localSerialiser, VkDevice device, const VkBufferCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkBuffer* pBuffer) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(VkBufferCreateInfo, info, *pCreateInfo); SERIALISE_ELEMENT(ResourceId, id, GetResID(*pBuffer)); if(m_State == READING) { device = GetResourceManager()->GetLiveHandle<VkDevice>(devId); VkBuffer buf = VK_NULL_HANDLE; VkBufferUsageFlags origusage = info.usage; // ensure we can always readback from buffers info.usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; VkResult ret = ObjDisp(device)->CreateBuffer(Unwrap(device), &info, NULL, &buf); info.usage = origusage; if(ret != VK_SUCCESS) { RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); } else { ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), buf); GetResourceManager()->AddLiveResource(id, buf); m_CreationInfo.m_Buffer[live].Init(GetResourceManager(), m_CreationInfo, &info); } } return true; }
bool WrappedOpenGL::Serialise_glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) { SERIALISE_ELEMENT(GLenum, Mode, mode); SERIALISE_ELEMENT(int32_t, First, first); SERIALISE_ELEMENT(uint32_t, Count, count); SERIALISE_ELEMENT(uint32_t, InstanceCount, instancecount); if(m_State <= EXECUTING) { m_Real.glDrawArraysInstanced(Mode, First, Count, InstanceCount); } const string desc = m_pSerialiser->GetDebugStr(); if(m_State == READING) { AddEvent(DRAWARRAYS_INSTANCED, desc); string name = "glDrawArraysInstanced(" + ToStr::Get(Mode) + ", " + ToStr::Get(First) + ", " + ToStr::Get(Count) + ", " + ToStr::Get(InstanceCount) + ")"; FetchDrawcall draw; draw.name = widen(name); draw.numIndices = Count; draw.numInstances = InstanceCount; draw.indexOffset = 0; draw.vertexOffset = First; draw.instanceOffset = 0; draw.flags |= eDraw_Drawcall|eDraw_Instanced; m_LastDrawMode = Mode; AddDrawcall(draw, true); } return true; }
bool WrappedVulkan::Serialise_vkUnmapMemory( Serialiser* localSerialiser, VkDevice device, VkDeviceMemory mem) { SERIALISE_ELEMENT(ResourceId, devId, GetResID(device)); SERIALISE_ELEMENT(ResourceId, id, GetResID(mem)); MemMapState *state; if(m_State >= WRITING) state = GetRecord(mem)->memMapState; SERIALISE_ELEMENT(uint64_t, memOffset, state->mapOffset); SERIALISE_ELEMENT(uint64_t, memSize, state->mapSize); SERIALISE_ELEMENT_BUF(byte*, data, (byte *)state->mappedPtr + state->mapOffset, (size_t)memSize); if(m_State < WRITING) { device = GetResourceManager()->GetLiveHandle<VkDevice>(devId); mem = GetResourceManager()->GetLiveHandle<VkDeviceMemory>(id); void *mapPtr = NULL; VkResult ret = ObjDisp(device)->MapMemory(Unwrap(device), Unwrap(mem), memOffset, memSize, 0, &mapPtr); if(ret != VK_SUCCESS) { RDCERR("Error mapping memory on replay: 0x%08x", ret); } else { memcpy((byte *)mapPtr, data, (size_t)memSize); ObjDisp(device)->UnmapMemory(Unwrap(device), Unwrap(mem)); } SAFE_DELETE_ARRAY(data); } return true; }
bool WrappedVulkan::Serialise_vkCmdSetScissor(Serialiser *localSerialiser, VkCommandBuffer cmdBuffer, uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *pScissors) { SERIALISE_ELEMENT(ResourceId, cmdid, GetResID(cmdBuffer)); SERIALISE_ELEMENT(uint32_t, first, firstScissor); SERIALISE_ELEMENT(uint32_t, count, scissorCount); SERIALISE_ELEMENT_ARR(VkRect2D, scissors, pScissors, count); Serialise_DebugMessages(localSerialiser, false); if(m_State < WRITING) m_LastCmdBufferID = cmdid; if(m_State == EXECUTING) { if(ShouldRerecordCmd(cmdid) && InRerecordRange(cmdid)) { cmdBuffer = RerecordCmdBuf(cmdid); ObjDisp(cmdBuffer)->CmdSetScissor(Unwrap(cmdBuffer), first, count, scissors); if(m_RenderState.scissors.size() < first + count) m_RenderState.scissors.resize(first + count); for(uint32_t i = 0; i < count; i++) m_RenderState.scissors[first + i] = scissors[i]; } } else if(m_State == READING) { cmdBuffer = GetResourceManager()->GetLiveHandle<VkCommandBuffer>(cmdid); ObjDisp(cmdBuffer)->CmdSetScissor(Unwrap(cmdBuffer), first, count, scissors); } SAFE_DELETE_ARRAY(scissors); return true; }
bool WrappedOpenGL::Serialise_glReadBuffer(GLenum mode) { SERIALISE_ELEMENT(GLenum, m, mode); SERIALISE_ELEMENT(ResourceId, id, m_ReadFramebufferRecord ? m_ReadFramebufferRecord->GetResourceID() : ResourceId()); if(m_State < WRITING) { if(id != ResourceId()) { GLResource res = GetResourceManager()->GetLiveResource(id); m_Real.glBindFramebuffer(eGL_READ_FRAMEBUFFER, res.name); } else { m_Real.glBindFramebuffer(eGL_READ_FRAMEBUFFER, 0); } m_Real.glReadBuffer(m); } return true; }
bool WrappedOpenGL::Serialise_glFenceSync(GLsync real, GLenum condition, GLbitfield flags) { SERIALISE_ELEMENT(GLenum, Condition, condition); SERIALISE_ELEMENT(uint32_t, Flags, flags); SERIALISE_ELEMENT(ResourceId, id, GetResourceManager()->GetSyncID(real)); if(m_State < WRITING) { GLsync real = m_Real.glFenceSync(Condition, Flags); GLuint name = 0; ResourceId liveid = ResourceId(); GetResourceManager()->RegisterSync(real, name, liveid); GLResource res = SyncRes(name); ResourceId live = m_ResourceManager->RegisterResource(res); GetResourceManager()->AddLiveResource(id, res); } return true; }
bool WrappedOpenGL::Serialise_glBindSampler(GLuint unit, GLuint sampler) { SERIALISE_ELEMENT(uint32_t, Unit, unit); SERIALISE_ELEMENT(ResourceId, id, sampler ? GetResourceManager()->GetID(SamplerRes(GetCtx(), sampler)) : ResourceId()); if(m_State < WRITING) { if(id == ResourceId()) { m_Real.glBindSampler(Unit, 0); } else { GLResource res = GetResourceManager()->GetLiveResource(id); m_Real.glBindSampler(Unit, res.name); } } return true; }
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; }