Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/asahi/compiler/cmdline.c
4564 views
1
/*
2
* Copyright (C) 2019 Ryan Houdek <[email protected]>
3
* Copyright (C) 2014 Rob Clark <[email protected]>
4
* Copyright © 2015 Red Hat
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the "Software"),
8
* to deal in the Software without restriction, including without limitation
9
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
* and/or sell copies of the Software, and to permit persons to whom the
11
* Software is furnished to do so, subject to the following conditions:
12
*
13
* The above copyright notice and this permission notice (including the next
14
* paragraph) shall be included in all copies or substantial portions of the
15
* Software.
16
*
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
* SOFTWARE.
24
*/
25
26
#include "main/mtypes.h"
27
#include "compiler/glsl/standalone.h"
28
#include "compiler/glsl/glsl_to_nir.h"
29
#include "compiler/glsl/gl_nir.h"
30
#include "compiler/nir_types.h"
31
#include "util/u_dynarray.h"
32
#include "agx_compile.h"
33
#include "agx_minifloat.h"
34
35
static int
36
st_packed_uniforms_type_size(const struct glsl_type *type, bool bindless)
37
{
38
return glsl_count_dword_slots(type, bindless);
39
}
40
41
static int
42
glsl_type_size(const struct glsl_type *type, bool bindless)
43
{
44
return glsl_count_attribute_slots(type, false);
45
}
46
47
static void
48
insert_sorted(struct exec_list *var_list, nir_variable *new_var)
49
{
50
nir_foreach_variable_in_list (var, var_list) {
51
if (var->data.location > new_var->data.location) {
52
exec_node_insert_node_before(&var->node, &new_var->node);
53
return;
54
}
55
}
56
exec_list_push_tail(var_list, &new_var->node);
57
}
58
59
static void
60
sort_varyings(nir_shader *nir, nir_variable_mode mode)
61
{
62
struct exec_list new_list;
63
exec_list_make_empty(&new_list);
64
nir_foreach_variable_with_modes_safe (var, nir, mode) {
65
exec_node_remove(&var->node);
66
insert_sorted(&new_list, var);
67
}
68
exec_list_append(&nir->variables, &new_list);
69
}
70
71
static void
72
fixup_varying_slots(nir_shader *nir, nir_variable_mode mode)
73
{
74
nir_foreach_variable_with_modes (var, nir, mode) {
75
if (var->data.location >= VARYING_SLOT_VAR0) {
76
var->data.location += 9;
77
} else if ((var->data.location >= VARYING_SLOT_TEX0) &&
78
(var->data.location <= VARYING_SLOT_TEX7)) {
79
var->data.location += VARYING_SLOT_VAR0 - VARYING_SLOT_TEX0;
80
}
81
}
82
}
83
84
static void
85
compile_shader(char **argv)
86
{
87
struct gl_shader_program *prog;
88
nir_shader *nir[2];
89
unsigned shader_types[2] = {
90
MESA_SHADER_VERTEX,
91
MESA_SHADER_FRAGMENT,
92
};
93
94
struct standalone_options options = {
95
.glsl_version = 300, /* ES - needed for precision */
96
.do_link = true,
97
.lower_precision = true
98
};
99
100
static struct gl_context local_ctx;
101
102
prog = standalone_compile_shader(&options, 2, argv, &local_ctx);
103
prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->info.stage = MESA_SHADER_FRAGMENT;
104
105
struct util_dynarray binary;
106
107
util_dynarray_init(&binary, NULL);
108
109
for (unsigned i = 0; i < 2; ++i) {
110
nir[i] = glsl_to_nir(&local_ctx, prog, shader_types[i], &agx_nir_options);
111
112
if (i == 0) {
113
nir_assign_var_locations(nir[i], nir_var_shader_in, &nir[i]->num_inputs,
114
glsl_type_size);
115
sort_varyings(nir[i], nir_var_shader_out);
116
nir_assign_var_locations(nir[i], nir_var_shader_out, &nir[i]->num_outputs,
117
glsl_type_size);
118
fixup_varying_slots(nir[i], nir_var_shader_out);
119
} else {
120
sort_varyings(nir[i], nir_var_shader_in);
121
nir_assign_var_locations(nir[i], nir_var_shader_in, &nir[i]->num_inputs,
122
glsl_type_size);
123
fixup_varying_slots(nir[i], nir_var_shader_in);
124
nir_assign_var_locations(nir[i], nir_var_shader_out, &nir[i]->num_outputs,
125
glsl_type_size);
126
}
127
128
nir_assign_var_locations(nir[i], nir_var_uniform, &nir[i]->num_uniforms,
129
glsl_type_size);
130
131
NIR_PASS_V(nir[i], nir_lower_global_vars_to_local);
132
NIR_PASS_V(nir[i], nir_lower_io_to_temporaries, nir_shader_get_entrypoint(nir[i]), true, i == 0);
133
NIR_PASS_V(nir[i], nir_lower_system_values);
134
NIR_PASS_V(nir[i], gl_nir_lower_samplers, prog);
135
NIR_PASS_V(nir[i], nir_split_var_copies);
136
NIR_PASS_V(nir[i], nir_lower_var_copies);
137
138
NIR_PASS_V(nir[i], nir_lower_io, nir_var_uniform,
139
st_packed_uniforms_type_size,
140
(nir_lower_io_options)0);
141
NIR_PASS_V(nir[i], nir_lower_uniforms_to_ubo, true, false);
142
143
/* before buffers and vars_to_ssa */
144
NIR_PASS_V(nir[i], gl_nir_lower_images, true);
145
146
NIR_PASS_V(nir[i], gl_nir_lower_buffers, prog);
147
NIR_PASS_V(nir[i], nir_opt_constant_folding);
148
149
struct agx_shader_info out = { 0 };
150
struct agx_shader_key keys[2] = {
151
{
152
.vs = {
153
.num_vbufs = 1,
154
.vbuf_strides = { 16 },
155
.attributes = {
156
{
157
.buf = 0,
158
.src_offset = 0,
159
.format = AGX_FORMAT_I32,
160
.nr_comps_minus_1 = 4 - 1
161
}
162
},
163
}
164
},
165
{
166
.fs = {
167
.tib_formats = { AGX_FORMAT_U8NORM }
168
}
169
}
170
};
171
172
agx_compile_shader_nir(nir[i], &keys[i], &binary, &out);
173
174
char *fn = NULL;
175
asprintf(&fn, "shader_%u.bin", i);
176
assert(fn != NULL);
177
FILE *fp = fopen(fn, "wb");
178
fwrite(binary.data, 1, binary.size, fp);
179
fclose(fp);
180
free(fn);
181
182
util_dynarray_clear(&binary);
183
}
184
185
util_dynarray_fini(&binary);
186
}
187
188
static void
189
disassemble(const char *filename, bool verbose)
190
{
191
FILE *fp = fopen(filename, "rb");
192
assert(fp);
193
194
fseek(fp, 0, SEEK_END);
195
unsigned filesize = ftell(fp);
196
rewind(fp);
197
198
uint32_t *code = malloc(filesize);
199
unsigned res = fread(code, 1, filesize, fp);
200
if (res != filesize) {
201
printf("Couldn't read full file\n");
202
}
203
fclose(fp);
204
205
/* TODO: stub */
206
207
free(code);
208
}
209
210
static void
211
tests()
212
{
213
#ifndef NDEBUG
214
agx_minifloat_tests();
215
printf("Pass.\n");
216
#else
217
fprintf(stderr, "tests not compiled in NDEBUG mode");
218
#endif
219
}
220
221
int
222
main(int argc, char **argv)
223
{
224
if (argc < 2) {
225
printf("Pass a command\n");
226
exit(1);
227
}
228
229
if (strcmp(argv[1], "compile") == 0)
230
compile_shader(&argv[2]);
231
else if (strcmp(argv[1], "disasm") == 0)
232
disassemble(argv[2], false);
233
else if (strcmp(argv[1], "disasm-verbose") == 0)
234
disassemble(argv[2], true);
235
else if (strcmp(argv[1], "test") == 0)
236
tests();
237
else
238
unreachable("Unknown command. Valid: compile/disasm/disasm-verbose");
239
240
return 0;
241
}
242
243