Force initial states for 'viewed' resources in GL

* If a buffer is used as a texbuffer, or a texture as a view, then any
  time the underlying data is dirty and needs to be saved as initial
  contents but the data object is never referenced directly (only the
  view), we need to force the underlying data object to have initial
  contents.
This commit is contained in:
baldurk
2016-09-28 15:09:02 +02:00
parent a9e4396655
commit 4ccfe298f3
11 changed files with 64 additions and 11 deletions
+3 -3
View File
@@ -427,7 +427,7 @@ protected:
virtual bool ResourceTypeRelease(WrappedResourceType res) = 0;
virtual bool Force_InitialState(WrappedResourceType res) = 0;
virtual bool Force_InitialState(WrappedResourceType res, bool prepare) = 0;
virtual bool AllowDeletedResource_InitialState() { return false; }
virtual bool Need_InitialStateChunk(WrappedResourceType res) = 0;
virtual bool Prepare_InitialState(WrappedResourceType res) = 0;
@@ -943,7 +943,7 @@ void ResourceManager<WrappedResourceType, RealResourceType, RecordType>::Prepare
if(it->second == (WrappedResourceType)RecordType::NullResource)
continue;
if(Force_InitialState(it->second))
if(Force_InitialState(it->second, true))
{
prepared++;
Prepare_InitialState(it->second);
@@ -1049,7 +1049,7 @@ void ResourceManager<WrappedResourceType, RealResourceType, RecordType>::InsertI
if(it->second == (WrappedResourceType)RecordType::NullResource)
continue;
if(Force_InitialState(it->second))
if(Force_InitialState(it->second, false))
{
dirty++;
+1 -1
View File
@@ -89,7 +89,7 @@ bool D3D11ResourceManager::ResourceTypeRelease(ID3D11DeviceChild *res)
return true;
}
bool D3D11ResourceManager::Force_InitialState(ID3D11DeviceChild *res)
bool D3D11ResourceManager::Force_InitialState(ID3D11DeviceChild *res, bool prepare)
{
return IdentifyTypeByPtr(res) == Resource_UnorderedAccessView;
}
+1 -1
View File
@@ -187,7 +187,7 @@ private:
bool ResourceTypeRelease(ID3D11DeviceChild *res);
bool Force_InitialState(ID3D11DeviceChild *res);
bool Force_InitialState(ID3D11DeviceChild *res, bool prepare);
bool Need_InitialStateChunk(ID3D11DeviceChild *res);
bool Prepare_InitialState(ID3D11DeviceChild *res);
bool Serialise_InitialState(ResourceId resid, ID3D11DeviceChild *res);
+1 -1
View File
@@ -431,7 +431,7 @@ bool D3D12ResourceManager::ResourceTypeRelease(ID3D12DeviceChild *res)
return true;
}
bool D3D12ResourceManager::Force_InitialState(ID3D12DeviceChild *res)
bool D3D12ResourceManager::Force_InitialState(ID3D12DeviceChild *res, bool prepare)
{
return false;
}
+1 -1
View File
@@ -323,7 +323,7 @@ private:
bool ResourceTypeRelease(ID3D12DeviceChild *res);
bool Force_InitialState(ID3D12DeviceChild *res);
bool Force_InitialState(ID3D12DeviceChild *res, bool prepare);
bool Need_InitialStateChunk(ID3D12DeviceChild *res);
bool Prepare_InitialState(ID3D12DeviceChild *res);
void Create_InitialState(ResourceId id, ID3D12DeviceChild *live, bool hasData);
+34 -1
View File
@@ -888,8 +888,41 @@ void GLResourceManager::PrepareTextureInitialContents(ResourceId liveid, Resourc
}
}
bool GLResourceManager::Force_InitialState(GLResource res)
bool GLResourceManager::Force_InitialState(GLResource res, bool prepare)
{
if(res.Namespace != eResBuffer && res.Namespace != eResTexture)
return false;
// don't need to force anything if we're already including all resources
if(RenderDoc::Inst().GetCaptureOptions().RefAllResources)
return false;
GLResourceRecord *record = GetResourceRecord(res);
// if we have some viewers, check to see if they were referenced but we weren't, and force our own
// initial state inclusion.
if(record && !record->viewTextures.empty())
{
// need to prepare all such resources, just in case for the worst case.
if(prepare)
return true;
// if this data resource was referenced already, just skip
if(m_FrameReferencedResources.find(record->GetResourceID()) != m_FrameReferencedResources.end())
return false;
// see if any of our viewers were referenced
for(auto it = record->viewTextures.begin(); it != record->viewTextures.end(); ++it)
{
// if so, return true to force our inclusion, for the benefit of the view
if(m_FrameReferencedResources.find(*it) != m_FrameReferencedResources.end())
{
RDCDEBUG("Forcing inclusion of %llu for %llu", record->GetResourceID(), *it);
return true;
}
}
}
return false;
}
+1 -1
View File
@@ -212,7 +212,7 @@ private:
bool SerialisableResource(ResourceId id, GLResourceRecord *record);
bool ResourceTypeRelease(GLResource res) { return true; }
bool Force_InitialState(GLResource res);
bool Force_InitialState(GLResource res, bool prepare);
bool Need_InitialStateChunk(GLResource res);
bool Prepare_InitialState(GLResource res);
+7
View File
@@ -258,6 +258,13 @@ struct GLResourceRecord : public ResourceRecord
GLenum datatype;
GLenum usage;
// for texture buffers and texture views, this points from the data texture (or buffer)
// to the view texture. When preparing resource initial states, we force initial states
// for anything that is viewed if the viewer is frame referenced. Otherwise we might
// lose the underlying data for the view.
// Since it's 1-to-many, we keep a set here.
set<ResourceId> viewTextures;
GLResource Resource;
void AllocShadowStorage(size_t size)
@@ -671,6 +671,7 @@ void WrappedOpenGL::glTextureView(GLuint texture, GLenum target, GLuint origtext
record->AddChunk(scope.Get());
record->AddParent(origrecord);
origrecord->viewTextures.insert(record->GetResourceID());
// illegal to re-type textures
record->VerifyDataType(target);
@@ -5483,7 +5484,10 @@ void WrappedOpenGL::Common_glTextureBufferRangeEXT(ResourceId texId, GLenum targ
GLResourceRecord *bufRecord = GetResourceManager()->GetResourceRecord(bufid);
if(bufRecord)
{
record->AddParent(bufRecord);
bufRecord->viewTextures.insert(record->GetResourceID());
}
}
return;
@@ -5512,7 +5516,10 @@ void WrappedOpenGL::Common_glTextureBufferRangeEXT(ResourceId texId, GLenum targ
GLResourceRecord *bufRecord = GetResourceManager()->GetResourceRecord(bufid);
if(bufRecord)
{
record->AddParent(bufRecord);
bufRecord->viewTextures.insert(record->GetResourceID());
}
}
}
@@ -5643,7 +5650,10 @@ void WrappedOpenGL::Common_glTextureBufferEXT(ResourceId texId, GLenum target,
GLResourceRecord *bufRecord = GetResourceManager()->GetResourceRecord(bufid);
if(bufRecord)
{
record->AddParent(bufRecord);
bufRecord->viewTextures.insert(record->GetResourceID());
}
}
return;
@@ -5673,7 +5683,10 @@ void WrappedOpenGL::Common_glTextureBufferEXT(ResourceId texId, GLenum target,
GLResourceRecord *bufRecord = GetResourceManager()->GetResourceRecord(bufid);
if(bufRecord)
{
record->AddParent(bufRecord);
bufRecord->viewTextures.insert(record->GetResourceID());
}
}
}
+1 -1
View File
@@ -527,7 +527,7 @@ void VulkanResourceManager::ApplyBarriers(vector<pair<ResourceId, ImageRegionSta
}
}
bool VulkanResourceManager::Force_InitialState(WrappedVkRes *res)
bool VulkanResourceManager::Force_InitialState(WrappedVkRes *res, bool prepare)
{
return false;
}
+1 -1
View File
@@ -252,7 +252,7 @@ private:
bool ResourceTypeRelease(WrappedVkRes *res);
bool Force_InitialState(WrappedVkRes *res);
bool Force_InitialState(WrappedVkRes *res, bool prepare);
bool AllowDeletedResource_InitialState() { return true; }
bool Need_InitialStateChunk(WrappedVkRes *res);
bool Prepare_InitialState(WrappedVkRes *res);