diff --git a/renderdoc/core/resource_manager.h b/renderdoc/core/resource_manager.h index 4d4087ba5..3a03fdd9d 100644 --- a/renderdoc/core/resource_manager.h +++ b/renderdoc/core/resource_manager.h @@ -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::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::InsertI if(it->second == (WrappedResourceType)RecordType::NullResource) continue; - if(Force_InitialState(it->second)) + if(Force_InitialState(it->second, false)) { dirty++; diff --git a/renderdoc/driver/d3d11/d3d11_manager.cpp b/renderdoc/driver/d3d11/d3d11_manager.cpp index 5051f9180..e19b2a6e2 100644 --- a/renderdoc/driver/d3d11/d3d11_manager.cpp +++ b/renderdoc/driver/d3d11/d3d11_manager.cpp @@ -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; } diff --git a/renderdoc/driver/d3d11/d3d11_manager.h b/renderdoc/driver/d3d11/d3d11_manager.h index 25d1bbf82..f45486e64 100644 --- a/renderdoc/driver/d3d11/d3d11_manager.h +++ b/renderdoc/driver/d3d11/d3d11_manager.h @@ -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); diff --git a/renderdoc/driver/d3d12/d3d12_manager.cpp b/renderdoc/driver/d3d12/d3d12_manager.cpp index 954b1c1f7..8089be1a8 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.cpp +++ b/renderdoc/driver/d3d12/d3d12_manager.cpp @@ -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; } diff --git a/renderdoc/driver/d3d12/d3d12_manager.h b/renderdoc/driver/d3d12/d3d12_manager.h index 7c581a788..7933acce6 100644 --- a/renderdoc/driver/d3d12/d3d12_manager.h +++ b/renderdoc/driver/d3d12/d3d12_manager.h @@ -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); diff --git a/renderdoc/driver/gl/gl_manager.cpp b/renderdoc/driver/gl/gl_manager.cpp index 19bfc4d7e..5a0256ee1 100644 --- a/renderdoc/driver/gl/gl_manager.cpp +++ b/renderdoc/driver/gl/gl_manager.cpp @@ -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; } diff --git a/renderdoc/driver/gl/gl_manager.h b/renderdoc/driver/gl/gl_manager.h index a23d76dc8..e898b0397 100644 --- a/renderdoc/driver/gl/gl_manager.h +++ b/renderdoc/driver/gl/gl_manager.h @@ -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); diff --git a/renderdoc/driver/gl/gl_resources.h b/renderdoc/driver/gl/gl_resources.h index b64b1f6a8..e236ed9ad 100644 --- a/renderdoc/driver/gl/gl_resources.h +++ b/renderdoc/driver/gl/gl_resources.h @@ -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 viewTextures; + GLResource Resource; void AllocShadowStorage(size_t size) diff --git a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp index 5dfeaa2ee..93cbc0d11 100644 --- a/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp +++ b/renderdoc/driver/gl/wrappers/gl_texture_funcs.cpp @@ -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()); + } } } diff --git a/renderdoc/driver/vulkan/vk_manager.cpp b/renderdoc/driver/vulkan/vk_manager.cpp index c23af01b5..834c40ea2 100644 --- a/renderdoc/driver/vulkan/vk_manager.cpp +++ b/renderdoc/driver/vulkan/vk_manager.cpp @@ -527,7 +527,7 @@ void VulkanResourceManager::ApplyBarriers(vector