mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-23 11:10:10 +01:00
258 lines
6.2 KiB
C++
258 lines
6.2 KiB
C++
|
|
/*
|
||
|
|
* Copyright © 2025 Intel Corporation
|
||
|
|
* SPDX-License-Identifier: MIT
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include "test_helpers.h"
|
||
|
|
#include "brw_builder.h"
|
||
|
|
|
||
|
|
std::string
|
||
|
|
brw_shader_to_string(brw_shader *s)
|
||
|
|
{
|
||
|
|
if (!s->cfg)
|
||
|
|
brw_calculate_cfg(*s);
|
||
|
|
|
||
|
|
char *str = NULL;
|
||
|
|
size_t size = 0;
|
||
|
|
|
||
|
|
FILE *f = open_memstream(&str, &size);
|
||
|
|
brw_print_instructions(*s, f);
|
||
|
|
fclose(f);
|
||
|
|
|
||
|
|
std::string result(str);
|
||
|
|
free(str);
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
void
|
||
|
|
brw_reindex_vgrfs(brw_shader *s)
|
||
|
|
{
|
||
|
|
struct Entry {
|
||
|
|
int new_nr;
|
||
|
|
int size;
|
||
|
|
bool valid;
|
||
|
|
};
|
||
|
|
|
||
|
|
unsigned next_nr = 0;
|
||
|
|
Entry *map = rzalloc_array(NULL, Entry, s->alloc.count);
|
||
|
|
|
||
|
|
/* Build map and update references to VGRFs instructions as
|
||
|
|
* they are seen. First destination then sources.
|
||
|
|
*/
|
||
|
|
foreach_block_and_inst(block, brw_inst, inst, s->cfg) {
|
||
|
|
if (inst->dst.file == VGRF) {
|
||
|
|
Entry &entry = map[inst->dst.nr];
|
||
|
|
if (!entry.valid) {
|
||
|
|
entry.new_nr = next_nr++;
|
||
|
|
entry.size = s->alloc.sizes[inst->dst.nr];
|
||
|
|
entry.valid = true;
|
||
|
|
}
|
||
|
|
inst->dst.nr = entry.new_nr;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (int i = 0; i < inst->sources; i++) {
|
||
|
|
if (inst->src[i].file == VGRF) {
|
||
|
|
Entry &entry = map[inst->src[i].nr];
|
||
|
|
if (!entry.valid) {
|
||
|
|
entry.new_nr = next_nr++;
|
||
|
|
entry.size = s->alloc.sizes[inst->src[i].nr];
|
||
|
|
entry.valid = true;
|
||
|
|
}
|
||
|
|
inst->src[i].nr = entry.new_nr;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Move unused entries to the end. */
|
||
|
|
for (unsigned i = 0; i < s->alloc.count; i++) {
|
||
|
|
Entry &entry = map[i];
|
||
|
|
if (!entry.valid) {
|
||
|
|
entry.new_nr = next_nr++;
|
||
|
|
entry.size = s->alloc.sizes[i];
|
||
|
|
entry.valid = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
assert(next_nr == s->alloc.count);
|
||
|
|
|
||
|
|
/* Update sizes. */
|
||
|
|
for (unsigned i = 0; i < s->alloc.count; i++)
|
||
|
|
s->alloc.sizes[map[i].new_nr] = map[i].size;
|
||
|
|
|
||
|
|
ralloc_free(map);
|
||
|
|
|
||
|
|
s->invalidate_analysis(BRW_DEPENDENCY_VARIABLES);
|
||
|
|
}
|
||
|
|
|
||
|
|
void
|
||
|
|
EXPECT_SHADERS_MATCH(brw_shader *a, brw_shader *b)
|
||
|
|
{
|
||
|
|
if (!a->cfg)
|
||
|
|
brw_calculate_cfg(*a);
|
||
|
|
if (!b->cfg)
|
||
|
|
brw_calculate_cfg(*b);
|
||
|
|
|
||
|
|
brw_validate(*a);
|
||
|
|
brw_validate(*b);
|
||
|
|
|
||
|
|
brw_reindex_vgrfs(a);
|
||
|
|
brw_reindex_vgrfs(b);
|
||
|
|
|
||
|
|
std::string sa = brw_shader_to_string(a);
|
||
|
|
std::string sb = brw_shader_to_string(b);
|
||
|
|
|
||
|
|
EXPECT_EQ(sa, sb);
|
||
|
|
}
|
||
|
|
|
||
|
|
class TestHelpers : public brw_shader_pass_test {};
|
||
|
|
|
||
|
|
TEST_F(TestHelpers, ReindexVGRFsDestinations)
|
||
|
|
{
|
||
|
|
brw_builder bld = make_shader();
|
||
|
|
|
||
|
|
brw_reg d = bld.vgrf(BRW_TYPE_UD);
|
||
|
|
brw_reg c = bld.vgrf(BRW_TYPE_UD);
|
||
|
|
brw_reg b = bld.vgrf(BRW_TYPE_UD);
|
||
|
|
brw_reg a = bld.vgrf(BRW_TYPE_UD);
|
||
|
|
|
||
|
|
brw_inst *mov_a = bld.MOV(a, brw_vec8_grf(0, 0));
|
||
|
|
brw_inst *mov_b = bld.MOV(b, a);
|
||
|
|
brw_inst *mov_c = bld.MOV(c, b);
|
||
|
|
brw_inst *add_d = bld.ADD(d, a, b);
|
||
|
|
|
||
|
|
EXPECT_EQ(mov_a->dst.nr, 3);
|
||
|
|
EXPECT_EQ(mov_b->dst.nr, 2);
|
||
|
|
EXPECT_EQ(mov_c->dst.nr, 1);
|
||
|
|
EXPECT_EQ(add_d->dst.nr, 0);
|
||
|
|
|
||
|
|
brw_calculate_cfg(*bld.shader);
|
||
|
|
brw_reindex_vgrfs(bld.shader);
|
||
|
|
|
||
|
|
EXPECT_EQ(mov_a->dst.nr, 0);
|
||
|
|
EXPECT_EQ(mov_b->dst.nr, 1);
|
||
|
|
EXPECT_EQ(mov_c->dst.nr, 2);
|
||
|
|
EXPECT_EQ(add_d->dst.nr, 3);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TestHelpers, ReindexVGRFsSources)
|
||
|
|
{
|
||
|
|
brw_builder bld = make_shader();
|
||
|
|
|
||
|
|
brw_reg d = bld.vgrf(BRW_TYPE_UD);
|
||
|
|
brw_reg c = bld.vgrf(BRW_TYPE_UD);
|
||
|
|
brw_reg b = bld.vgrf(BRW_TYPE_UD);
|
||
|
|
brw_reg a = bld.vgrf(BRW_TYPE_UD);
|
||
|
|
|
||
|
|
brw_inst *mov_a = bld.MOV(brw_vec8_grf(0, 0), a);
|
||
|
|
brw_inst *mov_b = bld.MOV(brw_vec8_grf(7, 0), b);
|
||
|
|
brw_inst *add_cd = bld.ADD(brw_vec8_grf(14, 0), c, d);
|
||
|
|
|
||
|
|
EXPECT_EQ(mov_a->src[0].nr, 3);
|
||
|
|
EXPECT_EQ(mov_b->src[0].nr, 2);
|
||
|
|
EXPECT_EQ(add_cd->src[0].nr, 1);
|
||
|
|
EXPECT_EQ(add_cd->src[1].nr, 0);
|
||
|
|
|
||
|
|
brw_calculate_cfg(*bld.shader);
|
||
|
|
brw_reindex_vgrfs(bld.shader);
|
||
|
|
|
||
|
|
EXPECT_EQ(mov_a->src[0].nr, 0);
|
||
|
|
EXPECT_EQ(mov_b->src[0].nr, 1);
|
||
|
|
EXPECT_EQ(add_cd->src[0].nr, 2);
|
||
|
|
EXPECT_EQ(add_cd->src[1].nr, 3);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TestHelpers, ReindexVGRFsIncludesSizes)
|
||
|
|
{
|
||
|
|
brw_builder bld = make_shader();
|
||
|
|
|
||
|
|
brw_reg d = bld.vgrf(BRW_TYPE_UD, 1);
|
||
|
|
brw_reg c = bld.vgrf(BRW_TYPE_UD, 6);
|
||
|
|
brw_reg b = bld.vgrf(BRW_TYPE_UD, 8);
|
||
|
|
brw_reg a = bld.vgrf(BRW_TYPE_UD, 2);
|
||
|
|
|
||
|
|
brw_inst *mov_a = bld.MOV(a, brw_imm_d(2222));
|
||
|
|
brw_inst *mov_b = bld.MOV(b, brw_imm_d(8888));
|
||
|
|
brw_inst *mov_c = bld.MOV(c, brw_imm_d(6666));
|
||
|
|
brw_inst *mov_d = bld.MOV(d, brw_imm_d(1111));
|
||
|
|
|
||
|
|
EXPECT_EQ(mov_a->dst.nr, 3);
|
||
|
|
EXPECT_EQ(mov_b->dst.nr, 2);
|
||
|
|
EXPECT_EQ(mov_c->dst.nr, 1);
|
||
|
|
EXPECT_EQ(mov_d->dst.nr, 0);
|
||
|
|
|
||
|
|
brw_calculate_cfg(*bld.shader);
|
||
|
|
brw_reindex_vgrfs(bld.shader);
|
||
|
|
|
||
|
|
EXPECT_EQ(mov_a->dst.nr, 0);
|
||
|
|
EXPECT_EQ(mov_b->dst.nr, 1);
|
||
|
|
EXPECT_EQ(mov_c->dst.nr, 2);
|
||
|
|
EXPECT_EQ(mov_d->dst.nr, 3);
|
||
|
|
|
||
|
|
brw_shader *s = bld.shader;
|
||
|
|
EXPECT_EQ(s->alloc.count, 4);
|
||
|
|
EXPECT_EQ(s->alloc.sizes[0], 2);
|
||
|
|
EXPECT_EQ(s->alloc.sizes[1], 8);
|
||
|
|
EXPECT_EQ(s->alloc.sizes[2], 6);
|
||
|
|
EXPECT_EQ(s->alloc.sizes[3], 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TestHelpers, ReindexVGRFsUnusedAreMovedToTheEnd)
|
||
|
|
{
|
||
|
|
brw_builder bld = make_shader();
|
||
|
|
|
||
|
|
brw_reg a = bld.vgrf(BRW_TYPE_UD, 4);
|
||
|
|
UNUSED brw_reg b = bld.vgrf(BRW_TYPE_UD, 6);
|
||
|
|
brw_reg c = bld.vgrf(BRW_TYPE_UD, 8);
|
||
|
|
|
||
|
|
brw_inst *add = bld.ADD(a, a, c);
|
||
|
|
|
||
|
|
brw_calculate_cfg(*bld.shader);
|
||
|
|
brw_reindex_vgrfs(bld.shader);
|
||
|
|
|
||
|
|
EXPECT_EQ(add->src[0].nr, 0);
|
||
|
|
EXPECT_EQ(add->src[1].nr, 1);
|
||
|
|
|
||
|
|
brw_shader *s = bld.shader;
|
||
|
|
EXPECT_EQ(s->alloc.count, 3);
|
||
|
|
EXPECT_EQ(s->alloc.sizes[0], 4);
|
||
|
|
EXPECT_EQ(s->alloc.sizes[1], 8);
|
||
|
|
EXPECT_EQ(s->alloc.sizes[2], 6);
|
||
|
|
}
|
||
|
|
|
||
|
|
TEST_F(TestHelpers, MatchShadersSameStructureDifferentNumbers)
|
||
|
|
{
|
||
|
|
brw_builder a = make_shader();
|
||
|
|
brw_builder b = make_shader();
|
||
|
|
|
||
|
|
int nr_from_a;
|
||
|
|
int nr_from_b;
|
||
|
|
|
||
|
|
/* Build using the builder automatic allocations. */
|
||
|
|
{
|
||
|
|
brw_inst *add = NULL;
|
||
|
|
|
||
|
|
brw_reg src0 = a.MOV(brw_ud8_grf(1, 0));
|
||
|
|
brw_reg src1 = a.MOV(brw_ud8_grf(7, 0));
|
||
|
|
a.ADD(src0, src1, &add);
|
||
|
|
|
||
|
|
EXPECT_EQ(add->dst.file, VGRF);
|
||
|
|
nr_from_a = add->dst.nr;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Build using explicitly created VGRFs. */
|
||
|
|
{
|
||
|
|
brw_reg dst = b.vgrf(BRW_TYPE_UD);
|
||
|
|
brw_reg src0 = b.vgrf(BRW_TYPE_UD);
|
||
|
|
brw_reg src1 = b.vgrf(BRW_TYPE_UD);
|
||
|
|
|
||
|
|
b.MOV(src0, brw_ud8_grf(1, 0));
|
||
|
|
b.MOV(src1, brw_ud8_grf(7, 0));
|
||
|
|
b.ADD(dst, src0, src1);
|
||
|
|
|
||
|
|
nr_from_b = dst.nr;
|
||
|
|
}
|
||
|
|
|
||
|
|
EXPECT_NE(nr_from_a, nr_from_b);
|
||
|
|
EXPECT_SHADERS_MATCH(a, b);
|
||
|
|
}
|