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
)
80 pred
= block
->comp
->var_nodes
[src
->ssa
->index
];
84 pred
= gpir_node_create(block
, gpir_op_load_reg
);
85 list_addtail(&pred
->list
, &succ
->list
);
87 gpir_load_node
*load
= gpir_node_to_load(pred
);
88 list_for_each_entry(gpir_reg
, reg
, &block
->comp
->reg_list
, list
) {
89 if (reg
->index
== src
->reg
.reg
->index
) {
91 list_addtail(&load
->reg_link
, ®
->uses_list
);
100 static int nir_to_gpir_opcodes
[nir_num_opcodes
] = {
102 [0 ... nir_last_opcode
] = -1,
104 [nir_op_fmul
] = gpir_op_mul
,
105 [nir_op_fadd
] = gpir_op_add
,
106 [nir_op_fneg
] = gpir_op_neg
,
107 [nir_op_fnot
] = gpir_op_not
,
108 [nir_op_fmin
] = gpir_op_min
,
109 [nir_op_fmax
] = gpir_op_max
,
110 [nir_op_frcp
] = gpir_op_rcp
,
111 [nir_op_frsq
] = gpir_op_rsqrt
,
112 [nir_op_slt
] = gpir_op_lt
,
113 [nir_op_sge
] = gpir_op_ge
,
114 [nir_op_fcsel
] = gpir_op_select
,
115 [nir_op_ffloor
] = gpir_op_floor
,
116 [nir_op_fsign
] = gpir_op_sign
,
117 [nir_op_seq
] = gpir_op_eq
,
118 [nir_op_sne
] = gpir_op_ne
,
119 [nir_op_fand
] = gpir_op_min
,
120 [nir_op_for
] = gpir_op_max
,
121 [nir_op_fabs
] = gpir_op_abs
,
122 [nir_op_fmov
] = gpir_op_mov
,
125 static bool gpir_emit_alu(gpir_block
*block
, nir_instr
*ni
)
127 nir_alu_instr
*instr
= nir_instr_as_alu(ni
);
128 int op
= nir_to_gpir_opcodes
[instr
->op
];
131 gpir_error("unsupported nir_op: %s\n", nir_op_infos
[instr
->op
].name
);
135 gpir_alu_node
*node
= gpir_node_create_dest(block
, op
, &instr
->dest
.dest
);
139 unsigned num_child
= nir_op_infos
[instr
->op
].num_inputs
;
140 assert(num_child
<= ARRAY_SIZE(node
->children
));
141 node
->num_child
= num_child
;
143 for (int i
= 0; i
< num_child
; i
++) {
144 nir_alu_src
*src
= instr
->src
+ i
;
145 node
->children_negate
[i
] = src
->negate
;
147 gpir_node
*child
= gpir_node_find(block
, &node
->node
, &src
->src
);
148 node
->children
[i
] = child
;
150 gpir_node_add_dep(&node
->node
, child
, GPIR_DEP_INPUT
);
156 static gpir_node
*gpir_create_load(gpir_block
*block
, nir_dest
*dest
,
157 int op
, int index
, int component
)
159 gpir_load_node
*load
= gpir_node_create_dest(block
, op
, dest
);
164 load
->component
= component
;
168 static bool gpir_emit_intrinsic(gpir_block
*block
, nir_instr
*ni
)
170 nir_intrinsic_instr
*instr
= nir_instr_as_intrinsic(ni
);
172 switch (instr
->intrinsic
) {
173 case nir_intrinsic_load_input
:
174 return gpir_create_load(block
, &instr
->dest
,
175 gpir_op_load_attribute
,
176 nir_intrinsic_base(instr
),
177 nir_intrinsic_component(instr
)) != NULL
;
178 case nir_intrinsic_load_uniform
:
180 int offset
= nir_intrinsic_base(instr
);
181 offset
+= (int)nir_src_as_float(instr
->src
[0]);
183 return gpir_create_load(block
, &instr
->dest
,
184 gpir_op_load_uniform
,
185 offset
/ 4, offset
% 4) != NULL
;
187 case nir_intrinsic_store_output
:
189 gpir_store_node
*store
= gpir_node_create(block
, gpir_op_store_varying
);
190 if (unlikely(!store
))
192 list_addtail(&store
->node
.list
, &block
->node_list
);
194 store
->index
= nir_intrinsic_base(instr
);
195 store
->component
= nir_intrinsic_component(instr
);
197 gpir_node
*child
= gpir_node_find(block
, &store
->node
, instr
->src
);
198 store
->child
= child
;
199 gpir_node_add_dep(&store
->node
, child
, GPIR_DEP_INPUT
);
204 gpir_error("unsupported nir_intrinsic_instr %s\n",
205 nir_intrinsic_infos
[instr
->intrinsic
].name
);
210 static bool gpir_emit_load_const(gpir_block
*block
, nir_instr
*ni
)
212 nir_load_const_instr
*instr
= nir_instr_as_load_const(ni
);
213 gpir_const_node
*node
=
214 gpir_node_create_ssa(block
, gpir_op_const
, &instr
->def
);
218 assert(instr
->def
.bit_size
== 32);
219 assert(instr
->def
.num_components
== 1);
221 node
->value
.i
= instr
->value
[0].i32
;
226 static bool gpir_emit_ssa_undef(gpir_block
*block
, nir_instr
*ni
)
228 gpir_error("nir_ssa_undef_instr not support\n");
232 static bool gpir_emit_tex(gpir_block
*block
, nir_instr
*ni
)
234 gpir_error("nir_jump_instr not support\n");
238 static bool gpir_emit_jump(gpir_block
*block
, nir_instr
*ni
)
240 gpir_error("nir_jump_instr not support\n");
244 static bool (*gpir_emit_instr
[nir_instr_type_phi
])(gpir_block
*, nir_instr
*) = {
245 [nir_instr_type_alu
] = gpir_emit_alu
,
246 [nir_instr_type_intrinsic
] = gpir_emit_intrinsic
,
247 [nir_instr_type_load_const
] = gpir_emit_load_const
,
248 [nir_instr_type_ssa_undef
] = gpir_emit_ssa_undef
,
249 [nir_instr_type_tex
] = gpir_emit_tex
,
250 [nir_instr_type_jump
] = gpir_emit_jump
,
253 static gpir_block
*gpir_block_create(gpir_compiler
*comp
)
255 gpir_block
*block
= ralloc(comp
, gpir_block
);
259 list_inithead(&block
->node_list
);
260 list_inithead(&block
->instr_list
);
265 static bool gpir_emit_block(gpir_compiler
*comp
, nir_block
*nblock
)
267 gpir_block
*block
= gpir_block_create(comp
);
271 list_addtail(&block
->list
, &comp
->block_list
);
274 nir_foreach_instr(instr
, nblock
) {
275 assert(instr
->type
< nir_instr_type_phi
);
276 if (!gpir_emit_instr
[instr
->type
](block
, instr
))
283 static bool gpir_emit_if(gpir_compiler
*comp
, nir_if
*nif
)
285 gpir_error("if nir_cf_node not support\n");
289 static bool gpir_emit_loop(gpir_compiler
*comp
, nir_loop
*nloop
)
291 gpir_error("loop nir_cf_node not support\n");
295 static bool gpir_emit_function(gpir_compiler
*comp
, nir_function_impl
*nfunc
)
297 gpir_error("function nir_cf_node not support\n");
301 static bool gpir_emit_cf_list(gpir_compiler
*comp
, struct exec_list
*list
)
303 foreach_list_typed(nir_cf_node
, node
, node
, list
) {
306 switch (node
->type
) {
307 case nir_cf_node_block
:
308 ret
= gpir_emit_block(comp
, nir_cf_node_as_block(node
));
311 ret
= gpir_emit_if(comp
, nir_cf_node_as_if(node
));
313 case nir_cf_node_loop
:
314 ret
= gpir_emit_loop(comp
, nir_cf_node_as_loop(node
));
316 case nir_cf_node_function
:
317 ret
= gpir_emit_function(comp
, nir_cf_node_as_function(node
));
320 gpir_error("unknown NIR node type %d\n", node
->type
);
331 gpir_reg
*gpir_create_reg(gpir_compiler
*comp
)
333 gpir_reg
*reg
= ralloc(comp
, gpir_reg
);
334 reg
->index
= comp
->cur_reg
++;
335 list_addtail(®
->list
, &comp
->reg_list
);
336 list_inithead(®
->defs_list
);
337 list_inithead(®
->uses_list
);
341 static gpir_compiler
*gpir_compiler_create(void *prog
, unsigned num_reg
, unsigned num_ssa
)
343 gpir_compiler
*comp
= rzalloc(prog
, gpir_compiler
);
345 list_inithead(&comp
->block_list
);
346 list_inithead(&comp
->reg_list
);
348 for (int i
= 0; i
< num_reg
; i
++)
349 gpir_create_reg(comp
);
351 comp
->var_nodes
= rzalloc_array(comp
, gpir_node
*, num_ssa
);
356 static int gpir_glsl_type_size(enum glsl_base_type type
)
358 /* only support GLSL_TYPE_FLOAT */
359 assert(type
== GLSL_TYPE_FLOAT
);
363 bool gpir_compile_nir(struct lima_vs_shader_state
*prog
, struct nir_shader
*nir
)
365 nir_function_impl
*func
= nir_shader_get_entrypoint(nir
);
366 gpir_compiler
*comp
= gpir_compiler_create(prog
, func
->reg_alloc
, func
->ssa_alloc
);
370 comp
->constant_base
= nir
->num_uniforms
;
371 prog
->uniform_pending_offset
= nir
->num_uniforms
* 16;
373 if (!gpir_emit_cf_list(comp
, &func
->body
))
376 gpir_node_print_prog_seq(comp
);
377 gpir_node_print_prog_dep(comp
);
379 if (!gpir_pre_rsched_lower_prog(comp
))
382 if (!gpir_reduce_reg_pressure_schedule_prog(comp
))
385 if (!gpir_post_rsched_lower_prog(comp
))
388 if (!gpir_value_regalloc_prog(comp
))
391 if (!gpir_physical_regalloc_prog(comp
))
394 if (!gpir_schedule_prog(comp
))
397 if (!gpir_codegen_prog(comp
))
400 nir_foreach_variable(var
, &nir
->outputs
) {
401 if (var
->data
.location
== VARYING_SLOT_POS
)
402 assert(var
->data
.driver_location
== 0);
404 struct lima_varying_info
*v
= prog
->varying
+ var
->data
.driver_location
;
405 if (!v
->components
) {
406 v
->component_size
= gpir_glsl_type_size(glsl_get_base_type(var
->type
));
410 v
->components
+= glsl_get_components(var
->type
);