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"
31 class saturate_propagation_test
: public ::testing::Test
{
35 struct brw_compiler
*compiler
;
36 struct gen_device_info
*devinfo
;
37 struct gl_context
*ctx
;
38 struct brw_wm_prog_data
*prog_data
;
39 struct gl_shader_program
*shader_prog
;
43 class saturate_propagation_fs_visitor
: public fs_visitor
46 saturate_propagation_fs_visitor(struct brw_compiler
*compiler
,
47 struct brw_wm_prog_data
*prog_data
,
49 : fs_visitor(compiler
, NULL
, NULL
, NULL
,
50 &prog_data
->base
, shader
, 16, -1) {}
54 void saturate_propagation_test::SetUp()
56 ctx
= (struct gl_context
*)calloc(1, sizeof(*ctx
));
57 compiler
= (struct brw_compiler
*)calloc(1, sizeof(*compiler
));
58 devinfo
= (struct gen_device_info
*)calloc(1, sizeof(*devinfo
));
59 compiler
->devinfo
= devinfo
;
61 prog_data
= ralloc(NULL
, struct brw_wm_prog_data
);
63 nir_shader_create(NULL
, MESA_SHADER_FRAGMENT
, NULL
, NULL
);
65 v
= new saturate_propagation_fs_visitor(compiler
, prog_data
, shader
);
71 instruction(bblock_t
*block
, int num
)
73 fs_inst
*inst
= (fs_inst
*)block
->start();
74 for (int i
= 0; i
< num
; i
++) {
75 inst
= (fs_inst
*)inst
->next
;
81 saturate_propagation(fs_visitor
*v
)
83 const bool print
= false;
86 fprintf(stderr
, "= Before =\n");
90 bool ret
= v
->opt_saturate_propagation();
93 fprintf(stderr
, "\n= After =\n");
100 TEST_F(saturate_propagation_test
, basic
)
102 const fs_builder
&bld
= v
->bld
;
103 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
104 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
105 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
106 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
107 bld
.ADD(dst0
, src0
, src1
);
108 set_saturate(true, bld
.MOV(dst1
, dst0
));
112 * 0: add(16) dst0 src0 src1
113 * 1: mov.sat(16) dst1 dst0
116 * 0: add.sat(16) dst0 src0 src1
117 * 1: mov(16) dst1 dst0
121 bblock_t
*block0
= v
->cfg
->blocks
[0];
123 EXPECT_EQ(0, block0
->start_ip
);
124 EXPECT_EQ(1, block0
->end_ip
);
126 EXPECT_TRUE(saturate_propagation(v
));
127 EXPECT_EQ(0, block0
->start_ip
);
128 EXPECT_EQ(1, block0
->end_ip
);
129 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
130 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
131 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
132 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
135 TEST_F(saturate_propagation_test
, other_non_saturated_use
)
137 const fs_builder
&bld
= v
->bld
;
138 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
139 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
140 fs_reg dst2
= v
->vgrf(glsl_type::float_type
);
141 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
142 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
143 bld
.ADD(dst0
, src0
, src1
);
144 set_saturate(true, bld
.MOV(dst1
, dst0
));
145 bld
.ADD(dst2
, dst0
, src0
);
149 * 0: add(16) dst0 src0 src1
150 * 1: mov.sat(16) dst1 dst0
151 * 2: add(16) dst2 dst0 src0
158 bblock_t
*block0
= v
->cfg
->blocks
[0];
160 EXPECT_EQ(0, block0
->start_ip
);
161 EXPECT_EQ(2, block0
->end_ip
);
163 EXPECT_FALSE(saturate_propagation(v
));
164 EXPECT_EQ(0, block0
->start_ip
);
165 EXPECT_EQ(2, block0
->end_ip
);
166 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
167 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
168 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
169 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
170 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 2)->opcode
);
173 TEST_F(saturate_propagation_test
, predicated_instruction
)
175 const fs_builder
&bld
= v
->bld
;
176 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
177 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
178 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
179 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
180 bld
.ADD(dst0
, src0
, src1
)
181 ->predicate
= BRW_PREDICATE_NORMAL
;
182 set_saturate(true, bld
.MOV(dst1
, dst0
));
186 * 0: (+f0) add(16) dst0 src0 src1
187 * 1: mov.sat(16) dst1 dst0
194 bblock_t
*block0
= v
->cfg
->blocks
[0];
196 EXPECT_EQ(0, block0
->start_ip
);
197 EXPECT_EQ(1, block0
->end_ip
);
199 EXPECT_FALSE(saturate_propagation(v
));
200 EXPECT_EQ(0, block0
->start_ip
);
201 EXPECT_EQ(1, block0
->end_ip
);
202 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
203 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
204 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
205 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
208 TEST_F(saturate_propagation_test
, neg_mov_sat
)
210 const fs_builder
&bld
= v
->bld
;
211 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
212 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
213 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
214 bld
.RNDU(dst0
, src0
);
216 set_saturate(true, bld
.MOV(dst1
, dst0
));
220 * 0: rndu(16) dst0 src0
221 * 1: mov.sat(16) dst1 -dst0
228 bblock_t
*block0
= v
->cfg
->blocks
[0];
230 EXPECT_EQ(0, block0
->start_ip
);
231 EXPECT_EQ(1, block0
->end_ip
);
233 EXPECT_FALSE(saturate_propagation(v
));
234 EXPECT_EQ(0, block0
->start_ip
);
235 EXPECT_EQ(1, block0
->end_ip
);
236 EXPECT_EQ(BRW_OPCODE_RNDU
, instruction(block0
, 0)->opcode
);
237 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
238 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
239 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
242 TEST_F(saturate_propagation_test
, add_neg_mov_sat
)
244 const fs_builder
&bld
= v
->bld
;
245 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
246 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
247 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
248 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
249 bld
.ADD(dst0
, src0
, src1
);
251 set_saturate(true, bld
.MOV(dst1
, dst0
));
255 * 0: add(16) dst0 src0 src1
256 * 1: mov.sat(16) dst1 -dst0
259 * 0: add.sat(16) dst0 -src0 -src1
260 * 1: mov(16) dst1 dst0
264 bblock_t
*block0
= v
->cfg
->blocks
[0];
266 EXPECT_EQ(0, block0
->start_ip
);
267 EXPECT_EQ(1, block0
->end_ip
);
269 EXPECT_TRUE(saturate_propagation(v
));
270 EXPECT_EQ(0, block0
->start_ip
);
271 EXPECT_EQ(1, block0
->end_ip
);
272 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
273 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
274 EXPECT_TRUE(instruction(block0
, 0)->src
[0].negate
);
275 EXPECT_TRUE(instruction(block0
, 0)->src
[1].negate
);
276 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
277 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
280 TEST_F(saturate_propagation_test
, add_imm_float_neg_mov_sat
)
282 const fs_builder
&bld
= v
->bld
;
283 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
284 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
285 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
286 fs_reg src1
= brw_imm_f(1.0f
);
287 bld
.ADD(dst0
, src0
, src1
);
289 set_saturate(true, bld
.MOV(dst1
, dst0
));
293 * 0: add(16) dst0 src0 1.0f
294 * 1: mov.sat(16) dst1 -dst0
297 * 0: add.sat(16) dst0 -src0 -1.0f
298 * 1: mov(16) dst1 dst0
302 bblock_t
*block0
= v
->cfg
->blocks
[0];
304 EXPECT_EQ(0, block0
->start_ip
);
305 EXPECT_EQ(1, block0
->end_ip
);
307 EXPECT_TRUE(saturate_propagation(v
));
308 EXPECT_EQ(0, block0
->start_ip
);
309 EXPECT_EQ(1, block0
->end_ip
);
310 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
311 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
312 EXPECT_TRUE(instruction(block0
, 0)->src
[0].negate
);
313 EXPECT_EQ(instruction(block0
, 0)->src
[1].f
, -1.0f
);
314 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
315 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
318 TEST_F(saturate_propagation_test
, mul_neg_mov_sat
)
320 const fs_builder
&bld
= v
->bld
;
321 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
322 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
323 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
324 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
325 bld
.MUL(dst0
, src0
, src1
);
327 set_saturate(true, bld
.MOV(dst1
, dst0
));
331 * 0: mul(16) dst0 src0 src1
332 * 1: mov.sat(16) dst1 -dst0
335 * 0: mul.sat(16) dst0 src0 -src1
336 * 1: mov(16) dst1 dst0
340 bblock_t
*block0
= v
->cfg
->blocks
[0];
342 EXPECT_EQ(0, block0
->start_ip
);
343 EXPECT_EQ(1, block0
->end_ip
);
345 EXPECT_TRUE(saturate_propagation(v
));
346 EXPECT_EQ(0, block0
->start_ip
);
347 EXPECT_EQ(1, block0
->end_ip
);
348 EXPECT_EQ(BRW_OPCODE_MUL
, instruction(block0
, 0)->opcode
);
349 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
350 EXPECT_TRUE(instruction(block0
, 0)->src
[0].negate
);
351 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
352 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
353 EXPECT_FALSE(instruction(block0
, 1)->src
[0].negate
);
356 TEST_F(saturate_propagation_test
, mad_neg_mov_sat
)
358 const fs_builder
&bld
= v
->bld
;
359 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
360 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
361 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
362 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
363 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
364 bld
.MAD(dst0
, src0
, src1
, src2
);
366 set_saturate(true, bld
.MOV(dst1
, dst0
));
370 * 0: mad(16) dst0 src0 src1 src2
371 * 1: mov.sat(16) dst1 -dst0
374 * 0: mad.sat(16) dst0 -src0 -src1 src2
375 * 1: mov(16) dst1 dst0
379 bblock_t
*block0
= v
->cfg
->blocks
[0];
381 EXPECT_EQ(0, block0
->start_ip
);
382 EXPECT_EQ(1, block0
->end_ip
);
384 EXPECT_TRUE(saturate_propagation(v
));
385 EXPECT_EQ(0, block0
->start_ip
);
386 EXPECT_EQ(1, block0
->end_ip
);
387 EXPECT_EQ(BRW_OPCODE_MAD
, instruction(block0
, 0)->opcode
);
388 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
389 EXPECT_TRUE(instruction(block0
, 0)->src
[0].negate
);
390 EXPECT_TRUE(instruction(block0
, 0)->src
[1].negate
);
391 EXPECT_FALSE(instruction(block0
, 0)->src
[2].negate
);
392 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
393 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
394 EXPECT_FALSE(instruction(block0
, 1)->src
[0].negate
);
397 TEST_F(saturate_propagation_test
, mad_imm_float_neg_mov_sat
)
399 const fs_builder
&bld
= v
->bld
;
400 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
401 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
402 fs_reg src0
= brw_imm_f(1.0f
);
403 fs_reg src1
= brw_imm_f(-2.0f
);
404 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
405 /* The builder for MAD tries to be helpful and not put immediates as direct
406 * sources. We want to test specifically that case.
408 fs_inst
*mad
= bld
.MAD(dst0
, src2
, src2
, src2
);
412 set_saturate(true, bld
.MOV(dst1
, dst0
));
416 * 0: mad(16) dst0 1.0f -2.0f src2
417 * 1: mov.sat(16) dst1 -dst0
420 * 0: mad.sat(16) dst0 -1.0f 2.0f src2
421 * 1: mov(16) dst1 dst0
425 bblock_t
*block0
= v
->cfg
->blocks
[0];
427 EXPECT_EQ(0, block0
->start_ip
);
428 EXPECT_EQ(1, block0
->end_ip
);
430 EXPECT_TRUE(saturate_propagation(v
));
431 EXPECT_EQ(0, block0
->start_ip
);
432 EXPECT_EQ(1, block0
->end_ip
);
433 EXPECT_EQ(BRW_OPCODE_MAD
, instruction(block0
, 0)->opcode
);
434 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
435 EXPECT_EQ(instruction(block0
, 0)->src
[0].f
, -1.0f
);
436 EXPECT_EQ(instruction(block0
, 0)->src
[1].f
, 2.0f
);
437 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
438 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
439 EXPECT_FALSE(instruction(block0
, 1)->src
[0].negate
);
442 TEST_F(saturate_propagation_test
, mul_mov_sat_neg_mov_sat
)
444 const fs_builder
&bld
= v
->bld
;
445 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
446 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
447 fs_reg dst2
= v
->vgrf(glsl_type::float_type
);
448 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
449 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
450 bld
.MUL(dst0
, src0
, src1
);
451 set_saturate(true, bld
.MOV(dst1
, dst0
));
453 set_saturate(true, bld
.MOV(dst2
, dst0
));
457 * 0: mul(16) dst0 src0 src1
458 * 1: mov.sat(16) dst1 dst0
459 * 2: mov.sat(16) dst2 -dst0
466 bblock_t
*block0
= v
->cfg
->blocks
[0];
468 EXPECT_EQ(0, block0
->start_ip
);
469 EXPECT_EQ(2, block0
->end_ip
);
471 EXPECT_FALSE(saturate_propagation(v
));
472 EXPECT_EQ(0, block0
->start_ip
);
473 EXPECT_EQ(2, block0
->end_ip
);
474 EXPECT_EQ(BRW_OPCODE_MUL
, instruction(block0
, 0)->opcode
);
475 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
476 EXPECT_FALSE(instruction(block0
, 0)->src
[1].negate
);
477 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
478 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
479 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 2)->opcode
);
480 EXPECT_TRUE(instruction(block0
, 2)->src
[0].negate
);
481 EXPECT_TRUE(instruction(block0
, 2)->saturate
);
484 TEST_F(saturate_propagation_test
, mul_neg_mov_sat_neg_mov_sat
)
486 const fs_builder
&bld
= v
->bld
;
487 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
488 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
489 fs_reg dst2
= v
->vgrf(glsl_type::float_type
);
490 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
491 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
492 bld
.MUL(dst0
, src0
, src1
);
494 set_saturate(true, bld
.MOV(dst1
, dst0
));
495 set_saturate(true, bld
.MOV(dst2
, dst0
));
499 * 0: mul(16) dst0 src0 src1
500 * 1: mov.sat(16) dst1 -dst0
501 * 2: mov.sat(16) dst2 -dst0
508 bblock_t
*block0
= v
->cfg
->blocks
[0];
510 EXPECT_EQ(0, block0
->start_ip
);
511 EXPECT_EQ(2, block0
->end_ip
);
513 EXPECT_FALSE(saturate_propagation(v
));
514 EXPECT_EQ(0, block0
->start_ip
);
515 EXPECT_EQ(2, block0
->end_ip
);
516 EXPECT_EQ(BRW_OPCODE_MUL
, instruction(block0
, 0)->opcode
);
517 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
518 EXPECT_FALSE(instruction(block0
, 0)->src
[1].negate
);
519 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
520 EXPECT_TRUE(instruction(block0
, 1)->src
[0].negate
);
521 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
522 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 2)->opcode
);
523 EXPECT_TRUE(instruction(block0
, 2)->src
[0].negate
);
524 EXPECT_TRUE(instruction(block0
, 2)->saturate
);
527 TEST_F(saturate_propagation_test
, abs_mov_sat
)
529 const fs_builder
&bld
= v
->bld
;
530 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
531 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
532 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
533 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
534 bld
.ADD(dst0
, src0
, src1
);
536 set_saturate(true, bld
.MOV(dst1
, dst0
));
540 * 0: add(16) dst0 src0 src1
541 * 1: mov.sat(16) dst1 (abs)dst0
548 bblock_t
*block0
= v
->cfg
->blocks
[0];
550 EXPECT_EQ(0, block0
->start_ip
);
551 EXPECT_EQ(1, block0
->end_ip
);
553 EXPECT_FALSE(saturate_propagation(v
));
554 EXPECT_EQ(0, block0
->start_ip
);
555 EXPECT_EQ(1, block0
->end_ip
);
556 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
557 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
558 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
559 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
562 TEST_F(saturate_propagation_test
, producer_saturates
)
564 const fs_builder
&bld
= v
->bld
;
565 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
566 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
567 fs_reg dst2
= v
->vgrf(glsl_type::float_type
);
568 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
569 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
570 set_saturate(true, bld
.ADD(dst0
, src0
, src1
));
571 set_saturate(true, bld
.MOV(dst1
, dst0
));
576 * 0: add.sat(16) dst0 src0 src1
577 * 1: mov.sat(16) dst1 dst0
578 * 2: mov(16) dst2 dst0
581 * 0: add.sat(16) dst0 src0 src1
582 * 1: mov(16) dst1 dst0
583 * 2: mov(16) dst2 dst0
587 bblock_t
*block0
= v
->cfg
->blocks
[0];
589 EXPECT_EQ(0, block0
->start_ip
);
590 EXPECT_EQ(2, block0
->end_ip
);
592 EXPECT_TRUE(saturate_propagation(v
));
593 EXPECT_EQ(0, block0
->start_ip
);
594 EXPECT_EQ(2, block0
->end_ip
);
595 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
596 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
597 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
598 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
601 TEST_F(saturate_propagation_test
, intervening_saturating_copy
)
603 const fs_builder
&bld
= v
->bld
;
604 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
605 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
606 fs_reg dst2
= v
->vgrf(glsl_type::float_type
);
607 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
608 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
609 bld
.ADD(dst0
, src0
, src1
);
610 set_saturate(true, bld
.MOV(dst1
, dst0
));
611 set_saturate(true, bld
.MOV(dst2
, dst0
));
615 * 0: add(16) dst0 src0 src1
616 * 1: mov.sat(16) dst1 dst0
617 * 2: mov.sat(16) dst2 dst0
620 * 0: add.sat(16) dst0 src0 src1
621 * 1: mov(16) dst1 dst0
622 * 2: mov(16) dst2 dst0
626 bblock_t
*block0
= v
->cfg
->blocks
[0];
628 EXPECT_EQ(0, block0
->start_ip
);
629 EXPECT_EQ(2, block0
->end_ip
);
631 EXPECT_TRUE(saturate_propagation(v
));
632 EXPECT_EQ(0, block0
->start_ip
);
633 EXPECT_EQ(2, block0
->end_ip
);
634 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
635 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
636 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
637 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
638 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 2)->opcode
);
639 EXPECT_FALSE(instruction(block0
, 2)->saturate
);
642 TEST_F(saturate_propagation_test
, intervening_dest_write
)
644 const fs_builder
&bld
= v
->bld
;
645 fs_reg dst0
= v
->vgrf(glsl_type::vec4_type
);
646 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
647 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
648 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
649 fs_reg src2
= v
->vgrf(glsl_type::vec2_type
);
650 bld
.ADD(offset(dst0
, bld
, 2), src0
, src1
);
651 bld
.emit(SHADER_OPCODE_TEX
, dst0
, src2
)
652 ->size_written
= 8 * REG_SIZE
;
653 set_saturate(true, bld
.MOV(dst1
, offset(dst0
, bld
, 2)));
657 * 0: add(16) dst0+2 src0 src1
658 * 1: tex(16) rlen 4 dst0+0 src2
659 * 2: mov.sat(16) dst1 dst0+2
666 bblock_t
*block0
= v
->cfg
->blocks
[0];
668 EXPECT_EQ(0, block0
->start_ip
);
669 EXPECT_EQ(2, block0
->end_ip
);
671 EXPECT_FALSE(saturate_propagation(v
));
672 EXPECT_EQ(0, block0
->start_ip
);
673 EXPECT_EQ(2, block0
->end_ip
);
674 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
675 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
676 EXPECT_EQ(SHADER_OPCODE_TEX
, instruction(block0
, 1)->opcode
);
677 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
678 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 2)->opcode
);
679 EXPECT_TRUE(instruction(block0
, 2)->saturate
);
682 TEST_F(saturate_propagation_test
, mul_neg_mov_sat_mov_sat
)
684 const fs_builder
&bld
= v
->bld
;
685 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
686 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
687 fs_reg dst2
= v
->vgrf(glsl_type::float_type
);
688 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
689 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
690 bld
.MUL(dst0
, src0
, src1
);
692 set_saturate(true, bld
.MOV(dst1
, dst0
));
694 set_saturate(true, bld
.MOV(dst2
, dst0
));
698 * 0: mul(16) dst0 src0 src1
699 * 1: mov.sat(16) dst1 -dst0
700 * 2: mov.sat(16) dst2 dst0
707 bblock_t
*block0
= v
->cfg
->blocks
[0];
709 EXPECT_EQ(0, block0
->start_ip
);
710 EXPECT_EQ(2, block0
->end_ip
);
712 EXPECT_FALSE(saturate_propagation(v
));
713 EXPECT_EQ(0, block0
->start_ip
);
714 EXPECT_EQ(2, block0
->end_ip
);
715 EXPECT_EQ(BRW_OPCODE_MUL
, instruction(block0
, 0)->opcode
);
716 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
717 EXPECT_FALSE(instruction(block0
, 0)->src
[1].negate
);
718 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
719 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
720 EXPECT_TRUE(instruction(block0
, 1)->src
[0].negate
);
721 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 2)->opcode
);
722 EXPECT_TRUE(instruction(block0
, 2)->saturate
);
725 TEST_F(saturate_propagation_test
, smaller_exec_size_consumer
)
727 const fs_builder
&bld
= v
->bld
;
728 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
729 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
730 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
731 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
732 bld
.ADD(dst0
, src0
, src1
);
733 set_saturate(true, bld
.group(8, 0).MOV(dst1
, dst0
));
737 * 0: add(16) dst0 src0 src1
738 * 1: mov.sat(8) dst1 dst0
745 bblock_t
*block0
= v
->cfg
->blocks
[0];
747 EXPECT_EQ(0, block0
->start_ip
);
748 EXPECT_EQ(1, block0
->end_ip
);
750 EXPECT_FALSE(saturate_propagation(v
));
751 EXPECT_EQ(0, block0
->start_ip
);
752 EXPECT_EQ(1, block0
->end_ip
);
753 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
754 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
755 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
756 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
759 TEST_F(saturate_propagation_test
, larger_exec_size_consumer
)
761 const fs_builder
&bld
= v
->bld
;
762 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
763 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
764 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
765 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
766 bld
.group(8, 0).ADD(dst0
, src0
, src1
);
767 set_saturate(true, bld
.MOV(dst1
, dst0
));
771 * 0: add(8) dst0 src0 src1
772 * 1: mov.sat(16) dst1 dst0
779 bblock_t
*block0
= v
->cfg
->blocks
[0];
781 EXPECT_EQ(0, block0
->start_ip
);
782 EXPECT_EQ(1, block0
->end_ip
);
784 EXPECT_FALSE(saturate_propagation(v
));
785 EXPECT_EQ(0, block0
->start_ip
);
786 EXPECT_EQ(1, block0
->end_ip
);
787 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
788 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
789 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
790 EXPECT_TRUE(instruction(block0
, 1)->saturate
);