diff options
author | Chia-I Wu <[email protected]> | 2013-06-13 18:22:40 +0800 |
---|---|---|
committer | Chia-I Wu <[email protected]> | 2013-06-13 23:47:18 +0800 |
commit | c7e9b15010c32302d3cceac06ff8c34619deab7c (patch) | |
tree | 39f139711c3d679e5cd1ce29cd07b46756899353 /src/gallium/drivers/ilo/ilo_state.c | |
parent | 5f15050dc9819beb4513b9923af3b5d1600b184f (diff) |
ilo: mapping a resource may make some states dirty
When a resource is busy and is mapped with
PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE, the underlying bo is replaced. We need
to mark states affected by the resource dirty.
With this change, we no longer have to emit vertex buffers and index buffer
unconditionally.
Diffstat (limited to 'src/gallium/drivers/ilo/ilo_state.c')
-rw-r--r-- | src/gallium/drivers/ilo/ilo_state.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c index 3fe19e0fba9..865bc5c7bd9 100644 --- a/src/gallium/drivers/ilo/ilo_state.c +++ b/src/gallium/drivers/ilo/ilo_state.c @@ -1156,3 +1156,103 @@ ilo_cleanup_states(struct ilo_context *ilo) for (i = 0; i < ilo->global_binding.count; i++) pipe_resource_reference(&ilo->global_binding.resources[i], NULL); } + +/** + * Mark all states that have the resource dirty. + */ +void +ilo_mark_states_with_resource_dirty(struct ilo_context *ilo, + const struct pipe_resource *res) +{ + uint32_t states = 0; + unsigned sh, i; + + if (res->target == PIPE_BUFFER) { + uint32_t vb_mask = ilo->vb.enabled_mask; + + while (vb_mask) { + const unsigned idx = u_bit_scan(&vb_mask); + + if (ilo->vb.states[idx].buffer == res) { + states |= ILO_DIRTY_VERTEX_BUFFERS; + break; + } + } + + if (ilo->ib.state.buffer == res) + states |= ILO_DIRTY_INDEX_BUFFER; + + for (i = 0; i < ilo->so.count; i++) { + if (ilo->so.states[i]->buffer == res) { + states |= ILO_DIRTY_STREAM_OUTPUT_TARGETS; + break; + } + } + } + + for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) { + for (i = 0; i < ilo->view[sh].count; i++) { + struct pipe_sampler_view *view = ilo->view[sh].states[i]; + + if (view->texture == res) { + static const unsigned view_dirty_bits[PIPE_SHADER_TYPES] = { + [PIPE_SHADER_VERTEX] = ILO_DIRTY_VERTEX_SAMPLER_VIEWS, + [PIPE_SHADER_FRAGMENT] = ILO_DIRTY_FRAGMENT_SAMPLER_VIEWS, + [PIPE_SHADER_GEOMETRY] = ILO_DIRTY_GEOMETRY_SAMPLER_VIEWS, + [PIPE_SHADER_COMPUTE] = ILO_DIRTY_COMPUTE_SAMPLER_VIEWS, + }; + + states |= view_dirty_bits[sh]; + break; + } + } + + if (res->target == PIPE_BUFFER) { + for (i = 0; i < Elements(ilo->cbuf[sh].cso); i++) { + struct ilo_cbuf_cso *cbuf = &ilo->cbuf[sh].cso[i]; + + if (cbuf->resource == res) { + states |= ILO_DIRTY_CONSTANT_BUFFER; + break; + } + } + } + } + + for (i = 0; i < ilo->resource.count; i++) { + if (ilo->resource.states[i]->texture == res) { + states |= ILO_DIRTY_SHADER_RESOURCES; + break; + } + } + + /* for now? */ + if (res->target != PIPE_BUFFER) { + for (i = 0; i < ilo->fb.state.nr_cbufs; i++) { + if (ilo->fb.state.cbufs[i]->texture == res) { + states |= ILO_DIRTY_FRAMEBUFFER; + break; + } + } + + if (ilo->fb.state.zsbuf && ilo->fb.state.zsbuf->texture == res) + states |= ILO_DIRTY_FRAMEBUFFER; + } + + for (i = 0; i < ilo->cs_resource.count; i++) { + pipe_surface_reference(&ilo->cs_resource.states[i], NULL); + if (ilo->cs_resource.states[i]->texture == res) { + states |= ILO_DIRTY_COMPUTE_RESOURCES; + break; + } + } + + for (i = 0; i < ilo->global_binding.count; i++) { + if (ilo->global_binding.resources[i] == res) { + states |= ILO_DIRTY_GLOBAL_BINDING; + break; + } + } + + ilo->dirty |= states; +} |