diff options
author | Chia-I Wu <[email protected]> | 2013-06-26 13:44:27 +0800 |
---|---|---|
committer | Chia-I Wu <[email protected]> | 2013-06-26 16:42:46 +0800 |
commit | 95c21f12f321bb33ae8e1f1b255680ac8eeffade (patch) | |
tree | be15c847df41f9b7b82c7ad18c2891b0b7c0bb12 /src/gallium/drivers/ilo/ilo_state.c | |
parent | 5fb5d4f0a6208e720998bbdbfe83df1035957f4a (diff) |
ilo: support PIPE_CAP_USER_INDEX_BUFFERS
We want to access the user buffer, if available, when primitive restart is
enabled and the restart index/primitive type is not natively supported.
And since we are handling index buffer uploads in the driver with this change,
we can also work around misalignment of index buffer offsets.
Diffstat (limited to 'src/gallium/drivers/ilo/ilo_state.c')
-rw-r--r-- | src/gallium/drivers/ilo/ilo_state.c | 62 |
1 files changed, 55 insertions, 7 deletions
diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c index 0e4e937879f..ede72623f17 100644 --- a/src/gallium/drivers/ilo/ilo_state.c +++ b/src/gallium/drivers/ilo/ilo_state.c @@ -126,6 +126,44 @@ finalize_constant_buffers(struct ilo_context *ilo) } } +static void +finalize_index_buffer(struct ilo_context *ilo) +{ + struct pipe_resource *res; + unsigned offset, size; + bool uploaded = false; + + if (!ilo->draw->indexed) + return; + + res = ilo->ib.resource; + offset = ilo->ib.state.index_size * ilo->draw->start; + size = ilo->ib.state.index_size * ilo->draw->count; + + if (ilo->ib.state.user_buffer) { + u_upload_data(ilo->uploader, 0, size, + ilo->ib.state.user_buffer + offset, &offset, &res); + uploaded = true; + } + else if (unlikely(ilo->ib.state.offset % ilo->ib.state.index_size)) { + u_upload_buffer(ilo->uploader, 0, ilo->ib.state.offset + offset, size, + ilo->ib.state.buffer, &offset, &res); + uploaded = true; + } + + if (uploaded) { + ilo->ib.resource = res; + + assert(offset % ilo->ib.state.index_size == 0); + ilo->ib.draw_start_offset = offset / ilo->ib.state.index_size; + + /* could be negative */ + ilo->ib.draw_start_offset -= ilo->draw->start; + + ilo->dirty |= ILO_DIRTY_INDEX_BUFFER; + } +} + /** * Finalize states. Some states depend on other states and are * incomplete/invalid until finalized. @@ -138,6 +176,7 @@ ilo_finalize_3d_states(struct ilo_context *ilo, finalize_shader_states(ilo); finalize_constant_buffers(ilo); + finalize_index_buffer(ilo); u_upload_unmap(ilo->uploader); } @@ -818,19 +857,28 @@ ilo_set_index_buffer(struct pipe_context *pipe, struct ilo_context *ilo = ilo_context(pipe); if (state) { - /* no PIPE_CAP_USER_INDEX_BUFFERS */ - assert(!state->user_buffer); - - ilo->ib.state.index_size = state->index_size; - ilo->ib.state.offset = state->offset; pipe_resource_reference(&ilo->ib.state.buffer, state->buffer); + ilo->ib.state.offset = state->offset; + ilo->ib.state.index_size = state->index_size; + + /* state->offset does not apply for user buffer */ ilo->ib.state.user_buffer = state->user_buffer; + + /* + * when there is no state->buffer or state->offset is misaligned, + * ilo_finalize_3d_states() will set these to the valid values + */ + pipe_resource_reference(&ilo->ib.resource, state->buffer); + ilo->ib.draw_start_offset = state->offset / state->index_size; } else { - ilo->ib.state.index_size = 0; - ilo->ib.state.offset = 0; pipe_resource_reference(&ilo->ib.state.buffer, NULL); + ilo->ib.state.offset = 0; + ilo->ib.state.index_size = 0; ilo->ib.state.user_buffer = NULL; + + pipe_resource_reference(&ilo->ib.resource, NULL); + ilo->ib.draw_start_offset = 0; } ilo->dirty |= ILO_DIRTY_INDEX_BUFFER; |