Mesa (master): r300-gallium: Add draw_arrays and friends.

Corbin Simpson csimpson at kemper.freedesktop.org
Mon Feb 16 11:17:09 UTC 2009


Module: Mesa
Branch: master
Commit: 1b77138a1effe2e18a9ce9e16c43852ff855a7be
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=1b77138a1effe2e18a9ce9e16c43852ff855a7be

Author: Corbin Simpson <MostAwesomeDude at gmail.com>
Date:   Mon Feb 16 02:53:34 2009 -0800

r300-gallium: Add draw_arrays and friends.

This is the last bit of Gallium-side plumbing for drawing things.
>From this point on, the only missing parts should be in r3xx-specific
code areas...

---

 src/gallium/drivers/r300/r300_context.c    |   76 +++++++++++++++++++++++++++-
 src/gallium/drivers/r300/r300_context.h    |   36 ++++++++++----
 src/gallium/drivers/r300/r300_emit.c       |    2 +-
 src/gallium/drivers/r300/r300_state.c      |   28 ++++++++++-
 src/gallium/drivers/r300/r300_swtcl_emit.c |   20 ++++----
 5 files changed, 138 insertions(+), 24 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 7b605ae..37dc9e8 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -22,6 +22,76 @@
 
 #include "r300_context.h"
 
