mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-05 17:40:39 +00:00
Add WriteBeforeRead to FrameRefType.
`WriteBeforeRead` is used to signify that a resource is partially written, and then later read. For the purpose of correct replay, `WriteBeforeRead` can be treated as `Read`--the resource needs to be initialized once (so that the non-overwritten data is correct), but does not need to be reset for later replays (since performing the same write again will not change the data). However, it is useful to track this state separately from `Read`, because the user may inspect the resource at a point in time before the write, and it might be confusing to see the result of the future write (which would be visible if `WriteBeforeRead` was treated as `Read`). Change-Id: I7df58bacb4444f7e8d7e26a5532a55b0ff8f128d
This commit is contained in:
committed by
Baldur Karlsson
parent
30b02bc1dd
commit
40c56dafa3
@@ -83,21 +83,12 @@ FrameRefType ComposeFrameRefs(FrameRefType first, FrameRefType second)
|
||||
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_PartialWrite:
|
||||
case eFrameRef_CompleteWrite:
|
||||
case eFrameRef_ReadBeforeWrite:
|
||||
// First read, and then written
|
||||
return eFrameRef_ReadBeforeWrite;
|
||||
|
||||
default: RDCERR("Unknown FrameRefType: %d", second); return eFrameRef_Maximum;
|
||||
}
|
||||
case eFrameRef_WriteBeforeRead:
|
||||
if(IncludesWrite(second))
|
||||
// `first` reads before `second` writes
|
||||
return eFrameRef_ReadBeforeWrite;
|
||||
else
|
||||
return first;
|
||||
|
||||
case eFrameRef_CompleteWrite:
|
||||
case eFrameRef_ReadBeforeWrite:
|
||||
@@ -126,7 +117,12 @@ FrameRefType ComposeFrameRefsUnordered(FrameRefType first, FrameRefType second)
|
||||
|
||||
FrameRefType ComposeFrameRefsDisjoint(FrameRefType x, FrameRefType y)
|
||||
{
|
||||
return RDCMAX(x, y);
|
||||
if(x == eFrameRef_ReadBeforeWrite || y == eFrameRef_ReadBeforeWrite)
|
||||
// If any subresource is `ReadBeforeWrite`, then the whole resource is.
|
||||
return eFrameRef_ReadBeforeWrite;
|
||||
else
|
||||
// For all other cases, just return the larger value.
|
||||
return RDCMAX(x, y);
|
||||
}
|
||||
|
||||
bool IncludesRead(FrameRefType refType)
|
||||
@@ -134,6 +130,7 @@ bool IncludesRead(FrameRefType refType)
|
||||
switch(refType)
|
||||
{
|
||||
case eFrameRef_Read:
|
||||
case eFrameRef_WriteBeforeRead:
|
||||
case eFrameRef_ReadBeforeWrite: return true;
|
||||
default: return false;
|
||||
}
|
||||
@@ -145,6 +142,7 @@ bool IncludesWrite(FrameRefType refType)
|
||||
{
|
||||
case eFrameRef_PartialWrite:
|
||||
case eFrameRef_CompleteWrite:
|
||||
case eFrameRef_WriteBeforeRead:
|
||||
case eFrameRef_ReadBeforeWrite: return true;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
@@ -40,29 +40,33 @@
|
||||
// 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
|
||||
// +------------------ NONE -----------------------------+
|
||||
// | | |
|
||||
// read partialWrite completeWrite
|
||||
// | | |
|
||||
// V V V
|
||||
// READ PARTIAL_WRITE --completeWrite--> COMPLETE_WRITE
|
||||
// | |
|
||||
// | read
|
||||
// write |
|
||||
// | V
|
||||
// | WRITE_BEFORE_READ
|
||||
// V |
|
||||
// READ_BEFORE_WRITE <--write--+
|
||||
//
|
||||
// Note:
|
||||
// * All resources begin implicitly in the None state.
|
||||
// * The transitions labeled "write" correspond to either PartialWrite or
|
||||
// CompleteWrite (e.g. in the READ state, either a PartialWrite or a
|
||||
// CompleteWrite moves to the READ_BEFORE_WRITE 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.
|
||||
// ReadBeforeWrite moves from NONE state to READBEFOREWRITE state);
|
||||
// similarly, the state transitions for WriteBeforeRead are the composition
|
||||
// of the transition for write, followed by the transition for read.
|
||||
// * All other transitions (excluding ReadBeforeWrite and WriteBeforeRead)
|
||||
// that are not explicitly shown leave the state unchanged (e.g. a read in
|
||||
// the COMPLETE_WRITE state remains in the COMPLETE_WRITE state).
|
||||
enum FrameRefType
|
||||
{
|
||||
// Initial state, no reads or writes
|
||||
@@ -92,6 +96,13 @@ enum FrameRefType
|
||||
// initial contents; therefore, the initial contents will need to be reset
|
||||
// before each time we replay the frame.
|
||||
eFrameRef_ReadBeforeWrite = 4,
|
||||
|
||||
// Partial write followed by read;
|
||||
// For the purpose of correct replay, this is equivalent to `Read`. However,
|
||||
// if this resource is inspected by the user before the write, the future
|
||||
// read could, incorrectly, be observed. This is because read-only resources
|
||||
// are not reset, so the write from the previous replay may still be present.
|
||||
eFrameRef_WriteBeforeRead = 5,
|
||||
};
|
||||
|
||||
bool IncludesRead(FrameRefType refType);
|
||||
@@ -99,7 +110,7 @@ bool IncludesRead(FrameRefType refType);
|
||||
bool IncludesWrite(FrameRefType refType);
|
||||
|
||||
const FrameRefType eFrameRef_Minimum = eFrameRef_None;
|
||||
const FrameRefType eFrameRef_Maximum = eFrameRef_ReadBeforeWrite;
|
||||
const FrameRefType eFrameRef_Maximum = eFrameRef_WriteBeforeRead;
|
||||
|
||||
DECLARE_REFLECTION_ENUM(FrameRefType);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user