mesa/st/tests: Add array life range tests infrastructure to common test class

Signed-off-by: Gert Wollny <gw.fossdev@gmail.com>
Acked-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Gert Wollny 2018-06-05 22:26:48 +02:00
parent d8c2119f9b
commit 0981fc84df
2 changed files with 186 additions and 27 deletions

View file

@ -46,7 +46,8 @@ void *FakeCodeline::mem_ctx = nullptr;
FakeCodeline::FakeCodeline(tgsi_opcode _op, const vector<int>& _dst,
const vector<int>& _src, const vector<int>&_to):
op(_op),
max_temp_id(0)
max_temp_id(0),
max_array_id(0)
{
transform(_dst.begin(), _dst.end(), std::back_inserter(dst),
[this](int i) { return create_dst_register(i);});
@ -64,7 +65,8 @@ FakeCodeline::FakeCodeline(tgsi_opcode _op, const vector<pair<int,int>>& _dst,
const vector<pair<int, const char *>>&_to,
SWZ with_swizzle):
op(_op),
max_temp_id(0)
max_temp_id(0),
max_array_id(0)
{
(void)with_swizzle;
@ -88,7 +90,8 @@ FakeCodeline::FakeCodeline(tgsi_opcode _op, const vector<tuple<int,int,int>>& _d
const vector<tuple<int,int,int>>& _src,
const vector<tuple<int,int,int>>&_to, RA with_reladdr):
op(_op),
max_temp_id(0)
max_temp_id(0),
max_array_id(0)
{
(void)with_reladdr;
@ -108,9 +111,35 @@ FakeCodeline::FakeCodeline(tgsi_opcode _op, const vector<tuple<int,int,int>>& _d
});
}
FakeCodeline::FakeCodeline(tgsi_opcode _op, const vector<tuple<int,int,int>>& _dst,
const vector<tuple<int,int, const char*>>& _src,
const vector<tuple<int,int, const char*>>&_to,
ARR with_array):
FakeCodeline(_op)
{
(void)with_array;
transform(_dst.begin(), _dst.end(), std::back_inserter(dst),
[this](const tuple<int,int,int>& r) {
return create_array_dst_register(r);
});
transform(_src.begin(), _src.end(), std::back_inserter(src),
[this](const tuple<int,int,const char*>& r) {
return create_array_src_register(r);
});
transform(_to.begin(), _to.end(), std::back_inserter(tex_offsets),
[this](const tuple<int,int,const char*>& r) {
return create_array_src_register(r);
});
}
FakeCodeline::FakeCodeline(const glsl_to_tgsi_instruction& instr):
op(instr.op),
max_temp_id(0)
max_temp_id(0),
max_array_id(0)
{
int nsrc = num_inst_src_regs(&instr);
int ndst = num_inst_dst_regs(&instr);
@ -129,7 +158,14 @@ FakeCodeline::FakeCodeline(const glsl_to_tgsi_instruction& instr):
template <typename st_reg>
void FakeCodeline::read_reg(const st_reg& s)
{
if (s.file == PROGRAM_TEMPORARY) {
if (s.file == PROGRAM_ARRAY) {
if (s.array_id > max_array_id)
max_array_id = s.array_id;
if (s.reladdr)
read_reg(*s.reladdr);
if (s.reladdr2)
read_reg(*s.reladdr2);
} else if (s.file == PROGRAM_TEMPORARY) {
if (s.index > max_temp_id)
max_temp_id = s.index;
}
@ -207,6 +243,8 @@ st_src_reg FakeCodeline::create_src_register(int src_idx, gl_register_file file)
max_temp_id = src_idx;
} else if (file == PROGRAM_ARRAY) {
retval.array_id = 1;
if (max_array_id < 1)
max_array_id = 1;
}
retval.swizzle = SWIZZLE_XYZW;
retval.type = GLSL_TYPE_INT;
@ -223,6 +261,48 @@ st_src_reg *FakeCodeline::create_rel_src_register(int idx)
return retval;
}
st_src_reg FakeCodeline::create_array_src_register(const tuple<int,int, const char*>& r)
{
int array_id = std::get<0>(r);
int idx = std::get<1>(r);
st_src_reg retval = create_src_register(idx, std::get<2>(r));
if (array_id > 0) {
retval.file = PROGRAM_ARRAY;
retval.array_id = array_id;
if (max_array_id < array_id)
max_array_id = array_id;
} else {
if (max_temp_id < idx)
max_temp_id = idx;
}
return retval;
}
st_dst_reg FakeCodeline::create_array_dst_register(const tuple<int,int,int>& r)
{
int array_id = std::get<0>(r);
int idx = std::get<1>(r);
st_dst_reg retval = create_dst_register(idx, std::get<2>(r));
if (array_id > 0) {
retval.file = PROGRAM_ARRAY;
retval.array_id = array_id;
if (max_array_id < array_id)
max_array_id = array_id;
} else {
if (max_temp_id < idx)
max_temp_id = idx;
}
return retval;
}
st_src_reg FakeCodeline::create_src_register(const tuple<int,int,int>& src)
{
int src_idx = std::get<0>(src);
@ -286,6 +366,8 @@ st_dst_reg FakeCodeline::create_dst_register(int dst_idx, gl_register_file file)
max_temp_id = dst_idx;
} else if (file == PROGRAM_ARRAY) {
retval.array_id = 1;
if (max_array_id < 1)
max_array_id = 1;
}
retval.writemask = 0xF;
retval.type = GLSL_TYPE_INT;
@ -350,30 +432,43 @@ void FakeCodeline::set_mem_ctx(void *ctx)
FakeShader::FakeShader(const vector<FakeCodeline>& source):
program(source),
num_temps(0)
num_temps(0),
num_arrays(0)
{
for (const FakeCodeline& i: source) {
int t = i.get_max_reg_id();
if (t > num_temps)
num_temps = t;
int a = i.get_max_array_id();
if (a > num_arrays)
num_arrays = a;
}
++num_temps;
}
FakeShader::FakeShader(exec_list *tgsi_prog):
num_temps(0)
num_temps(0),
num_arrays(0)
{
FakeCodeline nop(TGSI_OPCODE_NOP);
FakeCodeline& last = nop;
foreach_in_list(glsl_to_tgsi_instruction, inst, tgsi_prog) {
program.push_back(last = FakeCodeline(*inst));
if (last.get_max_array_id() > num_arrays)
num_arrays = last.get_max_array_id();
if (num_temps < last.get_max_reg_id())
num_temps = last.get_max_reg_id();
}
++num_temps;
}
int FakeShader::get_num_arrays() const
{
return num_arrays;
}
int FakeShader::get_num_temps() const
{
return num_temps;
@ -390,6 +485,16 @@ exec_list* FakeShader::get_program(void *ctx) const
return prog;
}
size_t FakeShader::length() const
{
return program.size();
}
const FakeCodeline& FakeShader::line(unsigned i) const
{
return program[i];
}
void MesaTestWithMemCtx::SetUp()
{
mem_ctx = ralloc_context(nullptr);
@ -404,32 +509,36 @@ void MesaTestWithMemCtx::TearDown()
}
LifetimeEvaluatorTest::lifetime_result
LifetimeEvaluatorTest::life_range_result
LifetimeEvaluatorTest::run(const vector<FakeCodeline>& code, bool& success)
{
FakeShader shader(code);
lifetime_result result(shader.get_num_temps());
vector <array_live_range> arr(10);
life_range_result result = make_pair(life_range_result::first_type(shader.get_num_temps()),
life_range_result::second_type(shader.get_num_arrays()));
success =
get_temp_registers_required_live_ranges(mem_ctx, shader.get_program(mem_ctx),
shader.get_num_temps(),
&result[0], 9, &arr[0]);
shader.get_num_temps(),&result.first[0],
shader.get_num_arrays(), &result.second[0]);
return result;
}
void LifetimeEvaluatorTest::run(const vector<FakeCodeline>& code, const temp_lt_expect& e)
{
FakeShader shader(code);
lifetime_result result(shader.get_num_temps());
vector <array_live_range> arr(10);
bool success =
get_temp_registers_required_live_ranges(mem_ctx, shader.get_program(mem_ctx),
shader.get_num_temps(),
&result[0], 9, &arr[0]);
bool success = false;
auto result = run(code, success);
ASSERT_TRUE(success);
ASSERT_EQ(result.size(), e.size());
check(result, e);
ASSERT_EQ(result.first.size(), e.size());
check(result.first, e);
}
void LifetimeEvaluatorTest::run(const vector<FakeCodeline>& code, const array_lt_expect& e)
{
bool success = false;
auto result = run(code, success);
ASSERT_TRUE(success);
ASSERT_EQ(result.second.size(), e.size());
check(result.second, e);
}
void LifetimeEvaluatorExactTest::check( const vector<register_live_range>& lifetimes,
@ -441,6 +550,16 @@ void LifetimeEvaluatorExactTest::check( const vector<register_live_range>& lifet
}
}
void LifetimeEvaluatorExactTest::check(const vector<array_live_range>& lifetimes,
const array_lt_expect& e)
{
for (unsigned i = 0; i < lifetimes.size(); ++i) {
EXPECT_EQ(lifetimes[i].begin(), e[i].begin());
EXPECT_EQ(lifetimes[i].end(), e[i].end());
EXPECT_EQ(lifetimes[i].access_mask(), e[i].access_mask());
}
}
void LifetimeEvaluatorAtLeastTest::check( const vector<register_live_range>& lifetimes,
const temp_lt_expect& e)
{
@ -450,6 +569,20 @@ void LifetimeEvaluatorAtLeastTest::check( const vector<register_live_range>& lif
}
}
void LifetimeEvaluatorAtLeastTest::check(const vector<array_live_range>& lifetimes,
const array_lt_expect& e)
{
for (unsigned i = 0; i < lifetimes.size(); ++i) {
EXPECT_LE(lifetimes[i].begin(), e[i].begin());
EXPECT_GE(lifetimes[i].end(), e[i].end());
/* Tests that lifetimes doesn't add unexpected swizzles */
EXPECT_EQ(lifetimes[i].access_mask()| e[i].access_mask(),
e[i].access_mask());
}
}
void RegisterRemappingTest::run(const vector<register_live_range>& lt,
const vector<int>& expect)
{
@ -478,9 +611,9 @@ void RegisterLifetimeAndRemappingTest::run(const vector<FakeCodeline>& code,
{
FakeShader shader(code);
std::vector<register_live_range> lt(shader.get_num_temps());
vector <array_live_range> arr(10);
std::vector<array_live_range> alt(shader.get_num_arrays());
get_temp_registers_required_live_ranges(mem_ctx, shader.get_program(mem_ctx),
shader.get_num_temps(), &lt[0],
9, &arr[0]);
shader.get_num_arrays(), &alt[0]);
this->run(lt, expect);
}

View file

@ -39,9 +39,12 @@ struct SWZ {};
/* Use this to make the compiler pick the constructor with reladdr below */
struct RA {};
/* Use this to make the compiler pick the constructor with array below */
struct ARR {};
/* A line to describe a TGSI instruction for building mock shaders. */
struct FakeCodeline {
FakeCodeline(tgsi_opcode _op): op(_op), max_temp_id(0) {}
FakeCodeline(tgsi_opcode _op): op(_op), max_temp_id(0), max_array_id(0) {}
FakeCodeline(tgsi_opcode _op, const std::vector<int>& _dst, const std::vector<int>& _src,
const std::vector<int>&_to);
@ -53,9 +56,14 @@ struct FakeCodeline {
const std::vector<std::tuple<int,int,int>>& _src,
const std::vector<std::tuple<int,int,int>>&_to, RA with_reladdr);
FakeCodeline(tgsi_opcode _op, const std::vector<std::tuple<int, int, int> > &_dst,
const std::vector<std::tuple<int,int, const char*>>& _src,
const std::vector<std::tuple<int,int, const char*>>&_to, ARR with_array);
FakeCodeline(const glsl_to_tgsi_instruction& inst);
int get_max_reg_id() const { return max_temp_id;}
int get_max_array_id() const { return max_array_id;}
glsl_to_tgsi_instruction *get_codeline() const;
@ -70,6 +78,8 @@ private:
st_src_reg create_src_register(int src_idx, gl_register_file file);
st_src_reg create_src_register(const std::tuple<int,int,int>& src);
st_src_reg *create_rel_src_register(int idx);
st_src_reg create_array_src_register(const std::tuple<int,int,const char*>& r);
st_dst_reg create_array_dst_register(const std::tuple<int,int,int>& r);
st_dst_reg create_dst_register(int dst_idx);
st_dst_reg create_dst_register(int dst_idx, int writemask);
@ -85,6 +95,7 @@ private:
std::vector<st_src_reg> tex_offsets;
int max_temp_id;
int max_array_id;
static void *mem_ctx;
};
@ -112,14 +123,21 @@ public:
exec_list* get_program(void *ctx) const;
int get_num_temps() const;
int get_num_arrays() const;
size_t length() const;
const FakeCodeline& line(unsigned i) const;
private:
std::vector<FakeCodeline> program;
int num_temps;
int num_arrays;
};
using temp_lt_expect = std::vector<std::vector<int>>;
using array_lt_expect = std::vector<array_live_range>;
class MesaTestWithMemCtx : public testing::Test {
void SetUp();
@ -131,12 +149,16 @@ protected:
class LifetimeEvaluatorTest : public MesaTestWithMemCtx {
protected:
void run(const std::vector<FakeCodeline>& code, const temp_lt_expect& e);
void run(const std::vector<FakeCodeline>& code, const array_lt_expect& e);
private:
using lifetime_result=std::vector<register_live_range>;
lifetime_result run(const std::vector<FakeCodeline>& code, bool& success);
using life_range_result=std::pair<std::vector<register_live_range>,
std::vector<array_live_range>>;
life_range_result run(const std::vector<FakeCodeline>& code, bool& success);
virtual void check(const std::vector<register_live_range>& result,
const temp_lt_expect& e) = 0;
virtual void check(const std::vector<array_live_range>& lifetimes,
const array_lt_expect& e) = 0;
};
/* This is a test class to check the exact life times of
@ -146,6 +168,8 @@ protected:
void check(const std::vector<register_live_range>& result,
const temp_lt_expect& e);
void check(const std::vector<array_live_range>& result,
const array_lt_expect& e);
};
/* This test class checks that the life time covers at least
@ -156,6 +180,8 @@ protected:
class LifetimeEvaluatorAtLeastTest : public LifetimeEvaluatorTest {
protected:
void check(const std::vector<register_live_range>& result, const temp_lt_expect& e);
void check(const std::vector<array_live_range>& result,
const array_lt_expect& e);
};
/* With this test class the renaming mapping estimation is tested */