+static boolean r300_draw_range_elements(struct pipe_context* pipe,
+                                        struct pipe_buffer* indexBuffer,
+                                        unsigned indexSize,
+                                        unsigned minIndex,
+                                        unsigned maxIndex,
+                                        unsigned mode,
+                                        unsigned start,
+                                        unsigned count)
+{
+    struct r300_context* r300 = r300_context(pipe);
+    int i;
+
+    if (r300->dirty_state) {
+        r300_update_derived_state(r300);
+        r300_emit_dirty_state(r300);
+    }
+
+    for (i = 0; i < r300->vertex_buffer_count; i++) {
+        void* buf = pipe_buffer_map(pipe->screen,
+                                    r300->vertex_buffers[i].buffer,
+                                    PIPE_BUFFER_USAGE_CPU_READ);
+        draw_set_mapped_vertex_buffer(r300->draw, i, buf);
+    }
+
+    if (indexBuffer) {
+        void* indices = pipe_buffer_map(pipe->screen, indexBuffer,
+                                        PIPE_BUFFER_USAGE_CPU_READ);
+        draw_set_mapped_element_buffer_range(r300->draw, indexSize,
+                                             minIndex, maxIndex, indices);
+    } else {
+        draw_set_mapped_element_buffer(r300->draw, 0, NULL);
+    }
+
+    draw_set_mapped_constant_buffer(r300->draw,
+            r300->shader_constants[PIPE_SHADER_VERTEX].constants,
+            r300->shader_constants[PIPE_SHADER_VERTEX].user_count *
+                (sizeof(float) * 4));
+
+    /* Abandon all hope, ye who enter here. */
+    draw_arrays(r300->draw, mode, start, count);
+
+    for (i = 0; i < r300->vertex_buffer_count; i++) {
+        pipe_buffer_unmap(pipe->screen, r300->vertex_buffers[i].buffer);
+        draw_set_mapped_vertex_buffer(r300->draw, i, NULL);
+    }
+
+    if (indexBuffer) {
+        pipe_buffer_unmap(pipe->screen, indexBuffer);
+        draw_set_mapped_element_buffer_range(r300->draw, 0, start,
+                                             start + count - 1, NULL);
+    }
+
+    return true;
+}
+
+static boolean r300_draw_elements(struct pipe_context* pipe,
+                                  struct pipe_buffer* indexBuffer,
+                                  unsigned indexSize, unsigned mode,
+                                  unsigned start, unsigned count)
+{
+    return r300_draw_range_elements(pipe, indexBuffer, indexSize, 0, ~0,
+                                    mode, start, count);
+}
+
+static boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
+                                unsigned start, unsigned count)
+{
+    return r300_draw_elements(pipe, NULL, 0, mode, start, count);
+}
+
 static void r300_destroy_context(struct pipe_context* context) {
     struct r300_context* r300 = r300_context(context);
 
@@ -49,8 +119,12 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
 
     r300->context.clear = r300_clear;
 
+    r300->context.draw_arrays = r300_draw_arrays;
+    r300->context.draw_elements = r300_draw_elements;
+    r300->context.draw_range_elements = r300_draw_range_elements;
+
     r300->draw = draw_create();
-    /*XXX draw_set_rasterize_stage(r300->draw, r300_draw_swtcl_stage(r300));*/
+    draw_set_rasterize_stage(r300->draw, r300_draw_swtcl_stage(r300));
 
     r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state);
     r300->scissor_state = CALLOC_STRUCT(r300_scissor_state);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index caedbb8..53e41bf 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -88,20 +88,31 @@ struct r300_texture_state {
 
 #define R300_NEW_BLEND           0x0000001
 #define R300_NEW_BLEND_COLOR     0x0000002
-#define R300_NEW_DSA             0x0000004
-#define R300_NEW_FRAMEBUFFERS    0x0000008
-#define R300_NEW_FRAGMENT_SHADER 0x0000010
-#define R300_NEW_RASTERIZER      0x0000020
-#define R300_NEW_SAMPLER         0x0000040
-#define R300_NEW_SCISSOR         0x0004000
-#define R300_NEW_TEXTURE         0x0008000
-#define R300_NEW_VERTEX_FORMAT   0x0800000
-#define R300_NEW_VERTEX_SHADER   0x1000000
-#define R300_NEW_KITCHEN_SINK    0x1ffffff
+#define R300_NEW_CONSTANTS       0x0000004
+#define R300_NEW_DSA             0x0000008
+#define R300_NEW_FRAMEBUFFERS    0x0000010
+#define R300_NEW_FRAGMENT_SHADER 0x0000020
+#define R300_NEW_RASTERIZER      0x0000040
+#define R300_NEW_SAMPLER         0x0000080
+#define R300_NEW_SCISSOR         0x0008000
+#define R300_NEW_TEXTURE         0x0010000
+#define R300_NEW_VERTEX_FORMAT   0x1000000
+#define R300_NEW_VERTEX_SHADER   0x2000000
+#define R300_NEW_KITCHEN_SINK    0x3ffffff
 
 /* The next several objects are not pure Radeon state; they inherit from
  * various Gallium classes. */
 
+struct r300_constant_buffer {
+    /* Buffer of constants */
+    /* XXX first number should be raised */
+    float constants[8][4];
+    /* Number of user-defined constants */
+    int user_count;
+    /* Total number of constants */
+    int count;
+};
+
 struct r3xx_fragment_shader {
     /* Parent class */
     struct pipe_shader_state state;
@@ -188,6 +199,8 @@ struct r300_context {
     struct r300_blend_state* blend_state;
     /* Blend color state. */
     struct r300_blend_color_state* blend_color_state;
+    /* Shader constants. */
+    struct r300_constant_buffer shader_constants[PIPE_SHADER_TYPES];
     /* Depth, stencil, and alpha state. */
     struct r300_dsa_state* dsa_state;
     /* Fragment shader. */
@@ -205,6 +218,9 @@ struct r300_context {
     struct r300_texture* textures[8];
     struct r300_texture_state* texture_states[8];
     int texture_count;
+    /* Vertex buffers. */
+    struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
+    int vertex_buffer_count;
     /* Vertex information. */
     struct vertex_info vertex_info;
     /* Bitmask of dirty state objects. */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index cfc7036..32c9681 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -219,7 +219,7 @@ void r300_emit_scissor_state(struct r300_context* r300,
 }
 
 /* Emit all dirty state. */
-static void r300_emit_dirty_state(struct r300_context* r300)
+void r300_emit_dirty_state(struct r300_context* r300)
 {
     struct r300_screen* r300screen =
         (struct r300_screen*)r300->context.screen;
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 6ecd61e..559844f 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -22,7 +22,9 @@
 
 #include "util/u_math.h"
 #include "util/u_pack_color.h"
+
 #include "pipe/p_debug.h"
+#include "pipe/internal/p_winsys_screen.h"
 
 #include "r300_context.h"
 #include "r300_reg.h"
@@ -211,7 +213,24 @@ static void
                              uint shader, uint index,
                              const struct pipe_constant_buffer* buffer)
 {
-    /* XXX */
+    struct r300_context* r300 = r300_context(pipe);
+
+    /* This entire chunk of code seems ever-so-slightly baked.
+     * It's as if I've got pipe_buffer* matryoshkas... */
+    if (buffer && buffer->buffer && buffer->buffer->size) {
+        void* map = pipe->winsys->buffer_map(pipe->winsys, buffer->buffer,
+                                             PIPE_BUFFER_USAGE_CPU_READ);
+        memcpy(r300->shader_constants[shader].constants,
+            map, buffer->buffer->size);
+        pipe->winsys->buffer_unmap(pipe->winsys, map);
+
+        r300->shader_constants[shader].user_count =
+            buffer->buffer->size / (sizeof(float) * 4);
+    } else {
+        r300->shader_constants[shader].user_count = 0;
+    }
+
+    r300->dirty_state |= R300_NEW_CONSTANTS;
 }
 
 static uint32_t translate_depth_stencil_function(int zs_func) {
@@ -738,7 +757,12 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
                                     const struct pipe_vertex_buffer* buffers)
 {
     struct r300_context* r300 = r300_context(pipe);
-    /* XXX Draw */
+
+    memcpy(r300->vertex_buffers, buffers,
+        sizeof(struct pipe_vertex_buffer) * count);
+
+    r300->vertex_buffer_count = count;
+
     draw_flush(r300->draw);
     draw_set_vertex_buffers(r300->draw, count, buffers);
 }
diff --git a/src/gallium/drivers/r300/r300_swtcl_emit.c b/src/gallium/drivers/r300/r300_swtcl_emit.c
index e51ac2c..ca078d6 100644
--- a/src/gallium/drivers/r300/r300_swtcl_emit.c
+++ b/src/gallium/drivers/r300/r300_swtcl_emit.c
@@ -54,22 +54,22 @@ static INLINE void r300_emit_vertex(struct r300_context* r300,
         j = vinfo->attrib[i].src_index;
         switch (vinfo->attrib[i].emit) {
             case EMIT_1F:
-                CS_OUT_32F(vertex->data[j][0]);
+                OUT_CS_32F(vertex->data[j][0]);
                 break;
             case EMIT_2F:
-                CS_OUT_32F(vertex->data[j][0]);
-                CS_OUT_32F(vertex->data[j][1]);
+                OUT_CS_32F(vertex->data[j][0]);
+                OUT_CS_32F(vertex->data[j][1]);
                 break;
             case EMIT_3F:
-                CS_OUT_32F(vertex->data[j][0]);
-                CS_OUT_32F(vertex->data[j][1]);
-                CS_OUT_32F(vertex->data[j][2]);
+                OUT_CS_32F(vertex->data[j][0]);
+                OUT_CS_32F(vertex->data[j][1]);
+                OUT_CS_32F(vertex->data[j][2]);
                 break;
             case EMIT_4F:
-                CS_OUT_32F(vertex->data[j][0]);
-                CS_OUT_32F(vertex->data[j][1]);
-                CS_OUT_32F(vertex->data[j][2]);
-                CS_OUT_32F(vertex->data[j][3]);
+                OUT_CS_32F(vertex->data[j][0]);
+                OUT_CS_32F(vertex->data[j][1]);
+                OUT_CS_32F(vertex->data[j][2]);
+                OUT_CS_32F(vertex->data[j][3]);
                 break;
             default:
                 debug_printf("r300: Unknown emit value %d\n",




More information about the mesa-commit mailing list