summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/iris/iris_draw.c
diff options
context:
space:
mode:
authorIllia Iorin <[email protected]>2019-05-10 00:44:39 +0300
committerKenneth Graunke <[email protected]>2019-05-11 23:56:52 -0700
commita35269cf446bfad2261dc1e7945cd779fb42208d (patch)
tree240c6920af187e94f6a2202990211e0b04f4fbe3 /src/gallium/drivers/iris/iris_draw.c
parent21a0be4a797e39117d507b970abfa1243fef99b0 (diff)
iris: Implement ARB_indirect_parameters
iris_draw_vbo is divided into two functions to remove unnecessary operations from the loop. This implementation of ARB_indirect_parameters takes into account NV_conditional_render by saving MI_PREDICATE_RESULT at the start of a draw call and restoring it at the end also the result of NV_conditional_render is taken into account when computing predicates that limit draw calls for ARB_indirect_parameters in a similar way to 1952fd8d in ANV. v2: Optimize indirect draws (suggested by Kenneth Graunke) v3: (by Kenneth Graunke) - Fix an issue where indirect draws wouldn't set patch information before updating the compiled TCS. - Move some code back to iris_draw_vbo to avoid duplicating it. - Fix minor indentation issues. Signed-off-by: Illia Iorin <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/gallium/drivers/iris/iris_draw.c')
-rw-r--r--src/gallium/drivers/iris/iris_draw.c61
1 files changed, 57 insertions, 4 deletions
diff --git a/src/gallium/drivers/iris/iris_draw.c b/src/gallium/drivers/iris/iris_draw.c
index 87399c430ee..17e4eab67d8 100644
--- a/src/gallium/drivers/iris/iris_draw.c
+++ b/src/gallium/drivers/iris/iris_draw.c
@@ -141,6 +141,58 @@ iris_update_draw_parameters(struct iris_context *ice,
}
}
+static void
+iris_indirect_draw_vbo(struct iris_context *ice,
+ const struct pipe_draw_info *dinfo)
+{
+ struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
+ struct pipe_draw_info info = *dinfo;
+
+ if (info.indirect->indirect_draw_count &&
+ ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT) {
+ /* Upload MI_PREDICATE_RESULT to GPR2.*/
+ ice->vtbl.load_register_reg64(batch, CS_GPR(2), MI_PREDICATE_RESULT);
+ }
+
+ uint64_t orig_dirty = ice->state.dirty;
+
+ for (int i = 0; i < info.indirect->draw_count; i++) {
+ info.drawid = i;
+
+ iris_batch_maybe_flush(batch, 1500);
+
+ iris_update_draw_parameters(ice, &info);
+
+ ice->vtbl.upload_render_state(ice, batch, &info);
+
+ ice->state.dirty &= ~IRIS_ALL_DIRTY_FOR_RENDER;
+
+ info.indirect->offset += info.indirect->stride;
+ }
+
+ if (info.indirect->indirect_draw_count &&
+ ice->state.predicate == IRIS_PREDICATE_STATE_USE_BIT) {
+ /* Restore MI_PREDICATE_RESULT. */
+ ice->vtbl.load_register_reg64(batch, MI_PREDICATE_RESULT, CS_GPR(2));
+ }
+
+ /* Put this back for post-draw resolves, we'll clear it again after. */
+ ice->state.dirty = orig_dirty;
+}
+
+static void
+iris_simple_draw_vbo(struct iris_context *ice,
+ const struct pipe_draw_info *draw)
+{
+ struct iris_batch *batch = &ice->batches[IRIS_BATCH_RENDER];
+
+ iris_batch_maybe_flush(batch, 1500);
+
+ iris_update_draw_parameters(ice, draw);
+
+ ice->vtbl.upload_render_state(ice, batch, draw);
+}
+
/**
* The pipe->draw_vbo() driver hook. Performs a draw on the GPU.
*/
@@ -161,10 +213,7 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
if (unlikely(INTEL_DEBUG & DEBUG_REEMIT))
ice->state.dirty |= IRIS_ALL_DIRTY_FOR_RENDER & ~IRIS_DIRTY_SO_BUFFERS;
- iris_batch_maybe_flush(batch, 1500);
-
iris_update_draw_info(ice, info);
- iris_update_draw_parameters(ice, dinfo);
if (devinfo->gen == 9)
gen9_toggle_preemption(ice, batch, info);
@@ -184,7 +233,11 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
iris_binder_reserve_3d(ice);
ice->vtbl.update_surface_base_address(batch, &ice->state.binder);
- ice->vtbl.upload_render_state(ice, batch, info);
+
+ if (info->indirect)
+ iris_indirect_draw_vbo(ice, info);
+ else
+ iris_simple_draw_vbo(ice, info);
iris_postdraw_update_resolve_tracking(ice, batch);