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
, (struct gl_program
*) NULL
,
55 void saturate_propagation_test::SetUp()
57 ctx
= (struct gl_context
*)calloc(1, sizeof(*ctx
));
58 compiler
= (struct brw_compiler
*)calloc(1, sizeof(*compiler
));
59 devinfo
= (struct gen_device_info
*)calloc(1, sizeof(*devinfo
));
60 compiler
->devinfo
= devinfo
;
62 prog_data
= ralloc(NULL
, struct brw_wm_prog_data
);
64 nir_shader_create(NULL
, MESA_SHADER_FRAGMENT
, NULL
, NULL
);
66 v
= new saturate_propagation_fs_visitor(compiler
, prog_data
, shader
);
72 instruction(bblock_t
*block
, int num
)
74 fs_inst
*inst
= (fs_inst
*)block
->start();
75 for (int i
= 0; i
< num
; i
++) {
76 inst
= (fs_inst
*)inst
->next
;
82 saturate_propagation(fs_visitor
*v
)
84 const bool print
= false;
87 fprintf(stderr
, "= Before =\n");
91 bool ret
= v
->opt_saturate_propagation();
94 fprintf(stderr
, "\n= After =\n");
101 TEST_F(saturate_propagation_test
, basic
)
103 const fs_builder
&bld
= v
->bld
;
104 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
105 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
106 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
107 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
108 bld
.ADD(dst0
, src0
, src1
);
109 set_saturate(true, bld
.MOV(dst1
, dst0
));
113 * 0: add(16) dst0 src0 src1
114 * 1: mov.sat(16) dst1 dst0
117 * 0: add.sat(16) dst0 src0 src1
118 * 1: mov(16) dst1 dst0
122 bblock_t
*block0
= v
->cfg
->blocks
[0];
124 EXPECT_EQ(0, block0
->start_ip
);
125 EXPECT_EQ(1, block0
->end_ip
);
127 EXPECT_TRUE(saturate_propagation(v
));
128 EXPECT_EQ(0, block0
->start_ip
);
129 EXPECT_EQ(1, block0
->end_ip
);
130 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
131 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
132 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
133 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
136 TEST_F(saturate_propagation_test
, other_non_saturated_use
)
138 const fs_builder
&bld
= v
->bld
;
139 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
140 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
141 fs_reg dst2
= v
->vgrf(glsl_type::float_type
);
142 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
143 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
144 bld
.ADD(dst0
, src0
, src1
);
145 set_saturate(true, bld
.MOV(dst1
, dst0
));
146 bld
.ADD(dst2
, dst0
, src0
);
150 * 0: add(16) dst0 src0 src1
151 * 1: mov.sat(16) dst1 dst0
152 * 2: add(16) dst2 dst0 src0
159 bblock_t
*block0
= v
->cfg
->blocks
[0];
161 EXPECT_EQ(0, block0
->start_ip
);
162 EXPECT_EQ(2, block0
->end_ip
);
164 EXPECT_FALSE(saturate_propagation(v
));
165 EXPECT_EQ(0, block0
->start_ip
);
166 EXPECT_EQ(2, block0
->end_ip
);
167 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
168 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
169 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
170 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
171 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 2)->opcode
);
174 TEST_F(saturate_propagation_test
, predicated_instruction
)
176 const fs_builder
&bld
= v
->bld
;
177 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
178 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
179 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
180 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
181 bld
.ADD(dst0
, src0
, src1
)
182 ->predicate
= BRW_PREDICATE_NORMAL
;
183 set_saturate(true, bld
.MOV(dst1
, dst0
));
187 * 0: (+f0) add(16) dst0 src0 src1
188 * 1: mov.sat(16) dst1 dst0
195 bblock_t
*block0
= v
->cfg
->blocks
[0];
197 EXPECT_EQ(0, block0
->start_ip
);
198 EXPECT_EQ(1, block0
->end_ip
);
200 EXPECT_FALSE(saturate_propagation(v
));
201 EXPECT_EQ(0, block0
->start_ip
);
202 EXPECT_EQ(1, block0
->end_ip
);
203 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
204 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
205 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
206 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
209 TEST_F(saturate_propagation_test
, neg_mov_sat
)
211 const fs_builder
&bld
= v
->bld
;
212 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
213 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
214 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
215 bld
.RNDU(dst0
, src0
);
217 set_saturate(true, bld
.MOV(dst1
, dst0
));
221 * 0: rndu(16) dst0 src0
222 * 1: mov.sat(16) dst1 -dst0
229 bblock_t
*block0
= v
->cfg
->blocks
[0];
231 EXPECT_EQ(0, block0
->start_ip
);
232 EXPECT_EQ(1, block0
->end_ip
);
234 EXPECT_FALSE(saturate_propagation(v
));
235 EXPECT_EQ(0, block0
->start_ip
);
236 EXPECT_EQ(1, block0
->end_ip
);
237 EXPECT_EQ(BRW_OPCODE_RNDU
, instruction(block0
, 0)->opcode
);
238 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
239 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
240 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
243 TEST_F(saturate_propagation_test
, add_neg_mov_sat
)
245 const fs_builder
&bld
= v
->bld
;
246 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
247 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
248 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
249 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
250 bld
.ADD(dst0
, src0
, src1
);
252 set_saturate(true, bld
.MOV(dst1
, dst0
));
256 * 0: add(16) dst0 src0 src1
257 * 1: mov.sat(16) dst1 -dst0
260 * 0: add.sat(16) dst0 -src0 -src1
261 * 1: mov(16) dst1 dst0
265 bblock_t
*block0
= v
->cfg
->blocks
[0];
267 EXPECT_EQ(0, block0
->start_ip
);
268 EXPECT_EQ(1, block0
->end_ip
);
270 EXPECT_TRUE(saturate_propagation(v
));
271 EXPECT_EQ(0, block0
->start_ip
);
272 EXPECT_EQ(1, block0
->end_ip
);
273 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
274 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
275 EXPECT_TRUE(instruction(block0
, 0)->src
[0].negate
);
276 EXPECT_TRUE(instruction(block0
, 0)->src
[1].negate
);
277 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
278 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
281 TEST_F(saturate_propagation_test
, add_imm_float_neg_mov_sat
)
283 const fs_builder
&bld
= v
->bld
;
284 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
285 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
286 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
287 fs_reg src1
= brw_imm_f(1.0f
);
288 bld
.ADD(dst0
, src0
, src1
);
290 set_saturate(true, bld
.MOV(dst1
, dst0
));
294 * 0: add(16) dst0 src0 1.0f
295 * 1: mov.sat(16) dst1 -dst0
298 * 0: add.sat(16) dst0 -src0 -1.0f
299 * 1: mov(16) dst1 dst0
303 bblock_t
*block0
= v
->cfg
->blocks
[0];
305 EXPECT_EQ(0, block0
->start_ip
);
306 EXPECT_EQ(1, block0
->end_ip
);
308 EXPECT_TRUE(saturate_propagation(v
));
309 EXPECT_EQ(0, block0
->start_ip
);
310 EXPECT_EQ(1, block0
->end_ip
);
311 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
312 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
313 EXPECT_TRUE(instruction(block0
, 0)->src
[0].negate
);
314 EXPECT_EQ(instruction(block0
, 0)->src
[1].f
, -1.0f
);
315 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
316 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
319 TEST_F(saturate_propagation_test
, mul_neg_mov_sat
)
321 const fs_builder
&bld
= v
->bld
;
322 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
323 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
324 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
325 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
326 bld
.MUL(dst0
, src0
, src1
);
328 set_saturate(true, bld
.MOV(dst1
, dst0
));
332 * 0: mul(16) dst0 src0 src1
333 * 1: mov.sat(16) dst1 -dst0
336 * 0: mul.sat(16) dst0 src0 -src1
337 * 1: mov(16) dst1 dst0
341 bblock_t
*block0
= v
->cfg
->blocks
[0];
343 EXPECT_EQ(0, block0
->start_ip
);
344 EXPECT_EQ(1, block0
->end_ip
);
346 EXPECT_TRUE(saturate_propagation(v
));
347 EXPECT_EQ(0, block0
->start_ip
);
348 EXPECT_EQ(1, block0
->end_ip
);
349 EXPECT_EQ(BRW_OPCODE_MUL
, instruction(block0
, 0)->opcode
);
350 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
351 EXPECT_TRUE(instruction(block0
, 0)->src
[0].negate
);
352 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
353 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
354 EXPECT_FALSE(instruction(block0
, 1)->src
[0].negate
);
357 TEST_F(saturate_propagation_test
, mad_neg_mov_sat
)
359 const fs_builder
&bld
= v
->bld
;
360 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
361 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
362 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
363 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
364 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
365 bld
.MAD(dst0
, src0
, src1
, src2
);
367 set_saturate(true, bld
.MOV(dst1
, dst0
));
371 * 0: mad(16) dst0 src0 src1 src2
372 * 1: mov.sat(16) dst1 -dst0
375 * 0: mad.sat(16) dst0 -src0 -src1 src2
376 * 1: mov(16) dst1 dst0
380 bblock_t
*block0
= v
->cfg
->blocks
[0];
382 EXPECT_EQ(0, block0
->start_ip
);
383 EXPECT_EQ(1, block0
->end_ip
);
385 EXPECT_TRUE(saturate_propagation(v
));
386 EXPECT_EQ(0, block0
->start_ip
);
387 EXPECT_EQ(1, block0
->end_ip
);
388 EXPECT_EQ(BRW_OPCODE_MAD
, instruction(block0
, 0)->opcode
);
389 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
390 EXPECT_TRUE(instruction(block0
, 0)->src
[0].negate
);
391 EXPECT_TRUE(instruction(block0
, 0)->src
[1].negate
);
392 EXPECT_FALSE(instruction(block0
, 0)->src
[2].negate
);
393 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
394 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
395 EXPECT_FALSE(instruction(block0
, 1)->src
[0].negate
);
398 TEST_F(saturate_propagation_test
, mad_imm_float_neg_mov_sat
)
400 const fs_builder
&bld
= v
->bld
;
401 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
402 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
403 fs_reg src0
= brw_imm_f(1.0f
);
404 fs_reg src1
= brw_imm_f(-2.0f
);
405 fs_reg src2
= v
->vgrf(glsl_type::float_type
);
406 /* The builder for MAD tries to be helpful and not put immediates as direct
407 * sources. We want to test specifically that case.
409 fs_inst
*mad
= bld
.MAD(dst0
, src2
, src2
, src2
);
413 set_saturate(true, bld
.MOV(dst1
, dst0
));
417 * 0: mad(16) dst0 1.0f -2.0f src2
418 * 1: mov.sat(16) dst1 -dst0
421 * 0: mad.sat(16) dst0 -1.0f 2.0f src2
422 * 1: mov(16) dst1 dst0
426 bblock_t
*block0
= v
->cfg
->blocks
[0];
428 EXPECT_EQ(0, block0
->start_ip
);
429 EXPECT_EQ(1, block0
->end_ip
);
431 EXPECT_TRUE(saturate_propagation(v
));
432 EXPECT_EQ(0, block0
->start_ip
);
433 EXPECT_EQ(1, block0
->end_ip
);
434 EXPECT_EQ(BRW_OPCODE_MAD
, instruction(block0
, 0)->opcode
);
435 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
436 EXPECT_EQ(instruction(block0
, 0)->src
[0].f
, -1.0f
);
437 EXPECT_EQ(instruction(block0
, 0)->src
[1].f
, 2.0f
);
438 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
439 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
440 EXPECT_FALSE(instruction(block0
, 1)->src
[0].negate
);
443 TEST_F(saturate_propagation_test
, mul_mov_sat_neg_mov_sat
)
445 const fs_builder
&bld
= v
->bld
;
446 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
447 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
448 fs_reg dst2
= v
->vgrf(glsl_type::float_type
);
449 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
450 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
451 bld
.MUL(dst0
, src0
, src1
);
452 set_saturate(true, bld
.MOV(dst1
, dst0
));
454 set_saturate(true, bld
.MOV(dst2
, dst0
));
458 * 0: mul(16) dst0 src0 src1
459 * 1: mov.sat(16) dst1 dst0
460 * 2: mov.sat(16) dst2 -dst0
467 bblock_t
*block0
= v
->cfg
->blocks
[0];
469 EXPECT_EQ(0, block0
->start_ip
);
470 EXPECT_EQ(2, block0
->end_ip
);
472 EXPECT_FALSE(saturate_propagation(v
));
473 EXPECT_EQ(0, block0
->start_ip
);
474 EXPECT_EQ(2, block0
->end_ip
);
475 EXPECT_EQ(BRW_OPCODE_MUL
, instruction(block0
, 0)->opcode
);
476 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
477 EXPECT_FALSE(instruction(block0
, 0)->src
[1].negate
);
478 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
479 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
480 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 2)->opcode
);
481 EXPECT_TRUE(instruction(block0
, 2)->src
[0].negate
);
482 EXPECT_TRUE(instruction(block0
, 2)->saturate
);
485 TEST_F(saturate_propagation_test
, mul_neg_mov_sat_neg_mov_sat
)
487 const fs_builder
&bld
= v
->bld
;
488 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
489 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
490 fs_reg dst2
= v
->vgrf(glsl_type::float_type
);
491 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
492 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
493 bld
.MUL(dst0
, src0
, src1
);
495 set_saturate(true, bld
.MOV(dst1
, dst0
));
496 set_saturate(true, bld
.MOV(dst2
, dst0
));
500 * 0: mul(16) dst0 src0 src1
501 * 1: mov.sat(16) dst1 -dst0
502 * 2: mov.sat(16) dst2 -dst0
509 bblock_t
*block0
= v
->cfg
->blocks
[0];
511 EXPECT_EQ(0, block0
->start_ip
);
512 EXPECT_EQ(2, block0
->end_ip
);
514 EXPECT_FALSE(saturate_propagation(v
));
515 EXPECT_EQ(0, block0
->start_ip
);
516 EXPECT_EQ(2, block0
->end_ip
);
517 EXPECT_EQ(BRW_OPCODE_MUL
, instruction(block0
, 0)->opcode
);
518 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
519 EXPECT_FALSE(instruction(block0
, 0)->src
[1].negate
);
520 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
521 EXPECT_TRUE(instruction(block0
, 1)->src
[0].negate
);
522 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
523 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 2)->opcode
);
524 EXPECT_TRUE(instruction(block0
, 2)->src
[0].negate
);
525 EXPECT_TRUE(instruction(block0
, 2)->saturate
);
528 TEST_F(saturate_propagation_test
, abs_mov_sat
)
530 const fs_builder
&bld
= v
->bld
;
531 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
532 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
533 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
534 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
535 bld
.ADD(dst0
, src0
, src1
);
537 set_saturate(true, bld
.MOV(dst1
, dst0
));
541 * 0: add(16) dst0 src0 src1
542 * 1: mov.sat(16) dst1 (abs)dst0
549 bblock_t
*block0
= v
->cfg
->blocks
[0];
551 EXPECT_EQ(0, block0
->start_ip
);
552 EXPECT_EQ(1, block0
->end_ip
);
554 EXPECT_FALSE(saturate_propagation(v
));
555 EXPECT_EQ(0, block0
->start_ip
);
556 EXPECT_EQ(1, block0
->end_ip
);
557 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
558 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
559 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
560 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
563 TEST_F(saturate_propagation_test
, producer_saturates
)
565 const fs_builder
&bld
= v
->bld
;
566 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
567 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
568 fs_reg dst2
= v
->vgrf(glsl_type::float_type
);
569 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
570 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
571 set_saturate(true, bld
.ADD(dst0
, src0
, src1
));
572 set_saturate(true, bld
.MOV(dst1
, dst0
));
577 * 0: add.sat(16) dst0 src0 src1
578 * 1: mov.sat(16) dst1 dst0
579 * 2: mov(16) dst2 dst0
582 * 0: add.sat(16) dst0 src0 src1
583 * 1: mov(16) dst1 dst0
584 * 2: mov(16) dst2 dst0
588 bblock_t
*block0
= v
->cfg
->blocks
[0];
590 EXPECT_EQ(0, block0
->start_ip
);
591 EXPECT_EQ(2, block0
->end_ip
);
593 EXPECT_TRUE(saturate_propagation(v
));
594 EXPECT_EQ(0, block0
->start_ip
);
595 EXPECT_EQ(2, block0
->end_ip
);
596 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
597 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
598 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
599 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
602 TEST_F(saturate_propagation_test
, intervening_saturating_copy
)
604 const fs_builder
&bld
= v
->bld
;
605 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
606 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
607 fs_reg dst2
= v
->vgrf(glsl_type::float_type
);
608 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
609 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
610 bld
.ADD(dst0
, src0
, src1
);
611 set_saturate(true, bld
.MOV(dst1
, dst0
));
612 set_saturate(true, bld
.MOV(dst2
, dst0
));
616 * 0: add(16) dst0 src0 src1
617 * 1: mov.sat(16) dst1 dst0
618 * 2: mov.sat(16) dst2 dst0
621 * 0: add.sat(16) dst0 src0 src1
622 * 1: mov(16) dst1 dst0
623 * 2: mov(16) dst2 dst0
627 bblock_t
*block0
= v
->cfg
->blocks
[0];
629 EXPECT_EQ(0, block0
->start_ip
);
630 EXPECT_EQ(2, block0
->end_ip
);
632 EXPECT_TRUE(saturate_propagation(v
));
633 EXPECT_EQ(0, block0
->start_ip
);
634 EXPECT_EQ(2, block0
->end_ip
);
635 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
636 EXPECT_TRUE(instruction(block0
, 0)->saturate
);
637 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
638 EXPECT_FALSE(instruction(block0
, 1)->saturate
);
639 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 2)->opcode
);
640 EXPECT_FALSE(instruction(block0
, 2)->saturate
);
643 TEST_F(saturate_propagation_test
, intervening_dest_write
)
645 const fs_builder
&bld
= v
->bld
;
646 fs_reg dst0
= v
->vgrf(glsl_type::vec4_type
);
647 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
648 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
649 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
650 fs_reg src2
= v
->vgrf(glsl_type::vec2_type
);
651 bld
.ADD(offset(dst0
, bld
, 2), src0
, src1
);
652 bld
.emit(SHADER_OPCODE_TEX
, dst0
, src2
)
653 ->size_written
= 8 * REG_SIZE
;
654 set_saturate(true, bld
.MOV(dst1
, offset(dst0
, bld
, 2)));
658 * 0: add(16) dst0+2 src0 src1
659 * 1: tex(16) rlen 4 dst0+0 src2
660 * 2: mov.sat(16) dst1 dst0+2
667 bblock_t
*block0
= v
->cfg
->blocks
[0];
669 EXPECT_EQ(0, block0
->start_ip
);
670 EXPECT_EQ(2, block0
->end_ip
);
672 EXPECT_FALSE(saturate_propagation(v
));
673 EXPECT_EQ(0, block0
->start_ip
);
674 EXPECT_EQ(2, block0
->end_ip
);
675 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
676 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
677 EXPECT_EQ(SHADER_OPCODE_TEX
, instruction(block0
, 1)->opcode
);
678 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
679 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 2)->opcode
);
680 EXPECT_TRUE(instruction(block0
, 2)->saturate
);
683 TEST_F(saturate_propagation_test
, mul_neg_mov_sat_mov_sat
)
685 const fs_builder
&bld
= v
->bld
;
686 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
687 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
688 fs_reg dst2
= v
->vgrf(glsl_type::float_type
);
689 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
690 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
691 bld
.MUL(dst0
, src0
, src1
);
693 set_saturate(true, bld
.MOV(dst1
, dst0
));
695 set_saturate(true, bld
.MOV(dst2
, dst0
));
699 * 0: mul(16) dst0 src0 src1
700 * 1: mov.sat(16) dst1 -dst0
701 * 2: mov.sat(16) dst2 dst0
708 bblock_t
*block0
= v
->cfg
->blocks
[0];
710 EXPECT_EQ(0, block0
->start_ip
);
711 EXPECT_EQ(2, block0
->end_ip
);
713 EXPECT_FALSE(saturate_propagation(v
));
714 EXPECT_EQ(0, block0
->start_ip
);
715 EXPECT_EQ(2, block0
->end_ip
);
716 EXPECT_EQ(BRW_OPCODE_MUL
, instruction(block0
, 0)->opcode
);
717 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
718 EXPECT_FALSE(instruction(block0
, 0)->src
[1].negate
);
719 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
720 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
721 EXPECT_TRUE(instruction(block0
, 1)->src
[0].negate
);
722 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 2)->opcode
);
723 EXPECT_TRUE(instruction(block0
, 2)->saturate
);
726 TEST_F(saturate_propagation_test
, smaller_exec_size_consumer
)
728 const fs_builder
&bld
= v
->bld
;
729 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
730 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
731 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
732 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
733 bld
.ADD(dst0
, src0
, src1
);
734 set_saturate(true, bld
.group(8, 0).MOV(dst1
, dst0
));
738 * 0: add(16) dst0 src0 src1
739 * 1: mov.sat(8) dst1 dst0
746 bblock_t
*block0
= v
->cfg
->blocks
[0];
748 EXPECT_EQ(0, block0
->start_ip
);
749 EXPECT_EQ(1, block0
->end_ip
);
751 EXPECT_FALSE(saturate_propagation(v
));
752 EXPECT_EQ(0, block0
->start_ip
);
753 EXPECT_EQ(1, block0
->end_ip
);
754 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
755 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
756 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
757 EXPECT_TRUE(instruction(block0
, 1)->saturate
);
760 TEST_F(saturate_propagation_test
, larger_exec_size_consumer
)
762 const fs_builder
&bld
= v
->bld
;
763 fs_reg dst0
= v
->vgrf(glsl_type::float_type
);
764 fs_reg dst1
= v
->vgrf(glsl_type::float_type
);
765 fs_reg src0
= v
->vgrf(glsl_type::float_type
);
766 fs_reg src1
= v
->vgrf(glsl_type::float_type
);
767 bld
.group(8, 0).ADD(dst0
, src0
, src1
);
768 set_saturate(true, bld
.MOV(dst1
, dst0
));
772 * 0: add(8) dst0 src0 src1
773 * 1: mov.sat(16) dst1 dst0
780 bblock_t
*block0
= v
->cfg
->blocks
[0];
782 EXPECT_EQ(0, block0
->start_ip
);
783 EXPECT_EQ(1, block0
->end_ip
);
785 EXPECT_FALSE(saturate_propagation(v
));
786 EXPECT_EQ(0, block0
->start_ip
);
787 EXPECT_EQ(1, block0
->end_ip
);
788 EXPECT_EQ(BRW_OPCODE_ADD
, instruction(block0
, 0)->opcode
);
789 EXPECT_FALSE(instruction(block0
, 0)->saturate
);
790 EXPECT_EQ(BRW_OPCODE_MOV
, instruction(block0
, 1)->opcode
);
791 EXPECT_TRUE(instruction(block0
, 1)->saturate
);