perf/pixel-rate: new pixel throughput microbenchmark
[piglit.git] / unittests / framework / replay / backends / test_renderdoc.py
blob3da198fbde55ad6b090a13e4e8c2a0e551a32cba
1 # coding=utf-8
3 # Copyright © 2020 Valve Corporation.
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 """Tests for replayer's renderdoc backend."""
28 import pytest
30 import os
31 import subprocess
33 from os import path
35 from framework import core
36 from framework import exceptions
37 from framework.replay import backends
38 from framework.replay.options import OPTIONS
41 @pytest.fixture
42 def config(mocker):
43 conf = mocker.patch('framework.core.PIGLIT_CONFIG',
44 new_callable=core.PiglitConfig)
45 conf.add_section('replay')
46 yield conf
48 class TestRenderDocBackend(object):
49 """Tests for the RenderDocBackend class."""
51 def mock_renderdoc_subprocess_run(self, cmd, stdout, stderr, env=None):
52 ret = subprocess.CompletedProcess(cmd, 0)
53 if len(cmd) > 3:
54 calls = cmd[3:]
55 else:
56 calls = [self.gl_trace_last_call]
57 if (cmd[1] == self.gl_trace_path and
58 calls != [self.gl_trace_wrong_call]):
59 prefix = path.join(cmd[2], path.basename(cmd[1]))
60 ret.stdout = b''
61 for call in calls:
62 if call != self.gl_trace_wrong_call:
63 dump = prefix + '-' + call + '.png'
64 with open(dump, 'w') as f:
65 f.write("content")
66 if call == self.gl_trace_last_call:
67 call_text = 'End of Capture'
68 else:
69 call_text = 'glDrawArrays(4)'
70 ret.stdout += bytearray('Saving image at eventId ' + call +
71 ': ' + call_text + ' to ' + dump +
72 '\n', 'utf-8')
73 else:
74 ret.stdout = b''
75 ret.returncode = 1
77 return ret
79 @pytest.fixture(autouse=True)
80 def setup(self, mocker, tmpdir):
81 """Setup for TestRenderDocBackend.
83 This set ups the basic environment for testing.
84 """
86 OPTIONS.device_name = 'test-device'
87 self.renderdoc = 'renderdoc/renderdoc_dump_images.py'
88 self.gl_trace_path = tmpdir.mkdir(
89 'db-path').join('glmark2/desktop.rdc').strpath
90 self.gl_replay_crashes_trace_path = tmpdir.join(
91 'db-path',
92 'replay/fails.rdc').strpath
93 self.gl_trace_calls = '47,332'
94 self.gl_trace_last_call = '340'
95 self.gl_trace_wrong_call = '333'
96 self.output_dir = tmpdir.mkdir('results').strpath
97 self.results_partial_path = path.join('trace', OPTIONS.device_name)
98 self.m_renderdoc_subprocess_run = mocker.patch(
99 'framework.replay.backends.abstract.subprocess.run',
100 side_effect=self.mock_renderdoc_subprocess_run)
101 self.tmpdir = tmpdir
102 self.mocker = mocker
104 @pytest.mark.raises(exception=exceptions.PiglitFatalError)
105 def test_init_unsupported_trace(self):
106 """Tests for the init method.
108 Should raise an exception in case of creating with an unsupported trace
109 format.
112 test = backends.renderdoc.RenderDocBackend('unsupported_trace.gfxr')
114 def test_dump_gl_options(self):
115 """Tests for the dump method: basic with options.
117 Check basic GL dumps with different configurations. No specific output
118 directory is provided and leaving to the method to figure out the last
119 call from the trace file itself.
122 calls = self.gl_trace_last_call
123 trace_path = self.gl_trace_path
124 test = backends.renderdoc.RenderDocBackend(trace_path)
125 assert test.dump()
126 snapshot_prefix = trace_path + '-'
127 self.m_renderdoc_subprocess_run.assert_called_once()
128 for call in calls.split(','):
129 assert path.exists(snapshot_prefix + call + '.png')
131 def test_dump_gl_output(self):
132 """Tests for the dump method: explicit output directory.
134 Check a basic GL dump, specifying the output and leaving for the method
135 to figure out the last call from the trace file itself.
138 calls = self.gl_trace_last_call
139 trace_path = self.gl_trace_path
140 test = backends.renderdoc.RenderDocBackend(trace_path,
141 output_dir=self.output_dir)
142 assert test.dump()
143 snapshot_prefix = path.join(self.output_dir,
144 path.basename(trace_path) + '-')
145 self.m_renderdoc_subprocess_run.assert_called_once()
146 for call in calls.split(','):
147 assert path.exists(snapshot_prefix + call + '.png')
149 def test_dump_gl_calls(self):
150 """Tests for the dump method: explicit valid calls.
152 Check a basic GL dump, specifying valid calls to dump. No specific
153 output directory is provided.
156 calls = self.gl_trace_calls
157 trace_path = self.gl_trace_path
158 test = backends.renderdoc.RenderDocBackend(trace_path,
159 calls=calls.split(','))
160 assert test.dump()
161 snapshot_prefix = trace_path + '-'
162 self.m_renderdoc_subprocess_run.assert_called_once()
163 for call in calls.split(','):
164 assert path.exists(snapshot_prefix + call + '.png')
166 def test_dump_gl_wrong_call(self):
167 """Tests for the dump method: explicit invalid call.
169 Check a basic GL dump, specifying an invalid call to dump. No specific
170 output directory is provided.
173 calls = self.gl_trace_wrong_call
174 trace_path = self.gl_trace_path
175 test = backends.renderdoc.RenderDocBackend(trace_path,
176 calls=calls.split(','))
177 assert not test.dump()
178 snapshot_prefix = trace_path + '-'
179 self.m_renderdoc_subprocess_run.assert_called_once()
180 for call in calls.split(','):
181 assert not path.exists(snapshot_prefix + call + '.png')
183 def test_dump_gl_replay_crashes(self):
184 """Tests for the dump method: the replay call crashes.
186 Check a basic GL dump. The replay call crashes.
189 calls = self.gl_trace_last_call
190 trace_path = self.gl_replay_crashes_trace_path
191 test = backends.renderdoc.RenderDocBackend(trace_path)
192 assert not test.dump()
193 snapshot_prefix = trace_path + '-'
194 self.m_renderdoc_subprocess_run.assert_called_once()
195 for call in calls.split(','):
196 assert not path.exists(snapshot_prefix + call + '.png')