diff --git a/doc/CaptureAndReplay.md b/doc/CaptureAndReplay.md index ec4e3d7c3..f735b04e8 100644 --- a/doc/CaptureAndReplay.md +++ b/doc/CaptureAndReplay.md @@ -67,16 +67,15 @@ A good way to test out the capture is to use environment variables in conjunctio template. For example: ``` -$ ANGLE_CAPTURE_FRAME_END=4 ANGLE_CAPTURE_OUT_DIR=samples/capture_replay out/Debug/simple_texture_2d +$ ANGLE_CAPTURE_FRAME_END=4 ANGLE_CAPTURE_OUT_DIR=samples/capture_replay out/Debug/simple_texture_2d --use-angle=vulkan ``` ## Running the capture_replay sample (desktop only) -*Note: The capture_replay sample is broken until http://anglebug.com/5911 is addressed.* - To run a sample replay you can use a template located in -[samples/capture_replay](../samples/capture_replay). First run your capture and ensure all capture +[samples/capture_replay](../samples/capture_replay). First run your sample and ensure all capture files are written to `samples/capture_replay`. You can conveniently use `ANGLE_CAPTURE_OUT_DIR`. +Make sure `ANGLE_CAPTURE_LABEL` is left unset during capture to use the default file names. Then enable the `capture_replay_sample` via `gn args`: ``` diff --git a/samples/BUILD.gn b/samples/BUILD.gn index 1e08eb6c1..b0b0994b2 100644 --- a/samples/BUILD.gn +++ b/samples/BUILD.gn @@ -210,33 +210,17 @@ angle_sample("multiple_contexts") { } if (angle_build_capture_replay_sample) { - # The capture_replay sample is set up to work with a single Context. - # To use the capture replay sample first move your capture sources into - # the capture_replay folder and enable the gn arg above. angle_sample("capture_replay_sample") { - _contextid = angle_capture_replay_sample_context_id - sources = - rebase_path( - read_file( - "capture_replay/angle_capture_context${_contextid}_files.txt", - "list lines"), - ".", - "capture_replay") + - [ - "capture_replay/CaptureReplay.cpp", - "capture_replay/angle_capture_context${_contextid}.cpp", - "capture_replay/angle_capture_context${_contextid}.h", - ] + sources = [ "capture_replay/CaptureReplay.cpp" ] - deps = [ "$angle_root:angle_compression" ] - data = [ "capture_replay/angle_capture_context${_contextid}.angledata.gz" ] + deps = [ + "$angle_root:angle_compression", + "$angle_root/util:angle_frame_capture_test_utils", + "capture_replay:capture_replay_sample_trace", + ] _data_path = rebase_path("capture_replay", root_out_dir) - defines = [ - "ANGLE_CAPTURE_REPLAY_SAMPLE_DATA_DIR=\"${_data_path}\"", - "ANGLE_CAPTURE_REPLAY_SAMPLE_CONTEXT_ID=${_contextid}", - "ANGLE_CAPTURE_REPLAY_SAMPLE_HEADER=angle_capture_context${_contextid}.h", - ] + defines = [ "ANGLE_CAPTURE_REPLAY_SAMPLE_DATA_DIR=\"${_data_path}\"" ] suppressed_configs = [ "$angle_root:constructor_and_destructor_warnings" ] configs = [] diff --git a/samples/capture_replay/BUILD.gn b/samples/capture_replay/BUILD.gn new file mode 100644 index 000000000..6f9516263 --- /dev/null +++ b/samples/capture_replay/BUILD.gn @@ -0,0 +1,28 @@ +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("../../gni/angle.gni") + +angle_trace_fixture("angle_capture_replay_sample_fixture") { + gl_header = "angle_trace_gl.h" + public_deps = [ + "$angle_root:libEGL", + "$angle_root/util:angle_util", + ] +} + +angle_trace("capture_replay_sample_trace") { + _trace = "angle_capture" + + _trace_data = [] + _trace_data = read_file("$_trace.json", "json") + + sources = _trace_data.TraceFiles + + data = [ + "$_trace.json", + "$_trace.angledata.gz", + ] + fixture = ":angle_capture_replay_sample_fixture" +} diff --git a/samples/capture_replay/CaptureReplay.cpp b/samples/capture_replay/CaptureReplay.cpp index fd4e2ca00..2e547fb6c 100644 --- a/samples/capture_replay/CaptureReplay.cpp +++ b/samples/capture_replay/CaptureReplay.cpp @@ -11,46 +11,35 @@ #include "util/capture/frame_capture_test_utils.h" -// Build the right context header based on replay ID -// This will expand to "angle_capture_context<#>.h" -#include ANGLE_MACRO_STRINGIZE(ANGLE_CAPTURE_REPLAY_SAMPLE_HEADER) - -// Assign the context numbered functions based on GN arg selecting replay ID -std::function SetupContextReplay = reinterpret_cast( - ANGLE_MACRO_CONCAT(SetupContext, - ANGLE_MACRO_CONCAT(ANGLE_CAPTURE_REPLAY_SAMPLE_CONTEXT_ID, Replay))); -std::function ReplayContextFrame = reinterpret_cast( - ANGLE_MACRO_CONCAT(ReplayContext, - ANGLE_MACRO_CONCAT(ANGLE_CAPTURE_REPLAY_SAMPLE_CONTEXT_ID, Frame))); -std::function ResetContextReplay = reinterpret_cast( - ANGLE_MACRO_CONCAT(ResetContext, - ANGLE_MACRO_CONCAT(ANGLE_CAPTURE_REPLAY_SAMPLE_CONTEXT_ID, Replay))); - class CaptureReplaySample : public SampleApplication { public: - CaptureReplaySample(int argc, char **argv) + CaptureReplaySample(int argc, char **argv, const angle::TraceInfo &traceInfo) : SampleApplication("CaptureReplaySample", argc, argv, 3, 0, - kReplayDrawSurfaceWidth, - kReplayDrawSurfaceHeight) + traceInfo.drawSurfaceWidth, + traceInfo.drawSurfaceHeight), + mTraceInfo(traceInfo) {} bool initialize() override { - // Set CWD to executable directory. - std::string exeDir = angle::GetExecutableDirectory(); - if (!angle::SetCWD(exeDir.c_str())) - return false; - if (kIsBinaryDataCompressed) + mTraceLibrary.reset(new angle::TraceLibrary("capture_replay_sample_trace")); + assert(mTraceLibrary->valid()); + + if (mTraceInfo.isBinaryDataCompressed) { - SetBinaryDataDecompressCallback(angle::DecompressBinaryData); + mTraceLibrary->setBinaryDataDecompressCallback(angle::DecompressBinaryData); } - SetBinaryDataDir(ANGLE_CAPTURE_REPLAY_SAMPLE_DATA_DIR); - SetupContextReplay(); + + std::stringstream binaryPathStream; + binaryPathStream << angle::GetExecutableDirectory() << angle::GetPathSeparator() + << ANGLE_CAPTURE_REPLAY_SAMPLE_DATA_DIR; + mTraceLibrary->setBinaryDataDir(binaryPathStream.str().c_str()); + mTraceLibrary->setupReplay(); return true; } @@ -58,14 +47,14 @@ class CaptureReplaySample : public SampleApplication void draw() override { - // Compute the current frame, looping from kReplayFrameStart to kReplayFrameEnd. - uint32_t frame = - kReplayFrameStart + (mCurrentFrame % ((kReplayFrameEnd - kReplayFrameStart) + 1)); + // Compute the current frame, looping from frameStart to frameEnd. + uint32_t frame = mTraceInfo.frameStart + + (mCurrentFrame % ((mTraceInfo.frameEnd - mTraceInfo.frameStart) + 1)); if (mPreviousFrame > frame) { - ResetContextReplay(); + mTraceLibrary->resetReplay(); } - ReplayContextFrame(frame); + mTraceLibrary->replayFrame(frame); mPreviousFrame = frame; mCurrentFrame++; } @@ -73,10 +62,28 @@ class CaptureReplaySample : public SampleApplication private: uint32_t mCurrentFrame = 0; uint32_t mPreviousFrame = 0; + const angle::TraceInfo mTraceInfo; + std::unique_ptr mTraceLibrary; }; int main(int argc, char **argv) { - CaptureReplaySample app(argc, argv); + std::string exeDir = angle::GetExecutableDirectory(); + + std::stringstream traceJsonPathStream; + traceJsonPathStream << exeDir << angle::GetPathSeparator() + << ANGLE_CAPTURE_REPLAY_SAMPLE_DATA_DIR << angle::GetPathSeparator() + << "angle_capture.json"; + + std::string traceJsonPath = traceJsonPathStream.str(); + + angle::TraceInfo traceInfo = {}; + if (!angle::LoadTraceInfoFromJSON("capture_replay_sample_trace", traceJsonPath, &traceInfo)) + { + std::cout << "Unable to load trace data: " << traceJsonPath << "\n"; + return 1; + } + + CaptureReplaySample app(argc, argv, traceInfo); return app.run(); } diff --git a/samples/capture_replay/angle_trace_gl.h b/samples/capture_replay/angle_trace_gl.h index 8b2a2f28a..12795b7b2 100644 --- a/samples/capture_replay/angle_trace_gl.h +++ b/samples/capture_replay/angle_trace_gl.h @@ -8,6 +8,7 @@ #ifndef ANGLE_TRACE_GL_H_ #define ANGLE_TRACE_GL_H_ +#include "trace_fixture.h" #include "util/util_gl.h" #endif // ANGLE_TRACE_GL_H_