Mesa (master): gallium: separate indirect stuff from pipe_draw_info - 80 - > 56 bytes

Marek Olšák mareko at kemper.freedesktop.org
Wed May 10 17:25:45 UTC 2017


Module: Mesa
Branch: master
Commit: 22f6624ed318e8131681ec1f2e7b3a59449df412
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=22f6624ed318e8131681ec1f2e7b3a59449df412

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Sun Apr  2 15:24:19 2017 +0200

gallium: separate indirect stuff from pipe_draw_info - 80 -> 56 bytes

For faster initialization of non-indirect draws.

---

 src/gallium/auxiliary/util/u_draw.c          |  4 +-
 src/gallium/auxiliary/util/u_dump_state.c    | 15 ++++---
 src/gallium/auxiliary/util/u_vbuf.c          |  8 ++--
 src/gallium/docs/source/screen.rst           |  2 +-
 src/gallium/drivers/ddebug/dd_draw.c         | 42 ++++++++++-------
 src/gallium/drivers/ddebug/dd_pipe.h         |  7 ++-
 src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c  | 16 +++----
 src/gallium/drivers/r600/r600_state_common.c | 12 ++---
 src/gallium/drivers/radeonsi/si_state_draw.c | 59 +++++++++++++-----------
 src/gallium/drivers/trace/tr_dump_state.c    | 12 ++++-
 src/gallium/include/pipe/p_state.h           | 67 +++++++++++++++-------------
 src/gallium/state_trackers/nine/device9.c    |  1 -
 src/gallium/state_trackers/nine/nine_state.c |  1 -
 src/mesa/state_tracker/st_draw.c             | 19 ++++----
 14 files changed, 152 insertions(+), 113 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_draw.c b/src/gallium/auxiliary/util/u_draw.c
index ca78648978..e7abbfc422 100644
--- a/src/gallium/auxiliary/util/u_draw.c
+++ b/src/gallium/auxiliary/util/u_draw.c
@@ -145,8 +145,8 @@ util_draw_indirect(struct pipe_context *pipe,
 
    params = (uint32_t *)
       pipe_buffer_map_range(pipe,
-                            info_in->indirect,
-                            info_in->indirect_offset,
+                            info_in->indirect->buffer,
+                            info_in->indirect->offset,
                             num_params * sizeof(uint32_t),
                             PIPE_TRANSFER_READ,
                             &transfer);
diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c
index b9e6b52258..5e42bdd302 100644
--- a/src/gallium/auxiliary/util/u_dump_state.c
+++ b/src/gallium/auxiliary/util/u_dump_state.c
@@ -941,11 +941,16 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
 
    util_dump_member(stream, ptr, state, count_from_stream_output);
 
-   util_dump_member(stream, ptr, state, indirect);
-   util_dump_member(stream, uint, state, indirect_offset);
-   util_dump_member(stream, uint, state, indirect_stride);
-   util_dump_member(stream, uint, state, indirect_count);
-   util_dump_member(stream, uint, state, indirect_params_offset);
+   if (!state->indirect) {
+      util_dump_member(stream, ptr, state, indirect);
+   } else {
+      util_dump_member(stream, uint, state, indirect->offset);
+      util_dump_member(stream, uint, state, indirect->stride);
+      util_dump_member(stream, uint, state, indirect->draw_count);
+      util_dump_member(stream, uint, state, indirect->indirect_draw_count_offset);
+      util_dump_member(stream, ptr, state, indirect->buffer);
+      util_dump_member(stream, ptr, state, indirect->indirect_draw_count);
+   }
 
    util_dump_struct_end(stream);
 }
diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c
index 62b88acca5..9d6d5297e6 100644
--- a/src/gallium/auxiliary/util/u_vbuf.c
+++ b/src/gallium/auxiliary/util/u_vbuf.c
@@ -1168,15 +1168,15 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
       int *data;
 
       if (new_info.indexed) {
-         data = pipe_buffer_map_range(pipe, new_info.indirect,
-                                      new_info.indirect_offset, 20,
+         data = pipe_buffer_map_range(pipe, new_info.indirect->buffer,
+                                      new_info.indirect->offset, 20,
                                       PIPE_TRANSFER_READ, &transfer);
          new_info.index_bias = data[3];
          new_info.start_instance = data[4];
       }
       else {
-         data = pipe_buffer_map_range(pipe, new_info.indirect,
-                                      new_info.indirect_offset, 16,
+         data = pipe_buffer_map_range(pipe, new_info.indirect->buffer,
+                                      new_info.indirect->offset, 16,
                                       PIPE_TRANSFER_READ, &transfer);
          new_info.start_instance = data[3];
       }
diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
index de9de05b40..03a37f0bd2 100644
--- a/src/gallium/docs/source/screen.rst
+++ b/src/gallium/docs/source/screen.rst
@@ -217,7 +217,7 @@ The integer capabilities:
   pipe_draw_info::indirect_stride and ::indirect_count
 * ``PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS``: Whether the driver supports
   taking the number of indirect draws from a separate parameter
-  buffer, see pipe_draw_info::indirect_params.
+  buffer, see pipe_draw_indirect_info::indirect_draw_count.
 * ``PIPE_CAP_TGSI_FS_FINE_DERIVATIVE``: Whether the fragment shader supports
   the FINE versions of DDX/DDY.
 * ``PIPE_CAP_VENDOR_ID``: The vendor ID of the underlying hardware. If it's
diff --git a/src/gallium/drivers/ddebug/dd_draw.c b/src/gallium/drivers/ddebug/dd_draw.c
index 90ccf160e6..4b14516fb2 100644
--- a/src/gallium/drivers/ddebug/dd_draw.c
+++ b/src/gallium/drivers/ddebug/dd_draw.c
@@ -297,10 +297,12 @@ dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info, FILE
    if (info->count_from_stream_output)
       DUMP_M(stream_output_target, info,
              count_from_stream_output);
-   if (info->indirect)
-      DUMP_M(resource, info, indirect);
-   if (info->indirect_params)
-      DUMP_M(resource, info, indirect_params);
+   if (info->indirect) {
+      DUMP_M(resource, info, indirect->buffer);
+      if (info->indirect->indirect_draw_count)
+         DUMP_M(resource, info, indirect->indirect_draw_count);
+   }
+
    fprintf(f, "\n");
 
    /* TODO: dump active queries */
@@ -500,7 +502,7 @@ dd_dump_call(FILE *f, struct dd_draw_state *state, struct dd_call *call)
 {
    switch (call->type) {
    case CALL_DRAW_VBO:
-      dd_dump_draw_vbo(state, &call->info.draw_vbo, f);
+      dd_dump_draw_vbo(state, &call->info.draw_vbo.draw, f);
       break;
    case CALL_LAUNCH_GRID:
       dd_dump_launch_grid(state, &call->info.launch_grid, f);
@@ -619,9 +621,9 @@ dd_unreference_copy_of_call(struct dd_call *dst)
 {
    switch (dst->type) {
    case CALL_DRAW_VBO:
-      pipe_so_target_reference(&dst->info.draw_vbo.count_from_stream_output, NULL);
-      pipe_resource_reference(&dst->info.draw_vbo.indirect, NULL);
-      pipe_resource_reference(&dst->info.draw_vbo.indirect_params, NULL);
+      pipe_so_target_reference(&dst->info.draw_vbo.draw.count_from_stream_output, NULL);
+      pipe_resource_reference(&dst->info.draw_vbo.indirect.buffer, NULL);
+      pipe_resource_reference(&dst->info.draw_vbo.indirect.indirect_draw_count, NULL);
       break;
    case CALL_LAUNCH_GRID:
       pipe_resource_reference(&dst->info.launch_grid.indirect, NULL);
@@ -661,13 +663,17 @@ dd_copy_call(struct dd_call *dst, struct dd_call *src)
 
    switch (src->type) {
    case CALL_DRAW_VBO:
-      pipe_so_target_reference(&dst->info.draw_vbo.count_from_stream_output,
-                               src->info.draw_vbo.count_from_stream_output);
-      pipe_resource_reference(&dst->info.draw_vbo.indirect,
-                              src->info.draw_vbo.indirect);
-      pipe_resource_reference(&dst->info.draw_vbo.indirect_params,
-                              src->info.draw_vbo.indirect_params);
+      pipe_so_target_reference(&dst->info.draw_vbo.draw.count_from_stream_output,
+                               src->info.draw_vbo.draw.count_from_stream_output);
+      pipe_resource_reference(&dst->info.draw_vbo.indirect.buffer,
+                              src->info.draw_vbo.indirect.buffer);
+      pipe_resource_reference(&dst->info.draw_vbo.indirect.indirect_draw_count,
+                              src->info.draw_vbo.indirect.indirect_draw_count);
       dst->info.draw_vbo = src->info.draw_vbo;
+      if (!src->info.draw_vbo.draw.indirect)
+         dst->info.draw_vbo.draw.indirect = NULL;
+      else
+         dst->info.draw_vbo.draw.indirect = &dst->info.draw_vbo.indirect;
       break;
    case CALL_LAUNCH_GRID:
       pipe_resource_reference(&dst->info.launch_grid.indirect,
@@ -1173,7 +1179,13 @@ dd_context_draw_vbo(struct pipe_context *_pipe,
    struct dd_call call;
 
    call.type = CALL_DRAW_VBO;
-   call.info.draw_vbo = *info;
+   call.info.draw_vbo.draw = *info;
+   if (info->indirect) {
+      call.info.draw_vbo.indirect = *info->indirect;
+      call.info.draw_vbo.draw.indirect = &call.info.draw_vbo.indirect;
+   } else {
+      memset(&call.info.draw_vbo.indirect, 0, sizeof(*info->indirect));
+   }
 
    dd_before_draw(dctx);
    pipe->draw_vbo(pipe, info);
diff --git a/src/gallium/drivers/ddebug/dd_pipe.h b/src/gallium/drivers/ddebug/dd_pipe.h
index deae1f5bc3..ea3319397a 100644
--- a/src/gallium/drivers/ddebug/dd_pipe.h
+++ b/src/gallium/drivers/ddebug/dd_pipe.h
@@ -104,12 +104,17 @@ struct call_generate_mipmap {
    unsigned last_layer;
 };
 
+struct call_draw_info {
+   struct pipe_draw_info draw;
+   struct pipe_draw_indirect_info indirect;
+};
+
 struct dd_call
 {
    enum call_type type;
 
    union {
-      struct pipe_draw_info draw_vbo;
+      struct call_draw_info draw_vbo;
       struct pipe_grid_info launch_grid;
       struct call_resource_copy_region resource_copy_region;
       struct pipe_blit_info blit;
diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
index b42b468560..7cea5fb692 100644
--- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
+++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
@@ -818,10 +818,10 @@ static void
 nvc0_draw_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
 {
    struct nouveau_pushbuf *push = nvc0->base.pushbuf;
-   struct nv04_resource *buf = nv04_resource(info->indirect);
-   struct nv04_resource *buf_count = nv04_resource(info->indirect_params);
-   unsigned size, macro, count = info->indirect_count, drawid = info->drawid;
-   uint32_t offset = buf->offset + info->indirect_offset;
+   struct nv04_resource *buf = nv04_resource(info->indirect->buffer);
+   struct nv04_resource *buf_count = nv04_resource(info->indirect->indirect_draw_count);
+   unsigned size, macro, count = info->indirect->draw_count, drawid = info->drawid;
+   uint32_t offset = buf->offset + info->indirect->offset;
    struct nvc0_screen *screen = nvc0->screen;
 
    PUSH_SPACE(push, 7);
@@ -870,7 +870,7 @@ nvc0_draw_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
     */
    while (count) {
       unsigned draws = count, pushes, i;
-      if (info->indirect_stride == size * 4) {
+      if (info->indirect->stride == size * 4) {
          draws = MIN2(draws, (NV04_PFIFO_MAX_PACKET_LEN - 4) / size);
          pushes = 1;
       } else {
@@ -890,20 +890,20 @@ nvc0_draw_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *info)
       if (buf_count) {
          nouveau_pushbuf_data(push,
                               buf_count->bo,
-                              buf_count->offset + info->indirect_params_offset,
+                              buf_count->offset + info->indirect->indirect_draw_count_offset,
                               NVC0_IB_ENTRY_1_NO_PREFETCH | 4);
       }
       if (pushes == 1) {
          nouveau_pushbuf_data(push,
                               buf->bo, offset,
                               NVC0_IB_ENTRY_1_NO_PREFETCH | (size * 4 * draws));
-         offset += draws * info->indirect_stride;
+         offset += draws * info->indirect->stride;
       } else {
          for (i = 0; i < pushes; i++) {
             nouveau_pushbuf_data(push,
                                  buf->bo, offset,
                                  NVC0_IB_ENTRY_1_NO_PREFETCH | (size * 4));
-            offset += info->indirect_stride;
+            offset += info->indirect->stride;
          }
       }
       count -= draws;
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index f3011c82cf..ee6fd2667b 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -1770,11 +1770,11 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
 			}
 			else {
 				/* Have to get start/count from indirect buffer, slow path ahead... */
-				struct r600_resource *indirect_resource = (struct r600_resource *)info->indirect;
+				struct r600_resource *indirect_resource = (struct r600_resource *)info->indirect->buffer;
 				unsigned *data = r600_buffer_map_sync_with_rings(&rctx->b, indirect_resource,
 					PIPE_TRANSFER_READ);
 				if (data) {
-					data += info->indirect_offset / sizeof(unsigned);
+					data += info->indirect->offset / sizeof(unsigned);
 					start = data[2] * ib.index_size;
 					count = data[0];
 				}
@@ -1918,7 +1918,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
 		radeon_emit(cs, PKT3(PKT3_NUM_INSTANCES, 0, 0));
 		radeon_emit(cs, info->instance_count);
 	} else {
-		uint64_t va = r600_resource(info->indirect)->gpu_address;
+		uint64_t va = r600_resource(info->indirect->buffer)->gpu_address;
 		assert(rctx->b.chip_class >= EVERGREEN);
 
 		// Invalidate so non-indirect draw calls reset this state
@@ -1932,7 +1932,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
 
 		radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
 		radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx,
-							  (struct r600_resource*)info->indirect,
+							  (struct r600_resource*)info->indirect->buffer,
 							  RADEON_USAGE_READ,
                                                           RADEON_PRIO_DRAW_INDIRECT));
 	}
@@ -1982,7 +1982,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
 				radeon_emit(cs, max_size);
 
 				radeon_emit(cs, PKT3(EG_PKT3_DRAW_INDEX_INDIRECT, 1, render_cond_bit));
-				radeon_emit(cs, info->indirect_offset);
+				radeon_emit(cs, info->indirect->offset);
 				radeon_emit(cs, V_0287F0_DI_SRC_SEL_DMA);
 			}
 		}
@@ -2012,7 +2012,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
 		}
 		else {
 			radeon_emit(cs, PKT3(EG_PKT3_DRAW_INDIRECT, 1, render_cond_bit));
-			radeon_emit(cs, info->indirect_offset);
+			radeon_emit(cs, info->indirect->offset);
 		}
 		radeon_emit(cs, V_0287F0_DI_SRC_SEL_AUTO_INDEX |
 				(info->count_from_stream_output ? S_0287F0_USE_OPAQUE(1) : 0));
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index f7190055e3..50bf829346 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -627,6 +627,7 @@ static void si_emit_draw_packets(struct si_context *sctx,
 				 const struct pipe_draw_info *info,
 				 const struct pipe_index_buffer *ib)
 {
+	struct pipe_draw_indirect_info *indirect = info->indirect;
 	struct radeon_winsys_cs *cs = sctx->b.gfx.cs;
 	unsigned sh_base_reg = sctx->shader_userdata.sh_base[PIPE_SHADER_VERTEX];
 	bool render_cond_bit = sctx->b.render_cond && !sctx->b.render_cond_force_off;
@@ -707,8 +708,8 @@ static void si_emit_draw_packets(struct si_context *sctx,
 			sctx->last_index_size = -1;
 	}
 
-	if (info->indirect) {
-		uint64_t indirect_va = r600_resource(info->indirect)->gpu_address;
+	if (indirect) {
+		uint64_t indirect_va = r600_resource(indirect->buffer)->gpu_address;
 
 		assert(indirect_va % 8 == 0);
 
@@ -720,13 +721,13 @@ static void si_emit_draw_packets(struct si_context *sctx,
 		radeon_emit(cs, indirect_va >> 32);
 
 		radeon_add_to_buffer_list(&sctx->b, &sctx->b.gfx,
-				      (struct r600_resource *)info->indirect,
+				      (struct r600_resource *)indirect->buffer,
 				      RADEON_USAGE_READ, RADEON_PRIO_DRAW_INDIRECT);
 
 		unsigned di_src_sel = info->indexed ? V_0287F0_DI_SRC_SEL_DMA
 						    : V_0287F0_DI_SRC_SEL_AUTO_INDEX;
 
-		assert(info->indirect_offset % 4 == 0);
+		assert(indirect->offset % 4 == 0);
 
 		if (info->indexed) {
 			radeon_emit(cs, PKT3(PKT3_INDEX_BASE, 1, 0));
@@ -741,37 +742,37 @@ static void si_emit_draw_packets(struct si_context *sctx,
 			radeon_emit(cs, PKT3(info->indexed ? PKT3_DRAW_INDEX_INDIRECT
 							   : PKT3_DRAW_INDIRECT,
 					     3, render_cond_bit));
-			radeon_emit(cs, info->indirect_offset);
+			radeon_emit(cs, indirect->offset);
 			radeon_emit(cs, (sh_base_reg + SI_SGPR_BASE_VERTEX * 4 - SI_SH_REG_OFFSET) >> 2);
 			radeon_emit(cs, (sh_base_reg + SI_SGPR_START_INSTANCE * 4 - SI_SH_REG_OFFSET) >> 2);
 			radeon_emit(cs, di_src_sel);
 		} else {
 			uint64_t count_va = 0;
 
-			if (info->indirect_params) {
+			if (indirect->indirect_draw_count) {
 				struct r600_resource *params_buf =
-					(struct r600_resource *)info->indirect_params;
+					(struct r600_resource *)indirect->indirect_draw_count;
 
 				radeon_add_to_buffer_list(
 					&sctx->b, &sctx->b.gfx, params_buf,
 					RADEON_USAGE_READ, RADEON_PRIO_DRAW_INDIRECT);
 
-				count_va = params_buf->gpu_address + info->indirect_params_offset;
+				count_va = params_buf->gpu_address + indirect->indirect_draw_count_offset;
 			}
 
 			radeon_emit(cs, PKT3(info->indexed ? PKT3_DRAW_INDEX_INDIRECT_MULTI :
 							     PKT3_DRAW_INDIRECT_MULTI,
 					     8, render_cond_bit));
-			radeon_emit(cs, info->indirect_offset);
+			radeon_emit(cs, indirect->offset);
 			radeon_emit(cs, (sh_base_reg + SI_SGPR_BASE_VERTEX * 4 - SI_SH_REG_OFFSET) >> 2);
 			radeon_emit(cs, (sh_base_reg + SI_SGPR_START_INSTANCE * 4 - SI_SH_REG_OFFSET) >> 2);
 			radeon_emit(cs, ((sh_base_reg + SI_SGPR_DRAWID * 4 - SI_SH_REG_OFFSET) >> 2) |
 					S_2C3_DRAW_INDEX_ENABLE(1) |
-					S_2C3_COUNT_INDIRECT_ENABLE(!!info->indirect_params));
-			radeon_emit(cs, info->indirect_count);
+					S_2C3_COUNT_INDIRECT_ENABLE(!!indirect->indirect_draw_count));
+			radeon_emit(cs, indirect->draw_count);
 			radeon_emit(cs, count_va);
 			radeon_emit(cs, count_va >> 32);
-			radeon_emit(cs, info->indirect_stride);
+			radeon_emit(cs, indirect->stride);
 			radeon_emit(cs, di_src_sel);
 		}
 	} else {
@@ -1072,17 +1073,19 @@ static void si_get_draw_start_count(struct si_context *sctx,
 				    const struct pipe_draw_info *info,
 				    unsigned *start, unsigned *count)
 {
-	if (info->indirect) {
+	struct pipe_draw_indirect_info *indirect = info->indirect;
+
+	if (indirect) {
 		unsigned indirect_count;
 		struct pipe_transfer *transfer;
 		unsigned begin, end;
 		unsigned map_size;
 		unsigned *data;
 
-		if (info->indirect_params) {
+		if (indirect->indirect_draw_count) {
 			data = pipe_buffer_map_range(&sctx->b.b,
-					info->indirect_params,
-					info->indirect_params_offset,
+					indirect->indirect_draw_count,
+					indirect->indirect_draw_count_offset,
 					sizeof(unsigned),
 					PIPE_TRANSFER_READ, &transfer);
 
@@ -1090,7 +1093,7 @@ static void si_get_draw_start_count(struct si_context *sctx,
 
 			pipe_buffer_unmap(&sctx->b.b, transfer);
 		} else {
-			indirect_count = info->indirect_count;
+			indirect_count = indirect->draw_count;
 		}
 
 		if (!indirect_count) {
@@ -1098,9 +1101,9 @@ static void si_get_draw_start_count(struct si_context *sctx,
 			return;
 		}
 
-		map_size = (indirect_count - 1) * info->indirect_stride + 3 * sizeof(unsigned);
-		data = pipe_buffer_map_range(&sctx->b.b, info->indirect,
-					     info->indirect_offset, map_size,
+		map_size = (indirect_count - 1) * indirect->stride + 3 * sizeof(unsigned);
+		data = pipe_buffer_map_range(&sctx->b.b, indirect->buffer,
+					     indirect->offset, map_size,
 					     PIPE_TRANSFER_READ, &transfer);
 
 		begin = UINT_MAX;
@@ -1115,7 +1118,7 @@ static void si_get_draw_start_count(struct si_context *sctx,
 				end = MAX2(end, start + count);
 			}
 
-			data += info->indirect_stride / sizeof(unsigned);
+			data += indirect->stride / sizeof(unsigned);
 		}
 
 		pipe_buffer_unmap(&sctx->b.b, transfer);
@@ -1301,18 +1304,20 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
 	}
 
 	if (info->indirect) {
+		struct pipe_draw_indirect_info *indirect = info->indirect;
+
 		/* Add the buffer size for memory checking in need_cs_space. */
-		r600_context_add_resource_size(ctx, info->indirect);
+		r600_context_add_resource_size(ctx, indirect->buffer);
 
-		if (r600_resource(info->indirect)->TC_L2_dirty) {
+		if (r600_resource(indirect->buffer)->TC_L2_dirty) {
 			sctx->b.flags |= SI_CONTEXT_WRITEBACK_GLOBAL_L2;
-			r600_resource(info->indirect)->TC_L2_dirty = false;
+			r600_resource(indirect->buffer)->TC_L2_dirty = false;
 		}
 
-		if (info->indirect_params &&
-		    r600_resource(info->indirect_params)->TC_L2_dirty) {
+		if (indirect->indirect_draw_count &&
+		    r600_resource(indirect->indirect_draw_count)->TC_L2_dirty) {
 			sctx->b.flags |= SI_CONTEXT_WRITEBACK_GLOBAL_L2;
-			r600_resource(info->indirect_params)->TC_L2_dirty = false;
+			r600_resource(indirect->indirect_draw_count)->TC_L2_dirty = false;
 		}
 	}
 
diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c
index 13c0a9d5bc..e4a5e3b693 100644
--- a/src/gallium/drivers/trace/tr_dump_state.c
+++ b/src/gallium/drivers/trace/tr_dump_state.c
@@ -812,8 +812,16 @@ void trace_dump_draw_info(const struct pipe_draw_info *state)
 
    trace_dump_member(ptr, state, count_from_stream_output);
 
-   trace_dump_member(ptr, state, indirect);
-   trace_dump_member(uint, state, indirect_offset);
+   if (!state->indirect) {
+      trace_dump_member(ptr, state, indirect);
+   } else {
+      trace_dump_member(uint, state, indirect->offset);
+      trace_dump_member(uint, state, indirect->stride);
+      trace_dump_member(uint, state, indirect->draw_count);
+      trace_dump_member(uint, state, indirect->indirect_draw_count_offset);
+      trace_dump_member(ptr, state, indirect->buffer);
+      trace_dump_member(ptr, state, indirect->indirect_draw_count);
+   }
 
    trace_dump_struct_end();
 }
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 0c9b4b4591..3cfdd349fe 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -641,6 +641,40 @@ struct pipe_index_buffer
 };
 
 
+struct pipe_draw_indirect_info
+{
+   unsigned offset; /**< must be 4 byte aligned */
+   unsigned stride; /**< must be 4 byte aligned */
+   unsigned draw_count; /**< number of indirect draws */
+   unsigned indirect_draw_count_offset; /**< must be 4 byte aligned */
+
+   /* Indirect draw parameters resource is laid out as follows:
+    *
+    * if indexed is TRUE:
+    *  struct {
+    *     uint32_t count;
+    *     uint32_t instance_count;
+    *     uint32_t start;
+    *     int32_t index_bias;
+    *     uint32_t start_instance;
+    *  };
+    * otherwise:
+    *  struct {
+    *     uint32_t count;
+    *     uint32_t instance_count;
+    *     uint32_t start;
+    *     uint32_t start_instance;
+    *  };
+    */
+   struct pipe_resource *buffer;
+
+   /* Indirect draw count resource: If not NULL, contains a 32-bit value which
+    * is to be used as the real draw_count.
+    */
+   struct pipe_resource *indirect_draw_count;
+};
+
+
 /**
  * Information to describe a draw_vbo call.
  */
@@ -671,40 +705,9 @@ struct pipe_draw_info
     */
    unsigned restart_index;
 
-   unsigned indirect_offset; /**< must be 4 byte aligned */
-   unsigned indirect_stride; /**< must be 4 byte aligned */
-   unsigned indirect_count; /**< number of indirect draws */
-
-   unsigned indirect_params_offset; /**< must be 4 byte aligned */
-
    /* Pointers must be at the end for an optimal structure layout on 64-bit. */
 
-   /* Indirect draw parameters resource: If not NULL, most values are taken
-    * from this buffer instead, which is laid out as follows:
-    *
-    * if indexed is TRUE:
-    *  struct {
-    *     uint32_t count;
-    *     uint32_t instance_count;
-    *     uint32_t start;
-    *     int32_t index_bias;
-    *     uint32_t start_instance;
-    *  };
-    * otherwise:
-    *  struct {
-    *     uint32_t count;
-    *     uint32_t instance_count;
-    *     uint32_t start;
-    *     uint32_t start_instance;
-    *  };
-    */
-   struct pipe_resource *indirect;
-
-   /* Indirect draw count resource: If not NULL, contains a 32-bit value which
-    * is to be used as the real indirect_count. In that case indirect_count
-    * becomes the maximum possible value.
-    */
-   struct pipe_resource *indirect_params;
+   struct pipe_draw_indirect_info *indirect; /**< Indirect draw. */
 
    /**
     * Stream output target. If not NULL, it's used to provide the 'count'
diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
index 6f97ddd647..6390735ac5 100644
--- a/src/gallium/state_trackers/nine/device9.c
+++ b/src/gallium/state_trackers/nine/device9.c
@@ -3031,7 +3031,6 @@ NineDevice9_ProcessVertices( struct NineDevice9 *This,
     draw.restart_index = 0;
     draw.count_from_stream_output = NULL;
     draw.indirect = NULL;
-    draw.indirect_params = NULL;
     draw.instance_count = 1;
     draw.indexed = FALSE;
     draw.start = 0;
diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c
index 2046d9dbf2..3b1cd7ced6 100644
--- a/src/gallium/state_trackers/nine/nine_state.c
+++ b/src/gallium/state_trackers/nine/nine_state.c
@@ -2559,7 +2559,6 @@ init_draw_info(struct pipe_draw_info *info,
     info->restart_index = 0;
     info->count_from_stream_output = NULL;
     info->indirect = NULL;
-    info->indirect_params = NULL;
 }
 
 CSMT_ITEM_NO_WAIT(nine_context_draw_primitive,
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 5c9f7ea791..29381b654d 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -264,6 +264,7 @@ st_indirect_draw_vbo(struct gl_context *ctx,
 {
    struct st_context *st = st_context(ctx);
    struct pipe_draw_info info;
+   struct pipe_draw_indirect_info indirect;
 
    /* Mesa core state should have been validated already */
    assert(ctx->NewState == 0x0);
@@ -281,6 +282,7 @@ st_indirect_draw_vbo(struct gl_context *ctx,
       return;
    }
 
+   memset(&indirect, 0, sizeof(indirect));
    util_draw_init_info(&info);
 
    if (ib) {
@@ -294,8 +296,9 @@ st_indirect_draw_vbo(struct gl_context *ctx,
 
    info.mode = translate_prim(ctx, mode);
    info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices;
-   info.indirect = st_buffer_object(indirect_data)->buffer;
-   info.indirect_offset = indirect_offset;
+   info.indirect = &indirect;
+   indirect.buffer = st_buffer_object(indirect_data)->buffer;
+   indirect.offset = indirect_offset;
 
    if (ST_DEBUG & DEBUG_DRAW) {
       debug_printf("st/draw indirect: mode %s drawcount %d indexed %d\n",
@@ -308,18 +311,18 @@ st_indirect_draw_vbo(struct gl_context *ctx,
       int i;
 
       assert(!indirect_params);
-      info.indirect_count = 1;
+      indirect.draw_count = 1;
       for (i = 0; i < draw_count; i++) {
          info.drawid = i;
          cso_draw_vbo(st->cso_context, &info);
-         info.indirect_offset += stride;
+         indirect.offset += stride;
       }
    } else {
-      info.indirect_count = draw_count;
-      info.indirect_stride = stride;
+      indirect.draw_count = draw_count;
+      indirect.stride = stride;
       if (indirect_params) {
-         info.indirect_params = st_buffer_object(indirect_params)->buffer;
-         info.indirect_params_offset = indirect_params_offset;
+         indirect.indirect_draw_count = st_buffer_object(indirect_params)->buffer;
+         indirect.indirect_draw_count_offset = indirect_params_offset;
       }
       cso_draw_vbo(st->cso_context, &info);
    }




More information about the mesa-commit mailing list