Am 08.08.2013 02:20, schrieb Marek Olšák:
It's the same as in r600g. Look how simple it is.

That concept has the problem that we don't necessary know in which order the state is emitted.

Why not just add an "emit" callback to si_pm4_state for the short term instead?

For the long term we should probably teach the kernel interface to accept a bunch of pointers to smaller IB fragments instead of one large IB. That would allow us to not only save the copy of commands for the CSO states, but also allows us to emit optional IB fragments that are only inserted if the we had a context switch in between.

Christian.

---
  src/gallium/drivers/radeonsi/r600_hw_context.c |  8 ++++++++
  src/gallium/drivers/radeonsi/radeonsi_pipe.h   |  9 +++++++++
  src/gallium/drivers/radeonsi/si_state.h        | 10 ++++++++++
  src/gallium/drivers/radeonsi/si_state_draw.c   |  8 +++++++-
  4 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/radeonsi/r600_hw_context.c 
b/src/gallium/drivers/radeonsi/r600_hw_context.c
index 382382b..7ed7496 100644
--- a/src/gallium/drivers/radeonsi/r600_hw_context.c
+++ b/src/gallium/drivers/radeonsi/r600_hw_context.c
@@ -114,9 +114,17 @@ err:
  void si_need_cs_space(struct r600_context *ctx, unsigned num_dw,
                        boolean count_draw_in)
  {
+       int i;
+
        /* The number of dwords we already used in the CS so far. */
        num_dw += ctx->cs->cdw;
+ for (i = 0; i < ctx->num_atoms; i++) {
+               if (ctx->atoms[i]->dirty) {
+                       num_dw += ctx->atoms[i]->num_dw;
+               }
+       }
+
        if (count_draw_in) {
                /* The number of dwords all the dirty states would take. */
                num_dw += ctx->pm4_dirty_cdwords;
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.h 
b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
index e370149..5fa9bdc 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.h
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
@@ -145,6 +145,10 @@ struct r600_context {
        void                            *custom_blend_decompress;
        struct r600_screen              *screen;
        struct radeon_winsys            *ws;
+
+       struct si_atom                  *atoms[SI_MAX_ATOMS];
+       unsigned                        num_atoms;
+
        struct si_vertex_element        *vertex_elements;
        struct pipe_framebuffer_state   framebuffer;
        unsigned                        fb_log_samples;
@@ -329,4 +333,9 @@ static INLINE uint64_t r600_resource_va(struct pipe_screen 
*screen, struct pipe_
        return rscreen->ws->buffer_get_virtual_address(rresource->cs_buf);
  }
+static INLINE void si_add_atom(struct r600_context *rctx, struct si_atom *atom)
+{
+       rctx->atoms[rctx->num_atoms++] = atom;
+}
+
  #endif
diff --git a/src/gallium/drivers/radeonsi/si_state.h 
b/src/gallium/drivers/radeonsi/si_state.h
index b01fbf2..4aabdef 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -29,6 +29,16 @@
#include "radeonsi_pm4.h" +#define SI_MAX_ATOMS 2
+
+/* This encapsulates a state or an operation which can emitted into the GPU
+ * command stream. */
+struct si_atom {
+       void (*emit)(struct r600_context *ctx, struct si_atom *state);
+       unsigned                num_dw;
+       bool                    dirty;
+};
+
  struct si_state_blend {
        struct si_pm4_state     pm4;
        uint32_t                cb_target_mask;
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c 
b/src/gallium/drivers/radeonsi/si_state_draw.c
index 4208fa7..bcae778 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -664,7 +664,7 @@ void si_draw_vbo(struct pipe_context *ctx, const struct 
pipe_draw_info *info)
  {
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct pipe_index_buffer ib = {};
-       uint32_t cp_coher_cntl;
+       uint32_t cp_coher_cntl, i;
if (!info->count && (info->indexed || !info->count_from_stream_output))
                return;
@@ -728,6 +728,12 @@ void si_draw_vbo(struct pipe_context *ctx, const struct 
pipe_draw_info *info)
si_need_cs_space(rctx, 0, TRUE); + for (i = 0; i < rctx->num_atoms; i++) {
+               if (rctx->atoms[i]->dirty) {
+                       rctx->atoms[i]->emit(rctx, rctx->atoms[i]);
+               }
+       }
+
        si_pm4_emit_dirty(rctx);
        rctx->pm4_dirty_cdwords = 0;

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to