mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 02:20:11 +01:00
nouveau/mme: Add some generic builder tests
These don't need hardware and instead run entirely in the simulator. The goal is to have something that we can run in CI and which ensures consistency between the Turing and Fermi MMEs. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
parent
15295e32ec
commit
e8032b893d
4 changed files with 302 additions and 0 deletions
|
|
@ -109,6 +109,24 @@ idep_nouveau_mme = declare_dependency(
|
|||
)
|
||||
|
||||
if with_tests and not with_platform_android
|
||||
test('mme_builder',
|
||||
executable(
|
||||
'mme_builder_test',
|
||||
files('tests/mme_runner.cpp', 'tests/mme_builder_test.cpp'),
|
||||
gnu_symbol_visibility : 'hidden',
|
||||
include_directories : [inc_include, inc_src],
|
||||
dependencies : [
|
||||
dep_libdrm,
|
||||
idep_gtest,
|
||||
idep_mesautil,
|
||||
idep_nvidia_headers,
|
||||
idep_nouveau_mme,
|
||||
idep_nouveau_ws
|
||||
],
|
||||
),
|
||||
suite : ['nouveau'],
|
||||
)
|
||||
|
||||
executable(
|
||||
'mme_fermi_sim_hw_test',
|
||||
files('tests/mme_runner.cpp', 'tests/mme_fermi_sim_hw_test.cpp'),
|
||||
|
|
|
|||
179
src/nouveau/mme/tests/mme_builder_test.cpp
Normal file
179
src/nouveau/mme/tests/mme_builder_test.cpp
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
#include "mme_runner.h"
|
||||
#include "mme_tu104_sim.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "nvk_clc597.h"
|
||||
|
||||
class mme_builder_test : public ::testing::Test {
|
||||
public:
|
||||
mme_builder_test();
|
||||
~mme_builder_test();
|
||||
|
||||
std::vector<mme_runner *> sims;
|
||||
uint32_t expected[DATA_DWORDS];
|
||||
|
||||
private:
|
||||
mme_fermi_sim_runner fermi_sim;
|
||||
mme_tu104_sim_runner tu104_sim;
|
||||
};
|
||||
|
||||
#define DATA_ADDR 0xc0ffee00
|
||||
|
||||
mme_builder_test::mme_builder_test() :
|
||||
fermi_sim(DATA_ADDR),
|
||||
tu104_sim(DATA_ADDR)
|
||||
{
|
||||
memset(expected, 0, sizeof(expected));
|
||||
sims.push_back(&fermi_sim);
|
||||
sims.push_back(&tu104_sim);
|
||||
}
|
||||
|
||||
mme_builder_test::~mme_builder_test()
|
||||
{ }
|
||||
|
||||
#define ASSERT_SIM_DATA(sim) do { \
|
||||
for (uint32_t i = 0; i < DATA_DWORDS; i++) \
|
||||
ASSERT_EQ((sim)->data[i], expected[i]); \
|
||||
} while (0)
|
||||
|
||||
TEST_F(mme_builder_test, sanity)
|
||||
{
|
||||
const uint32_t canary = 0xc0ffee01;
|
||||
|
||||
expected[0] = canary;
|
||||
|
||||
for (auto sim : sims) {
|
||||
mme_builder b;
|
||||
mme_builder_init(&b, sim->devinfo);
|
||||
|
||||
sim->mme_store_data(&b, 0, mme_imm(canary));
|
||||
|
||||
auto macro = mme_builder_finish_vec(&b);
|
||||
|
||||
std::vector<uint32_t> params;
|
||||
sim->run_macro(macro, params);
|
||||
ASSERT_SIM_DATA(sim);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
merge(uint32_t x, uint32_t y,
|
||||
uint16_t dst_pos, uint16_t bits, uint16_t src_pos)
|
||||
{
|
||||
x &= ~(BITFIELD_MASK(bits) << dst_pos);
|
||||
y &= (BITFIELD_MASK(bits) << src_pos);
|
||||
return x | ((y >> src_pos) << dst_pos);
|
||||
}
|
||||
|
||||
static const uint32_t add_cases[] = {
|
||||
0x00000001,
|
||||
0xffffffff,
|
||||
0x0000ffff,
|
||||
0x00008000,
|
||||
0x0001ffff,
|
||||
0xffff8000,
|
||||
0x00010000,
|
||||
0x00020000,
|
||||
0xfffc0000,
|
||||
0xfffe0000,
|
||||
};
|
||||
|
||||
TEST_F(mme_builder_test, add)
|
||||
{
|
||||
for (auto sim : sims) {
|
||||
mme_builder b;
|
||||
mme_builder_init(&b, sim->devinfo);
|
||||
|
||||
mme_value x = mme_load(&b);
|
||||
mme_value y = mme_load(&b);
|
||||
|
||||
sim->mme_store_data(&b, 0, mme_add(&b, x, y));
|
||||
|
||||
auto macro = mme_builder_finish_vec(&b);
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(add_cases); i++) {
|
||||
for (uint32_t j = 0; j < ARRAY_SIZE(add_cases); j++) {
|
||||
std::vector<uint32_t> params;
|
||||
params.push_back(add_cases[i]);
|
||||
params.push_back(add_cases[j]);
|
||||
|
||||
sim->run_macro(macro, params);
|
||||
ASSERT_EQ(sim->data[0], add_cases[i] + add_cases[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(mme_builder_test, add_imm)
|
||||
{
|
||||
for (auto sim : sims) {
|
||||
mme_builder b;
|
||||
mme_builder_init(&b, sim->devinfo);
|
||||
|
||||
mme_value x = mme_load(&b);
|
||||
|
||||
for (uint32_t j = 0; j < ARRAY_SIZE(add_cases); j++) {
|
||||
mme_value y = mme_imm(add_cases[j]);
|
||||
sim->mme_store_data(&b, j, mme_add(&b, x, y), true);
|
||||
}
|
||||
|
||||
auto macro = mme_builder_finish_vec(&b);
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(add_cases); i++) {
|
||||
std::vector<uint32_t> params;
|
||||
params.push_back(add_cases[i]);
|
||||
|
||||
sim->run_macro(macro, params);
|
||||
|
||||
for (uint32_t j = 0; j < ARRAY_SIZE(add_cases); j++)
|
||||
ASSERT_EQ(sim->data[j], add_cases[i] + add_cases[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(mme_builder_test, merge)
|
||||
{
|
||||
static const struct {
|
||||
uint16_t dst_pos;
|
||||
uint16_t bits;
|
||||
uint16_t src_pos;
|
||||
} cases[] = {
|
||||
{ 12, 12, 20 },
|
||||
{ 12, 8, 20 },
|
||||
{ 8, 12, 20 },
|
||||
{ 12, 16, 8 },
|
||||
{ 24, 12, 8 },
|
||||
};
|
||||
|
||||
static const uint32_t x = 0x0c406fe0;
|
||||
static const uint32_t y = 0x76543210;
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(cases); i++) {
|
||||
expected[i] = merge(x, y, cases[i].dst_pos,
|
||||
cases[i].bits, cases[i].src_pos);
|
||||
}
|
||||
|
||||
for (auto sim : sims) {
|
||||
mme_builder b;
|
||||
mme_builder_init(&b, sim->devinfo);
|
||||
|
||||
mme_value xv = mme_load(&b);
|
||||
mme_value yv = mme_load(&b);
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(cases); i++) {
|
||||
mme_value mv = mme_merge(&b, xv, yv, cases[i].dst_pos,
|
||||
cases[i].bits, cases[i].src_pos);
|
||||
sim->mme_store_data(&b, i, mv, true);
|
||||
}
|
||||
|
||||
auto macro = mme_builder_finish_vec(&b);
|
||||
|
||||
std::vector<uint32_t> params;
|
||||
params.push_back(x);
|
||||
params.push_back(y);
|
||||
|
||||
sim->run_macro(macro, params);
|
||||
ASSERT_SIM_DATA(sim);
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,8 @@
|
|||
#include "mme_fermi_sim.h"
|
||||
#include "mme_tu104_sim.h"
|
||||
|
||||
#include "nvk_clc597.h"
|
||||
|
||||
#include "nouveau_bo.h"
|
||||
#include "nouveau_context.h"
|
||||
|
||||
|
|
@ -29,6 +31,13 @@ mme_hw_runner::mme_hw_runner() :
|
|||
memset(&push, 0, sizeof(push));
|
||||
}
|
||||
|
||||
void
|
||||
mme_runner::mme_store_data(mme_builder *b, uint32_t dw_idx,
|
||||
mme_value data, bool free_reg)
|
||||
{
|
||||
mme_store_imm_addr(b, data_addr + dw_idx * 4, data, free_reg);
|
||||
}
|
||||
|
||||
mme_hw_runner::~mme_hw_runner()
|
||||
{
|
||||
if (push_bo) {
|
||||
|
|
@ -178,3 +187,69 @@ mme_hw_runner::run_macro(const std::vector<uint32_t>& macro,
|
|||
|
||||
submit_push();
|
||||
}
|
||||
|
||||
mme_fermi_sim_runner::mme_fermi_sim_runner(uint64_t data_addr)
|
||||
{
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.cls_eng3d = FERMI_A;
|
||||
|
||||
memset(data_store, 0, sizeof(data_store));
|
||||
|
||||
this->devinfo = &info;
|
||||
this->data_addr = data_addr,
|
||||
this->data = data_store;
|
||||
}
|
||||
|
||||
mme_fermi_sim_runner::~mme_fermi_sim_runner()
|
||||
{ }
|
||||
|
||||
void
|
||||
mme_fermi_sim_runner::run_macro(const std::vector<uint32_t>& macro,
|
||||
const std::vector<uint32_t>& params)
|
||||
{
|
||||
std::vector<mme_fermi_inst> insts(macro.size());
|
||||
mme_fermi_decode(&insts[0], ¯o[0], macro.size());
|
||||
|
||||
/* First, make a copy of the data and simulate the macro */
|
||||
mme_fermi_sim_mem sim_mem = {
|
||||
.addr = data_addr,
|
||||
.data = data,
|
||||
.size = DATA_BO_SIZE,
|
||||
};
|
||||
mme_fermi_sim(insts.size(), &insts[0],
|
||||
params.size(), ¶ms[0],
|
||||
1, &sim_mem);
|
||||
}
|
||||
|
||||
mme_tu104_sim_runner::mme_tu104_sim_runner(uint64_t data_addr)
|
||||
{
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.cls_eng3d = TURING_A;
|
||||
|
||||
memset(data_store, 0, sizeof(data_store));
|
||||
|
||||
this->devinfo = &info;
|
||||
this->data_addr = data_addr,
|
||||
this->data = data_store;
|
||||
}
|
||||
|
||||
mme_tu104_sim_runner::~mme_tu104_sim_runner()
|
||||
{ }
|
||||
|
||||
void
|
||||
mme_tu104_sim_runner::run_macro(const std::vector<uint32_t>& macro,
|
||||
const std::vector<uint32_t>& params)
|
||||
{
|
||||
std::vector<mme_tu104_inst> insts(macro.size());
|
||||
mme_tu104_decode(&insts[0], ¯o[0], macro.size());
|
||||
|
||||
/* First, make a copy of the data and simulate the macro */
|
||||
mme_tu104_sim_mem sim_mem = {
|
||||
.addr = data_addr,
|
||||
.data = data,
|
||||
.size = DATA_BO_SIZE,
|
||||
};
|
||||
mme_tu104_sim(insts.size(), &insts[0],
|
||||
params.size(), ¶ms[0],
|
||||
1, &sim_mem);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ struct nouveau_ws_device;
|
|||
#include "nvk_cl9097.h"
|
||||
|
||||
#define DATA_BO_SIZE 4096
|
||||
#define DATA_DWORDS 1024
|
||||
|
||||
class mme_runner {
|
||||
public:
|
||||
|
|
@ -20,6 +21,9 @@ public:
|
|||
virtual void run_macro(const std::vector<uint32_t>& macro,
|
||||
const std::vector<uint32_t>& params) = 0;
|
||||
|
||||
void mme_store_data(mme_builder *b, uint32_t dw_idx,
|
||||
mme_value data, bool free_reg = false);
|
||||
|
||||
const nv_device_info *devinfo;
|
||||
uint64_t data_addr;
|
||||
uint32_t *data;
|
||||
|
|
@ -49,6 +53,32 @@ private:
|
|||
struct nv_push push;
|
||||
};
|
||||
|
||||
class mme_fermi_sim_runner : public mme_runner {
|
||||
public:
|
||||
mme_fermi_sim_runner(uint64_t data_addr);
|
||||
virtual ~mme_fermi_sim_runner();
|
||||
|
||||
virtual void run_macro(const std::vector<uint32_t>& macro,
|
||||
const std::vector<uint32_t>& params);
|
||||
|
||||
private:
|
||||
struct nv_device_info info;
|
||||
uint32_t data_store[DATA_DWORDS];
|
||||
};
|
||||
|
||||
class mme_tu104_sim_runner : public mme_runner {
|
||||
public:
|
||||
mme_tu104_sim_runner(uint64_t data_addr);
|
||||
virtual ~mme_tu104_sim_runner();
|
||||
|
||||
virtual void run_macro(const std::vector<uint32_t>& macro,
|
||||
const std::vector<uint32_t>& params);
|
||||
|
||||
private:
|
||||
struct nv_device_info info;
|
||||
uint32_t data_store[DATA_DWORDS];
|
||||
};
|
||||
|
||||
inline std::vector<uint32_t>
|
||||
mme_builder_finish_vec(mme_builder *b)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue