3 # Copyright (c) 2019 Collabora Ltd
5 # Permission is hereby granted, free of charge, to any person obtaining a
6 # copy of this software and associated documentation files (the "Software"),
7 # to deal in the Software without restriction, including without limitation
8 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 # and/or sell copies of the Software, and to permit persons to whom the
10 # Software is furnished to do so, subject to the following conditions:
12 # The above copyright notice and this permission notice shall be included
13 # in all copies or substantial portions of the Software.
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 # OTHER DEALINGS IN THE SOFTWARE.
23 # SPDX-License-Identifier: MIT
26 from pathlib
import Path
28 import renderdoc
as rd
30 def findDrawWithEventId(controller
, eventId
):
31 for d
in controller
.GetDrawcalls():
32 if d
.eventId
== eventId
:
37 def dumpImage(controller
, eventId
, outputDir
, tracefile
):
38 draw
= findDrawWithEventId(controller
, eventId
)
40 raise RuntimeError("Couldn't find draw call with eventId " + str(eventId
))
42 controller
.SetFrameEvent(draw
.eventId
, True)
44 texsave
= rd
.TextureSave()
46 # Select the first color output
47 texsave
.resourceId
= draw
.outputs
[0]
49 if texsave
.resourceId
== rd
.ResourceId
.Null():
52 filepath
= Path(outputDir
)
53 filepath
.mkdir(parents
= True, exist_ok
= True)
54 filepath
= filepath
/ (tracefile
+ "-" + str(int(draw
.eventId
)) + ".png")
56 print("Saving image at eventId %d: %s to %s" % (draw
.eventId
, draw
.name
, filepath
))
58 # Most formats can only display a single image per file, so we select the
59 # first mip and first slice
61 texsave
.slice.sliceIndex
= 0
63 # For formats with an alpha channel, preserve it
64 texsave
.alpha
= rd
.AlphaMapping
.Preserve
65 texsave
.destType
= rd
.FileType
.PNG
66 controller
.SaveTexture(texsave
, str(filepath
))
68 def loadCapture(filename
):
69 cap
= rd
.OpenCaptureFile()
71 status
= cap
.OpenFile(filename
, '', None)
73 if status
!= rd
.ReplayStatus
.Succeeded
:
74 raise RuntimeError("Couldn't open file: " + str(status
))
75 if not cap
.LocalReplaySupport():
76 raise RuntimeError("Capture cannot be replayed")
78 status
,controller
= cap
.OpenCapture(rd
.ReplayOptions(), None)
80 if status
!= rd
.ReplayStatus
.Succeeded
:
81 raise RuntimeError("Couldn't initialise replay: " + str(status
))
83 return (cap
, controller
)
85 def renderdoc_dump_images(filename
, eventIds
, outputDir
):
86 rd
.InitialiseReplay(rd
.GlobalEnvironment(), [])
87 cap
, controller
= loadCapture(filename
);
89 tracefile
= Path(filename
).name
91 if len(eventIds
) == 0:
92 eventIds
.append(controller
.GetDrawcalls()[-1].eventId
)
94 for eventId
in eventIds
:
95 dumpImage(controller
, eventId
, outputDir
, tracefile
)
102 if __name__
== "__main__":
103 if len(sys
.argv
) < 3:
104 raise RuntimeError("Usage: renderdoc_dump_images.py <trace> <outputdir> [<draw-id>...]")
106 eventIds
= [int(e
) for e
in sys
.argv
[3:]]
108 renderdoc_dump_images(sys
.argv
[1], eventIds
, sys
.argv
[2])