r300g: turn rasterizer state into a command buffer
This commit is contained in:
parent
c200c47e6c
commit
0a9510814e
|
@ -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 */
|
||||
/* 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;
|
||||
|
||||
/* Whether polygon offset is enabled. */
|
||||
boolean polygon_offset_enable;
|
||||
|
||||
/* This is emitted in the draw function. */
|
||||
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 */
|
||||
|
||||
/* 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 */
|
||||
};
|
||||
|
||||
struct r300_rs_block {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue