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);});
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;
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;
});
}
+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);
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;
}
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;
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);
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;
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;
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);
}
-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.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.size(), e.size());
- check(result, e);
+ ASSERT_EQ(result.second.size(), e.size());
+ check(result.second, e);
}
void LifetimeEvaluatorExactTest::check( const vector<register_live_range>& lifetimes,
}
}
+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)
{
}
}
+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)
{
{
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(), <[0],
- 9, &arr[0]);
+ shader.get_num_arrays(), &alt[0]);
this->run(lt, expect);
}
/* 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);
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;
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);
std::vector<st_src_reg> tex_offsets;
int max_temp_id;
+ int max_array_id;
static void *mem_ctx;
};
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();
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
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
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 */