util/vbuf: handle multidraws
this moves the handling from cso_conext to vbuf, which reduces overhead for draws that aren't rewritten Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17686>
This commit is contained in:
parent
7c484b0c1c
commit
6b07893b31
|
@ -1642,7 +1642,7 @@ cso_draw_vbo(struct cso_context *cso,
|
||||||
indirect->count_from_stream_output == NULL);
|
indirect->count_from_stream_output == NULL);
|
||||||
|
|
||||||
if (vbuf) {
|
if (vbuf) {
|
||||||
u_vbuf_draw_vbo(vbuf, info, drawid_offset, indirect, draw);
|
u_vbuf_draw_vbo(vbuf, info, drawid_offset, indirect, &draw, 1);
|
||||||
} else {
|
} else {
|
||||||
struct pipe_context *pipe = cso->pipe;
|
struct pipe_context *pipe = cso->pipe;
|
||||||
pipe->draw_vbo(pipe, info, drawid_offset, indirect, &draw, 1);
|
pipe->draw_vbo(pipe, info, drawid_offset, indirect, &draw, 1);
|
||||||
|
@ -1660,19 +1660,7 @@ cso_multi_draw(struct cso_context *cso,
|
||||||
struct u_vbuf *vbuf = cso->vbuf_current;
|
struct u_vbuf *vbuf = cso->vbuf_current;
|
||||||
|
|
||||||
if (vbuf) {
|
if (vbuf) {
|
||||||
/* Increase refcount to be able to use take_index_buffer_ownership with
|
u_vbuf_draw_vbo(vbuf, info, drawid_offset, NULL, draws, num_draws);
|
||||||
* all draws.
|
|
||||||
*/
|
|
||||||
if (num_draws > 1 && info->take_index_buffer_ownership)
|
|
||||||
p_atomic_add(&info->index.resource->reference.count, num_draws - 1);
|
|
||||||
|
|
||||||
unsigned drawid = drawid_offset;
|
|
||||||
for (unsigned i = 0; i < num_draws; i++) {
|
|
||||||
u_vbuf_draw_vbo(vbuf, info, drawid, NULL, draws[i]);
|
|
||||||
|
|
||||||
if (info->increment_draw_id)
|
|
||||||
drawid++;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
struct pipe_context *pipe = cso->pipe;
|
struct pipe_context *pipe = cso->pipe;
|
||||||
|
|
||||||
|
|
|
@ -1450,14 +1450,15 @@ u_vbuf_split_indexed_multidraw(struct u_vbuf *mgr, struct pipe_draw_info *info,
|
||||||
draw.index_bias = indirect_data[offset + 3];
|
draw.index_bias = indirect_data[offset + 3];
|
||||||
info->start_instance = indirect_data[offset + 4];
|
info->start_instance = indirect_data[offset + 4];
|
||||||
|
|
||||||
u_vbuf_draw_vbo(mgr, info, drawid_offset, NULL, draw);
|
u_vbuf_draw_vbo(mgr, info, drawid_offset, NULL, &draw, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
|
void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
|
||||||
unsigned drawid_offset,
|
unsigned drawid_offset,
|
||||||
const struct pipe_draw_indirect_info *indirect,
|
const struct pipe_draw_indirect_info *indirect,
|
||||||
const struct pipe_draw_start_count_bias draw)
|
const struct pipe_draw_start_count_bias *draws,
|
||||||
|
unsigned num_draws)
|
||||||
{
|
{
|
||||||
struct pipe_context *pipe = mgr->pipe;
|
struct pipe_context *pipe = mgr->pipe;
|
||||||
int start_vertex;
|
int start_vertex;
|
||||||
|
@ -1495,288 +1496,298 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
|
||||||
u_vbuf_set_driver_vertex_buffers(mgr);
|
u_vbuf_set_driver_vertex_buffers(mgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe->draw_vbo(pipe, info, drawid_offset, indirect, &draw, 1);
|
pipe->draw_vbo(pipe, info, drawid_offset, indirect, draws, num_draws);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Increase refcount to be able to use take_index_buffer_ownership with
|
||||||
|
* all draws.
|
||||||
|
*/
|
||||||
|
if (num_draws > 1 && info->take_index_buffer_ownership)
|
||||||
|
p_atomic_add(&info->index.resource->reference.count, num_draws - 1);
|
||||||
new_info = *info;
|
new_info = *info;
|
||||||
new_draw = draw;
|
|
||||||
|
|
||||||
/* Handle indirect (multi)draws. */
|
for (unsigned d = 0; d < num_draws; d++) {
|
||||||
if (indirect && indirect->buffer) {
|
new_draw = draws[d];
|
||||||
unsigned draw_count = 0;
|
if (info->increment_draw_id)
|
||||||
|
drawid_offset++;
|
||||||
|
|
||||||
/* Get the number of draws. */
|
/* Handle indirect (multi)draws. */
|
||||||
if (indirect->indirect_draw_count) {
|
if (indirect && indirect->buffer) {
|
||||||
pipe_buffer_read(pipe, indirect->indirect_draw_count,
|
unsigned draw_count = 0;
|
||||||
indirect->indirect_draw_count_offset,
|
|
||||||
4, &draw_count);
|
|
||||||
} else {
|
|
||||||
draw_count = indirect->draw_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!draw_count)
|
/* Get the number of draws. */
|
||||||
goto cleanup;
|
if (indirect->indirect_draw_count) {
|
||||||
|
pipe_buffer_read(pipe, indirect->indirect_draw_count,
|
||||||
unsigned data_size = (draw_count - 1) * indirect->stride +
|
indirect->indirect_draw_count_offset,
|
||||||
(new_info.index_size ? 20 : 16);
|
4, &draw_count);
|
||||||
unsigned *data = malloc(data_size);
|
} else {
|
||||||
if (!data)
|
draw_count = indirect->draw_count;
|
||||||
goto cleanup; /* report an error? */
|
|
||||||
|
|
||||||
/* Read the used buffer range only once, because the read can be
|
|
||||||
* uncached.
|
|
||||||
*/
|
|
||||||
pipe_buffer_read(pipe, indirect->buffer, indirect->offset, data_size,
|
|
||||||
data);
|
|
||||||
|
|
||||||
if (info->index_size) {
|
|
||||||
/* Indexed multidraw. */
|
|
||||||
unsigned index_bias0 = data[3];
|
|
||||||
bool index_bias_same = true;
|
|
||||||
|
|
||||||
/* If we invoke the translate path, we have to split the multidraw. */
|
|
||||||
if (incompatible_vb_mask ||
|
|
||||||
mgr->ve->incompatible_elem_mask) {
|
|
||||||
u_vbuf_split_indexed_multidraw(mgr, &new_info, drawid_offset, data,
|
|
||||||
indirect->stride, draw_count);
|
|
||||||
free(data);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if index_bias is the same for all draws. */
|
if (!draw_count)
|
||||||
for (unsigned i = 1; i < draw_count; i++) {
|
goto cleanup;
|
||||||
if (data[i * indirect->stride / 4 + 3] != index_bias0) {
|
|
||||||
index_bias_same = false;
|
unsigned data_size = (draw_count - 1) * indirect->stride +
|
||||||
break;
|
(new_info.index_size ? 20 : 16);
|
||||||
|
unsigned *data = malloc(data_size);
|
||||||
|
if (!data)
|
||||||
|
goto cleanup; /* report an error? */
|
||||||
|
|
||||||
|
/* Read the used buffer range only once, because the read can be
|
||||||
|
* uncached.
|
||||||
|
*/
|
||||||
|
pipe_buffer_read(pipe, indirect->buffer, indirect->offset, data_size,
|
||||||
|
data);
|
||||||
|
|
||||||
|
if (info->index_size) {
|
||||||
|
/* Indexed multidraw. */
|
||||||
|
unsigned index_bias0 = data[3];
|
||||||
|
bool index_bias_same = true;
|
||||||
|
|
||||||
|
/* If we invoke the translate path, we have to split the multidraw. */
|
||||||
|
if (incompatible_vb_mask ||
|
||||||
|
mgr->ve->incompatible_elem_mask) {
|
||||||
|
u_vbuf_split_indexed_multidraw(mgr, &new_info, drawid_offset, data,
|
||||||
|
indirect->stride, draw_count);
|
||||||
|
free(data);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Split the multidraw if index_bias is different. */
|
/* See if index_bias is the same for all draws. */
|
||||||
if (!index_bias_same) {
|
for (unsigned i = 1; i < draw_count; i++) {
|
||||||
u_vbuf_split_indexed_multidraw(mgr, &new_info, drawid_offset, data,
|
if (data[i * indirect->stride / 4 + 3] != index_bias0) {
|
||||||
indirect->stride, draw_count);
|
index_bias_same = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Split the multidraw if index_bias is different. */
|
||||||
|
if (!index_bias_same) {
|
||||||
|
u_vbuf_split_indexed_multidraw(mgr, &new_info, drawid_offset, data,
|
||||||
|
indirect->stride, draw_count);
|
||||||
|
free(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we don't need to use the translate path and index_bias is
|
||||||
|
* the same, we can process the multidraw with the time complexity
|
||||||
|
* equal to 1 draw call (except for the index range computation).
|
||||||
|
* We only need to compute the index range covering all draw calls
|
||||||
|
* of the multidraw.
|
||||||
|
*
|
||||||
|
* The driver will not look at these values because indirect != NULL.
|
||||||
|
* These values determine the user buffer bounds to upload.
|
||||||
|
*/
|
||||||
|
new_draw.index_bias = index_bias0;
|
||||||
|
new_info.index_bounds_valid = true;
|
||||||
|
new_info.min_index = ~0u;
|
||||||
|
new_info.max_index = 0;
|
||||||
|
new_info.start_instance = ~0u;
|
||||||
|
unsigned end_instance = 0;
|
||||||
|
|
||||||
|
struct pipe_transfer *transfer = NULL;
|
||||||
|
const uint8_t *indices;
|
||||||
|
|
||||||
|
if (info->has_user_indices) {
|
||||||
|
indices = (uint8_t*)info->index.user;
|
||||||
|
} else {
|
||||||
|
indices = (uint8_t*)pipe_buffer_map(pipe, info->index.resource,
|
||||||
|
PIPE_MAP_READ, &transfer);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < draw_count; i++) {
|
||||||
|
unsigned offset = i * indirect->stride / 4;
|
||||||
|
unsigned start = data[offset + 2];
|
||||||
|
unsigned count = data[offset + 0];
|
||||||
|
unsigned start_instance = data[offset + 4];
|
||||||
|
unsigned instance_count = data[offset + 1];
|
||||||
|
|
||||||
|
if (!count || !instance_count)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Update the ranges of instances. */
|
||||||
|
new_info.start_instance = MIN2(new_info.start_instance,
|
||||||
|
start_instance);
|
||||||
|
end_instance = MAX2(end_instance, start_instance + instance_count);
|
||||||
|
|
||||||
|
/* Update the index range. */
|
||||||
|
unsigned min, max;
|
||||||
|
u_vbuf_get_minmax_index_mapped(&new_info, count,
|
||||||
|
indices +
|
||||||
|
new_info.index_size * start,
|
||||||
|
&min, &max);
|
||||||
|
|
||||||
|
new_info.min_index = MIN2(new_info.min_index, min);
|
||||||
|
new_info.max_index = MAX2(new_info.max_index, max);
|
||||||
|
}
|
||||||
free(data);
|
free(data);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we don't need to use the translate path and index_bias is
|
if (transfer)
|
||||||
* the same, we can process the multidraw with the time complexity
|
pipe_buffer_unmap(pipe, transfer);
|
||||||
* equal to 1 draw call (except for the index range computation).
|
|
||||||
* We only need to compute the index range covering all draw calls
|
|
||||||
* of the multidraw.
|
|
||||||
*
|
|
||||||
* The driver will not look at these values because indirect != NULL.
|
|
||||||
* These values determine the user buffer bounds to upload.
|
|
||||||
*/
|
|
||||||
new_draw.index_bias = index_bias0;
|
|
||||||
new_info.index_bounds_valid = true;
|
|
||||||
new_info.min_index = ~0u;
|
|
||||||
new_info.max_index = 0;
|
|
||||||
new_info.start_instance = ~0u;
|
|
||||||
unsigned end_instance = 0;
|
|
||||||
|
|
||||||
struct pipe_transfer *transfer = NULL;
|
/* Set the final instance count. */
|
||||||
const uint8_t *indices;
|
new_info.instance_count = end_instance - new_info.start_instance;
|
||||||
|
|
||||||
if (info->has_user_indices) {
|
if (new_info.start_instance == ~0u || !new_info.instance_count)
|
||||||
indices = (uint8_t*)info->index.user;
|
goto cleanup;
|
||||||
} else {
|
} else {
|
||||||
indices = (uint8_t*)pipe_buffer_map(pipe, info->index.resource,
|
/* Non-indexed multidraw.
|
||||||
PIPE_MAP_READ, &transfer);
|
*
|
||||||
|
* Keep the draw call indirect and compute minimums & maximums,
|
||||||
|
* which will determine the user buffer bounds to upload, but
|
||||||
|
* the driver will not look at these values because indirect != NULL.
|
||||||
|
*
|
||||||
|
* This efficiently processes the multidraw with the time complexity
|
||||||
|
* equal to 1 draw call.
|
||||||
|
*/
|
||||||
|
new_draw.start = ~0u;
|
||||||
|
new_info.start_instance = ~0u;
|
||||||
|
unsigned end_vertex = 0;
|
||||||
|
unsigned end_instance = 0;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < draw_count; i++) {
|
||||||
|
unsigned offset = i * indirect->stride / 4;
|
||||||
|
unsigned start = data[offset + 2];
|
||||||
|
unsigned count = data[offset + 0];
|
||||||
|
unsigned start_instance = data[offset + 3];
|
||||||
|
unsigned instance_count = data[offset + 1];
|
||||||
|
|
||||||
|
new_draw.start = MIN2(new_draw.start, start);
|
||||||
|
new_info.start_instance = MIN2(new_info.start_instance,
|
||||||
|
start_instance);
|
||||||
|
|
||||||
|
end_vertex = MAX2(end_vertex, start + count);
|
||||||
|
end_instance = MAX2(end_instance, start_instance + instance_count);
|
||||||
|
}
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
/* Set the final counts. */
|
||||||
|
new_draw.count = end_vertex - new_draw.start;
|
||||||
|
new_info.instance_count = end_instance - new_info.start_instance;
|
||||||
|
|
||||||
|
if (new_draw.start == ~0u || !new_draw.count || !new_info.instance_count)
|
||||||
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < draw_count; i++) {
|
|
||||||
unsigned offset = i * indirect->stride / 4;
|
|
||||||
unsigned start = data[offset + 2];
|
|
||||||
unsigned count = data[offset + 0];
|
|
||||||
unsigned start_instance = data[offset + 4];
|
|
||||||
unsigned instance_count = data[offset + 1];
|
|
||||||
|
|
||||||
if (!count || !instance_count)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Update the ranges of instances. */
|
|
||||||
new_info.start_instance = MIN2(new_info.start_instance,
|
|
||||||
start_instance);
|
|
||||||
end_instance = MAX2(end_instance, start_instance + instance_count);
|
|
||||||
|
|
||||||
/* Update the index range. */
|
|
||||||
unsigned min, max;
|
|
||||||
u_vbuf_get_minmax_index_mapped(&new_info, count,
|
|
||||||
indices +
|
|
||||||
new_info.index_size * start,
|
|
||||||
&min, &max);
|
|
||||||
|
|
||||||
new_info.min_index = MIN2(new_info.min_index, min);
|
|
||||||
new_info.max_index = MAX2(new_info.max_index, max);
|
|
||||||
}
|
|
||||||
free(data);
|
|
||||||
|
|
||||||
if (transfer)
|
|
||||||
pipe_buffer_unmap(pipe, transfer);
|
|
||||||
|
|
||||||
/* Set the final instance count. */
|
|
||||||
new_info.instance_count = end_instance - new_info.start_instance;
|
|
||||||
|
|
||||||
if (new_info.start_instance == ~0u || !new_info.instance_count)
|
|
||||||
goto cleanup;
|
|
||||||
} else {
|
} else {
|
||||||
/* Non-indexed multidraw.
|
if ((!indirect && !new_draw.count) || !new_info.instance_count)
|
||||||
*
|
|
||||||
* Keep the draw call indirect and compute minimums & maximums,
|
|
||||||
* which will determine the user buffer bounds to upload, but
|
|
||||||
* the driver will not look at these values because indirect != NULL.
|
|
||||||
*
|
|
||||||
* This efficiently processes the multidraw with the time complexity
|
|
||||||
* equal to 1 draw call.
|
|
||||||
*/
|
|
||||||
new_draw.start = ~0u;
|
|
||||||
new_info.start_instance = ~0u;
|
|
||||||
unsigned end_vertex = 0;
|
|
||||||
unsigned end_instance = 0;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < draw_count; i++) {
|
|
||||||
unsigned offset = i * indirect->stride / 4;
|
|
||||||
unsigned start = data[offset + 2];
|
|
||||||
unsigned count = data[offset + 0];
|
|
||||||
unsigned start_instance = data[offset + 3];
|
|
||||||
unsigned instance_count = data[offset + 1];
|
|
||||||
|
|
||||||
new_draw.start = MIN2(new_draw.start, start);
|
|
||||||
new_info.start_instance = MIN2(new_info.start_instance,
|
|
||||||
start_instance);
|
|
||||||
|
|
||||||
end_vertex = MAX2(end_vertex, start + count);
|
|
||||||
end_instance = MAX2(end_instance, start_instance + instance_count);
|
|
||||||
}
|
|
||||||
free(data);
|
|
||||||
|
|
||||||
/* Set the final counts. */
|
|
||||||
new_draw.count = end_vertex - new_draw.start;
|
|
||||||
new_info.instance_count = end_instance - new_info.start_instance;
|
|
||||||
|
|
||||||
if (new_draw.start == ~0u || !new_draw.count || !new_info.instance_count)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if ((!indirect && !new_draw.count) || !new_info.instance_count)
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_info.index_size) {
|
if (new_info.index_size) {
|
||||||
/* See if anything needs to be done for per-vertex attribs. */
|
/* See if anything needs to be done for per-vertex attribs. */
|
||||||
if (u_vbuf_need_minmax_index(mgr, misaligned)) {
|
if (u_vbuf_need_minmax_index(mgr, misaligned)) {
|
||||||
unsigned max_index;
|
unsigned max_index;
|
||||||
|
|
||||||
if (new_info.index_bounds_valid) {
|
if (new_info.index_bounds_valid) {
|
||||||
min_index = new_info.min_index;
|
min_index = new_info.min_index;
|
||||||
max_index = new_info.max_index;
|
max_index = new_info.max_index;
|
||||||
|
} else {
|
||||||
|
u_vbuf_get_minmax_index(mgr->pipe, &new_info, &new_draw,
|
||||||
|
&min_index, &max_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(min_index <= max_index);
|
||||||
|
|
||||||
|
start_vertex = min_index + new_draw.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 (!indirect &&
|
||||||
|
!new_info.primitive_restart &&
|
||||||
|
util_is_vbo_upload_ratio_too_large(new_draw.count, num_vertices) &&
|
||||||
|
!u_vbuf_mapping_vertex_buffer_blocks(mgr, misaligned)) {
|
||||||
|
unroll_indices = TRUE;
|
||||||
|
user_vb_mask &= ~(mgr->nonzero_stride_vb_mask &
|
||||||
|
mgr->ve->noninstance_vb_mask_any);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
u_vbuf_get_minmax_index(mgr->pipe, &new_info, &new_draw,
|
/* Nothing to do for per-vertex attribs. */
|
||||||
&min_index, &max_index);
|
start_vertex = 0;
|
||||||
}
|
num_vertices = 0;
|
||||||
|
min_index = 0;
|
||||||
assert(min_index <= max_index);
|
|
||||||
|
|
||||||
start_vertex = min_index + new_draw.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 (!indirect &&
|
|
||||||
!new_info.primitive_restart &&
|
|
||||||
util_is_vbo_upload_ratio_too_large(new_draw.count, num_vertices) &&
|
|
||||||
!u_vbuf_mapping_vertex_buffer_blocks(mgr, misaligned)) {
|
|
||||||
unroll_indices = TRUE;
|
|
||||||
user_vb_mask &= ~(mgr->nonzero_stride_vb_mask &
|
|
||||||
mgr->ve->noninstance_vb_mask_any);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Nothing to do for per-vertex attribs. */
|
start_vertex = new_draw.start;
|
||||||
start_vertex = 0;
|
num_vertices = new_draw.count;
|
||||||
num_vertices = 0;
|
|
||||||
min_index = 0;
|
min_index = 0;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
start_vertex = new_draw.start;
|
|
||||||
num_vertices = new_draw.count;
|
|
||||||
min_index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Translate vertices with non-native layouts or formats. */
|
/* Translate vertices with non-native layouts or formats. */
|
||||||
if (unroll_indices ||
|
if (unroll_indices ||
|
||||||
incompatible_vb_mask ||
|
incompatible_vb_mask ||
|
||||||
mgr->ve->incompatible_elem_mask) {
|
mgr->ve->incompatible_elem_mask) {
|
||||||
if (!u_vbuf_translate_begin(mgr, &new_info, &new_draw,
|
if (!u_vbuf_translate_begin(mgr, &new_info, &new_draw,
|
||||||
start_vertex, num_vertices,
|
start_vertex, num_vertices,
|
||||||
min_index, unroll_indices, misaligned)) {
|
min_index, unroll_indices, misaligned)) {
|
||||||
debug_warn_once("u_vbuf_translate_begin() failed");
|
debug_warn_once("u_vbuf_translate_begin() failed");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unroll_indices) {
|
||||||
|
new_info.index_size = 0;
|
||||||
|
new_draw.index_bias = 0;
|
||||||
|
new_info.index_bounds_valid = true;
|
||||||
|
new_info.min_index = 0;
|
||||||
|
new_info.max_index = new_draw.count - 1;
|
||||||
|
new_draw.start = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
user_vb_mask &= ~(incompatible_vb_mask |
|
||||||
|
mgr->ve->incompatible_vb_mask_all);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Upload user buffers. */
|
||||||
|
if (user_vb_mask) {
|
||||||
|
if (u_vbuf_upload_buffers(mgr, start_vertex, num_vertices,
|
||||||
|
new_info.start_instance,
|
||||||
|
new_info.instance_count) != PIPE_OK) {
|
||||||
|
debug_warn_once("u_vbuf_upload_buffers() failed");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
mgr->dirty_real_vb_mask |= user_vb_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (unroll_indices) {
|
if (unroll_indices) {
|
||||||
new_info.index_size = 0;
|
printf("unrolling indices: start_vertex = %i, num_vertices = %i\n",
|
||||||
new_draw.index_bias = 0;
|
start_vertex, num_vertices);
|
||||||
new_info.index_bounds_valid = true;
|
util_dump_draw_info(stdout, info);
|
||||||
new_info.min_index = 0;
|
printf("\n");
|
||||||
new_info.max_index = new_draw.count - 1;
|
|
||||||
new_draw.start = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
user_vb_mask &= ~(incompatible_vb_mask |
|
unsigned i;
|
||||||
mgr->ve->incompatible_vb_mask_all);
|
for (i = 0; i < mgr->nr_vertex_buffers; i++) {
|
||||||
}
|
printf("input %i: ", i);
|
||||||
|
util_dump_vertex_buffer(stdout, mgr->vertex_buffer+i);
|
||||||
/* Upload user buffers. */
|
printf("\n");
|
||||||
if (user_vb_mask) {
|
|
||||||
if (u_vbuf_upload_buffers(mgr, start_vertex, num_vertices,
|
|
||||||
new_info.start_instance,
|
|
||||||
new_info.instance_count) != PIPE_OK) {
|
|
||||||
debug_warn_once("u_vbuf_upload_buffers() failed");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < mgr->nr_real_vertex_buffers; i++) {
|
||||||
|
printf("real %i: ", i);
|
||||||
|
util_dump_vertex_buffer(stdout, mgr->real_vertex_buffer+i);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
mgr->dirty_real_vb_mask |= user_vb_mask;
|
u_upload_unmap(pipe->stream_uploader);
|
||||||
|
if (mgr->dirty_real_vb_mask)
|
||||||
|
u_vbuf_set_driver_vertex_buffers(mgr);
|
||||||
|
|
||||||
|
if ((new_info.index_size == 1 && mgr->caps.rewrite_ubyte_ibs) ||
|
||||||
|
(new_info.primitive_restart &&
|
||||||
|
((new_info.restart_index != fixed_restart_index && mgr->caps.rewrite_restart_index) ||
|
||||||
|
!(mgr->caps.supported_restart_modes & BITFIELD_BIT(new_info.mode)))) ||
|
||||||
|
!(mgr->caps.supported_prim_modes & BITFIELD_BIT(new_info.mode))) {
|
||||||
|
util_primconvert_save_flatshade_first(mgr->pc, mgr->flatshade_first);
|
||||||
|
util_primconvert_draw_vbo(mgr->pc, &new_info, drawid_offset, indirect, &new_draw, 1);
|
||||||
|
} else
|
||||||
|
pipe->draw_vbo(pipe, &new_info, drawid_offset, indirect, &new_draw, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
if (unroll_indices) {
|
|
||||||
printf("unrolling indices: start_vertex = %i, num_vertices = %i\n",
|
|
||||||
start_vertex, num_vertices);
|
|
||||||
util_dump_draw_info(stdout, info);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < mgr->nr_vertex_buffers; i++) {
|
|
||||||
printf("input %i: ", i);
|
|
||||||
util_dump_vertex_buffer(stdout, mgr->vertex_buffer+i);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
for (i = 0; i < mgr->nr_real_vertex_buffers; i++) {
|
|
||||||
printf("real %i: ", i);
|
|
||||||
util_dump_vertex_buffer(stdout, mgr->real_vertex_buffer+i);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
u_upload_unmap(pipe->stream_uploader);
|
|
||||||
if (mgr->dirty_real_vb_mask)
|
|
||||||
u_vbuf_set_driver_vertex_buffers(mgr);
|
|
||||||
|
|
||||||
if ((new_info.index_size == 1 && mgr->caps.rewrite_ubyte_ibs) ||
|
|
||||||
(new_info.primitive_restart &&
|
|
||||||
((new_info.restart_index != fixed_restart_index && mgr->caps.rewrite_restart_index) ||
|
|
||||||
!(mgr->caps.supported_restart_modes & BITFIELD_BIT(new_info.mode)))) ||
|
|
||||||
!(mgr->caps.supported_prim_modes & BITFIELD_BIT(new_info.mode))) {
|
|
||||||
util_primconvert_save_flatshade_first(mgr->pc, mgr->flatshade_first);
|
|
||||||
util_primconvert_draw_vbo(mgr->pc, &new_info, drawid_offset, indirect, &new_draw, 1);
|
|
||||||
} else
|
|
||||||
pipe->draw_vbo(pipe, &new_info, drawid_offset, indirect, &new_draw, 1);
|
|
||||||
|
|
||||||
if (mgr->using_translate) {
|
if (mgr->using_translate) {
|
||||||
u_vbuf_translate_end(mgr);
|
u_vbuf_translate_end(mgr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,8 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr,
|
||||||
void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
|
void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
|
||||||
unsigned drawid_offset,
|
unsigned drawid_offset,
|
||||||
const struct pipe_draw_indirect_info *indirect,
|
const struct pipe_draw_indirect_info *indirect,
|
||||||
const struct pipe_draw_start_count_bias draw);
|
const struct pipe_draw_start_count_bias *draws,
|
||||||
|
unsigned num_draws);
|
||||||
void u_vbuf_get_minmax_index(struct pipe_context *pipe,
|
void u_vbuf_get_minmax_index(struct pipe_context *pipe,
|
||||||
const struct pipe_draw_info *info,
|
const struct pipe_draw_info *info,
|
||||||
const struct pipe_draw_start_count_bias *draw,
|
const struct pipe_draw_start_count_bias *draw,
|
||||||
|
|
Loading…
Reference in New Issue