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"
29 #include "lima_context.h"
32 static inline void *gpir_node_create_ssa(gpir_block
*block
, gpir_op op
, nir_ssa_def
*ssa
)
34 int index
= ssa
->index
;
35 gpir_node
*node
= gpir_node_create(block
, op
);
37 block
->comp
->var_nodes
[index
] = node
;
38 snprintf(node
->name
, sizeof(node
->name
), "ssa%d", index
);
39 list_addtail(&node
->list
, &block
->node_list
);
43 static inline void *gpir_node_create_reg(gpir_block
*block
, gpir_op op
, nir_reg_dest
*reg
)
45 int index
= reg
->reg
->index
;
46 gpir_node
*node
= gpir_node_create(block
, op
);
47 gpir_store_node
*store
= gpir_node_create(block
, gpir_op_store_reg
);
49 snprintf(node
->name
, sizeof(node
->name
), "reg%d", index
);
52 gpir_node_add_dep(&store
->node
, node
, GPIR_DEP_INPUT
);
54 list_for_each_entry(gpir_reg
, reg
, &block
->comp
->reg_list
, list
) {
55 if (reg
->index
== index
) {
57 list_addtail(&store
->reg_link
, ®
->defs_list
);
62 list_addtail(&node
->list
, &block
->node_list
);
63 list_addtail(&store
->node
.list
, &block
->node_list
);
67 static void *gpir_node_create_dest(gpir_block
*block
, gpir_op op
, nir_dest
*dest
)
70 return gpir_node_create_ssa(block
, op
, &dest
->ssa
);
72 return gpir_node_create_reg(block
, op
, &dest
->reg
);
75 static gpir_node
*gpir_node_find(gpir_block
*block
, gpir_node
*succ
, nir_src
*src
,
78 gpir_node
*pred
= NULL
;
81 if (src
->ssa
->num_components
> 1) {
82 for (int i
= 0; i
< GPIR_VECTOR_SSA_NUM
; i
++) {
83 if (block
->comp
->vector_ssa
[i
].ssa
== src
->ssa
->index
) {
84 pred
= block
->comp
->vector_ssa
[i
].nodes
[channel
];
89 pred
= block
->comp
->var_nodes
[src
->ssa
->index
];
94 pred
= gpir_node_create(block
, gpir_op_load_reg
);
95 list_addtail(&pred
->list
, &succ
->list
);
97 gpir_load_node
*load
= gpir_node_to_load(pred
);
98 list_for_each_entry(gpir_reg
, reg
, &block
->comp
->reg_list
, list
) {
99 if (reg
->index
== src
->reg
.reg
->index
) {
101 list_addtail(&load
->reg_link
, ®
->uses_list
);
110 static int nir_to_gpir_opcodes
[nir_num_opcodes
] = {
112 [0 ... nir_last_opcode
] = -1,
114 [nir_op_fmul
] = gpir_op_mul
,
115 [nir_op_fadd
] = gpir_op_add
,
116 [nir_op_fneg
] = gpir_op_neg
,
117 [nir_op_fmin
] = gpir_op_min
,
118 [nir_op_fmax
] = gpir_op_max
,
119 [nir_op_frcp
] = gpir_op_rcp
,
120 [nir_op_frsq
] = gpir_op_rsqrt
,
121 [nir_op_fexp2
] = gpir_op_exp2
,
122 [nir_op_flog2
] = gpir_op_log2
,
123 [nir_op_slt
] = gpir_op_lt
,
124 [nir_op_sge
] = gpir_op_ge
,
125 [nir_op_fcsel
] = gpir_op_select
,
126 [nir_op_ffloor
] = gpir_op_floor
,
127 [nir_op_fsign
] = gpir_op_sign
,
128 [nir_op_seq
] = gpir_op_eq
,
129 [nir_op_sne
] = gpir_op_ne
,
130 [nir_op_fabs
] = gpir_op_abs
,
131 [nir_op_mov
] = gpir_op_mov
,
134 static bool gpir_emit_alu(gpir_block
*block
, nir_instr
*ni
)
136 nir_alu_instr
*instr
= nir_instr_as_alu(ni
);
137 int op
= nir_to_gpir_opcodes
[instr
->op
];
140 gpir_error("unsupported nir_op: %s\n", nir_op_infos
[instr
->op
].name
);
144 gpir_alu_node
*node
= gpir_node_create_dest(block
, op
, &instr
->dest
.dest
);
148 unsigned num_child
= nir_op_infos
[instr
->op
].num_inputs
;
149 assert(num_child
<= ARRAY_SIZE(node
->children
));
150 node
->num_child
= num_child
;
152 for (int i
= 0; i
< num_child
; i
++) {
153 nir_alu_src
*src
= instr
->src
+ i
;
154 node
->children_negate
[i
] = src
->negate
;
156 gpir_node
*child
= gpir_node_find(block
, &node
->node
, &src
->src
, src
->swizzle
[0]);
157 node
->children
[i
] = child
;
159 gpir_node_add_dep(&node
->node
, child
, GPIR_DEP_INPUT
);
165 static gpir_node
*gpir_create_load(gpir_block
*block
, nir_dest
*dest
,
166 int op
, int index
, int component
)
168 gpir_load_node
*load
= gpir_node_create_dest(block
, op
, dest
);
173 load
->component
= component
;
177 static bool gpir_create_vector_load(gpir_block
*block
, nir_dest
*dest
, int index
)
179 assert(dest
->is_ssa
);
180 assert(index
< GPIR_VECTOR_SSA_NUM
);
182 block
->comp
->vector_ssa
[index
].ssa
= dest
->ssa
.index
;
184 for (int i
= 0; i
< dest
->ssa
.num_components
; i
++) {
185 gpir_node
*node
= gpir_create_load(block
, dest
, gpir_op_load_uniform
,
186 block
->comp
->constant_base
+ index
, i
);
190 block
->comp
->vector_ssa
[index
].nodes
[i
] = node
;
191 snprintf(node
->name
, sizeof(node
->name
), "ssa%d.%c", dest
->ssa
.index
, "xyzw"[i
]);
197 static bool gpir_emit_intrinsic(gpir_block
*block
, nir_instr
*ni
)
199 nir_intrinsic_instr
*instr
= nir_instr_as_intrinsic(ni
);
201 switch (instr
->intrinsic
) {
202 case nir_intrinsic_load_input
:
203 return gpir_create_load(block
, &instr
->dest
,
204 gpir_op_load_attribute
,
205 nir_intrinsic_base(instr
),
206 nir_intrinsic_component(instr
)) != NULL
;
207 case nir_intrinsic_load_uniform
:
209 int offset
= nir_intrinsic_base(instr
);
210 offset
+= (int)nir_src_as_float(instr
->src
[0]);
212 return gpir_create_load(block
, &instr
->dest
,
213 gpir_op_load_uniform
,
214 offset
/ 4, offset
% 4) != NULL
;
216 case nir_intrinsic_load_viewport_scale
:
217 return gpir_create_vector_load(block
, &instr
->dest
, GPIR_VECTOR_SSA_VIEWPORT_SCALE
);
218 case nir_intrinsic_load_viewport_offset
:
219 return gpir_create_vector_load(block
, &instr
->dest
, GPIR_VECTOR_SSA_VIEWPORT_OFFSET
);
220 case nir_intrinsic_store_output
:
222 gpir_store_node
*store
= gpir_node_create(block
, gpir_op_store_varying
);
223 if (unlikely(!store
))
225 list_addtail(&store
->node
.list
, &block
->node_list
);
227 store
->index
= nir_intrinsic_base(instr
);
228 store
->component
= nir_intrinsic_component(instr
);
230 gpir_node
*child
= gpir_node_find(block
, &store
->node
, instr
->src
, 0);
231 store
->child
= child
;
232 gpir_node_add_dep(&store
->node
, child
, GPIR_DEP_INPUT
);
237 gpir_error("unsupported nir_intrinsic_instr %s\n",
238 nir_intrinsic_infos
[instr
->intrinsic
].name
);
243 static bool gpir_emit_load_const(gpir_block
*block
, nir_instr
*ni
)
245 nir_load_const_instr
*instr
= nir_instr_as_load_const(ni
);
246 gpir_const_node
*node
=
247 gpir_node_create_ssa(block
, gpir_op_const
, &instr
->def
);
251 assert(instr
->def
.bit_size
== 32);
252 assert(instr
->def
.num_components
== 1);
254 node
->value
.i
= instr
->value
[0].i32
;
259 static bool gpir_emit_ssa_undef(gpir_block
*block
, nir_instr
*ni
)
261 gpir_error("nir_ssa_undef_instr not support\n");
265 static bool gpir_emit_tex(gpir_block
*block
, nir_instr
*ni
)
267 gpir_error("nir_jump_instr not support\n");
271 static bool gpir_emit_jump(gpir_block
*block
, nir_instr
*ni
)
273 gpir_error("nir_jump_instr not support\n");
277 static bool (*gpir_emit_instr
[nir_instr_type_phi
])(gpir_block
*, nir_instr
*) = {
278 [nir_instr_type_alu
] = gpir_emit_alu
,
279 [nir_instr_type_intrinsic
] = gpir_emit_intrinsic
,
280 [nir_instr_type_load_const
] = gpir_emit_load_const
,
281 [nir_instr_type_ssa_undef
] = gpir_emit_ssa_undef
,
282 [nir_instr_type_tex
] = gpir_emit_tex
,
283 [nir_instr_type_jump
] = gpir_emit_jump
,
286 static gpir_block
*gpir_block_create(gpir_compiler
*comp
)
288 gpir_block
*block
= ralloc(comp
, gpir_block
);
292 list_inithead(&block
->node_list
);
293 list_inithead(&block
->instr_list
);
298 static bool gpir_emit_block(gpir_compiler
*comp
, nir_block
*nblock
)
300 gpir_block
*block
= gpir_block_create(comp
);
304 list_addtail(&block
->list
, &comp
->block_list
);
307 nir_foreach_instr(instr
, nblock
) {
308 assert(instr
->type
< nir_instr_type_phi
);
309 if (!gpir_emit_instr
[instr
->type
](block
, instr
))
316 static bool gpir_emit_if(gpir_compiler
*comp
, nir_if
*nif
)
318 gpir_error("if nir_cf_node not support\n");
322 static bool gpir_emit_loop(gpir_compiler
*comp
, nir_loop
*nloop
)
324 gpir_error("loop nir_cf_node not support\n");
328 static bool gpir_emit_function(gpir_compiler
*comp
, nir_function_impl
*nfunc
)
330 gpir_error("function nir_cf_node not support\n");
334 static bool gpir_emit_cf_list(gpir_compiler
*comp
, struct exec_list
*list
)
336 foreach_list_typed(nir_cf_node
, node
, node
, list
) {
339 switch (node
->type
) {
340 case nir_cf_node_block
:
341 ret
= gpir_emit_block(comp
, nir_cf_node_as_block(node
));
344 ret
= gpir_emit_if(comp
, nir_cf_node_as_if(node
));
346 case nir_cf_node_loop
:
347 ret
= gpir_emit_loop(comp
, nir_cf_node_as_loop(node
));
349 case nir_cf_node_function
:
350 ret
= gpir_emit_function(comp
, nir_cf_node_as_function(node
));
353 gpir_error("unknown NIR node type %d\n", node
->type
);
364 gpir_reg
*gpir_create_reg(gpir_compiler
*comp
)
366 gpir_reg
*reg
= ralloc(comp
, gpir_reg
);
367 reg
->index
= comp
->cur_reg
++;
368 list_addtail(®
->list
, &comp
->reg_list
);
369 list_inithead(®
->defs_list
);
370 list_inithead(®
->uses_list
);
374 static gpir_compiler
*gpir_compiler_create(void *prog
, unsigned num_reg
, unsigned num_ssa
)
376 gpir_compiler
*comp
= rzalloc(prog
, gpir_compiler
);
378 list_inithead(&comp
->block_list
);
379 list_inithead(&comp
->reg_list
);
381 for (int i
= 0; i
< num_reg
; i
++)
382 gpir_create_reg(comp
);
384 for (int i
= 0; i
< GPIR_VECTOR_SSA_NUM
; i
++)
385 comp
->vector_ssa
[i
].ssa
= -1;
387 comp
->var_nodes
= rzalloc_array(comp
, gpir_node
*, num_ssa
);
392 static int gpir_glsl_type_size(enum glsl_base_type type
)
394 /* only support GLSL_TYPE_FLOAT */
395 assert(type
== GLSL_TYPE_FLOAT
);
399 bool gpir_compile_nir(struct lima_vs_shader_state
*prog
, struct nir_shader
*nir
)
401 nir_function_impl
*func
= nir_shader_get_entrypoint(nir
);
402 gpir_compiler
*comp
= gpir_compiler_create(prog
, func
->reg_alloc
, func
->ssa_alloc
);
406 comp
->constant_base
= nir
->num_uniforms
;
407 prog
->uniform_pending_offset
= nir
->num_uniforms
* 16;
409 if (!gpir_emit_cf_list(comp
, &func
->body
))
412 gpir_node_print_prog_seq(comp
);
413 gpir_node_print_prog_dep(comp
);
415 /* increase for viewport uniforms */
416 comp
->constant_base
+= GPIR_VECTOR_SSA_NUM
;
418 if (!gpir_pre_rsched_lower_prog(comp
))
421 if (!gpir_reduce_reg_pressure_schedule_prog(comp
))
424 if (!gpir_post_rsched_lower_prog(comp
))
427 if (!gpir_regalloc_prog(comp
))
430 if (!gpir_schedule_prog(comp
))
433 if (!gpir_codegen_prog(comp
))
436 nir_foreach_variable(var
, &nir
->outputs
) {
437 if (var
->data
.location
== VARYING_SLOT_POS
)
438 assert(var
->data
.driver_location
== 0);
440 struct lima_varying_info
*v
= prog
->varying
+ var
->data
.driver_location
;
441 if (!v
->components
) {
442 v
->component_size
= gpir_glsl_type_size(glsl_get_base_type(var
->type
));
446 v
->components
+= glsl_get_components(var
->type
);