Commit 5111a062 by Jamie Madill

Update dEQP integration.

Intead of generating a case list from a build dEQP executable and packing it into a gzip file, we can use the Android CTS mustpass list. This has the benefit of allowing us to remove some failure expectations for broken tests. It also means we don't need to ever regenerate our case list files. Also remove the old dEQP test integration, since it is no longer supported or possibly even working. And update our test expectations to match the new Android CTS must-pass lists. This change will likely need to be landed simulatanously with a Chromium-side CL, due to the nature of the gyp/DEPS configuration. BUG=angleproject:1236 Change-Id: I352e4a651dfb88193a1c4991974502dee1edb67b Reviewed-on: https://chromium-review.googlesource.com/313792Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 984ef41a
...@@ -1476,22 +1476,6 @@ ...@@ -1476,22 +1476,6 @@
'<(angle_path)/util/util.gyp:angle_util', '<(angle_path)/util/util.gyp:angle_util',
], ],
'copies':
[
{
'destination': '<(PRODUCT_DIR)/deqp_support',
'files':
[
'deqp_support/dEQP-EGL-cases.txt.gz',
'deqp_support/dEQP-GLES2-cases.txt.gz',
'deqp_support/dEQP-GLES3-cases.txt.gz',
'deqp_support/deqp_egl_test_expectations.txt',
'deqp_support/deqp_gles2_test_expectations.txt',
'deqp_support/deqp_gles3_test_expectations.txt',
],
},
],
'direct_dependent_settings': 'direct_dependent_settings':
{ {
'include_dirs': 'include_dirs':
...@@ -1558,19 +1542,6 @@ ...@@ -1558,19 +1542,6 @@
}], }],
], ],
}, },
'conditions':
[
['angle_standalone==1',
{
'dependencies': [ 'angle_zlib' ],
'export_dependent_settings': [ 'angle_zlib' ],
},
{ # angle_standalone!=1
'dependencies': [ '<(zlib_path)/zlib.gyp:zlib' ],
'export_dependent_settings': [ '<(zlib_path)/zlib.gyp:zlib' ],
}],
],
}, },
], # targets ], # targets
}], # angle_build_deqp_gtest_support }], # angle_build_deqp_gtest_support
......
...@@ -7,25 +7,31 @@ ...@@ -7,25 +7,31 @@
// dEQP and GoogleTest integration logic. Calls through to the random // dEQP and GoogleTest integration logic. Calls through to the random
// order executor. // order executor.
#include <fstream>
#include <stdint.h> #include <stdint.h>
#include <zlib.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "angle_deqp_libtester.h" #include "angle_deqp_libtester.h"
#include "common/angleutils.h" #include "common/angleutils.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/Optional.h"
#include "common/string_utils.h"
#include "gpu_test_expectations_parser.h" #include "gpu_test_expectations_parser.h"
#include "system_utils.h" #include "system_utils.h"
namespace namespace
{ {
const char *g_CaseListFiles[] = const char *g_CaseListRelativePath = "/../../third_party/deqp/src/android/cts/master/";
{
"dEQP-GLES2-cases.txt.gz", const char *g_TestExpectationsSearchPaths[] = {
"dEQP-GLES3-cases.txt.gz", "/../../src/tests/deqp_support/", "/../../third_party/angle/src/tests/deqp_support/",
"dEQP-EGL-cases.txt.gz", "/deqp_support/",
};
const char *g_CaseListFiles[] = {
"gles2-master.txt", "gles3-master.txt", "egl-master.txt",
}; };
const char *g_TestExpectationsFiles[] = const char *g_TestExpectationsFiles[] =
...@@ -35,6 +41,25 @@ const char *g_TestExpectationsFiles[] = ...@@ -35,6 +41,25 @@ const char *g_TestExpectationsFiles[] =
"deqp_egl_test_expectations.txt", "deqp_egl_test_expectations.txt",
}; };
Optional<std::string> FindTestExpectationsPath(const std::string &exeDir, size_t testModuleIndex)
{
for (const char *testPath : g_TestExpectationsSearchPaths)
{
std::stringstream testExpectationsPathStr;
testExpectationsPathStr << exeDir << testPath << g_TestExpectationsFiles[testModuleIndex];
std::string path = testExpectationsPathStr.str();
std::ifstream inFile(path.c_str());
if (!inFile.fail())
{
inFile.close();
return Optional<std::string>(path);
}
}
return Optional<std::string>::Invalid();
}
class dEQPCaseList class dEQPCaseList
{ {
public: public:
...@@ -97,15 +122,16 @@ void dEQPCaseList::initialize() ...@@ -97,15 +122,16 @@ void dEQPCaseList::initialize()
std::string exeDir = angle::GetExecutableDirectory(); std::string exeDir = angle::GetExecutableDirectory();
std::stringstream caseListPathStr; std::stringstream caseListPathStr;
caseListPathStr << exeDir << "/deqp_support/" << g_CaseListFiles[mTestModuleIndex]; caseListPathStr << exeDir << g_CaseListRelativePath << g_CaseListFiles[mTestModuleIndex];
std::string caseListPath = caseListPathStr.str(); std::string caseListPath = caseListPathStr.str();
std::stringstream testExpectationsPathStr; Optional<std::string> testExpectationsPath = FindTestExpectationsPath(exeDir, mTestModuleIndex);
testExpectationsPathStr << exeDir << "/deqp_support/" if (!testExpectationsPath.valid())
<< g_TestExpectationsFiles[mTestModuleIndex]; {
std::string testExpectationsPath = testExpectationsPathStr.str(); FAIL() << "Failed to find test expectations file.";
}
if (!mTestExpectationsParser.LoadTestExpectationsFromFile(testExpectationsPath)) if (!mTestExpectationsParser.LoadTestExpectationsFromFile(testExpectationsPath.value()))
{ {
std::stringstream errorMsgStream; std::stringstream errorMsgStream;
for (const auto &message : mTestExpectationsParser.GetErrorMessages()) for (const auto &message : mTestExpectationsParser.GetErrorMessages())
...@@ -121,44 +147,28 @@ void dEQPCaseList::initialize() ...@@ -121,44 +147,28 @@ void dEQPCaseList::initialize()
FAIL() << "Failed to load test configuration."; FAIL() << "Failed to load test configuration.";
} }
std::stringstream caseListStream; std::ifstream caseListStream(caseListPath);
std::vector<char> buf(1024 * 1024 * 16);
gzFile *fi = static_cast<gzFile *>(gzopen(caseListPath.c_str(), "rb"));
if (fi == nullptr)
{
FAIL() << "Failed to read gzipped test information.";
}
gzrewind(fi);
while (!gzeof(fi))
{
int len = gzread(fi, &buf[0], static_cast<unsigned int>(buf.size()) - 1);
buf[len] = '\0';
caseListStream << &buf[0];
}
gzclose(fi);
while (!caseListStream.eof()) while (!caseListStream.eof())
{ {
std::string inString; std::string inString;
std::getline(caseListStream, inString); std::getline(caseListStream, inString);
if (inString.substr(0, 4) == "TEST") std::string dEQPName = angle::TrimString(inString, angle::kWhitespaceASCII);
if (dEQPName.empty())
continue;
std::string gTestName = dEQPName.substr(dEQPName.find('.') + 1);
if (gTestName.empty())
continue;
std::replace(gTestName.begin(), gTestName.end(), '.', '_');
// Occurs in some luminance tests
gTestName.erase(std::remove(gTestName.begin(), gTestName.end(), '-'), gTestName.end());
int expectation = mTestExpectationsParser.GetTestExpectation(dEQPName, mTestConfig);
if (expectation != gpu::GPUTestExpectationsParser::kGpuTestSkip)
{ {
std::string dEQPName = inString.substr(6); mCaseInfoList.push_back(CaseInfo(dEQPName, gTestName, expectation));
std::string gTestName = dEQPName.substr(dEQPName.find('.') + 1);
std::replace(gTestName.begin(), gTestName.end(), '.', '_');
// Occurs in some luminance tests
gTestName.erase(std::remove(gTestName.begin(), gTestName.end(), '-'), gTestName.end());
int expectation = mTestExpectationsParser.GetTestExpectation(dEQPName, mTestConfig);
if (expectation != gpu::GPUTestExpectationsParser::kGpuTestSkip)
{
mCaseInfoList.push_back(CaseInfo(dEQPName, gTestName, expectation));
}
} }
} }
} }
......
...@@ -75,8 +75,6 @@ ...@@ -75,8 +75,6 @@
1033 WIN : dEQP-GLES2.functional.polygon_offset.fixed16_render_with_units = FAIL 1033 WIN : dEQP-GLES2.functional.polygon_offset.fixed16_render_with_units = FAIL
1015 WIN : dEQP-GLES2.functional.shaders.functions.misc.missing_returns_vertex = FAIL 1015 WIN : dEQP-GLES2.functional.shaders.functions.misc.missing_returns_vertex = FAIL
1015 WIN : dEQP-GLES2.functional.shaders.functions.misc.missing_returns_fragment = FAIL 1015 WIN : dEQP-GLES2.functional.shaders.functions.misc.missing_returns_fragment = FAIL
1018 WIN : dEQP-GLES2.functional.shaders.invariance.highp.loop_2 = FAIL
1018 WIN : dEQP-GLES2.functional.shaders.invariance.mediump.loop_2 = FAIL
1017 WIN : dEQP-GLES2.functional.shaders.loops.for_constant_iterations.nested_sequence_* = FAIL 1017 WIN : dEQP-GLES2.functional.shaders.loops.for_constant_iterations.nested_sequence_* = FAIL
1017 WIN : dEQP-GLES2.functional.shaders.loops.for_constant_iterations.nested_tricky_dataflow_* = FAIL 1017 WIN : dEQP-GLES2.functional.shaders.loops.for_constant_iterations.nested_tricky_dataflow_* = FAIL
1017 WIN : dEQP-GLES2.functional.shaders.loops.while_constant_iterations.nested_tricky_dataflow_* = FAIL 1017 WIN : dEQP-GLES2.functional.shaders.loops.while_constant_iterations.nested_tricky_dataflow_* = FAIL
......
#!/usr/bin/python
#
# Copyright 2015 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.
#
# generate_case_lists.py:
# Helper script for updating the dEQP case list files, stored in the repo.
# Generally only used when the dEQP config changes, or when we roll dEQP.
import subprocess
import sys
import os
import shutil
import gzip
# TODO(jmadill): other platforms
os_suffix = '.exe'
build_dir = os.path.join('build', 'Debug_x64')
def run_deqp(deqp_exe):
subprocess.call([deqp_exe, '--deqp-runmode=txt-caselist', '--deqp-gl-context-type=null'])
# This stuff is all hard-coded for now. If we need more versatility we can
# make some options into command line arguments with default values.
script_dir = os.path.dirname(sys.argv[0])
path_to_deqp_exe = os.path.join('..', '..', build_dir)
deqp_data_path = os.path.join('third_party', 'deqp', 'data')
os.chdir(os.path.join(script_dir, '..'))
run_deqp(os.path.join(path_to_deqp_exe, 'angle_deqp_gles2_tests' + os_suffix))
run_deqp(os.path.join(path_to_deqp_exe, 'angle_deqp_gles3_tests' + os_suffix))
run_deqp(os.path.join(path_to_deqp_exe, 'angle_deqp_egl_tests' + os_suffix))
def compress_case_list(case_file):
with open(os.path.join(deqp_data_path, case_file + '.txt')) as in_handle:
data = in_handle.read()
in_handle.close()
with gzip.open(os.path.join('deqp_support', case_file + '.txt.gz'), 'wb') as out_handle:
out_handle.write(data)
out_handle.close()
compress_case_list('dEQP-GLES2-cases')
compress_case_list('dEQP-GLES3-cases')
compress_case_list('dEQP-EGL-cases')
//
// Copyright (c) 2014 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.
//
#include "gtest/gtest.h"
#include "deqp_tests.h"
#include <EGL/eglext.h>
#include <map>
#include <string>
#include <vector>
int main(int argc, char** argv)
{
testing::InitGoogleTest(&argc, argv);
typedef std::pair<std::string, EGLNativeDisplayType> NameDisplayTypePair;
typedef std::map<std::string, EGLNativeDisplayType> DisplayTypeMap;
DisplayTypeMap allDisplays;
allDisplays["d3d11"] = EGL_D3D11_ONLY_DISPLAY_ANGLE;
// Iterate through the command line arguments and check if they are config names
std::vector<NameDisplayTypePair> requestedDisplays;
for (size_t i = 1; i < static_cast<size_t>(argc); i++)
{
DisplayTypeMap::const_iterator iter = allDisplays.find(argv[i]);
if (iter != allDisplays.end())
{
requestedDisplays.push_back(*iter);
}
}
// If no configs were requested, run them all
if (requestedDisplays.empty())
{
for (DisplayTypeMap::const_iterator i = allDisplays.begin(); i != allDisplays.end(); i++)
{
requestedDisplays.push_back(*i);
}
}
// Run each requested config
int rt = 0;
for (size_t i = 0; i < requestedDisplays.size(); i++)
{
DEQPConfig config;
config.displayType = requestedDisplays[i].second;
config.width = 256;
config.height = 256;
config.hidden = false;
SetCurrentConfig(config);
std::cout << "Running test configuration \"" << requestedDisplays[i].first << "\".\n";
rt |= RUN_ALL_TESTS();
}
return rt;
}
//
// Copyright (c) 2014 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.
//
#include "deqp_tests.h"
#include <EGL/eglext.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <sstream>
#include <stdarg.h>
#include <windows.h>
#include "tcuDefs.hpp"
#include "tcuCommandLine.hpp"
#include "tcuPlatform.hpp"
#include "tcuApp.hpp"
#include "tcuResource.hpp"
#include "tcuTestLog.hpp"
#include "tcuTestExecutor.hpp"
#include "deUniquePtr.hpp"
#include "tes3TestPackage.hpp"
#include "win32/tcuWin32EglPlatform.hpp"
// Register the gles3 test cases
static tcu::TestPackage* createTestPackage(tcu::TestContext& testCtx)
{
return new deqp::gles3::TestPackage(testCtx);
}
tcu::TestPackageDescriptor g_gles3PackageDescriptor("dEQP-GLES3", createTestPackage);
// Create a platform that supports custom display types
class Win32EglCustomDisplayPlatform : public tcu::Win32EglPlatform
{
public:
Win32EglCustomDisplayPlatform(EGLNativeDisplayType displayType)
: mDisplayType(displayType)
{
}
virtual ~Win32EglCustomDisplayPlatform()
{
}
virtual tcu::NativeDisplay* createDefaultDisplay()
{
return new tcu::Win32EglDisplay(mDisplayType);
}
private:
EGLNativeDisplayType mDisplayType;
};
static std::vector<char> FormatArg(const char* fmt, ...)
{
va_list vararg;
va_start(vararg, fmt);
int len = vsnprintf(NULL, 0, fmt, vararg);
va_end(vararg);
std::vector<char> buf(len + 1);
va_start(vararg, fmt);
vsnprintf(buf.data(), buf.size(), fmt, vararg);
va_end(vararg);
return buf;
}
static std::string GetExecutableDirectory()
{
std::vector<char> executableFileBuf(MAX_PATH);
DWORD executablePathLen = GetModuleFileNameA(NULL, executableFileBuf.data(), executableFileBuf.size());
if (executablePathLen == 0)
{
return false;
}
std::string executableLocation = executableFileBuf.data();
size_t lastPathSepLoc = executableLocation.find_last_of("\\/");
if (lastPathSepLoc != std::string::npos)
{
executableLocation = executableLocation.substr(0, lastPathSepLoc);
}
else
{
executableLocation = "";
}
return executableLocation;
}
static DEQPConfig kCurrentConfig = { 256, 256, false, EGL_D3D11_ONLY_DISPLAY_ANGLE };
void SetCurrentConfig(const DEQPConfig& config)
{
kCurrentConfig = config;
}
const DEQPConfig& GetCurrentConfig()
{
return kCurrentConfig;
}
void RunDEQPTest(const std::string &testPath, const DEQPConfig& config)
{
try
{
std::vector<char*> args;
// Empty first argument for the program name
args.push_back("deqp-gles3");
std::vector<char> visibilityArg = FormatArg("--deqp-visibility=%s", config.hidden ? "hidden" : "windowed");
args.push_back(visibilityArg.data());
std::vector<char> widthArg = FormatArg("--deqp-surface-width=%u", config.width);
args.push_back(widthArg.data());
std::vector<char> heightArg = FormatArg("--deqp-surface-height=%u", config.height);
args.push_back(heightArg.data());
std::vector<char> testNameArg = FormatArg("--deqp-case=%s", testPath.c_str());
args.push_back(testNameArg.data());
// Redirect cout
std::streambuf* oldCoutStreamBuf = std::cout.rdbuf();
std::ostringstream strCout;
std::cout.rdbuf(strCout.rdbuf());
tcu::CommandLine cmdLine(args.size(), args.data());
tcu::DirArchive archive(GetExecutableDirectory().c_str());
tcu::TestLog log(cmdLine.getLogFileName(), cmdLine.getLogFlags());
de::UniquePtr<tcu::Platform> platform(new Win32EglCustomDisplayPlatform(config.displayType));
de::UniquePtr<tcu::App> app(new tcu::App(*platform, archive, log, cmdLine));
// Main loop.
for (;;)
{
if (!app->iterate())
{
break;
}
}
// Restore old cout
std::cout.rdbuf(oldCoutStreamBuf);
EXPECT_EQ(0, app->getResult().numFailed) << strCout.str();
}
catch (const std::exception& e)
{
FAIL() << e.what();
}
}
//
// Copyright (c) 2014 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.
//
#ifndef DEQP_TESTS_DEQP_TESTS_H_
#define DEQP_TESTS_DEQP_TESTS_H_
#include "gtest/gtest.h"
#include <EGL/egl.h>
#include <string>
struct DEQPConfig
{
size_t width;
size_t height;
bool hidden;
EGLNativeDisplayType displayType;
};
void SetCurrentConfig(const DEQPConfig& config);
const DEQPConfig& GetCurrentConfig();
void RunDEQPTest(const std::string &testPath, const DEQPConfig& config);
#endif // DEQP_TESTS_DEQP_TESTS_H_
dEQP-GLES3.functional.prerequisite.*
dEQP-GLES3.functional.buffer.write.*
dEQP-GLES3.functional.samplers.*
dEQP-GLES3.functional.state_query.internal_format.*
dEQP-GLES3.functional.shaders.preprocessor.basic.*
dEQP-GLES3.functional.shaders.preprocessor.invalid_redefinitions.*
dEQP-GLES3.functional.shaders.preprocessor.comments.*
dEQP-GLES3.functional.shaders.preprocessor.function_definitions.*
dEQP-GLES3.functional.shaders.preprocessor.recursion.*
dEQP-GLES3.functional.shaders.preprocessor.function_redefinitions.*
dEQP-GLES3.functional.shaders.preprocessor.semantic.*
dEQP-GLES3.functional.shaders.preprocessor.invalid_ops.*
dEQP-GLES3.functional.shaders.preprocessor.directive.*
dEQP-GLES3.functional.shaders.preprocessor.extensions.*
dEQP-GLES3.functional.shaders.preprocessor.invalid_expressions.*
dEQP-GLES3.functional.shaders.preprocessor.operator_precedence.*
dEQP-GLES3.functional.shaders.constants.*
dEQP-GLES3.functional.shaders.linkage.varying.interpolation.*
dEQP-GLES3.functional.shaders.linkage.varying.usage.*
dEQP-GLES3.functional.shaders.conversions.scalar_to_scalar.*
dEQP-GLES3.functional.shaders.conversions.scalar_to_vector.*
dEQP-GLES3.functional.shaders.conversions.vector_to_scalar.*
dEQP-GLES3.functional.shaders.conversions.vector_illegal.*
dEQP-GLES3.functional.shaders.conversions.vector_to_vector.*
dEQP-GLES3.functional.texture.mipmap.2d.basic.*
dEQP-GLES3.functional.texture.mipmap.2d.affine.*
dEQP-GLES3.functional.texture.mipmap.2d.bias.*
dEQP-GLES3.functional.texture.mipmap.cube.projected.*
dEQP-GLES3.functional.texture.mipmap.cube.bias.*
dEQP-GLES3.functional.texture.mipmap.3d.basic.*
dEQP-GLES3.functional.texture.mipmap.3d.affine.*
dEQP-GLES3.functional.texture.mipmap.3d.projected.*
dEQP-GLES3.functional.texture.mipmap.3d.bias.*
dEQP-GLES3.functional.multisample.*
dEQP-GLES3.functional.shaders.linkage.varying.basic_types.*
dEQP-GLES3.functional.shaders.linkage.varying.struct.*
dEQP-GLES3.functional.shaders.linkage.varying.interpolation.*
dEQP-GLES3.functional.shaders.linkage.varying.usage.*
dEQP-GLES3.functional.shaders.linkage.uniform.*
dEQP-GLES3.functional.rasterizer_discard.*
\ No newline at end of file
import os
import re
import sys
def ReadFileAsLines(filename):
"""Reads a file, removing blank lines and lines that start with #"""
file = open(filename, "r")
raw_lines = file.readlines()
file.close()
lines = []
for line in raw_lines:
line = line.strip()
if len(line) > 0 and not line.startswith("#"):
lines.append(line)
return lines
def GetCleanTestName(testName):
replacements = { "dEQP-": "", ".*": "", ".":"_", }
cleanName = testName
for replaceKey in replacements:
cleanName = cleanName.replace(replaceKey, replacements[replaceKey])
return cleanName
def GenerateTests(outFile, testNames):
''' Remove duplicate tests '''
testNames = list(set(testNames))
outFile.write("#include \"deqp_tests.h\"\n\n")
for test in testNames:
outFile.write("TEST(deqp, " + GetCleanTestName(test) + ")\n")
outFile.write("{\n")
outFile.write(" RunDEQPTest(\"" + test + "\", GetCurrentConfig());\n")
outFile.write("}\n\n")
def main(argv):
tests = ReadFileAsLines(argv[0])
output = open(argv[1], 'wb')
GenerateTests(output, tests)
output.close()
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
'variables': 'variables':
{ {
'angle_build_conformance_tests%': '0', 'angle_build_conformance_tests%': '0',
'angle_build_deqp_tests%': '0',
'rapidjson_include_dir': 'third_party/rapidjson/include', 'rapidjson_include_dir': 'third_party/rapidjson/include',
'rapidjson_headers': 'rapidjson_headers':
...@@ -363,71 +362,6 @@ ...@@ -363,71 +362,6 @@
}, },
], ],
}], }],
['angle_build_deqp_tests',
{
'targets':
[
{
'target_name': 'angle_deqp_tests',
'type': 'executable',
'includes': [ '../../build/common_defines.gypi', ],
'dependencies':
[
'<(angle_path)/src/angle.gyp:libGLESv2',
'<(angle_path)/src/angle.gyp:libEGL',
'third_party/deqp/src/deqp/modules/gles3/gles3.gyp:deqp-gles3',
'third_party/deqp/src/deqp/framework/platform/platform.gyp:tcutil-platform',
'angle_test_support',
],
'include_dirs':
[
'<(angle_path)/include',
'deqp_tests',
],
'variables':
{
'deqp_tests_output_dir': '<(SHARED_INTERMEDIATE_DIR)/deqp_tests',
'deqp_tests_input_file': 'deqp_tests/deqp_tests.txt',
'deqp_tests_generated_file': '<(deqp_tests_output_dir)/generated_deqp_tests.cpp',
},
'sources':
[
'deqp_tests/deqp_test_main.cpp',
'deqp_tests/deqp_tests.cpp',
'deqp_tests/deqp_tests.h',
'<(deqp_tests_generated_file)',
],
'actions':
[
{
'action_name': 'generate_deqp_tests',
'message': 'Generating dEQP tests...',
'msvs_cygwin_shell': 0,
'variables':
{
'deqp_tests_generator_script': 'deqp_tests/generate_deqp_tests.py',
},
'inputs':
[
'<(deqp_tests_generator_script)',
'<(deqp_tests_input_file)',
],
'outputs':
[
'<(deqp_tests_generated_file)',
],
'action':
[
'python',
'<(deqp_tests_generator_script)',
'<(deqp_tests_input_file)',
'<(deqp_tests_generated_file)',
],
},
],
},
],
}],
], ],
}], }],
], ],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment