From a5cc19ccc68fc9a4b5632c29b51bca0fa41fc585 Mon Sep 17 00:00:00 2001 From: baldurk Date: Sat, 11 Apr 2015 11:03:19 +0100 Subject: [PATCH] Implement replay-side resource tracking for OpenGL * This means that the timeline bar will show use as read/write/clear etc and that right clicking on textures in the texture viewer will show the events where that texture is used for rendering, for reading, and so on. --- renderdoc/api/replay/data_types.h | 14 + renderdoc/api/replay/replay_enums.h | 52 ++-- renderdoc/driver/d3d11/d3d11_analyse.cpp | 20 +- renderdoc/driver/d3d11/d3d11_context.cpp | 44 +-- renderdoc/driver/d3d11/d3d11_context_wrap.cpp | 2 +- renderdoc/driver/gl/gl_common.h | 2 + renderdoc/driver/gl/gl_driver.cpp | 262 +++++++++++++++++- renderdoc/driver/gl/gl_driver.h | 7 +- renderdoc/driver/gl/gl_renderstate.h | 2 +- renderdoc/driver/gl/gl_replay.cpp | 212 +------------- renderdoc/driver/gl/gl_replay.h | 2 - renderdoc/driver/gl/gl_shader_refl.cpp | 191 +++++++++++++ .../driver/gl/wrappers/gl_draw_funcs.cpp | 141 +++++++++- .../gl/wrappers/gl_framebuffer_funcs.cpp | 53 ++++ .../driver/gl/wrappers/gl_texture_funcs.cpp | 12 + renderdoc/replay/replay_renderer.cpp | 40 +-- renderdocui/Interop/Enums.cs | 150 ++++++---- renderdocui/Windows/TextureViewer.cs | 6 +- renderdocui/Windows/TimelineBar.cs | 9 +- 19 files changed, 885 insertions(+), 336 deletions(-) diff --git a/renderdoc/api/replay/data_types.h b/renderdoc/api/replay/data_types.h index 98759fcb6..61993a2e7 100644 --- a/renderdoc/api/replay/data_types.h +++ b/renderdoc/api/replay/data_types.h @@ -142,11 +142,25 @@ struct FetchFrameInfo struct EventUsage { +#ifdef __cplusplus EventUsage() : eventID(0), usage(eUsage_None) {} EventUsage(uint32_t e, ResourceUsage u) : eventID(e), usage(u) {} + bool operator <(const EventUsage &o) const + { + if(eventID != o.eventID) + return eventID < o.eventID; + return usage < o.usage; + } + + bool operator ==(const EventUsage &o) const + { + return eventID == o.eventID && usage == o.usage; + } +#endif + uint32_t eventID; ResourceUsage usage; }; diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index cd671f2ae..66d6f3d42 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -319,30 +319,34 @@ enum ResourceUsage { eUsage_None, - eUsage_IA_VB, - eUsage_IA_IB, + eUsage_VertexBuffer, + eUsage_IndexBuffer, - eUsage_VS_CB, - eUsage_HS_CB, - eUsage_DS_CB, - eUsage_GS_CB, - eUsage_PS_CB, - eUsage_CS_CB, + eUsage_VS_Constants, + eUsage_HS_Constants, + eUsage_DS_Constants, + eUsage_GS_Constants, + eUsage_PS_Constants, + eUsage_CS_Constants, eUsage_SO, - eUsage_VS_SRV, - eUsage_HS_SRV, - eUsage_DS_SRV, - eUsage_GS_SRV, - eUsage_PS_SRV, - eUsage_CS_SRV, + eUsage_VS_Resource, + eUsage_HS_Resource, + eUsage_DS_Resource, + eUsage_GS_Resource, + eUsage_PS_Resource, + eUsage_CS_Resource, - eUsage_CS_UAV, - eUsage_PS_UAV, + eUsage_VS_RWResource, + eUsage_HS_RWResource, + eUsage_DS_RWResource, + eUsage_GS_RWResource, + eUsage_PS_RWResource, + eUsage_CS_RWResource, - eUsage_OM_RTV, - eUsage_OM_DSV, + eUsage_ColourTarget, + eUsage_DepthStencilTarget, eUsage_Clear, @@ -371,12 +375,12 @@ enum DrawcallFlags eDraw_GenMips = 0x400, // flags - eDraw_UseIBuffer = 0x01000, - eDraw_Instanced = 0x02000, - eDraw_Auto = 0x04000, - eDraw_Indirect = 0x08000, - eDraw_ClearColour = 0x10000, - eDraw_ClearDepth = 0x20000, + eDraw_UseIBuffer = 0x01000, + eDraw_Instanced = 0x02000, + eDraw_Auto = 0x04000, + eDraw_Indirect = 0x08000, + eDraw_ClearColour = 0x10000, + eDraw_ClearDepthStencil = 0x20000, }; enum SolidShadeMode diff --git a/renderdoc/driver/d3d11/d3d11_analyse.cpp b/renderdoc/driver/d3d11/d3d11_analyse.cpp index 2e9bb4618..81e14a0dc 100644 --- a/renderdoc/driver/d3d11/d3d11_analyse.cpp +++ b/renderdoc/driver/d3d11/d3d11_analyse.cpp @@ -3903,13 +3903,14 @@ vector D3D11DebugManager::PixelHistory(uint32_t frameID, vect curNumInst = D3D11_SHADER_MAX_INTERFACES; curNumScissors = curNumViews = 16; - bool uavOutput = (events[ev].usage == eUsage_PS_UAV || - events[ev].usage == eUsage_CS_UAV || - events[ev].usage == eUsage_CopyDst || - events[ev].usage == eUsage_Copy || - events[ev].usage == eUsage_Resolve || - events[ev].usage == eUsage_ResolveDst || - events[ev].usage == eUsage_GenMips); + bool uavOutput = ( + (events[ev].usage >= eUsage_VS_RWResource && + events[ev].usage <= eUsage_CS_RWResource) || + events[ev].usage == eUsage_CopyDst || + events[ev].usage == eUsage_Copy || + events[ev].usage == eUsage_Resolve || + events[ev].usage == eUsage_ResolveDst || + events[ev].usage == eUsage_GenMips); m_pImmediateContext->RSGetState(&curRS); m_pImmediateContext->OMGetBlendState(&curBS, blendFactor, &curSample); @@ -4394,8 +4395,9 @@ vector D3D11DebugManager::PixelHistory(uint32_t frameID, vect bool clear = (draw->flags & eDraw_Clear); - bool uavWrite = (events[i].usage == eUsage_PS_UAV || - events[i].usage == eUsage_CS_UAV || + bool uavWrite = ( + (events[i].usage >= eUsage_VS_RWResource && + events[i].usage <= eUsage_CS_RWResource) || events[i].usage == eUsage_CopyDst || events[i].usage == eUsage_Copy || events[i].usage == eUsage_Resolve || diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index 374eaf091..54315d61e 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -965,11 +965,11 @@ void WrappedID3D11DeviceContext::AddUsage(FetchDrawcall d) // IA if(d.flags & eDraw_UseIBuffer && pipe->IA.IndexBuffer != NULL) - m_ResourceUses[GetIDForResource(pipe->IA.IndexBuffer)].push_back(EventUsage(e, eUsage_IA_IB)); + m_ResourceUses[GetIDForResource(pipe->IA.IndexBuffer)].push_back(EventUsage(e, eUsage_IndexBuffer)); for(int i=0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) if(pipe->IA.Used_VB(m_pDevice, i)) - m_ResourceUses[GetIDForResource(pipe->IA.VBs[i])].push_back(EventUsage(e, eUsage_IA_VB)); + m_ResourceUses[GetIDForResource(pipe->IA.VBs[i])].push_back(EventUsage(e, eUsage_VertexBuffer)); ////////////////////////////// // Shaders @@ -981,17 +981,17 @@ void WrappedID3D11DeviceContext::AddUsage(FetchDrawcall d) for(int i=0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) if(sh.Used_CB(i)) - m_ResourceUses[GetIDForResource(sh.ConstantBuffers[i])].push_back(EventUsage(e, (ResourceUsage)(eUsage_VS_CB+s))); + m_ResourceUses[GetIDForResource(sh.ConstantBuffers[i])].push_back(EventUsage(e, (ResourceUsage)(eUsage_VS_Constants+s))); for(int i=0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) if(sh.Used_SRV(i)) - m_ResourceUses[((WrappedID3D11ShaderResourceView *)sh.SRVs[i])->GetResourceResID()].push_back(EventUsage(e, (ResourceUsage)(eUsage_VS_SRV+s))); + m_ResourceUses[((WrappedID3D11ShaderResourceView *)sh.SRVs[i])->GetResourceResID()].push_back(EventUsage(e, (ResourceUsage)(eUsage_VS_Resource+s))); if(s == 5) { for(int i=0; i < D3D11_PS_CS_UAV_REGISTER_COUNT; i++) if(pipe->CS.Used_UAV(i) && pipe->CS.UAVs[i]) - m_ResourceUses[((WrappedID3D11UnorderedAccessView *)pipe->CS.UAVs[i])->GetResourceResID()].push_back(EventUsage(e, eUsage_CS_UAV)); + m_ResourceUses[((WrappedID3D11UnorderedAccessView *)pipe->CS.UAVs[i])->GetResourceResID()].push_back(EventUsage(e, eUsage_CS_RWResource)); } } @@ -1007,14 +1007,14 @@ void WrappedID3D11DeviceContext::AddUsage(FetchDrawcall d) for(int i=0; i < D3D11_PS_CS_UAV_REGISTER_COUNT; i++) if(pipe->PS.Used_UAV(i) && pipe->OM.UAVs[i]) - m_ResourceUses[((WrappedID3D11UnorderedAccessView *)pipe->OM.UAVs[i])->GetResourceResID()].push_back(EventUsage(e, eUsage_PS_UAV)); + m_ResourceUses[((WrappedID3D11UnorderedAccessView *)pipe->OM.UAVs[i])->GetResourceResID()].push_back(EventUsage(e, eUsage_PS_RWResource)); if(pipe->OM.DepthView) // assuming for now that any DSV bound is used. - m_ResourceUses[((WrappedID3D11DepthStencilView *)pipe->OM.DepthView)->GetResourceResID()].push_back(EventUsage(e, eUsage_OM_DSV)); + m_ResourceUses[((WrappedID3D11DepthStencilView *)pipe->OM.DepthView)->GetResourceResID()].push_back(EventUsage(e, eUsage_DepthStencilTarget)); for(int i=0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) if(pipe->OM.RenderTargets[i]) // assuming for now that any RTV bound is used. - m_ResourceUses[((WrappedID3D11RenderTargetView *)pipe->OM.RenderTargets[i])->GetResourceResID()].push_back(EventUsage(e, eUsage_OM_RTV)); + m_ResourceUses[((WrappedID3D11RenderTargetView *)pipe->OM.RenderTargets[i])->GetResourceResID()].push_back(EventUsage(e, eUsage_ColourTarget)); } void WrappedID3D11DeviceContext::RefreshDrawcallIDs(DrawcallTreeNode &node) @@ -1252,16 +1252,27 @@ void WrappedID3D11DeviceContext::ReplayLog(LogState readType, uint32_t startEven m_ResourceUses[it->first]; for(auto it=WrappedID3D11Texture3D::m_TextureList.begin(); it != WrappedID3D11Texture3D::m_TextureList.end(); ++it) m_ResourceUses[it->first]; - + + // it's easier to remove duplicate usages here than check it as we go. + // this means if textures are bound in multiple places in the same draw + // we don't have duplicate uses for(auto it = m_ResourceUses.begin(); it != m_ResourceUses.end(); ++it) { + vector &v = it->second; + std::sort(v.begin(), v.end()); + v.erase( std::unique(v.begin(), v.end()), v.end() ); + +#if 0 ResourceId resid = m_pDevice->GetResourceManager()->GetOriginalID(it->first); - + if(m_pDevice->GetResourceManager()->GetInitialContents(resid).resource == NULL) continue; - + + // code disabled for now as skipping these initial states + // doesn't seem to produce any measurable improvement in any case + // I've checked RDCDEBUG("Resource %llu", resid); - if(it->second.empty()) + if(v.empty()) { RDCDEBUG("Never used!"); initialSkips++; @@ -1270,13 +1281,13 @@ void WrappedID3D11DeviceContext::ReplayLog(LogState readType, uint32_t startEven { bool written = false; - for(auto usit = it->second.begin(); usit != it->second.end(); ++usit) + for(auto usit = v.begin(); usit != v.end(); ++usit) { ResourceUsage u = usit->usage; if(u == eUsage_SO || - u == eUsage_CS_UAV || u == eUsage_PS_UAV || - u == eUsage_OM_DSV || u == eUsage_OM_RTV) + (u >= eUsage_VS_RWResource && u <= eUsage_CS_RWResource) || + u == eUsage_DepthStencilTarget || u == eUsage_ColourTarget) { written = true; break; @@ -1293,9 +1304,10 @@ void WrappedID3D11DeviceContext::ReplayLog(LogState readType, uint32_t startEven initialSkips++; } } +#endif } - RDCDEBUG("Can skip %d initial states.", initialSkips); + //RDCDEBUG("Can skip %d initial states.", initialSkips); } m_pDevice->GetResourceManager()->MarkInFrame(false); diff --git a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp index 8f1d05a53..b7e297331 100644 --- a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp @@ -6002,7 +6002,7 @@ bool WrappedID3D11DeviceContext::Serialise_ClearDepthStencilView(ID3D11DepthSten FetchDrawcall draw; draw.name = name; - draw.flags |= eDraw_Clear|eDraw_ClearDepth; + draw.flags |= eDraw_Clear|eDraw_ClearDepthStencil; AddDrawcall(draw, true); diff --git a/renderdoc/driver/gl/gl_common.h b/renderdoc/driver/gl/gl_common.h index a1ae4aba5..7635b3a7f 100644 --- a/renderdoc/driver/gl/gl_common.h +++ b/renderdoc/driver/gl/gl_common.h @@ -100,6 +100,8 @@ const char *SamplerString(GLenum smpenum); GLuint GetBoundVertexBuffer(const GLHookSet &gl, GLuint idx); +void GetBindpointMapping(const GLHookSet &gl, GLuint curProg, int shadIdx, ShaderReflection *refl, ShaderBindpointMapping &mapping); + extern int GLCoreVersion; extern bool GLIsCore; diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index f9b64bee6..52d1cf054 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -798,8 +798,6 @@ void WrappedOpenGL::Initialise(GLInitParams ¶ms) gl.glGenFramebuffers(1, &m_FakeBB_FBO); gl.glBindFramebuffer(eGL_FRAMEBUFFER, m_FakeBB_FBO); - GLNOTIMP("backbuffer needs to resize if the size is exceeded"); - GLenum colfmt = eGL_RGBA8; if(params.colorBits == 32) @@ -3578,6 +3576,16 @@ void WrappedOpenGL::ContextReplayLog(LogState readType, uint32_t startEventID, u { GetFrameRecord().back().drawcallList = m_ParentDrawcall.Bake(); GetFrameRecord().back().frameInfo.debugMessages = GetDebugMessages(); + + // it's easier to remove duplicate usages here than check it as we go. + // this means if textures are bound in multiple places in the same draw + // we don't have duplicate uses + for(auto it = m_ResourceUses.begin(); it != m_ResourceUses.end(); ++it) + { + vector &v = it->second; + std::sort(v.begin(), v.end()); + v.erase( std::unique(v.begin(), v.end()), v.end() ); + } } GetResourceManager()->MarkInFrame(false); @@ -3656,6 +3664,254 @@ void WrappedOpenGL::ContextProcessChunk(uint64_t offset, GLChunkType chunk, bool context->m_State = state; } +void WrappedOpenGL::AddUsage(FetchDrawcall d) +{ + if((d.flags & (eDraw_Drawcall|eDraw_Dispatch)) == 0) + return; + + const GLHookSet &gl = m_Real; + + GLResourceManager *rm = GetResourceManager(); + + void *ctx = GetCtx(); + + uint32_t e = d.eventID; + + ////////////////////////////// + // Input + + if(d.flags & eDraw_UseIBuffer) + { + GLuint ibuffer = 0; + gl.glGetIntegerv(eGL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint*)&ibuffer); + + if(ibuffer) + m_ResourceUses[rm->GetID(BufferRes(ctx, ibuffer))].push_back(EventUsage(e, eUsage_IndexBuffer)); + } + + // Vertex buffers and attributes + GLint numVBufferBindings = 16; + gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIB_BINDINGS, &numVBufferBindings); + + for(GLuint i=0; i < (GLuint)numVBufferBindings; i++) + { + GLuint buffer = GetBoundVertexBuffer(m_Real, i); + + if(buffer) + m_ResourceUses[rm->GetID(BufferRes(ctx, buffer))].push_back(EventUsage(e, eUsage_VertexBuffer)); + } + + ////////////////////////////// + // Shaders + + { + GLRenderState rs(&m_Real, NULL, READING); + rs.FetchState(ctx, this); + + ShaderReflection *refl[6] = { NULL }; + ShaderBindpointMapping mapping[6]; + + GLuint curProg = 0; + gl.glGetIntegerv(eGL_CURRENT_PROGRAM, (GLint*)&curProg); + + if(curProg == 0) + { + gl.glGetIntegerv(eGL_PROGRAM_PIPELINE_BINDING, (GLint*)&curProg); + + if(curProg == 0) + { + // no program bound at this draw + } + else + { + auto &pipeDetails = m_Pipelines[rm->GetID(ProgramPipeRes(ctx, curProg))]; + + for(size_t i=0; i < ARRAY_COUNT(pipeDetails.stageShaders); i++) + { + if(pipeDetails.stageShaders[i] != ResourceId()) + { + curProg = rm->GetCurrentResource(pipeDetails.stagePrograms[i]).name; + + refl[i] = &m_Shaders[pipeDetails.stageShaders[i]].reflection; + GetBindpointMapping(m_Real, curProg, (int)i, refl[i], mapping[i]); + } + } + } + } + else + { + auto &progDetails = m_Programs[rm->GetID(ProgramRes(ctx, curProg))]; + + for(size_t i=0; i < ARRAY_COUNT(progDetails.stageShaders); i++) + { + if(progDetails.stageShaders[i] != ResourceId()) + { + refl[i] = &m_Shaders[progDetails.stageShaders[i]].reflection; + GetBindpointMapping(m_Real, curProg, (int)i, refl[i], mapping[i]); + } + } + } + + for(size_t i=0; i < ARRAY_COUNT(refl); i++) + { + EventUsage cb = EventUsage(e, ResourceUsage(eUsage_VS_Constants + i)); + EventUsage res = EventUsage(e, ResourceUsage(eUsage_VS_Resource + i)); + EventUsage rw = EventUsage(e, ResourceUsage(eUsage_VS_RWResource + i)); + + if(refl[i]) + { + for(int32_t c=0; c < refl[i]->ConstantBlocks.count; c++) + { + if(!refl[i]->ConstantBlocks[c].bufferBacked) continue; + if(refl[i]->ConstantBlocks[c].bindPoint < 0 || + refl[i]->ConstantBlocks[c].bindPoint >= mapping[i].ConstantBlocks.count) continue; + + int32_t bind = mapping[i].ConstantBlocks[ refl[i]->ConstantBlocks[c].bindPoint ].bind; + + if(rs.UniformBinding[bind].name) + m_ResourceUses[rm->GetID(BufferRes(ctx, rs.UniformBinding[bind].name))].push_back(cb); + } + + for(int32_t r=0; r < refl[i]->Resources.count; r++) + { + int32_t bind = mapping[i].Resources[ refl[i]->Resources[r].bindPoint ].bind; + + if(refl[i]->Resources[r].IsReadWrite) + { + if(refl[i]->Resources[r].IsTexture) + { + if(rs.Images[bind].name) + m_ResourceUses[rm->GetID(TextureRes(ctx, rs.UniformBinding[bind].name))].push_back(rw); + } + else + { + if(refl[i]->Resources[r].variableType.descriptor.cols == 1 && + refl[i]->Resources[r].variableType.descriptor.rows == 1 && + refl[i]->Resources[r].variableType.descriptor.type == eVar_UInt) + { + if(rs.AtomicCounter[bind].name) + m_ResourceUses[rm->GetID(BufferRes(ctx, rs.AtomicCounter[bind].name))].push_back(rw); + } + else + { + if(rs.ShaderStorage[bind].name) + m_ResourceUses[rm->GetID(BufferRes(ctx, rs.ShaderStorage[bind].name))].push_back(rw); + } + } + continue; + } + + uint32_t *texList = NULL; + + switch(refl[i]->Resources[r].resType) + { + case eResType_None: + texList = NULL; + break; + case eResType_Buffer: + texList = rs.TexBuffer; + break; + case eResType_Texture1D: + texList = rs.Tex1D; + break; + case eResType_Texture1DArray: + texList = rs.Tex1DArray; + break; + case eResType_Texture2D: + texList = rs.Tex2D; + break; + case eResType_TextureRect: + texList = rs.TexRect; + break; + case eResType_Texture2DArray: + texList = rs.Tex2DArray; + break; + case eResType_Texture2DMS: + texList = rs.Tex2DMS; + break; + case eResType_Texture2DMSArray: + texList = rs.Tex2DMSArray; + break; + case eResType_Texture3D: + texList = rs.Tex3D; + break; + case eResType_TextureCube: + texList = rs.TexCube; + break; + case eResType_TextureCubeArray: + texList = rs.TexCubeArray; + break; + } + + if(texList != NULL && texList[bind] != 0) + m_ResourceUses[rm->GetID(TextureRes(ctx, texList[bind]))].push_back(res); + } + } + } + } + + ////////////////////////////// + // Feedback + + GLint maxCount = 0; + gl.glGetIntegerv(eGL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxCount); + + for(int i=0; i < maxCount; i++) + { + GLuint buffer = 0; + gl.glGetIntegeri_v(eGL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, (GLint*)&buffer); + + if(buffer) + m_ResourceUses[rm->GetID(BufferRes(ctx, buffer))].push_back(EventUsage(e, eUsage_SO)); + } + + ////////////////////////////// + // FBO + + GLint numCols = 8; + gl.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); + + GLuint attachment = 0; + GLenum type = eGL_TEXTURE; + for(GLint i=0; i < numCols; i++) + { + type = eGL_TEXTURE; + + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[rm->GetID(TextureRes(ctx, attachment))].push_back(EventUsage(e, eUsage_ColourTarget)); + else + m_ResourceUses[rm->GetID(RenderbufferRes(ctx, attachment))].push_back(EventUsage(e, eUsage_ColourTarget)); + } + } + + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[rm->GetID(TextureRes(ctx, attachment))].push_back(EventUsage(e, eUsage_DepthStencilTarget)); + else + m_ResourceUses[rm->GetID(RenderbufferRes(ctx, attachment))].push_back(EventUsage(e, eUsage_DepthStencilTarget)); + } + + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); + gl.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[rm->GetID(TextureRes(ctx, attachment))].push_back(EventUsage(e, eUsage_DepthStencilTarget)); + else + m_ResourceUses[rm->GetID(RenderbufferRes(ctx, attachment))].push_back(EventUsage(e, eUsage_DepthStencilTarget)); + } +} + void WrappedOpenGL::AddDrawcall(FetchDrawcall d, bool hasEvents) { if(d.context == ResourceId()) d.context = GetResourceManager()->GetOriginalID(m_ContextResourceID); @@ -3711,7 +3967,7 @@ void WrappedOpenGL::AddDrawcall(FetchDrawcall d, bool hasEvents) draw.events = evs; } - //AddUsage(draw); + AddUsage(draw); // should have at least the root drawcall here, push this drawcall // onto the back's children list. diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 001639777..5d794ff65 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -55,7 +55,7 @@ struct GLInitParams : public RDCInitParams uint32_t width; uint32_t height; - static const uint32_t GL_SERIALISE_VERSION = 0x000000B; + static const uint32_t GL_SERIALISE_VERSION = 0x000000C; // version number internal to opengl stream uint32_t SerialiseVersion; @@ -197,6 +197,8 @@ class WrappedOpenGL list m_DrawcallStack; + map > m_ResourceUses; + // buffer used vector m_ScratchBuf; @@ -299,6 +301,7 @@ class WrappedOpenGL void ProcessChunk(uint64_t offset, GLChunkType context); void ContextReplayLog(LogState readType, uint32_t startEventID, uint32_t endEventID, bool partial); void ContextProcessChunk(uint64_t offset, GLChunkType chunk, bool forceExecute); + void AddUsage(FetchDrawcall draw); void AddDrawcall(FetchDrawcall d, bool hasEvents); void AddEvent(GLChunkType type, string description, ResourceId ctx = ResourceId()); @@ -436,6 +439,8 @@ class WrappedOpenGL const FetchDrawcall *GetDrawcall(uint32_t frameID, uint32_t eventID); + vector GetUsage(ResourceId id) { return m_ResourceUses[id]; } + void CreateContext(GLWindowingData winData, void *shareContext, GLInitParams initParams, bool core, bool attribsCreate); void DeleteContext(void *contextHandle); void ActivateContext(GLWindowingData winData); diff --git a/renderdoc/driver/gl/gl_renderstate.h b/renderdoc/driver/gl/gl_renderstate.h index d8448bd9d..5eaa9b5f8 100644 --- a/renderdoc/driver/gl/gl_renderstate.h +++ b/renderdoc/driver/gl/gl_renderstate.h @@ -174,7 +174,7 @@ struct GLRenderState uint32_t name; uint64_t start; uint64_t size; - } AtomicCounter[1], ShaderStorage[8], TransformFeedback[4], UniformBinding[84]; + } AtomicCounter[8], ShaderStorage[96], TransformFeedback[4], UniformBinding[84]; struct BlendState { diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index 8c3562acb..00d68e83a 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -784,12 +784,6 @@ vector GLReplay::GetDebugMessages() ShaderReflection *GLReplay::GetShader(ResourceId id) { - WrappedOpenGL &gl = *m_pDriver; - - MakeCurrentReplayContext(&m_ReplayCtx); - - void *ctx = m_ReplayCtx.ctx; - auto &shaderDetails = m_pDriver->m_Shaders[id]; if(shaderDetails.prog == 0) @@ -801,198 +795,6 @@ ShaderReflection *GLReplay::GetShader(ResourceId id) return &shaderDetails.reflection; } -void GLReplay::GetMapping(WrappedOpenGL &gl, GLuint curProg, int shadIdx, ShaderReflection *refl, ShaderBindpointMapping &mapping) -{ - // in case of bugs, we readback into this array instead of - GLint dummyReadback[32]; - -#if !defined(RELEASE) - for(size_t i=1; i < ARRAY_COUNT(dummyReadback); i++) - dummyReadback[i] = 0x6c7b8a9d; -#endif - - const GLenum refEnum[] = { - eGL_REFERENCED_BY_VERTEX_SHADER, - eGL_REFERENCED_BY_TESS_CONTROL_SHADER, - eGL_REFERENCED_BY_TESS_EVALUATION_SHADER, - eGL_REFERENCED_BY_GEOMETRY_SHADER, - eGL_REFERENCED_BY_FRAGMENT_SHADER, - eGL_REFERENCED_BY_COMPUTE_SHADER, - }; - - create_array_uninit(mapping.Resources, refl->Resources.count); - for(int32_t i=0; i < refl->Resources.count; i++) - { - if(refl->Resources.elems[i].IsTexture) - { - // normal sampler or image load/store - - GLint loc = gl.glGetUniformLocation(curProg, refl->Resources.elems[i].name.elems); - if(loc >= 0) - { - gl.glGetUniformiv(curProg, loc, dummyReadback); - mapping.Resources[i].bind = dummyReadback[0]; - } - - // handle sampler arrays, use the base name - string name = refl->Resources.elems[i].name.elems; - if(name.back() == ']') - { - do - { - name.pop_back(); - } while(name.back() != '['); - name.pop_back(); - } - - GLuint idx = 0; - idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, name.c_str()); - - if(idx == GL_INVALID_INDEX) - { - mapping.Resources[i].used = false; - } - else - { - GLint used = 0; - gl.glGetProgramResourceiv(curProg, eGL_UNIFORM, idx, 1, &refEnum[shadIdx], 1, NULL, &used); - mapping.Resources[i].used = (used != 0); - } - } - else if(refl->Resources.elems[i].IsReadWrite && !refl->Resources.elems[i].IsTexture) - { - if(refl->Resources.elems[i].variableType.descriptor.cols == 1 && - refl->Resources.elems[i].variableType.descriptor.rows == 1 && - refl->Resources.elems[i].variableType.descriptor.type == eVar_UInt) - { - // atomic uint - GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, refl->Resources.elems[i].name.elems); - - if(idx == GL_INVALID_INDEX) - { - mapping.Resources[i].bind = -1; - mapping.Resources[i].used = false; - } - else - { - GLenum prop = eGL_ATOMIC_COUNTER_BUFFER_INDEX; - GLuint atomicIndex; - gl.glGetProgramResourceiv(curProg, eGL_UNIFORM, idx, 1, &prop, 1, NULL, (GLint *)&atomicIndex); - - if(atomicIndex == GL_INVALID_INDEX) - { - mapping.Resources[i].bind = -1; - mapping.Resources[i].used = false; - } - else - { - const GLenum atomicRefEnum[] = { - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER, - eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER, - }; - gl.glGetActiveAtomicCounterBufferiv(curProg, atomicIndex, eGL_ATOMIC_COUNTER_BUFFER_BINDING, &mapping.Resources[i].bind); - GLint used = 0; - gl.glGetActiveAtomicCounterBufferiv(curProg, atomicIndex, atomicRefEnum[shadIdx], &used); - mapping.Resources[i].used = (used != 0); - } - } - } - else - { - // shader storage buffer object - GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_SHADER_STORAGE_BLOCK, refl->Resources.elems[i].name.elems); - - if(idx == GL_INVALID_INDEX) - { - mapping.Resources[i].bind = -1; - mapping.Resources[i].used = false; - } - else - { - GLenum prop = eGL_BUFFER_BINDING; - gl.glGetProgramResourceiv(curProg, eGL_SHADER_STORAGE_BLOCK, idx, 1, &prop, 1, NULL, &mapping.Resources[i].bind); - GLint used = 0; - gl.glGetProgramResourceiv(curProg, eGL_SHADER_STORAGE_BLOCK, idx, 1, &refEnum[shadIdx], 1, NULL, &used); - mapping.Resources[i].used = (used != 0); - } - } - } - else - { - mapping.Resources[i].bind = -1; - mapping.Resources[i].used = false; - } - } - - create_array_uninit(mapping.ConstantBlocks, refl->ConstantBlocks.count); - for(int32_t i=0; i < refl->ConstantBlocks.count; i++) - { - if(refl->ConstantBlocks.elems[i].bufferBacked) - { - GLint loc = gl.glGetUniformBlockIndex(curProg, refl->ConstantBlocks.elems[i].name.elems); - if(loc >= 0) - { - gl.glGetActiveUniformBlockiv(curProg, loc, eGL_UNIFORM_BLOCK_BINDING, dummyReadback); - mapping.ConstantBlocks[i].bind = dummyReadback[0]; - } - } - else - { - mapping.ConstantBlocks[i].bind = -1; - } - - if(!refl->ConstantBlocks.elems[i].bufferBacked) - { - mapping.ConstantBlocks[i].used = true; - } - else - { - GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM_BLOCK, refl->ConstantBlocks.elems[i].name.elems); - if(idx == GL_INVALID_INDEX) - { - mapping.ConstantBlocks[i].used = false; - } - else - { - GLint used = 0; - gl.glGetProgramResourceiv(curProg, eGL_UNIFORM_BLOCK, idx, 1, &refEnum[shadIdx], 1, NULL, &used); - mapping.ConstantBlocks[i].used = (used != 0); - } - } - } - - GLint numVAttribBindings = 16; - gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIBS, &numVAttribBindings); - - create_array_uninit(mapping.InputAttributes, numVAttribBindings); - for(int32_t i=0; i < numVAttribBindings; i++) - mapping.InputAttributes[i] = -1; - - // override identity map with bindings - if(shadIdx == 0) - { - for(int32_t i=0; i < refl->InputSig.count; i++) - { - GLint loc = gl.glGetAttribLocation(curProg, refl->InputSig.elems[i].varName.elems); - - if(loc >= 0 && loc < numVAttribBindings) - { - mapping.InputAttributes[loc] = i; - } - } - } - -#if !defined(RELEASE) - for(size_t i=1; i < ARRAY_COUNT(dummyReadback); i++) - if(dummyReadback[i] != 0x6c7b8a9d) - RDCERR("Invalid uniform readback - data beyond first element modified!"); -#endif -} - void GLReplay::SavePipelineState() { GLPipelineState &pipe = m_CurPipelineState; @@ -1236,7 +1038,7 @@ void GLReplay::SavePipelineState() curProg = rm->GetCurrentResource(pipeDetails.stagePrograms[i]).name; stages[i]->Shader = rm->GetOriginalID(pipeDetails.stageShaders[i]); refls[i] = GetShader(pipeDetails.stageShaders[i]); - GetMapping(gl, curProg, (int)i, refls[i], stages[i]->BindpointMapping); + GetBindpointMapping(gl.GetHookset(), curProg, (int)i, refls[i], stages[i]->BindpointMapping); mappings[i] = &stages[i]->BindpointMapping; } else @@ -1256,7 +1058,7 @@ void GLReplay::SavePipelineState() { stages[i]->Shader = rm->GetOriginalID(progDetails.stageShaders[i]); refls[i] = GetShader(progDetails.stageShaders[i]); - GetMapping(gl, curProg, (int)i, refls[i], stages[i]->BindpointMapping); + GetBindpointMapping(gl.GetHookset(), curProg, (int)i, refls[i], stages[i]->BindpointMapping); mappings[i] = &stages[i]->BindpointMapping; } } @@ -2950,17 +2752,17 @@ void GLReplay::SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSize) m_pDriver->glNamedBufferSubDataEXT(buf, 0, dataSize, data); } +vector GLReplay::GetUsage(ResourceId id) +{ + return m_pDriver->GetUsage(id); +} + #pragma endregion -vector GLReplay::GetUsage(ResourceId id) -{ - GLNOTIMP("GetUsage"); - return vector(); -} void GLReplay::SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv) { diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index aa54c3ba2..950bfa9e6 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -196,8 +196,6 @@ class GLReplay : public IReplayDriver void CreateCustomShaderTex(uint32_t w, uint32_t h); void SetupOverlayPipeline(GLuint Program, GLuint Pipeline, GLuint fragProgram); - - void GetMapping(WrappedOpenGL &gl, GLuint curProg, int shadIdx, ShaderReflection *refl, ShaderBindpointMapping &mapping); void CopyArrayToTex2DMS(GLuint destMS, GLuint srcArray, GLint width, GLint height, GLint arraySize, GLint samples, GLenum intFormat); void CopyTex2DMSToArray(GLuint destArray, GLuint srcMS, GLint width, GLint height, GLint arraySize, GLint samples, GLenum intFormat); diff --git a/renderdoc/driver/gl/gl_shader_refl.cpp b/renderdoc/driver/gl/gl_shader_refl.cpp index 7d9adc42d..a9a83d05b 100644 --- a/renderdoc/driver/gl/gl_shader_refl.cpp +++ b/renderdoc/driver/gl/gl_shader_refl.cpp @@ -1744,3 +1744,194 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg, refl.ConstantBlocks = cbuffers; } +void GetBindpointMapping(const GLHookSet &gl, GLuint curProg, int shadIdx, ShaderReflection *refl, ShaderBindpointMapping &mapping) +{ + // in case of bugs, we readback into this array instead of + GLint dummyReadback[32]; + +#if !defined(RELEASE) + for(size_t i=1; i < ARRAY_COUNT(dummyReadback); i++) + dummyReadback[i] = 0x6c7b8a9d; +#endif + + const GLenum refEnum[] = { + eGL_REFERENCED_BY_VERTEX_SHADER, + eGL_REFERENCED_BY_TESS_CONTROL_SHADER, + eGL_REFERENCED_BY_TESS_EVALUATION_SHADER, + eGL_REFERENCED_BY_GEOMETRY_SHADER, + eGL_REFERENCED_BY_FRAGMENT_SHADER, + eGL_REFERENCED_BY_COMPUTE_SHADER, + }; + + create_array_uninit(mapping.Resources, refl->Resources.count); + for(int32_t i=0; i < refl->Resources.count; i++) + { + if(refl->Resources.elems[i].IsTexture) + { + // normal sampler or image load/store + + GLint loc = gl.glGetUniformLocation(curProg, refl->Resources.elems[i].name.elems); + if(loc >= 0) + { + gl.glGetUniformiv(curProg, loc, dummyReadback); + mapping.Resources[i].bind = dummyReadback[0]; + } + + // handle sampler arrays, use the base name + string name = refl->Resources.elems[i].name.elems; + if(name.back() == ']') + { + do + { + name.pop_back(); + } while(name.back() != '['); + name.pop_back(); + } + + GLuint idx = 0; + idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, name.c_str()); + + if(idx == GL_INVALID_INDEX) + { + mapping.Resources[i].used = false; + } + else + { + GLint used = 0; + gl.glGetProgramResourceiv(curProg, eGL_UNIFORM, idx, 1, &refEnum[shadIdx], 1, NULL, &used); + mapping.Resources[i].used = (used != 0); + } + } + else if(refl->Resources.elems[i].IsReadWrite && !refl->Resources.elems[i].IsTexture) + { + if(refl->Resources.elems[i].variableType.descriptor.cols == 1 && + refl->Resources.elems[i].variableType.descriptor.rows == 1 && + refl->Resources.elems[i].variableType.descriptor.type == eVar_UInt) + { + // atomic uint + GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM, refl->Resources.elems[i].name.elems); + + if(idx == GL_INVALID_INDEX) + { + mapping.Resources[i].bind = -1; + mapping.Resources[i].used = false; + } + else + { + GLenum prop = eGL_ATOMIC_COUNTER_BUFFER_INDEX; + GLuint atomicIndex; + gl.glGetProgramResourceiv(curProg, eGL_UNIFORM, idx, 1, &prop, 1, NULL, (GLint *)&atomicIndex); + + if(atomicIndex == GL_INVALID_INDEX) + { + mapping.Resources[i].bind = -1; + mapping.Resources[i].used = false; + } + else + { + const GLenum atomicRefEnum[] = { + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER, + eGL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER, + }; + gl.glGetActiveAtomicCounterBufferiv(curProg, atomicIndex, eGL_ATOMIC_COUNTER_BUFFER_BINDING, &mapping.Resources[i].bind); + GLint used = 0; + gl.glGetActiveAtomicCounterBufferiv(curProg, atomicIndex, atomicRefEnum[shadIdx], &used); + mapping.Resources[i].used = (used != 0); + } + } + } + else + { + // shader storage buffer object + GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_SHADER_STORAGE_BLOCK, refl->Resources.elems[i].name.elems); + + if(idx == GL_INVALID_INDEX) + { + mapping.Resources[i].bind = -1; + mapping.Resources[i].used = false; + } + else + { + GLenum prop = eGL_BUFFER_BINDING; + gl.glGetProgramResourceiv(curProg, eGL_SHADER_STORAGE_BLOCK, idx, 1, &prop, 1, NULL, &mapping.Resources[i].bind); + GLint used = 0; + gl.glGetProgramResourceiv(curProg, eGL_SHADER_STORAGE_BLOCK, idx, 1, &refEnum[shadIdx], 1, NULL, &used); + mapping.Resources[i].used = (used != 0); + } + } + } + else + { + mapping.Resources[i].bind = -1; + mapping.Resources[i].used = false; + } + } + + create_array_uninit(mapping.ConstantBlocks, refl->ConstantBlocks.count); + for(int32_t i=0; i < refl->ConstantBlocks.count; i++) + { + if(refl->ConstantBlocks.elems[i].bufferBacked) + { + GLint loc = gl.glGetUniformBlockIndex(curProg, refl->ConstantBlocks.elems[i].name.elems); + if(loc >= 0) + { + gl.glGetActiveUniformBlockiv(curProg, loc, eGL_UNIFORM_BLOCK_BINDING, dummyReadback); + mapping.ConstantBlocks[i].bind = dummyReadback[0]; + } + } + else + { + mapping.ConstantBlocks[i].bind = -1; + } + + if(!refl->ConstantBlocks.elems[i].bufferBacked) + { + mapping.ConstantBlocks[i].used = true; + } + else + { + GLuint idx = gl.glGetProgramResourceIndex(curProg, eGL_UNIFORM_BLOCK, refl->ConstantBlocks.elems[i].name.elems); + if(idx == GL_INVALID_INDEX) + { + mapping.ConstantBlocks[i].used = false; + } + else + { + GLint used = 0; + gl.glGetProgramResourceiv(curProg, eGL_UNIFORM_BLOCK, idx, 1, &refEnum[shadIdx], 1, NULL, &used); + mapping.ConstantBlocks[i].used = (used != 0); + } + } + } + + GLint numVAttribBindings = 16; + gl.glGetIntegerv(eGL_MAX_VERTEX_ATTRIBS, &numVAttribBindings); + + create_array_uninit(mapping.InputAttributes, numVAttribBindings); + for(int32_t i=0; i < numVAttribBindings; i++) + mapping.InputAttributes[i] = -1; + + // override identity map with bindings + if(shadIdx == 0) + { + for(int32_t i=0; i < refl->InputSig.count; i++) + { + GLint loc = gl.glGetAttribLocation(curProg, refl->InputSig.elems[i].varName.elems); + + if(loc >= 0 && loc < numVAttribBindings) + { + mapping.InputAttributes[loc] = i; + } + } + } + +#if !defined(RELEASE) + for(size_t i=1; i < ARRAY_COUNT(dummyReadback); i++) + if(dummyReadback[i] != 0x6c7b8a9d) + RDCERR("Invalid uniform readback - data beyond first element modified!"); +#endif +} diff --git a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp index d0766e9e6..209f59679 100644 --- a/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_draw_funcs.cpp @@ -2543,8 +2543,26 @@ bool WrappedOpenGL::Serialise_glClearNamedFramebufferfv(GLuint framebuffer, GLen FetchDrawcall draw; draw.name = name; draw.flags |= eDraw_Clear; + if(buf == eGL_COLOR) + draw.flags |= eDraw_ClearColour; + else + draw.flags |= eDraw_ClearDepthStencil; AddDrawcall(draw, true); + + GLuint attachment = 0; + GLenum attachName = buf == eGL_COLOR ? GLenum(eGL_COLOR_ATTACHMENT0 + drawbuf) : eGL_DEPTH_ATTACHMENT; + GLenum type = eGL_TEXTURE; + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + } } @@ -2649,8 +2667,26 @@ bool WrappedOpenGL::Serialise_glClearNamedFramebufferiv(GLuint framebuffer, GLen FetchDrawcall draw; draw.name = name; draw.flags |= eDraw_Clear; + if(buf == eGL_COLOR) + draw.flags |= eDraw_ClearColour; + else + draw.flags |= eDraw_ClearDepthStencil; AddDrawcall(draw, true); + + GLuint attachment = 0; + GLenum attachName = buf == eGL_COLOR ? GLenum(eGL_COLOR_ATTACHMENT0 + drawbuf) : eGL_STENCIL_ATTACHMENT; + GLenum type = eGL_TEXTURE; + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + } } @@ -2740,9 +2776,23 @@ bool WrappedOpenGL::Serialise_glClearNamedFramebufferuiv(GLuint framebuffer, GLe FetchDrawcall draw; draw.name = name; - draw.flags |= eDraw_Clear; + draw.flags |= eDraw_Clear|eDraw_ClearColour; AddDrawcall(draw, true); + + GLuint attachment = 0; + GLenum attachName = GLenum(eGL_COLOR_ATTACHMENT0 + drawbuf); + GLenum type = eGL_TEXTURE; + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + } } return true; @@ -2817,9 +2867,35 @@ bool WrappedOpenGL::Serialise_glClearNamedFramebufferfi(GLuint framebuffer, GLen FetchDrawcall draw; draw.name = name; - draw.flags |= eDraw_Clear; + draw.flags |= eDraw_Clear|eDraw_ClearDepthStencil; AddDrawcall(draw, true); + + GLuint attachment = 0; + GLenum type = eGL_TEXTURE; + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + } + + attachment = 0; + type = eGL_TEXTURE; + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(framebuffer, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + } } return true; @@ -3123,8 +3199,69 @@ bool WrappedOpenGL::Serialise_glClear(GLbitfield mask) FetchDrawcall draw; draw.name = name; draw.flags |= eDraw_Clear; + if(Mask & GL_COLOR_BUFFER_BIT) + draw.flags |= eDraw_ClearColour; + if(Mask & (eGL_DEPTH_BUFFER_BIT|eGL_STENCIL_BUFFER_BIT)) + draw.flags |= eDraw_ClearDepthStencil; AddDrawcall(draw, true); + + GLuint attachment = 0; + GLenum type = eGL_TEXTURE; + + if(Mask & GL_DEPTH_BUFFER_BIT) + { + m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); + m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_DEPTH_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + } + } + + attachment = 0; + type = eGL_TEXTURE; + + if(Mask & GL_STENCIL_BUFFER_BIT) + { + m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); + m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, eGL_STENCIL_ATTACHMENT, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + } + } + + if(Mask & GL_COLOR_BUFFER_BIT) + { + GLint numCols = 8; + m_Real.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); + + for(int i=0; i < numCols; i++) + { + attachment = 0; + type = eGL_TEXTURE; + + m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&attachment); + m_Real.glGetFramebufferAttachmentParameteriv(eGL_DRAW_FRAMEBUFFER, GLenum(eGL_COLOR_ATTACHMENT0+i), eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&type); + + if(attachment) + { + if(type == eGL_TEXTURE) + m_ResourceUses[GetResourceManager()->GetID(TextureRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + else + m_ResourceUses[GetResourceManager()->GetID(RenderbufferRes(GetCtx(), attachment))].push_back(EventUsage(m_CurEventID, eUsage_Clear)); + } + } + } } return true; diff --git a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp index 8ea28af72..2646a9d6e 100644 --- a/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_framebuffer_funcs.cpp @@ -1275,6 +1275,59 @@ bool WrappedOpenGL::Serialise_glBlitNamedFramebuffer(GLuint readFramebuffer, GLu draw.flags |= eDraw_Resolve; AddDrawcall(draw, true); + + GLint numCols = 8; + m_Real.glGetIntegerv(eGL_MAX_COLOR_ATTACHMENTS, &numCols); + + for(int i=0; i < numCols+2; i++) + { + GLenum attachName = GLenum(eGL_COLOR_ATTACHMENT0+i); + if(i == numCols ) attachName = eGL_DEPTH_ATTACHMENT; + if(i == numCols+1) attachName = eGL_STENCIL_ATTACHMENT; + + GLuint srcattachment = 0, dstattachment = 0; + GLenum srctype = eGL_TEXTURE, dsttype = eGL_TEXTURE; + + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(readFramebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&srcattachment); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(readFramebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&srctype); + + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(drawFramebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, (GLint*)&dstattachment); + m_Real.glGetNamedFramebufferAttachmentParameterivEXT(drawFramebuffer, attachName, eGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, (GLint*)&dsttype); + + ResourceId srcid, dstid; + + if(srctype == eGL_TEXTURE) + srcid = GetResourceManager()->GetID(TextureRes(GetCtx(), srcattachment)); + else + srcid = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), srcattachment)); + + if(dstattachment == srcattachment) + { + m_ResourceUses[srcid].push_back(EventUsage(m_CurEventID, eUsage_Copy)); + } + else + { + if(dsttype == eGL_TEXTURE) + dstid = GetResourceManager()->GetID(TextureRes(GetCtx(), dstattachment)); + else + dstid = GetResourceManager()->GetID(RenderbufferRes(GetCtx(), dstattachment)); + + // MS to non-MS is a resolve + if((m_Textures[srcid].curType == eGL_TEXTURE_2D_MULTISAMPLE || + m_Textures[srcid].curType == eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) && + m_Textures[dstid].curType != eGL_TEXTURE_2D_MULTISAMPLE && + m_Textures[dstid].curType != eGL_TEXTURE_2D_MULTISAMPLE_ARRAY) + { + m_ResourceUses[srcid].push_back(EventUsage(m_CurEventID, eUsage_ResolveSrc)); + m_ResourceUses[dstid].push_back(EventUsage(m_CurEventID, eUsage_ResolveDst)); + } + else + { + m_ResourceUses[srcid].push_back(EventUsage(m_CurEventID, eUsage_CopySrc)); + m_ResourceUses[dstid].push_back(EventUsage(m_CurEventID, eUsage_CopyDst)); + } + } + } } return true; diff --git a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp index 20e87352d..4de9c06c0 100644 --- a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp @@ -655,6 +655,8 @@ bool WrappedOpenGL::Serialise_glGenerateTextureMipmapEXT(GLuint texture, GLenum draw.flags |= eDraw_GenMips; AddDrawcall(draw, true); + + m_ResourceUses[GetResourceManager()->GetLiveID(id)].push_back(EventUsage(m_CurEventID, eUsage_GenMips)); } return true; @@ -772,6 +774,16 @@ bool WrappedOpenGL::Serialise_glCopyImageSubData(GLuint srcName, GLenum srcTarge draw.flags |= eDraw_Copy; AddDrawcall(draw, true); + + if(srcid == dstid) + { + m_ResourceUses[GetResourceManager()->GetLiveID(srcid)].push_back(EventUsage(m_CurEventID, eUsage_Copy)); + } + else + { + m_ResourceUses[GetResourceManager()->GetLiveID(srcid)].push_back(EventUsage(m_CurEventID, eUsage_CopySrc)); + m_ResourceUses[GetResourceManager()->GetLiveID(dstid)].push_back(EventUsage(m_CurEventID, eUsage_CopyDst)); + } } return true; diff --git a/renderdoc/replay/replay_renderer.cpp b/renderdoc/replay/replay_renderer.cpp index aec998ea1..cf7e37538 100644 --- a/renderdoc/replay/replay_renderer.cpp +++ b/renderdoc/replay/replay_renderer.cpp @@ -1138,20 +1138,20 @@ bool ReplayRenderer::PixelHistory(ResourceId target, uint32_t x, uint32_t y, uin switch(usage[i].usage) { - case eUsage_IA_VB: - case eUsage_IA_IB: - case eUsage_VS_CB: - case eUsage_HS_CB: - case eUsage_DS_CB: - case eUsage_GS_CB: - case eUsage_PS_CB: - case eUsage_CS_CB: - case eUsage_VS_SRV: - case eUsage_HS_SRV: - case eUsage_DS_SRV: - case eUsage_GS_SRV: - case eUsage_PS_SRV: - case eUsage_CS_SRV: + case eUsage_VertexBuffer: + case eUsage_IndexBuffer: + case eUsage_VS_Constants: + case eUsage_HS_Constants: + case eUsage_DS_Constants: + case eUsage_GS_Constants: + case eUsage_PS_Constants: + case eUsage_CS_Constants: + case eUsage_VS_Resource: + case eUsage_HS_Resource: + case eUsage_DS_Resource: + case eUsage_GS_Resource: + case eUsage_PS_Resource: + case eUsage_CS_Resource: case eUsage_CopySrc: case eUsage_ResolveSrc: // read-only, not a valid pixel history event @@ -1159,10 +1159,14 @@ bool ReplayRenderer::PixelHistory(ResourceId target, uint32_t x, uint32_t y, uin case eUsage_None: case eUsage_SO: - case eUsage_CS_UAV: - case eUsage_PS_UAV: - case eUsage_OM_RTV: - case eUsage_OM_DSV: + case eUsage_VS_RWResource: + case eUsage_HS_RWResource: + case eUsage_DS_RWResource: + case eUsage_GS_RWResource: + case eUsage_PS_RWResource: + case eUsage_CS_RWResource: + case eUsage_ColourTarget: + case eUsage_DepthStencilTarget: case eUsage_Clear: case eUsage_Copy: case eUsage_CopyDst: diff --git a/renderdocui/Interop/Enums.cs b/renderdocui/Interop/Enums.cs index a645fc53e..86b457980 100644 --- a/renderdocui/Interop/Enums.cs +++ b/renderdocui/Interop/Enums.cs @@ -316,30 +316,34 @@ namespace renderdoc { None, - IA_VB, - IA_IB, + VertexBuffer, + IndexBuffer, - VS_CB, - HS_CB, - DS_CB, - GS_CB, - PS_CB, - CS_CB, + VS_Constants, + HS_Constants, + DS_Constants, + GS_Constants, + PS_Constants, + CS_Constants, SO, - VS_SRV, - HS_SRV, - DS_SRV, - GS_SRV, - PS_SRV, - CS_SRV, + VS_Resource, + HS_Resource, + DS_Resource, + GS_Resource, + PS_Resource, + CS_Resource, - CS_UAV, - PS_UAV, + VS_RWResource, + HS_RWResource, + DS_RWResource, + GS_RWResource, + PS_RWResource, + CS_RWResource, - OM_RTV, - OM_DSV, + ColourTarget, + DepthStencilTarget, Clear, @@ -561,44 +565,96 @@ namespace renderdoc return "Unknown resource type"; } - public static string Str(this ResourceUsage usage) + + public static string Str(this ResourceUsage usage, APIPipelineStateType apitype) { - switch (usage) + if (apitype == APIPipelineStateType.D3D11) { - case ResourceUsage.IA_VB: return "Vertex Buffer"; - case ResourceUsage.IA_IB: return "Index Buffer"; + switch (usage) + { + case ResourceUsage.VertexBuffer: return "Vertex Buffer"; + case ResourceUsage.IndexBuffer: return "Index Buffer"; - case ResourceUsage.VS_CB: return "VS - Constant Buffer"; - case ResourceUsage.GS_CB: return "GS - Constant Buffer"; - case ResourceUsage.HS_CB: return "HS - Constant Buffer"; - case ResourceUsage.DS_CB: return "DS - Constant Buffer"; - case ResourceUsage.CS_CB: return "CS - Constant Buffer"; - case ResourceUsage.PS_CB: return "PS - Constant Buffer"; + case ResourceUsage.VS_Constants: return "VS - Constant Buffer"; + case ResourceUsage.GS_Constants: return "GS - Constant Buffer"; + case ResourceUsage.HS_Constants: return "HS - Constant Buffer"; + case ResourceUsage.DS_Constants: return "DS - Constant Buffer"; + case ResourceUsage.CS_Constants: return "CS - Constant Buffer"; + case ResourceUsage.PS_Constants: return "PS - Constant Buffer"; - case ResourceUsage.SO: return "Stream Out"; + case ResourceUsage.SO: return "Stream Out"; - case ResourceUsage.VS_SRV: return "VS - Resource"; - case ResourceUsage.GS_SRV: return "GS - Resource"; - case ResourceUsage.HS_SRV: return "HS - Resource"; - case ResourceUsage.DS_SRV: return "DS - Resource"; - case ResourceUsage.CS_SRV: return "CS - Resource"; - case ResourceUsage.PS_SRV: return "PS - Resource"; + case ResourceUsage.VS_Resource: return "VS - Resource"; + case ResourceUsage.GS_Resource: return "GS - Resource"; + case ResourceUsage.HS_Resource: return "HS - Resource"; + case ResourceUsage.DS_Resource: return "DS - Resource"; + case ResourceUsage.CS_Resource: return "CS - Resource"; + case ResourceUsage.PS_Resource: return "PS - Resource"; - case ResourceUsage.CS_UAV: return "CS - UAV"; - case ResourceUsage.PS_UAV: return "PS - UAV"; + case ResourceUsage.VS_RWResource: return "VS - UAV"; + case ResourceUsage.HS_RWResource: return "HS - UAV"; + case ResourceUsage.DS_RWResource: return "DS - UAV"; + case ResourceUsage.GS_RWResource: return "GS - UAV"; + case ResourceUsage.PS_RWResource: return "PS - UAV"; + case ResourceUsage.CS_RWResource: return "CS - UAV"; - case ResourceUsage.OM_RTV: return "Rendertarget"; - case ResourceUsage.OM_DSV: return "Depthstencil"; + case ResourceUsage.ColourTarget: return "Rendertarget"; + case ResourceUsage.DepthStencilTarget: return "Depthstencil"; - case ResourceUsage.Clear: return "Clear"; + case ResourceUsage.Clear: return "Clear"; - case ResourceUsage.GenMips: return "Generate Mips"; - case ResourceUsage.Resolve: return "Resolve"; - case ResourceUsage.ResolveSrc: return "Resolve - Source"; - case ResourceUsage.ResolveDst: return "Resolve - Dest"; - case ResourceUsage.Copy: return "Copy"; - case ResourceUsage.CopySrc: return "Copy - Source"; - case ResourceUsage.CopyDst: return "Copy - Dest"; + case ResourceUsage.GenMips: return "Generate Mips"; + case ResourceUsage.Resolve: return "Resolve"; + case ResourceUsage.ResolveSrc: return "Resolve - Source"; + case ResourceUsage.ResolveDst: return "Resolve - Dest"; + case ResourceUsage.Copy: return "Copy"; + case ResourceUsage.CopySrc: return "Copy - Source"; + case ResourceUsage.CopyDst: return "Copy - Dest"; + } + } + else if (apitype == APIPipelineStateType.OpenGL) + { + switch (usage) + { + case ResourceUsage.VertexBuffer: return "Vertex Buffer"; + case ResourceUsage.IndexBuffer: return "Index Buffer"; + + case ResourceUsage.VS_Constants: return "VS - Uniform Buffer"; + case ResourceUsage.GS_Constants: return "GS - Uniform Buffer"; + case ResourceUsage.HS_Constants: return "HS - Uniform Buffer"; + case ResourceUsage.DS_Constants: return "DS - Uniform Buffer"; + case ResourceUsage.CS_Constants: return "CS - Uniform Buffer"; + case ResourceUsage.PS_Constants: return "PS - Uniform Buffer"; + + case ResourceUsage.SO: return "Transform Feedback"; + + case ResourceUsage.VS_Resource: return "VS - Texture"; + case ResourceUsage.GS_Resource: return "GS - Texture"; + case ResourceUsage.HS_Resource: return "HS - Texture"; + case ResourceUsage.DS_Resource: return "DS - Texture"; + case ResourceUsage.CS_Resource: return "CS - Texture"; + case ResourceUsage.PS_Resource: return "PS - Texture"; + + case ResourceUsage.VS_RWResource: return "VS - Image/SSBO"; + case ResourceUsage.HS_RWResource: return "HS - Image/SSBO"; + case ResourceUsage.DS_RWResource: return "DS - Image/SSBO"; + case ResourceUsage.GS_RWResource: return "GS - Image/SSBO"; + case ResourceUsage.PS_RWResource: return "PS - Image/SSBO"; + case ResourceUsage.CS_RWResource: return "CS - Image/SSBO"; + + case ResourceUsage.ColourTarget: return "FBO Colour"; + case ResourceUsage.DepthStencilTarget: return "FBO Depthstencil"; + + case ResourceUsage.Clear: return "Clear"; + + case ResourceUsage.GenMips: return "Generate Mips"; + case ResourceUsage.Resolve: return "Framebuffer blit"; + case ResourceUsage.ResolveSrc: return "Framebuffer blit - Source"; + case ResourceUsage.ResolveDst: return "Framebuffer blit - Dest"; + case ResourceUsage.Copy: return "Copy"; + case ResourceUsage.CopySrc: return "Copy - Source"; + case ResourceUsage.CopyDst: return "Copy - Dest"; + } } return "Unknown Usage String"; diff --git a/renderdocui/Windows/TextureViewer.cs b/renderdocui/Windows/TextureViewer.cs index 2da99f736..8a3563be5 100644 --- a/renderdocui/Windows/TextureViewer.cs +++ b/renderdocui/Windows/TextureViewer.cs @@ -3051,9 +3051,9 @@ namespace renderdocui.Windows ToolStripItem item = null; if (start == end) - item = new ToolStripLabel("EID " + start + ": " + usage.Str()); + item = new ToolStripLabel("EID " + start + ": " + usage.Str(m_Core.APIProps.pipelineType)); else - item = new ToolStripLabel("EID " + start + "-" + end + ": " + usage.Str()); + item = new ToolStripLabel("EID " + start + "-" + end + ": " + usage.Str(m_Core.APIProps.pipelineType)); item.Click += new EventHandler(resourceContextItem_Click); item.Tag = end; @@ -3091,7 +3091,7 @@ namespace renderdocui.Windows { uint start = 0; uint end = 0; - ResourceUsage us = ResourceUsage.IA_IB; + ResourceUsage us = ResourceUsage.IndexBuffer; foreach (var u in usage) { diff --git a/renderdocui/Windows/TimelineBar.cs b/renderdocui/Windows/TimelineBar.cs index 9ce390115..49569d135 100644 --- a/renderdocui/Windows/TimelineBar.cs +++ b/renderdocui/Windows/TimelineBar.cs @@ -620,8 +620,9 @@ namespace renderdocui.Windows if (u.eventID == s.draws[d].eventID) { // read/write - if (u.usage == ResourceUsage.CS_UAV || - u.usage == ResourceUsage.PS_UAV || + if ( + ((int)u.usage >= (int)ResourceUsage.VS_RWResource && + (int)u.usage <= (int)ResourceUsage.CS_RWResource) || u.usage == ResourceUsage.GenMips || u.usage == ResourceUsage.Copy || u.usage == ResourceUsage.Resolve) @@ -632,8 +633,8 @@ namespace renderdocui.Windows } // write else if (u.usage == ResourceUsage.SO || - u.usage == ResourceUsage.OM_DSV || - u.usage == ResourceUsage.OM_RTV || + u.usage == ResourceUsage.DepthStencilTarget || + u.usage == ResourceUsage.ColourTarget || u.usage == ResourceUsage.CopyDst || u.usage == ResourceUsage.ResolveDst) {