mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 11:48:06 +02:00
draw: respect driver's max vertex buffer size
This commit is contained in:
parent
c218b8c6c6
commit
0a4aea0e86
10 changed files with 64 additions and 25 deletions
|
|
@ -387,6 +387,12 @@ vbuf_alloc_vertices( struct vbuf_stage *vbuf )
|
|||
|
||||
/* Allocate a new vertex buffer */
|
||||
vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size;
|
||||
|
||||
/* Must always succeed -- driver gives us a
|
||||
* 'max_vertex_buffer_bytes' which it guarantees it can allocate,
|
||||
* and it will flush itself if necessary to do so. If this does
|
||||
* fail, we are basically without usable hardware.
|
||||
*/
|
||||
vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render,
|
||||
(ushort) vbuf->vertex_size,
|
||||
(ushort) vbuf->max_vertices);
|
||||
|
|
|
|||
|
|
@ -265,6 +265,7 @@ void draw_pipeline_destroy( struct draw_context *draw );
|
|||
* These flags expected at first vertex of lines & triangles when
|
||||
* unfilled and/or line stipple modes are operational.
|
||||
*/
|
||||
#define DRAW_PIPE_MAX_VERTICES (0x1<<12)
|
||||
#define DRAW_PIPE_EDGE_FLAG_0 (0x1<<12)
|
||||
#define DRAW_PIPE_EDGE_FLAG_1 (0x2<<12)
|
||||
#define DRAW_PIPE_EDGE_FLAG_2 (0x4<<12)
|
||||
|
|
|
|||
|
|
@ -84,7 +84,8 @@ struct draw_pt_front_end {
|
|||
struct draw_pt_middle_end {
|
||||
void (*prepare)( struct draw_pt_middle_end *,
|
||||
unsigned prim,
|
||||
unsigned opt );
|
||||
unsigned opt,
|
||||
unsigned *max_vertices );
|
||||
|
||||
void (*run)( struct draw_pt_middle_end *,
|
||||
const unsigned *fetch_elts,
|
||||
|
|
@ -105,6 +106,8 @@ struct draw_pt_middle_end {
|
|||
const ushort *draw_elts,
|
||||
unsigned draw_count );
|
||||
|
||||
int (*get_max_vertex_count)( struct draw_pt_middle_end * );
|
||||
|
||||
void (*finish)( struct draw_pt_middle_end * );
|
||||
void (*destroy)( struct draw_pt_middle_end * );
|
||||
};
|
||||
|
|
@ -158,7 +161,8 @@ boolean draw_pt_get_edgeflag( struct draw_context *draw,
|
|||
struct pt_emit;
|
||||
|
||||
void draw_pt_emit_prepare( struct pt_emit *emit,
|
||||
unsigned prim );
|
||||
unsigned prim,
|
||||
unsigned *max_vertices );
|
||||
|
||||
void draw_pt_emit( struct pt_emit *emit,
|
||||
const float (*vertex_data)[4],
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ struct pt_emit {
|
|||
};
|
||||
|
||||
void draw_pt_emit_prepare( struct pt_emit *emit,
|
||||
unsigned prim )
|
||||
unsigned prim,
|
||||
unsigned *max_vertices )
|
||||
{
|
||||
struct draw_context *draw = emit->draw;
|
||||
const struct vertex_info *vinfo;
|
||||
|
|
@ -139,6 +140,9 @@ void draw_pt_emit_prepare( struct pt_emit *emit,
|
|||
translate_key_sanitize(&hw_key);
|
||||
emit->translate = translate_cache_find(emit->cache, &hw_key);
|
||||
}
|
||||
|
||||
*max_vertices = (draw->render->max_vertex_buffer_bytes /
|
||||
(vinfo->size * 4));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -90,7 +90,8 @@ struct fetch_emit_middle_end {
|
|||
|
||||
static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
|
||||
unsigned prim,
|
||||
unsigned opt )
|
||||
unsigned opt,
|
||||
unsigned *max_vertices )
|
||||
{
|
||||
struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle;
|
||||
struct draw_context *draw = feme->draw;
|
||||
|
|
@ -196,6 +197,9 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
|
|||
draw->pt.vertex_buffer[i].buffer_offset),
|
||||
draw->pt.vertex_buffer[i].pitch );
|
||||
}
|
||||
|
||||
*max_vertices = (draw->render->max_vertex_buffer_bytes /
|
||||
(vinfo->size * 4));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,8 @@ struct fetch_shade_emit {
|
|||
|
||||
static void fse_prepare( struct draw_pt_middle_end *middle,
|
||||
unsigned prim,
|
||||
unsigned opt )
|
||||
unsigned opt,
|
||||
unsigned *max_vertices )
|
||||
{
|
||||
struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
|
||||
struct draw_context *draw = fse->draw;
|
||||
|
|
@ -189,6 +190,11 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
|
|||
draw->pt.vertex_buffer[buf].pitch );
|
||||
}
|
||||
|
||||
*max_vertices = (draw->render->max_vertex_buffer_bytes /
|
||||
(vinfo->size * 4));
|
||||
|
||||
|
||||
|
||||
//return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +210,6 @@ static void fse_run_linear( struct draw_pt_middle_end *middle,
|
|||
{
|
||||
struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
|
||||
struct draw_context *draw = fse->draw;
|
||||
unsigned alloc_count = align(count, 4);
|
||||
char *hw_verts;
|
||||
|
||||
/* XXX: need to flush to get prim_vbuf.c to release its allocation??
|
||||
|
|
@ -213,7 +218,7 @@ static void fse_run_linear( struct draw_pt_middle_end *middle,
|
|||
|
||||
hw_verts = draw->render->allocate_vertices( draw->render,
|
||||
(ushort)fse->key.output_stride,
|
||||
(ushort)alloc_count );
|
||||
(ushort)count );
|
||||
|
||||
if (!hw_verts) {
|
||||
assert(0);
|
||||
|
|
@ -264,7 +269,6 @@ fse_run(struct draw_pt_middle_end *middle,
|
|||
{
|
||||
struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
|
||||
struct draw_context *draw = fse->draw;
|
||||
unsigned alloc_count = align(fetch_count, 4);
|
||||
void *hw_verts;
|
||||
|
||||
/* XXX: need to flush to get prim_vbuf.c to release its allocation??
|
||||
|
|
@ -273,7 +277,7 @@ fse_run(struct draw_pt_middle_end *middle,
|
|||
|
||||
hw_verts = draw->render->allocate_vertices( draw->render,
|
||||
(ushort)fse->key.output_stride,
|
||||
(ushort)alloc_count );
|
||||
(ushort)fetch_count );
|
||||
if (!hw_verts) {
|
||||
assert(0);
|
||||
return;
|
||||
|
|
@ -319,7 +323,6 @@ static void fse_run_linear_elts( struct draw_pt_middle_end *middle,
|
|||
{
|
||||
struct fetch_shade_emit *fse = (struct fetch_shade_emit *)middle;
|
||||
struct draw_context *draw = fse->draw;
|
||||
unsigned alloc_count = align(count, 4);
|
||||
char *hw_verts;
|
||||
|
||||
/* XXX: need to flush to get prim_vbuf.c to release its allocation??
|
||||
|
|
@ -328,7 +331,7 @@ static void fse_run_linear_elts( struct draw_pt_middle_end *middle,
|
|||
|
||||
hw_verts = draw->render->allocate_vertices( draw->render,
|
||||
(ushort)fse->key.output_stride,
|
||||
(ushort)alloc_count );
|
||||
(ushort)count );
|
||||
|
||||
if (!hw_verts) {
|
||||
assert(0);
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ struct fetch_pipeline_middle_end {
|
|||
|
||||
static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
|
||||
unsigned prim,
|
||||
unsigned opt )
|
||||
unsigned opt,
|
||||
unsigned *max_vertices )
|
||||
{
|
||||
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
|
||||
struct draw_context *draw = fpme->draw;
|
||||
|
|
@ -86,14 +87,21 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
|
|||
(boolean)draw->rasterizer->gl_rasterization_rules );
|
||||
|
||||
|
||||
if (!(opt & PT_PIPELINE))
|
||||
if (!(opt & PT_PIPELINE)) {
|
||||
draw_pt_emit_prepare( fpme->emit,
|
||||
prim );
|
||||
prim,
|
||||
max_vertices );
|
||||
|
||||
*max_vertices = MAX2( *max_vertices,
|
||||
DRAW_PIPE_MAX_VERTICES );
|
||||
}
|
||||
else {
|
||||
*max_vertices = DRAW_PIPE_MAX_VERTICES;
|
||||
}
|
||||
|
||||
/* No need to prepare the shader.
|
||||
*/
|
||||
vs->prepare(vs, draw);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ struct varray_frontend {
|
|||
|
||||
unsigned fetch_start;
|
||||
|
||||
unsigned driver_fetch_max;
|
||||
unsigned fetch_max;
|
||||
|
||||
struct draw_pt_middle_end *middle;
|
||||
|
||||
unsigned input_prim;
|
||||
|
|
@ -183,7 +186,7 @@ static void varray_prepare(struct draw_pt_front_end *frontend,
|
|||
varray->output_prim = decompose_prim[prim];
|
||||
|
||||
varray->middle = middle;
|
||||
middle->prepare(middle, varray->output_prim, opt);
|
||||
middle->prepare(middle, varray->output_prim, opt, &varray->fetch_max );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ static void FUNC(struct draw_pt_front_end *frontend,
|
|||
case PIPE_PRIM_QUAD_STRIP:
|
||||
for (j = 0; j < count;) {
|
||||
unsigned remaining = count - j;
|
||||
unsigned nr = trim( MIN2(FETCH_MAX, remaining), first, incr );
|
||||
unsigned nr = trim( MIN2(varray->fetch_max, remaining), first, incr );
|
||||
varray_flush_linear(varray, start + j, nr);
|
||||
j += nr;
|
||||
if (nr != remaining)
|
||||
|
|
@ -50,8 +50,9 @@ static void FUNC(struct draw_pt_front_end *frontend,
|
|||
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
if (count >= 2) {
|
||||
unsigned fetch_max = MIN2(FETCH_MAX, varray->fetch_max);
|
||||
for (j = 0; j + first <= count; j += i) {
|
||||
unsigned end = MIN2(FETCH_MAX, count - j);
|
||||
unsigned end = MIN2(fetch_max, count - j);
|
||||
end -= (end % incr);
|
||||
for (i = 1; i < end; i++) {
|
||||
LINE(varray, i - 1, i);
|
||||
|
|
@ -66,9 +67,10 @@ static void FUNC(struct draw_pt_front_end *frontend,
|
|||
|
||||
|
||||
case PIPE_PRIM_POLYGON:
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
case PIPE_PRIM_TRIANGLE_FAN: {
|
||||
unsigned fetch_max = MIN2(FETCH_MAX, varray->fetch_max);
|
||||
for (j = 0; j + first <= count; j += i) {
|
||||
unsigned end = MIN2(FETCH_MAX, count - j);
|
||||
unsigned end = MIN2(fetch_max, count - j);
|
||||
end -= (end % incr);
|
||||
for (i = 2; i < end; i++) {
|
||||
TRIANGLE(varray, 0, i - 1, i);
|
||||
|
|
@ -78,6 +80,7 @@ static void FUNC(struct draw_pt_front_end *frontend,
|
|||
varray_flush(varray);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@
|
|||
#include "draw/draw_pt.h"
|
||||
|
||||
|
||||
#define CACHE_MAX 1024
|
||||
#define FETCH_MAX 4096
|
||||
#define CACHE_MAX 256
|
||||
#define FETCH_MAX 256
|
||||
#define DRAW_MAX (16*1024)
|
||||
|
||||
struct vcache_frontend {
|
||||
|
|
@ -52,6 +52,7 @@ struct vcache_frontend {
|
|||
|
||||
unsigned draw_count;
|
||||
unsigned fetch_count;
|
||||
unsigned fetch_max;
|
||||
|
||||
struct draw_pt_middle_end *middle;
|
||||
|
||||
|
|
@ -296,10 +297,12 @@ static void vcache_check_run( struct draw_pt_front_end *frontend,
|
|||
ushort *storage = NULL;
|
||||
|
||||
|
||||
if (0) debug_printf("fetch_count %d draw_count %d\n", fetch_count, draw_count);
|
||||
if (0) debug_printf("fetch_count %d fetch_max %d draw_count %d\n", fetch_count,
|
||||
vcache->fetch_max,
|
||||
draw_count);
|
||||
|
||||
if (max_index == 0xffffffff ||
|
||||
fetch_count >= FETCH_MAX ||
|
||||
fetch_count >= vcache->fetch_max ||
|
||||
fetch_count > draw_count) {
|
||||
if (0) debug_printf("fail\n");
|
||||
goto fail;
|
||||
|
|
@ -409,7 +412,7 @@ static void vcache_prepare( struct draw_pt_front_end *frontend,
|
|||
vcache->output_prim = draw_pt_reduced_prim(prim);
|
||||
|
||||
vcache->middle = middle;
|
||||
middle->prepare( middle, vcache->output_prim, opt );
|
||||
middle->prepare( middle, vcache->output_prim, opt, &vcache->fetch_max );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue