diff --git a/src/compiler/glsl/meson.build b/src/compiler/glsl/meson.build index c356fcea9f9..f9f300f6269 100644 --- a/src/compiler/glsl/meson.build +++ b/src/compiler/glsl/meson.build @@ -259,20 +259,6 @@ glsl_compiler = executable( install : with_tools.contains('glsl'), ) -glsl_test = executable( - 'glsl_test', - ['test.cpp', 'test_optpass.cpp', 'test_optpass.h', - ir_expression_operation_h], - c_args : [c_msvc_compat_args, no_override_init_args], - cpp_args : [cpp_msvc_compat_args], - gnu_symbol_visibility : 'hidden', - include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux], - dependencies : [dep_clock, dep_thread, idep_getopt, idep_mesautil, idep_compiler], - link_with : [libglsl, libglsl_standalone, libglsl_util], - build_by_default : with_tools.contains('glsl'), - install : with_tools.contains('glsl'), -) - if with_any_opengl and with_tests subdir('tests') endif diff --git a/src/compiler/glsl/test.cpp b/src/compiler/glsl/test.cpp deleted file mode 100644 index b1ff92ed1d4..00000000000 --- a/src/compiler/glsl/test.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * \file test.cpp - * - * Standalone tests for the GLSL compiler. - * - * This file provides a standalone executable which can be used to - * test components of the GLSL. - * - * Each test is a function with the same signature as main(). The - * main function interprets its first argument as the name of the test - * to run, strips out that argument, and then calls the test function. - */ - -#include -#include -#include - -#include "test_optpass.h" - -/** - * Print proper usage and exit with failure. - */ -static void -usage_fail(const char *name) -{ - printf("*** usage: %s \n", name); - printf("\n"); - printf("Possible commands are:\n"); - printf(" optpass: test an optimization pass in isolation\n"); - exit(EXIT_FAILURE); -} - -static const char *extract_command_from_argv(int *argc, char **argv) -{ - if (*argc < 2) { - usage_fail(argv[0]); - } - const char *command = argv[1]; - --*argc; - memmove(&argv[1], &argv[2], (*argc) * sizeof(argv[1])); - return command; -} - -int main(int argc, char **argv) -{ - const char *command = extract_command_from_argv(&argc, argv); - if (strcmp(command, "optpass") == 0) { - return test_optpass(argc, argv); - } else { - usage_fail(argv[0]); - } - - /* Execution should never reach here. */ - return EXIT_FAILURE; -} diff --git a/src/compiler/glsl/test_optpass.cpp b/src/compiler/glsl/test_optpass.cpp deleted file mode 100644 index 075bf496a4a..00000000000 --- a/src/compiler/glsl/test_optpass.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * \file test_optpass.cpp - * - * Standalone test for optimization passes. - * - * This file provides the "optpass" command for the standalone - * glsl_test app. It accepts either GLSL or high-level IR as input, - * and performs the optimiation passes specified on the command line. - * It outputs the IR, both before and after optimiations. - */ - -#include -#include -#include -#include - -#include "ast.h" -#include "ir_optimization.h" -#include "program.h" -#include "ir_reader.h" -#include "standalone_scaffolding.h" -#include "main/mtypes.h" - -using namespace std; - -static string read_stdin_to_eof() -{ - stringbuf sb; - cin.get(sb, '\0'); - return sb.str(); -} - -static GLboolean -do_optimization(struct exec_list *ir, const char *optimization, - const struct gl_shader_compiler_options *options) -{ - int int_0; - int int_1; - int int_2; - int int_3; - - if (sscanf(optimization, "do_common_optimization ( %d ) ", &int_0) == 1) { - return do_common_optimization(ir, int_0 != 0, options, true); - } else if (strcmp(optimization, "do_algebraic") == 0) { - return do_algebraic(ir, true, options); - } else if (strcmp(optimization, "do_dead_code") == 0) { - return do_dead_code(ir); - } else if (strcmp(optimization, "do_dead_code_local") == 0) { - return do_dead_code_local(ir); - } else if (strcmp(optimization, "do_dead_code_unlinked") == 0) { - return do_dead_code_unlinked(ir); - } else if (sscanf(optimization, - "do_lower_jumps ( %d , %d , %d , %d ) ", - &int_0, &int_1, &int_2, &int_3) == 4) { - return do_lower_jumps(ir, int_0 != 0, int_3 != 0); - } else if (strcmp(optimization, "do_if_simplification") == 0) { - return do_if_simplification(ir); - } else if (strcmp(optimization, "do_mat_op_to_vec") == 0) { - return do_mat_op_to_vec(ir); - } else if (strcmp(optimization, "do_tree_grafting") == 0) { - return do_tree_grafting(ir); - } else if (strcmp(optimization, "do_vec_index_to_cond_assign") == 0) { - return do_vec_index_to_cond_assign(ir); - } else if (sscanf(optimization, "lower_instructions ( %d ) ", - &int_0) == 1) { - return lower_instructions(ir, false, false); - } else { - printf("Unrecognized optimization %s\n", optimization); - exit(EXIT_FAILURE); - return false; - } -} - -static GLboolean -do_optimization_passes(struct exec_list *ir, char **optimizations, - int num_optimizations, bool quiet, - const struct gl_shader_compiler_options *options) -{ - GLboolean overall_progress = false; - - for (int i = 0; i < num_optimizations; ++i) { - const char *optimization = optimizations[i]; - if (!quiet) { - printf("*** Running optimization %s...", optimization); - } - GLboolean progress = do_optimization(ir, optimization, options); - if (!quiet) { - printf("%s\n", progress ? "progress" : "no progress"); - } - validate_ir_tree(ir); - - overall_progress = overall_progress || progress; - } - - return overall_progress; -} - -int test_optpass(int argc, char **argv) -{ - int input_format_ir = 0; /* 0=glsl, 1=ir */ - int loop = 0; - int shader_type = GL_VERTEX_SHADER; - int quiet = 0; - int error; - - const struct option optpass_opts[] = { - { "input-ir", no_argument, &input_format_ir, 1 }, - { "input-glsl", no_argument, &input_format_ir, 0 }, - { "loop", no_argument, &loop, 1 }, - { "vertex-shader", no_argument, &shader_type, GL_VERTEX_SHADER }, - { "fragment-shader", no_argument, &shader_type, GL_FRAGMENT_SHADER }, - { "quiet", no_argument, &quiet, 1 }, - { NULL, 0, NULL, 0 } - }; - - int idx = 0; - int c; - while ((c = getopt_long(argc, argv, "", optpass_opts, &idx)) != -1) { - if (c != 0) { - printf("*** usage: %s optpass \n", argv[0]); - printf("\n"); - printf("Possible options are:\n"); - printf(" --input-ir: input format is IR\n"); - printf(" --input-glsl: input format is GLSL (the default)\n"); - printf(" --loop: run optimizations repeatedly until no progress\n"); - printf(" --vertex-shader: test with a vertex shader (the default)\n"); - printf(" --fragment-shader: test with a fragment shader\n"); - exit(EXIT_FAILURE); - } - } - - glsl_type_singleton_init_or_ref(); - - struct gl_context local_ctx; - struct gl_context *ctx = &local_ctx; - initialize_context_to_defaults(ctx, API_OPENGL_COMPAT); - - ir_variable::temporaries_allocate_names = true; - - struct gl_shader *shader = rzalloc(NULL, struct gl_shader); - shader->Type = shader_type; - shader->Stage = _mesa_shader_enum_to_shader_stage(shader_type); - - string input = read_stdin_to_eof(); - - struct _mesa_glsl_parse_state *state - = new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader); - - if (input_format_ir) { - shader->ir = new(shader) exec_list; - _mesa_glsl_initialize_types(state); - _mesa_glsl_read_ir(state, shader->ir, input.c_str(), true); - } else { - shader->Source = input.c_str(); - const char *source = shader->Source; - state->error = glcpp_preprocess(state, &source, &state->info_log, - NULL, NULL, ctx) != 0; - - if (!state->error) { - _mesa_glsl_lexer_ctor(state, source); - _mesa_glsl_parse(state); - _mesa_glsl_lexer_dtor(state); - } - - shader->ir = new(shader) exec_list; - if (!state->error && !state->translation_unit.is_empty()) - _mesa_ast_to_hir(shader->ir, state); - } - - /* Print out the initial IR */ - if (!state->error && !quiet) { - printf("*** pre-optimization IR:\n"); - _mesa_print_ir(stdout, shader->ir, state); - printf("\n--\n"); - } - - /* Optimization passes */ - if (!state->error) { - GLboolean progress; - const struct gl_shader_compiler_options *options = - &ctx->Const.ShaderCompilerOptions[_mesa_shader_enum_to_shader_stage(shader_type)]; - do { - progress = do_optimization_passes(shader->ir, &argv[optind], - argc - optind, quiet != 0, options); - } while (loop && progress); - } - - /* Print out the resulting IR */ - if (!state->error) { - if (!quiet) { - printf("*** resulting IR:\n"); - } - _mesa_print_ir(stdout, shader->ir, state); - if (!quiet) { - printf("\n--\n"); - } - } - - if (state->error) { - printf("*** error(s) occurred:\n"); - printf("%s\n", state->info_log); - printf("--\n"); - } - - error = state->error; - - ralloc_free(state); - ralloc_free(shader); - - glsl_type_singleton_decref(); - - return error; -} - diff --git a/src/compiler/glsl/test_optpass.h b/src/compiler/glsl/test_optpass.h deleted file mode 100644 index 477a8f21133..00000000000 --- a/src/compiler/glsl/test_optpass.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright © 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef TEST_OPTPASS_H -#define TEST_OPTPASS_H - -int test_optpass(int argc, char **argv); - -#endif /* TEST_OPTPASS_H */ diff --git a/src/compiler/glsl/tests/lower_jump_cases.py b/src/compiler/glsl/tests/lower_jump_cases.py deleted file mode 100644 index a51c9bbfc4f..00000000000 --- a/src/compiler/glsl/tests/lower_jump_cases.py +++ /dev/null @@ -1,307 +0,0 @@ -# coding=utf-8 -# -# Copyright © 2011, 2018 Intel Corporation -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice (including the next -# paragraph) shall be included in all copies or substantial portions of the -# Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. - -from sexps import * - -def make_test_case(f_name, ret_type, body): - """Create a simple optimization test case consisting of a single - function with the given name, return type, and body. - - Global declarations are automatically created for any undeclared - variables that are referenced by the function. All undeclared - variables are assumed to be floats. - """ - check_sexp(body) - declarations = {} - def make_declarations(sexp, already_declared = ()): - if isinstance(sexp, list): - if len(sexp) == 2 and sexp[0] == 'var_ref': - if sexp[1] not in already_declared: - declarations[sexp[1]] = [ - 'declare', ['in'], 'float', sexp[1]] - elif len(sexp) == 4 and sexp[0] == 'assign': - assert sexp[2][0] == 'var_ref' - if sexp[2][1] not in already_declared: - declarations[sexp[2][1]] = [ - 'declare', ['out'], 'float', sexp[2][1]] - make_declarations(sexp[3], already_declared) - else: - already_declared = set(already_declared) - for s in sexp: - if isinstance(s, list) and len(s) >= 4 and \ - s[0] == 'declare': - already_declared.add(s[3]) - else: - make_declarations(s, already_declared) - make_declarations(body) - return list(declarations.values()) + \ - [['function', f_name, ['signature', ret_type, ['parameters'], body]]] - - -# The following functions can be used to build expressions. - -def const_float(value): - """Create an expression representing the given floating point value.""" - return ['constant', 'float', ['{0:.6f}'.format(value)]] - -def const_bool(value): - """Create an expression representing the given boolean value. - - If value is not a boolean, it is converted to a boolean. So, for - instance, const_bool(1) is equivalent to const_bool(True). - """ - return ['constant', 'bool', ['{0}'.format(1 if value else 0)]] - -def gt_zero(var_name): - """Create Construct the expression var_name > 0""" - return ['expression', 'bool', '<', const_float(0), ['var_ref', var_name]] - - -# The following functions can be used to build complex control flow -# statements. All of these functions return statement lists (even -# those which only create a single statement), so that statements can -# be sequenced together using the '+' operator. - -def return_(value = None): - """Create a return statement.""" - if value is not None: - return [['return', value]] - else: - return [['return']] - -def break_(): - """Create a break statement.""" - return ['break'] - -def continue_(): - """Create a continue statement.""" - return ['continue'] - -def simple_if(var_name, then_statements, else_statements = None): - """Create a statement of the form - - if (var_name > 0.0) { - - } else { - - } - - else_statements may be omitted. - """ - if else_statements is None: - else_statements = [] - check_sexp(then_statements) - check_sexp(else_statements) - return [['if', gt_zero(var_name), then_statements, else_statements]] - -def loop(statements): - """Create a loop containing the given statements as its loop - body. - """ - check_sexp(statements) - return [['loop', statements]] - -def declare_temp(var_type, var_name): - """Create a declaration of the form - - (declare (temporary) to the variable - . The assignment uses the mask (x). - """ - check_sexp(value) - return [['assign', ['x'], ['var_ref', var_name], value]] - -def complex_if(var_prefix, statements): - """Create a statement of the form - - if (a > 0.0) { - if (b > 0.0) { - - } - } - - This is useful in testing jump lowering, because if - ends in a jump, lower_jumps.cpp won't try to combine this - construct with the code that follows it, as it might do for a - simple if. - - All variables used in the if statement are prefixed with - var_prefix. This can be used to ensure uniqueness. - """ - check_sexp(statements) - return simple_if(var_prefix + 'a', simple_if(var_prefix + 'b', statements)) - -def declare_execute_flag(): - """Create the statements that lower_jumps.cpp uses to declare and - initialize the temporary boolean execute_flag. - """ - return declare_temp('bool', 'execute_flag') + \ - assign_x('execute_flag', const_bool(True)) - -def declare_return_flag(): - """Create the statements that lower_jumps.cpp uses to declare and - initialize the temporary boolean return_flag. - """ - return declare_temp('bool', 'return_flag') + \ - assign_x('return_flag', const_bool(False)) - -def declare_return_value(): - """Create the statements that lower_jumps.cpp uses to declare and - initialize the temporary variable return_value. Assume that - return_value is a float. - """ - return declare_temp('float', 'return_value') - -def declare_break_flag(): - """Create the statements that lower_jumps.cpp uses to declare and - initialize the temporary boolean break_flag. - """ - return declare_temp('bool', 'break_flag') + \ - assign_x('break_flag', const_bool(False)) - -def lowered_return_simple(value = None): - """Create the statements that lower_jumps.cpp lowers a return - statement to, in situations where it does not need to clear the - execute flag. - """ - if value: - result = assign_x('return_value', value) - else: - result = [] - return result + assign_x('return_flag', const_bool(True)) - -def lowered_return(value = None): - """Create the statements that lower_jumps.cpp lowers a return - statement to, in situations where it needs to clear the execute - flag. - """ - return lowered_return_simple(value) + \ - assign_x('execute_flag', const_bool(False)) - -def lowered_continue(): - """Create the statement that lower_jumps.cpp lowers a continue - statement to. - """ - return assign_x('execute_flag', const_bool(False)) - -def lowered_break_simple(): - """Create the statement that lower_jumps.cpp lowers a break - statement to, in situations where it does not need to clear the - execute flag. - """ - return assign_x('break_flag', const_bool(True)) - -def lowered_break(): - """Create the statement that lower_jumps.cpp lowers a break - statement to, in situations where it needs to clear the execute - flag. - """ - return lowered_break_simple() + assign_x('execute_flag', const_bool(False)) - -def if_execute_flag(statements): - """Wrap statements in an if test so that they will only execute if - execute_flag is True. - """ - check_sexp(statements) - return [['if', ['var_ref', 'execute_flag'], statements, []]] - -def if_return_flag(then_statements, else_statements): - """Wrap statements in an if test with return_flag as the condition. - """ - check_sexp(then_statements) - check_sexp(else_statements) - return [['if', ['var_ref', 'return_flag'], then_statements, else_statements]] - -def if_not_return_flag(statements): - """Wrap statements in an if test so that they will only execute if - return_flag is False. - """ - check_sexp(statements) - return [['if', ['var_ref', 'return_flag'], [], statements]] - -def final_return(): - """Create the return statement that lower_jumps.cpp places at the - end of a function when lowering returns. - """ - return [['return', ['var_ref', 'return_value']]] - -def final_break(): - """Create the conditional break statement that lower_jumps.cpp - places at the end of a function when lowering breaks. - """ - return [['if', ['var_ref', 'break_flag'], break_(), []]] - -def bash_quote(*args): - """Quote the arguments appropriately so that bash will understand - each argument as a single word. - """ - def quote_word(word): - for c in word: - if not (c.isalpha() or c.isdigit() or c in '@%_-+=:,./'): - break - else: - if not word: - return "''" - return word - return "'{0}'".format(word.replace("'", "'\"'\"'")) - return ' '.join(quote_word(word) for word in args) - -def create_test_case(input_sexp, expected_sexp, test_name, - pull_out_jumps=False, lower_sub_return=False, - lower_main_return=False, lower_continue=False): - """Create a test case that verifies that do_lower_jumps transforms - the given code in the expected way. - """ - check_sexp(input_sexp) - check_sexp(expected_sexp) - input_str = sexp_to_string(sort_decls(input_sexp)) - expected_output = sexp_to_string(sort_decls(expected_sexp)) # XXX: don't stringify this - optimization = ( - 'do_lower_jumps({0:d}, {1:d}, {2:d}, {3:d})'.format( - pull_out_jumps, lower_sub_return, lower_main_return, - lower_continue)) - - return (test_name, optimization, input_str, expected_output) - - -def test_remove_continue_at_end_of_loop(): - """Test that a redundant continue-statement at the end of a loop is - removed. - """ - input_sexp = make_test_case('main', 'void', ( - loop(assign_x('a', const_float(1)) + - continue_()) - )) - expected_sexp = make_test_case('main', 'void', ( - loop(assign_x('a', const_float(1))) - )) - yield create_test_case(input_sexp, expected_sexp, 'remove_continue_at_end_of_loop') - - -CASES = [ - test_remove_continue_at_end_of_loop, -] diff --git a/src/compiler/glsl/tests/meson.build b/src/compiler/glsl/tests/meson.build index 0ecfb9f496b..3d0773039b6 100644 --- a/src/compiler/glsl/tests/meson.build +++ b/src/compiler/glsl/tests/meson.build @@ -72,16 +72,6 @@ if meson.can_run_host_binaries() suite : ['compiler', 'glsl'], timeout: 60, ) - - test( - 'glsl optimization', - prog_python, - args : [ - files('optimization_test.py'), - '--test-runner', glsl_test - ], - suite : ['compiler', 'glsl'], - ) endif if with_tools.contains('glsl') diff --git a/src/compiler/glsl/tests/optimization_test.py b/src/compiler/glsl/tests/optimization_test.py deleted file mode 100644 index 7f5bdd665c6..00000000000 --- a/src/compiler/glsl/tests/optimization_test.py +++ /dev/null @@ -1,125 +0,0 @@ -# encoding=utf-8 -# Copyright © 2018 Intel Corporation - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -"""Script to generate and run glsl optimization tests.""" - -import argparse -import difflib -import errno -import os -import subprocess -import sys - -import sexps -import lower_jump_cases - -# The meson version handles windows paths better, but if it's not available -# fall back to shlex -try: - from meson.mesonlib import split_args -except ImportError: - from shlex import split as split_args - - -def arg_parser(): - parser = argparse.ArgumentParser() - parser.add_argument( - '--test-runner', - required=True, - help='The glsl_test binary.') - return parser.parse_args() - - -def compare(actual, expected): - """Compare the s-expresions and return a diff if they are different.""" - actual = sexps.sort_decls(sexps.parse_sexp(actual)) - expected = sexps.sort_decls(sexps.parse_sexp(expected)) - - if actual == expected: - return None - - actual = sexps.sexp_to_string(actual) - expected = sexps.sexp_to_string(expected) - - return difflib.unified_diff(expected.splitlines(), actual.splitlines()) - - -def get_test_runner(runner): - """Wrap the test runner in the exe wrapper if necessary.""" - wrapper = os.environ.get('MESON_EXE_WRAPPER', None) - if wrapper is None: - return [runner] - return split_args(wrapper) + [runner] - - -def main(): - """Generate each test and report pass or fail.""" - args = arg_parser() - - total = 0 - passes = 0 - - runner = get_test_runner(args.test_runner) - - for gen in lower_jump_cases.CASES: - for name, opt, source, expected in gen(): - total += 1 - print('{}: '.format(name), end='') - proc = subprocess.Popen( - runner + ['optpass', '--quiet', '--input-ir', opt], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - stdin=subprocess.PIPE) - out, err = proc.communicate(source.encode('utf-8')) - out = out.decode('utf-8') - err = err.decode('utf-8') - - if proc.returncode == 255: - print("Test returned general error, possibly missing linker") - sys.exit(77) - - if err: - print('FAIL') - print('Unexpected output on stderr: {}'.format(err), - file=sys.stdout) - continue - - result = compare(out, expected) - if result is not None: - print('FAIL') - for l in result: - print(l, file=sys.stderr) - else: - print('PASS') - passes += 1 - - print('{}/{} tests returned correct results'.format(passes, total)) - exit(0 if passes == total else 1) - - -if __name__ == '__main__': - try: - main() - except OSError as e: - if e.errno == errno.ENOEXEC: - print('Skipping due to inability to run host binaries', file=sys.stderr) - sys.exit(77) - raise diff --git a/src/compiler/glsl/tests/sexps.py b/src/compiler/glsl/tests/sexps.py deleted file mode 100644 index fae8bc899db..00000000000 --- a/src/compiler/glsl/tests/sexps.py +++ /dev/null @@ -1,103 +0,0 @@ -# coding=utf-8 -# -# Copyright © 2011 Intel Corporation -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice (including the next -# paragraph) shall be included in all copies or substantial portions of the -# Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. - -# This file contains helper functions for manipulating sexps in Python. -# -# We represent a sexp in Python using nested lists containing strings. -# So, for example, the sexp (constant float (1.000000)) is represented -# as ['constant', 'float', ['1.000000']]. - -import re - -def check_sexp(sexp): - """Verify that the argument is a proper sexp. - - That is, raise an exception if the argument is not a string or a - list, or if it contains anything that is not a string or a list at - any nesting level. - """ - if isinstance(sexp, list): - for s in sexp: - check_sexp(s) - elif not isinstance(sexp, str): - raise Exception('Not a sexp: {0!r}'.format(sexp)) - -def parse_sexp(sexp): - """Convert a string, of the form that would be output by mesa, - into a sexp represented as nested lists containing strings. - """ - sexp_token_regexp = re.compile( - '[a-zA-Z_]+(@[0-9]+)?|[0-9]+(\\.[0-9]+)?|[^ \r?\n]') - stack = [[]] - for match in sexp_token_regexp.finditer(sexp): - token = match.group(0) - if token == '(': - stack.append([]) - elif token == ')': - if len(stack) == 1: - raise Exception('Unmatched )') - sexp = stack.pop() - stack[-1].append(sexp) - else: - stack[-1].append(token) - if len(stack) != 1: - raise Exception('Unmatched (') - if len(stack[0]) != 1: - raise Exception('Multiple sexps') - return stack[0][0] - -def sexp_to_string(sexp): - """Convert a sexp, represented as nested lists containing strings, - into a single string of the form parseable by mesa. - """ - if isinstance(sexp, str): - return sexp - assert isinstance(sexp, list) - result = '' - for s in sexp: - sub_result = sexp_to_string(s) - if result == '': - result = sub_result - elif '\n' not in result and '\n' not in sub_result and \ - len(result) + len(sub_result) + 1 <= 70: - result += ' ' + sub_result - else: - result += '\n' + sub_result - return '({0})'.format(result.replace('\n', '\n ')) - -def sort_decls(sexp): - """Sort all toplevel variable declarations in sexp. - - This is used to work around the fact that - ir_reader::read_instructions reorders declarations. - """ - assert isinstance(sexp, list) - decls = [] - other_code = [] - for s in sexp: - if isinstance(s, list) and len(s) >= 4 and s[0] == 'declare': - decls.append(s) - else: - other_code.append(s) - return sorted(decls) + other_code -