diff options
author | Illia Iorin <[email protected]> | 2019-05-10 00:44:39 +0300 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2019-05-11 23:56:52 -0700 |
commit | a35269cf446bfad2261dc1e7945cd779fb42208d (patch) | |
tree | 240c6920af187e94f6a2202990211e0b04f4fbe3 /src/gallium/drivers/iris/iris_draw.c | |
parent | 21a0be4a797e39117d507b970abfa1243fef99b0 (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.c | 61 |
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); |