Capture/Replay: Generate code integration.

This sources the trace list from a json file and uses that to make the
"glue" that works with each individual trace test.

Bug: angleproject:4590
Change-Id: I40808cbd0e00f9ed01f93c4cfbd678401db3fec0
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2168539
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Cody Northrop <cnorthrop@google.com>
This commit is contained in:
Jamie Madill 2020-04-27 15:52:56 -04:00 коммит произвёл Commit Bot
Родитель 45bb2b9c93
Коммит 92b3a720a2
9 изменённых файлов: 461 добавлений и 85 удалений

Просмотреть файл

@ -0,0 +1,10 @@
{
"src/tests/perf_tests/restricted_traces/gen_restricted_traces.py":
"9cd5b4fa06f8d53fc7ae5ce3059efeaa",
"src/tests/perf_tests/restricted_traces/restricted_traces.json":
"b73081e6815268e7712599d83f4bfb7c",
"src/tests/perf_tests/restricted_traces/restricted_traces_autogen.gni":
"00afbfd7987ff25af045af104477a680",
"src/tests/perf_tests/restricted_traces/restricted_traces_autogen.h":
"d0b8cfda99009a6e042989ffa0ea3608"
}

Просмотреть файл

@ -85,8 +85,12 @@ generators = {
'src/libANGLE/renderer/d3d/d3d11/gen_dxgi_format_table.py',
'DXGI format support':
'src/libANGLE/renderer/d3d/d3d11/gen_dxgi_support_tables.py',
'Emulated HLSL functions':
'src/compiler/translator/gen_emulated_builtin_function_tables.py',
'GL copy conversion table':
'src/libANGLE/gen_copy_conversion_table.py',
'GL CTS (dEQP) build files':
'scripts/gen_vk_gl_cts_build.py',
'GL/EGL/WGL loader':
'scripts/generate_loader.py',
'GL/EGL entry points':
@ -95,34 +99,32 @@ generators = {
'scripts/gen_gl_enum_utils.py',
'GL format map':
'src/libANGLE/gen_format_map.py',
'uniform type':
'src/common/gen_uniform_type_table.py',
'Metal format table':
'src/libANGLE/renderer/metal/gen_mtl_format_table.py',
'Metal default shaders':
'src/libANGLE/renderer/metal/shaders/gen_mtl_internal_shaders.py',
'OpenGL dispatch table':
'src/libANGLE/renderer/gl/generate_gl_dispatch_table.py',
'overlay fonts':
'src/libANGLE/gen_overlay_fonts.py',
'overlay widgets':
'src/libANGLE/gen_overlay_widgets.py',
'packed enum':
'src/common/gen_packed_gl_enums.py',
'proc table':
'scripts/gen_proc_table.py',
'restricted traces':
'src/tests/perf_tests/restricted_traces/gen_restricted_traces.py',
'Static builtins':
'src/compiler/translator/gen_builtin_symbols.py',
'uniform type':
'src/common/gen_uniform_type_table.py',
'Vulkan format':
'src/libANGLE/renderer/vulkan/gen_vk_format_table.py',
'Vulkan mandatory format support table':
'src/libANGLE/renderer/vulkan/gen_vk_mandatory_format_support_table.py',
'Vulkan internal shader programs':
'src/libANGLE/renderer/vulkan/gen_vk_internal_shaders.py',
'overlay fonts':
'src/libANGLE/gen_overlay_fonts.py',
'overlay widgets':
'src/libANGLE/gen_overlay_widgets.py',
'Emulated HLSL functions':
'src/compiler/translator/gen_emulated_builtin_function_tables.py',
'Static builtins':
'src/compiler/translator/gen_builtin_symbols.py',
'Metal format table':
'src/libANGLE/renderer/metal/gen_mtl_format_table.py',
'Metal default shaders':
'src/libANGLE/renderer/metal/shaders/gen_mtl_internal_shaders.py',
'GL CTS (dEQP) build files':
'scripts/gen_vk_gl_cts_build.py',
}

Просмотреть файл

@ -286,10 +286,20 @@ if (is_win || is_linux || is_android || is_mac || is_fuchsia) {
testonly = true
if (build_angle_trace_perf_tests) {
# Imports "angle_restricted_traces"
import("perf_tests/restricted_traces/restricted_traces.gni")
sources = [ "perf_tests/TracePerfTest.cpp" ]
import("perf_tests/restricted_traces/restricted_traces_autogen.gni")
sources = [
"perf_tests/TracePerfTest.cpp",
"perf_tests/restricted_traces/restricted_traces_autogen.h",
]
defines = []
if (is_android) {
_trace_data_path = "/sdcard/chromium_tests_root/third_party/angle/src/tests/perf_tests/restricted_traces"
} else {
_trace_data_path =
rebase_path("perf_tests/restricted_traces", root_out_dir)
}
defines = [ "ANGLE_TRACE_DATA_DIR=\"${_trace_data_path}\"" ]
data = []
foreach(_test, angle_restricted_traces) {
@ -306,14 +316,8 @@ if (is_win || is_linux || is_android || is_mac || is_fuchsia) {
"${_test_ctx}.h",
]
if (is_android) {
_test_data_path = "/sdcard/chromium_tests_root/third_party/angle/src/tests/perf_tests/restricted_traces/${_test}"
} else {
_test_data_path = rebase_path("${_test_dir}", root_out_dir)
}
defines += [ "ANGLE_TRACE_DATA_DIR_${_test}=\"${_test_data_path}\"" ]
defines +=
[ "ANGLE_TRACE_DATA_DIR_${_test}=\"${_trace_data_path}/${_test}\"" ]
data += [ "${_test_dir}/${_test}_capture_context1.angledata.gz" ]
}

Просмотреть файл

@ -15,8 +15,7 @@
#include "util/egl_loader_autogen.h"
#include "util/frame_capture_utils.h"
#include "restricted_traces/manhattan_10/manhattan_10_capture_context1.h"
#include "restricted_traces/trex_200/trex_200_capture_context1.h"
#include "restricted_traces/restricted_traces_autogen.h"
#include <cassert>
#include <functional>
@ -29,13 +28,6 @@ namespace
{
void FramebufferChangeCallback(void *userData, GLenum target, GLuint framebuffer);
enum class TracePerfTestID
{
Manhattan10,
TRex200,
InvalidEnum,
};
struct TracePerfParams final : public RenderTestParams
{
// Common default options
@ -54,26 +46,11 @@ struct TracePerfParams final : public RenderTestParams
std::string story() const override
{
std::stringstream strstr;
strstr << RenderTestParams::story();
switch (testID)
{
case TracePerfTestID::Manhattan10:
strstr << "_manhattan_10";
break;
case TracePerfTestID::TRex200:
strstr << "_trex_200";
break;
default:
assert(0);
break;
}
strstr << RenderTestParams::story() << "_" << kTraceInfos[testID].name;
return strstr.str();
}
TracePerfTestID testID;
RestrictedTraceID testID;
};
std::ostream &operator<<(std::ostream &os, const TracePerfParams &params)
@ -95,7 +72,6 @@ class TracePerfTest : public ANGLERenderTest, public ::testing::WithParamInterfa
uint32_t mStartFrame;
uint32_t mEndFrame;
std::function<void(uint32_t)> mReplayFunc;
double getHostTimeFromGLTime(GLint64 glTime);
@ -129,21 +105,12 @@ TracePerfTest::TracePerfTest()
// TODO(anglebug.com/4533) This fails after the upgrade to the 26.20.100.7870 driver.
if (IsWindows() && IsIntel() &&
GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE &&
GetParam().testID == TracePerfTestID::Manhattan10)
GetParam().testID == RestrictedTraceID::manhattan_10)
{
mSkipTest = true;
}
}
// TODO(jmadill/cnorthrop): Use decompression path. http://anglebug.com/3630
#define TRACE_TEST_CASE(NAME) \
mStartFrame = NAME::kReplayFrameStart; \
mEndFrame = NAME::kReplayFrameEnd; \
mReplayFunc = NAME::ReplayContext1Frame; \
NAME::SetBinaryDataDecompressCallback(DecompressBinaryData); \
NAME::SetBinaryDataDir(ANGLE_TRACE_DATA_DIR_##NAME); \
NAME::SetupContext1Replay()
void TracePerfTest::initializeBenchmark()
{
const auto &params = GetParam();
@ -157,18 +124,18 @@ void TracePerfTest::initializeBenchmark()
angle::SetCWD(exeDir.c_str());
}
switch (params.testID)
{
case TracePerfTestID::Manhattan10:
TRACE_TEST_CASE(manhattan_10);
break;
case TracePerfTestID::TRex200:
TRACE_TEST_CASE(trex_200);
break;
default:
assert(0);
break;
}
const TraceInfo &traceInfo = kTraceInfos[params.testID];
mStartFrame = traceInfo.startFrame;
mEndFrame = traceInfo.endFrame;
SetBinaryDataDecompressCallback(params.testID, DecompressBinaryData);
std::stringstream testDataDirStr;
testDataDirStr << ANGLE_TRACE_DATA_DIR << "/" << traceInfo.name;
std::string testDataDir = testDataDirStr.str();
SetBinaryDataDir(params.testID, testDataDir.c_str());
// Potentially slow. Can load a lot of resources.
SetupReplay(params.testID);
ASSERT_TRUE(mEndFrame > mStartFrame);
@ -215,7 +182,7 @@ void TracePerfTest::drawBenchmark()
sprintf(frameName, "Frame %u", frame);
beginInternalTraceEvent(frameName);
mReplayFunc(frame);
ReplayFrame(GetParam().testID, frame);
getGLWindow()->swap();
endInternalTraceEvent(frameName);
@ -335,7 +302,7 @@ TEST_P(TracePerfTest, Run)
run();
}
TracePerfParams CombineTestID(const TracePerfParams &in, TracePerfTestID id)
TracePerfParams CombineTestID(const TracePerfParams &in, RestrictedTraceID id)
{
TracePerfParams out = in;
out.testID = id;
@ -345,7 +312,8 @@ TracePerfParams CombineTestID(const TracePerfParams &in, TracePerfTestID id)
using namespace params;
using P = TracePerfParams;
std::vector<P> gTestsWithID = CombineWithValues({P()}, AllEnums<TracePerfTestID>(), CombineTestID);
std::vector<P> gTestsWithID =
CombineWithValues({P()}, AllEnums<RestrictedTraceID>(), CombineTestID);
std::vector<P> gTestsWithRenderer = CombineWithFuncs(gTestsWithID, {Vulkan<P>});
ANGLE_INSTANTIATE_TEST_ARRAY(TracePerfTest, gTestsWithRenderer);

Просмотреть файл

@ -116,10 +116,14 @@ upload_to_google_storage.py --bucket chrome-angle-capture-binaries --archive tre
upload_to_google_storage.py --bucket chrome-angle-capture-binaries --archive manhattan_10
```
## Adding new tests
Once you are able to capture a set of frames from an application using the steps above, you'll need to:
After uploading, add the sha1 files created by the upload and submit them with your changes.
* Add the tests to restricted_traces/angle_trace_perf_tests.gni
* Update TracePerfTest.cpp to include the headers from the test, add it to the list of TracePerfTestID, and support it throughout the file using the namespace created in the trace.
* Upload the traces to the cloud using the steps above.
* Add the sha1 files created by the upload and submit them with your changes.
## Adding new tests
After you capture and upload a set of frames from an application using the steps above you'll need to:
* Add the new traces to [`restricted_traces/restricted_traces.json`](restricted_traces.json).
* Re-run code generation with [`scripts/run_code_generation.py`][run_code_generation].
* Update your CL to include the new generated code. Your trace tests should now be turned on.
[run_code_generation]: ../../../../scripts/run_code_generation.py

Просмотреть файл

@ -0,0 +1,235 @@
#!/usr/bin/python2
#
# Copyright 2020 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# gen_restricted_traces.py:
# Generates integration code for the restricted trace tests.
import json
import sys
gni_template = """# GENERATED FILE - DO NOT EDIT.
# Generated by {script_name} using data from {data_source_name}
#
# Copyright 2020 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# A list of all restricted trace tests. Can be consumed by tests/BUILD.gn.
angle_restricted_traces = [
{test_list}
]
"""
header_template = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name}
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Types and enumerations for trace tests.
#ifndef ANGLE_RESTRICTED_TRACES_H_
#define ANGLE_RESTRICTED_TRACES_H_
{includes}
namespace angle
{{
enum class RestrictedTraceID
{{
{trace_ids}, InvalidEnum, EnumCount = InvalidEnum
}};
using ReplayFunc = void (*)(uint32_t);
using SetupFunc = void (*)();
using DecompressFunc = uint8_t *(*)(const std::vector<uint8_t> &);
using SetBinaryDataDirFunc = void (*)(const char *);
static constexpr size_t kTraceInfoMaxNameLen = 32;
struct TraceInfo
{{
uint32_t startFrame;
uint32_t endFrame;
char name[kTraceInfoMaxNameLen];
}};
constexpr angle::PackedEnumMap<RestrictedTraceID, TraceInfo> kTraceInfos = {{
{trace_infos}
}};
using DecompressCallback = uint8_t *(*)(const std::vector<uint8_t> &);
using FramebufferChangeCallback = void(*)(void *userData, GLenum target, GLuint framebuffer);
inline void ReplayFrame(RestrictedTraceID traceID, uint32_t frameIndex)
{{
switch (traceID)
{{
{replay_func_cases}
default:
fprintf(stderr, "Error in switch.\\n");
assert(0);
break;
}}
}}
inline void SetupReplay(RestrictedTraceID traceID)
{{
switch (traceID)
{{
{setup_func_cases}
default:
fprintf(stderr, "Error in switch.\\n");
assert(0);
break;
}}
}}
inline void SetBinaryDataDir(RestrictedTraceID traceID, const char *dataDir)
{{
switch (traceID)
{{
{set_binary_data_dir_cases}
default:
fprintf(stderr, "Error in switch.\\n");
assert(0);
break;
}}
}}
inline void SetBinaryDataDecompressCallback(RestrictedTraceID traceID, DecompressCallback callback)
{{
switch (traceID)
{{
{decompress_callback_cases}
default:
fprintf(stderr, "Error in switch.\\n");
assert(0);
break;
}}
}}
inline void SetFramebufferChangeCallback(RestrictedTraceID traceID, void *userData, FramebufferChangeCallback callback)
{{
switch (traceID)
{{
{on_fb_change_callback_cases}
default:
fprintf(stderr, "Error in switch.\\n");
assert(0);
break;
}}
}}
}} // namespace angle
#endif // ANGLE_RESTRICTED_TRACES_H_
"""
def reject_duplicate_keys(pairs):
found_keys = {}
for key, value in pairs:
if key in found_keys:
raise ValueError("duplicate key: %r" % (key,))
else:
found_keys[key] = value
return found_keys
def gen_gni(traces, gni_file, format_args):
format_args["test_list"] = ",\n".join(['"%s"' % trace for trace in traces])
gni_data = gni_template.format(**format_args)
with open(gni_file, "w") as out_file:
out_file.write(gni_data)
return True
def get_trace_info(trace):
info = ["%s::kReplayFrameStart", "%s::kReplayFrameEnd", "\"%s\""]
return ", ".join([element % trace for element in info])
def get_cases(traces, function, args):
funcs = [
"case RestrictedTraceID::%s: %s::%s(%s); break;" % (trace, trace, function, args)
for trace in traces
]
return "\n".join(funcs)
def gen_header(traces, header_file, format_args):
includes = ["#include \"%s/%s_capture_context1.h\"" % (trace, trace) for trace in traces]
trace_infos = [
"{RestrictedTraceID::%s, {%s}}" % (trace, get_trace_info(trace)) for trace in traces
]
format_args["includes"] = "\n".join(includes)
format_args["trace_ids"] = ",\n".join(traces)
format_args["trace_infos"] = ",\n".join(trace_infos)
format_args["replay_func_cases"] = get_cases(traces, "ReplayContext1Frame", "frameIndex")
format_args["setup_func_cases"] = get_cases(traces, "SetupContext1Replay", "")
format_args["set_binary_data_dir_cases"] = get_cases(traces, "SetBinaryDataDir", "dataDir")
format_args["decompress_callback_cases"] = get_cases(traces, "SetBinaryDataDecompressCallback",
"callback")
format_args["on_fb_change_callback_cases"] = get_cases(traces, "SetFramebufferChangeCallback",
"userData, callback")
header_data = header_template.format(**format_args)
with open(header_file, "w") as out_file:
out_file.write(header_data)
return True
def read_json(json_file):
with open(json_file) as map_file:
return json.loads(map_file.read(), object_pairs_hook=reject_duplicate_keys)
def main():
json_file = 'restricted_traces.json'
gni_file = 'restricted_traces_autogen.gni'
header_file = 'restricted_traces_autogen.h'
# auto_script parameters.
if len(sys.argv) > 1:
inputs = [json_file]
outputs = [gni_file, header_file]
if sys.argv[1] == 'inputs':
print ','.join(inputs)
elif sys.argv[1] == 'outputs':
print ','.join(outputs)
else:
print('Invalid script parameters.')
return 1
return 0
json_data = read_json(json_file)
if 'traces' not in json_data:
print('Trace data missing traces key.')
return 1
format_args = {
"script_name": __file__,
"data_source_name": json_file,
}
traces = json_data['traces']
if not gen_gni(traces, gni_file, format_args):
print('.gni file generation failed.')
return 1
if not gen_header(traces, header_file, format_args):
print('.h file generation failed.')
return 1
return 0
if __name__ == '__main__':
sys.exit(main())

Просмотреть файл

@ -0,0 +1,13 @@
{
"description": [
"Copyright 2020 The ANGLE Project Authors. All rights reserved.",
"Use of this source code is governed by a BSD-style license that can be",
"found in the LICENSE file.",
"",
"restricted_traces.json: List of restricted trace tests in ANGLE."
],
"traces": [
"manhattan_10",
"trex_200"
]
}

Просмотреть файл

@ -1,3 +1,6 @@
# GENERATED FILE - DO NOT EDIT.
# Generated by gen_restricted_traces.py using data from restricted_traces.json
#
# Copyright 2020 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

Просмотреть файл

@ -0,0 +1,137 @@
// GENERATED FILE - DO NOT EDIT.
// Generated by gen_restricted_traces.py using data from restricted_traces.json
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Types and enumerations for trace tests.
#ifndef ANGLE_RESTRICTED_TRACES_H_
#define ANGLE_RESTRICTED_TRACES_H_
#include "manhattan_10/manhattan_10_capture_context1.h"
#include "trex_200/trex_200_capture_context1.h"
namespace angle
{
enum class RestrictedTraceID
{
manhattan_10,
trex_200,
InvalidEnum,
EnumCount = InvalidEnum
};
using ReplayFunc = void (*)(uint32_t);
using SetupFunc = void (*)();
using DecompressFunc = uint8_t *(*)(const std::vector<uint8_t> &);
using SetBinaryDataDirFunc = void (*)(const char *);
static constexpr size_t kTraceInfoMaxNameLen = 32;
struct TraceInfo
{
uint32_t startFrame;
uint32_t endFrame;
char name[kTraceInfoMaxNameLen];
};
constexpr angle::PackedEnumMap<RestrictedTraceID, TraceInfo> kTraceInfos = {
{RestrictedTraceID::manhattan_10,
{manhattan_10::kReplayFrameStart, manhattan_10::kReplayFrameEnd, "manhattan_10"}},
{RestrictedTraceID::trex_200,
{trex_200::kReplayFrameStart, trex_200::kReplayFrameEnd, "trex_200"}}};
using DecompressCallback = uint8_t *(*)(const std::vector<uint8_t> &);
using FramebufferChangeCallback = void (*)(void *userData, GLenum target, GLuint framebuffer);
inline void ReplayFrame(RestrictedTraceID traceID, uint32_t frameIndex)
{
switch (traceID)
{
case RestrictedTraceID::manhattan_10:
manhattan_10::ReplayContext1Frame(frameIndex);
break;
case RestrictedTraceID::trex_200:
trex_200::ReplayContext1Frame(frameIndex);
break;
default:
fprintf(stderr, "Error in switch.\n");
assert(0);
break;
}
}
inline void SetupReplay(RestrictedTraceID traceID)
{
switch (traceID)
{
case RestrictedTraceID::manhattan_10:
manhattan_10::SetupContext1Replay();
break;
case RestrictedTraceID::trex_200:
trex_200::SetupContext1Replay();
break;
default:
fprintf(stderr, "Error in switch.\n");
assert(0);
break;
}
}
inline void SetBinaryDataDir(RestrictedTraceID traceID, const char *dataDir)
{
switch (traceID)
{
case RestrictedTraceID::manhattan_10:
manhattan_10::SetBinaryDataDir(dataDir);
break;
case RestrictedTraceID::trex_200:
trex_200::SetBinaryDataDir(dataDir);
break;
default:
fprintf(stderr, "Error in switch.\n");
assert(0);
break;
}
}
inline void SetBinaryDataDecompressCallback(RestrictedTraceID traceID, DecompressCallback callback)
{
switch (traceID)
{
case RestrictedTraceID::manhattan_10:
manhattan_10::SetBinaryDataDecompressCallback(callback);
break;
case RestrictedTraceID::trex_200:
trex_200::SetBinaryDataDecompressCallback(callback);
break;
default:
fprintf(stderr, "Error in switch.\n");
assert(0);
break;
}
}
inline void SetFramebufferChangeCallback(RestrictedTraceID traceID,
void *userData,
FramebufferChangeCallback callback)
{
switch (traceID)
{
case RestrictedTraceID::manhattan_10:
manhattan_10::SetFramebufferChangeCallback(userData, callback);
break;
case RestrictedTraceID::trex_200:
trex_200::SetFramebufferChangeCallback(userData, callback);
break;
default:
fprintf(stderr, "Error in switch.\n");
assert(0);
break;
}
}
} // namespace angle
#endif // ANGLE_RESTRICTED_TRACES_H_