summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2011-05-14 19:25:55 +0200
committerMarek Olšák <[email protected]>2011-05-14 20:03:03 +0200
commit51095f74cf92d3cada7366ce898ade7693570b48 (patch)
tree6d6b118c2dbe000f69c941ecf97ef0c436e1888c
parentad2999d2113356d526b39774eb8114e974dac048 (diff)
u_vbuf_mgr: fix max_index computation once again
See how I compute and use the 'unused' variable in the code. It's crucial for getting max_index right. Fixed with the help of apitrace. (bisecting the problematic draw call manually was not fun though) This should fix: https://bugs.freedesktop.org/show_bug.cgi?id=36268 https://bugs.freedesktop.org/show_bug.cgi?id=36609
-rw-r--r--src/gallium/auxiliary/util/u_vbuf_mgr.c62
1 files changed, 47 insertions, 15 deletions
diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.c b/src/gallium/auxiliary/util/u_vbuf_mgr.c
index dea2928f950..a034483ee5c 100644
--- a/src/gallium/auxiliary/util/u_vbuf_mgr.c
+++ b/src/gallium/auxiliary/util/u_vbuf_mgr.c
@@ -53,9 +53,11 @@ struct u_vbuf_mgr_elements {
unsigned count;
struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS];
- /* If (velem[i].src_format != real_format[i]), the vertex buffer
+ unsigned src_format_size[PIPE_MAX_ATTRIBS];
+
+ /* If (velem[i].src_format != native_format[i]), the vertex buffer
* referenced by the vertex element cannot be used for rendering and
- * its vertex data must be translated to real_format[i]. */
+ * its vertex data must be translated to native_format[i]. */
enum pipe_format native_format[PIPE_MAX_ATTRIBS];
unsigned native_format_size[PIPE_MAX_ATTRIBS];
@@ -353,6 +355,8 @@ u_vbuf_mgr_create_vertex_elements(struct u_vbuf_mgr *mgrb,
for (i = 0; i < count; i++) {
enum pipe_format format = ve->ve[i].src_format;
+ ve->src_format_size[i] = util_format_get_blocksize(format);
+
/* Choose a native format.
* For now we don't care about the alignment, that's going to
* be sorted out later. */
@@ -460,7 +464,6 @@ void u_vbuf_mgr_set_vertex_buffers(struct u_vbuf_mgr *mgrb,
struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
unsigned i;
- mgr->b.max_index = ~0;
mgr->any_user_vbs = FALSE;
mgr->incompatible_vb_layout = FALSE;
@@ -483,23 +486,16 @@ void u_vbuf_mgr_set_vertex_buffers(struct u_vbuf_mgr *mgrb,
pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, vb->buffer);
pipe_resource_reference(&mgr->b.real_vertex_buffer[i], NULL);
- if (u_vbuf_resource(vb->buffer)->user_ptr) {
- mgr->any_user_vbs = TRUE;
+ if (!vb->buffer) {
continue;
}
- pipe_resource_reference(&mgr->b.real_vertex_buffer[i], vb->buffer);
-
- /* The stride of zero means we will be fetching only the first
- * vertex, so don't care about max_index. */
- if (!vb->stride) {
+ if (u_vbuf_resource(vb->buffer)->user_ptr) {
+ mgr->any_user_vbs = TRUE;
continue;
}
- /* Update the maximum index. */
- mgr->b.max_index =
- MIN2(mgr->b.max_index,
- (vb->buffer->width0 - vb->buffer_offset) / vb->stride - 1);
+ pipe_resource_reference(&mgr->b.real_vertex_buffer[i], vb->buffer);
}
for (; i < mgr->b.nr_real_vertex_buffers; i++) {
@@ -519,7 +515,7 @@ static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr,
unsigned instance_count,
boolean *upload_flushed)
{
- int i, nr = mgr->ve->count;
+ unsigned i, nr = mgr->ve->count;
unsigned count = max_index + 1 - min_index;
boolean uploaded[PIPE_MAX_ATTRIBS] = {0};
@@ -562,6 +558,40 @@ static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr,
}
}
+static void u_vbuf_mgr_compute_max_index(struct u_vbuf_mgr_priv *mgr)
+{
+ unsigned i, nr = mgr->ve->count;
+
+ mgr->b.max_index = ~0;
+
+ for (i = 0; i < nr; i++) {
+ struct pipe_vertex_buffer *vb =
+ &mgr->b.vertex_buffer[mgr->ve->ve[i].vertex_buffer_index];
+ int unused;
+ unsigned max_index;
+
+ if (!vb->buffer ||
+ !vb->stride ||
+ u_vbuf_resource(vb->buffer)->user_ptr) {
+ continue;
+ }
+
+ /* How many bytes is unused after the last vertex.
+ * width0 may be "count*stride - unused" and we have to compensate
+ * for that when dividing by stride. */
+ unused = vb->stride -
+ (mgr->ve->ve[i].src_offset + mgr->ve->src_format_size[i]);
+ assert(unused >= 0);
+
+ /* Compute the maximum index for this vertex element. */
+ max_index =
+ (vb->buffer->width0 - vb->buffer_offset + (unsigned)unused) /
+ vb->stride - 1;
+
+ mgr->b.max_index = MIN2(mgr->b.max_index, max_index);
+ }
+}
+
void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgrb,
const struct pipe_draw_info *info,
boolean *buffers_updated,
@@ -571,6 +601,8 @@ void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgrb,
boolean bufs_updated = FALSE, upload_flushed = FALSE;
int min_index, max_index;
+ u_vbuf_mgr_compute_max_index(mgr);
+
min_index = info->min_index - info->index_bias;
if (info->max_index == ~0) {
max_index = mgr->b.max_index;