brw: Simplify the test code for brw passes
The key change is to use a builder to write the expected shader result
and compare that. To make this less error prone, a few helper functions
were added
- a way to allocate VGRFs from both shaders in parallel, that way the
same brw_reg can be used in both of them;
- assertions that a pass will make progress or not, and proper output
when the unexpected happens;
- use a common brw_shader_pass_test class so to collect some of the helpers;
- make some helpers work directly with builder.
The idea is to improve the signal in tests, so that the disasm comments
are not necessary anymore. For example
```
TEST_F(saturate_propagation_test, basic)
{
brw_reg dst1 = bld.vgrf(BRW_TYPE_F);
brw_reg src0 = bld.vgrf(BRW_TYPE_F);
brw_reg src1 = bld.vgrf(BRW_TYPE_F);
brw_reg dst0 = bld.ADD(src0, src1);
set_saturate(true, bld.MOV(dst1, dst0));
/* = Before =
*
* 0: add(16) dst0 src0 src1
* 1: mov.sat(16) dst1 dst0
*
* = After =
* 0: add.sat(16) dst0 src0 src1
* 1: mov(16) dst1 dst0
*/
brw_calculate_cfg(*v);
bblock_t *block0 = v->cfg->blocks[0];
EXPECT_EQ(0, block0->start_ip);
EXPECT_EQ(1, block0->end_ip);
EXPECT_TRUE(saturate_propagation(v));
EXPECT_EQ(0, block0->start_ip);
EXPECT_EQ(1, block0->end_ip);
EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
EXPECT_TRUE(instruction(block0, 0)->saturate);
EXPECT_EQ(BRW_OPCODE_MOV, instruction(block0, 1)->opcode);
EXPECT_FALSE(instruction(block0, 1)->saturate);
}
```
becomes
```
TEST_F(saturate_propagation_test, basic)
{
brw_builder bld = make_shader(MESA_SHADER_FRAGMENT, 16);
brw_builder exp = make_shader(MESA_SHADER_FRAGMENT, 16);
brw_reg dst0 = vgrf(bld, exp, BRW_TYPE_F);
brw_reg dst1 = vgrf(bld, exp, BRW_TYPE_F);
brw_reg src0 = vgrf(bld, exp, BRW_TYPE_F);
brw_reg src1 = vgrf(bld, exp, BRW_TYPE_F);
bld.ADD(dst0, src0, src1);
bld.MOV(dst1, dst0)->saturate = true;
EXPECT_PROGRESS(brw_opt_saturate_propagation, bld);
exp.ADD(dst0, src0, src1)->saturate = true;
exp.MOV(dst1, dst0);
EXPECT_SHADERS_MATCH(bld, exp);
}
```
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33936>
This commit is contained in:
@@ -3,101 +3,41 @@
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include "brw_shader.h"
|
||||
#include "test_helpers.h"
|
||||
#include "brw_builder.h"
|
||||
#include "brw_cfg.h"
|
||||
|
||||
struct FSCombineConstantsTest : public ::testing::Test {
|
||||
FSCombineConstantsTest() {
|
||||
mem_ctx = ralloc_context(NULL);
|
||||
class CombineConstantsTest : public brw_shader_pass_test {};
|
||||
|
||||
devinfo = {};
|
||||
devinfo.ver = 9;
|
||||
devinfo.verx10 = 90;
|
||||
|
||||
compiler = {};
|
||||
compiler.devinfo = &devinfo;
|
||||
brw_init_isa_info(&compiler.isa, &devinfo);
|
||||
|
||||
params = {};
|
||||
params.mem_ctx = mem_ctx;
|
||||
|
||||
prog_data = {};
|
||||
nir_shader *nir =
|
||||
nir_shader_create(mem_ctx, MESA_SHADER_COMPUTE, NULL, NULL);
|
||||
|
||||
shader = new brw_shader(&compiler, ¶ms, NULL,
|
||||
&prog_data.base, nir, 8, false, false);
|
||||
}
|
||||
|
||||
~FSCombineConstantsTest() override {
|
||||
delete shader;
|
||||
ralloc_free(mem_ctx);
|
||||
mem_ctx = NULL;
|
||||
}
|
||||
|
||||
void *mem_ctx;
|
||||
brw_compiler compiler;
|
||||
brw_compile_params params;
|
||||
intel_device_info devinfo;
|
||||
struct brw_wm_prog_data prog_data;
|
||||
struct gl_shader_program *shader_prog;
|
||||
|
||||
brw_shader *shader;
|
||||
|
||||
bool opt_combine_constants(brw_shader *s) {
|
||||
const bool print = getenv("TEST_DEBUG");
|
||||
|
||||
if (print) {
|
||||
fprintf(stderr, "= Before =\n");
|
||||
s->cfg->dump();
|
||||
}
|
||||
|
||||
bool ret = brw_opt_combine_constants(*s);
|
||||
|
||||
if (print) {
|
||||
fprintf(stderr, "\n= After =\n");
|
||||
s->cfg->dump();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(FSCombineConstantsTest, Simple)
|
||||
TEST_F(CombineConstantsTest, Simple)
|
||||
{
|
||||
brw_builder bld = brw_builder(shader);
|
||||
brw_builder bld = make_shader(MESA_SHADER_COMPUTE);
|
||||
brw_builder exp = make_shader(MESA_SHADER_COMPUTE);
|
||||
|
||||
brw_reg r = brw_vec8_grf(1, 0);
|
||||
brw_reg imm_a = brw_imm_ud(1);
|
||||
brw_reg imm_b = brw_imm_ud(2);
|
||||
brw_reg imm_a = brw_imm_d(1);
|
||||
brw_reg imm_b = brw_imm_d(2);
|
||||
|
||||
bld.SEL(r, imm_a, imm_b);
|
||||
brw_calculate_cfg(*shader);
|
||||
|
||||
bool progress = opt_combine_constants(shader);
|
||||
ASSERT_TRUE(progress);
|
||||
EXPECT_PROGRESS(brw_opt_combine_constants, bld);
|
||||
|
||||
ASSERT_EQ(shader->cfg->num_blocks, 1);
|
||||
bblock_t *block = shader->cfg->first_block();
|
||||
ASSERT_NE(block, nullptr);
|
||||
brw_reg tmp = component(exp.vgrf(BRW_TYPE_D), 0);
|
||||
|
||||
/* We can do better but for now sanity check that
|
||||
* there's a MOV and a SEL.
|
||||
*/
|
||||
ASSERT_EQ(block->start()->opcode, BRW_OPCODE_MOV);
|
||||
ASSERT_EQ(block->end()->opcode, BRW_OPCODE_SEL);
|
||||
exp.group(1, 0).exec_all().MOV(tmp, imm_a);
|
||||
exp .SEL(r, tmp, imm_b);
|
||||
|
||||
EXPECT_SHADERS_MATCH(bld, exp);
|
||||
}
|
||||
|
||||
TEST_F(FSCombineConstantsTest, DoContainingDo)
|
||||
TEST_F(CombineConstantsTest, DoContainingDo)
|
||||
{
|
||||
brw_builder bld = brw_builder(shader);
|
||||
brw_builder bld = make_shader(MESA_SHADER_COMPUTE);
|
||||
brw_builder exp = make_shader(MESA_SHADER_COMPUTE);
|
||||
|
||||
brw_reg r1 = brw_vec8_grf(1, 0);
|
||||
brw_reg r2 = brw_vec8_grf(2, 0);
|
||||
brw_reg imm_a = brw_imm_ud(1);
|
||||
brw_reg imm_b = brw_imm_ud(2);
|
||||
brw_reg imm_a = brw_imm_d(1);
|
||||
brw_reg imm_b = brw_imm_d(2);
|
||||
|
||||
bld.DO();
|
||||
bld.DO();
|
||||
@@ -105,18 +45,19 @@ TEST_F(FSCombineConstantsTest, DoContainingDo)
|
||||
bld.WHILE();
|
||||
bld.WHILE();
|
||||
bld.SEL(r2, imm_a, imm_b);
|
||||
brw_calculate_cfg(*shader);
|
||||
|
||||
unsigned original_num_blocks = shader->cfg->num_blocks;
|
||||
EXPECT_PROGRESS(brw_opt_combine_constants, bld);
|
||||
|
||||
bool progress = opt_combine_constants(shader);
|
||||
ASSERT_TRUE(progress);
|
||||
/* Explicit emit the expected FLOW instruction. */
|
||||
exp.emit(BRW_OPCODE_DO);
|
||||
brw_reg tmp = component(exp.vgrf(BRW_TYPE_D), 0);
|
||||
exp.group(1, 0).exec_all().MOV(tmp, imm_a);
|
||||
exp.emit(SHADER_OPCODE_FLOW);
|
||||
exp.DO();
|
||||
exp.SEL(r1, tmp, imm_b);
|
||||
exp.WHILE();
|
||||
exp.WHILE();
|
||||
exp.SEL(r2, tmp, imm_b);
|
||||
|
||||
/* We can do better but for now sanity check there's
|
||||
* enough blocks, since the original issue motivating this
|
||||
* test is that the shader would be empty.
|
||||
*/
|
||||
ASSERT_GE(shader->cfg->num_blocks, original_num_blocks);
|
||||
brw_validate(*shader);
|
||||
EXPECT_SHADERS_MATCH(bld, exp);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user