mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 10:00:40 +00:00
Refactor FrameRefType and add Clear reference type
This change simplifies the `FrameRefType` enum by removing the separate states and transitions, and replacing them with a smaller set of reference types, together with functions that compose those reference types. This change also introduces a `Clear` reference type, which is used to represent an access to the resource that completely overwrites the previous contents; this is in contrast with a `Write` access that may leave some of the previous contents untouched.
This commit is contained in:
committed by
Baldur Karlsson
parent
0f29c40c5f
commit
cf74b67660
@@ -25,6 +25,8 @@
|
||||
|
||||
#include "resource_manager.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace ResourceIDGen
|
||||
{
|
||||
static volatile int64_t globalIDCounter = 1;
|
||||
@@ -51,44 +53,96 @@ void SetReplayResourceIDs()
|
||||
|
||||
INSTANTIATE_SERIALISE_TYPE(ResourceManagerInternal::WrittenRecord);
|
||||
|
||||
FrameRefType ComposeFrameRefs(FrameRefType first, FrameRefType second)
|
||||
{
|
||||
RDCASSERT(eFrameRef_Minimum <= first && first <= eFrameRef_Maximum);
|
||||
RDCASSERT(eFrameRef_Minimum <= second && second <= eFrameRef_Maximum);
|
||||
|
||||
switch(first)
|
||||
{
|
||||
case eFrameRef_None:
|
||||
case eFrameRef_Write:
|
||||
if(second == eFrameRef_None)
|
||||
// A `None` reference after any other reference type does not change
|
||||
// the first reference type
|
||||
return first;
|
||||
else
|
||||
// A `None` or `Write` reference before any non-`None` reference type
|
||||
// does not change the reference type.
|
||||
return second;
|
||||
|
||||
case eFrameRef_Read:
|
||||
switch(second)
|
||||
{
|
||||
case eFrameRef_None:
|
||||
case eFrameRef_Read:
|
||||
// Only referenced as `Read` (and possibly `None`)
|
||||
return eFrameRef_Read;
|
||||
|
||||
case eFrameRef_Write:
|
||||
case eFrameRef_Clear:
|
||||
case eFrameRef_ReadBeforeWrite:
|
||||
// First read, and then written
|
||||
return eFrameRef_ReadBeforeWrite;
|
||||
|
||||
default: RDCERR("Unknown FrameRefType: %d", second); return eFrameRef_Maximum;
|
||||
}
|
||||
|
||||
case eFrameRef_Clear:
|
||||
case eFrameRef_ReadBeforeWrite:
|
||||
// These reference types are both locked in, and cannot be affected by
|
||||
// later references.
|
||||
return first;
|
||||
|
||||
default: RDCERR("Unknown FrameRefType: %d", first); return eFrameRef_Maximum;
|
||||
}
|
||||
}
|
||||
|
||||
FrameRefType ComposeFrameRefsUnordered(FrameRefType first, FrameRefType second)
|
||||
{
|
||||
RDCASSERT(eFrameRef_Minimum <= first && first <= eFrameRef_Maximum);
|
||||
RDCASSERT(eFrameRef_Minimum <= second && second <= eFrameRef_Maximum);
|
||||
|
||||
// The order of the reference types is irrelevant, so put them in a
|
||||
// consistent order (`first >= second`) to reduce the number of cases to
|
||||
// consider.
|
||||
if(first < second)
|
||||
std::swap(first, second);
|
||||
|
||||
if(first == eFrameRef_Read && (second == eFrameRef_Write || second == eFrameRef_Clear))
|
||||
// The resource is referenced both read and write/clear;
|
||||
// We don't know whether the read or write/clear occurs first;
|
||||
// if the write happens first, the final state would be Read or Clear;
|
||||
// if the read happens first, the final state would be ReadBeforeWrite.
|
||||
// We conservatively return ReadBeforeWrite, because this will force the
|
||||
// resource to be reset before each frame when replaying.
|
||||
return eFrameRef_ReadBeforeWrite;
|
||||
|
||||
// In all other cases, we just return the more conservative reference type--
|
||||
// i.e. the reference type with the strongest (re)initialization
|
||||
// requirements for replay. Because larger values in the `FrameRefType` have
|
||||
// stronger (re)initialization requirements, this is simply the maximum
|
||||
// reference type; note that `first >= second` by the earlier swap.
|
||||
return first;
|
||||
}
|
||||
|
||||
bool IsDirtyFrameRef(FrameRefType refType)
|
||||
{
|
||||
return (refType != eFrameRef_None && refType != eFrameRef_Read);
|
||||
}
|
||||
|
||||
bool MarkReferenced(std::map<ResourceId, FrameRefType> &refs, ResourceId id, FrameRefType refType)
|
||||
{
|
||||
if(refs.find(id) == refs.end())
|
||||
auto refit = refs.find(id);
|
||||
if(refit == refs.end())
|
||||
{
|
||||
if(refType == eFrameRef_Read)
|
||||
refs[id] = eFrameRef_ReadOnly;
|
||||
else if(refType == eFrameRef_Write)
|
||||
refs[id] = eFrameRef_ReadAndWrite;
|
||||
else // unknown or existing state
|
||||
refs[id] = refType;
|
||||
|
||||
refs[id] = refType;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(refType == eFrameRef_Unknown)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
else if(refType == eFrameRef_ReadBeforeWrite)
|
||||
{
|
||||
// special case, explicitly set to ReadBeforeWrite for when
|
||||
// we know that this use will likely be a partial-write
|
||||
refs[id] = eFrameRef_ReadBeforeWrite;
|
||||
}
|
||||
else if(refs[id] == eFrameRef_Unknown)
|
||||
{
|
||||
if(refType == eFrameRef_Read || refType == eFrameRef_ReadOnly)
|
||||
refs[id] = eFrameRef_ReadOnly;
|
||||
else
|
||||
refs[id] = eFrameRef_ReadAndWrite;
|
||||
}
|
||||
else if(refs[id] == eFrameRef_ReadOnly && refType == eFrameRef_Write)
|
||||
{
|
||||
refs[id] = eFrameRef_ReadBeforeWrite;
|
||||
}
|
||||
refit->second = ComposeFrameRefs(refit->second, refType);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -121,14 +175,9 @@ void ResourceRecord::Delete(ResourceRecordHandler *mgr)
|
||||
DataPtr = NULL;
|
||||
|
||||
for(auto it = m_FrameRefs.begin(); it != m_FrameRefs.end(); ++it)
|
||||
{
|
||||
if(it->second == eFrameRef_Write || it->second == eFrameRef_ReadAndWrite ||
|
||||
it->second == eFrameRef_ReadBeforeWrite)
|
||||
{
|
||||
if(IsDirtyFrameRef(it->second))
|
||||
// lost a write to this resource, must mark it as gpu dirty.
|
||||
mgr->MarkPendingDirty(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
DeleteChunks();
|
||||
|
||||
|
||||
@@ -36,23 +36,84 @@
|
||||
using std::set;
|
||||
using std::map;
|
||||
|
||||
// in what way (read, write, etc) was a resource referenced in a frame -
|
||||
// used to determine if initial contents are needed and to what degree
|
||||
// In what way (read, write, etc) was a resource referenced in a frame -
|
||||
// used to determine if initial contents are needed and to what degree.
|
||||
// These values are used both as states (representing the cumulative previous
|
||||
// accesses to the resource), and state transitions (access by a single
|
||||
// command, modifying the state). This state machine is illustrated below,
|
||||
// with states represented in caps, and transitions in lower case.
|
||||
//
|
||||
// +------------ NONE -------------+
|
||||
// | | |
|
||||
// read write clear
|
||||
// | | |
|
||||
// V V V
|
||||
// READ <--read-- WRITE --clear--> CLEAR
|
||||
// |
|
||||
// write/clear
|
||||
// |
|
||||
// V
|
||||
// READBEFOREWRITE
|
||||
//
|
||||
// Note:
|
||||
// * All resources begin implicitly in the None state.
|
||||
// * The state transitions for ReadBeforeWrite are simply the composition of
|
||||
// the transition for read, followed by the transition for write (e.g.
|
||||
// ReadBeforeWrite moves from NONE state to READBEFOREWRITE state).
|
||||
// * All other transitions (excluding ReadBeforeWrite) that are not explicitly
|
||||
// shown leave the state unchanged (e.g. a read in the CLEAR state remains
|
||||
// in the CLEAR state).
|
||||
//
|
||||
// The enum values are ordered so that larger values correspond to greater
|
||||
// requirements for (re)initialization of the resource during replay.
|
||||
enum FrameRefType
|
||||
{
|
||||
eFrameRef_Unknown, // for the initial start of frame pipeline state - can't be marked as
|
||||
// written/read yet until first action.
|
||||
// Initial state, no reads or writes
|
||||
eFrameRef_None = 0,
|
||||
|
||||
// Inputs
|
||||
eFrameRef_Read,
|
||||
eFrameRef_Write,
|
||||
// Write to some unknown subset of resource.
|
||||
// As a state, this represents that unlike clear, some part of the
|
||||
// initial contents might still be visible to later reads.
|
||||
eFrameRef_Write = 1,
|
||||
|
||||
// States
|
||||
eFrameRef_ReadOnly,
|
||||
eFrameRef_ReadAndWrite,
|
||||
eFrameRef_ReadBeforeWrite,
|
||||
// Clear the entire resource.
|
||||
// As a state, this represents that no later reads will even be able to see
|
||||
// the initial contents, and therefore, the initial contents need not be
|
||||
// restored for replay.
|
||||
eFrameRef_Clear = 2,
|
||||
|
||||
// Read from the resource;
|
||||
// As a state, this represents a read that could have seen the resource's
|
||||
// initial contents, but the value seen by the read has not been overwritten;
|
||||
// therefore, the initial contents needs to be restored before the first time
|
||||
// we replay, but doesn't need to be reset between subsequent replays.
|
||||
eFrameRef_Read = 3,
|
||||
|
||||
// Read followed by a write;
|
||||
// As a state, this represents a read that could have seen the resource
|
||||
// initial contents, followed by a write that could have modified that
|
||||
// initial contents; therefore, the initial contents will need to be reset
|
||||
// before each time we replay the frame.
|
||||
eFrameRef_ReadBeforeWrite = 4,
|
||||
};
|
||||
|
||||
const FrameRefType eFrameRef_Minimum = eFrameRef_None;
|
||||
const FrameRefType eFrameRef_Maximum = eFrameRef_ReadBeforeWrite;
|
||||
|
||||
// Compose frame refs that occur in a known order.
|
||||
// This can be thought of as a state (`first`) and a transition from that state
|
||||
// (`second`), returning the new state (see the state diagram for
|
||||
// `FrameRefType` above)
|
||||
FrameRefType ComposeFrameRefs(FrameRefType first, FrameRefType second);
|
||||
|
||||
// Compose frame refs when the order is unknown.
|
||||
// This is conservative, in that, if there is both a Read and a Write/Clear, it
|
||||
// assumes the Read occurs before the Write/Clear, forcing that resource to be
|
||||
// reset for replay.
|
||||
FrameRefType ComposeFrameRefsUnordered(FrameRefType first, FrameRefType second);
|
||||
|
||||
bool IsDirtyFrameRef(FrameRefType refType);
|
||||
|
||||
// handle marking a resource referenced for read or write and storing RAW access etc.
|
||||
bool MarkReferenced(std::map<ResourceId, FrameRefType> &refs, ResourceId id, FrameRefType refType);
|
||||
|
||||
@@ -685,8 +746,7 @@ void ResourceManager<Configuration>::Serialise_InitialContentsNeeded(WriteSerial
|
||||
for(auto it = m_FrameReferencedResources.begin(); it != m_FrameReferencedResources.end(); ++it)
|
||||
{
|
||||
RecordType *record = GetResourceRecord(it->first);
|
||||
|
||||
if(it->second != eFrameRef_ReadOnly && it->second != eFrameRef_Unknown)
|
||||
if(IsDirtyFrameRef(it->second))
|
||||
{
|
||||
WrittenRecord wr = {it->first, record ? record->DataInSerialiser : true};
|
||||
|
||||
@@ -698,7 +758,7 @@ void ResourceManager<Configuration>::Serialise_InitialContentsNeeded(WriteSerial
|
||||
{
|
||||
ResourceId id = *it;
|
||||
auto ref = m_FrameReferencedResources.find(id);
|
||||
if(ref == m_FrameReferencedResources.end() || ref->second == eFrameRef_ReadOnly)
|
||||
if(ref == m_FrameReferencedResources.end() || !IsDirtyFrameRef(ref->second))
|
||||
{
|
||||
WrittenRecord wr = {id, true};
|
||||
|
||||
|
||||
@@ -165,15 +165,14 @@ void D3D11RenderState::ReleaseRefs()
|
||||
|
||||
void D3D11RenderState::MarkReferenced(WrappedID3D11DeviceContext *ctx, bool initial) const
|
||||
{
|
||||
ctx->MarkResourceReferenced(GetIDForResource(IA.Layout),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
ctx->MarkResourceReferenced(GetIDForResource(IA.Layout), initial ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
ctx->MarkResourceReferenced(GetIDForResource(IA.IndexBuffer),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
for(UINT i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++)
|
||||
ctx->MarkResourceReferenced(GetIDForResource(IA.VBs[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
const Shader *stages[] = {&VS, &HS, &DS, &GS, &PS, &CS};
|
||||
for(int s = 0; s < 6; s++)
|
||||
@@ -181,24 +180,24 @@ void D3D11RenderState::MarkReferenced(WrappedID3D11DeviceContext *ctx, bool init
|
||||
const Shader *sh = stages[s];
|
||||
|
||||
ctx->MarkResourceReferenced(GetIDForResource(sh->Object),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
for(UINT i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++)
|
||||
ctx->MarkResourceReferenced(GetIDForResource(sh->ConstantBuffers[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
for(UINT i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; i++)
|
||||
ctx->MarkResourceReferenced(GetIDForResource(sh->Samplers[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
for(UINT i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++)
|
||||
{
|
||||
if(sh->SRVs[i])
|
||||
{
|
||||
ctx->MarkResourceReferenced(GetIDForResource(sh->SRVs[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
ctx->MarkResourceReferenced(GetViewResourceResID(sh->SRVs[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,37 +210,36 @@ void D3D11RenderState::MarkReferenced(WrappedID3D11DeviceContext *ctx, bool init
|
||||
{
|
||||
// UAVs we always assume to be partial updates
|
||||
ctx->MarkResourceReferenced(GetIDForResource(CSUAVs[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
ctx->MarkResourceReferenced(GetIDForResource(CSUAVs[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Write);
|
||||
initial ? eFrameRef_None : eFrameRef_Write);
|
||||
ctx->MarkResourceReferenced(GetViewResourceResID(CSUAVs[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
ctx->MarkResourceReferenced(GetViewResourceResID(CSUAVs[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Write);
|
||||
initial ? eFrameRef_None : eFrameRef_Write);
|
||||
}
|
||||
}
|
||||
|
||||
for(UINT i = 0; i < D3D11_SO_BUFFER_SLOT_COUNT; i++)
|
||||
ctx->MarkResourceReferenced(GetIDForResource(SO.Buffers[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Write);
|
||||
initial ? eFrameRef_None : eFrameRef_Write);
|
||||
|
||||
ctx->MarkResourceReferenced(GetIDForResource(RS.State),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
ctx->MarkResourceReferenced(GetIDForResource(RS.State), initial ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
ctx->MarkResourceReferenced(GetIDForResource(OM.BlendState),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
ctx->MarkResourceReferenced(GetIDForResource(OM.DepthStencilState),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
for(UINT i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
||||
{
|
||||
if(OM.RenderTargets[i])
|
||||
{
|
||||
ctx->MarkResourceReferenced(GetIDForResource(OM.RenderTargets[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
ctx->MarkResourceReferenced(GetViewResourceResID(OM.RenderTargets[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Write);
|
||||
initial ? eFrameRef_None : eFrameRef_Write);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,28 +249,28 @@ void D3D11RenderState::MarkReferenced(WrappedID3D11DeviceContext *ctx, bool init
|
||||
{
|
||||
// UAVs we always assume to be partial updates
|
||||
ctx->MarkResourceReferenced(GetIDForResource(OM.UAVs[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
ctx->MarkResourceReferenced(GetIDForResource(OM.UAVs[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Write);
|
||||
initial ? eFrameRef_None : eFrameRef_Write);
|
||||
ctx->MarkResourceReferenced(GetViewResourceResID(OM.UAVs[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
ctx->MarkResourceReferenced(GetViewResourceResID(OM.UAVs[i]),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Write);
|
||||
initial ? eFrameRef_None : eFrameRef_Write);
|
||||
}
|
||||
}
|
||||
|
||||
if(OM.DepthView)
|
||||
{
|
||||
ctx->MarkResourceReferenced(GetIDForResource(OM.DepthView),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
ctx->MarkResourceReferenced(GetViewResourceResID(OM.DepthView),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Write);
|
||||
initial ? eFrameRef_None : eFrameRef_Write);
|
||||
}
|
||||
|
||||
if(Predicate)
|
||||
{
|
||||
ctx->MarkResourceReferenced(GetIDForResource(Predicate),
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ void GLResourceManager::MarkVAOReferenced(GLResource res, FrameRefType ref, bool
|
||||
{
|
||||
ContextPair &ctx = m_Driver->GetCtx();
|
||||
|
||||
MarkResourceFrameReferenced(res, ref == eFrameRef_Unknown ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
MarkResourceFrameReferenced(res, ref == eFrameRef_None ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
GLint numVBufferBindings = GetNumVertexBuffers();
|
||||
|
||||
@@ -61,7 +61,7 @@ void GLResourceManager::MarkFBOReferenced(GLResource res, FrameRefType ref)
|
||||
if(res.name == 0)
|
||||
return;
|
||||
|
||||
MarkResourceFrameReferenced(res, ref == eFrameRef_Unknown ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
MarkResourceFrameReferenced(res, ref == eFrameRef_None ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
ContextPair &ctx = m_Driver->GetCtx();
|
||||
|
||||
|
||||
@@ -457,68 +457,66 @@ void GLRenderState::MarkReferenced(WrappedOpenGL *driver, bool initial) const
|
||||
|
||||
for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(Tex2D); i++)
|
||||
{
|
||||
manager->MarkResourceFrameReferenced(Tex1D[i], initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Tex2D[i], initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Tex3D[i], initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Tex1DArray[i], initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Tex2DArray[i], initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(TexCubeArray[i],
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(TexRect[i], initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(TexBuffer[i], initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(TexCube[i], initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Tex2DMS[i], initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Tex2DMSArray[i],
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Samplers[i], initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Tex1D[i], initial ? eFrameRef_None : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Tex2D[i], initial ? eFrameRef_None : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Tex3D[i], initial ? eFrameRef_None : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Tex1DArray[i], initial ? eFrameRef_None : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Tex2DArray[i], initial ? eFrameRef_None : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(TexCubeArray[i], initial ? eFrameRef_None : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(TexRect[i], initial ? eFrameRef_None : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(TexBuffer[i], initial ? eFrameRef_None : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(TexCube[i], initial ? eFrameRef_None : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Tex2DMS[i], initial ? eFrameRef_None : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Tex2DMSArray[i], initial ? eFrameRef_None : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Samplers[i], initial ? eFrameRef_None : eFrameRef_Read);
|
||||
}
|
||||
|
||||
for(GLuint i = 0; i < (GLuint)ARRAY_COUNT(Images); i++)
|
||||
{
|
||||
manager->MarkResourceFrameReferenced(Images[i].res,
|
||||
initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite);
|
||||
initial ? eFrameRef_None : eFrameRef_ReadBeforeWrite);
|
||||
driver->AddMissingTrack(manager->GetID(Images[i].res));
|
||||
}
|
||||
|
||||
manager->MarkVAOReferenced(VAO, initial ? eFrameRef_Unknown : eFrameRef_Read, true);
|
||||
manager->MarkVAOReferenced(VAO, initial ? eFrameRef_None : eFrameRef_Read, true);
|
||||
|
||||
manager->MarkResourceFrameReferenced(FeedbackObj, initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(FeedbackObj, initial ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
manager->MarkResourceFrameReferenced(Program, initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Pipeline, initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Program, initial ? eFrameRef_None : eFrameRef_Read);
|
||||
manager->MarkResourceFrameReferenced(Pipeline, initial ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
// the pipeline correctly has program parents, but we must also mark the programs as frame
|
||||
// referenced so that their
|
||||
// initial contents will be serialised.
|
||||
GLResourceRecord *record = manager->GetResourceRecord(Pipeline);
|
||||
if(record)
|
||||
record->MarkParentsReferenced(manager, initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
record->MarkParentsReferenced(manager, initial ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
for(size_t i = 0; i < ARRAY_COUNT(BufferBindings); i++)
|
||||
manager->MarkResourceFrameReferenced(BufferBindings[i],
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
for(size_t i = 0; i < ARRAY_COUNT(AtomicCounter); i++)
|
||||
manager->MarkResourceFrameReferenced(AtomicCounter[i].res,
|
||||
initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite);
|
||||
initial ? eFrameRef_None : eFrameRef_ReadBeforeWrite);
|
||||
|
||||
for(size_t i = 0; i < ARRAY_COUNT(ShaderStorage); i++)
|
||||
manager->MarkResourceFrameReferenced(ShaderStorage[i].res,
|
||||
initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite);
|
||||
initial ? eFrameRef_None : eFrameRef_ReadBeforeWrite);
|
||||
|
||||
for(size_t i = 0; i < ARRAY_COUNT(TransformFeedback); i++)
|
||||
manager->MarkResourceFrameReferenced(TransformFeedback[i].res,
|
||||
initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite);
|
||||
initial ? eFrameRef_None : eFrameRef_ReadBeforeWrite);
|
||||
|
||||
for(size_t i = 0; i < ARRAY_COUNT(UniformBinding); i++)
|
||||
manager->MarkResourceFrameReferenced(UniformBinding[i].res,
|
||||
initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
initial ? eFrameRef_None : eFrameRef_Read);
|
||||
|
||||
manager->MarkFBOReferenced(DrawFBO, initial ? eFrameRef_Unknown : eFrameRef_ReadBeforeWrite);
|
||||
manager->MarkFBOReferenced(DrawFBO, initial ? eFrameRef_None : eFrameRef_ReadBeforeWrite);
|
||||
|
||||
// if same FBO is bound to both targets, treat it as draw only
|
||||
if(ReadFBO != DrawFBO)
|
||||
manager->MarkFBOReferenced(ReadFBO, initial ? eFrameRef_Unknown : eFrameRef_Read);
|
||||
manager->MarkFBOReferenced(ReadFBO, initial ? eFrameRef_None : eFrameRef_Read);
|
||||
}
|
||||
|
||||
void GLRenderState::MarkDirty(WrappedOpenGL *driver)
|
||||
|
||||
@@ -1039,17 +1039,16 @@ public:
|
||||
RDCERR("Unexpected NULL resource ID being added as a bind frame ref");
|
||||
return;
|
||||
}
|
||||
|
||||
if((descInfo->bindFrameRefs[id].first & ~DescriptorSetData::SPARSE_REF_BIT) == 0)
|
||||
auto it = descInfo->bindFrameRefs.find(id);
|
||||
if((it->second.first & ~DescriptorSetData::SPARSE_REF_BIT) == 0)
|
||||
{
|
||||
descInfo->bindFrameRefs[id] =
|
||||
std::make_pair(1 | (hasSparse ? DescriptorSetData::SPARSE_REF_BIT : 0), ref);
|
||||
it->second = std::make_pair(1 | (hasSparse ? DescriptorSetData::SPARSE_REF_BIT : 0), ref);
|
||||
}
|
||||
else
|
||||
{
|
||||
// be conservative - mark refs as read before write if we see a write and a read ref on it
|
||||
if(ref == eFrameRef_Write && descInfo->bindFrameRefs[id].second == eFrameRef_Read)
|
||||
descInfo->bindFrameRefs[id].second = eFrameRef_ReadBeforeWrite;
|
||||
descInfo->bindFrameRefs[id].second =
|
||||
ComposeFrameRefsUnordered(descInfo->bindFrameRefs[id].second, ref);
|
||||
descInfo->bindFrameRefs[id].first++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user