Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/lima/ir/pp/instr.c
4574 views
1
/*
2
* Copyright (c) 2017 Lima Project
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, sub license,
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
12
* next paragraph) shall be included in all copies or substantial portions
13
* of the 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 NON-INFRINGEMENT. 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
21
* DEALINGS IN THE SOFTWARE.
22
*
23
*/
24
25
#include "util/ralloc.h"
26
27
#include "ppir.h"
28
29
ppir_instr *ppir_instr_create(ppir_block *block)
30
{
31
ppir_instr *instr = rzalloc(block, ppir_instr);
32
if (!instr)
33
return NULL;
34
35
list_inithead(&instr->succ_list);
36
list_inithead(&instr->pred_list);
37
38
instr->index = block->comp->cur_instr_index++;
39
instr->reg_pressure = -1;
40
41
list_addtail(&instr->list, &block->instr_list);
42
return instr;
43
}
44
45
void ppir_instr_add_dep(ppir_instr *succ, ppir_instr *pred)
46
{
47
/* don't add duplicated instr */
48
ppir_instr_foreach_pred(succ, dep) {
49
if (pred == dep->pred)
50
return;
51
}
52
53
ppir_dep *dep = ralloc(succ, ppir_dep);
54
dep->pred = pred;
55
dep->succ = succ;
56
list_addtail(&dep->pred_link, &succ->pred_list);
57
list_addtail(&dep->succ_link, &pred->succ_list);
58
}
59
60
void ppir_instr_insert_mul_node(ppir_node *add, ppir_node *mul)
61
{
62
ppir_instr *instr = add->instr;
63
int pos = mul->instr_pos;
64
int *slots = ppir_op_infos[mul->op].slots;
65
66
for (int i = 0; slots[i] != PPIR_INSTR_SLOT_END; i++) {
67
/* possible to insert at required place */
68
if (slots[i] == pos) {
69
if (!instr->slots[pos]) {
70
ppir_alu_node *add_alu = ppir_node_to_alu(add);
71
ppir_alu_node *mul_alu = ppir_node_to_alu(mul);
72
ppir_dest *dest = &mul_alu->dest;
73
int pipeline = pos == PPIR_INSTR_SLOT_ALU_VEC_MUL ?
74
ppir_pipeline_reg_vmul : ppir_pipeline_reg_fmul;
75
76
/* ^vmul/^fmul can't be used as last arg */
77
if (add_alu->num_src > 1) {
78
ppir_src *last_src = add_alu->src + add_alu->num_src - 1;
79
if (ppir_node_target_equal(last_src, dest))
80
return;
81
}
82
83
/* update add node src to use pipeline reg */
84
ppir_src *src = add_alu->src;
85
if (add_alu->num_src == 3) {
86
if (ppir_node_target_equal(src, dest)) {
87
src->type = ppir_target_pipeline;
88
src->pipeline = pipeline;
89
}
90
91
if (ppir_node_target_equal(++src, dest)) {
92
src->type = ppir_target_pipeline;
93
src->pipeline = pipeline;
94
}
95
}
96
else {
97
assert(ppir_node_target_equal(src, dest));
98
src->type = ppir_target_pipeline;
99
src->pipeline = pipeline;
100
}
101
102
/* update mul node dest to output to pipeline reg */
103
dest->type = ppir_target_pipeline;
104
dest->pipeline = pipeline;
105
106
instr->slots[pos] = mul;
107
mul->instr = instr;
108
}
109
return;
110
}
111
}
112
}
113
114
/* check whether a const slot fix into another const slot */
115
static bool ppir_instr_insert_const(ppir_const *dst, const ppir_const *src,
116
uint8_t *swizzle)
117
{
118
int i, j;
119
120
for (i = 0; i < src->num; i++) {
121
for (j = 0; j < dst->num; j++) {
122
if (src->value[i].ui == dst->value[j].ui)
123
break;
124
}
125
126
if (j == dst->num) {
127
if (dst->num == 4)
128
return false;
129
dst->value[dst->num++] = src->value[i];
130
}
131
132
swizzle[i] = j;
133
}
134
135
return true;
136
}
137
138
static void ppir_update_src_pipeline(ppir_pipeline pipeline, ppir_src *src,
139
ppir_dest *dest, uint8_t *swizzle)
140
{
141
if (ppir_node_target_equal(src, dest)) {
142
src->type = ppir_target_pipeline;
143
src->pipeline = pipeline;
144
145
if (swizzle) {
146
for (int k = 0; k < 4; k++)
147
src->swizzle[k] = swizzle[src->swizzle[k]];
148
}
149
}
150
}
151
152
/* make alu node src reflact the pipeline reg */
153
static void ppir_instr_update_src_pipeline(ppir_instr *instr, ppir_pipeline pipeline,
154
ppir_dest *dest, uint8_t *swizzle)
155
{
156
for (int i = PPIR_INSTR_SLOT_ALU_START; i <= PPIR_INSTR_SLOT_ALU_END; i++) {
157
if (!instr->slots[i])
158
continue;
159
160
ppir_alu_node *alu = ppir_node_to_alu(instr->slots[i]);
161
for (int j = 0; j < alu->num_src; j++) {
162
ppir_src *src = alu->src + j;
163
ppir_update_src_pipeline(pipeline, src, dest, swizzle);
164
}
165
}
166
167
ppir_node *branch_node = instr->slots[PPIR_INSTR_SLOT_BRANCH];
168
if (branch_node && (branch_node->type == ppir_node_type_branch)) {
169
ppir_branch_node *branch = ppir_node_to_branch(branch_node);
170
for (int j = 0; j < 2; j++) {
171
ppir_src *src = branch->src + j;
172
ppir_update_src_pipeline(pipeline, src, dest, swizzle);
173
}
174
}
175
}
176
177
bool ppir_instr_insert_node(ppir_instr *instr, ppir_node *node)
178
{
179
if (node->op == ppir_op_const) {
180
int i;
181
ppir_const_node *c = ppir_node_to_const(node);
182
const ppir_const *nc = &c->constant;
183
184
for (i = 0; i < 2; i++) {
185
ppir_const ic = instr->constant[i];
186
uint8_t swizzle[4] = {0};
187
188
if (ppir_instr_insert_const(&ic, nc, swizzle)) {
189
ppir_node *succ = ppir_node_first_succ(node);
190
ppir_src *src = NULL;
191
for (int s = 0; s < ppir_node_get_src_num(succ); s++) {
192
src = ppir_node_get_src(succ, s);
193
if (src->node == node)
194
break;
195
}
196
assert(src->node == node);
197
198
instr->constant[i] = ic;
199
ppir_update_src_pipeline(ppir_pipeline_reg_const0 + i, src,
200
&c->dest, swizzle);
201
break;
202
}
203
}
204
205
/* no const slot can insert */
206
if (i == 2)
207
return false;
208
209
return true;
210
}
211
else {
212
int *slots = ppir_op_infos[node->op].slots;
213
for (int i = 0; slots[i] != PPIR_INSTR_SLOT_END; i++) {
214
int pos = slots[i];
215
216
if (instr->slots[pos]) {
217
/* node already in this instr, i.e. load_uniform */
218
if (instr->slots[pos] == node)
219
return true;
220
else
221
continue;
222
}
223
224
/* ^fmul dests (e.g. condition for select) can only be
225
* scheduled to ALU_SCL_MUL */
226
if (pos == PPIR_INSTR_SLOT_ALU_SCL_ADD) {
227
ppir_dest *dest = ppir_node_get_dest(node);
228
if (dest && dest->type == ppir_target_pipeline &&
229
dest->pipeline == ppir_pipeline_reg_fmul)
230
continue;
231
}
232
233
if (pos == PPIR_INSTR_SLOT_ALU_SCL_MUL ||
234
pos == PPIR_INSTR_SLOT_ALU_SCL_ADD) {
235
ppir_dest *dest = ppir_node_get_dest(node);
236
if (!ppir_target_is_scalar(dest))
237
continue;
238
}
239
240
instr->slots[pos] = node;
241
node->instr = instr;
242
node->instr_pos = pos;
243
244
if ((node->op == ppir_op_load_uniform) || (node->op == ppir_op_load_temp)) {
245
ppir_load_node *l = ppir_node_to_load(node);
246
ppir_instr_update_src_pipeline(
247
instr, ppir_pipeline_reg_uniform, &l->dest, NULL);
248
}
249
250
return true;
251
}
252
253
return false;
254
}
255
}
256
257
static struct {
258
int len;
259
char *name;
260
} ppir_instr_fields[] = {
261
[PPIR_INSTR_SLOT_VARYING] = { 4, "vary" },
262
[PPIR_INSTR_SLOT_TEXLD] = { 4, "texl"},
263
[PPIR_INSTR_SLOT_UNIFORM] = { 4, "unif" },
264
[PPIR_INSTR_SLOT_ALU_VEC_MUL] = { 4, "vmul" },
265
[PPIR_INSTR_SLOT_ALU_SCL_MUL] = { 4, "smul" },
266
[PPIR_INSTR_SLOT_ALU_VEC_ADD] = { 4, "vadd" },
267
[PPIR_INSTR_SLOT_ALU_SCL_ADD] = { 4, "sadd" },
268
[PPIR_INSTR_SLOT_ALU_COMBINE] = { 4, "comb" },
269
[PPIR_INSTR_SLOT_STORE_TEMP] = { 4, "stor" },
270
[PPIR_INSTR_SLOT_BRANCH] = { 4, "brch" },
271
};
272
273
void ppir_instr_print_list(ppir_compiler *comp)
274
{
275
if (!(lima_debug & LIMA_DEBUG_PP))
276
return;
277
278
printf("======ppir instr list======\n");
279
printf(" ");
280
for (int i = 0; i < PPIR_INSTR_SLOT_NUM; i++)
281
printf("%-*s ", ppir_instr_fields[i].len, ppir_instr_fields[i].name);
282
printf("const0|1\n");
283
284
list_for_each_entry(ppir_block, block, &comp->block_list, list) {
285
printf("-------block %3d-------\n", block->index);
286
list_for_each_entry(ppir_instr, instr, &block->instr_list, list) {
287
printf("%c%03d: ", instr->is_end ? '*' : ' ', instr->index);
288
for (int i = 0; i < PPIR_INSTR_SLOT_NUM; i++) {
289
ppir_node *node = instr->slots[i];
290
if (node)
291
printf("%-*d ", ppir_instr_fields[i].len, node->index);
292
else
293
printf("%-*s ", ppir_instr_fields[i].len, "null");
294
}
295
for (int i = 0; i < 2; i++) {
296
if (i)
297
printf("| ");
298
299
for (int j = 0; j < instr->constant[i].num; j++)
300
printf("%f ", instr->constant[i].value[j].f);
301
}
302
printf("\n");
303
}
304
}
305
printf("===========================\n");
306
}
307
308
static void ppir_instr_print_sub(ppir_instr *instr)
309
{
310
printf("[%s%d",
311
instr->printed && !ppir_instr_is_leaf(instr) ? "+" : "",
312
instr->index);
313
314
if (!instr->printed) {
315
ppir_instr_foreach_pred(instr, dep) {
316
ppir_instr_print_sub(dep->pred);
317
}
318
319
instr->printed = true;
320
}
321
322
printf("]");
323
}
324
325
void ppir_instr_print_dep(ppir_compiler *comp)
326
{
327
if (!(lima_debug & LIMA_DEBUG_PP))
328
return;
329
330
list_for_each_entry(ppir_block, block, &comp->block_list, list) {
331
list_for_each_entry(ppir_instr, instr, &block->instr_list, list) {
332
instr->printed = false;
333
}
334
}
335
336
printf("======ppir instr depend======\n");
337
list_for_each_entry(ppir_block, block, &comp->block_list, list) {
338
printf("-------block %3d-------\n", block->index);
339
list_for_each_entry(ppir_instr, instr, &block->instr_list, list) {
340
if (ppir_instr_is_root(instr)) {
341
ppir_instr_print_sub(instr);
342
printf("\n");
343
}
344
}
345
}
346
printf("=============================\n");
347
}
348
349