1 /*
2 * Copyright (c) 2024 Intel Corporation
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include <gtest/gtest.h>
7 #include "brw_fs.h"
8 #include "brw_fs_builder.h"
9 #include "brw_cfg.h"
10
11 using namespace brw;
12
13 struct FSCombineConstantsTest : public ::testing::Test {
FSCombineConstantsTestFSCombineConstantsTest14 FSCombineConstantsTest() {
15 mem_ctx = ralloc_context(NULL);
16
17 devinfo = {};
18 devinfo.ver = 9;
19 devinfo.verx10 = 90;
20
21 compiler = {};
22 compiler.devinfo = &devinfo;
23 brw_init_isa_info(&compiler.isa, &devinfo);
24
25 params = {};
26 params.mem_ctx = mem_ctx;
27
28 prog_data = {};
29 nir_shader *nir =
30 nir_shader_create(mem_ctx, MESA_SHADER_COMPUTE, NULL, NULL);
31
32 shader = new fs_visitor(&compiler, ¶ms, NULL,
33 &prog_data.base, nir, 8, false, false);
34 }
35
~FSCombineConstantsTestFSCombineConstantsTest36 ~FSCombineConstantsTest() override {
37 delete shader;
38 ralloc_free(mem_ctx);
39 mem_ctx = NULL;
40 }
41
42 void *mem_ctx;
43 brw_compiler compiler;
44 brw_compile_params params;
45 intel_device_info devinfo;
46 struct brw_wm_prog_data prog_data;
47 struct gl_shader_program *shader_prog;
48
49 fs_visitor *shader;
50
opt_combine_constantsFSCombineConstantsTest51 bool opt_combine_constants(fs_visitor *s) {
52 const bool print = getenv("TEST_DEBUG");
53
54 if (print) {
55 fprintf(stderr, "= Before =\n");
56 s->cfg->dump();
57 }
58
59 bool ret = brw_fs_opt_combine_constants(*s);
60
61 if (print) {
62 fprintf(stderr, "\n= After =\n");
63 s->cfg->dump();
64 }
65
66 return ret;
67 }
68 };
69
70 static fs_builder
make_builder(fs_visitor * s)71 make_builder(fs_visitor *s)
72 {
73 return fs_builder(s, s->dispatch_width).at_end();
74 }
75
TEST_F(FSCombineConstantsTest,Simple)76 TEST_F(FSCombineConstantsTest, Simple)
77 {
78 fs_builder bld = make_builder(shader);
79
80 brw_reg r = brw_vec8_grf(1, 0);
81 brw_reg imm_a = brw_imm_ud(1);
82 brw_reg imm_b = brw_imm_ud(2);
83
84 bld.SEL(r, imm_a, imm_b);
85 brw_calculate_cfg(*shader);
86
87 bool progress = opt_combine_constants(shader);
88 ASSERT_TRUE(progress);
89
90 ASSERT_EQ(shader->cfg->num_blocks, 1);
91 bblock_t *block = cfg_first_block(shader->cfg);
92 ASSERT_NE(block, nullptr);
93
94 /* We can do better but for now sanity check that
95 * there's a MOV and a SEL.
96 */
97 ASSERT_EQ(bblock_start(block)->opcode, BRW_OPCODE_MOV);
98 ASSERT_EQ(bblock_end(block)->opcode, BRW_OPCODE_SEL);
99 }
100
TEST_F(FSCombineConstantsTest,DoContainingDo)101 TEST_F(FSCombineConstantsTest, DoContainingDo)
102 {
103 fs_builder bld = make_builder(shader);
104
105 brw_reg r1 = brw_vec8_grf(1, 0);
106 brw_reg r2 = brw_vec8_grf(2, 0);
107 brw_reg imm_a = brw_imm_ud(1);
108 brw_reg imm_b = brw_imm_ud(2);
109
110 bld.DO();
111 bld.DO();
112 bld.SEL(r1, imm_a, imm_b);
113 bld.WHILE();
114 bld.WHILE();
115 bld.SEL(r2, imm_a, imm_b);
116 brw_calculate_cfg(*shader);
117
118 unsigned original_num_blocks = shader->cfg->num_blocks;
119
120 bool progress = opt_combine_constants(shader);
121 ASSERT_TRUE(progress);
122
123 /* We can do better but for now sanity check there's
124 * enough blocks, since the original issue motivating this
125 * test is that the shader would be empty.
126 */
127 ASSERT_GE(shader->cfg->num_blocks, original_num_blocks);
128 brw_fs_validate(*shader);
129 }
130
131