OSDN Git Service

3aa05987e4c8715d83f4e98971b77423cb5db3ab
[android-x86/external-mesa.git] / src / mesa / drivers / dri / i965 / test_fs_cmod_propagation.cpp
1 /*
2  * Copyright © 2015 Intel Corporation
3  *
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:
10  *
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
13  * Software.
14  *
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
21  * IN THE SOFTWARE.
22  */
23
24 #include <gtest/gtest.h>
25 #include "brw_fs.h"
26 #include "brw_cfg.h"
27 #include "program/program.h"
28
29 class cmod_propagation_test : public ::testing::Test {
30    virtual void SetUp();
31
32 public:
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;
38    fs_visitor *v;
39 };
40
41 class cmod_propagation_fs_visitor : public fs_visitor
42 {
43 public:
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) {}
48 };
49
50
51 void cmod_propagation_test::SetUp()
52 {
53    brw = (struct brw_context *)calloc(1, sizeof(*brw));
54    ctx = &brw->ctx;
55
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);
59
60    v = new cmod_propagation_fs_visitor(brw, prog_data, shader_prog);
61
62    _mesa_init_fragment_program(ctx, &fp->program, GL_FRAGMENT_SHADER, 0);
63
64    brw->gen = 4;
65 }
66
67 static fs_inst *
68 instruction(bblock_t *block, int num)
69 {
70    fs_inst *inst = (fs_inst *)block->start();
71    for (int i = 0; i < num; i++) {
72       inst = (fs_inst *)inst->next;
73    }
74    return inst;
75 }
76
77 static bool
78 cmod_propagation(fs_visitor *v)
79 {
80    const bool print = false;
81
82    if (print) {
83       fprintf(stderr, "= Before =\n");
84       v->cfg->dump(v);
85    }
86
87    bool ret = v->opt_cmod_propagation();
88
89    if (print) {
90       fprintf(stderr, "\n= After =\n");
91       v->cfg->dump(v);
92    }
93
94    return ret;
95 }
96
97 TEST_F(cmod_propagation_test, basic)
98 {
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);
102    fs_reg zero(0.0f);
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;
106
107    /* = Before =
108     *
109     * 0: add(8)        dest  src0  src1
110     * 1: cmp.ge.f0(8)  null  dest  0.0f
111     *
112     * = After =
113     * 0: add.ge.f0(8)  dest  src0  src1
114     */
115
116    v->calculate_cfg();
117    bblock_t *block0 = v->cfg->blocks[0];
118
119    EXPECT_EQ(0, block0->start_ip);
120    EXPECT_EQ(1, block0->end_ip);
121
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);
127 }
128
129 TEST_F(cmod_propagation_test, cmp_nonzero)
130 {
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;
138
139    /* = Before =
140     *
141     * 0: add(8)        dest  src0  src1
142     * 1: cmp.ge.f0(8)  null  dest  1.0f
143     *
144     * = After =
145     * (no changes)
146     */
147
148    v->calculate_cfg();
149    bblock_t *block0 = v->cfg->blocks[0];
150
151    EXPECT_EQ(0, block0->start_ip);
152    EXPECT_EQ(1, block0->end_ip);
153
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);
160 }
161
162 TEST_F(cmod_propagation_test, non_cmod_instruction)
163 {
164    fs_reg dest = v->vgrf(glsl_type::uint_type);
165    fs_reg src0 = v->vgrf(glsl_type::uint_type);
166    fs_reg zero(0u);
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;
170
171    /* = Before =
172     *
173     * 0: fbl(8)        dest  src0
174     * 1: cmp.ge.f0(8)  null  dest  0u
175     *
176     * = After =
177     * (no changes)
178     */
179
180    v->calculate_cfg();
181    bblock_t *block0 = v->cfg->blocks[0];
182
183    EXPECT_EQ(0, block0->start_ip);
184    EXPECT_EQ(1, block0->end_ip);
185
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);
192 }
193
194 TEST_F(cmod_propagation_test, intervening_flag_write)
195 {
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);
200    fs_reg zero(0.0f);
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;
206
207    /* = Before =
208     *
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
212     *
213     * = After =
214     * (no changes)
215     */
216
217    v->calculate_cfg();
218    bblock_t *block0 = v->cfg->blocks[0];
219
220    EXPECT_EQ(0, block0->start_ip);
221    EXPECT_EQ(2, block0->end_ip);
222
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);
231 }
232
233 TEST_F(cmod_propagation_test, intervening_flag_read)
234 {
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);
240    fs_reg zero(0.0f);
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;
246
247    /* = Before =
248     *
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
252     *
253     * = After =
254     * (no changes)
255     */
256
257    v->calculate_cfg();
258    bblock_t *block0 = v->cfg->blocks[0];
259
260    EXPECT_EQ(0, block0->start_ip);
261    EXPECT_EQ(2, block0->end_ip);
262
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);
271 }
272
273 TEST_F(cmod_propagation_test, intervening_dest_write)
274 {
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);
279    fs_reg zero(0.0f);
280    v->emit(BRW_OPCODE_ADD, offset(dest, 2), src0, src1);
281    v->emit(SHADER_OPCODE_TEX, dest, src2)
282       ->regs_written = 4;
283    v->emit(BRW_OPCODE_CMP, v->reg_null_f, offset(dest, 2), zero)
284       ->conditional_mod = BRW_CONDITIONAL_GE;
285
286    /* = Before =
287     *
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
291     *
292     * = After =
293     * (no changes)
294     */
295
296    v->calculate_cfg();
297    bblock_t *block0 = v->cfg->blocks[0];
298
299    EXPECT_EQ(0, block0->start_ip);
300    EXPECT_EQ(2, block0->end_ip);
301
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);
311 }