summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r300
diff options
context:
space:
mode:
authorCorbin Simpson <[email protected]>2009-01-17 01:41:52 -0800
committerCorbin Simpson <[email protected]>2009-02-01 23:30:23 -0800
commita08a830fd3c22bdbad1ee840e4e56302152375f1 (patch)
treeb90944d575a556b1d8428989cbecb89996317b19 /src/gallium/drivers/r300
parent4ce81294943177eed99d7418f1a2f88573b578fe (diff)
r300: Add more state.
pipe_rasterizer_state is big, and I'm still processing it. Todo: - LOL EVERYTHING - Moar cough syrup. - Even moar cough syrup.
Diffstat (limited to 'src/gallium/drivers/r300')
-rw-r--r--src/gallium/drivers/r300/r300_context.c8
-rw-r--r--src/gallium/drivers/r300/r300_context.h21
-rw-r--r--src/gallium/drivers/r300/r300_state.c136
3 files changed, 155 insertions, 10 deletions
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 67cc1e45867..6dfc9ed6246 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -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);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 0551275dcc7..ea057bcab77 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -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;
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 122e06c6e6a..7668b14c637 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -23,6 +23,23 @@
#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;