From e04eed28274ace94978d12345351588d2caa8dca Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Tue, 30 Jan 2024 18:23:01 +0100 Subject: [PATCH] auxiliary/draw: fix streamout overflow calculation If the stride is larger than the component with the largest offset plus the size of that component, it is still considered an overflow if there's not enough space in the buffer to fit the whole stride-sized thing, even when there would be enough space to actually write all components. This is actually much simpler too, since we don't need to verify the individual components at all (stride is guaranteed to be larger or equal to the component with the largest offset plus the size of that component). Part-of: --- src/gallium/auxiliary/draw/draw_pt_so_emit.c | 35 +++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt_so_emit.c b/src/gallium/auxiliary/draw/draw_pt_so_emit.c index 976089e33da..2e181f2210f 100644 --- a/src/gallium/auxiliary/draw/draw_pt_so_emit.c +++ b/src/gallium/auxiliary/draw/draw_pt_so_emit.c @@ -146,27 +146,23 @@ so_emit_prim(struct pt_so_emit *so, } /* check have we space to emit prim first - if not don't do anything */ - for (unsigned i = 0; i < num_vertices; ++i) { - for (unsigned slot = 0; slot < state->num_outputs; ++slot) { - unsigned num_comps = state->output[slot].num_components; - int ob = state->output[slot].output_buffer; - unsigned dst_offset = state->output[slot].dst_offset * sizeof(float); - unsigned write_size = num_comps * sizeof(float); + for (unsigned slot = 0; slot < state->num_outputs; ++slot) { + int ob = state->output[slot].output_buffer; - if (state->output[slot].stream != so->stream) - continue; - /* If a buffer is missing then that's equivalent to - * an overflow */ - if (!draw->so.targets[ob]) { - return; - } - if ((buffer_total_bytes[ob] + write_size + dst_offset) > - draw->so.targets[ob]->target.buffer_size) { - return; - } + if (state->output[slot].stream != so->stream) + continue; + /* If a buffer is missing then that's equivalent to an overflow */ + if (!draw->so.targets[ob]) { + return; } - for (unsigned ob = 0; ob < draw->so.num_targets; ++ob) { - buffer_total_bytes[ob] += state->stride[ob] * sizeof(float); + buffer_written[ob] = true; + } + for (unsigned ob = 0; ob < draw->so.num_targets; ++ob) { + if (buffer_written[ob]) { + unsigned size_req = num_vertices * state->stride[ob] * sizeof(float); + if (buffer_total_bytes[ob] + size_req > draw->so.targets[ob]->target.buffer_size) { + return; + } } } @@ -191,7 +187,6 @@ so_emit_prim(struct pt_so_emit *so, continue; unsigned ob = state->output[slot].output_buffer; - buffer_written[ob] = true; float *buffer = (float *)((char *)draw->so.targets[ob]->mapping + draw->so.targets[ob]->target.buffer_offset +