2 * Copyright (c) 2017 Lima Project
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:
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
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.
25 #include "util/ralloc.h"
26 #include "compiler/nir/nir.h"
27 #include "pipe/p_state.h"
31 #include "lima_context.h"
33 gpir_reg
*gpir_create_reg(gpir_compiler
*comp
)
35 gpir_reg
*reg
= ralloc(comp
, gpir_reg
);
36 reg
->index
= comp
->cur_reg
++;
37 list_addtail(®
->list
, &comp
->reg_list
);
41 static gpir_reg
*reg_for_nir_reg(gpir_compiler
*comp
, nir_register
*nir_reg
)
43 unsigned index
= nir_reg
->index
;
44 gpir_reg
*reg
= comp
->reg_for_reg
[index
];
47 reg
= gpir_create_reg(comp
);
48 comp
->reg_for_reg
[index
] = reg
;
52 static void register_node_ssa(gpir_block
*block
, gpir_node
*node
, nir_ssa_def
*ssa
)
54 block
->comp
->node_for_ssa
[ssa
->index
] = node
;
55 snprintf(node
->name
, sizeof(node
->name
), "ssa%d", ssa
->index
);
57 /* If any uses are outside the current block, we'll need to create a
58 * register and store to it.
60 bool needs_register
= false;
61 nir_foreach_use(use
, ssa
) {
62 if (use
->parent_instr
->block
!= ssa
->parent_instr
->block
) {
63 needs_register
= true;
68 if (!needs_register
) {
69 nir_foreach_if_use(use
, ssa
) {
70 if (nir_cf_node_prev(&use
->parent_if
->cf_node
) !=
71 &ssa
->parent_instr
->block
->cf_node
) {
72 needs_register
= true;
79 gpir_store_node
*store
= gpir_node_create(block
, gpir_op_store_reg
);
81 store
->reg
= gpir_create_reg(block
->comp
);
82 gpir_node_add_dep(&store
->node
, node
, GPIR_DEP_INPUT
);
83 list_addtail(&store
->node
.list
, &block
->node_list
);
84 block
->comp
->reg_for_ssa
[ssa
->index
] = store
->reg
;
88 static void register_node_reg(gpir_block
*block
, gpir_node
*node
, nir_reg_dest
*nir_reg
)
90 block
->comp
->node_for_reg
[nir_reg
->reg
->index
] = node
;
91 gpir_store_node
*store
= gpir_node_create(block
, gpir_op_store_reg
);
93 snprintf(node
->name
, sizeof(node
->name
), "reg%d", nir_reg
->reg
->index
);
96 store
->reg
= reg_for_nir_reg(block
->comp
, nir_reg
->reg
);
97 gpir_node_add_dep(&store
->node
, node
, GPIR_DEP_INPUT
);
99 list_addtail(&store
->node
.list
, &block
->node_list
);
102 /* Register the given gpir_node as providing the given NIR destination, so
103 * that gpir_node_find() will return it. Also insert any stores necessary if
104 * the destination will be used after the end of this basic block. The node
105 * must already be inserted.
107 static void register_node(gpir_block
*block
, gpir_node
*node
, nir_dest
*dest
)
110 register_node_ssa(block
, node
, &dest
->ssa
);
112 register_node_reg(block
, node
, &dest
->reg
);
115 static gpir_node
*gpir_node_find(gpir_block
*block
, nir_src
*src
,
118 gpir_reg
*reg
= NULL
;
119 gpir_node
*pred
= NULL
;
121 if (src
->ssa
->num_components
> 1) {
122 for (int i
= 0; i
< GPIR_VECTOR_SSA_NUM
; i
++) {
123 if (block
->comp
->vector_ssa
[i
].ssa
== src
->ssa
->index
) {
124 return block
->comp
->vector_ssa
[i
].nodes
[channel
];
128 gpir_node
*pred
= block
->comp
->node_for_ssa
[src
->ssa
->index
];
129 if (pred
->block
== block
)
131 reg
= block
->comp
->reg_for_ssa
[src
->ssa
->index
];
134 pred
= block
->comp
->node_for_reg
[src
->reg
.reg
->index
];
135 if (pred
&& pred
->block
== block
)
137 reg
= reg_for_nir_reg(block
->comp
, src
->reg
.reg
);
141 pred
= gpir_node_create(block
, gpir_op_load_reg
);
142 gpir_load_node
*load
= gpir_node_to_load(pred
);
144 list_addtail(&pred
->list
, &block
->node_list
);
149 static int nir_to_gpir_opcodes
[nir_num_opcodes
] = {
151 [0 ... nir_last_opcode
] = -1,
153 [nir_op_fmul
] = gpir_op_mul
,
154 [nir_op_fadd
] = gpir_op_add
,
155 [nir_op_fneg
] = gpir_op_neg
,
156 [nir_op_fmin
] = gpir_op_min
,
157 [nir_op_fmax
] = gpir_op_max
,
158 [nir_op_frcp
] = gpir_op_rcp
,
159 [nir_op_frsq
] = gpir_op_rsqrt
,
160 [nir_op_fexp2
] = gpir_op_exp2
,
161 [nir_op_flog2
] = gpir_op_log2
,
162 [nir_op_slt
] = gpir_op_lt
,
163 [nir_op_sge
] = gpir_op_ge
,
164 [nir_op_fcsel
] = gpir_op_select
,
165 [nir_op_ffloor
] = gpir_op_floor
,
166 [nir_op_fsign
] = gpir_op_sign
,
167 [nir_op_seq
] = gpir_op_eq
,
168 [nir_op_sne
] = gpir_op_ne
,
169 [nir_op_fabs
] = gpir_op_abs
,
172 static bool gpir_emit_alu(gpir_block
*block
, nir_instr
*ni
)
174 nir_alu_instr
*instr
= nir_instr_as_alu(ni
);
176 /* gpir_op_mov is useless before the final scheduler, and the scheduler
177 * currently doesn't expect us to emit it. Just register the destination of
178 * this instruction with its source. This will also emit any necessary
179 * register loads/stores for things like "r0 = mov ssa_0" or
182 if (instr
->op
== nir_op_mov
) {
183 gpir_node
*child
= gpir_node_find(block
, &instr
->src
[0].src
,
184 instr
->src
[0].swizzle
[0]);
185 register_node(block
, child
, &instr
->dest
.dest
);
189 int op
= nir_to_gpir_opcodes
[instr
->op
];
192 gpir_error("unsupported nir_op: %s\n", nir_op_infos
[instr
->op
].name
);
196 gpir_alu_node
*node
= gpir_node_create(block
, op
);
200 unsigned num_child
= nir_op_infos
[instr
->op
].num_inputs
;
201 assert(num_child
<= ARRAY_SIZE(node
->children
));
202 node
->num_child
= num_child
;
204 for (int i
= 0; i
< num_child
; i
++) {
205 nir_alu_src
*src
= instr
->src
+ i
;
206 node
->children_negate
[i
] = src
->negate
;
208 gpir_node
*child
= gpir_node_find(block
, &src
->src
, src
->swizzle
[0]);
209 node
->children
[i
] = child
;
211 gpir_node_add_dep(&node
->node
, child
, GPIR_DEP_INPUT
);
214 list_addtail(&node
->node
.list
, &block
->node_list
);
215 register_node(block
, &node
->node
, &instr
->dest
.dest
);
220 static gpir_node
*gpir_create_load(gpir_block
*block
, nir_dest
*dest
,
221 int op
, int index
, int component
)
223 gpir_load_node
*load
= gpir_node_create(block
, op
);
228 load
->component
= component
;
229 list_addtail(&load
->node
.list
, &block
->node_list
);
230 register_node(block
, &load
->node
, dest
);
234 static bool gpir_create_vector_load(gpir_block
*block
, nir_dest
*dest
, int index
)
236 assert(dest
->is_ssa
);
237 assert(index
< GPIR_VECTOR_SSA_NUM
);
239 block
->comp
->vector_ssa
[index
].ssa
= dest
->ssa
.index
;
241 for (int i
= 0; i
< dest
->ssa
.num_components
; i
++) {
242 gpir_node
*node
= gpir_create_load(block
, dest
, gpir_op_load_uniform
,
243 block
->comp
->constant_base
+ index
, i
);
247 block
->comp
->vector_ssa
[index
].nodes
[i
] = node
;
248 snprintf(node
->name
, sizeof(node
->name
), "ssa%d.%c", dest
->ssa
.index
, "xyzw"[i
]);
254 static bool gpir_emit_intrinsic(gpir_block
*block
, nir_instr
*ni
)
256 nir_intrinsic_instr
*instr
= nir_instr_as_intrinsic(ni
);
258 switch (instr
->intrinsic
) {
259 case nir_intrinsic_load_input
:
260 return gpir_create_load(block
, &instr
->dest
,
261 gpir_op_load_attribute
,
262 nir_intrinsic_base(instr
),
263 nir_intrinsic_component(instr
)) != NULL
;
264 case nir_intrinsic_load_uniform
:
266 int offset
= nir_intrinsic_base(instr
);
267 offset
+= (int)nir_src_as_float(instr
->src
[0]);
269 return gpir_create_load(block
, &instr
->dest
,
270 gpir_op_load_uniform
,
271 offset
/ 4, offset
% 4) != NULL
;
273 case nir_intrinsic_load_viewport_scale
:
274 return gpir_create_vector_load(block
, &instr
->dest
, GPIR_VECTOR_SSA_VIEWPORT_SCALE
);
275 case nir_intrinsic_load_viewport_offset
:
276 return gpir_create_vector_load(block
, &instr
->dest
, GPIR_VECTOR_SSA_VIEWPORT_OFFSET
);
277 case nir_intrinsic_store_output
:
279 gpir_store_node
*store
= gpir_node_create(block
, gpir_op_store_varying
);
280 if (unlikely(!store
))
282 gpir_node
*child
= gpir_node_find(block
, instr
->src
, 0);
283 store
->child
= child
;
284 store
->index
= nir_intrinsic_base(instr
);
285 store
->component
= nir_intrinsic_component(instr
);
287 gpir_node_add_dep(&store
->node
, child
, GPIR_DEP_INPUT
);
288 list_addtail(&store
->node
.list
, &block
->node_list
);
293 gpir_error("unsupported nir_intrinsic_instr %s\n",
294 nir_intrinsic_infos
[instr
->intrinsic
].name
);
299 static bool gpir_emit_load_const(gpir_block
*block
, nir_instr
*ni
)
301 nir_load_const_instr
*instr
= nir_instr_as_load_const(ni
);
302 gpir_const_node
*node
= gpir_node_create(block
, gpir_op_const
);
306 assert(instr
->def
.bit_size
== 32);
307 assert(instr
->def
.num_components
== 1);
309 node
->value
.i
= instr
->value
[0].i32
;
311 list_addtail(&node
->node
.list
, &block
->node_list
);
312 register_node_ssa(block
, &node
->node
, &instr
->def
);
316 static bool gpir_emit_ssa_undef(gpir_block
*block
, nir_instr
*ni
)
318 gpir_error("nir_ssa_undef_instr not support\n");
322 static bool gpir_emit_tex(gpir_block
*block
, nir_instr
*ni
)
324 gpir_error("nir_jump_instr not support\n");
328 static bool gpir_emit_jump(gpir_block
*block
, nir_instr
*ni
)
330 /* Jumps are emitted at the end of the basic block, so do nothing. */
334 static bool (*gpir_emit_instr
[nir_instr_type_phi
])(gpir_block
*, nir_instr
*) = {
335 [nir_instr_type_alu
] = gpir_emit_alu
,
336 [nir_instr_type_intrinsic
] = gpir_emit_intrinsic
,
337 [nir_instr_type_load_const
] = gpir_emit_load_const
,
338 [nir_instr_type_ssa_undef
] = gpir_emit_ssa_undef
,
339 [nir_instr_type_tex
] = gpir_emit_tex
,
340 [nir_instr_type_jump
] = gpir_emit_jump
,
343 static bool gpir_emit_function(gpir_compiler
*comp
, nir_function_impl
*impl
)
345 nir_index_blocks(impl
);
346 comp
->blocks
= ralloc_array(comp
, gpir_block
*, impl
->num_blocks
);
348 nir_foreach_block(block_nir
, impl
) {
349 gpir_block
*block
= ralloc(comp
, gpir_block
);
353 list_inithead(&block
->node_list
);
354 list_inithead(&block
->instr_list
);
356 list_addtail(&block
->list
, &comp
->block_list
);
358 comp
->blocks
[block_nir
->index
] = block
;
361 nir_foreach_block(block_nir
, impl
) {
362 gpir_block
*block
= comp
->blocks
[block_nir
->index
];
363 nir_foreach_instr(instr
, block_nir
) {
364 assert(instr
->type
< nir_instr_type_phi
);
365 if (!gpir_emit_instr
[instr
->type
](block
, instr
))
369 if (block_nir
->successors
[0] == impl
->end_block
)
370 block
->successors
[0] = NULL
;
372 block
->successors
[0] = comp
->blocks
[block_nir
->successors
[0]->index
];
373 block
->successors
[1] = NULL
;
375 if (block_nir
->successors
[1] != NULL
) {
376 nir_if
*nif
= nir_cf_node_as_if(nir_cf_node_next(&block_nir
->cf_node
));
377 gpir_alu_node
*cond
= gpir_node_create(block
, gpir_op_not
);
378 cond
->children
[0] = gpir_node_find(block
, &nif
->condition
, 0);
380 gpir_node_add_dep(&cond
->node
, cond
->children
[0], GPIR_DEP_INPUT
);
381 list_addtail(&cond
->node
.list
, &block
->node_list
);
383 gpir_branch_node
*branch
= gpir_node_create(block
, gpir_op_branch_cond
);
384 list_addtail(&branch
->node
.list
, &block
->node_list
);
386 branch
->dest
= comp
->blocks
[block_nir
->successors
[1]->index
];
387 block
->successors
[1] = branch
->dest
;
389 branch
->cond
= &cond
->node
;
390 gpir_node_add_dep(&branch
->node
, &cond
->node
, GPIR_DEP_INPUT
);
392 assert(block_nir
->successors
[0]->index
== block_nir
->index
+ 1);
393 } else if (block_nir
->successors
[0]->index
!= block_nir
->index
+ 1) {
394 gpir_branch_node
*branch
= gpir_node_create(block
, gpir_op_branch_uncond
);
395 list_addtail(&branch
->node
.list
, &block
->node_list
);
397 branch
->dest
= comp
->blocks
[block_nir
->successors
[0]->index
];
404 static gpir_compiler
*gpir_compiler_create(void *prog
, unsigned num_reg
, unsigned num_ssa
)
406 gpir_compiler
*comp
= rzalloc(prog
, gpir_compiler
);
408 list_inithead(&comp
->block_list
);
409 list_inithead(&comp
->reg_list
);
411 for (int i
= 0; i
< GPIR_VECTOR_SSA_NUM
; i
++)
412 comp
->vector_ssa
[i
].ssa
= -1;
414 comp
->node_for_ssa
= rzalloc_array(comp
, gpir_node
*, num_ssa
);
415 comp
->node_for_reg
= rzalloc_array(comp
, gpir_node
*, num_reg
);
416 comp
->reg_for_ssa
= rzalloc_array(comp
, gpir_reg
*, num_ssa
);
417 comp
->reg_for_reg
= rzalloc_array(comp
, gpir_reg
*, num_reg
);
422 static int gpir_glsl_type_size(enum glsl_base_type type
)
424 /* only support GLSL_TYPE_FLOAT */
425 assert(type
== GLSL_TYPE_FLOAT
);
429 static void gpir_print_shader_db(struct nir_shader
*nir
, gpir_compiler
*comp
,
430 struct pipe_debug_callback
*debug
)
432 const struct shader_info
*info
= &nir
->info
;
434 int ret
= asprintf(&shaderdb
,
435 "%s shader: %d inst, %d loops, %d:%d spills:fills\n",
436 gl_shader_stage_name(info
->stage
),
443 if (lima_debug
& LIMA_DEBUG_SHADERDB
)
444 fprintf(stderr
, "SHADER-DB: %s\n", shaderdb
);
446 pipe_debug_message(debug
, SHADER_INFO
, "%s", shaderdb
);
450 bool gpir_compile_nir(struct lima_vs_shader_state
*prog
, struct nir_shader
*nir
,
451 struct pipe_debug_callback
*debug
)
453 nir_function_impl
*func
= nir_shader_get_entrypoint(nir
);
454 gpir_compiler
*comp
= gpir_compiler_create(prog
, func
->reg_alloc
, func
->ssa_alloc
);
458 comp
->constant_base
= nir
->num_uniforms
;
459 prog
->uniform_pending_offset
= nir
->num_uniforms
* 16;
460 prog
->gl_pos_idx
= 0;
461 prog
->point_size_idx
= -1;
463 if (!gpir_emit_function(comp
, func
))
466 gpir_node_print_prog_seq(comp
);
467 gpir_node_print_prog_dep(comp
);
469 /* increase for viewport uniforms */
470 comp
->constant_base
+= GPIR_VECTOR_SSA_NUM
;
472 if (!gpir_optimize(comp
))
475 if (!gpir_pre_rsched_lower_prog(comp
))
478 if (!gpir_reduce_reg_pressure_schedule_prog(comp
))
481 if (!gpir_regalloc_prog(comp
))
484 if (!gpir_schedule_prog(comp
))
487 if (!gpir_codegen_prog(comp
))
490 nir_foreach_shader_out_variable(var
, nir
) {
492 switch (var
->data
.location
) {
493 case VARYING_SLOT_POS
:
494 prog
->gl_pos_idx
= var
->data
.driver_location
;
497 case VARYING_SLOT_PSIZ
:
498 prog
->point_size_idx
= var
->data
.driver_location
;
503 struct lima_varying_info
*v
= prog
->varying
+ var
->data
.driver_location
;
504 if (!v
->components
) {
505 v
->component_size
= gpir_glsl_type_size(glsl_get_base_type(var
->type
));
508 prog
->num_varyings
++;
511 v
->components
+= glsl_get_components(var
->type
);
514 gpir_print_shader_db(nir
, comp
, debug
);