diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/drivers/r300/r300_context.c | 8 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 21 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state.c | 136 | 
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 67cc1e4586..6dfc9ed624 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 0551275dcc..ea057bcab7 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 122e06c6e6..7668b14c63 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; | 
