r300g: fix rendering with no vertex elements
authorMarek Olšák <maraeo@gmail.com>
Sun, 14 Nov 2010 17:57:14 +0000 (18:57 +0100)
committerMarek Olšák <maraeo@gmail.com>
Sat, 20 Nov 2010 15:20:48 +0000 (16:20 +0100)
Fixes glsl-vs-point-size, although I meant to fix glsl-novertexdata.
Since swrast fails glsl-novertexdata too, I guess it's a core issue.

src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_render.c
src/gallium/drivers/r300/r300_state.c

index fb099e2a7d0e0f1e9392e98eda7acaa75f272d30..e8c09b214af4fa8e189bc64e11792f786757515f 100644 (file)
@@ -79,6 +79,9 @@ static void r300_release_referenced_objects(struct r300_context *r300)
                 NULL);
     }
 
+    /* The dummy VBO. */
+    pipe_resource_reference(&r300->dummy_vb, NULL);
+
     /* The SWTCL VBO. */
     pipe_resource_reference(&r300->vbo, NULL);
 
@@ -488,6 +491,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
         rtempl.target = PIPE_TEXTURE_2D;
         rtempl.format = PIPE_FORMAT_I8_UNORM;
         rtempl.bind = PIPE_BIND_SAMPLER_VIEW;
+        rtempl.usage = PIPE_USAGE_IMMUTABLE;
         rtempl.width0 = 1;
         rtempl.height0 = 1;
         rtempl.depth0 = 1;
@@ -501,6 +505,19 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
         pipe_resource_reference(&tex, NULL);
     }
 
+    {
+        struct pipe_resource vb = {};
+        vb.target = PIPE_BUFFER;
+        vb.format = PIPE_FORMAT_R8_UNORM;
+        vb.bind = PIPE_BIND_VERTEX_BUFFER;
+        vb.usage = PIPE_USAGE_IMMUTABLE;
+        vb.width0 = sizeof(float) * 16;
+        vb.height0 = 1;
+        vb.depth0 = 1;
+
+        r300->dummy_vb = screen->resource_create(screen, &vb);
+    }
+
     return &r300->context;
 
  fail:
index b59bc00261011aa78b30ac7a39fe78d9b1977e01..7217c51b9516cf05307a6c99d391de3a69718e38 100644 (file)
@@ -480,6 +480,10 @@ struct r300_context {
      * dummy texture there. */
     struct r300_sampler_view *texkill_sampler;
 
+    /* When no vertex buffer is set, this one is used instead to prevent
+     * hardlocks. */
+    struct pipe_resource *dummy_vb;
+
     /* The currently active query. */
     struct r300_query *query_current;
     /* The saved query for blitter operations. */
index 000f8a0d4810bd75813faf0fa7ace8eedd770c64..60700cf30372888d7f726f85854860395194df98 100644 (file)
@@ -643,10 +643,6 @@ static void r300_draw_vbo(struct pipe_context* pipe,
         return;
     }
 
-    if (!r300->velems->count || !r300->vertex_buffer_count) {
-        return;
-    }
-
     /* Index buffer range checking. */
     if (indexed) {
         assert(r300->index_buffer.offset % r300->index_buffer.index_size == 0);
index bd08bf2d3fd5573d938a378c6efa13b4e391b950..247c22216e18806bc573e9958d50b8eb4c0ab355 100644 (file)
@@ -1448,6 +1448,15 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
     struct pipe_vertex_buffer *vbo;
     unsigned i, max_index = (1 << 24) - 1;
     boolean any_user_buffer = FALSE;
+    struct pipe_vertex_buffer dummy_vb = {0};
+
+    /* There must be at least one vertex buffer set, otherwise it locks up. */
+    if (!count) {
+        dummy_vb.buffer = r300->dummy_vb;
+        dummy_vb.max_index = r300->dummy_vb->width0 / 4;
+        buffers = &dummy_vb;
+        count = 1;
+    }
 
     if (count == r300->vertex_buffer_count &&
         memcmp(r300->vertex_buffer, buffers,
@@ -1601,6 +1610,14 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
     struct r300_vertex_element_state *velems;
     unsigned i;
     enum pipe_format *format;
+    struct pipe_vertex_element dummy_attrib = {0};
+
+    /* R300 Programmable Stream Control (PSC) doesn't support 0 vertex elements. */
+    if (!count) {
+        dummy_attrib.src_format = PIPE_FORMAT_R8G8B8A8_UNORM;
+        attribs = &dummy_attrib;
+        count = 1;
+    }
 
     assert(count <= PIPE_MAX_ATTRIBS);
     velems = CALLOC_STRUCT(r300_vertex_element_state);
@@ -1667,7 +1684,8 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
              * swizzles are already set up.
              * Also compute the vertex size. */
             for (i = 0; i < count; i++) {
-                /* This is OK because we check for aligned strides too. */
+                /* This is OK because we check for aligned strides too
+                 * elsewhere. */
                 velems->hw_format_size[i] =
                     align(util_format_get_blocksize(velems->hw_format[i]), 4);
                 velems->vertex_size_dwords += velems->hw_format_size[i] / 4;