iris: Use SATURATE
[mesa.git] / src / gallium / drivers / iris / iris_draw.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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
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:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23 /**
24 * @file iris_draw.c
25 *
26 * The main driver hooks for drawing and launching compute shaders.
27 */
28
29 #include <stdio.h>
30 #include <errno.h>
31 #include "pipe/p_defines.h"
32 #include "pipe/p_state.h"
33 #include "pipe/p_context.h"
34 #include "pipe/p_screen.h"
35 #include "util/u_inlines.h"
36 #include "util/u_transfer.h"
37 #include "util/u_upload_mgr.h"
38 #include "intel/compiler/brw_compiler.h"
39 #include "intel/compiler/brw_eu_defines.h"
40 #include "iris_context.h"
41 #include "iris_defines.h"
42
43 static bool
44 prim_is_points_or_lines(const struct pipe_draw_info *draw)
45 {
46 /* We don't need to worry about adjacency - it can only be used with
47 * geometry shaders, and we don't care about this info when GS is on.
48 */
49 return draw->mode == PIPE_PRIM_POINTS ||
50 draw->mode == PIPE_PRIM_LINES ||
51 draw->mode == PIPE_PRIM_LINE_LOOP ||
52 draw->mode == PIPE_PRIM_LINE_STRIP;
53 }
54
55 /**
56 * Record the current primitive mode and restart information, flagging
57 * related packets as dirty if necessary.
58 *
59 * This must be called before updating compiled shaders, because the patch
60 * information informs the TCS key.
61 */
62 static void
63 iris_update_draw_info(struct iris_context *ice,
64 const struct pipe_draw_info *info)
65 {
66 struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen;
67 const struct brw_compiler *compiler = screen->compiler;
68
69 if (ice->state.prim_mode != info->mode) {
70 ice->state.prim_mode = info->mode;
71 ice->state.dirty |= IRIS_DIRTY_VF_TOPOLOGY;
72
73
74 /* For XY Clip enables */
75 bool points_or_lines = prim_is_points_or_lines(info);
76 if (points_or_lines != ice->state.prim_is_points_or_lines) {
77 ice->state.prim_is_points_or_lines = points_or_lines;
78 ice->state.dirty |= IRIS_DIRTY_CLIP;
79 }
80 }
81
82 if (info->mode == PIPE_PRIM_PATCHES &&
83 ice->state.vertices_per_patch != info->vertices_per_patch) {
84 ice->state.vertices_per_patch = info->vertices_per_patch;
85 ice->state.dirty |= IRIS_DIRTY_VF_TOPOLOGY;
86
87 /* 8_PATCH TCS needs this for key->input_vertices */
88 if (compiler->use_tcs_8_patch)
89 ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_TCS;
90
91 /* Flag constants dirty for gl_PatchVerticesIn if needed. */
92 const struct shader_info *tcs_info =
93 iris_get_shader_info(ice, MESA_SHADER_TESS_CTRL);
94 if (tcs_info &&
95 tcs_info->system_values_read & (1ull << SYSTEM_VALUE_VERTICES_IN)) {
96 ice->state.dirty |= IRIS_DIRTY_CONSTANTS_TCS;
97 ice->state.shaders[MESA_SHADER_TESS_CTRL].sysvals_need_upload = true;
98 }
99 }
100
101 if (ice->state.primitive_restart != info->primitive_restart ||
102 ice->state.cut_index != info->restart_index) {
103 ice->state.dirty |= IRIS_DIRTY_VF;
104 ice->state.primitive_restart = info->primitive_restart;
105 ice->state.cut_index = info->restart_index;
106 }
107 }
108
109 /**
110 * Update shader draw parameters, flagging VF packets as dirty if necessary.
111 */
112 static void
113 iris_update_draw_parameters(struct iris_context *ice,
114 const struct pipe_draw_info *info)
115 {
116 bool changed = false;
117
118 if (ice->state.vs_uses_draw_params) {
119 struct iris_state_ref *draw_params = &ice->draw.draw_params;
120
121 if (info->indirect) {
122 pipe_resource_reference(&draw_params->res, info->indirect->buffer);
123 draw_params->offset =
124 info->indirect->offset + (info->index_size ? 12 : 8);
125
126 changed = true;
127 ice->draw.params_valid = false;
128 } else {
129 int firstvertex = info->index_size ? info->index_bias : info->start;
130
131 if (!ice->draw.params_valid ||
132 ice->draw.params.firstvertex != firstvertex ||
133 ice->draw.params.baseinstance != info->start_instance) {
134
135 changed = true;
136 ice->draw.params.firstvertex = firstvertex;
137 ice->draw.params.baseinstance = info->start_instance;
138 ice->draw.params_valid = true;
139
140 u_upload_data(ice->ctx.stream_uploader, 0,
141 sizeof(ice->draw.params), 4, &ice->draw.params,
142 &draw_params->offset, &draw_params->res);
143 }
144 }
145 }
146
147 if (ice->state.vs_uses_derived_draw_params) {
148 struct iris_state_ref *derived_params = &ice->draw.derived_draw_params;
149 int is_indexed_draw = info->index_size ? -1 : 0;
150
151 if (ice->draw.derived_params.drawid != info->drawid ||
152 ice->draw.derived_params.is_indexed_draw != is_indexed_draw) {
153
154 changed = true;
155 ice->draw.derived_params.drawid = info->drawid;
156 ice->draw.derived_params.is_indexed_draw = is_indexed_draw;
157
158 u_upload_data(ice->ctx.stream_uploader, 0,
159 sizeof(ice->draw.derived_params), 4,
160 &ice->draw.derived_params,
161 &derived_params->offset, &derived_params->res);
162 }
163 }
164
165 if (changed) {
166 ice->state.dirty |= IRIS_DIRTY_VERTEX_BUFFERS |
167 IRIS_DIRTY_VERTEX_ELEMENTS |
168 IRIS_DIRTY_VF_SGVS;
169 }
170 }
171
172 static void
173 iris_indirect_draw_vbo(struct iris_context *ice,
174 const struct pipe_draw_info *dinfo)
175 {
176 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
177 struct pipe_draw_info info = *dinfo;
178
179 if (info.indirect->indirect_draw_count &&
180 ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT) {
181 /* Upload MI_PREDICATE_RESULT to GPR15.*/
182 batch->screen->vtbl.load_register_reg64(batch, CS_GPR(15), MI_PREDICATE_RESULT);
183 }
184
185 uint64_t orig_dirty = ice->state.dirty;
186
187 for (int i = 0; i < info.indirect->draw_count; i++) {
188 info.drawid = i;
189
190 iris_batch_maybe_flush(batch, 1500);
191
192 iris_update_draw_parameters(ice, &info);
193
194 batch->screen->vtbl.upload_render_state(ice, batch, &info);
195
196 ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_RENDER;
197
198 info.indirect->offset += info.indirect->stride;
199 }
200
201 if (info.indirect->indirect_draw_count &&
202 ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT) {
203 /* Restore MI_PREDICATE_RESULT. */
204 batch->screen->vtbl.load_register_reg64(batch, MI_PREDICATE_RESULT, CS_GPR(15));
205 }
206
207 /* Put this back for post-draw resolves, we'll clear it again after. */
208 ice->state.dirty = orig_dirty;
209 }
210
211 static void
212 iris_simple_draw_vbo(struct iris_context *ice,
213 const struct pipe_draw_info *draw)
214 {
215 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
216
217 iris_batch_maybe_flush(batch, 1500);
218
219 iris_update_draw_parameters(ice, draw);
220
221 batch->screen->vtbl.upload_render_state(ice, batch, draw);
222 }
223
224 /**
225 * The pipe->draw_vbo() driver hook. Performs a draw on the GPU.
226 */
227 void
228 iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
229 {
230 struct iris_context *ice = (struct iris_context *) ctx;
231 struct iris_screen *screen = (struct iris_screen*)ice->ctx.screen;
232 const struct gen_device_info *devinfo = &screen->devinfo;
233 struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
234
235 if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
236 return;
237
238 /* We can't safely re-emit 3DSTATE_SO_BUFFERS because it may zero the
239 * write offsets, changing the behavior.
240 */
241 if (unlikely(INTEL_DEBUG & DEBUG_REEMIT))
242 ice->state.dirty |= IRIS_ALL_DIRTY_FOR_RENDER & ~IRIS_DIRTY_SO_BUFFERS;
243
244 iris_update_draw_info(ice, info);
245
246 if (devinfo->gen == 9)
247 gen9_toggle_preemption(ice, batch, info);
248
249 iris_update_compiled_shaders(ice);
250
251 if (ice->state.dirty & IRIS_DIRTY_RENDER_RESOLVES_AND_FLUSHES) {
252 bool draw_aux_buffer_disabled[BRW_MAX_DRAW_BUFFERS] = { };
253 for (gl_shader_stage stage = 0; stage < MESA_SHADER_COMPUTE; stage++) {
254 if (ice->shaders.prog[stage])
255 iris_predraw_resolve_inputs(ice, batch, draw_aux_buffer_disabled,
256 stage, true);
257 }
258 iris_predraw_resolve_framebuffer(ice, batch, draw_aux_buffer_disabled);
259 }
260
261 iris_binder_reserve_3d(ice);
262
263 batch->screen->vtbl.update_surface_base_address(batch, &ice->state.binder);
264
265 iris_handle_always_flush_cache(batch);
266
267 if (info->indirect)
268 iris_indirect_draw_vbo(ice, info);
269 else
270 iris_simple_draw_vbo(ice, info);
271
272 iris_handle_always_flush_cache(batch);
273
274 iris_postdraw_update_resolve_tracking(ice, batch);
275
276 ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_RENDER;
277 }
278
279 static void
280 iris_update_grid_size_resource(struct iris_context *ice,
281 const struct pipe_grid_info *grid)
282 {
283 const struct iris_screen *screen = (void *) ice->ctx.screen;
284 const struct isl_device *isl_dev = &screen->isl_dev;
285 struct iris_state_ref *grid_ref = &ice->state.grid_size;
286 struct iris_state_ref *state_ref = &ice->state.grid_surf_state;
287
288 const struct iris_compiled_shader *shader = ice->shaders.prog[MESA_SHADER_COMPUTE];
289 bool grid_needs_surface = shader->bt.used_mask[IRIS_SURFACE_GROUP_CS_WORK_GROUPS];
290 bool grid_updated = false;
291
292 if (grid->indirect) {
293 pipe_resource_reference(&grid_ref->res, grid->indirect);
294 grid_ref->offset = grid->indirect_offset;
295
296 /* Zero out the grid size so that the next non-indirect grid launch will
297 * re-upload it properly.
298 */
299 memset(ice->state.last_grid, 0, sizeof(ice->state.last_grid));
300 grid_updated = true;
301 } else if (memcmp(ice->state.last_grid, grid->grid, sizeof(grid->grid)) != 0) {
302 memcpy(ice->state.last_grid, grid->grid, sizeof(grid->grid));
303 u_upload_data(ice->state.dynamic_uploader, 0, sizeof(grid->grid), 4,
304 grid->grid, &grid_ref->offset, &grid_ref->res);
305 grid_updated = true;
306 }
307
308 /* If we changed the grid, the old surface state is invalid. */
309 if (grid_updated)
310 pipe_resource_reference(&state_ref->res, NULL);
311
312 /* Skip surface upload if we don't need it or we already have one */
313 if (!grid_needs_surface || state_ref->res)
314 return;
315
316 struct iris_bo *grid_bo = iris_resource_bo(grid_ref->res);
317
318 void *surf_map = NULL;
319 u_upload_alloc(ice->state.surface_uploader, 0, isl_dev->ss.size,
320 isl_dev->ss.align, &state_ref->offset, &state_ref->res,
321 &surf_map);
322 state_ref->offset +=
323 iris_bo_offset_from_base_address(iris_resource_bo(state_ref->res));
324 isl_buffer_fill_state(&screen->isl_dev, surf_map,
325 .address = grid_ref->offset + grid_bo->gtt_offset,
326 .size_B = sizeof(grid->grid),
327 .format = ISL_FORMAT_RAW,
328 .stride_B = 1,
329 .mocs = iris_mocs(grid_bo, isl_dev));
330
331 ice->state.dirty |= IRIS_DIRTY_BINDINGS_CS;
332 }
333
334 void
335 iris_launch_grid(struct pipe_context *ctx, const struct pipe_grid_info *grid)
336 {
337 struct iris_context *ice = (struct iris_context *) ctx;
338 struct iris_batch *batch = &ice->batches[IRIS_BATCH_COMPUTE];
339
340 if (ice->state.predicate == IRIS_PREDICATE_STATE_DONT_RENDER)
341 return;
342
343 if (unlikely(INTEL_DEBUG & DEBUG_REEMIT))
344 ice->state.dirty |= IRIS_ALL_DIRTY_FOR_COMPUTE;
345
346 /* We can't do resolves on the compute engine, so awkwardly, we have to
347 * do them on the render batch...
348 */
349 if (ice->state.dirty & IRIS_DIRTY_COMPUTE_RESOLVES_AND_FLUSHES) {
350 iris_predraw_resolve_inputs(ice, &ice->batches[IRIS_BATCH_RENDER], NULL,
351 MESA_SHADER_COMPUTE, false);
352 }
353
354 iris_batch_maybe_flush(batch, 1500);
355
356 iris_update_compiled_compute_shader(ice);
357
358 if (memcmp(ice->state.last_block, grid->block, sizeof(grid->block)) != 0) {
359 memcpy(ice->state.last_block, grid->block, sizeof(grid->block));
360 ice->state.dirty |= IRIS_DIRTY_CONSTANTS_CS;
361 ice->state.shaders[MESA_SHADER_COMPUTE].sysvals_need_upload = true;
362 }
363
364 iris_update_grid_size_resource(ice, grid);
365
366 iris_binder_reserve_compute(ice);
367 batch->screen->vtbl.update_surface_base_address(batch, &ice->state.binder);
368
369 if (ice->state.compute_predicate) {
370 batch->screen->vtbl.load_register_mem64(batch, MI_PREDICATE_RESULT,
371 ice->state.compute_predicate, 0);
372 ice->state.compute_predicate = NULL;
373 }
374
375 iris_handle_always_flush_cache(batch);
376
377 batch->screen->vtbl.upload_compute_state(ice, batch, grid);
378
379 iris_handle_always_flush_cache(batch);
380
381 ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_COMPUTE;
382
383 /* Note: since compute shaders can't access the framebuffer, there's
384 * no need to call iris_postdraw_update_resolve_tracking.
385 */
386 }