mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-13 17:25:54 +00:00
add D3D11 support for annotations on immediate context only
This commit is contained in:
@@ -528,6 +528,10 @@ bool D3D11InitParams::IsSupportedVersion(uint64_t ver)
|
||||
if(ver == 0x12)
|
||||
return true;
|
||||
|
||||
// 0x13 -> 0x14 - added serialised annotations
|
||||
if(ver == 0x12)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -403,6 +403,7 @@ enum class D3D11Chunk : uint32_t
|
||||
OpenSharedResource1,
|
||||
OpenSharedResourceByName,
|
||||
SetShaderExtUAV,
|
||||
SetCommandAnnotation,
|
||||
Max,
|
||||
};
|
||||
|
||||
|
||||
@@ -236,6 +236,17 @@ WrappedID3D11DeviceContext::~WrappedID3D11DeviceContext()
|
||||
|
||||
SAFE_DELETE(m_DescriptorStore);
|
||||
|
||||
// Clean up annotation data
|
||||
for(auto it = m_Annotations.begin(); it != m_Annotations.end(); ++it)
|
||||
delete it->second;
|
||||
m_Annotations.clear();
|
||||
|
||||
SAFE_DELETE(m_RootAnnotation);
|
||||
|
||||
for(SDObject *obj : m_EventAnnotations)
|
||||
delete obj;
|
||||
m_EventAnnotations.clear();
|
||||
|
||||
SAFE_DELETE(m_FrameReader);
|
||||
|
||||
SAFE_RELEASE(m_WrappedVideo.m_pReal);
|
||||
@@ -451,6 +462,35 @@ bool WrappedID3D11DeviceContext::Serialise_BeginCaptureFrame(SerialiserType &ser
|
||||
}
|
||||
}
|
||||
|
||||
// Serialize object annotations
|
||||
if(ser.VersionAtLeast(0x14))
|
||||
{
|
||||
SCOPED_LOCK(m_AnnotationsLock);
|
||||
|
||||
SERIALISE_ELEMENT_LOCAL(numAnnotations, uint32_t(m_Annotations.size()));
|
||||
|
||||
auto it = m_Annotations.begin();
|
||||
for(uint32_t i = 0; i < numAnnotations; i++)
|
||||
{
|
||||
SERIALISE_ELEMENT_LOCAL(id, it->first);
|
||||
SDObject *annotation = it->second;
|
||||
if(ser.IsReading())
|
||||
annotation = new SDObject(""_lit, ""_lit); // will be overwritten below
|
||||
ser.Serialise("annotation"_lit, *annotation);
|
||||
|
||||
if(ser.IsReading() && IsLoading(m_State))
|
||||
{
|
||||
m_Annotations[id] = annotation;
|
||||
m_pDevice->GetReplay()->GetResourceDesc(id).annotations = annotation;
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
if(numAnnotations > 0)
|
||||
m_pDevice->GetReplay()->WriteFrameRecord().frameInfo.containsAnnotations = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -895,6 +935,11 @@ bool WrappedID3D11DeviceContext::ProcessChunk(ReadSerialiser &ser, D3D11Chunk ch
|
||||
case D3D11Chunk::SetMarker: ret = Serialise_SetMarker(ser, 0, L""); break;
|
||||
case D3D11Chunk::PopMarker: ret = Serialise_PopMarker(ser); break;
|
||||
|
||||
case D3D11Chunk::SetCommandAnnotation:
|
||||
ret = Serialise_SetCommandAnnotation(ser, rdcstr(), eRENDERDOC_AnnotationMax, 0,
|
||||
RENDERDOC_AnnotationValue());
|
||||
break;
|
||||
|
||||
case D3D11Chunk::DiscardResource: ret = Serialise_DiscardResource(ser, NULL); break;
|
||||
case D3D11Chunk::DiscardView: ret = Serialise_DiscardView(ser, NULL); break;
|
||||
case D3D11Chunk::DiscardView1: ret = Serialise_DiscardView1(ser, NULL, NULL, 0); break;
|
||||
@@ -1014,7 +1059,8 @@ bool WrappedID3D11DeviceContext::ProcessChunk(ReadSerialiser &ser, D3D11Chunk ch
|
||||
m_ActionStack.pop_back();
|
||||
}
|
||||
|
||||
if(!m_AddedAction)
|
||||
// annotations don't add events
|
||||
if(!m_AddedAction && chunk != D3D11Chunk::SetCommandAnnotation)
|
||||
AddEvent();
|
||||
}
|
||||
|
||||
@@ -1212,6 +1258,13 @@ void WrappedID3D11DeviceContext::AddEvent()
|
||||
}
|
||||
}
|
||||
|
||||
// Apply current annotation state to this event
|
||||
if(m_RootAnnotation)
|
||||
{
|
||||
apievent.annotations = m_RootAnnotation->Duplicate();
|
||||
m_EventAnnotations.push_back(apievent.annotations);
|
||||
}
|
||||
|
||||
m_CurEvents.push_back(apievent);
|
||||
|
||||
if(IsLoading(m_State))
|
||||
@@ -1382,7 +1435,10 @@ RDResult WrappedID3D11DeviceContext::ReplayLog(CaptureState readType, uint32_t s
|
||||
break;
|
||||
|
||||
m_LastChunk = chunktype;
|
||||
m_CurEventID++;
|
||||
|
||||
// annotations do not produce events
|
||||
if(chunktype != D3D11Chunk::SetCommandAnnotation)
|
||||
m_CurEventID++;
|
||||
}
|
||||
|
||||
if(IsLoading(m_State))
|
||||
|
||||
@@ -227,6 +227,12 @@ private:
|
||||
rdcarray<Annotation> m_AnnotationQueue;
|
||||
Threading::CriticalSection m_AnnotLock;
|
||||
|
||||
// Object and command annotation support
|
||||
Threading::CriticalSection m_AnnotationsLock;
|
||||
std::unordered_map<ResourceId, SDObject *> m_Annotations; // Object annotations by ResourceId
|
||||
SDObject *m_RootAnnotation = NULL; // Root for event annotation state
|
||||
rdcarray<SDObject *> m_EventAnnotations; // Track allocations for cleanup
|
||||
|
||||
uint64_t m_TimeBase = 0;
|
||||
double m_TimeFrequency = 1.0f;
|
||||
SDFile *m_StructuredFile = NULL;
|
||||
@@ -290,12 +296,25 @@ private:
|
||||
|
||||
SERIALISED_ID3D11CONTEXT_MARKER_FUNCTIONS();
|
||||
|
||||
#define SERIALISED_ID3D11CONTEXT_ANNOTATION_FUNCTIONS() \
|
||||
IMPLEMENT_FUNCTION_SERIALISED(bool, SetCommandAnnotation, rdcstr key, \
|
||||
RENDERDOC_AnnotationType valueType, uint32_t valueVectorWidth, \
|
||||
RENDERDOC_AnnotationValue value);
|
||||
|
||||
SERIALISED_ID3D11CONTEXT_ANNOTATION_FUNCTIONS();
|
||||
|
||||
public:
|
||||
ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11DeviceContext);
|
||||
|
||||
WrappedID3D11DeviceContext(WrappedID3D11Device *realDevice, ID3D11DeviceContext *context);
|
||||
virtual ~WrappedID3D11DeviceContext();
|
||||
|
||||
void RemoveAnnotations(ResourceId id)
|
||||
{
|
||||
SCOPED_LOCK(m_AnnotationsLock);
|
||||
m_Annotations.erase(id);
|
||||
}
|
||||
|
||||
void SetReplayResourceID(ResourceId id) { m_ResourceID = id; }
|
||||
|
||||
void VerifyState();
|
||||
@@ -358,6 +377,12 @@ public:
|
||||
void IntAddRef();
|
||||
void IntRelease();
|
||||
|
||||
// annotations functions in DeviceContext (immediate only)
|
||||
uint32_t SetCommandAnnotation(const char *key, RENDERDOC_AnnotationType valueType,
|
||||
uint32_t valueVectorWidth, const RENDERDOC_AnnotationValue *value);
|
||||
uint32_t SetObjectAnnotation(void *object, const char *key, RENDERDOC_AnnotationType valueType,
|
||||
uint32_t valueVectorWidth, const RENDERDOC_AnnotationValue *value);
|
||||
|
||||
//////////////////////////////
|
||||
// implement IUnknown
|
||||
ULONG STDMETHODCALLTYPE AddRef();
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "tinyfiledialogs/tinyfiledialogs.h"
|
||||
#include "d3d11_debug.h"
|
||||
#include "d3d11_renderstate.h"
|
||||
#include "d3d11_replay.h"
|
||||
#include "d3d11_resources.h"
|
||||
|
||||
#ifndef DXGI_ERROR_INVALID_CALL
|
||||
@@ -188,6 +189,118 @@ int WrappedID3D11DeviceContext::PopMarker()
|
||||
return --m_MarkerIndentLevel;
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
bool WrappedID3D11DeviceContext::Serialise_SetCommandAnnotation(SerialiserType &ser, rdcstr key,
|
||||
RENDERDOC_AnnotationType valueType,
|
||||
uint32_t valueVectorWidth,
|
||||
RENDERDOC_AnnotationValue value)
|
||||
{
|
||||
SERIALISE_ELEMENT(key);
|
||||
SERIALISE_ELEMENT(valueType);
|
||||
ser.SetStructArg(valueType);
|
||||
SERIALISE_ELEMENT(valueVectorWidth);
|
||||
SERIALISE_ELEMENT(value);
|
||||
|
||||
SERIALISE_CHECK_READ_ERRORS();
|
||||
|
||||
if(IsReplayingAndReading())
|
||||
{
|
||||
if(IsLoading(m_State))
|
||||
{
|
||||
if(!m_RootAnnotation)
|
||||
m_RootAnnotation = new SDObject("Event Annotations"_lit, "Event Annotations"_lit);
|
||||
|
||||
SDObject *root = m_RootAnnotation;
|
||||
|
||||
if(valueType == eRENDERDOC_Empty)
|
||||
{
|
||||
root->EraseChildByKeyPath(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteAnnotation(root->CreateChildByKeyPath(key), valueType, valueVectorWidth, value);
|
||||
}
|
||||
|
||||
m_pDevice->GetReplay()->WriteFrameRecord().frameInfo.containsAnnotations = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t WrappedID3D11DeviceContext::SetCommandAnnotation(const char *key,
|
||||
RENDERDOC_AnnotationType valueType,
|
||||
uint32_t valueVectorWidth,
|
||||
const RENDERDOC_AnnotationValue *value)
|
||||
{
|
||||
SERIALISE_TIME_CALL();
|
||||
|
||||
if(IsActiveCapturing(m_State))
|
||||
{
|
||||
USE_SCRATCH_SERIALISER();
|
||||
GET_SERIALISER.SetActionChunk();
|
||||
SCOPED_SERIALISE_CHUNK(D3D11Chunk::SetCommandAnnotation);
|
||||
SERIALISE_ELEMENT(m_ResourceID).Named("Context"_lit).TypedAs("ID3D11DeviceContext *"_lit);
|
||||
|
||||
RENDERDOC_AnnotationValue val = value ? *value : RENDERDOC_AnnotationValue();
|
||||
|
||||
if(valueType == eRENDERDOC_APIObject && val.apiObject)
|
||||
{
|
||||
ResourceId id = GetIDForDeviceChild((ID3D11DeviceChild *)val.apiObject);
|
||||
RDCCOMPILE_ASSERT(sizeof(val.uint64) == sizeof(id), "ResourceId isn't 64-bit!");
|
||||
memcpy(&val.uint64, &id, sizeof(id));
|
||||
}
|
||||
|
||||
Serialise_SetCommandAnnotation(GET_SERIALISER, key, valueType, valueVectorWidth, val);
|
||||
|
||||
m_ContextRecord->AddChunk(scope.Get());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t WrappedID3D11DeviceContext::SetObjectAnnotation(void *object, const char *key,
|
||||
RENDERDOC_AnnotationType valueType,
|
||||
uint32_t valueVectorWidth,
|
||||
const RENDERDOC_AnnotationValue *value)
|
||||
{
|
||||
ResourceId id = GetIDForDeviceChild((ID3D11DeviceChild *)object);
|
||||
|
||||
if(id != ResourceId())
|
||||
{
|
||||
RENDERDOC_AnnotationValue val = value ? *value : RENDERDOC_AnnotationValue();
|
||||
|
||||
// Convert API object references to ResourceId
|
||||
if(valueType == eRENDERDOC_APIObject && val.apiObject)
|
||||
{
|
||||
ResourceId valId = GetIDForDeviceChild((ID3D11DeviceChild *)val.apiObject);
|
||||
RDCCOMPILE_ASSERT(sizeof(val.uint64) == sizeof(valId), "ResourceId isn't 64-bit!");
|
||||
memcpy(&val.uint64, &valId, sizeof(valId));
|
||||
}
|
||||
|
||||
SDObject *root = NULL;
|
||||
{
|
||||
SCOPED_LOCK(m_AnnotationsLock);
|
||||
root = m_Annotations[id];
|
||||
if(!root)
|
||||
root = m_Annotations[id] = new SDObject("Object Annotations"_lit, "Object Annotations"_lit);
|
||||
}
|
||||
|
||||
if(valueType == eRENDERDOC_Empty)
|
||||
{
|
||||
root->EraseChildByKeyPath(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteAnnotation(root->CreateChildByKeyPath(key), valueType, valueVectorWidth, val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
void WrappedID3D11DeviceContext::ThreadSafe_SetMarker(uint32_t col, const wchar_t *name)
|
||||
{
|
||||
Annotation annot;
|
||||
@@ -8153,3 +8266,4 @@ void WrappedID3D11DeviceContext::Unmap(ID3D11Resource *pResource, UINT Subresour
|
||||
|
||||
SERIALISED_ID3D11CONTEXT_FUNCTIONS();
|
||||
SERIALISED_ID3D11CONTEXT_MARKER_FUNCTIONS();
|
||||
SERIALISED_ID3D11CONTEXT_ANNOTATION_FUNCTIONS();
|
||||
|
||||
@@ -1230,6 +1230,7 @@ bool WrappedID3D11Device::ProcessChunk(ReadSerialiser &ser, D3D11Chunk context)
|
||||
case D3D11Chunk::PostExecuteCommandList:
|
||||
case D3D11Chunk::PostFinishCommandListSet:
|
||||
case D3D11Chunk::SwapDeviceContextState:
|
||||
case D3D11Chunk::SetCommandAnnotation:
|
||||
case D3D11Chunk::SwapchainPresent: return m_pImmediateContext->ProcessChunk(ser, context);
|
||||
|
||||
// no explicit default so that we have compiler warnings if a chunk isn't explicitly handled.
|
||||
@@ -1947,6 +1948,9 @@ void WrappedID3D11Device::DestroyDeadObject(ID3D11DeviceChild *child)
|
||||
{
|
||||
ResourceId id = wrapped->GetResourceID();
|
||||
|
||||
if(m_pImmediateContext)
|
||||
m_pImmediateContext->RemoveAnnotations(id);
|
||||
|
||||
// clean up book-keeping
|
||||
rm->RemoveWrapper(wrapped->GetReal());
|
||||
rm->ReleaseResource(id);
|
||||
@@ -1998,6 +2002,32 @@ int WrappedID3D11Device::EndEvent()
|
||||
return m_pCurrentWrappedDevice->m_pImmediateContext->ThreadSafe_EndEvent();
|
||||
}
|
||||
|
||||
uint32_t WrappedID3D11Device::SetObjectAnnotation(void *object, const char *key,
|
||||
RENDERDOC_AnnotationType valueType,
|
||||
uint32_t valueVectorWidth,
|
||||
const RENDERDOC_AnnotationValue *value)
|
||||
{
|
||||
return m_pImmediateContext->SetObjectAnnotation(object, key, valueType, valueVectorWidth, value);
|
||||
}
|
||||
|
||||
uint32_t WrappedID3D11Device::SetCommandAnnotation(void *queueOrCommandBuffer, const char *key,
|
||||
RENDERDOC_AnnotationType valueType,
|
||||
uint32_t valueVectorWidth,
|
||||
const RENDERDOC_AnnotationValue *value)
|
||||
{
|
||||
if(queueOrCommandBuffer != NULL && queueOrCommandBuffer != m_pImmediateContext)
|
||||
return 2;
|
||||
|
||||
// D3D11 doesn't have queues or command buffers, so we accept NULL
|
||||
// and treat all command annotations as immediate/global
|
||||
if(IsActiveCapturing(m_State))
|
||||
{
|
||||
return m_pImmediateContext->SetCommandAnnotation(key, valueType, valueVectorWidth, value);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WrappedID3D11Device::StartFrameCapture(DeviceOwnedWindow devWnd)
|
||||
{
|
||||
SCOPED_LOCK(m_D3DLock);
|
||||
|
||||
@@ -82,7 +82,7 @@ struct D3D11InitParams
|
||||
uint32_t VendorUAV = ~0U;
|
||||
|
||||
// check if a frame capture section version is supported
|
||||
static const uint64_t CurrentVersion = 0x13;
|
||||
static const uint64_t CurrentVersion = 0x14;
|
||||
static bool IsSupportedVersion(uint64_t ver);
|
||||
};
|
||||
|
||||
@@ -722,16 +722,10 @@ public:
|
||||
bool EndFrameCapture(DeviceOwnedWindow devWnd);
|
||||
bool DiscardFrameCapture(DeviceOwnedWindow devWnd);
|
||||
uint32_t SetObjectAnnotation(void *object, const char *key, RENDERDOC_AnnotationType valueType,
|
||||
uint32_t valueVectorWidth, const RENDERDOC_AnnotationValue *value)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
uint32_t valueVectorWidth, const RENDERDOC_AnnotationValue *value);
|
||||
uint32_t SetCommandAnnotation(void *queueOrCommandBuffer, const char *key,
|
||||
RENDERDOC_AnnotationType valueType, uint32_t valueVectorWidth,
|
||||
const RENDERDOC_AnnotationValue *value)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
const RENDERDOC_AnnotationValue *value);
|
||||
|
||||
ID3DUserDefinedAnnotation *GetAnnotations() { return m_RealAnnotations; }
|
||||
ID3D11InfoQueue *GetInfoQueue() { return m_pInfoQueue; }
|
||||
|
||||
@@ -59,7 +59,7 @@ rdcstr DoStringise(const D3D11ResourceType &el)
|
||||
template <>
|
||||
rdcstr DoStringise(const D3D11Chunk &el)
|
||||
{
|
||||
RDCCOMPILE_ASSERT((uint32_t)D3D11Chunk::Max == 1131, "Chunks changed without updating names");
|
||||
RDCCOMPILE_ASSERT((uint32_t)D3D11Chunk::Max == 1132, "Chunks changed without updating names");
|
||||
|
||||
BEGIN_ENUM_STRINGISE(D3D11Chunk)
|
||||
{
|
||||
@@ -213,6 +213,8 @@ rdcstr DoStringise(const D3D11Chunk &el)
|
||||
STRINGISE_ENUM_CLASS_NAMED(OpenSharedResource1, "ID3D11Device1::OpenSharedResource1");
|
||||
STRINGISE_ENUM_CLASS_NAMED(OpenSharedResourceByName, "ID3D11Device1::OpenSharedResourceByName");
|
||||
STRINGISE_ENUM_CLASS_NAMED(SetShaderExtUAV, "VendorExtension::SetExtensionUAVSlot");
|
||||
STRINGISE_ENUM_CLASS_NAMED(SetCommandAnnotation, "Internal::SetCommandAnnotation");
|
||||
|
||||
STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk");
|
||||
}
|
||||
END_ENUM_STRINGISE()
|
||||
|
||||
Reference in New Issue
Block a user