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.
29 #include "main/mtypes.h"
31 #include "compiler/glsl/standalone.h"
32 #include "compiler/glsl/glsl_to_nir.h"
33 #include "compiler/glsl/gl_nir.h"
34 #include "compiler/nir_types.h"
36 #include "lima_context.h"
37 #include "lima_program.h"
38 #include "ir/lima_ir.h"
39 #include "standalone/glsl.h"
44 printf("Usage: lima_compiler [OPTIONS]... FILE\n");
45 printf(" --help - show this message\n");
49 insert_sorted(struct exec_list
*var_list
, nir_variable
*new_var
)
51 nir_foreach_variable_in_list(var
, var_list
) {
52 if (var
->data
.location
> new_var
->data
.location
&&
53 new_var
->data
.location
>= 0) {
54 exec_node_insert_node_before(&var
->node
, &new_var
->node
);
58 exec_list_push_tail(var_list
, &new_var
->node
);
62 sort_varyings(nir_shader
*nir
, nir_variable_mode mode
)
64 struct exec_list new_list
;
65 exec_list_make_empty(&new_list
);
66 nir_foreach_variable_with_modes_safe(var
, nir
, mode
) {
67 exec_node_remove(&var
->node
);
68 insert_sorted(&new_list
, var
);
70 exec_list_append(&nir
->variables
, &new_list
);
74 fixup_varying_slots(nir_shader
*nir
, nir_variable_mode mode
)
76 nir_foreach_variable_with_modes(var
, nir
, mode
) {
77 if (var
->data
.location
>= VARYING_SLOT_VAR0
) {
78 var
->data
.location
+= 9;
79 } else if ((var
->data
.location
>= VARYING_SLOT_TEX0
) &&
80 (var
->data
.location
<= VARYING_SLOT_TEX7
)) {
81 var
->data
.location
+= VARYING_SLOT_VAR0
- VARYING_SLOT_TEX0
;
87 load_glsl(unsigned num_files
, char* const* files
, gl_shader_stage stage
)
89 static const struct standalone_options options
= {
95 case MESA_SHADER_FRAGMENT
:
96 shader
= PIPE_SHADER_FRAGMENT
;
98 case MESA_SHADER_VERTEX
:
99 shader
= PIPE_SHADER_VERTEX
;
102 unreachable("bad stage");
104 struct gl_shader_program
*prog
;
105 const nir_shader_compiler_options
*nir_options
=
106 lima_program_get_compiler_options(shader
);
107 static struct gl_context local_ctx
;
109 prog
= standalone_compile_shader(&options
, num_files
, files
, &local_ctx
);
111 errx(1, "couldn't parse `%s'", files
[0]);
113 lima_do_glsl_optimizations(prog
->_LinkedShaders
[stage
]->ir
);
115 nir_shader
*nir
= glsl_to_nir(&local_ctx
, prog
, stage
, nir_options
);
117 /* required NIR passes: */
118 if (nir_options
->lower_all_io_to_temps
||
119 nir
->info
.stage
== MESA_SHADER_VERTEX
||
120 nir
->info
.stage
== MESA_SHADER_GEOMETRY
) {
121 NIR_PASS_V(nir
, nir_lower_io_to_temporaries
,
122 nir_shader_get_entrypoint(nir
),
124 } else if (nir
->info
.stage
== MESA_SHADER_FRAGMENT
) {
125 NIR_PASS_V(nir
, nir_lower_io_to_temporaries
,
126 nir_shader_get_entrypoint(nir
),
130 NIR_PASS_V(nir
, nir_lower_global_vars_to_local
);
131 NIR_PASS_V(nir
, nir_split_var_copies
);
132 NIR_PASS_V(nir
, nir_lower_var_copies
);
134 NIR_PASS_V(nir
, nir_split_var_copies
);
135 NIR_PASS_V(nir
, nir_lower_var_copies
);
136 nir_print_shader(nir
, stdout
);
137 NIR_PASS_V(nir
, gl_nir_lower_atomics
, prog
, true);
138 NIR_PASS_V(nir
, nir_lower_atomics_to_ssbo
);
139 nir_print_shader(nir
, stdout
);
142 case MESA_SHADER_VERTEX
:
143 nir_assign_var_locations(nir
, nir_var_shader_in
, &nir
->num_inputs
,
146 /* Re-lower global vars, to deal with any dead VS inputs. */
147 NIR_PASS_V(nir
, nir_lower_global_vars_to_local
);
149 sort_varyings(nir
, nir_var_shader_out
);
150 nir_assign_var_locations(nir
, nir_var_shader_out
, &nir
->num_outputs
,
152 fixup_varying_slots(nir
, nir_var_shader_out
);
154 case MESA_SHADER_FRAGMENT
:
155 sort_varyings(nir
, nir_var_shader_in
);
156 nir_assign_var_locations(nir
, nir_var_shader_in
, &nir
->num_inputs
,
158 fixup_varying_slots(nir
, nir_var_shader_in
);
159 nir_assign_var_locations(nir
, nir_var_shader_out
, &nir
->num_outputs
,
163 errx(1, "unhandled shader stage: %d", stage
);
166 nir_assign_var_locations(nir
, nir_var_uniform
,
170 NIR_PASS_V(nir
, nir_lower_system_values
);
171 NIR_PASS_V(nir
, nir_lower_frexp
);
172 NIR_PASS_V(nir
, gl_nir_lower_samplers
, prog
);
178 main(int argc
, char **argv
)
182 lima_debug
= LIMA_DEBUG_GP
| LIMA_DEBUG_PP
;
189 for (n
= 1; n
< argc
; n
++) {
190 if (!strcmp(argv
[n
], "--help")) {
198 char *filename
[10] = {0};
199 filename
[0] = argv
[n
];
201 char *ext
= rindex(filename
[0], '.');
204 if (!strcmp(ext
, ".frag")) {
205 stage
= MESA_SHADER_FRAGMENT
;
207 else if (!strcmp(ext
, ".vert")) {
208 stage
= MESA_SHADER_VERTEX
;
215 struct nir_lower_tex_options tex_options
= {
219 nir_shader
*nir
= load_glsl(1, filename
, stage
);
222 case MESA_SHADER_VERTEX
:
223 lima_program_optimize_vs_nir(nir
);
225 nir_print_shader(nir
, stdout
);
227 struct lima_vs_shader_state
*vs
= ralloc(nir
, struct lima_vs_shader_state
);
228 gpir_compile_nir(vs
, nir
, NULL
);
230 case MESA_SHADER_FRAGMENT
:
231 lima_program_optimize_fs_nir(nir
, &tex_options
);
233 nir_print_shader(nir
, stdout
);
235 struct lima_fs_shader_state
*so
= rzalloc(NULL
, struct lima_fs_shader_state
);
236 struct ra_regs
*ra
= ppir_regalloc_init(NULL
);
237 ppir_compile_nir(so
, nir
, ra
, NULL
);
240 errx(1, "unhandled shader stage: %d", stage
);