mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 08:40:11 +01:00
vbo/dlist: use DrawGallium(Complex)
We can build the needed structs during list compilation and then use DrawGallium (if one draw or a single primitive mode is used) or DrawGalliumComplex otherwise. Reviewed-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9533>
This commit is contained in:
parent
43e243762f
commit
d0fefddf4a
4 changed files with 74 additions and 28 deletions
|
|
@ -804,7 +804,8 @@ vbo_destroy_vertex_list(struct gl_context *ctx, struct vbo_save_vertex_list *nod
|
|||
free(node->prim_store);
|
||||
}
|
||||
|
||||
free(node->merged.prims);
|
||||
free(node->merged.mode);
|
||||
free(node->merged.start_count);
|
||||
|
||||
_mesa_reference_buffer_object(ctx, &node->merged.ib.obj, NULL);
|
||||
free(node->current_data);
|
||||
|
|
|
|||
|
|
@ -69,10 +69,11 @@ struct vbo_save_vertex_list {
|
|||
GLuint min_index, max_index;
|
||||
|
||||
struct {
|
||||
struct _mesa_prim *prims;
|
||||
struct _mesa_index_buffer ib;
|
||||
GLuint prim_count;
|
||||
GLuint min_index, max_index;
|
||||
struct pipe_draw_info info;
|
||||
unsigned char *mode;
|
||||
struct pipe_draw_start_count *start_count;
|
||||
unsigned num_draws;
|
||||
} merged;
|
||||
|
||||
struct vbo_save_primitive_store *prim_store;
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#include "util/bitscan.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "gallium/include/pipe/p_state.h"
|
||||
|
||||
#include "vbo_noop.h"
|
||||
#include "vbo_private.h"
|
||||
|
||||
|
|
@ -534,6 +536,8 @@ compile_vertex_list(struct gl_context *ctx)
|
|||
if (!node)
|
||||
return;
|
||||
|
||||
memset(node, 0, sizeof(struct vbo_save_vertex_list));
|
||||
|
||||
/* Make sure the pointer is aligned to the size of a pointer */
|
||||
assert((GLintptr) node % sizeof(void *) == 0);
|
||||
|
||||
|
|
@ -574,9 +578,7 @@ compile_vertex_list(struct gl_context *ctx)
|
|||
node->vertex_count = save->vert_count;
|
||||
node->wrap_count = save->copied.nr;
|
||||
node->prims = save->prims;
|
||||
node->merged.prims = NULL;
|
||||
node->merged.ib.obj = NULL;
|
||||
node->merged.prim_count = 0;
|
||||
node->prim_count = save->prim_count;
|
||||
node->prim_store = save->prim_store;
|
||||
|
||||
|
|
@ -673,7 +675,7 @@ compile_vertex_list(struct gl_context *ctx)
|
|||
}
|
||||
int size = max_indices_count * sizeof(uint32_t);
|
||||
uint32_t* indices = (uint32_t*) malloc(size);
|
||||
uint32_t max_index = 0, min_index = 0xFFFFFFFF;
|
||||
struct _mesa_prim *merged_prims = NULL;
|
||||
|
||||
int idx = 0;
|
||||
|
||||
|
|
@ -694,7 +696,7 @@ compile_vertex_list(struct gl_context *ctx)
|
|||
|
||||
/* If 2 consecutive prims use the same mode => merge them. */
|
||||
bool merge_prims = last_valid_prim >= 0 &&
|
||||
mode == node->merged.prims[last_valid_prim].mode &&
|
||||
mode == merged_prims[last_valid_prim].mode &&
|
||||
mode != GL_LINE_LOOP && mode != GL_TRIANGLE_FAN &&
|
||||
mode != GL_QUAD_STRIP && mode != GL_POLYGON &&
|
||||
mode != GL_PATCHES;
|
||||
|
|
@ -705,18 +707,18 @@ compile_vertex_list(struct gl_context *ctx)
|
|||
if (merge_prims &&
|
||||
mode == GL_TRIANGLE_STRIP) {
|
||||
/* Insert a degenerate triangle */
|
||||
assert(node->merged.prims[last_valid_prim].mode == GL_TRIANGLE_STRIP);
|
||||
unsigned tri_count = node->merged.prims[last_valid_prim].count - 2;
|
||||
assert(merged_prims[last_valid_prim].mode == GL_TRIANGLE_STRIP);
|
||||
unsigned tri_count = merged_prims[last_valid_prim].count - 2;
|
||||
|
||||
indices[idx] = indices[idx - 1];
|
||||
indices[idx + 1] = original_prims[i].start;
|
||||
idx += 2;
|
||||
node->merged.prims[last_valid_prim].count += 2;
|
||||
merged_prims[last_valid_prim].count += 2;
|
||||
|
||||
if (tri_count % 2) {
|
||||
/* Add another index to preserve winding order */
|
||||
indices[idx++] = original_prims[i].start;
|
||||
node->merged.prims[last_valid_prim].count++;
|
||||
merged_prims[last_valid_prim].count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -747,32 +749,27 @@ compile_vertex_list(struct gl_context *ctx)
|
|||
}
|
||||
}
|
||||
|
||||
min_index = MIN2(min_index, indices[start]);
|
||||
max_index = MAX2(max_index, indices[idx - 1]);
|
||||
|
||||
if (merge_prims) {
|
||||
/* Update vertex count. */
|
||||
node->merged.prims[last_valid_prim].count += idx - start;
|
||||
merged_prims[last_valid_prim].count += idx - start;
|
||||
} else {
|
||||
/* Keep this primitive */
|
||||
last_valid_prim += 1;
|
||||
assert(last_valid_prim <= i);
|
||||
node->merged.prims = realloc(node->merged.prims, (1 + last_valid_prim) * sizeof(struct _mesa_prim));
|
||||
node->merged.prims[last_valid_prim] = original_prims[i];
|
||||
node->merged.prims[last_valid_prim].start = indices_offset + start;
|
||||
node->merged.prims[last_valid_prim].count = idx - start;
|
||||
merged_prims = realloc(merged_prims, (1 + last_valid_prim) * sizeof(struct _mesa_prim));
|
||||
merged_prims[last_valid_prim] = original_prims[i];
|
||||
merged_prims[last_valid_prim].start = indices_offset + start;
|
||||
merged_prims[last_valid_prim].count = idx - start;
|
||||
}
|
||||
node->merged.prims[last_valid_prim].mode = mode;
|
||||
merged_prims[last_valid_prim].mode = mode;
|
||||
}
|
||||
|
||||
assert(idx > 0 && idx <= max_indices_count);
|
||||
|
||||
node->merged.prim_count = last_valid_prim + 1;
|
||||
unsigned merged_prim_count = last_valid_prim + 1;
|
||||
node->merged.ib.ptr = NULL;
|
||||
node->merged.ib.count = idx;
|
||||
node->merged.ib.index_size_shift = (GL_UNSIGNED_INT - GL_UNSIGNED_BYTE) >> 1;
|
||||
node->merged.min_index = min_index;
|
||||
node->merged.max_index = max_index;
|
||||
|
||||
if (!indices_offset) {
|
||||
/* Allocate a new index buffer */
|
||||
|
|
@ -804,7 +801,42 @@ compile_vertex_list(struct gl_context *ctx)
|
|||
node->prim_count = 0;
|
||||
}
|
||||
|
||||
/* Prepare for DrawGallium */
|
||||
memset(&node->merged.info, 0, sizeof(struct pipe_draw_info));
|
||||
/* The other info fields will be updated in vbo_save_playback_vertex_list */
|
||||
node->merged.info.index_size = 4;
|
||||
node->merged.info.instance_count = 1;
|
||||
node->merged.info.index.gl_bo = node->merged.ib.obj;
|
||||
node->merged.start_count = malloc(merged_prim_count * sizeof(struct pipe_draw_start_count));
|
||||
if (merged_prim_count == 1) {
|
||||
node->merged.info.mode = merged_prims[0].mode;
|
||||
node->merged.mode = NULL;
|
||||
} else {
|
||||
node->merged.mode = malloc(merged_prim_count * sizeof(unsigned char));
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < merged_prim_count; i++) {
|
||||
node->merged.start_count[i].start = merged_prims[i].start;
|
||||
node->merged.start_count[i].count = merged_prims[i].count;
|
||||
if (merged_prim_count > 1)
|
||||
node->merged.mode[i] = merged_prims[i].mode;
|
||||
}
|
||||
node->merged.num_draws = merged_prim_count;
|
||||
if (node->merged.num_draws > 1) {
|
||||
bool same_mode = true;
|
||||
for (unsigned i = 1; i < node->merged.num_draws && same_mode; i++) {
|
||||
same_mode = node->merged.mode[i] == node->merged.mode[0];
|
||||
}
|
||||
if (same_mode) {
|
||||
/* All primitives use the same mode, so we can simplify a bit */
|
||||
node->merged.info.mode = node->merged.mode[0];
|
||||
free(node->merged.mode);
|
||||
node->merged.mode = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free(indices);
|
||||
free(merged_prims);
|
||||
}
|
||||
|
||||
/* Deal with GL_COMPILE_AND_EXECUTE:
|
||||
|
|
|
|||
|
|
@ -225,15 +225,27 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data)
|
|||
if (node->vertex_count > 0) {
|
||||
bool draw_using_merged_prim = (ctx->Const.AllowIncorrectPrimitiveId ||
|
||||
ctx->_PrimitiveIDIsUnused) &&
|
||||
node->merged.prims;
|
||||
node->merged.num_draws;
|
||||
if (!draw_using_merged_prim) {
|
||||
ctx->Driver.Draw(ctx, node->prims, node->prim_count,
|
||||
NULL, true,
|
||||
false, 0, node->min_index, node->max_index, 1, 0);
|
||||
} else {
|
||||
ctx->Driver.Draw(ctx, node->merged.prims, node->merged.prim_count,
|
||||
&node->merged.ib, true,
|
||||
false, 0, node->merged.min_index, node->merged.max_index, 1, 0);
|
||||
struct pipe_draw_info *info = (struct pipe_draw_info *) &node->merged.info;
|
||||
info->vertices_per_patch = ctx->TessCtrlProgram.patch_vertices;
|
||||
void *gl_bo = info->index.gl_bo;
|
||||
if (node->merged.mode) {
|
||||
ctx->Driver.DrawGalliumComplex(ctx, info,
|
||||
node->merged.start_count,
|
||||
node->merged.mode,
|
||||
NULL,
|
||||
node->merged.num_draws);
|
||||
} else {
|
||||
ctx->Driver.DrawGallium(ctx, info,
|
||||
node->merged.start_count,
|
||||
node->merged.num_draws);
|
||||
}
|
||||
info->index.gl_bo = gl_bo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue