summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2008-06-02 12:59:16 +0100
committerKeith Whitwell <[email protected]>2008-06-04 11:25:54 +0100
commit0a4aea0e86a897d9afb9f2a0ec27f03faf8f1b21 (patch)
tree9873d3bcf68cf71e2e5abc7b60f911ad73cc5f90
parentc218b8c6c6593f434a749bf67ad976007e6eef61 (diff)
draw: respect driver's max vertex buffer size
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_vbuf.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_private.h1
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.h8
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_emit.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c17
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c16
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_varray.c5
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h11
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_vcache.c13
10 files changed, 64 insertions, 25 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
index d514e28b77f..9e5597c32c4 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
@@ -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);
diff --git a/src/gallium/auxiliary/draw/draw_private.h b/src/gallium/auxiliary/draw/draw_private.h
index 423f64262b8..1865601cc04 100644
--- a/src/gallium/auxiliary/draw/draw_private.h
+++ b/src/gallium/auxiliary/draw/draw_private.h
@@ -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)
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index 6b8ba1d171b..3d2a9c78b70 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -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],
diff --git a/src/gallium/auxiliary/draw/draw_pt_emit.c b/src/gallium/auxiliary/draw/draw_pt_emit.c
index cf87cde9965..a02f1f46fed 100644
--- a/src/gallium/auxiliary/draw/draw_pt_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_emit.c
@@ -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));
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index 09bdc5fb5e1..083ce105bfd 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -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));
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
index efa6dddbda8..5a1d79d996e 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
@@ -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);
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
index eb6988ff03b..25118712a66 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -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);
-
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_varray.c b/src/gallium/auxiliary/draw/draw_pt_varray.c
index f19e8850b3e..f5495a80c78 100644
--- a/src/gallium/auxiliary/draw/draw_pt_varray.c
+++ b/src/gallium/auxiliary/draw/draw_pt_varray.c
@@ -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 );
}
diff --git a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
index 114ed371a06..6e5e30f38e5 100644
--- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
+++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
@@ -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);
diff --git a/src/gallium/auxiliary/draw/draw_pt_vcache.c b/src/gallium/auxiliary/draw/draw_pt_vcache.c
index ad86ab42925..2eafe270bc0 100644
--- a/src/gallium/auxiliary/draw/draw_pt_vcache.c
+++ b/src/gallium/auxiliary/draw/draw_pt_vcache.c
@@ -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 );
}