diff options
Diffstat (limited to 'src/gallium/drivers/ilo/ilo_draw.c')
-rw-r--r-- | src/gallium/drivers/ilo/ilo_draw.c | 280 |
1 files changed, 113 insertions, 167 deletions
diff --git a/src/gallium/drivers/ilo/ilo_draw.c b/src/gallium/drivers/ilo/ilo_draw.c index 19ea6a7d080..3d2b128804e 100644 --- a/src/gallium/drivers/ilo/ilo_draw.c +++ b/src/gallium/drivers/ilo/ilo_draw.c @@ -38,13 +38,13 @@ #include "ilo_draw.h" static void -ilo_3d_own_render_ring(struct ilo_3d *hw3d) +ilo_draw_set_owner(struct ilo_context *ilo) { - ilo_cp_set_owner(hw3d->cp, INTEL_RING_RENDER, &hw3d->owner); + ilo_cp_set_owner(ilo->cp, INTEL_RING_RENDER, &ilo->draw.cp_owner); } static uint64_t -query_timestamp_to_ns(const struct ilo_3d *hw3d, uint64_t timestamp) +query_timestamp_to_ns(const struct ilo_context *ilo, uint64_t timestamp) { /* see ilo_get_timestamp() */ return (timestamp & 0xffffffff) * 80; @@ -54,7 +54,7 @@ query_timestamp_to_ns(const struct ilo_3d *hw3d, uint64_t timestamp) * Process the bo and accumulate the result. The bo is emptied. */ static void -query_process_bo(const struct ilo_3d *hw3d, struct ilo_query *q) +query_process_bo(const struct ilo_context *ilo, struct ilo_query *q) { const uint64_t *vals; uint64_t tmp; @@ -81,14 +81,14 @@ query_process_bo(const struct ilo_3d *hw3d, struct ilo_query *q) tmp += vals[2 * i + 1] - vals[2 * i]; if (q->type == PIPE_QUERY_TIME_ELAPSED) - tmp = query_timestamp_to_ns(hw3d, tmp); + tmp = query_timestamp_to_ns(ilo, tmp); q->result.u64 += tmp; break; case PIPE_QUERY_TIMESTAMP: assert(q->stride == sizeof(*vals)); - q->result.u64 = query_timestamp_to_ns(hw3d, vals[q->used - 1]); + q->result.u64 = query_timestamp_to_ns(ilo, vals[q->used - 1]); break; case PIPE_QUERY_PIPELINE_STATISTICS: assert(q->stride == sizeof(*vals) * 22); @@ -122,19 +122,19 @@ query_process_bo(const struct ilo_3d *hw3d, struct ilo_query *q) } static void -query_begin_bo(struct ilo_3d *hw3d, struct ilo_query *q) +query_begin_bo(struct ilo_context *ilo, struct ilo_query *q) { /* bo is full */ if (q->used >= q->count) - query_process_bo(hw3d, q); + query_process_bo(ilo, q); /* write the beginning value to the bo */ if (q->in_pairs) - ilo_3d_pipeline_emit_query(hw3d->pipeline, q, q->stride * q->used); + ilo_3d_pipeline_emit_query(ilo->pipeline, q, q->stride * q->used); } static void -query_end_bo(struct ilo_3d *hw3d, struct ilo_query *q) +query_end_bo(struct ilo_context *ilo, struct ilo_query *q) { uint32_t offset; @@ -147,13 +147,12 @@ query_end_bo(struct ilo_3d *hw3d, struct ilo_query *q) q->used++; /* write the ending value to the bo */ - ilo_3d_pipeline_emit_query(hw3d->pipeline, q, offset); + ilo_3d_pipeline_emit_query(ilo->pipeline, q, offset); } bool -ilo_3d_init_query(struct pipe_context *pipe, struct ilo_query *q) +ilo_init_draw_query(struct ilo_context *ilo, struct ilo_query *q) { - struct ilo_context *ilo = ilo_context(pipe); unsigned bo_size; switch (q->type) { @@ -177,7 +176,7 @@ ilo_3d_init_query(struct pipe_context *pipe, struct ilo_query *q) break; } - q->cmd_len = ilo_3d_pipeline_estimate_size(ilo->hw3d->pipeline, + q->cmd_len = ilo_3d_pipeline_estimate_size(ilo->pipeline, ILO_3D_PIPELINE_QUERY, q); /* double cmd_len and stride if in pairs */ @@ -195,44 +194,40 @@ ilo_3d_init_query(struct pipe_context *pipe, struct ilo_query *q) } void -ilo_3d_begin_query(struct pipe_context *pipe, struct ilo_query *q) +ilo_begin_draw_query(struct ilo_context *ilo, struct ilo_query *q) { - struct ilo_3d *hw3d = ilo_context(pipe)->hw3d; - - ilo_3d_own_render_ring(hw3d); + ilo_draw_set_owner(ilo); /* need to submit first */ - if (!ilo_builder_validate(&hw3d->cp->builder, 1, &q->bo) || - ilo_cp_space(hw3d->cp) < q->cmd_len) { - ilo_cp_submit(hw3d->cp, "out of aperture or space"); + if (!ilo_builder_validate(&ilo->cp->builder, 1, &q->bo) || + ilo_cp_space(ilo->cp) < q->cmd_len) { + ilo_cp_submit(ilo->cp, "out of aperture or space"); - assert(ilo_builder_validate(&hw3d->cp->builder, 1, &q->bo)); - assert(ilo_cp_space(hw3d->cp) >= q->cmd_len); + assert(ilo_builder_validate(&ilo->cp->builder, 1, &q->bo)); + assert(ilo_cp_space(ilo->cp) >= q->cmd_len); - ilo_3d_own_render_ring(hw3d); + ilo_draw_set_owner(ilo); } /* reserve the space for ending/pausing the query */ - hw3d->owner.reserve += q->cmd_len >> q->in_pairs; + ilo->draw.cp_owner.reserve += q->cmd_len >> q->in_pairs; - query_begin_bo(hw3d, q); + query_begin_bo(ilo, q); if (q->in_pairs) - list_add(&q->list, &hw3d->queries); + list_add(&q->list, &ilo->draw.queries); } void -ilo_3d_end_query(struct pipe_context *pipe, struct ilo_query *q) +ilo_end_draw_query(struct ilo_context *ilo, struct ilo_query *q) { - struct ilo_3d *hw3d = ilo_context(pipe)->hw3d; - - ilo_3d_own_render_ring(hw3d); + ilo_draw_set_owner(ilo); /* reclaim the reserved space */ - hw3d->owner.reserve -= q->cmd_len >> q->in_pairs; - assert(hw3d->owner.reserve >= 0); + ilo->draw.cp_owner.reserve -= q->cmd_len >> q->in_pairs; + assert(ilo->draw.cp_owner.reserve >= 0); - query_end_bo(hw3d, q); + query_end_bo(ilo, q); list_delinit(&q->list); } @@ -241,39 +236,37 @@ ilo_3d_end_query(struct pipe_context *pipe, struct ilo_query *q) * Process the raw query data. */ void -ilo_3d_process_query(struct pipe_context *pipe, struct ilo_query *q) +ilo_process_draw_query(struct ilo_context *ilo, struct ilo_query *q) { - struct ilo_3d *hw3d = ilo_context(pipe)->hw3d; - - query_process_bo(hw3d, q); + query_process_bo(ilo, q); } static void -ilo_3d_own_cp(struct ilo_cp *cp, void *data) +ilo_draw_own_cp(struct ilo_cp *cp, void *data) { - struct ilo_3d *hw3d = data; + struct ilo_context *ilo = data; /* multiply by 2 for both resuming and pausing */ - if (ilo_cp_space(hw3d->cp) < hw3d->owner.reserve * 2) { - ilo_cp_submit(hw3d->cp, "out of space"); - assert(ilo_cp_space(hw3d->cp) >= hw3d->owner.reserve * 2); + if (ilo_cp_space(ilo->cp) < ilo->draw.cp_owner.reserve * 2) { + ilo_cp_submit(ilo->cp, "out of space"); + assert(ilo_cp_space(ilo->cp) >= ilo->draw.cp_owner.reserve * 2); } while (true) { struct ilo_builder_snapshot snapshot; struct ilo_query *q; - ilo_builder_batch_snapshot(&hw3d->cp->builder, &snapshot); + ilo_builder_batch_snapshot(&ilo->cp->builder, &snapshot); /* resume queries */ - LIST_FOR_EACH_ENTRY(q, &hw3d->queries, list) - query_begin_bo(hw3d, q); + LIST_FOR_EACH_ENTRY(q, &ilo->draw.queries, list) + query_begin_bo(ilo, q); - if (!ilo_builder_validate(&hw3d->cp->builder, 0, NULL)) { - ilo_builder_batch_restore(&hw3d->cp->builder, &snapshot); + if (!ilo_builder_validate(&ilo->cp->builder, 0, NULL)) { + ilo_builder_batch_restore(&ilo->cp->builder, &snapshot); - if (ilo_builder_batch_used(&hw3d->cp->builder)) { - ilo_cp_submit(hw3d->cp, "out of aperture"); + if (ilo_builder_batch_used(&ilo->cp->builder)) { + ilo_cp_submit(ilo->cp, "out of aperture"); continue; } } @@ -281,96 +274,38 @@ ilo_3d_own_cp(struct ilo_cp *cp, void *data) break; } - assert(ilo_cp_space(hw3d->cp) >= hw3d->owner.reserve); + assert(ilo_cp_space(ilo->cp) >= ilo->draw.cp_owner.reserve); } static void -ilo_3d_release_cp(struct ilo_cp *cp, void *data) +ilo_draw_release_cp(struct ilo_cp *cp, void *data) { - struct ilo_3d *hw3d = data; + struct ilo_context *ilo = data; struct ilo_query *q; - assert(ilo_cp_space(hw3d->cp) >= hw3d->owner.reserve); + assert(ilo_cp_space(ilo->cp) >= ilo->draw.cp_owner.reserve); /* pause queries */ - LIST_FOR_EACH_ENTRY(q, &hw3d->queries, list) - query_end_bo(hw3d, q); -} - -/** - * Hook for CP new-batch. - */ -void -ilo_3d_cp_submitted(struct ilo_3d *hw3d) -{ - /* invalidate the pipeline */ - ilo_3d_pipeline_invalidate(hw3d->pipeline, - ILO_3D_PIPELINE_INVALIDATE_BATCH_BO | - ILO_3D_PIPELINE_INVALIDATE_STATE_BO | - ILO_3D_PIPELINE_INVALIDATE_KERNEL_BO); - - hw3d->new_batch = true; -} - -/** - * Create a 3D context. - */ -struct ilo_3d * -ilo_3d_create(struct ilo_cp *cp, const struct ilo_dev_info *dev) -{ - struct ilo_3d *hw3d; - - hw3d = CALLOC_STRUCT(ilo_3d); - if (!hw3d) - return NULL; - - hw3d->cp = cp; - hw3d->owner.own = ilo_3d_own_cp; - hw3d->owner.release = ilo_3d_release_cp; - hw3d->owner.data = hw3d; - hw3d->owner.reserve = 0; - - hw3d->new_batch = true; - - list_inithead(&hw3d->queries); - - hw3d->pipeline = ilo_3d_pipeline_create(&cp->builder); - if (!hw3d->pipeline) { - FREE(hw3d); - return NULL; - } - - return hw3d; -} - -/** - * Destroy a 3D context. - */ -void -ilo_3d_destroy(struct ilo_3d *hw3d) -{ - ilo_3d_pipeline_destroy(hw3d->pipeline); - FREE(hw3d); + LIST_FOR_EACH_ENTRY(q, &ilo->draw.queries, list) + query_end_bo(ilo, q); } static bool -draw_vbo(struct ilo_3d *hw3d, const struct ilo_state_vector *vec) +draw_vbo(struct ilo_context *ilo, const struct ilo_state_vector *vec) { bool need_flush = false; bool success = true; int max_len, before_space; /* on GEN7+, we need SOL_RESET to reset the SO write offsets */ - if (ilo_dev_gen(hw3d->pipeline->dev) >= ILO_GEN(7) && + if (ilo_dev_gen(ilo->dev) >= ILO_GEN(7) && (vec->dirty & ILO_DIRTY_SO) && vec->so.enabled && !vec->so.append_bitmask) { - ilo_cp_submit(hw3d->cp, "SOL_RESET"); - ilo_cp_set_one_off_flags(hw3d->cp, INTEL_EXEC_GEN7_SOL_RESET); + ilo_cp_submit(ilo->cp, "SOL_RESET"); + ilo_cp_set_one_off_flags(ilo->cp, INTEL_EXEC_GEN7_SOL_RESET); } - ilo_3d_own_render_ring(hw3d); - - if (!hw3d->new_batch) { + if (ilo_builder_batch_used(&ilo->cp->builder)) { /* * Without a better tracking mechanism, when the framebuffer changes, we * have to assume that the old framebuffer may be sampled from. If that @@ -383,39 +318,41 @@ draw_vbo(struct ilo_3d *hw3d, const struct ilo_state_vector *vec) need_flush |= (vec->dirty & ILO_DIRTY_SO); } + ilo_draw_set_owner(ilo); + /* make sure there is enough room first */ - max_len = ilo_3d_pipeline_estimate_size(hw3d->pipeline, + max_len = ilo_3d_pipeline_estimate_size(ilo->pipeline, ILO_3D_PIPELINE_DRAW, vec); if (need_flush) { - max_len += ilo_3d_pipeline_estimate_size(hw3d->pipeline, + max_len += ilo_3d_pipeline_estimate_size(ilo->pipeline, ILO_3D_PIPELINE_FLUSH, NULL); } - if (max_len > ilo_cp_space(hw3d->cp)) { - ilo_cp_submit(hw3d->cp, "out of space"); + if (max_len > ilo_cp_space(ilo->cp)) { + ilo_cp_submit(ilo->cp, "out of space"); need_flush = false; - assert(max_len <= ilo_cp_space(hw3d->cp)); + assert(max_len <= ilo_cp_space(ilo->cp)); } /* space available before emission */ - before_space = ilo_cp_space(hw3d->cp); + before_space = ilo_cp_space(ilo->cp); if (need_flush) - ilo_3d_pipeline_emit_flush(hw3d->pipeline); + ilo_3d_pipeline_emit_flush(ilo->pipeline); while (true) { struct ilo_builder_snapshot snapshot; - ilo_builder_batch_snapshot(&hw3d->cp->builder, &snapshot); + ilo_builder_batch_snapshot(&ilo->cp->builder, &snapshot); - ilo_3d_pipeline_emit_draw(hw3d->pipeline, vec); + ilo_3d_pipeline_emit_draw(ilo->pipeline, vec); - if (!ilo_builder_validate(&hw3d->cp->builder, 0, NULL)) { - ilo_builder_batch_restore(&hw3d->cp->builder, &snapshot); + if (!ilo_builder_validate(&ilo->cp->builder, 0, NULL)) { + ilo_builder_batch_restore(&ilo->cp->builder, &snapshot); /* flush and try again */ - if (ilo_builder_batch_used(&hw3d->cp->builder)) { - ilo_cp_submit(hw3d->cp, "out of aperture"); + if (ilo_builder_batch_used(&ilo->cp->builder)) { + ilo_cp_submit(ilo->cp, "out of aperture"); continue; } @@ -425,32 +362,36 @@ draw_vbo(struct ilo_3d *hw3d, const struct ilo_state_vector *vec) break; } - hw3d->pipeline->invalidate_flags = 0x0; + ilo->pipeline->invalidate_flags = 0x0; /* sanity check size estimation */ - assert(before_space - ilo_cp_space(hw3d->cp) <= max_len); + assert(before_space - ilo_cp_space(ilo->cp) <= max_len); return success; } void -ilo_3d_draw_rectlist(struct ilo_3d *hw3d, const struct ilo_blitter *blitter) +ilo_draw_rectlist(struct ilo_context *ilo) { int max_len, before_space; + bool need_flush; + + need_flush = ilo_builder_batch_used(&ilo->cp->builder); - ilo_3d_own_render_ring(hw3d); + ilo_draw_set_owner(ilo); - max_len = ilo_3d_pipeline_estimate_size(hw3d->pipeline, - ILO_3D_PIPELINE_RECTLIST, blitter); - max_len += ilo_3d_pipeline_estimate_size(hw3d->pipeline, + max_len = ilo_3d_pipeline_estimate_size(ilo->pipeline, + ILO_3D_PIPELINE_RECTLIST, ilo->blitter); + max_len += ilo_3d_pipeline_estimate_size(ilo->pipeline, ILO_3D_PIPELINE_FLUSH, NULL) * 2; - if (max_len > ilo_cp_space(hw3d->cp)) { - ilo_cp_submit(hw3d->cp, "out of space"); - assert(max_len <= ilo_cp_space(hw3d->cp)); + if (max_len > ilo_cp_space(ilo->cp)) { + ilo_cp_submit(ilo->cp, "out of space"); + need_flush = false; + assert(max_len <= ilo_cp_space(ilo->cp)); } - before_space = ilo_cp_space(hw3d->cp); + before_space = ilo_cp_space(ilo->cp); /* * From the Sandy Bridge PRM, volume 2 part 1, page 313: @@ -474,22 +415,22 @@ ilo_3d_draw_rectlist(struct ilo_3d *hw3d, const struct ilo_blitter *blitter) * * Skip checking blitter->op and do the flushes. */ - if (!hw3d->new_batch) - ilo_3d_pipeline_emit_flush(hw3d->pipeline); + if (need_flush) + ilo_3d_pipeline_emit_flush(ilo->pipeline); while (true) { struct ilo_builder_snapshot snapshot; - ilo_builder_batch_snapshot(&hw3d->cp->builder, &snapshot); + ilo_builder_batch_snapshot(&ilo->cp->builder, &snapshot); - ilo_3d_pipeline_emit_rectlist(hw3d->pipeline, blitter); + ilo_3d_pipeline_emit_rectlist(ilo->pipeline, ilo->blitter); - if (!ilo_builder_validate(&hw3d->cp->builder, 0, NULL)) { - ilo_builder_batch_restore(&hw3d->cp->builder, &snapshot); + if (!ilo_builder_validate(&ilo->cp->builder, 0, NULL)) { + ilo_builder_batch_restore(&ilo->cp->builder, &snapshot); /* flush and try again */ - if (ilo_builder_batch_used(&hw3d->cp->builder)) { - ilo_cp_submit(hw3d->cp, "out of aperture"); + if (ilo_builder_batch_used(&ilo->cp->builder)) { + ilo_cp_submit(ilo->cp, "out of aperture"); continue; } } @@ -497,14 +438,12 @@ ilo_3d_draw_rectlist(struct ilo_3d *hw3d, const struct ilo_blitter *blitter) break; } - ilo_3d_pipeline_invalidate(hw3d->pipeline, ILO_3D_PIPELINE_INVALIDATE_HW); + ilo_3d_pipeline_invalidate(ilo->pipeline, ILO_3D_PIPELINE_INVALIDATE_HW); - ilo_3d_pipeline_emit_flush(hw3d->pipeline); + ilo_3d_pipeline_emit_flush(ilo->pipeline); /* sanity check size estimation */ - assert(before_space - ilo_cp_space(hw3d->cp) <= max_len); - - hw3d->new_batch = false; + assert(before_space - ilo_cp_space(ilo->cp) <= max_len); } static void @@ -612,7 +551,6 @@ static void ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) { struct ilo_context *ilo = ilo_context(pipe); - struct ilo_3d *hw3d = ilo->hw3d; if (ilo_debug & ILO_DEBUG_DRAW) { if (info->indexed) { @@ -640,39 +578,37 @@ ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) ilo_finalize_3d_states(ilo, info); - ilo_shader_cache_upload(ilo->shader_cache, &hw3d->cp->builder); + ilo_shader_cache_upload(ilo->shader_cache, &ilo->cp->builder); ilo_blit_resolve_framebuffer(ilo); /* If draw_vbo ever fails, return immediately. */ - if (!draw_vbo(hw3d, &ilo->state_vector)) + if (!draw_vbo(ilo, &ilo->state_vector)) return; /* clear dirty status */ ilo->state_vector.dirty = 0x0; - hw3d->new_batch = false; /* avoid dangling pointer reference */ ilo->state_vector.draw = NULL; if (ilo_debug & ILO_DEBUG_NOCACHE) - ilo_3d_pipeline_emit_flush(hw3d->pipeline); + ilo_3d_pipeline_emit_flush(ilo->pipeline); } static void ilo_texture_barrier(struct pipe_context *pipe) { struct ilo_context *ilo = ilo_context(pipe); - struct ilo_3d *hw3d = ilo->hw3d; if (ilo->cp->ring != INTEL_RING_RENDER) return; - ilo_3d_pipeline_emit_flush(hw3d->pipeline); + ilo_3d_pipeline_emit_flush(ilo->pipeline); /* don't know why */ if (ilo_dev_gen(ilo->dev) >= ILO_GEN(7)) - ilo_cp_submit(hw3d->cp, "texture barrier"); + ilo_cp_submit(ilo->cp, "texture barrier"); } static void @@ -682,18 +618,28 @@ ilo_get_sample_position(struct pipe_context *pipe, float *out_value) { struct ilo_context *ilo = ilo_context(pipe); - struct ilo_3d *hw3d = ilo->hw3d; - ilo_3d_pipeline_get_sample_position(hw3d->pipeline, + ilo_3d_pipeline_get_sample_position(ilo->pipeline, sample_count, sample_index, &out_value[0], &out_value[1]); } +void +ilo_init_draw(struct ilo_context *ilo) +{ + ilo->draw.cp_owner.own = ilo_draw_own_cp; + ilo->draw.cp_owner.release = ilo_draw_release_cp; + ilo->draw.cp_owner.data = (void *) ilo; + ilo->draw.cp_owner.reserve = 0; + + list_inithead(&ilo->draw.queries); +} + /** * Initialize 3D-related functions. */ void -ilo_init_3d_functions(struct ilo_context *ilo) +ilo_init_draw_functions(struct ilo_context *ilo) { ilo->base.draw_vbo = ilo_draw_vbo; ilo->base.texture_barrier = ilo_texture_barrier; |