mesa/st/tests: unify MockCodeLine* classes
* Merge the classes MockCodeLine and MockCodelineWithSwizzle into one, and refactor tests accordingly. * Change memory allocations to use ralloc* interface. v2: * move the test classes into a conveniance library * rename the Mock* classes to Fake* since they are not really Mocks * Base assertion of correct number of src and dst registers in tests on what the operatand actually expects * Fix number of destinations in one test v6: * fix local includes using "..." insteadof <...> Reviewed-by: Brian Paul <brianp@vmware.com> Signed-off-by: Gert Wollny <gw.fossdev@gmail.com>
This commit is contained in:
@@ -18,8 +18,13 @@ AM_CPPFLAGS = \
|
|||||||
if HAVE_STD_CXX11
|
if HAVE_STD_CXX11
|
||||||
TESTS = st-renumerate-test
|
TESTS = st-renumerate-test
|
||||||
check_PROGRAMS = st-renumerate-test
|
check_PROGRAMS = st-renumerate-test
|
||||||
|
|
||||||
|
noinst_LIBRARIES = libmesa-st-tests-common.a
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
libmesa_st_tests_common_a_SOURCES = \
|
||||||
|
st_tests_common.cpp
|
||||||
|
|
||||||
st_renumerate_test_SOURCES = \
|
st_renumerate_test_SOURCES = \
|
||||||
test_glsl_to_tgsi_lifetime.cpp
|
test_glsl_to_tgsi_lifetime.cpp
|
||||||
|
|
||||||
@@ -27,6 +32,7 @@ st_renumerate_test_LDFLAGS = \
|
|||||||
$(LLVM_LDFLAGS)
|
$(LLVM_LDFLAGS)
|
||||||
|
|
||||||
st_renumerate_test_LDADD = \
|
st_renumerate_test_LDADD = \
|
||||||
|
libmesa-st-tests-common.a \
|
||||||
$(top_builddir)/src/mesa/libmesagallium.la \
|
$(top_builddir)/src/mesa/libmesagallium.la \
|
||||||
$(top_builddir)/src/mapi/shared-glapi/libglapi.la \
|
$(top_builddir)/src/mapi/shared-glapi/libglapi.la \
|
||||||
$(top_builddir)/src/gallium/auxiliary/libgallium.la \
|
$(top_builddir)/src/gallium/auxiliary/libgallium.la \
|
||||||
|
|||||||
@@ -0,0 +1,394 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2017 Gert Wollny
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "st_tests_common.h"
|
||||||
|
|
||||||
|
#include "mesa/program/prog_instruction.h"
|
||||||
|
#include "tgsi/tgsi_info.h"
|
||||||
|
#include "tgsi/tgsi_ureg.h"
|
||||||
|
#include "compiler/glsl/list.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
using std::vector;
|
||||||
|
using std::pair;
|
||||||
|
using std::make_pair;
|
||||||
|
using std::transform;
|
||||||
|
using std::copy;
|
||||||
|
using std::tuple;
|
||||||
|
|
||||||
|
|
||||||
|
/* Implementation of helper and test classes */
|
||||||
|
void *FakeCodeline::mem_ctx = nullptr;
|
||||||
|
|
||||||
|
FakeCodeline::FakeCodeline(unsigned _op, const vector<int>& _dst,
|
||||||
|
const vector<int>& _src, const vector<int>&_to):
|
||||||
|
op(_op),
|
||||||
|
max_temp_id(0)
|
||||||
|
{
|
||||||
|
transform(_dst.begin(), _dst.end(), std::back_inserter(dst),
|
||||||
|
[this](int i) { return create_dst_register(i);});
|
||||||
|
|
||||||
|
transform(_src.begin(), _src.end(), std::back_inserter(src),
|
||||||
|
[this](int i) { return create_src_register(i);});
|
||||||
|
|
||||||
|
transform(_to.begin(), _to.end(), std::back_inserter(tex_offsets),
|
||||||
|
[this](int i) { return create_src_register(i);});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
FakeCodeline::FakeCodeline(unsigned _op, const vector<pair<int,int>>& _dst,
|
||||||
|
const vector<pair<int, const char *>>& _src,
|
||||||
|
const vector<pair<int, const char *>>&_to,
|
||||||
|
SWZ with_swizzle):
|
||||||
|
op(_op),
|
||||||
|
max_temp_id(0)
|
||||||
|
{
|
||||||
|
(void)with_swizzle;
|
||||||
|
|
||||||
|
transform(_dst.begin(), _dst.end(), std::back_inserter(dst),
|
||||||
|
[this](pair<int,int> r) {
|
||||||
|
return create_dst_register(r.first, r.second);
|
||||||
|
});
|
||||||
|
|
||||||
|
transform(_src.begin(), _src.end(), std::back_inserter(src),
|
||||||
|
[this](const pair<int,const char *>& r) {
|
||||||
|
return create_src_register(r.first, r.second);
|
||||||
|
});
|
||||||
|
|
||||||
|
transform(_to.begin(), _to.end(), std::back_inserter(tex_offsets),
|
||||||
|
[this](const pair<int,const char *>& r) {
|
||||||
|
return create_src_register(r.first, r.second);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
FakeCodeline::FakeCodeline(const glsl_to_tgsi_instruction& instr):
|
||||||
|
op(instr.op),
|
||||||
|
max_temp_id(0)
|
||||||
|
{
|
||||||
|
int nsrc = num_inst_src_regs(&instr);
|
||||||
|
int ndst = num_inst_dst_regs(&instr);
|
||||||
|
|
||||||
|
copy(instr.src, instr.src + nsrc, std::back_inserter(src));
|
||||||
|
copy(instr.dst, instr.dst + ndst, std::back_inserter(dst));
|
||||||
|
|
||||||
|
for (auto& s: src)
|
||||||
|
read_reg(s);
|
||||||
|
|
||||||
|
for (auto& d: dst)
|
||||||
|
read_reg(d);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename st_reg>
|
||||||
|
void FakeCodeline::read_reg(const st_reg& s)
|
||||||
|
{
|
||||||
|
if (s.file == PROGRAM_TEMPORARY) {
|
||||||
|
if (s.index > max_temp_id)
|
||||||
|
max_temp_id = s.index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeCodeline::print(std::ostream& os) const
|
||||||
|
{
|
||||||
|
const struct tgsi_opcode_info *info = tgsi_get_opcode_info(op);
|
||||||
|
os << tgsi_get_opcode_name(info->opcode) << " ";
|
||||||
|
|
||||||
|
for (auto d: dst) {
|
||||||
|
os << d << " ";
|
||||||
|
}
|
||||||
|
os << " <- ";
|
||||||
|
for (auto s: src) {
|
||||||
|
os << s << " ";
|
||||||
|
}
|
||||||
|
os << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator == (const FakeCodeline& lhs, const FakeCodeline& rhs)
|
||||||
|
{
|
||||||
|
if ((lhs.op != rhs.op) ||
|
||||||
|
(lhs.src.size() != rhs.src.size()) ||
|
||||||
|
(lhs.dst.size() != rhs.dst.size()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return std::equal(lhs.src.begin(), lhs.src.end(), rhs.src.begin()) &&
|
||||||
|
std::equal(lhs.dst.begin(), lhs.dst.end(), rhs.dst.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
st_src_reg FakeCodeline::create_src_register(int src_idx)
|
||||||
|
{
|
||||||
|
return create_src_register(src_idx,
|
||||||
|
src_idx < 0 ? PROGRAM_INPUT : PROGRAM_TEMPORARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int swizzle_from_char(const char *sw)
|
||||||
|
{
|
||||||
|
int swizzle = 0;
|
||||||
|
if (!sw || sw[0] == 0)
|
||||||
|
return SWIZZLE_XYZW;
|
||||||
|
|
||||||
|
const char *isw = sw;
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
switch (*isw) {
|
||||||
|
case 'x': break; /* is zero */
|
||||||
|
case 'y': swizzle |= SWIZZLE_Y << 3 * i; break;
|
||||||
|
case 'z': swizzle |= SWIZZLE_Z << 3 * i; break;
|
||||||
|
case 'w': swizzle |= SWIZZLE_W << 3 * i; break;
|
||||||
|
default:
|
||||||
|
assert(!"This test uses an unknown swizzle character");
|
||||||
|
}
|
||||||
|
if (isw[1] != 0)
|
||||||
|
++isw;
|
||||||
|
}
|
||||||
|
return swizzle;
|
||||||
|
}
|
||||||
|
|
||||||
|
st_src_reg FakeCodeline::create_src_register(int src_idx, const char *sw)
|
||||||
|
{
|
||||||
|
st_src_reg result = create_src_register(src_idx);
|
||||||
|
result.swizzle = swizzle_from_char(sw);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
st_src_reg FakeCodeline::create_src_register(int src_idx, gl_register_file file)
|
||||||
|
{
|
||||||
|
st_src_reg retval;
|
||||||
|
retval.file = file;
|
||||||
|
retval.index = src_idx >= 0 ? src_idx : 1 - src_idx;
|
||||||
|
|
||||||
|
if (file == PROGRAM_TEMPORARY) {
|
||||||
|
if (max_temp_id < src_idx)
|
||||||
|
max_temp_id = src_idx;
|
||||||
|
} else if (file == PROGRAM_ARRAY) {
|
||||||
|
retval.array_id = 1;
|
||||||
|
}
|
||||||
|
retval.swizzle = SWIZZLE_XYZW;
|
||||||
|
retval.type = GLSL_TYPE_INT;
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
st_dst_reg FakeCodeline::create_dst_register(int dst_idx)
|
||||||
|
{
|
||||||
|
return create_dst_register(dst_idx, dst_idx < 0 ?
|
||||||
|
PROGRAM_OUTPUT : PROGRAM_TEMPORARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
st_dst_reg FakeCodeline::create_dst_register(int dst_idx,int writemask)
|
||||||
|
{
|
||||||
|
gl_register_file file;
|
||||||
|
int idx = 0;
|
||||||
|
if (dst_idx >= 0) {
|
||||||
|
file = PROGRAM_TEMPORARY;
|
||||||
|
idx = dst_idx;
|
||||||
|
if (max_temp_id < idx)
|
||||||
|
max_temp_id = idx;
|
||||||
|
} else {
|
||||||
|
file = PROGRAM_OUTPUT;
|
||||||
|
idx = 1 - dst_idx;
|
||||||
|
}
|
||||||
|
return st_dst_reg(file, writemask, GLSL_TYPE_INT, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
st_dst_reg FakeCodeline::create_dst_register(int dst_idx, gl_register_file file)
|
||||||
|
{
|
||||||
|
st_dst_reg retval;
|
||||||
|
retval.file = file;
|
||||||
|
retval.index = dst_idx >= 0 ? dst_idx : 1 - dst_idx;
|
||||||
|
|
||||||
|
if (file == PROGRAM_TEMPORARY) {
|
||||||
|
if (max_temp_id < dst_idx)
|
||||||
|
max_temp_id = dst_idx;
|
||||||
|
} else if (file == PROGRAM_ARRAY) {
|
||||||
|
retval.array_id = 1;
|
||||||
|
}
|
||||||
|
retval.writemask = 0xF;
|
||||||
|
retval.type = GLSL_TYPE_INT;
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
glsl_to_tgsi_instruction *FakeCodeline::get_codeline() const
|
||||||
|
{
|
||||||
|
glsl_to_tgsi_instruction *next_instr = new(mem_ctx) glsl_to_tgsi_instruction();
|
||||||
|
next_instr->op = op;
|
||||||
|
next_instr->info = tgsi_get_opcode_info(op);
|
||||||
|
|
||||||
|
assert(src.size() == num_inst_src_regs(next_instr));
|
||||||
|
assert(dst.size() == num_inst_dst_regs(next_instr));
|
||||||
|
assert(tex_offsets.size() < 3);
|
||||||
|
|
||||||
|
copy(src.begin(), src.end(), next_instr->src);
|
||||||
|
copy(dst.begin(), dst.end(), next_instr->dst);
|
||||||
|
|
||||||
|
next_instr->tex_offset_num_offset = tex_offsets.size();
|
||||||
|
|
||||||
|
if (next_instr->tex_offset_num_offset > 0) {
|
||||||
|
next_instr->tex_offsets = ralloc_array(mem_ctx, st_src_reg, tex_offsets.size());
|
||||||
|
copy(tex_offsets.begin(), tex_offsets.end(), next_instr->tex_offsets);
|
||||||
|
} else {
|
||||||
|
next_instr->tex_offsets = nullptr;
|
||||||
|
}
|
||||||
|
return next_instr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FakeCodeline::set_mem_ctx(void *ctx)
|
||||||
|
{
|
||||||
|
mem_ctx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
FakeShader::FakeShader(const vector<FakeCodeline>& source):
|
||||||
|
program(source),
|
||||||
|
num_temps(0)
|
||||||
|
{
|
||||||
|
for (const FakeCodeline& i: source) {
|
||||||
|
int t = i.get_max_reg_id();
|
||||||
|
if (t > num_temps)
|
||||||
|
num_temps = t;
|
||||||
|
}
|
||||||
|
++num_temps;
|
||||||
|
}
|
||||||
|
|
||||||
|
FakeShader::FakeShader(exec_list *tgsi_prog):
|
||||||
|
num_temps(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 (num_temps < last.get_max_reg_id())
|
||||||
|
num_temps = last.get_max_reg_id();
|
||||||
|
}
|
||||||
|
++num_temps;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FakeShader::get_num_temps() const
|
||||||
|
{
|
||||||
|
return num_temps;
|
||||||
|
}
|
||||||
|
|
||||||
|
exec_list* FakeShader::get_program(void *ctx) const
|
||||||
|
{
|
||||||
|
exec_list *prog = new(ctx) exec_list();
|
||||||
|
|
||||||
|
for (const FakeCodeline& i: program) {
|
||||||
|
prog->push_tail(i.get_codeline());
|
||||||
|
}
|
||||||
|
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MesaTestWithMemCtx::SetUp()
|
||||||
|
{
|
||||||
|
mem_ctx = ralloc_context(nullptr);
|
||||||
|
FakeCodeline::set_mem_ctx(mem_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MesaTestWithMemCtx::TearDown()
|
||||||
|
{
|
||||||
|
ralloc_free(mem_ctx);
|
||||||
|
FakeCodeline::set_mem_ctx(nullptr);
|
||||||
|
mem_ctx = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LifetimeEvaluatorTest::lifetime_result
|
||||||
|
LifetimeEvaluatorTest::run(const vector<FakeCodeline>& code, bool& success)
|
||||||
|
{
|
||||||
|
FakeShader shader(code);
|
||||||
|
lifetime_result result(shader.get_num_temps());
|
||||||
|
|
||||||
|
success =
|
||||||
|
get_temp_registers_required_lifetimes(mem_ctx, shader.get_program(mem_ctx),
|
||||||
|
shader.get_num_temps(),
|
||||||
|
&result[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());
|
||||||
|
bool success =
|
||||||
|
get_temp_registers_required_lifetimes(mem_ctx, shader.get_program(mem_ctx),
|
||||||
|
shader.get_num_temps(),
|
||||||
|
&result[0]);
|
||||||
|
ASSERT_TRUE(success);
|
||||||
|
ASSERT_EQ(result.size(), e.size());
|
||||||
|
check(result, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LifetimeEvaluatorExactTest::check( const vector<lifetime>& lifetimes,
|
||||||
|
const temp_lt_expect& e)
|
||||||
|
{
|
||||||
|
for (unsigned i = 1; i < lifetimes.size(); ++i) {
|
||||||
|
EXPECT_EQ(lifetimes[i].begin, e[i][0]);
|
||||||
|
EXPECT_EQ(lifetimes[i].end, e[i][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LifetimeEvaluatorAtLeastTest::check( const vector<lifetime>& lifetimes,
|
||||||
|
const temp_lt_expect& e)
|
||||||
|
{
|
||||||
|
for (unsigned i = 1; i < lifetimes.size(); ++i) {
|
||||||
|
EXPECT_LE(lifetimes[i].begin, e[i][0]);
|
||||||
|
EXPECT_GE(lifetimes[i].end, e[i][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterRemappingTest::run(const vector<lifetime>& lt,
|
||||||
|
const vector<int>& expect)
|
||||||
|
{
|
||||||
|
rename_reg_pair proto{false,0};
|
||||||
|
vector<rename_reg_pair> result(lt.size(), proto);
|
||||||
|
|
||||||
|
get_temp_registers_remapping(mem_ctx, lt.size(), <[0], &result[0]);
|
||||||
|
|
||||||
|
vector<int> remap(lt.size());
|
||||||
|
for (unsigned i = 0; i < lt.size(); ++i) {
|
||||||
|
remap[i] = result[i].valid ? result[i].new_reg : i;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::transform(remap.begin(), remap.end(), result.begin(), remap.begin(),
|
||||||
|
[](int x, const rename_reg_pair& rn) {
|
||||||
|
return rn.valid ? rn.new_reg : x;
|
||||||
|
});
|
||||||
|
|
||||||
|
for(unsigned i = 1; i < remap.size(); ++i) {
|
||||||
|
EXPECT_EQ(remap[i], expect[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterLifetimeAndRemappingTest::run(const vector<FakeCodeline>& code,
|
||||||
|
const vector<int>& expect)
|
||||||
|
{
|
||||||
|
FakeShader shader(code);
|
||||||
|
std::vector<lifetime> lt(shader.get_num_temps());
|
||||||
|
get_temp_registers_required_lifetimes(mem_ctx, shader.get_program(mem_ctx),
|
||||||
|
shader.get_num_temps(), <[0]);
|
||||||
|
this->run(lt, expect);
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2017 Gert Wollny
|
||||||
|
*
|
||||||
|
* 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 mesa_st_tests_h
|
||||||
|
#define mesa_st_tests_h
|
||||||
|
|
||||||
|
#include <state_tracker/st_glsl_to_tgsi_temprename.h>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#define MP(X, W) std::make_pair(X, W)
|
||||||
|
#define MT(X,Y,Z) std::make_tuple(X,Y,Z)
|
||||||
|
|
||||||
|
|
||||||
|
/* Use this to make the compiler pick the swizzle constructor below */
|
||||||
|
struct SWZ {};
|
||||||
|
|
||||||
|
/* A line to describe a TGSI instruction for building mock shaders. */
|
||||||
|
struct FakeCodeline {
|
||||||
|
FakeCodeline(unsigned _op): op(_op), max_temp_id(0){}
|
||||||
|
FakeCodeline(unsigned _op, const std::vector<int>& _dst, const std::vector<int>& _src,
|
||||||
|
const std::vector<int>&_to);
|
||||||
|
|
||||||
|
FakeCodeline(unsigned _op, const std::vector<std::pair<int,int>>& _dst,
|
||||||
|
const std::vector<std::pair<int, const char *>>& _src,
|
||||||
|
const std::vector<std::pair<int, const char *>>&_to, SWZ with_swizzle);
|
||||||
|
|
||||||
|
FakeCodeline(const glsl_to_tgsi_instruction& inst);
|
||||||
|
|
||||||
|
int get_max_reg_id() const { return max_temp_id;}
|
||||||
|
|
||||||
|
glsl_to_tgsi_instruction *get_codeline() const;
|
||||||
|
|
||||||
|
static void set_mem_ctx(void *ctx);
|
||||||
|
|
||||||
|
friend bool operator == (const FakeCodeline& lsh, const FakeCodeline& rhs);
|
||||||
|
|
||||||
|
void print(std::ostream& os) const;
|
||||||
|
private:
|
||||||
|
st_src_reg create_src_register(int src_idx);
|
||||||
|
st_src_reg create_src_register(int src_idx, const char *swizzle);
|
||||||
|
st_src_reg create_src_register(int src_idx, gl_register_file file);
|
||||||
|
|
||||||
|
st_dst_reg create_dst_register(int dst_idx);
|
||||||
|
st_dst_reg create_dst_register(int dst_idx, int writemask);
|
||||||
|
st_dst_reg create_dst_register(int dst_idx, gl_register_file file);
|
||||||
|
|
||||||
|
template <typename st_reg>
|
||||||
|
void read_reg(const st_reg& s);
|
||||||
|
|
||||||
|
unsigned op;
|
||||||
|
std::vector<st_dst_reg> dst;
|
||||||
|
std::vector<st_src_reg> src;
|
||||||
|
std::vector<st_src_reg> tex_offsets;
|
||||||
|
|
||||||
|
int max_temp_id;
|
||||||
|
static void *mem_ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::ostream& operator << (std::ostream& os, const FakeCodeline& line)
|
||||||
|
{
|
||||||
|
line.print(os);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A few constants that will not be tracked as temporary registers
|
||||||
|
by the fake shader.
|
||||||
|
*/
|
||||||
|
const int in0 = -1;
|
||||||
|
const int in1 = -2;
|
||||||
|
const int in2 = -3;
|
||||||
|
|
||||||
|
const int out0 = -1;
|
||||||
|
const int out1 = -2;
|
||||||
|
const int out2 = -3;
|
||||||
|
|
||||||
|
class FakeShader {
|
||||||
|
public:
|
||||||
|
FakeShader(const std::vector<FakeCodeline>& source);
|
||||||
|
FakeShader(exec_list *tgsi_prog);
|
||||||
|
|
||||||
|
exec_list* get_program(void *ctx) const;
|
||||||
|
int get_num_temps() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::vector<FakeCodeline> program;
|
||||||
|
int num_temps;
|
||||||
|
};
|
||||||
|
|
||||||
|
using temp_lt_expect = std::vector<std::vector<int>>;
|
||||||
|
|
||||||
|
class MesaTestWithMemCtx : public testing::Test {
|
||||||
|
void SetUp();
|
||||||
|
void TearDown();
|
||||||
|
protected:
|
||||||
|
void *mem_ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LifetimeEvaluatorTest : public MesaTestWithMemCtx {
|
||||||
|
protected:
|
||||||
|
void run(const std::vector<FakeCodeline>& code, const temp_lt_expect& e);
|
||||||
|
private:
|
||||||
|
using lifetime_result=std::vector<lifetime>;
|
||||||
|
lifetime_result run(const std::vector<FakeCodeline>& code, bool& success);
|
||||||
|
|
||||||
|
virtual void check(const std::vector<lifetime>& result, const temp_lt_expect& e) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This is a test class to check the exact life times of
|
||||||
|
* registers. */
|
||||||
|
class LifetimeEvaluatorExactTest : public LifetimeEvaluatorTest {
|
||||||
|
protected:
|
||||||
|
void check(const std::vector<lifetime>& result, const temp_lt_expect& e);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This test class checks that the life time covers at least
|
||||||
|
* in the expected range. It is used for cases where we know that
|
||||||
|
* a the implementation could be improved on estimating the minimal
|
||||||
|
* life time.
|
||||||
|
*/
|
||||||
|
class LifetimeEvaluatorAtLeastTest : public LifetimeEvaluatorTest {
|
||||||
|
protected:
|
||||||
|
void check(const std::vector<lifetime>& result, const temp_lt_expect& e);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* With this test class the renaming mapping estimation is tested */
|
||||||
|
class RegisterRemappingTest : public MesaTestWithMemCtx {
|
||||||
|
protected:
|
||||||
|
void run(const std::vector<lifetime>& lt, const std::vector<int> &expect);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* With this test class the combined lifetime estimation and renaming
|
||||||
|
* mepping estimation is tested
|
||||||
|
*/
|
||||||
|
class RegisterLifetimeAndRemappingTest : public RegisterRemappingTest {
|
||||||
|
protected:
|
||||||
|
using RegisterRemappingTest::run;
|
||||||
|
void run(const std::vector<FakeCodeline>& code, const std::vector<int> &expect);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user