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.
This commit is contained in:
baldurk
2015-04-11 11:03:19 +01:00
parent e0e345abd7
commit a5cc19ccc6
19 changed files with 885 additions and 336 deletions
+14
View File
@@ -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;
};
+28 -24
View File
@@ -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
+11 -9
View File
@@ -3903,13 +3903,14 @@ vector<PixelModification> 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<PixelModification> 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 ||
+28 -16
View File
@@ -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<EventUsage> &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);
@@ -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);
+2
View File
@@ -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;
+259 -3
View File
@@ -798,8 +798,6 @@ void WrappedOpenGL::Initialise(GLInitParams &params)
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<EventUsage> &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.
+6 -1
View File
@@ -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<DrawcallTreeNode *> m_DrawcallStack;
map<ResourceId, vector<EventUsage> > m_ResourceUses;
// buffer used
vector<byte> 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<EventUsage> 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);
+1 -1
View File
@@ -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
{
+7 -205
View File
@@ -784,12 +784,6 @@ vector<DebugMessage> 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<EventUsage> GLReplay::GetUsage(ResourceId id)
{
return m_pDriver->GetUsage(id);
}
#pragma endregion
vector<EventUsage> GLReplay::GetUsage(ResourceId id)
{
GLNOTIMP("GetUsage");
return vector<EventUsage>();
}
void GLReplay::SetContextFilter(ResourceId id, uint32_t firstDefEv, uint32_t lastDefEv)
{
-2
View File
@@ -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);
+191
View File
@@ -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
}
+139 -2
View File
@@ -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;
@@ -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;
@@ -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;
+22 -18
View File
@@ -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:
+103 -47
View File
@@ -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";
+3 -3
View File
@@ -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)
{
+5 -4
View File
@@ -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)
{