iris: lower io
[mesa.git] / src / gallium / drivers / iris / iris_program.c
1 /*
2 * Copyright © 2017 Intel Corporation
3 *
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 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
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 AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23 #include <stdio.h>
24 #include <errno.h>
25 #include "pipe/p_defines.h"
26 #include "pipe/p_state.h"
27 #include "pipe/p_context.h"
28 #include "pipe/p_screen.h"
29 #include "util/u_atomic.h"
30 #include "compiler/nir/nir.h"
31 #include "compiler/nir/nir_builder.h"
32 #include "intel/compiler/brw_compiler.h"
33 #include "intel/compiler/brw_nir.h"
34 #include "iris_context.h"
35
36 static unsigned
37 get_new_program_id(struct iris_screen *screen)
38 {
39 return p_atomic_inc_return(&screen->program_id);
40 }
41
42 struct iris_uncompiled_shader {
43 struct pipe_shader_state base;
44 unsigned program_id;
45 };
46
47 // XXX: need unify_interfaces() at link time...
48
49 static void *
50 iris_create_shader_state(struct pipe_context *ctx,
51 const struct pipe_shader_state *state)
52 {
53 //struct iris_context *ice = (struct iris_context *)ctx;
54 struct iris_screen *screen = (struct iris_screen *)ctx->screen;
55
56 assert(state->type == PIPE_SHADER_IR_NIR);
57
58 nir_shader *nir = state->ir.nir;
59
60 struct iris_uncompiled_shader *ish =
61 calloc(1, sizeof(struct iris_uncompiled_shader));
62 if (!ish)
63 return NULL;
64
65 nir = brw_preprocess_nir(screen->compiler, nir);
66
67 nir_assign_var_locations(&nir->uniforms, &nir->num_uniforms,
68 type_size_scalar_bytes);
69 nir_lower_io(nir, nir_var_uniform, type_size_scalar_bytes, 0);
70 //NIR_PASS_V(nir, brw_nir_lower_uniforms, true);
71
72 ish->program_id = get_new_program_id(screen);
73 ish->base.type = PIPE_SHADER_IR_NIR;
74 ish->base.ir.nir = nir;
75
76 return ish;
77 }
78
79 static void
80 iris_delete_shader_state(struct pipe_context *ctx, void *hwcso)
81 {
82 struct iris_uncompiled_shader *ish = hwcso;
83
84 ralloc_free(ish->base.ir.nir);
85 free(ish);
86 }
87
88 static void
89 iris_bind_vs_state(struct pipe_context *ctx, void *hwcso)
90 {
91 struct iris_context *ice = (struct iris_context *)ctx;
92
93 ice->shaders.progs[MESA_SHADER_VERTEX] = hwcso;
94 ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_VS;
95 }
96
97 static void
98 iris_bind_tcs_state(struct pipe_context *ctx, void *hwcso)
99 {
100 struct iris_context *ice = (struct iris_context *)ctx;
101
102 ice->shaders.progs[MESA_SHADER_TESS_CTRL] = hwcso;
103 ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_TCS;
104 }
105
106 static void
107 iris_bind_tes_state(struct pipe_context *ctx, void *hwcso)
108 {
109 struct iris_context *ice = (struct iris_context *)ctx;
110
111 ice->shaders.progs[MESA_SHADER_TESS_EVAL] = hwcso;
112 ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_TES;
113 }
114
115 static void
116 iris_bind_gs_state(struct pipe_context *ctx, void *hwcso)
117 {
118 struct iris_context *ice = (struct iris_context *)ctx;
119
120 ice->shaders.progs[MESA_SHADER_GEOMETRY] = hwcso;
121 ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_GS;
122 }
123
124 static void
125 iris_bind_fs_state(struct pipe_context *ctx, void *hwcso)
126 {
127 struct iris_context *ice = (struct iris_context *)ctx;
128
129 ice->shaders.progs[MESA_SHADER_FRAGMENT] = hwcso;
130 ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_FS;
131 }
132
133 /**
134 * Sets up the starting offsets for the groups of binding table entries
135 * common to all pipeline stages.
136 *
137 * Unused groups are initialized to 0xd0d0d0d0 to make it obvious that they're
138 * unused but also make sure that addition of small offsets to them will
139 * trigger some of our asserts that surface indices are < BRW_MAX_SURFACES.
140 */
141 static uint32_t
142 assign_common_binding_table_offsets(const struct gen_device_info *devinfo,
143 const struct shader_info *info,
144 struct brw_stage_prog_data *prog_data,
145 uint32_t next_binding_table_offset)
146 {
147 prog_data->binding_table.texture_start = next_binding_table_offset;
148 prog_data->binding_table.gather_texture_start = next_binding_table_offset;
149 next_binding_table_offset += info->num_textures;
150
151 if (info->num_ubos) {
152 //assert(info->num_ubos <= BRW_MAX_UBO);
153 prog_data->binding_table.ubo_start = next_binding_table_offset;
154 next_binding_table_offset += info->num_ubos;
155 } else {
156 prog_data->binding_table.ubo_start = 0xd0d0d0d0;
157 }
158
159 if (info->num_ssbos || info->num_abos) {
160 //assert(info->num_abos <= BRW_MAX_ABO);
161 //assert(info->num_ssbos <= BRW_MAX_SSBO);
162 prog_data->binding_table.ssbo_start = next_binding_table_offset;
163 next_binding_table_offset += info->num_abos + info->num_ssbos;
164 } else {
165 prog_data->binding_table.ssbo_start = 0xd0d0d0d0;
166 }
167
168 prog_data->binding_table.shader_time_start = 0xd0d0d0d0;
169
170 if (info->num_images) {
171 prog_data->binding_table.image_start = next_binding_table_offset;
172 next_binding_table_offset += info->num_images;
173 } else {
174 prog_data->binding_table.image_start = 0xd0d0d0d0;
175 }
176
177 /* This may or may not be used depending on how the compile goes. */
178 prog_data->binding_table.pull_constants_start = next_binding_table_offset;
179 next_binding_table_offset++;
180
181 /* Plane 0 is just the regular texture section */
182 prog_data->binding_table.plane_start[0] = prog_data->binding_table.texture_start;
183
184 prog_data->binding_table.plane_start[1] = next_binding_table_offset;
185 next_binding_table_offset += info->num_textures;
186
187 prog_data->binding_table.plane_start[2] = next_binding_table_offset;
188 next_binding_table_offset += info->num_textures;
189
190 /* prog_data->base.binding_table.size will be set by brw_mark_surface_used. */
191
192 //assert(next_binding_table_offset <= BRW_MAX_SURFACES);
193 return next_binding_table_offset;
194 }
195
196 static bool
197 iris_compile_vs(struct iris_context *ice,
198 struct iris_uncompiled_shader *ish,
199 const struct brw_vs_prog_key *key)
200 {
201 struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
202 const struct brw_compiler *compiler = screen->compiler;
203 const struct gen_device_info *devinfo = &screen->devinfo;
204 const unsigned *program;
205 struct brw_vs_prog_data vs_prog_data;
206 struct brw_stage_prog_data *prog_data = &vs_prog_data.base.base;
207 void *mem_ctx = ralloc_context(NULL);
208
209 assert(ish->base.type == PIPE_SHADER_IR_NIR);
210
211 nir_shader *nir = ish->base.ir.nir;
212
213 memset(&vs_prog_data, 0, sizeof(vs_prog_data));
214
215 // XXX: alt mode
216 assign_common_binding_table_offsets(devinfo, &nir->info, prog_data, 0);
217 brw_compute_vue_map(devinfo,
218 &vs_prog_data.base.vue_map, nir->info.outputs_written,
219 nir->info.separate_shader);
220
221 char *error_str = NULL;
222 program = brw_compile_vs(compiler, &ice->dbg, mem_ctx, key, &vs_prog_data,
223 nir, -1, &error_str);
224 if (program == NULL) {
225 dbg_printf("Failed to compile vertex shader: %s\n", error_str);
226
227 ralloc_free(mem_ctx);
228 return false;
229 }
230
231 /* The param and pull_param arrays will be freed by the shader cache. */
232 ralloc_steal(NULL, prog_data->param);
233 ralloc_steal(NULL, prog_data->pull_param);
234 iris_upload_cache(ice, IRIS_CACHE_VS, key, sizeof(*key), program,
235 prog_data->program_size, prog_data, sizeof(vs_prog_data),
236 &ice->shaders.prog_offset[MESA_SHADER_VERTEX],
237 &ice->shaders.prog_data[MESA_SHADER_VERTEX]);
238 ralloc_free(mem_ctx);
239
240 return true;
241 }
242
243 static void
244 iris_populate_vs_key(struct iris_context *ice, struct brw_vs_prog_key *key)
245 {
246 memset(key, 0, sizeof(*key));
247 }
248
249 static void
250 iris_update_compiled_vs(struct iris_context *ice)
251 {
252 struct brw_vs_prog_key key;
253 iris_populate_vs_key(ice, &key);
254
255 if (iris_search_cache(ice, IRIS_CACHE_VS, &key, sizeof(key), IRIS_DIRTY_VS,
256 &ice->shaders.prog_offset[MESA_SHADER_VERTEX],
257 &ice->shaders.prog_data[MESA_SHADER_VERTEX]))
258 return;
259
260 UNUSED bool success =
261 iris_compile_vs(ice, ice->shaders.progs[MESA_SHADER_VERTEX], &key);
262 }
263
264 static bool
265 iris_compile_fs(struct iris_context *ice,
266 struct iris_uncompiled_shader *ish,
267 const struct brw_wm_prog_key *key,
268 struct brw_vue_map *vue_map)
269 {
270 struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
271 const struct brw_compiler *compiler = screen->compiler;
272 const struct gen_device_info *devinfo = &screen->devinfo;
273 const unsigned *program;
274 struct brw_wm_prog_data fs_prog_data;
275 struct brw_stage_prog_data *prog_data = &fs_prog_data.base;
276 void *mem_ctx = ralloc_context(NULL);
277
278 assert(ish->base.type == PIPE_SHADER_IR_NIR);
279
280 nir_shader *nir = ish->base.ir.nir;
281
282 memset(&fs_prog_data, 0, sizeof(fs_prog_data));
283
284 // XXX: alt mode
285 assign_common_binding_table_offsets(devinfo, &nir->info, prog_data,
286 MAX2(key->nr_color_regions, 1));
287
288 char *error_str = NULL;
289 program = brw_compile_fs(compiler, &ice->dbg, mem_ctx, key, &fs_prog_data,
290 nir, NULL, -1, -1, -1, true, false, vue_map,
291 &error_str);
292 if (program == NULL) {
293 dbg_printf("Failed to compile fragment shader: %s\n", error_str);
294
295 ralloc_free(mem_ctx);
296 return false;
297 }
298
299 //brw_alloc_stage_scratch(brw, &brw->wm.base, prog_data.base.total_scratch);
300
301 /* The param and pull_param arrays will be freed by the shader cache. */
302 ralloc_steal(NULL, prog_data->param);
303 ralloc_steal(NULL, prog_data->pull_param);
304 #if 0
305 brw_upload_cache(&brw->cache, BRW_CACHE_FS_PROG,
306 key, sizeof(struct brw_wm_prog_key),
307 program, prog_data.base.program_size,
308 &prog_data, sizeof(prog_data),
309 &brw->wm.base.prog_offset, &brw->wm.base.prog_data);
310 #endif
311
312 ralloc_free(mem_ctx);
313
314 return true;
315 }
316
317 static void
318 iris_populate_fs_key(struct iris_context *ice, struct brw_wm_prog_key *key)
319 {
320 memset(key, 0, sizeof(*key));
321
322 /* XXX: dirty flags? */
323 struct pipe_framebuffer_state *fb = &ice->state.framebuffer;
324 //struct iris_depth_stencil_alpha_state *zsa = ice->state.framebuffer;
325 // XXX: can't access iris structs outside iris_state.c :(
326 // XXX: maybe just move these to iris_state.c, honestly...they're more
327 // about state than programs...
328
329 key->nr_color_regions = fb->nr_cbufs;
330
331 // key->force_dual_color_blend for unigine
332 #if 0
333 //key->replicate_alpha = fb->nr_cbufs > 1 && alpha test or alpha to coverage
334 if (cso_rast->multisample) {
335 key->persample_interp =
336 ctx->Multisample.SampleShading &&
337 (ctx->Multisample.MinSampleShadingValue *
338 _mesa_geometric_samples(ctx->DrawBuffer) > 1);
339
340 key->multisample_fbo = fb->samples > 1;
341 }
342 #endif
343
344 key->coherent_fb_fetch = true;
345 }
346
347 static void
348 iris_update_compiled_fs(struct iris_context *ice)
349 {
350 struct brw_wm_prog_key key;
351 iris_populate_fs_key(ice, &key);
352
353 if (iris_search_cache(ice, IRIS_CACHE_FS, &key, sizeof(key), IRIS_DIRTY_FS,
354 &ice->shaders.prog_offset[MESA_SHADER_FRAGMENT],
355 &ice->shaders.prog_data[MESA_SHADER_FRAGMENT]))
356 return;
357
358 UNUSED bool success =
359 iris_compile_fs(ice, ice->shaders.progs[MESA_SHADER_FRAGMENT], &key,
360 ice->shaders.last_vue_map);
361 }
362
363 static void
364 update_last_vue_map(struct iris_context *ice)
365 {
366 struct brw_stage_prog_data *prog_data;
367
368 if (ice->shaders.progs[MESA_SHADER_GEOMETRY])
369 prog_data = ice->shaders.prog_data[MESA_SHADER_GEOMETRY];
370 else if (ice->shaders.progs[MESA_SHADER_TESS_EVAL])
371 prog_data = ice->shaders.prog_data[MESA_SHADER_TESS_EVAL];
372 else
373 prog_data = ice->shaders.prog_data[MESA_SHADER_VERTEX];
374
375 struct brw_vue_prog_data *vue_prog_data = (void *) prog_data;
376 ice->shaders.last_vue_map = &vue_prog_data->vue_map;
377 }
378
379 void
380 iris_update_compiled_shaders(struct iris_context *ice)
381 {
382 iris_update_compiled_vs(ice);
383 update_last_vue_map(ice);
384 iris_update_compiled_fs(ice);
385 // ...
386 }
387
388 void
389 iris_init_program_functions(struct pipe_context *ctx)
390 {
391 ctx->create_vs_state = iris_create_shader_state;
392 ctx->create_tcs_state = iris_create_shader_state;
393 ctx->create_tes_state = iris_create_shader_state;
394 ctx->create_gs_state = iris_create_shader_state;
395 ctx->create_fs_state = iris_create_shader_state;
396
397 ctx->delete_vs_state = iris_delete_shader_state;
398 ctx->delete_tcs_state = iris_delete_shader_state;
399 ctx->delete_tes_state = iris_delete_shader_state;
400 ctx->delete_gs_state = iris_delete_shader_state;
401 ctx->delete_fs_state = iris_delete_shader_state;
402
403 ctx->bind_vs_state = iris_bind_vs_state;
404 ctx->bind_tcs_state = iris_bind_tcs_state;
405 ctx->bind_tes_state = iris_bind_tes_state;
406 ctx->bind_gs_state = iris_bind_gs_state;
407 ctx->bind_fs_state = iris_bind_fs_state;
408 }