summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2013-06-13 18:22:40 +0800
committerChia-I Wu <[email protected]>2013-06-13 23:47:18 +0800
commitc7e9b15010c32302d3cceac06ff8c34619deab7c (patch)
tree39f139711c3d679e5cd1ce29cd07b46756899353
parent5f15050dc9819beb4513b9923af3b5d1600b184f (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.
-rw-r--r--src/gallium/drivers/ilo/ilo_3d.c7
-rw-r--r--src/gallium/drivers/ilo/ilo_state.c100
-rw-r--r--src/gallium/drivers/ilo/ilo_state.h5
-rw-r--r--src/gallium/drivers/ilo/ilo_transfer.c9
4 files changed, 112 insertions, 9 deletions
diff --git a/src/gallium/drivers/ilo/ilo_3d.c b/src/gallium/drivers/ilo/ilo_3d.c
index aba92a0375a..b2cbcf04e0c 100644
--- a/src/gallium/drivers/ilo/ilo_3d.c
+++ b/src/gallium/drivers/ilo/ilo_3d.c
@@ -661,13 +661,6 @@ ilo_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
ILO_3D_PIPELINE_INVALIDATE_KERNEL_BO);
}
- /*
- * The VBs and/or IB may have different BOs due to being mapped with
- * PIPE_TRANSFER_DISCARD_x. We should track that instead of setting the
- * dirty flags for the performance reason.
- */
- ilo->dirty |= ILO_DIRTY_VERTEX_BUFFERS | ILO_DIRTY_INDEX_BUFFER;
-
/* If draw_vbo ever fails, return immediately. */
if (!draw_vbo(hw3d, ilo, info, &prim_generated, &prim_emitted))
return;
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;
+}
diff --git a/src/gallium/drivers/ilo/ilo_state.h b/src/gallium/drivers/ilo/ilo_state.h
index c73e8fb835b..8a0d5e7f14d 100644
--- a/src/gallium/drivers/ilo/ilo_state.h
+++ b/src/gallium/drivers/ilo/ilo_state.h
@@ -113,6 +113,7 @@ enum ilo_dirty_flags {
ILO_DIRTY_ALL = 0xffffffff,
};
+struct pipe_resource;
struct ilo_context;
void
@@ -127,4 +128,8 @@ ilo_cleanup_states(struct ilo_context *ilo);
void
ilo_finalize_states(struct ilo_context *ilo);
+void
+ilo_mark_states_with_resource_dirty(struct ilo_context *ilo,
+ const struct pipe_resource *res);
+
#endif /* ILO_STATE_H */
diff --git a/src/gallium/drivers/ilo/ilo_transfer.c b/src/gallium/drivers/ilo/ilo_transfer.c
index dcb9ab96d8b..9f68d4ad976 100644
--- a/src/gallium/drivers/ilo/ilo_transfer.c
+++ b/src/gallium/drivers/ilo/ilo_transfer.c
@@ -32,6 +32,7 @@
#include "ilo_cp.h"
#include "ilo_context.h"
#include "ilo_resource.h"
+#include "ilo_state.h"
#include "ilo_transfer.h"
static bool
@@ -135,8 +136,10 @@ choose_transfer_method(struct ilo_context *ilo, struct ilo_transfer *xfer)
else if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
/* discard old bo and allocate a new one for mapping */
if ((tex && ilo_texture_alloc_bo(tex)) ||
- (buf && ilo_buffer_alloc_bo(buf)))
+ (buf && ilo_buffer_alloc_bo(buf))) {
+ ilo_mark_states_with_resource_dirty(ilo, res);
will_stall = false;
+ }
}
else if (usage & PIPE_TRANSFER_FLUSH_EXPLICIT) {
/*
@@ -920,8 +923,10 @@ buf_pwrite(struct ilo_context *ilo, struct ilo_buffer *buf,
if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
/* old data not needed so discard the old bo to avoid stalling */
- if (ilo_buffer_alloc_bo(buf))
+ if (ilo_buffer_alloc_bo(buf)) {
+ ilo_mark_states_with_resource_dirty(ilo, &buf->base);
will_stall = false;
+ }
}
else {
/*