aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/gallium/auxiliary/util
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/gallium/auxiliary/util')
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.c2
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_draw.c43
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_draw.h8
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_dump_state.c3
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_vbuf.c116
5 files changed, 127 insertions, 45 deletions
diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c
index 7b058fe22..db0d1b894 100644
--- a/mesalib/src/gallium/auxiliary/util/u_blitter.c
+++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c
@@ -325,7 +325,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
}
if (pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) &&
- pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER)) {
+ pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT)) {
ctx->vs_layered = util_make_layered_clear_vertex_shader(pipe);
}
diff --git a/mesalib/src/gallium/auxiliary/util/u_draw.c b/mesalib/src/gallium/auxiliary/util/u_draw.c
index 83d9284b8..b9f8fcd3c 100644
--- a/mesalib/src/gallium/auxiliary/util/u_draw.c
+++ b/mesalib/src/gallium/auxiliary/util/u_draw.c
@@ -27,6 +27,7 @@
#include "util/u_debug.h"
+#include "util/u_inlines.h"
#include "util/u_math.h"
#include "util/u_format.h"
#include "util/u_draw.h"
@@ -123,3 +124,45 @@ util_draw_max_index(
return max_index + 1;
}
+
+
+/* This extracts the draw arguments from the info_in->indirect resource,
+ * puts them into a new instance of pipe_draw_info, and calls draw_vbo on it.
+ */
+void
+util_draw_indirect(struct pipe_context *pipe,
+ const struct pipe_draw_info *info_in)
+{
+ struct pipe_draw_info info;
+ struct pipe_transfer *transfer;
+ uint32_t *params;
+ const unsigned num_params = info_in->indexed ? 5 : 4;
+
+ assert(info_in->indirect);
+ assert(!info_in->count_from_stream_output);
+
+ memcpy(&info, info_in, sizeof(info));
+
+ params = (uint32_t *)
+ pipe_buffer_map_range(pipe,
+ info_in->indirect,
+ info_in->indirect_offset,
+ num_params * sizeof(uint32_t),
+ PIPE_TRANSFER_READ,
+ &transfer);
+ if (!transfer) {
+ debug_printf("%s: failed to map indirect buffer\n", __FUNCTION__);
+ return;
+ }
+
+ info.count = params[0];
+ info.instance_count = params[1];
+ info.start = params[2];
+ info.index_bias = info_in->indexed ? params[3] : 0;
+ info.start_instance = info_in->indexed ? params[4] : params[3];
+ info.indirect = NULL;
+
+ pipe_buffer_unmap(pipe, transfer);
+
+ pipe->draw_vbo(pipe, &info);
+}
diff --git a/mesalib/src/gallium/auxiliary/util/u_draw.h b/mesalib/src/gallium/auxiliary/util/u_draw.h
index 5a7ead27e..9fc3e9924 100644
--- a/mesalib/src/gallium/auxiliary/util/u_draw.h
+++ b/mesalib/src/gallium/auxiliary/util/u_draw.h
@@ -142,6 +142,14 @@ util_draw_range_elements(struct pipe_context *pipe,
}
+/* This converts an indirect draw into a direct draw by mapping the indirect
+ * buffer, extracting its arguments, and calling pipe->draw_vbo.
+ */
+void
+util_draw_indirect(struct pipe_context *pipe,
+ const struct pipe_draw_info *info);
+
+
unsigned
util_draw_max_index(
const struct pipe_vertex_buffer *vertex_buffers,
diff --git a/mesalib/src/gallium/auxiliary/util/u_dump_state.c b/mesalib/src/gallium/auxiliary/util/u_dump_state.c
index 12f1d2d6e..e6614d5d2 100644
--- a/mesalib/src/gallium/auxiliary/util/u_dump_state.c
+++ b/mesalib/src/gallium/auxiliary/util/u_dump_state.c
@@ -759,6 +759,9 @@ 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_struct_end(stream);
}
diff --git a/mesalib/src/gallium/auxiliary/util/u_vbuf.c b/mesalib/src/gallium/auxiliary/util/u_vbuf.c
index 0c9c349e0..c475ee1b3 100644
--- a/mesalib/src/gallium/auxiliary/util/u_vbuf.c
+++ b/mesalib/src/gallium/auxiliary/util/u_vbuf.c
@@ -1013,22 +1013,23 @@ static boolean u_vbuf_mapping_vertex_buffer_blocks(struct u_vbuf *mgr)
static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
struct pipe_index_buffer *ib,
- const struct pipe_draw_info *info,
+ boolean primitive_restart,
+ unsigned restart_index,
+ unsigned start, unsigned count,
int *out_min_index,
int *out_max_index)
{
struct pipe_transfer *transfer = NULL;
const void *indices;
unsigned i;
- unsigned restart_index = info->restart_index;
if (ib->user_buffer) {
indices = (uint8_t*)ib->user_buffer +
- ib->offset + info->start * ib->index_size;
+ ib->offset + start * ib->index_size;
} else {
indices = pipe_buffer_map_range(pipe, ib->buffer,
- ib->offset + info->start * ib->index_size,
- info->count * ib->index_size,
+ ib->offset + start * ib->index_size,
+ count * ib->index_size,
PIPE_TRANSFER_READ, &transfer);
}
@@ -1037,8 +1038,8 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
const unsigned *ui_indices = (const unsigned*)indices;
unsigned max_ui = 0;
unsigned min_ui = ~0U;
- if (info->primitive_restart) {
- for (i = 0; i < info->count; i++) {
+ if (primitive_restart) {
+ for (i = 0; i < count; i++) {
if (ui_indices[i] != restart_index) {
if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
@@ -1046,7 +1047,7 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
}
}
else {
- for (i = 0; i < info->count; i++) {
+ for (i = 0; i < count; i++) {
if (ui_indices[i] > max_ui) max_ui = ui_indices[i];
if (ui_indices[i] < min_ui) min_ui = ui_indices[i];
}
@@ -1059,8 +1060,8 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
const unsigned short *us_indices = (const unsigned short*)indices;
unsigned max_us = 0;
unsigned min_us = ~0U;
- if (info->primitive_restart) {
- for (i = 0; i < info->count; i++) {
+ if (primitive_restart) {
+ for (i = 0; i < count; i++) {
if (us_indices[i] != restart_index) {
if (us_indices[i] > max_us) max_us = us_indices[i];
if (us_indices[i] < min_us) min_us = us_indices[i];
@@ -1068,7 +1069,7 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
}
}
else {
- for (i = 0; i < info->count; i++) {
+ for (i = 0; i < count; i++) {
if (us_indices[i] > max_us) max_us = us_indices[i];
if (us_indices[i] < min_us) min_us = us_indices[i];
}
@@ -1081,8 +1082,8 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
const unsigned char *ub_indices = (const unsigned char*)indices;
unsigned max_ub = 0;
unsigned min_ub = ~0U;
- if (info->primitive_restart) {
- for (i = 0; i < info->count; i++) {
+ if (primitive_restart) {
+ for (i = 0; i < count; i++) {
if (ub_indices[i] != restart_index) {
if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
@@ -1090,7 +1091,7 @@ static void u_vbuf_get_minmax_index(struct pipe_context *pipe,
}
}
else {
- for (i = 0; i < info->count; i++) {
+ for (i = 0; i < count; i++) {
if (ub_indices[i] > max_ub) max_ub = ub_indices[i];
if (ub_indices[i] < min_ub) min_ub = ub_indices[i];
}
@@ -1132,6 +1133,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
uint32_t used_vb_mask = mgr->ve->used_vb_mask;
uint32_t user_vb_mask = mgr->user_vb_mask & used_vb_mask;
uint32_t incompatible_vb_mask = mgr->incompatible_vb_mask & used_vb_mask;
+ struct pipe_draw_info new_info;
/* Normal draw. No fallback and no user buffers. */
if (!incompatible_vb_mask &&
@@ -1147,33 +1149,62 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
return;
}
- if (info->indexed) {
+ new_info = *info;
+
+ /* Fallback. We need to know all the parameters. */
+ if (new_info.indirect) {
+ struct pipe_transfer *transfer = NULL;
+ int *data;
+
+ if (new_info.indexed) {
+ data = pipe_buffer_map_range(pipe, new_info.indirect,
+ 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,
+ PIPE_TRANSFER_READ, &transfer);
+ new_info.start_instance = data[3];
+ }
+
+ new_info.count = data[0];
+ new_info.instance_count = data[1];
+ new_info.start = data[2];
+ pipe_buffer_unmap(pipe, transfer);
+ new_info.indirect = NULL;
+ }
+
+ if (new_info.indexed) {
/* See if anything needs to be done for per-vertex attribs. */
if (u_vbuf_need_minmax_index(mgr)) {
int max_index;
- if (info->max_index != ~0) {
- min_index = info->min_index;
- max_index = info->max_index;
+ if (new_info.max_index != ~0) {
+ min_index = new_info.min_index;
+ max_index = new_info.max_index;
} else {
- u_vbuf_get_minmax_index(mgr->pipe, &mgr->index_buffer, info,
- &min_index, &max_index);
+ u_vbuf_get_minmax_index(mgr->pipe, &mgr->index_buffer,
+ new_info.primitive_restart,
+ new_info.restart_index, new_info.start,
+ new_info.count, &min_index, &max_index);
}
assert(min_index <= max_index);
- start_vertex = min_index + info->index_bias;
+ start_vertex = min_index + new_info.index_bias;
num_vertices = max_index + 1 - min_index;
/* Primitive restart doesn't work when unrolling indices.
* We would have to break this drawing operation into several ones. */
/* Use some heuristic to see if unrolling indices improves
* performance. */
- if (!info->primitive_restart &&
- num_vertices > info->count*2 &&
- num_vertices-info->count > 32 &&
+ if (!new_info.primitive_restart &&
+ num_vertices > new_info.count*2 &&
+ num_vertices - new_info.count > 32 &&
!u_vbuf_mapping_vertex_buffer_blocks(mgr)) {
- /*printf("num_vertices=%i count=%i\n", num_vertices, info->count);*/
unroll_indices = TRUE;
user_vb_mask &= ~(mgr->nonzero_stride_vb_mask &
mgr->ve->noninstance_vb_mask_any);
@@ -1185,8 +1216,8 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
min_index = 0;
}
} else {
- start_vertex = info->start;
- num_vertices = info->count;
+ start_vertex = new_info.start;
+ num_vertices = new_info.count;
min_index = 0;
}
@@ -1195,13 +1226,21 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
incompatible_vb_mask ||
mgr->ve->incompatible_elem_mask) {
if (!u_vbuf_translate_begin(mgr, start_vertex, num_vertices,
- info->start_instance, info->instance_count,
- info->start, info->count, min_index,
- unroll_indices)) {
+ new_info.start_instance,
+ new_info.instance_count, new_info.start,
+ new_info.count, min_index, unroll_indices)) {
debug_warn_once("u_vbuf_translate_begin() failed");
return;
}
+ if (unroll_indices) {
+ new_info.indexed = FALSE;
+ new_info.index_bias = 0;
+ new_info.min_index = 0;
+ new_info.max_index = new_info.count - 1;
+ new_info.start = 0;
+ }
+
user_vb_mask &= ~(incompatible_vb_mask |
mgr->ve->incompatible_vb_mask_all);
}
@@ -1209,8 +1248,8 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
/* Upload user buffers. */
if (user_vb_mask) {
if (u_vbuf_upload_buffers(mgr, start_vertex, num_vertices,
- info->start_instance,
- info->instance_count) != PIPE_OK) {
+ new_info.start_instance,
+ new_info.instance_count) != PIPE_OK) {
debug_warn_once("u_vbuf_upload_buffers() failed");
return;
}
@@ -1242,18 +1281,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info)
u_upload_unmap(mgr->uploader);
u_vbuf_set_driver_vertex_buffers(mgr);
- if (unlikely(unroll_indices)) {
- struct pipe_draw_info new_info = *info;
- new_info.indexed = FALSE;
- new_info.index_bias = 0;
- new_info.min_index = 0;
- new_info.max_index = info->count - 1;
- new_info.start = 0;
-
- pipe->draw_vbo(pipe, &new_info);
- } else {
- pipe->draw_vbo(pipe, info);
- }
+ pipe->draw_vbo(pipe, &new_info);
if (mgr->using_translate) {
u_vbuf_translate_end(mgr);