r300: Add more state.
authorCorbin Simpson <MostAwesomeDude@gmail.com>
Sat, 17 Jan 2009 09:41:52 +0000 (01:41 -0800)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Mon, 2 Feb 2009 07:30:23 +0000 (23:30 -0800)
pipe_rasterizer_state is big, and I'm still processing it.

Todo:
- LOL EVERYTHING
- Moar cough syrup.
- Even moar cough syrup.

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

index 67cc1e4..6dfc9ed 100644 (file)
@@ -27,7 +27,8 @@ static void r300_destroy_context(struct pipe_context* context) {
 
     draw_destroy(r300->draw);
 
-    FREE(context);
+    FREE(r300->scissor_state);
+    FREE(r300);
 }
 
 struct pipe_context* r300_create_context(struct pipe_screen* screen,
@@ -47,10 +48,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
 
     r300->draw = draw_create();
 
-    /* XXX this is almost certainly wrong
-     * put this all in winsys, where we can get an FD
-    struct radeon_cs_manager* csm = radeon_cs_manager_gem_ctor(fd);
-    r300->cs = cs_gem_create(csm, 64 * 1024 / 4); */
+    r300->scissor_state = CALLOC_STRUCT(r300_scissor_state);
 
     r300_init_surface_functions(r300);
 
index 0551275..ea057bc 100644 (file)
@@ -46,9 +46,24 @@ struct r300_dsa_state {
     uint32_t stencil_ref_bf;    /* R300_ZB_STENCILREFMASK_BF: 0x4fd4 */
 };
 
+struct r300_rs_state {
+    uint32_t polygon_offset_enable; /* R300_SU_POLY_OFFSET_ENABLE: 0x42b4 */
+    uint32_t cull_mode;             /* R300_SU_CULL_MODE: 0x42b8 */
+    uint32_t depth_scale_front;     /* R300_SU_POLY_OFFSET_FRONT_SCALE: 0x42a4 */
+    uint32_t depth_offset_front;    /* R300_SU_POLY_OFFSET_FRONT_OFFSET: 0x42a8 */
+    uint32_t depth_scale_back;      /* R300_SU_POLY_OFFSET_BACK_SCALE: 0x42ac */
+    uint32_t depth_offset_back;     /* R300_SU_POLY_OFFSET_BACK_OFFSET: 0x42b0 */
+};
+
+struct r300_scissor_state {
+    uint32_t scissor_top_left;     /* R300_SC_SCISSORS_TL: 0x43e0 */
+    uint32_t scissor_bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */
+};
+
 #define R300_NEW_BLEND    0x1
 #define R300_NEW_DSA      0x2
-#define R300_NEW_SCISSOR  0x4
+#define R300_NEW_RS       0x4
+#define R300_NEW_SCISSOR  0x8
 
 struct r300_context {
     /* Parent class */
@@ -64,8 +79,10 @@ struct r300_context {
     struct r300_blend_state* blend_state;
     /* Depth, stencil, and alpha state. */
     struct r300_dsa_state* dsa_state;
+    /* Rasterizer state. */
+    struct r300_rs_state* rs_state;
     /* Scissor state. */
-    struct pipe_scissor_state* scissor_state;
+    struct r300_scissor_state* scissor_state;
 
     /* Bitmask of dirty state objects. */
     uint32_t dirty_state;
index 122e06c..7668b14 100644 (file)
 #include "r300_context.h"
 #include "r300_state.h"
 
+/* r300_state: Functions used to intialize state context by translating
+ * Gallium state objects into semi-native r300 state objects.
+ *
+ * XXX break this file up into pieces if it gets too big! */
+
+/* Pack a float into a dword. */
+static uint32_t pack_float_32(float f)
+{
+    union {
+        float f;
+        uint32_t u;
+    } u;
+
+    u.f = f;
+    return u.u;
+}
+
 static uint32_t translate_blend_function(int blend_func) {
     switch (blend_func) {
         case PIPE_BLEND_ADD:
@@ -229,7 +246,7 @@ static uint32_t translate_alpha_function(int alpha_func) {
  * On the Radeon, depth and stencil buffer setup are intertwined, which is
  * the reason for some of the strange-looking assignments across registers. */
 static void* r300_create_dsa_state(struct pipe_context* pipe,
-                                     struct pipe_depth_stencil_alpha_state* state)
+                                   struct pipe_depth_stencil_alpha_state* state)
 {
     struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);
 
@@ -309,6 +326,102 @@ static void r300_delete_dsa_state(struct pipe_context* pipe,
 {
     FREE(state);
 }
+#if 0
+struct pipe_rasterizer_state
+{
+    unsigned flatshade:1;
+    unsigned light_twoside:1;
+    unsigned fill_cw:2;        /**< PIPE_POLYGON_MODE_x */
+    unsigned fill_ccw:2;       /**< PIPE_POLYGON_MODE_x */
+    unsigned scissor:1;
+    unsigned poly_smooth:1;
+    unsigned poly_stipple_enable:1;
+    unsigned point_smooth:1;
+    unsigned point_sprite:1;
+    unsigned point_size_per_vertex:1; /**< size computed in vertex shader */
+    unsigned multisample:1;         /* XXX maybe more ms state in future */
+    unsigned line_smooth:1;
+    unsigned line_stipple_enable:1;
+    unsigned line_stipple_factor:8;  /**< [1..256] actually */
+    unsigned line_stipple_pattern:16;
+    unsigned line_last_pixel:1;
+    unsigned bypass_clipping:1;
+    unsigned bypass_vs:1; /**< Skip the vertex shader.  Note that the shader is
+    still needed though, to indicate inputs/outputs */
+    unsigned origin_lower_left:1;  /**< Is (0,0) the lower-left corner? */
+    unsigned flatshade_first:1;   /**< take color attribute from the first vertex of a primitive */
+    unsigned gl_rasterization_rules:1; /**< enable tweaks for GL rasterization?  */
+
+    float line_width;
+    float point_size;           /**< used when no per-vertex size */
+    float point_size_min;        /* XXX - temporary, will go away */
+    float point_size_max;        /* XXX - temporary, will go away */
+    ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */
+};
+#endif
+/* Create a new rasterizer state based on the CSO rasterizer state.
+ *
+ * This is a very large chunk of state, and covers most of the graphics
+ * backend (GB), geometry assembly (GA), and setup unit (SU) blocks.
+ *
+ * In a not entirely unironic sidenote, this state has nearly nothing to do
+ * with the actual block on the Radeon called the rasterizer (RS). */
+static void* r300_create_rs_state(struct pipe_context* pipe,
+                                          struct pipe_rasterizer_state* state)
+{
+    struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state);
+
+    /* Radeons don't think in "CW/CCW", they think in "front/back". */
+    if (state->front_winding == PIPE_WINDING_CW) {
+        rs->cull_mode = R300_FRONT_FACE_CW;
+
+        if (state->offset_cw) {
+            rs->polygon_offset_enable |= R300_FRONT_ENABLE;
+        }
+        if (state->offset_ccw) {
+            rs->polygon_offset_enable |= R300_BACK_ENABLE;
+        }
+    } else {
+        rs->cull_mode = R300_FRONT_FACE_CCW;
+
+        if (state->offset_ccw) {
+            rs->polygon_offset_enable |= R300_FRONT_ENABLE;
+        }
+        if (state->offset_cw) {
+            rs->polygon_offset_enable |= R300_BACK_ENABLE;
+        }
+    }
+    if (state->front_winding & state->cull_mode) {
+        rs->cull_mode |= R300_CULL_FRONT;
+    }
+    if (~(state->front_winding) & state->cull_mode) {
+        rs->cull_mode |= R300_CULL_BACK;
+    }
+
+    if (rs->polygon_offset_enable) {
+        rs->depth_offset_front = rs->depth_offset_back =
+                pack_float_32(state->offset_units);
+        rs->depth_scale_front = rs->depth_scale_back =
+                pack_float_32(state->offset_scale);
+    }
+
+    return (void*)rs;
+}
+
+/* Bind rasterizer state. */
+static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
+{
+    struct r300_context* r300 = r300_context(pipe);
+
+    r300->rs_state = (struct r300_rs_state*)state;
+    r300->dirty_state |= R300_NEW_RS;
+}
+
+/* Free rasterizer state. */
+static void r300_delete_rs_state(struct pipe_context* pipe, void* state)
+{
+    FREE(state);
+}
 
 static void r300_set_scissor_state(struct pipe_context* pipe,
                                    struct pipe_scissor_state* state)
@@ -316,8 +429,21 @@ static void r300_set_scissor_state(struct pipe_context* pipe,
     struct r300_context* r300 = r300_context(pipe);
     draw_flush(r300->draw);
 
-    /* XXX figure out how this memory doesn't get lost in space
-    memcpy(r300->scissor, scissor, sizeof(struct pipe_scissor_state)); */
+    uint32_t left, top, right, bottom;
+
+    /* So, a bit of info. The scissors are offset by R300_SCISSORS_OFFSET in
+     * both directions for all values, and can only be 13 bits wide. Why?
+     * We may never know. */
+    left = (state->minx + R300_SCISSORS_OFFSET) & 0x1fff;
+    top = (state->miny + R300_SCISSORS_OFFSET) & 0x1fff;
+    right = (state->maxx + R300_SCISSORS_OFFSET) & 0x1fff;
+    bottom = (state->maxy + R300_SCISSORS_OFFSET) & 0x1fff;
+
+    r300->scissor_state->scissor_top_left = (left << R300_SCISSORS_X_SHIFT) |
+            (top << R300_SCISSORS_Y_SHIFT);
+    r300->scissor_state->scissor_bottom_right = (right << R300_SCISSORS_X_SHIFT) |
+            (bottom << R300_SCISSORS_Y_SHIFT);
+
     r300->dirty_state |= R300_NEW_SCISSOR;
 }
 
@@ -348,6 +474,10 @@ void r300_init_state_functions(struct r300_context* r300) {
     r300->context.bind_blend_state = r300_bind_blend_state;
     r300->context.delete_blend_state = r300_delete_blend_state;
 
+    r300->context.create_rasterizer_state = r300_create_rs_state;
+    r300->context.bind_rasterizer_state = r300_bind_rs_state;
+    r300->context.delete_rasterizer_state = r300_delete_rs_state;
+
     r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state;
     r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state;
     r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state;