diff options
| author | Marek Olšák <maraeo@gmail.com> | 2010-06-25 04:48:02 +0200 | 
|---|---|---|
| committer | Marek Olšák <maraeo@gmail.com> | 2010-06-27 15:13:13 +0200 | 
| commit | 0a9510814e2dfff57f7d73cc68aece0554ad794d (patch) | |
| tree | 564137f79fc3308346686cf8d2881d583390fd53 /src | |
| parent | c200c47e6c2f8581608b83e703d611db1bebd7f6 (diff) | |
r300g: turn rasterizer state into a command buffer
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 34 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_emit.c | 42 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_render_stencilref.c | 8 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state.c | 134 | 
4 files changed, 121 insertions, 97 deletions
| diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 5e35d89071..760336cc30 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -115,31 +115,19 @@ struct r300_rs_state {      /* Draw-specific rasterizer state. */      struct pipe_rasterizer_state rs_draw; -    uint32_t vap_control_status;    /* R300_VAP_CNTL_STATUS: 0x2140 */ -    uint32_t point_size;            /* R300_GA_POINT_SIZE: 0x421c */ -    uint32_t point_minmax;          /* R300_GA_POINT_MINMAX: 0x4230 */ -    uint32_t line_control;          /* R300_GA_LINE_CNTL: 0x4234 */ -    float depth_scale;            /* R300_SU_POLY_OFFSET_FRONT_SCALE: 0x42a4 */ -                                  /* R300_SU_POLY_OFFSET_BACK_SCALE: 0x42ac */ -    float depth_offset;           /* R300_SU_POLY_OFFSET_FRONT_OFFSET: 0x42a8 */ -                                  /* R300_SU_POLY_OFFSET_BACK_OFFSET: 0x42b0 */ -    uint32_t polygon_offset_enable; /* R300_SU_POLY_OFFSET_ENABLE: 0x42b4 */ -    uint32_t cull_mode;             /* R300_SU_CULL_MODE: 0x42b8 */ -    uint32_t line_stipple_config;   /* R300_GA_LINE_STIPPLE_CONFIG: 0x4328 */ -    uint32_t line_stipple_value;    /* R300_GA_LINE_STIPPLE_VALUE: 0x4260 */ -    uint32_t color_control;         /* R300_GA_COLOR_CONTROL: 0x4278 */ -    uint32_t polygon_mode;          /* R300_GA_POLY_MODE: 0x4288 */ -    uint32_t clip_rule;             /* R300_SC_CLIP_RULE: 0x43D0 */ +    /* Command buffers. */ +    uint32_t cb_main[25]; +    uint32_t cb_poly_offset_zb16[5]; +    uint32_t cb_poly_offset_zb24[5]; + +    /* The index to cb_main where the cull_mode register value resides. */ +    unsigned cull_mode_index; -    /* Specifies top of Raster pipe specific enable controls, -     * i.e. texture coordinates stuffing for points, lines, triangles */ -    uint32_t stuffing_enable;       /* R300_GB_ENABLE: 0x4008 */ +    /* Whether polygon offset is enabled. */ +    boolean polygon_offset_enable; -    /* Point sprites texture coordinates, 0: lower left, 1: upper right */ -    float point_texcoord_left;      /* R300_GA_POINT_S0: 0x4200 */ -    float point_texcoord_bottom;    /* R300_GA_POINT_T0: 0x4204 */ -    float point_texcoord_right;     /* R300_GA_POINT_S1: 0x4208 */ -    float point_texcoord_top;       /* R300_GA_POINT_T1: 0x420c */ +    /* This is emitted in the draw function. */ +    uint32_t color_control;         /* R300_GA_COLOR_CONTROL: 0x4278 */  };  struct r300_rs_block { diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 65cddc8848..5effb61200 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -565,49 +565,17 @@ void r300_emit_invariant_state(struct r300_context *r300,  void r300_emit_rs_state(struct r300_context* r300, unsigned size, void* state)  {      struct r300_rs_state* rs = state; -    float scale, offset;      CS_LOCALS(r300);      BEGIN_CS(size); -    OUT_CS_REG(R300_VAP_CNTL_STATUS, rs->vap_control_status); -    OUT_CS_REG(R300_GA_POINT_SIZE, rs->point_size); -    OUT_CS_REG_SEQ(R300_GA_POINT_MINMAX, 2); -    OUT_CS(rs->point_minmax); -    OUT_CS(rs->line_control); - +    OUT_CS_TABLE(rs->cb_main, 25);      if (rs->polygon_offset_enable) { -        scale = rs->depth_scale * 12; -        offset = rs->depth_offset; - -        switch (r300->zbuffer_bpp) { -            case 16: -                offset *= 4; -                break; -            case 24: -                offset *= 2; -                break; +        if (r300->zbuffer_bpp == 16) { +            OUT_CS_TABLE(rs->cb_poly_offset_zb16, 5); +        } else { +            OUT_CS_TABLE(rs->cb_poly_offset_zb24, 5);          } - -        OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 4); -        OUT_CS_32F(scale); -        OUT_CS_32F(offset); -        OUT_CS_32F(scale); -        OUT_CS_32F(offset);      } - -    OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_ENABLE, 2); -    OUT_CS(rs->polygon_offset_enable); -    OUT_CS(rs->cull_mode); -    OUT_CS_REG(R300_GA_LINE_STIPPLE_CONFIG, rs->line_stipple_config); -    OUT_CS_REG(R300_GA_LINE_STIPPLE_VALUE, rs->line_stipple_value); -    OUT_CS_REG(R300_GA_POLY_MODE, rs->polygon_mode); -    OUT_CS_REG(R300_SC_CLIP_RULE, rs->clip_rule); -    OUT_CS_REG(R300_GB_ENABLE, rs->stuffing_enable); -    OUT_CS_REG_SEQ(R300_GA_POINT_S0, 4); -    OUT_CS_32F(rs->point_texcoord_left); -    OUT_CS_32F(rs->point_texcoord_bottom); -    OUT_CS_32F(rs->point_texcoord_right); -    OUT_CS_32F(rs->point_texcoord_top);      END_CS;  } diff --git a/src/gallium/drivers/r300/r300_render_stencilref.c b/src/gallium/drivers/r300/r300_render_stencilref.c index d509ded3ec..9a6b4e12ff 100644 --- a/src/gallium/drivers/r300/r300_render_stencilref.c +++ b/src/gallium/drivers/r300/r300_render_stencilref.c @@ -64,12 +64,12 @@ static void r300_stencilref_begin(struct r300_context *r300)      struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;      /* Save state. */ -    sr->rs_cull_mode = rs->cull_mode; +    sr->rs_cull_mode = rs->cb_main[rs->cull_mode_index];      sr->zb_stencilrefmask = dsa->stencil_ref_mask;      sr->ref_value_front = r300->stencil_ref.ref_value[0];      /* We *cull* pixels, therefore no need to mask out the bits. */ -    rs->cull_mode |= R300_CULL_BACK; +    rs->cb_main[rs->cull_mode_index] |= R300_CULL_BACK;      r300->rs_state.dirty = TRUE;  } @@ -81,7 +81,7 @@ static void r300_stencilref_switch_side(struct r300_context *r300)      struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state;      struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state; -    rs->cull_mode = sr->rs_cull_mode | R300_CULL_FRONT; +    rs->cb_main[rs->cull_mode_index] = sr->rs_cull_mode | R300_CULL_FRONT;      dsa->stencil_ref_mask = dsa->stencil_ref_bf;      r300->stencil_ref.ref_value[0] = r300->stencil_ref.ref_value[1]; @@ -97,7 +97,7 @@ static void r300_stencilref_end(struct r300_context *r300)      struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;      /* Restore state. */ -    rs->cull_mode = sr->rs_cull_mode; +    rs->cb_main[rs->cull_mode_index] = sr->rs_cull_mode;      dsa->stencil_ref_mask = sr->zb_stencilrefmask;      r300->stencil_ref.ref_value[0] = sr->ref_value_front; diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index ea1210fcb4..09e694f041 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -850,6 +850,27 @@ static void* r300_create_rs_state(struct pipe_context* pipe,      struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state);      int i;      float psiz; +    uint32_t vap_control_status;    /* R300_VAP_CNTL_STATUS: 0x2140 */ +    uint32_t point_size;            /* R300_GA_POINT_SIZE: 0x421c */ +    uint32_t point_minmax;          /* R300_GA_POINT_MINMAX: 0x4230 */ +    uint32_t line_control;          /* R300_GA_LINE_CNTL: 0x4234 */ +    uint32_t polygon_offset_enable; /* R300_SU_POLY_OFFSET_ENABLE: 0x42b4 */ +    uint32_t cull_mode;             /* R300_SU_CULL_MODE: 0x42b8 */ +    uint32_t line_stipple_config;   /* R300_GA_LINE_STIPPLE_CONFIG: 0x4328 */ +    uint32_t line_stipple_value;    /* R300_GA_LINE_STIPPLE_VALUE: 0x4260 */ +    uint32_t polygon_mode;          /* R300_GA_POLY_MODE: 0x4288 */ +    uint32_t clip_rule;             /* R300_SC_CLIP_RULE: 0x43D0 */ + +    /* Specifies top of Raster pipe specific enable controls, +     * i.e. texture coordinates stuffing for points, lines, triangles */ +    uint32_t stuffing_enable;       /* R300_GB_ENABLE: 0x4008 */ + +    /* Point sprites texture coordinates, 0: lower left, 1: upper right */ +    float point_texcoord_left;      /* R300_GA_POINT_S0: 0x4200 */ +    float point_texcoord_bottom;    /* R300_GA_POINT_T0: 0x4204 */ +    float point_texcoord_right;     /* R300_GA_POINT_S1: 0x4208 */ +    float point_texcoord_top;       /* R300_GA_POINT_T1: 0x420c */ +    CB_LOCALS;      /* Copy rasterizer state. */      rs->rs = *state; @@ -859,18 +880,18 @@ static void* r300_create_rs_state(struct pipe_context* pipe,      rs->rs_draw.sprite_coord_enable = 0; /* We can do this in HW. */  #ifdef PIPE_ARCH_LITTLE_ENDIAN -    rs->vap_control_status = R300_VC_NO_SWAP; +    vap_control_status = R300_VC_NO_SWAP;  #else -    rs->vap_control_status = R300_VC_32BIT_SWAP; +    vap_control_status = R300_VC_32BIT_SWAP;  #endif      /* If no TCL engine is present, turn off the HW TCL. */      if (!r300_screen(pipe->screen)->caps.has_tcl) { -        rs->vap_control_status |= R300_VAP_TCL_BYPASS; +        vap_control_status |= R300_VAP_TCL_BYPASS;      }      /* Point size width and height. */ -    rs->point_size = +    point_size =          pack_float_16_6x(state->point_size) |          (pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT); @@ -880,68 +901,67 @@ static void* r300_create_rs_state(struct pipe_context* pipe,           * Clamp to [0, max FB size] */          psiz = pipe->screen->get_paramf(pipe->screen,                                          PIPE_CAP_MAX_POINT_WIDTH); -        rs->point_minmax = +        point_minmax =              pack_float_16_6x(psiz) << R300_GA_POINT_MINMAX_MAX_SHIFT;      } else {          /* We cannot disable the point-size vertex output,           * so clamp it. */          psiz = state->point_size; -        rs->point_minmax = +        point_minmax =              (pack_float_16_6x(psiz) << R300_GA_POINT_MINMAX_MIN_SHIFT) |              (pack_float_16_6x(psiz) << R300_GA_POINT_MINMAX_MAX_SHIFT);      }      /* Line control. */ -    rs->line_control = pack_float_16_6x(state->line_width) | +    line_control = pack_float_16_6x(state->line_width) |          R300_GA_LINE_CNTL_END_TYPE_COMP;      /* Enable polygon mode */ +    polygon_mode = 0;      if (state->fill_front != PIPE_POLYGON_MODE_FILL ||          state->fill_back != PIPE_POLYGON_MODE_FILL) { -        rs->polygon_mode = R300_GA_POLY_MODE_DUAL; +        polygon_mode = R300_GA_POLY_MODE_DUAL;      }      /* Front face */      if (state->front_ccw)  -        rs->cull_mode = R300_FRONT_FACE_CCW; +        cull_mode = R300_FRONT_FACE_CCW;      else -        rs->cull_mode = R300_FRONT_FACE_CW; +        cull_mode = R300_FRONT_FACE_CW;      /* Polygon offset */ +    polygon_offset_enable = 0;      if (util_get_offset(state, state->fill_front)) { -       rs->polygon_offset_enable |= R300_FRONT_ENABLE; +       polygon_offset_enable |= R300_FRONT_ENABLE;      }      if (util_get_offset(state, state->fill_back)) { -       rs->polygon_offset_enable |= R300_BACK_ENABLE; +       polygon_offset_enable |= R300_BACK_ENABLE;      } +    rs->polygon_offset_enable = polygon_offset_enable != 0; +      /* Polygon mode */ -    if (rs->polygon_mode) { -       rs->polygon_mode |= +    if (polygon_mode) { +       polygon_mode |=            r300_translate_polygon_mode_front(state->fill_front); -       rs->polygon_mode |= +       polygon_mode |=            r300_translate_polygon_mode_back(state->fill_back);      }      if (state->cull_face & PIPE_FACE_FRONT) { -        rs->cull_mode |= R300_CULL_FRONT; +        cull_mode |= R300_CULL_FRONT;      }      if (state->cull_face & PIPE_FACE_BACK) { -        rs->cull_mode |= R300_CULL_BACK; -    } - -    if (rs->polygon_offset_enable) { -        rs->depth_offset = state->offset_units; -        rs->depth_scale = state->offset_scale; +        cull_mode |= R300_CULL_BACK;      }      if (state->line_stipple_enable) { -        rs->line_stipple_config = +        line_stipple_config =              R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE |              (fui((float)state->line_stipple_factor) &                  R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK);          /* XXX this might need to be scaled up */ -        rs->line_stipple_value = state->line_stipple_pattern; +        line_stipple_value = state->line_stipple_pattern;      }      if (state->flatshade) { @@ -950,32 +970,80 @@ static void* r300_create_rs_state(struct pipe_context* pipe,          rs->color_control = R300_SHADE_MODEL_SMOOTH;      } -    rs->clip_rule = state->scissor ? 0xAAAA : 0xFFFF; +    clip_rule = state->scissor ? 0xAAAA : 0xFFFF;      /* Point sprites */ +    stuffing_enable = 0;      if (state->sprite_coord_enable) { -        rs->stuffing_enable = R300_GB_POINT_STUFF_ENABLE; +        stuffing_enable = R300_GB_POINT_STUFF_ENABLE;  	for (i = 0; i < 8; i++) {  	    if (state->sprite_coord_enable & (1 << i)) -		rs->stuffing_enable |= +                stuffing_enable |=  		    R300_GB_TEX_STR << (R300_GB_TEX0_SOURCE_SHIFT + (i*2));  	} -        rs->point_texcoord_left = 0.0f; -        rs->point_texcoord_right = 1.0f; +        point_texcoord_left = 0.0f; +        point_texcoord_right = 1.0f;          switch (state->sprite_coord_mode) {              case PIPE_SPRITE_COORD_UPPER_LEFT: -                rs->point_texcoord_top = 0.0f; -                rs->point_texcoord_bottom = 1.0f; +                point_texcoord_top = 0.0f; +                point_texcoord_bottom = 1.0f;                  break;              case PIPE_SPRITE_COORD_LOWER_LEFT: -                rs->point_texcoord_top = 1.0f; -                rs->point_texcoord_bottom = 0.0f; +                point_texcoord_top = 1.0f; +                point_texcoord_bottom = 0.0f;                  break;          }      } +    /* Build the main command buffer. */ +    BEGIN_CB(rs->cb_main, 25); +    OUT_CB_REG(R300_VAP_CNTL_STATUS, vap_control_status); +    OUT_CB_REG(R300_GA_POINT_SIZE, point_size); +    OUT_CB_REG_SEQ(R300_GA_POINT_MINMAX, 2); +    OUT_CB(point_minmax); +    OUT_CB(line_control); +    OUT_CB_REG_SEQ(R300_SU_POLY_OFFSET_ENABLE, 2); +    OUT_CB(polygon_offset_enable); +    rs->cull_mode_index = 25 - cs_count; +    OUT_CB(cull_mode); +    OUT_CB_REG(R300_GA_LINE_STIPPLE_CONFIG, line_stipple_config); +    OUT_CB_REG(R300_GA_LINE_STIPPLE_VALUE, line_stipple_value); +    OUT_CB_REG(R300_GA_POLY_MODE, polygon_mode); +    OUT_CB_REG(R300_SC_CLIP_RULE, clip_rule); +    OUT_CB_REG(R300_GB_ENABLE, stuffing_enable); +    OUT_CB_REG_SEQ(R300_GA_POINT_S0, 4); +    OUT_CB_32F(point_texcoord_left); +    OUT_CB_32F(point_texcoord_bottom); +    OUT_CB_32F(point_texcoord_right); +    OUT_CB_32F(point_texcoord_top); +    END_CB; + +    /* Build the two command buffers for polygon offset setup. */ +    if (polygon_offset_enable) { +        float scale = state->offset_scale * 12; +        float offset = state->offset_units * 4; + +        BEGIN_CB(rs->cb_poly_offset_zb16, 5); +        OUT_CB_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 4); +        OUT_CB_32F(scale); +        OUT_CB_32F(offset); +        OUT_CB_32F(scale); +        OUT_CB_32F(offset); +        END_CB; + +        offset = state->offset_units * 2; + +        BEGIN_CB(rs->cb_poly_offset_zb24, 5); +        OUT_CB_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 4); +        OUT_CB_32F(scale); +        OUT_CB_32F(offset); +        OUT_CB_32F(scale); +        OUT_CB_32F(offset); +        END_CB; +    } +      return (void*)rs;  } | 
