xref: /aosp_15_r20/external/mesa3d/src/intel/compiler/brw_fs_lower_pack.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2015 Connor Abbott
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 "util/half_float.h"
25 #include "brw_fs.h"
26 #include "brw_cfg.h"
27 #include "brw_fs_builder.h"
28 
29 using namespace brw;
30 
31 bool
brw_fs_lower_pack(fs_visitor & s)32 brw_fs_lower_pack(fs_visitor &s)
33 {
34    bool progress = false;
35 
36    foreach_block_and_inst_safe(block, fs_inst, inst, s.cfg) {
37       if (inst->opcode != FS_OPCODE_PACK &&
38           inst->opcode != FS_OPCODE_PACK_HALF_2x16_SPLIT)
39          continue;
40 
41       assert(inst->dst.file == VGRF);
42       assert(inst->saturate == false);
43       brw_reg dst = inst->dst;
44 
45       const fs_builder ibld(&s, block, inst);
46       /* The lowering generates 2 instructions for what was previously 1. This
47        * can trick the IR to believe we're doing partial writes, but the
48        * register is actually fully written. Mark it as undef to help the IR
49        * reduce the liveness of the register.
50        */
51       if (!inst->is_partial_write())
52          ibld.emit_undef_for_dst(inst);
53 
54       switch (inst->opcode) {
55       case FS_OPCODE_PACK:
56          for (unsigned i = 0; i < inst->sources; i++)
57             ibld.MOV(subscript(dst, inst->src[i].type, i), inst->src[i]);
58          break;
59       case FS_OPCODE_PACK_HALF_2x16_SPLIT:
60          assert(dst.type == BRW_TYPE_UD);
61 
62          for (unsigned i = 0; i < inst->sources; i++) {
63             if (inst->src[i].file == IMM) {
64                const uint32_t half = _mesa_float_to_half(inst->src[i].f);
65                ibld.MOV(subscript(dst, BRW_TYPE_UW, i),
66                         brw_imm_uw(half));
67             } else {
68                ibld.MOV(subscript(dst, BRW_TYPE_HF, i),
69                         inst->src[i]);
70             }
71          }
72          break;
73       default:
74          unreachable("skipped above");
75       }
76 
77       inst->remove(block);
78       progress = true;
79    }
80 
81    if (progress)
82       s.invalidate_analysis(DEPENDENCY_INSTRUCTIONS);
83 
84    return progress;
85 }
86