Skip to content

Commit

Permalink
Batching - fix number of verts in translation
Browse files Browse the repository at this point in the history
The translation to larger vertex formats was assuming that batches were rects, and not accounting that the num_commands had a different meaning for lines and polys, so the calculation for number of vertices to translate was incorrect in these cases.

Also prevents infinite loop if a single polygon has too many vertices to fit in the batch buffer.
  • Loading branch information
lawnjelly committed Apr 23, 2021
1 parent 3768a37 commit d08cf5f
Showing 1 changed file with 38 additions and 7 deletions.
45 changes: 38 additions & 7 deletions drivers/gles_common/rasterizer_canvas_batcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ class RasterizerCanvasBatcher {
// in the case of DEFAULT, this is num commands.
// with rects, is number of command and rects.
// with lines, is number of lines
// with polys, is number of indices (actual rendered verts)
uint32_t num_commands;

// first vertex of this batch in the vertex lists
Expand All @@ -193,6 +194,29 @@ class RasterizerCanvasBatcher {
// for default batches we will store the parent item
const RasterizerCanvas::Item *item;
};

uint32_t get_num_verts() const {
switch (type) {
default: {
} break;
case RasterizerStorageCommon::BT_RECT: {
return num_commands * 4;
} break;
case RasterizerStorageCommon::BT_LINE: {
return num_commands * 2;
} break;
case RasterizerStorageCommon::BT_LINE_AA: {
return num_commands * 2;
} break;
case RasterizerStorageCommon::BT_POLY: {
return num_commands;
} break;
}

// error condition
WARN_PRINT_ONCE("reading num_verts from incorrect batch type");
return 0;
}
};

struct BatchTex {
Expand Down Expand Up @@ -1596,7 +1620,15 @@ bool C_PREAMBLE::_prefill_polygon(RasterizerCanvas::Item::CommandPolygon *p_poly
// could be done with a temporary vertex buffer
BatchVertex *bvs = bdata.vertices.request(num_inds);
if (!bvs) {
// run out of space in the vertex buffer .. finish this function and draw what we have so far
// run out of space in the vertex buffer
// check for special case where the batching buffer is simply not big enough to fit this primitive.
if (!bdata.vertices.size()) {
// can't draw, ignore the primitive, otherwise we would enter an infinite loop
WARN_PRINT_ONCE("poly has too many indices to draw, increase batch buffer size");
return false;
}

// .. finish this function and draw what we have so far
// return where we got to
r_command_start = command_num;
return true;
Expand Down Expand Up @@ -2952,10 +2984,9 @@ void C_PREAMBLE::_translate_batches_to_larger_FVF(uint32_t p_sequence_batch_type
needs_new_batch = false;

// create the colored verts (only if not default)
//int first_vert = source_batch.first_quad * 4;
//int end_vert = 4 * (source_batch.first_quad + source_batch.num_commands);
int first_vert = source_batch.first_vert;
int end_vert = first_vert + (4 * source_batch.num_commands);
int num_verts = source_batch.get_num_verts();
int end_vert = first_vert + num_verts;

for (int v = first_vert; v < end_vert; v++) {
RAST_DEV_DEBUG_ASSERT(bdata.vertices.size());
Expand Down Expand Up @@ -3012,10 +3043,10 @@ void C_PREAMBLE::_translate_batches_to_larger_FVF(uint32_t p_sequence_batch_type

// create the colored verts (only if not default)
if (source_batch.type != RasterizerStorageCommon::BT_DEFAULT) {
// int first_vert = source_batch.first_quad * 4;
// int end_vert = 4 * (source_batch.first_quad + source_batch.num_commands);

int first_vert = source_batch.first_vert;
int end_vert = first_vert + (4 * source_batch.num_commands);
int num_verts = source_batch.get_num_verts();
int end_vert = first_vert + num_verts;

for (int v = first_vert; v < end_vert; v++) {
RAST_DEV_DEBUG_ASSERT(bdata.vertices.size());
Expand Down

0 comments on commit d08cf5f

Please sign in to comment.