Iterate Action tree¶
In this example we will show how to iterate over actions.
The actions returned from GetRootActions()
are actions or marker regions at the root level - with no parent marker region. There are multiple ways to iterate through the list of actions.
The first way illustrated in this sample is to walk the tree using children
, which contains the list of child actions at any point in the tree. There is also parent
which points to the parent action.
The second is to use previous
and next
, which point to the previous and next action respectively in a linear fashion, regardless of nesting depth.
In the example we use this iteration to determine the number of passes, using the action flags to denote the start of each pass by a starting clear call.
Example Source¶
import sys
# Import renderdoc if not already imported (e.g. in the UI)
if 'renderdoc' not in sys.modules and '_renderdoc' not in sys.modules:
import renderdoc
# Alias renderdoc for legibility
rd = renderdoc
# Define a recursive function for iterating over actions
def iterAction(d, indent = ''):
# Print this action
print('%s%d: %s' % (indent, d.eventId, d.GetName(controller.GetStructuredFile())))
# Iterate over the action's children
for d in d.children:
iterAction(d, indent + ' ')
def sampleCode(controller):
# Iterate over all of the root actions
for d in controller.GetRootActions():
iterAction(d)
# Start iterating from the first real action as a child of markers
action = controller.GetRootActions()[0]
while len(action.children) > 0:
action = action.children[0]
# Counter for which pass we're in
passnum = 0
# Counter for how many actions are in the pass
passcontents = 0
# Whether we've started seeing actions in the pass - i.e. we're past any
# starting clear calls that may be batched together
inpass = False
print("Pass #0 starts with %d: %s" % (action.eventId, action.GetName(controller.GetStructuredFile())))
while action != None:
# When we encounter a clear
if action.flags & rd.ActionFlags.Clear:
if inpass:
print("Pass #%d contained %d actions" % (passnum, passcontents))
passnum += 1
print("Pass #%d starts with %d: %s" % (passnum, action.eventId, action.GetName(controller.GetStructuredFile())))
passcontents = 0
inpass = False
else:
passcontents += 1
inpass = True
# Advance to the next action
action = action.next
if action is None:
break
if inpass:
print("Pass #%d contained %d actions" % (passnum, passcontents))
def loadCapture(filename):
# Open a capture file handle
cap = rd.OpenCaptureFile()
# Open a particular file - see also OpenBuffer to load from memory
result = cap.OpenFile(filename, '', None)
# Make sure the file opened successfully
if result != rd.ResultCode.Succeeded:
raise RuntimeError("Couldn't open file: " + str(result))
# Make sure we can replay
if not cap.LocalReplaySupport():
raise RuntimeError("Capture cannot be replayed")
# Initialise the replay
result,controller = cap.OpenCapture(rd.ReplayOptions(), None)
if result != rd.ResultCode.Succeeded:
raise RuntimeError("Couldn't initialise replay: " + str(result))
return cap,controller
if 'pyrenderdoc' in globals():
pyrenderdoc.Replay().BlockInvoke(sampleCode)
else:
rd.InitialiseReplay(rd.GlobalEnvironment(), [])
if len(sys.argv) <= 1:
print('Usage: python3 {} filename.rdc'.format(sys.argv[0]))
sys.exit(0)
cap,controller = loadCapture(sys.argv[1])
sampleCode(controller)
controller.Shutdown()
cap.Shutdown()
rd.ShutdownReplay()
Sample output:
1: Scene
2: ID3D11DeviceContext::ClearRenderTargetView()
3: ID3D11DeviceContext::ClearDepthStencilView()
9: ID3D11DeviceContext::ClearRenderTargetView()
10: ID3D11DeviceContext::ClearRenderTargetView()
11: ID3D11DeviceContext::ClearDepthStencilView()
13: GBuffer
25: Floor
28: ID3D11DeviceContext::DrawIndexed()
29: empty label
30: ID3DUserDefinedAnnotation::EndEvent()
40: Base
43: ID3D11DeviceContext::DrawIndexed()
53: Center sphere
56: ID3D11DeviceContext::DrawIndexed()
66: Cone
69: ID3D11DeviceContext::DrawIndexed()
79: Cone
82: ID3D11DeviceContext::DrawIndexed()
92: Cone
95: ID3D11DeviceContext::DrawIndexed()
105: Cone
108: ID3D11DeviceContext::DrawIndexed()
118: Cone
121: ID3D11DeviceContext::DrawIndexed()
131: Cone
134: ID3D11DeviceContext::DrawIndexed()
144: Cone
147: ID3D11DeviceContext::DrawIndexed()
157: Cone
160: ID3D11DeviceContext::DrawIndexed()
170: Cone
173: ID3D11DeviceContext::DrawIndexed()
183: Cone
186: ID3D11DeviceContext::DrawIndexed()
196: Sphere
199: ID3D11DeviceContext::DrawIndexed()
209: Sphere
212: ID3D11DeviceContext::DrawIndexed()
222: Sphere
225: ID3D11DeviceContext::DrawIndexed()
235: Sphere
238: ID3D11DeviceContext::DrawIndexed()
248: Sphere
251: ID3D11DeviceContext::DrawIndexed()
261: Sphere
264: ID3D11DeviceContext::DrawIndexed()
274: Sphere
277: ID3D11DeviceContext::DrawIndexed()
287: Sphere
290: ID3D11DeviceContext::DrawIndexed()
300: Sphere
303: ID3D11DeviceContext::DrawIndexed()
313: Sphere
316: ID3D11DeviceContext::DrawIndexed()
317: ID3DUserDefinedAnnotation::EndEvent()
319: ID3D11DeviceContext::ClearDepthStencilView()
321: Shadowmap
330: Floor
333: ID3D11DeviceContext::DrawIndexed()
334: empty label
335: ID3DUserDefinedAnnotation::EndEvent()
342: Base
345: ID3D11DeviceContext::DrawIndexed()
352: Center sphere
355: ID3D11DeviceContext::DrawIndexed()
362: Cone
365: ID3D11DeviceContext::DrawIndexed()
372: Cone
375: ID3D11DeviceContext::DrawIndexed()
382: Cone
385: ID3D11DeviceContext::DrawIndexed()
392: Cone
395: ID3D11DeviceContext::DrawIndexed()
402: Cone
405: ID3D11DeviceContext::DrawIndexed()
412: Cone
415: ID3D11DeviceContext::DrawIndexed()
422: Cone
425: ID3D11DeviceContext::DrawIndexed()
432: Cone
435: ID3D11DeviceContext::DrawIndexed()
442: Cone
445: ID3D11DeviceContext::DrawIndexed()
452: Cone
455: ID3D11DeviceContext::DrawIndexed()
462: Sphere
465: ID3D11DeviceContext::DrawIndexed()
472: Sphere
475: ID3D11DeviceContext::DrawIndexed()
482: Sphere
485: ID3D11DeviceContext::DrawIndexed()
492: Sphere
495: ID3D11DeviceContext::DrawIndexed()
502: Sphere
505: ID3D11DeviceContext::DrawIndexed()
512: Sphere
515: ID3D11DeviceContext::DrawIndexed()
522: Sphere
525: ID3D11DeviceContext::DrawIndexed()
532: Sphere
535: ID3D11DeviceContext::DrawIndexed()
542: Sphere
545: ID3D11DeviceContext::DrawIndexed()
552: Sphere
555: ID3D11DeviceContext::DrawIndexed()
556: ID3DUserDefinedAnnotation::EndEvent()
558: ID3D11DeviceContext::ClearRenderTargetView()
559: ID3D11DeviceContext::ClearDepthStencilView()
561: Lighting
563: ID3D11DeviceContext::ClearRenderTargetView()
564: ID3D11DeviceContext::ClearRenderTargetView()
566: Point light
580: ID3D11DeviceContext::DrawIndexed()
581: Sun light
597: ID3D11DeviceContext::DrawIndexed()
600: Cube light
614: ID3D11DeviceContext::DrawIndexed()
615: ID3DUserDefinedAnnotation::EndEvent()
617: ID3D11DeviceContext::ClearRenderTargetView()
618: ID3D11DeviceContext::ClearDepthStencilView()
620: Shading
630: ID3D11DeviceContext::Draw()
645: ID3D11DeviceContext::DrawIndexed()
652: ID3DUserDefinedAnnotation::EndEvent()
653: ID3DUserDefinedAnnotation::EndEvent()
654: Present(ResourceId::47)
Pass #0 starts with 2: ID3D11DeviceContext::ClearRenderTargetView()
Pass #0 contained 23 actions
Pass #1 starts with 319: ID3D11DeviceContext::ClearDepthStencilView()
Pass #1 contained 23 actions
Pass #2 starts with 558: ID3D11DeviceContext::ClearRenderTargetView()
Pass #2 contained 3 actions
Pass #3 starts with 617: ID3D11DeviceContext::ClearRenderTargetView()
Pass #3 contained 3 actions