r300: remove compiler tests
There are only three very simple tests but several hundreds of lines of corresponding infrastructure. The tests never helped me to catch a real issue and in fact I've only seen them fail when I changed the corresponding pass semantics and forgot to update the tests (or like when we enabled r300 in debian-testing and AddressSanitizer complained that there was not a single free in the tests). We now have a real CI and both piglit and dEQP contain tests that cover the regalloc and presub testing here and a shader-db run should catch if we fail the one omod optimization the optimize test is testing. So I think its time we just get rid of the tests. Signed-off-by: Pavel Ondračka <pavel.ondracka@gmail.com> Reviewed-by: Filip Gawin <filip.gawin@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27501>
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
RCP temp[0].x, const[1].x___;
|
||||
RCP temp[0].y, const[1]._y__;
|
||||
MUL temp[1].xy, const[0].xx__, temp[0].xy__;
|
||||
MOV output[0].xy, temp[1].xy;
|
||||
=
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 Tom Stellard <tstellar@gmail.com>
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "r300_compiler_tests.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
unsigned pass = 1;
|
||||
pass &= radeon_compiler_optimize_run_tests();
|
||||
pass &= radeon_compiler_regalloc_run_tests();
|
||||
pass &= radeon_compiler_util_run_tests();
|
||||
|
||||
if (pass) {
|
||||
return EXIT_SUCCESS;
|
||||
} else {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 Tom Stellard <tstellar@gmail.com>
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
*/
|
||||
|
||||
unsigned radeon_compiler_optimize_run_tests(void);
|
||||
unsigned radeon_compiler_regalloc_run_tests(void);
|
||||
unsigned radeon_compiler_util_run_tests(void);
|
||||
@@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* 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
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS 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.
|
||||
*
|
||||
* Author: Tom Stellard <thomas.stellard@amd.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "radeon_compiler.h"
|
||||
#include "radeon_dataflow.h"
|
||||
|
||||
#include "r300_compiler_tests.h"
|
||||
#include "rc_test_helpers.h"
|
||||
#include "unit_test.h"
|
||||
|
||||
static unsigned test_rc_optimize(
|
||||
struct test_result * result,
|
||||
struct radeon_compiler * c,
|
||||
const char * filename)
|
||||
{
|
||||
struct rc_test_file test_file;
|
||||
|
||||
test_begin(result);
|
||||
|
||||
if (!load_program(c, &test_file, filename)) {
|
||||
fprintf(stderr, "Failed to load program\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc_optimize(c, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void test_runner_rc_optimize(struct test_result * result)
|
||||
{
|
||||
unsigned pass = 1;
|
||||
struct radeon_compiler c;
|
||||
struct rc_instruction *inst;
|
||||
struct rc_instruction *inst_list[3];
|
||||
unsigned inst_count = 0;
|
||||
float const0[4] = {2.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
init_compiler(&c, RC_FRAGMENT_PROGRAM, 1, 0);
|
||||
|
||||
rc_constants_add_immediate_vec4(&c.Program.Constants, const0);
|
||||
|
||||
test_rc_optimize(result, &c, "omod_two_writers.test");
|
||||
|
||||
for(inst = c.Program.Instructions.Next;
|
||||
inst != &c.Program.Instructions;
|
||||
inst = inst->Next, inst_count++) {
|
||||
inst_list[inst_count] = inst;
|
||||
}
|
||||
|
||||
if (inst_list[0]->U.I.Omod != RC_OMOD_MUL_2 ||
|
||||
inst_list[1]->U.I.Omod != RC_OMOD_MUL_2 ||
|
||||
inst_list[2]->U.I.Opcode != RC_OPCODE_MOV) {
|
||||
pass = 0;
|
||||
}
|
||||
|
||||
test_check(result, pass);
|
||||
|
||||
destroy_compiler(&c);
|
||||
}
|
||||
|
||||
unsigned radeon_compiler_optimize_run_tests()
|
||||
{
|
||||
static struct test tests[] = {
|
||||
{"rc_optimize() => peephole_mul_omod()", test_runner_rc_optimize},
|
||||
{NULL, NULL}
|
||||
};
|
||||
return run_tests(tests);
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* 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
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS 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.
|
||||
*
|
||||
* Author: Tom Stellard <thomas.stellard@amd.com>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "radeon_program_pair.h"
|
||||
|
||||
#include "r300_compiler_tests.h"
|
||||
#include "rc_test_helpers.h"
|
||||
#include "unit_test.h"
|
||||
|
||||
static void dummy_allocate_hw_inputs(
|
||||
struct r300_fragment_program_compiler * c,
|
||||
void (*allocate)(void * data, unsigned input, unsigned hwreg),
|
||||
void * mydata)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < 10; i++) {
|
||||
allocate(mydata, i, i);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_runner_rc_regalloc(
|
||||
struct test_result *result,
|
||||
struct radeon_compiler *c,
|
||||
const char *filename)
|
||||
{
|
||||
struct rc_test_file test_file;
|
||||
unsigned optimizations = 1;
|
||||
unsigned do_full_regalloc = 1;
|
||||
struct rc_instruction *inst;
|
||||
unsigned pass = 1;
|
||||
|
||||
test_begin(result);
|
||||
|
||||
if (!load_program(c, &test_file, filename)) {
|
||||
fprintf(stderr, "Failed to load program\n");
|
||||
}
|
||||
|
||||
rc_pair_translate(c, NULL);
|
||||
rc_pair_schedule(c, &optimizations);
|
||||
rc_pair_remove_dead_sources(c, NULL);
|
||||
rc_pair_regalloc(c, &do_full_regalloc);
|
||||
|
||||
for(inst = c->Program.Instructions.Next;
|
||||
inst != &c->Program.Instructions;
|
||||
inst = inst->Next) {
|
||||
if (inst->Type == RC_INSTRUCTION_NORMAL &&
|
||||
inst->U.I.Opcode != RC_OPCODE_BEGIN_TEX) {
|
||||
if (GET_SWZ(inst->U.I.SrcReg[0].Swizzle, 0)
|
||||
!= RC_SWIZZLE_X) {
|
||||
pass = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test_check(result, pass);
|
||||
}
|
||||
|
||||
static void tex_1d_swizzle(struct test_result *result)
|
||||
{
|
||||
struct r300_fragment_program_compiler c;
|
||||
|
||||
memset(&c, 0, sizeof(c));
|
||||
init_compiler(&c.Base, RC_FRAGMENT_PROGRAM, 0, 0);
|
||||
c.AllocateHwInputs = dummy_allocate_hw_inputs;
|
||||
|
||||
test_runner_rc_regalloc(result, &c.Base, "regalloc_tex_1d_swizzle.test");
|
||||
|
||||
destroy_compiler(&c.Base);
|
||||
}
|
||||
|
||||
unsigned radeon_compiler_regalloc_run_tests()
|
||||
{
|
||||
static struct test tests[] = {
|
||||
{"rc_pair_regalloc() => TEX 1D Swizzle - r300", tex_1d_swizzle },
|
||||
{NULL, NULL}
|
||||
};
|
||||
return run_tests(tests);
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 Tom Stellard <tstellar@gmail.com>
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "radeon_compiler_util.h"
|
||||
#include "radeon_program.h"
|
||||
|
||||
#include "r300_compiler_tests.h"
|
||||
#include "rc_test_helpers.h"
|
||||
#include "unit_test.h"
|
||||
|
||||
static void test_rc_inst_can_use_presub(
|
||||
struct test_result * result,
|
||||
int expected,
|
||||
const char * add_str,
|
||||
const char * replace_str)
|
||||
{
|
||||
struct rc_instruction add_inst, replace_inst;
|
||||
int ret;
|
||||
|
||||
struct r300_fragment_program_compiler c = {};
|
||||
init_compiler(&c.Base, RC_FRAGMENT_PROGRAM, 0, 0);
|
||||
|
||||
test_begin(result);
|
||||
init_rc_normal_instruction(&add_inst, add_str);
|
||||
init_rc_normal_instruction(&replace_inst, replace_str);
|
||||
|
||||
ret = rc_inst_can_use_presub(&c.Base, &replace_inst, RC_PRESUB_ADD, 0,
|
||||
&replace_inst.U.I.SrcReg[0],
|
||||
&add_inst.U.I.SrcReg[0], &add_inst.U.I.SrcReg[1]);
|
||||
|
||||
test_check(result, ret == expected);
|
||||
|
||||
destroy_compiler(&c.Base);
|
||||
}
|
||||
|
||||
static void test_runner_rc_inst_can_use_presub(struct test_result * result)
|
||||
{
|
||||
|
||||
/* This tests the case where the source being replace has the same
|
||||
* register file and register index as another source register in the
|
||||
* CMP instruction. A previous version of this function was ignoring
|
||||
* all registers that shared the same file and index as the replacement
|
||||
* register when counting the number of source selects.
|
||||
*
|
||||
* https://bugs.freedesktop.org/show_bug.cgi?id=36527
|
||||
*/
|
||||
test_rc_inst_can_use_presub(result, 0,
|
||||
"ADD temp[0].z, temp[6].__x_, const[1].__x_;",
|
||||
"CMP temp[0].y, temp[0]._z__, const[0]._z__, temp[0]._y__;");
|
||||
|
||||
|
||||
/* Testing a random case that should fail
|
||||
*
|
||||
* https://bugs.freedesktop.org/show_bug.cgi?id=36527
|
||||
*/
|
||||
test_rc_inst_can_use_presub(result, 0,
|
||||
"ADD temp[3], temp[1], temp[2];",
|
||||
"MAD temp[1], temp[0], const[0].xxxx, -temp[3];");
|
||||
|
||||
/* This tests the case where the arguments of the ADD
|
||||
* instruction share the same register file and index. Normally, we
|
||||
* would need only one source select for these two arguments, but since
|
||||
* they will be part of a presubtract operation we need to use the two
|
||||
* source selects that the presubtract instruction expects
|
||||
* (src0 and src1).
|
||||
*
|
||||
* https://bugs.freedesktop.org/show_bug.cgi?id=36527
|
||||
*/
|
||||
test_rc_inst_can_use_presub(result, 0,
|
||||
"ADD temp[3].x, temp[0].x___, temp[0].x___;",
|
||||
"MAD temp[0].xyz, temp[2].xyz_, -temp[3].xxx_, input[5].xyz_;");
|
||||
}
|
||||
|
||||
unsigned radeon_compiler_util_run_tests()
|
||||
{
|
||||
static struct test tests[] = {
|
||||
{"rc_inst_can_use_presub()", test_runner_rc_inst_can_use_presub},
|
||||
{NULL, NULL}
|
||||
};
|
||||
return run_tests(tests);
|
||||
}
|
||||
@@ -1,637 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 Tom Stellard <tstellar@gmail.com>
|
||||
* Copyright 2013 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
* Author: Tom Stellard <thomas.stellard@amd.com>
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <regex.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "r500_fragprog.h"
|
||||
#include "r300_fragprog_swizzle.h"
|
||||
#include "radeon_compiler.h"
|
||||
#include "radeon_compiler_util.h"
|
||||
#include "radeon_opcodes.h"
|
||||
#include "radeon_program.h"
|
||||
#include "radeon_regalloc.h"
|
||||
#include "radeon_swizzle.h"
|
||||
#include "util/u_math.h"
|
||||
|
||||
#include "rc_test_helpers.h"
|
||||
|
||||
/* This file contains some helper functions for filling out the rc_instruction
|
||||
* data structures. These functions take a string as input based on the format
|
||||
* output by rc_program_print().
|
||||
*/
|
||||
|
||||
#define VERBOSE 0
|
||||
|
||||
#define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0)
|
||||
|
||||
#define REGEX_ERR_BUF_SIZE 50
|
||||
|
||||
struct match_info {
|
||||
const char * String;
|
||||
int Length;
|
||||
};
|
||||
|
||||
static int is_whitespace(const char *str)
|
||||
{
|
||||
regex_t regex;
|
||||
if (regcomp(®ex, "^[ \n]+$", REG_EXTENDED)) {
|
||||
fprintf(stderr, "Failed to compile whitespace regex\n");
|
||||
regfree(®ex);
|
||||
return 0;
|
||||
}
|
||||
bool ret = regexec(®ex, str, 0, NULL, 0) != REG_NOMATCH;
|
||||
regfree(®ex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int match_length(regmatch_t * matches, int index)
|
||||
{
|
||||
return matches[index].rm_eo - matches[index].rm_so;
|
||||
}
|
||||
|
||||
static int regex_helper(
|
||||
const char * regex_str,
|
||||
const char * search_str,
|
||||
regmatch_t * matches,
|
||||
int num_matches)
|
||||
{
|
||||
char err_buf[REGEX_ERR_BUF_SIZE];
|
||||
regex_t regex;
|
||||
int err_code;
|
||||
unsigned int i;
|
||||
|
||||
err_code = regcomp(®ex, regex_str, REG_EXTENDED);
|
||||
if (err_code) {
|
||||
regerror(err_code, ®ex, err_buf, REGEX_ERR_BUF_SIZE);
|
||||
fprintf(stderr, "Failed to compile regex: %s\n", err_buf);
|
||||
regfree(®ex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
err_code = regexec(®ex, search_str, num_matches, matches, 0);
|
||||
DBG("Search string: '%s'\n", search_str);
|
||||
for (i = 0; i < num_matches; i++) {
|
||||
DBG("Match %u start = %zu end = %zu\n", i,
|
||||
(size_t)matches[i].rm_so,
|
||||
(size_t)matches[i].rm_eo);
|
||||
}
|
||||
if (err_code) {
|
||||
regerror(err_code, ®ex, err_buf, REGEX_ERR_BUF_SIZE);
|
||||
fprintf(stderr, "Failed to match regex: %s\n", err_buf);
|
||||
regfree(®ex);
|
||||
return 0;
|
||||
}
|
||||
regfree(®ex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define REGEX_SRC_MATCHES 6
|
||||
|
||||
struct src_tokens {
|
||||
struct match_info Negate;
|
||||
struct match_info Abs;
|
||||
struct match_info File;
|
||||
struct match_info Index;
|
||||
struct match_info Swizzle;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the source register at index src_index for the instruction based
|
||||
* on src_str.
|
||||
*
|
||||
* NOTE: Warning in init_rc_normal_instruction() applies to this function as
|
||||
* well.
|
||||
*
|
||||
* @param src_str A string that represents the source register. The format for
|
||||
* this string is the same that is output by rc_program_print.
|
||||
* @return 1 On success, 0 on failure
|
||||
*/
|
||||
int init_rc_normal_src(
|
||||
struct rc_instruction * inst,
|
||||
unsigned int src_index,
|
||||
const char * src_str)
|
||||
{
|
||||
const char * regex_str = "(-*)(\\|*)([[:lower:]]*)\\[*([[:digit:]]*)\\]*(\\.*[[:lower:]_]*)";
|
||||
regmatch_t matches[REGEX_SRC_MATCHES];
|
||||
struct src_tokens tokens;
|
||||
struct rc_src_register * src_reg = &inst->U.I.SrcReg[src_index];
|
||||
unsigned int i;
|
||||
|
||||
/* Execute the regex */
|
||||
if (!regex_helper(regex_str, src_str, matches, REGEX_SRC_MATCHES)) {
|
||||
fprintf(stderr, "Failed to execute regex for src register.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create Tokens */
|
||||
tokens.Negate.String = src_str + matches[1].rm_so;
|
||||
tokens.Negate.Length = match_length(matches, 1);
|
||||
tokens.Abs.String = src_str + matches[2].rm_so;
|
||||
tokens.Abs.Length = match_length(matches, 2);
|
||||
tokens.File.String = src_str + matches[3].rm_so;
|
||||
tokens.File.Length = match_length(matches, 3);
|
||||
tokens.Index.String = src_str + matches[4].rm_so;
|
||||
tokens.Index.Length = match_length(matches, 4);
|
||||
tokens.Swizzle.String = src_str + matches[5].rm_so;
|
||||
tokens.Swizzle.Length = match_length(matches, 5);
|
||||
|
||||
/* Negate */
|
||||
if (tokens.Negate.Length > 0) {
|
||||
src_reg->Negate = RC_MASK_XYZW;
|
||||
}
|
||||
|
||||
/* Abs */
|
||||
if (tokens.Abs.Length > 0) {
|
||||
src_reg->Abs = 1;
|
||||
}
|
||||
|
||||
/* File */
|
||||
if (!strncmp(tokens.File.String, "temp", tokens.File.Length)) {
|
||||
src_reg->File = RC_FILE_TEMPORARY;
|
||||
} else if (!strncmp(tokens.File.String, "input", tokens.File.Length)) {
|
||||
src_reg->File = RC_FILE_INPUT;
|
||||
} else if (!strncmp(tokens.File.String, "const", tokens.File.Length)) {
|
||||
src_reg->File = RC_FILE_CONSTANT;
|
||||
} else if (!strncmp(tokens.File.String, "none", tokens.File.Length)) {
|
||||
src_reg->File = RC_FILE_NONE;
|
||||
}
|
||||
|
||||
/* Index */
|
||||
errno = 0;
|
||||
src_reg->Index = strtol(tokens.Index.String, NULL, 10);
|
||||
if (errno > 0) {
|
||||
fprintf(stderr, "Could not convert src register index.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Swizzle */
|
||||
if (tokens.Swizzle.Length == 0) {
|
||||
src_reg->Swizzle = RC_SWIZZLE_XYZW;
|
||||
} else {
|
||||
int str_index = 1;
|
||||
src_reg->Swizzle = RC_MAKE_SWIZZLE_SMEAR(RC_SWIZZLE_UNUSED);
|
||||
if (tokens.Swizzle.String[0] != '.') {
|
||||
fprintf(stderr, "First char of swizzle is not valid.\n");
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < 4 && str_index < tokens.Swizzle.Length;
|
||||
i++, str_index++) {
|
||||
if (tokens.Swizzle.String[str_index] == '-') {
|
||||
src_reg->Negate |= (1 << i);
|
||||
str_index++;
|
||||
}
|
||||
switch(tokens.Swizzle.String[str_index]) {
|
||||
case 'x':
|
||||
SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_X);
|
||||
break;
|
||||
case 'y':
|
||||
SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_Y);
|
||||
break;
|
||||
case 'z':
|
||||
SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_Z);
|
||||
break;
|
||||
case 'w':
|
||||
SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_W);
|
||||
break;
|
||||
case '1':
|
||||
SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_ONE);
|
||||
break;
|
||||
case '0':
|
||||
SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_ZERO);
|
||||
break;
|
||||
case 'H':
|
||||
SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_HALF);
|
||||
break;
|
||||
case '_':
|
||||
SET_SWZ(src_reg->Swizzle, i, RC_SWIZZLE_UNUSED);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown src register swizzle: %c\n",
|
||||
tokens.Swizzle.String[str_index]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
DBG("File=%u index=%u swizzle=%x negate=%u abs=%u\n",
|
||||
src_reg->File, src_reg->Index, src_reg->Swizzle,
|
||||
src_reg->Negate, src_reg->Abs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define REGEX_DST_MATCHES 4
|
||||
|
||||
struct dst_tokens {
|
||||
struct match_info File;
|
||||
struct match_info Index;
|
||||
struct match_info WriteMask;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the destination for the instruction based on dst_str.
|
||||
*
|
||||
* NOTE: Warning in init_rc_normal_instruction() applies to this function as
|
||||
* well.
|
||||
*
|
||||
* @param dst_str A string that represents the destination register. The format
|
||||
* for this string is the same that is output by rc_program_print.
|
||||
* @return 1 On success, 0 on failure
|
||||
*/
|
||||
int init_rc_normal_dst(
|
||||
struct rc_instruction * inst,
|
||||
const char * dst_str)
|
||||
{
|
||||
const char * regex_str = "([[:lower:]]*)\\[*([[:digit:]]*)\\]*(\\.*[[:lower:]]*)";
|
||||
regmatch_t matches[REGEX_DST_MATCHES];
|
||||
struct dst_tokens tokens;
|
||||
unsigned int i;
|
||||
|
||||
/* Execute the regex */
|
||||
if (!regex_helper(regex_str, dst_str, matches, REGEX_DST_MATCHES)) {
|
||||
fprintf(stderr, "Failed to execute regex for dst register.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create Tokens */
|
||||
tokens.File.String = dst_str + matches[1].rm_so;
|
||||
tokens.File.Length = match_length(matches, 1);
|
||||
tokens.Index.String = dst_str + matches[2].rm_so;
|
||||
tokens.Index.Length = match_length(matches, 2);
|
||||
tokens.WriteMask.String = dst_str + matches[3].rm_so;
|
||||
tokens.WriteMask.Length = match_length(matches, 3);
|
||||
|
||||
/* File Type */
|
||||
if (!strncmp(tokens.File.String, "temp", tokens.File.Length)) {
|
||||
inst->U.I.DstReg.File = RC_FILE_TEMPORARY;
|
||||
} else if (!strncmp(tokens.File.String, "output", tokens.File.Length)) {
|
||||
inst->U.I.DstReg.File = RC_FILE_OUTPUT;
|
||||
} else if (!strncmp(tokens.File.String, "none", tokens.File.Length)) {
|
||||
inst->U.I.DstReg.File = RC_FILE_NONE;
|
||||
return 1;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown dst register file type.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* File Index */
|
||||
errno = 0;
|
||||
inst->U.I.DstReg.Index = strtol(tokens.Index.String, NULL, 10);
|
||||
|
||||
if (errno > 0) {
|
||||
fprintf(stderr, "Could not convert dst register index\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* WriteMask */
|
||||
if (tokens.WriteMask.Length == 0) {
|
||||
inst->U.I.DstReg.WriteMask = RC_MASK_XYZW;
|
||||
} else {
|
||||
inst->U.I.DstReg.WriteMask = 0;
|
||||
/* The first character should be '.' */
|
||||
if (tokens.WriteMask.String[0] != '.') {
|
||||
fprintf(stderr, "1st char of writemask is not valid.\n");
|
||||
return 0;
|
||||
}
|
||||
for (i = 1; i < tokens.WriteMask.Length; i++) {
|
||||
switch(tokens.WriteMask.String[i]) {
|
||||
case 'x':
|
||||
inst->U.I.DstReg.WriteMask |= RC_MASK_X;
|
||||
break;
|
||||
case 'y':
|
||||
inst->U.I.DstReg.WriteMask |= RC_MASK_Y;
|
||||
break;
|
||||
case 'z':
|
||||
inst->U.I.DstReg.WriteMask |= RC_MASK_Z;
|
||||
break;
|
||||
case 'w':
|
||||
inst->U.I.DstReg.WriteMask |= RC_MASK_W;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown swizzle in writemask: %c\n",
|
||||
tokens.WriteMask.String[i]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
DBG("Dst Reg File=%u Index=%d Writemask=%d\n",
|
||||
inst->U.I.DstReg.File,
|
||||
inst->U.I.DstReg.Index,
|
||||
inst->U.I.DstReg.WriteMask);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define REGEX_INST_MATCHES 7
|
||||
#define REGEX_CONST_MATCHES 5
|
||||
|
||||
struct inst_tokens {
|
||||
struct match_info Opcode;
|
||||
struct match_info Sat;
|
||||
struct match_info Dst;
|
||||
struct match_info Srcs[3];
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize a normal instruction based on inst_str.
|
||||
*
|
||||
* WARNING: This function might not be able to handle every kind of format that
|
||||
* rc_program_print() can output. If you are having problems with a
|
||||
* particular string, you may need to add support for it to this functions.
|
||||
*
|
||||
* @param inst_str A string that represents the source register. The format for
|
||||
* this string is the same that is output by rc_program_print.
|
||||
* @return 1 On success, 0 on failure
|
||||
*/
|
||||
|
||||
int parse_rc_normal_instruction(
|
||||
struct rc_instruction * inst,
|
||||
const char * inst_str)
|
||||
{
|
||||
const char * regex_str = "[[:digit:]: ]*([[:upper:][:digit:]]+)(_SAT)*[ ]*([^,;]*)[, ]*([^,;]*)[, ]*([^,;]*)[, ]*([^;]*)";
|
||||
int i;
|
||||
regmatch_t matches[REGEX_INST_MATCHES];
|
||||
struct inst_tokens tokens;
|
||||
|
||||
/* Execute the regex */
|
||||
if (!regex_helper(regex_str, inst_str, matches, REGEX_INST_MATCHES)) {
|
||||
return 0;
|
||||
}
|
||||
memset(&tokens, 0, sizeof(tokens));
|
||||
|
||||
/* Create Tokens */
|
||||
tokens.Opcode.String = inst_str + matches[1].rm_so;
|
||||
tokens.Opcode.Length = match_length(matches, 1);
|
||||
if (matches[2].rm_so > -1) {
|
||||
tokens.Sat.String = inst_str + matches[2].rm_so;
|
||||
tokens.Sat.Length = match_length(matches, 2);
|
||||
}
|
||||
|
||||
|
||||
/* Fill out the rest of the instruction. */
|
||||
inst->Type = RC_INSTRUCTION_NORMAL;
|
||||
|
||||
for (i = 0; i < MAX_RC_OPCODE; i++) {
|
||||
const struct rc_opcode_info * info = rc_get_opcode_info(i);
|
||||
unsigned int first_src = 3;
|
||||
unsigned int j;
|
||||
if (strncmp(tokens.Opcode.String, info->Name, tokens.Opcode.Length)) {
|
||||
continue;
|
||||
}
|
||||
inst->U.I.Opcode = info->Opcode;
|
||||
if (info->HasDstReg) {
|
||||
char * dst_str;
|
||||
tokens.Dst.String = inst_str + matches[3].rm_so;
|
||||
tokens.Dst.Length = match_length(matches, 3);
|
||||
first_src++;
|
||||
|
||||
dst_str = malloc(sizeof(char) * (tokens.Dst.Length + 1));
|
||||
strncpy(dst_str, tokens.Dst.String, tokens.Dst.Length);
|
||||
dst_str[tokens.Dst.Length] = '\0';
|
||||
init_rc_normal_dst(inst, dst_str);
|
||||
free(dst_str);
|
||||
}
|
||||
for (j = 0; j < info->NumSrcRegs; j++) {
|
||||
char * src_str;
|
||||
tokens.Srcs[j].String =
|
||||
inst_str + matches[first_src + j].rm_so;
|
||||
tokens.Srcs[j].Length =
|
||||
match_length(matches, first_src + j);
|
||||
|
||||
src_str = malloc(sizeof(char) *
|
||||
(tokens.Srcs[j].Length + 1));
|
||||
strncpy(src_str, tokens.Srcs[j].String,
|
||||
tokens.Srcs[j].Length);
|
||||
src_str[tokens.Srcs[j].Length] = '\0';
|
||||
init_rc_normal_src(inst, j, src_str);
|
||||
free(src_str);
|
||||
}
|
||||
if (info->HasTexture) {
|
||||
/* XXX: Will this always be XYZW ? */
|
||||
inst->U.I.TexSwizzle = RC_SWIZZLE_XYZW;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define INDEX_TOKEN_LEN 4
|
||||
#define FLOAT_TOKEN_LEN 50
|
||||
int parse_constant(unsigned *index, float *data, const char *const_str)
|
||||
{
|
||||
int matched = sscanf(const_str, "const[%d] {%f, %f, %f, %f}", index,
|
||||
&data[0], &data[1], &data[2], &data[3]);
|
||||
return matched == 5;
|
||||
}
|
||||
|
||||
int init_rc_normal_instruction(
|
||||
struct rc_instruction * inst,
|
||||
const char * inst_str)
|
||||
{
|
||||
/* Initialize inst */
|
||||
memset(inst, 0, sizeof(struct rc_instruction));
|
||||
|
||||
return parse_rc_normal_instruction(inst, inst_str);
|
||||
}
|
||||
|
||||
void add_instruction(struct radeon_compiler *c, const char * inst_string)
|
||||
{
|
||||
struct rc_instruction * new_inst =
|
||||
rc_insert_new_instruction(c, c->Program.Instructions.Prev);
|
||||
|
||||
parse_rc_normal_instruction(new_inst, inst_string);
|
||||
|
||||
}
|
||||
|
||||
int add_constant(struct radeon_compiler *c, const char *const_str)
|
||||
{
|
||||
float data[4];
|
||||
unsigned index;
|
||||
struct rc_constant_list *constants;
|
||||
struct rc_constant constant;
|
||||
|
||||
if (!parse_constant(&index, data, const_str)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
constants = &c->Program.Constants;
|
||||
if (constants->_Reserved < index) {
|
||||
struct rc_constant * newlist;
|
||||
|
||||
constants->_Reserved = index + 100;
|
||||
|
||||
newlist = malloc(sizeof(struct rc_constant) * constants->_Reserved);
|
||||
if (constants->Constants) {
|
||||
memcpy(newlist, constants->Constants,
|
||||
sizeof(struct rc_constant) *
|
||||
constants->_Reserved);
|
||||
free(constants->Constants);
|
||||
}
|
||||
|
||||
constants->Constants = newlist;
|
||||
}
|
||||
|
||||
memset(&constant, 0, sizeof(constant));
|
||||
constant.Type = RC_CONSTANT_IMMEDIATE;
|
||||
constant.Size = 4;
|
||||
memcpy(constant.u.Immediate, data, sizeof(float) * 4);
|
||||
constants->Constants[index] = constant;
|
||||
constants->Count = MAX2(constants->Count, index + 1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void init_compiler(
|
||||
struct radeon_compiler *c,
|
||||
enum rc_program_type program_type,
|
||||
unsigned is_r500,
|
||||
unsigned is_r400)
|
||||
{
|
||||
struct rc_regalloc_state *rs = malloc(sizeof(struct rc_regalloc_state));
|
||||
rc_init_regalloc_state(rs, program_type);
|
||||
rc_init(c, rs);
|
||||
|
||||
c->type = program_type;
|
||||
c->is_r500 = is_r500;
|
||||
c->max_temp_regs = is_r500 ? 128 : (is_r400 ? 64 : 32);
|
||||
c->max_constants = is_r500 ? 256 : 32;
|
||||
c->max_alu_insts = (is_r500 || is_r400) ? 512 : 64;
|
||||
c->max_tex_insts = (is_r500 || is_r400) ? 512 : 32;
|
||||
if (program_type == RC_FRAGMENT_PROGRAM) {
|
||||
c->has_half_swizzles = 1;
|
||||
c->has_presub = 1;
|
||||
c->has_omod = 1;
|
||||
c->SwizzleCaps =
|
||||
is_r500 ? &r500_swizzle_caps : &r300_swizzle_caps;
|
||||
} else {
|
||||
c->SwizzleCaps = &r300_vertprog_swizzle_caps;
|
||||
}
|
||||
}
|
||||
|
||||
void destroy_compiler(struct radeon_compiler *c)
|
||||
{
|
||||
rc_destroy_regalloc_state((struct rc_regalloc_state *)c->regalloc_state);
|
||||
free((void *)c->regalloc_state);
|
||||
rc_destroy(c);
|
||||
}
|
||||
|
||||
#define MAX_LINE_LENGTH 100
|
||||
|
||||
unsigned load_program(
|
||||
struct radeon_compiler *c,
|
||||
struct rc_test_file *test,
|
||||
const char *filename)
|
||||
{
|
||||
char line[MAX_LINE_LENGTH];
|
||||
char path[PATH_MAX];
|
||||
FILE *file;
|
||||
unsigned *count;
|
||||
char **string_store;
|
||||
unsigned i = 0;
|
||||
int n;
|
||||
|
||||
memset(line, 0, sizeof(line));
|
||||
n = snprintf(path, PATH_MAX, TEST_PATH "/%s", filename);
|
||||
if (n < 0 || n >= PATH_MAX) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
file = fopen(path, "r");
|
||||
if (!file) {
|
||||
return 0;
|
||||
}
|
||||
memset(test, 0, sizeof(struct rc_test_file));
|
||||
|
||||
count = &test->num_input_lines;
|
||||
|
||||
while (fgets(line, MAX_LINE_LENGTH, file)){
|
||||
char last_char = line[MAX_LINE_LENGTH - 1];
|
||||
if (last_char && last_char != '\n') {
|
||||
fprintf(stderr, "Error line cannot be longer than 100 "
|
||||
"characters:\n%s\n", line);
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Comment
|
||||
if (line[0] == '#' || is_whitespace(line)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line[0] == '=') {
|
||||
count = &test->num_expected_lines;
|
||||
continue;
|
||||
}
|
||||
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
test->input = malloc(sizeof(char *) * test->num_input_lines);
|
||||
test->expected = malloc(sizeof(char *) * test->num_expected_lines);
|
||||
|
||||
rewind(file);
|
||||
string_store = test->input;
|
||||
|
||||
while(fgets(line, MAX_LINE_LENGTH, file)) {
|
||||
// Comment
|
||||
char * dst;
|
||||
if (line[0] == '#' || is_whitespace(line)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line[0] == '=') {
|
||||
i = 0;
|
||||
string_store = test->expected;
|
||||
continue;
|
||||
}
|
||||
|
||||
dst = string_store[i++] = malloc((strlen(line) + 1) *
|
||||
sizeof (char));
|
||||
strcpy(dst, line);
|
||||
}
|
||||
|
||||
for (i = 0; i < test->num_input_lines; i++) {
|
||||
if (test->input[i][0] == 'c') {
|
||||
add_constant(c, test->input[i]);
|
||||
free(test->input[i]);
|
||||
continue;
|
||||
}
|
||||
// XXX: Parse immediates from the file.
|
||||
add_instruction(c, test->input[i]);
|
||||
free(test->input[i]);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
free(test->input);
|
||||
free(test->expected);
|
||||
return 1;
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 Tom Stellard <tstellar@gmail.com>
|
||||
* Copyright 2013 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
* Author: Tom Stellard <thomas.stellard@amd.com>
|
||||
*/
|
||||
|
||||
#include "radeon_compiler.h"
|
||||
|
||||
struct rc_test_file {
|
||||
unsigned num_input_lines;
|
||||
char **input;
|
||||
unsigned num_expected_lines;
|
||||
char **expected;
|
||||
};
|
||||
|
||||
int init_rc_normal_src(
|
||||
struct rc_instruction * inst,
|
||||
unsigned int src_index,
|
||||
const char * src_str);
|
||||
|
||||
int init_rc_normal_dst(
|
||||
struct rc_instruction * inst,
|
||||
const char * dst_str);
|
||||
|
||||
int parse_rc_normal_instruction(
|
||||
struct rc_instruction * inst,
|
||||
const char * inst_str);
|
||||
|
||||
int parse_constant(unsigned *index, float *data, const char *const_str);
|
||||
|
||||
int init_rc_normal_instruction(
|
||||
struct rc_instruction * inst,
|
||||
const char * inst_str);
|
||||
|
||||
void add_instruction(struct radeon_compiler *c, const char * inst_string);
|
||||
|
||||
int add_constant(struct radeon_compiler *c, const char *const_str);
|
||||
|
||||
void init_compiler(
|
||||
struct radeon_compiler *c,
|
||||
enum rc_program_type program_type,
|
||||
unsigned is_r500,
|
||||
unsigned is_r400);
|
||||
|
||||
void destroy_compiler(struct radeon_compiler *c);
|
||||
|
||||
unsigned load_program(
|
||||
struct radeon_compiler *c,
|
||||
struct rc_test_file *test,
|
||||
const char *filename);
|
||||
@@ -1,15 +0,0 @@
|
||||
const[0] = { 0.0000 2.0000 1.0000 0.0000 }
|
||||
0: TEX temp[8].xyz, input[1].xy__, 2D[0];
|
||||
1: TEX temp[10].xyz, input[2].xyz_, CUBE[2];
|
||||
2: TEX temp[12].xyz, input[1].xy__, 2D[1];
|
||||
3: DP3 temp[14].w, input[2].xyz_, input[2].xyz_;
|
||||
4: MAD temp[15].xyz, temp[12].xyz_, const[0].yyy_, -none.111_;
|
||||
5: MAD temp[16].xyz, temp[10].xyz_, const[0].yyy_, -none.111_;
|
||||
6: MUL temp[17].xyz, temp[8].xyz_, input[0].xyz_;
|
||||
7: MOV output[0].w, none.___0;
|
||||
8: MOV temp[0].x, temp[14].w___;
|
||||
9: TEX temp[18].x, temp[0].x___, 1D[3];
|
||||
10: DP3 temp[20].w, temp[16].xyz_, temp[15].xyz_;
|
||||
11: MUL temp[21].xyz, temp[17].xyz_, temp[18].xxx_;
|
||||
12: MUL output[0].xyz, temp[21].xyz_, temp[20].www_;
|
||||
=
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 Tom Stellard <tstellar@gmail.com>
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "unit_test.h"
|
||||
|
||||
unsigned run_tests(struct test tests[])
|
||||
{
|
||||
int i;
|
||||
unsigned pass = 1;
|
||||
for (i = 0; tests[i].name; i++) {
|
||||
printf("Test %s\n", tests[i].name);
|
||||
memset(&tests[i].result, 0, sizeof(tests[i].result));
|
||||
tests[i].test_func(&tests[i].result);
|
||||
printf("Test %s (%d/%d) pass\n", tests[i].name,
|
||||
tests[i].result.pass, tests[i].result.test_count);
|
||||
if (tests[i].result.pass != tests[i].result.test_count) {
|
||||
pass = 0;
|
||||
}
|
||||
}
|
||||
return pass;
|
||||
}
|
||||
|
||||
void test_begin(struct test_result * result)
|
||||
{
|
||||
result->test_count++;
|
||||
}
|
||||
|
||||
void test_check(struct test_result * result, int cond)
|
||||
{
|
||||
printf("Subtest %u -> ", result->test_count);
|
||||
if (cond) {
|
||||
result->pass++;
|
||||
printf("Pass");
|
||||
} else {
|
||||
result->fail++;
|
||||
printf("Fail");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 Tom Stellard <tstellar@gmail.com>
|
||||
*
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
*/
|
||||
|
||||
struct test_result {
|
||||
unsigned int test_count;
|
||||
unsigned int pass;
|
||||
unsigned int fail;
|
||||
};
|
||||
|
||||
struct test {
|
||||
const char * name;
|
||||
void (*test_func)(struct test_result * result);
|
||||
struct test_result result;
|
||||
};
|
||||
|
||||
unsigned run_tests(struct test tests[]);
|
||||
|
||||
void test_begin(struct test_result * result);
|
||||
void test_check(struct test_result * result, int cond);
|
||||
@@ -145,32 +145,3 @@ driver_r300 = declare_dependency(
|
||||
compile_args : '-DGALLIUM_R300',
|
||||
link_with : [libr300, libradeonwinsys],
|
||||
)
|
||||
|
||||
if with_tests
|
||||
test(
|
||||
'r300_compiler_test',
|
||||
executable(
|
||||
'r300_compiler_test',
|
||||
files(
|
||||
'compiler/tests/r300_compiler_tests.c',
|
||||
'compiler/tests/radeon_compiler_optimize_tests.c',
|
||||
'compiler/tests/radeon_compiler_regalloc_tests.c',
|
||||
'compiler/tests/radeon_compiler_util_tests.c',
|
||||
'compiler/tests/rc_test_helpers.c',
|
||||
'compiler/tests/unit_test.c',
|
||||
),
|
||||
c_args : [
|
||||
'-DTEST_PATH="@0@"'.format(
|
||||
join_paths(meson.current_source_dir(), 'compiler', 'tests')
|
||||
)
|
||||
],
|
||||
include_directories : [
|
||||
inc_src, inc_include, inc_gallium, inc_gallium_aux,
|
||||
include_directories('compiler'),
|
||||
],
|
||||
link_with : [libr300, libgallium],
|
||||
dependencies : [dep_m, dep_clock, dep_dl, dep_unwind, idep_mesautil],
|
||||
),
|
||||
suite : ['r300'],
|
||||
)
|
||||
endif
|
||||
|
||||
Reference in New Issue
Block a user