From: Kenneth Graunke Date: Wed, 5 Dec 2018 00:38:14 +0000 (-0800) Subject: iris: rewrite set_vertex_buffer and VB handling X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2f5d85661fc413cff3fa5652183018187e73e7ed;p=mesa.git iris: rewrite set_vertex_buffer and VB handling I was using the Gallium API wrong. set_* functions with start_slot and count parameters are supposed to update a subrange of the items. I had been trashing all bound vertex buffers and starting over. This should hopefully also make it easier to slot in additional VERTEX_BUFFER_STATEs at draw time, say, for shader draw parameters. --- diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index 1eedd5d7100..d3ccc920eb1 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -454,6 +454,9 @@ struct iris_context { float default_outer_level[4]; float default_inner_level[2]; + /** Bitfield of which vertex buffers are bound (non-null). */ + uint64_t bound_vertex_buffers; + bool primitive_restart; unsigned cut_index; enum pipe_prim_type prim_mode:8; diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index d41cb7490b4..540f0dfa96d 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -740,14 +740,11 @@ iris_init_compute_context(struct iris_screen *screen, } struct iris_vertex_buffer_state { - /** The 3DSTATE_VERTEX_BUFFERS hardware packet. */ - uint32_t vertex_buffers[1 + 33 * GENX(VERTEX_BUFFER_STATE_length)]; + /** The VERTEX_BUFFER_STATE hardware structure. */ + uint32_t state[GENX(VERTEX_BUFFER_STATE_length)]; /** The resource to source vertex data from. */ - struct pipe_resource *resources[33]; - - /** The number of bound vertex buffers. */ - unsigned num_buffers; + struct pipe_resource *resource; }; struct iris_depth_buffer_state { @@ -765,7 +762,11 @@ struct iris_depth_buffer_state { * packets which vary by generation. */ struct iris_genx_state { - struct iris_vertex_buffer_state vertex_buffers; + struct iris_vertex_buffer_state vertex_buffers[33]; + + /** The number of bound vertex buffers. */ + uint64_t bound_vertex_buffers; + struct iris_depth_buffer_state depth_buffer; uint32_t so_buffers[4 * GENX(3DSTATE_SO_BUFFER_length)]; @@ -2335,13 +2336,6 @@ iris_delete_state(struct pipe_context *ctx, void *state) free(state); } -static void -iris_free_vertex_buffers(struct iris_vertex_buffer_state *cso) -{ - for (unsigned i = 0; i < cso->num_buffers; i++) - pipe_resource_reference(&cso->resources[i], NULL); -} - /** * The pipe->set_vertex_buffers() driver hook. * @@ -2353,53 +2347,43 @@ iris_set_vertex_buffers(struct pipe_context *ctx, const struct pipe_vertex_buffer *buffers) { struct iris_context *ice = (struct iris_context *) ctx; - struct iris_vertex_buffer_state *cso = &ice->state.genx->vertex_buffers; - - iris_free_vertex_buffers(&ice->state.genx->vertex_buffers); - - if (!buffers) - count = 0; - - cso->num_buffers = count; + struct iris_genx_state *genx = ice->state.genx; - iris_pack_command(GENX(3DSTATE_VERTEX_BUFFERS), cso->vertex_buffers, vb) { - vb.DWordLength = 4 * MAX2(cso->num_buffers, 1) - 1; - } + ice->state.bound_vertex_buffers &= ~u_bit_consecutive64(start_slot, count); - uint32_t *vb_pack_dest = &cso->vertex_buffers[1]; + for (unsigned i = 0; i < count; i++) { + const struct pipe_vertex_buffer *buffer = buffers ? &buffers[i] : NULL; + struct iris_vertex_buffer_state *state = + &genx->vertex_buffers[start_slot + i]; - if (count == 0) { - iris_pack_state(GENX(VERTEX_BUFFER_STATE), vb_pack_dest, vb) { - vb.VertexBufferIndex = start_slot; - vb.NullVertexBuffer = true; - vb.AddressModifyEnable = true; + if (!buffer) { + pipe_resource_reference(&state->resource, NULL); + continue; } - } - for (unsigned i = 0; i < count; i++) { - assert(!buffers[i].is_user_buffer); + assert(!buffer->is_user_buffer); - pipe_resource_reference(&cso->resources[i], buffers[i].buffer.resource); - struct iris_resource *res = (void *) cso->resources[i]; + ice->state.bound_vertex_buffers |= 1ull << (start_slot + i); + + pipe_resource_reference(&state->resource, buffer->buffer.resource); + struct iris_resource *res = (void *) state->resource; if (res) res->bind_history |= PIPE_BIND_VERTEX_BUFFER; - iris_pack_state(GENX(VERTEX_BUFFER_STATE), vb_pack_dest, vb) { + iris_pack_state(GENX(VERTEX_BUFFER_STATE), state->state, vb) { vb.VertexBufferIndex = start_slot + i; vb.MOCS = MOCS_WB; vb.AddressModifyEnable = true; - vb.BufferPitch = buffers[i].stride; + vb.BufferPitch = buffer->stride; if (res) { vb.BufferSize = res->bo->size; vb.BufferStartingAddress = - ro_bo(NULL, res->bo->gtt_offset + buffers[i].buffer_offset); + ro_bo(NULL, res->bo->gtt_offset + buffer->buffer_offset); } else { vb.NullVertexBuffer = true; } } - - vb_pack_dest += GENX(VERTEX_BUFFER_STATE_length); } ice->state.dirty |= IRIS_DIRTY_VERTEX_BUFFERS; @@ -3739,6 +3723,8 @@ iris_restore_render_saved_bos(struct iris_context *ice, struct iris_batch *batch, const struct pipe_draw_info *draw) { + struct iris_genx_state *genx = ice->state.genx; + // XXX: whack IRIS_SHADER_DIRTY_BINDING_TABLE on new batch const uint64_t clean = ~ice->state.dirty; @@ -3854,10 +3840,11 @@ iris_restore_render_saved_bos(struct iris_context *ice, } if (clean & IRIS_DIRTY_VERTEX_BUFFERS) { - struct iris_vertex_buffer_state *cso = &ice->state.genx->vertex_buffers; - for (unsigned i = 0; i < cso->num_buffers; i++) { - struct iris_resource *res = (void *) cso->resources[i]; - iris_use_pinned_bo(batch, res->bo, false); + uint64_t bound = ice->state.bound_vertex_buffers; + while (bound) { + const int i = u_bit_scan64(&bound); + struct pipe_resource *res = genx->vertex_buffers[i].resource; + iris_use_pinned_bo(batch, iris_resource_bo(res), false); } } } @@ -4416,10 +4403,9 @@ iris_upload_dirty_render_state(struct iris_context *ice, } if (dirty & IRIS_DIRTY_VERTEX_BUFFERS) { - struct iris_vertex_buffer_state *cso = &ice->state.genx->vertex_buffers; - const unsigned vb_dwords = GENX(VERTEX_BUFFER_STATE_length); + int count = util_bitcount64(ice->state.bound_vertex_buffers); - if (cso->num_buffers > 0) { + if (count) { /* The VF cache designers cut corners, and made the cache key's * tuple only consider the bottom * 32 bits of the address. If you have two vertex buffers which get @@ -4431,10 +4417,13 @@ iris_upload_dirty_render_state(struct iris_context *ice, */ unsigned flush_flags = 0; - for (unsigned i = 0; i < cso->num_buffers; i++) { + uint64_t bound = ice->state.bound_vertex_buffers; + while (bound) { + const int i = u_bit_scan64(&bound); uint16_t high_bits = 0; - struct iris_resource *res = (void *) cso->resources[i]; + struct iris_resource *res = + (void *) genx->vertex_buffers[i].resource; if (res) { iris_use_pinned_bo(batch, res->bo, false); @@ -4458,8 +4447,22 @@ iris_upload_dirty_render_state(struct iris_context *ice, if (flush_flags) iris_emit_pipe_control_flush(batch, flush_flags); - iris_batch_emit(batch, cso->vertex_buffers, sizeof(uint32_t) * - (1 + vb_dwords * cso->num_buffers)); + const unsigned vb_dwords = GENX(VERTEX_BUFFER_STATE_length); + + uint32_t *map = + iris_get_command_space(batch, 4 * (1 + vb_dwords * count)); + _iris_pack_command(batch, GENX(3DSTATE_VERTEX_BUFFERS), map, vb) { + vb.DWordLength = (vb_dwords * count + 1) - 2; + } + map += 1; + + bound = ice->state.bound_vertex_buffers; + while (bound) { + const int i = u_bit_scan64(&bound); + memcpy(map, genx->vertex_buffers[i].state, + sizeof(uint32_t) * vb_dwords); + map += vb_dwords; + } } } @@ -4798,7 +4801,13 @@ iris_upload_compute_state(struct iris_context *ice, static void iris_destroy_state(struct iris_context *ice) { - iris_free_vertex_buffers(&ice->state.genx->vertex_buffers); + struct iris_genx_state *genx = ice->state.genx; + + uint64_t bound_vbs = ice->state.bound_vertex_buffers; + while (bound_vbs) { + const int i = u_bit_scan64(&bound_vbs); + pipe_resource_reference(&genx->vertex_buffers[i].resource, NULL); + } // XXX: unreference resources/surfaces. for (unsigned i = 0; i < ice->state.framebuffer.nr_cbufs; i++) {