2 * Copyright © 2015 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 #include <gtest/gtest.h>
27 #include "program/program.h"
29 class cmod_propagation_test : public ::testing::Test {
33 struct brw_context *brw;
34 struct gl_context *ctx;
35 struct brw_wm_prog_data *prog_data;
36 struct gl_shader_program *shader_prog;
37 struct brw_fragment_program *fp;
41 class cmod_propagation_fs_visitor : public fs_visitor
44 cmod_propagation_fs_visitor(struct brw_context *brw,
45 struct brw_wm_prog_data *prog_data,
46 struct gl_shader_program *shader_prog)
47 : fs_visitor(brw, NULL, NULL, prog_data, shader_prog, NULL, 8) {}
51 void cmod_propagation_test::SetUp()
53 brw = (struct brw_context *)calloc(1, sizeof(*brw));
56 fp = ralloc(NULL, struct brw_fragment_program);
57 prog_data = ralloc(NULL, struct brw_wm_prog_data);
58 shader_prog = ralloc(NULL, struct gl_shader_program);
60 v = new cmod_propagation_fs_visitor(brw, prog_data, shader_prog);
62 _mesa_init_fragment_program(ctx, &fp->program, GL_FRAGMENT_SHADER, 0);
68 instruction(bblock_t *block, int num)
70 fs_inst *inst = (fs_inst *)block->start();
71 for (int i = 0; i < num; i++) {
72 inst = (fs_inst *)inst->next;
78 cmod_propagation(fs_visitor *v)
80 const bool print = false;
83 fprintf(stderr, "= Before =\n");
87 bool ret = v->opt_cmod_propagation();
90 fprintf(stderr, "\n= After =\n");
97 TEST_F(cmod_propagation_test, basic)
99 fs_reg dest = v->vgrf(glsl_type::float_type);
100 fs_reg src0 = v->vgrf(glsl_type::float_type);
101 fs_reg src1 = v->vgrf(glsl_type::float_type);
103 v->emit(BRW_OPCODE_ADD, dest, src0, src1);
104 v->emit(BRW_OPCODE_CMP, v->reg_null_f, dest, zero)
105 ->conditional_mod = BRW_CONDITIONAL_GE;
109 * 0: add(8) dest src0 src1
110 * 1: cmp.ge.f0(8) null dest 0.0f
113 * 0: add.ge.f0(8) dest src0 src1
117 bblock_t *block0 = v->cfg->blocks[0];
119 EXPECT_EQ(0, block0->start_ip);
120 EXPECT_EQ(1, block0->end_ip);
122 EXPECT_TRUE(cmod_propagation(v));
123 EXPECT_EQ(0, block0->start_ip);
124 EXPECT_EQ(0, block0->end_ip);
125 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
126 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 0)->conditional_mod);
129 TEST_F(cmod_propagation_test, cmp_nonzero)
131 fs_reg dest = v->vgrf(glsl_type::float_type);
132 fs_reg src0 = v->vgrf(glsl_type::float_type);
133 fs_reg src1 = v->vgrf(glsl_type::float_type);
134 fs_reg nonzero(1.0f);
135 v->emit(BRW_OPCODE_ADD, dest, src0, src1);
136 v->emit(BRW_OPCODE_CMP, v->reg_null_f, dest, nonzero)
137 ->conditional_mod = BRW_CONDITIONAL_GE;
141 * 0: add(8) dest src0 src1
142 * 1: cmp.ge.f0(8) null dest 1.0f
149 bblock_t *block0 = v->cfg->blocks[0];
151 EXPECT_EQ(0, block0->start_ip);
152 EXPECT_EQ(1, block0->end_ip);
154 EXPECT_FALSE(cmod_propagation(v));
155 EXPECT_EQ(0, block0->start_ip);
156 EXPECT_EQ(1, block0->end_ip);
157 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
158 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
159 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
162 TEST_F(cmod_propagation_test, non_cmod_instruction)
164 fs_reg dest = v->vgrf(glsl_type::uint_type);
165 fs_reg src0 = v->vgrf(glsl_type::uint_type);
167 v->emit(BRW_OPCODE_FBL, dest, src0);
168 v->emit(BRW_OPCODE_CMP, v->reg_null_ud, dest, zero)
169 ->conditional_mod = BRW_CONDITIONAL_GE;
173 * 0: fbl(8) dest src0
174 * 1: cmp.ge.f0(8) null dest 0u
181 bblock_t *block0 = v->cfg->blocks[0];
183 EXPECT_EQ(0, block0->start_ip);
184 EXPECT_EQ(1, block0->end_ip);
186 EXPECT_FALSE(cmod_propagation(v));
187 EXPECT_EQ(0, block0->start_ip);
188 EXPECT_EQ(1, block0->end_ip);
189 EXPECT_EQ(BRW_OPCODE_FBL, instruction(block0, 0)->opcode);
190 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
191 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
194 TEST_F(cmod_propagation_test, intervening_flag_write)
196 fs_reg dest = v->vgrf(glsl_type::float_type);
197 fs_reg src0 = v->vgrf(glsl_type::float_type);
198 fs_reg src1 = v->vgrf(glsl_type::float_type);
199 fs_reg src2 = v->vgrf(glsl_type::float_type);
201 v->emit(BRW_OPCODE_ADD, dest, src0, src1);
202 v->emit(BRW_OPCODE_CMP, v->reg_null_f, src2, zero)
203 ->conditional_mod = BRW_CONDITIONAL_GE;
204 v->emit(BRW_OPCODE_CMP, v->reg_null_f, dest, zero)
205 ->conditional_mod = BRW_CONDITIONAL_GE;
209 * 0: add(8) dest src0 src1
210 * 1: cmp.ge.f0(8) null src2 0.0f
211 * 2: cmp.ge.f0(8) null dest 0.0f
218 bblock_t *block0 = v->cfg->blocks[0];
220 EXPECT_EQ(0, block0->start_ip);
221 EXPECT_EQ(2, block0->end_ip);
223 EXPECT_FALSE(cmod_propagation(v));
224 EXPECT_EQ(0, block0->start_ip);
225 EXPECT_EQ(2, block0->end_ip);
226 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
227 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 1)->opcode);
228 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 1)->conditional_mod);
229 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
230 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
233 TEST_F(cmod_propagation_test, intervening_flag_read)
235 fs_reg dest0 = v->vgrf(glsl_type::float_type);
236 fs_reg dest1 = v->vgrf(glsl_type::float_type);
237 fs_reg src0 = v->vgrf(glsl_type::float_type);
238 fs_reg src1 = v->vgrf(glsl_type::float_type);
239 fs_reg src2 = v->vgrf(glsl_type::float_type);
241 v->emit(BRW_OPCODE_ADD, dest0, src0, src1);
242 v->emit(BRW_OPCODE_SEL, dest1, src2, zero)
243 ->predicate = BRW_PREDICATE_NORMAL;
244 v->emit(BRW_OPCODE_CMP, v->reg_null_f, dest0, zero)
245 ->conditional_mod = BRW_CONDITIONAL_GE;
249 * 0: add(8) dest0 src0 src1
250 * 1: (+f0) sel(8) dest1 src2 0.0f
251 * 2: cmp.ge.f0(8) null dest0 0.0f
258 bblock_t *block0 = v->cfg->blocks[0];
260 EXPECT_EQ(0, block0->start_ip);
261 EXPECT_EQ(2, block0->end_ip);
263 EXPECT_FALSE(cmod_propagation(v));
264 EXPECT_EQ(0, block0->start_ip);
265 EXPECT_EQ(2, block0->end_ip);
266 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
267 EXPECT_EQ(BRW_OPCODE_SEL, instruction(block0, 1)->opcode);
268 EXPECT_EQ(BRW_PREDICATE_NORMAL, instruction(block0, 1)->predicate);
269 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
270 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);
273 TEST_F(cmod_propagation_test, intervening_dest_write)
275 fs_reg dest = v->vgrf(glsl_type::vec4_type);
276 fs_reg src0 = v->vgrf(glsl_type::float_type);
277 fs_reg src1 = v->vgrf(glsl_type::float_type);
278 fs_reg src2 = v->vgrf(glsl_type::vec2_type);
280 v->emit(BRW_OPCODE_ADD, offset(dest, 2), src0, src1);
281 v->emit(SHADER_OPCODE_TEX, dest, src2)
283 v->emit(BRW_OPCODE_CMP, v->reg_null_f, offset(dest, 2), zero)
284 ->conditional_mod = BRW_CONDITIONAL_GE;
288 * 0: add(8) dest+2 src0 src1
289 * 1: tex(8) rlen 4 dest+0 src2
290 * 2: cmp.ge.f0(8) null dest+2 0.0f
297 bblock_t *block0 = v->cfg->blocks[0];
299 EXPECT_EQ(0, block0->start_ip);
300 EXPECT_EQ(2, block0->end_ip);
302 EXPECT_FALSE(cmod_propagation(v));
303 EXPECT_EQ(0, block0->start_ip);
304 EXPECT_EQ(2, block0->end_ip);
305 EXPECT_EQ(BRW_OPCODE_ADD, instruction(block0, 0)->opcode);
306 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
307 EXPECT_EQ(SHADER_OPCODE_TEX, instruction(block0, 1)->opcode);
308 EXPECT_EQ(BRW_CONDITIONAL_NONE, instruction(block0, 0)->conditional_mod);
309 EXPECT_EQ(BRW_OPCODE_CMP, instruction(block0, 2)->opcode);
310 EXPECT_EQ(BRW_CONDITIONAL_GE, instruction(block0, 2)->conditional_mod);