summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/r300/r300_render.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index d5ba4fab499..830b0d9d875 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -740,6 +740,55 @@ static void r300_draw_elements_instanced(struct r300_context *r300,
r300_draw_elements(r300, info, i);
}
+static unsigned r300_max_vertex_count(struct r300_context *r300)
+{
+ unsigned i, nr = r300->velems->count;
+ struct pipe_vertex_element *velems = r300->velems->velem;
+ unsigned result = ~0;
+
+ for (i = 0; i < nr; i++) {
+ struct pipe_vertex_buffer *vb =
+ &r300->vertex_buffer[velems[i].vertex_buffer_index];
+ unsigned size, max_count, value;
+
+ /* We're not interested in constant and per-instance attribs. */
+ if (!vb->buffer ||
+ !vb->stride ||
+ velems[i].instance_divisor) {
+ continue;
+ }
+
+ size = vb->buffer->width0;
+
+ /* Subtract buffer_offset. */
+ value = vb->buffer_offset;
+ if (value >= size) {
+ return 0;
+ }
+ size -= value;
+
+ /* Subtract src_offset. */
+ value = velems[i].src_offset;
+ if (value >= size) {
+ return 0;
+ }
+ size -= value;
+
+ /* Subtract format_size. */
+ value = r300->velems->format_size[i];
+ if (value >= size) {
+ return 0;
+ }
+ size -= value;
+
+ /* Compute the max count. */
+ max_count = 1 + size / vb->stride;
+ result = MIN2(result, max_count);
+ }
+ return result;
+}
+
+
static void r300_draw_vbo(struct pipe_context* pipe,
const struct pipe_draw_info *dinfo)
{
@@ -757,7 +806,7 @@ static void r300_draw_vbo(struct pipe_context* pipe,
/* Draw. */
if (info.indexed) {
- unsigned max_count = u_vbuf_draw_max_vertex_count(r300->vbuf_mgr);
+ unsigned max_count = r300_max_vertex_count(r300);
if (!max_count) {
fprintf(stderr, "r300: Skipping a draw command. There is a buffer "