Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/panfrost/bifrost/bir.c
4564 views
1
/*
2
* Copyright (C) 2020 Collabora Ltd.
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 FROM,
20
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
* SOFTWARE.
22
*
23
* Authors (Collabora):
24
* Alyssa Rosenzweig <[email protected]>
25
*/
26
27
#include "compiler.h"
28
29
bool
30
bi_has_arg(bi_instr *ins, bi_index arg)
31
{
32
if (!ins)
33
return false;
34
35
bi_foreach_src(ins, s) {
36
if (bi_is_equiv(ins->src[s], arg))
37
return true;
38
}
39
40
return false;
41
}
42
43
/* Precondition: valid 16-bit or 32-bit register format. Returns whether it is
44
* 32-bit. Note auto reads to 32-bit registers even if the memory format is
45
* 16-bit, so is considered as such here */
46
47
bool
48
bi_is_regfmt_16(enum bi_register_format fmt)
49
{
50
switch (fmt) {
51
case BI_REGISTER_FORMAT_F16:
52
case BI_REGISTER_FORMAT_S16:
53
case BI_REGISTER_FORMAT_U16:
54
return true;
55
case BI_REGISTER_FORMAT_F32:
56
case BI_REGISTER_FORMAT_S32:
57
case BI_REGISTER_FORMAT_U32:
58
case BI_REGISTER_FORMAT_AUTO:
59
return false;
60
default:
61
unreachable("Invalid register format");
62
}
63
}
64
65
static unsigned
66
bi_count_staging_registers(bi_instr *ins)
67
{
68
enum bi_sr_count count = bi_opcode_props[ins->op].sr_count;
69
unsigned vecsize = ins->vecsize + 1; /* XXX: off-by-one */
70
71
switch (count) {
72
case BI_SR_COUNT_0 ... BI_SR_COUNT_4:
73
return count;
74
case BI_SR_COUNT_FORMAT:
75
return bi_is_regfmt_16(ins->register_format) ?
76
DIV_ROUND_UP(vecsize, 2) : vecsize;
77
case BI_SR_COUNT_VECSIZE:
78
return vecsize;
79
case BI_SR_COUNT_SR_COUNT:
80
return ins->sr_count;
81
}
82
83
unreachable("Invalid sr_count");
84
}
85
86
unsigned
87
bi_count_read_registers(bi_instr *ins, unsigned s)
88
{
89
if (s == 0 && bi_opcode_props[ins->op].sr_read)
90
return bi_count_staging_registers(ins);
91
else
92
return 1;
93
}
94
95
unsigned
96
bi_count_write_registers(bi_instr *ins, unsigned d)
97
{
98
if (d == 0 && bi_opcode_props[ins->op].sr_write) {
99
/* TODO: this special case is even more special, TEXC has a
100
* generic write mask stuffed in the desc... */
101
if (ins->op == BI_OPCODE_TEXC)
102
return 4;
103
else
104
return bi_count_staging_registers(ins);
105
}
106
107
return 1;
108
}
109
110
unsigned
111
bi_writemask(bi_instr *ins, unsigned d)
112
{
113
unsigned mask = BITFIELD_MASK(bi_count_write_registers(ins, d));
114
unsigned shift = ins->dest[d].offset;
115
return (mask << shift);
116
}
117
118
bi_clause *
119
bi_next_clause(bi_context *ctx, pan_block *block, bi_clause *clause)
120
{
121
if (!block && !clause)
122
return NULL;
123
124
/* Try the first clause in this block if we're starting from scratch */
125
if (!clause && !list_is_empty(&((bi_block *) block)->clauses))
126
return list_first_entry(&((bi_block *) block)->clauses, bi_clause, link);
127
128
/* Try the next clause in this block */
129
if (clause && clause->link.next != &((bi_block *) block)->clauses)
130
return list_first_entry(&(clause->link), bi_clause, link);
131
132
/* Try the next block, or the one after that if it's empty, etc .*/
133
pan_block *next_block = pan_next_block(block);
134
135
bi_foreach_block_from(ctx, next_block, block) {
136
bi_block *blk = (bi_block *) block;
137
138
if (!list_is_empty(&blk->clauses))
139
return list_first_entry(&(blk->clauses), bi_clause, link);
140
}
141
142
return NULL;
143
}
144
145
/* Does an instruction have a side effect not captured by its register
146
* destination? Applies to certain message-passing instructions, +DISCARD, and
147
* branching only, used in dead code elimation. Branches are characterized by
148
* `last` which applies to them and some atomics, +BARRIER, +BLEND which
149
* implies no loss of generality */
150
151
bool
152
bi_side_effects(enum bi_opcode op)
153
{
154
if (bi_opcode_props[op].last || op == BI_OPCODE_DISCARD_F32)
155
return true;
156
157
switch (bi_opcode_props[op].message) {
158
case BIFROST_MESSAGE_NONE:
159
case BIFROST_MESSAGE_VARYING:
160
case BIFROST_MESSAGE_ATTRIBUTE:
161
case BIFROST_MESSAGE_TEX:
162
case BIFROST_MESSAGE_VARTEX:
163
case BIFROST_MESSAGE_LOAD:
164
case BIFROST_MESSAGE_64BIT:
165
return false;
166
167
case BIFROST_MESSAGE_STORE:
168
case BIFROST_MESSAGE_ATOMIC:
169
case BIFROST_MESSAGE_BARRIER:
170
case BIFROST_MESSAGE_BLEND:
171
case BIFROST_MESSAGE_Z_STENCIL:
172
case BIFROST_MESSAGE_ATEST:
173
case BIFROST_MESSAGE_JOB:
174
return true;
175
176
case BIFROST_MESSAGE_TILE:
177
return (op != BI_OPCODE_LD_TILE);
178
}
179
180
unreachable("Invalid message type");
181
}
182
183