mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 09:30:44 +00:00
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:
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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";
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user