Use front/back instead of cw/ccw throughout. Also, use offset_point/line/fill instead of offset_cw/ccw. Brings gallium representation of this state into line with its main user, and also what turns out to be the most common hardware representation. This fixes a long-standing bias in the interface towards the architecture of the software rasterizer.undefined
@@ -566,7 +566,7 @@ draw_get_rasterizer_no_cull( struct draw_context *draw, | |||
memset(&rast, 0, sizeof(rast)); | |||
rast.scissor = scissor; | |||
rast.flatshade = flatshade; | |||
rast.front_winding = PIPE_WINDING_CCW; | |||
rast.front_ccw = 1; | |||
rast.gl_rasterization_rules = draw->rasterizer->gl_rasterization_rules; | |||
draw->rasterizer_no_cull[scissor][flatshade] = |
@@ -40,7 +40,8 @@ | |||
struct cull_stage { | |||
struct draw_stage stage; | |||
unsigned winding; /**< which winding(s) to cull (one of PIPE_WINDING_x) */ | |||
unsigned cull_face; /**< which face(s) to cull (one of PIPE_FACE_x) */ | |||
unsigned front_ccw; | |||
}; | |||
@@ -73,9 +74,12 @@ static void cull_tri( struct draw_stage *stage, | |||
/* if det < 0 then Z points toward the camera and the triangle is | |||
* counter-clockwise winding. | |||
*/ | |||
unsigned winding = (header->det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; | |||
unsigned ccw = (header->det < 0); | |||
unsigned face = ((ccw == cull_stage(stage)->front_ccw) ? | |||
PIPE_FACE_FRONT : | |||
PIPE_FACE_BACK); | |||
if ((winding & cull_stage(stage)->winding) == 0) { | |||
if ((face & cull_stage(stage)->cull_face) == 0) { | |||
/* triangle is not culled, pass to next stage */ | |||
stage->next->tri( stage->next, header ); | |||
} | |||
@@ -88,7 +92,8 @@ static void cull_first_tri( struct draw_stage *stage, | |||
{ | |||
struct cull_stage *cull = cull_stage(stage); | |||
cull->winding = stage->draw->rasterizer->cull_mode; | |||
cull->cull_face = stage->draw->rasterizer->cull_face; | |||
cull->front_ccw = stage->draw->rasterizer->front_ccw; | |||
stage->tri = cull_tri; | |||
stage->tri( stage, header ); |
@@ -141,7 +141,7 @@ static void twoside_first_tri( struct draw_stage *stage, | |||
* if the triangle is back-facing (negative). | |||
* sign = -1 for CCW, +1 for CW | |||
*/ | |||
twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f; | |||
twoside->sign = stage->draw->rasterizer->front_ccw ? -1.0f : 1.0f; | |||
stage->tri = twoside_tri; | |||
stage->tri( stage, header ); |
@@ -159,9 +159,10 @@ static void unfilled_first_tri( struct draw_stage *stage, | |||
struct prim_header *header ) | |||
{ | |||
struct unfilled_stage *unfilled = unfilled_stage(stage); | |||
const struct pipe_rasterizer_state *rast = stage->draw->rasterizer; | |||
unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */ | |||
unfilled->mode[1] = stage->draw->rasterizer->fill_cw; /* back */ | |||
unfilled->mode[rast->front_ccw ? 0 : 1] = rast->fill_front; | |||
unfilled->mode[rast->front_ccw ? 1 : 0] = rast->fill_back; | |||
stage->tri = unfilled_tri; | |||
stage->tri( stage, header ); |
@@ -122,12 +122,14 @@ draw_need_pipeline(const struct draw_context *draw, | |||
return TRUE; | |||
/* unfilled polygons */ | |||
if (rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || | |||
rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) | |||
if (rasterizer->fill_front != PIPE_POLYGON_MODE_FILL || | |||
rasterizer->fill_front != PIPE_POLYGON_MODE_FILL) | |||
return TRUE; | |||
/* polygon offset */ | |||
if (rasterizer->offset_cw || rasterizer->offset_ccw) | |||
if (rasterizer->offset_point || | |||
rasterizer->offset_line || | |||
rasterizer->offset_tri) | |||
return TRUE; | |||
/* two-side lighting */ | |||
@@ -222,8 +224,8 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) | |||
next = draw->pipeline.pstipple; | |||
} | |||
if (rast->fill_cw != PIPE_POLYGON_MODE_FILL || | |||
rast->fill_ccw != PIPE_POLYGON_MODE_FILL) { | |||
if (rast->fill_front != PIPE_POLYGON_MODE_FILL || | |||
rast->fill_back != PIPE_POLYGON_MODE_FILL) { | |||
draw->pipeline.unfilled->next = next; | |||
next = draw->pipeline.unfilled; | |||
precalc_flat = TRUE; /* only needed for triangles really */ | |||
@@ -235,8 +237,9 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) | |||
next = draw->pipeline.flatshade; | |||
} | |||
if (rast->offset_cw || | |||
rast->offset_ccw) { | |||
if (rast->offset_point || | |||
rast->offset_line || | |||
rast->offset_tri) { | |||
draw->pipeline.offset->next = next; | |||
next = draw->pipeline.offset; | |||
need_det = TRUE; | |||
@@ -255,7 +258,7 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage ) | |||
* to less work emitting vertices, smaller vertex buffers, etc. | |||
* It's difficult to say whether this will be true in general. | |||
*/ | |||
if (need_det || rast->cull_mode) { | |||
if (need_det || rast->cull_face != PIPE_FACE_NONE) { | |||
draw->pipeline.cull->next = next; | |||
next = draw->pipeline.cull; | |||
} |
@@ -101,8 +101,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) | |||
/* rasterizer */ | |||
memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); | |||
ctx->rasterizer.front_winding = PIPE_WINDING_CW; | |||
ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; | |||
ctx->rasterizer.cull_face = PIPE_FACE_NONE; | |||
ctx->rasterizer.gl_rasterization_rules = 1; | |||
/* samplers */ |
@@ -175,8 +175,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) | |||
/* rasterizer state */ | |||
memset(&rs_state, 0, sizeof(rs_state)); | |||
rs_state.front_winding = PIPE_WINDING_CW; | |||
rs_state.cull_mode = PIPE_WINDING_NONE; | |||
rs_state.cull_face = PIPE_FACE_NONE; | |||
rs_state.gl_rasterization_rules = 1; | |||
rs_state.flatshade = 1; | |||
ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state); |
@@ -300,12 +300,13 @@ util_dump_rasterizer_state(struct os_stream *stream, const struct pipe_rasterize | |||
util_dump_member(stream, bool, state, flatshade); | |||
util_dump_member(stream, bool, state, light_twoside); | |||
util_dump_member(stream, uint, state, front_winding); | |||
util_dump_member(stream, uint, state, cull_mode); | |||
util_dump_member(stream, uint, state, fill_cw); | |||
util_dump_member(stream, uint, state, fill_ccw); | |||
util_dump_member(stream, bool, state, offset_cw); | |||
util_dump_member(stream, bool, state, offset_ccw); | |||
util_dump_member(stream, uint, state, front_ccw); | |||
util_dump_member(stream, uint, state, cull_face); | |||
util_dump_member(stream, uint, state, fill_front); | |||
util_dump_member(stream, uint, state, fill_back); | |||
util_dump_member(stream, bool, state, offset_point); | |||
util_dump_member(stream, bool, state, offset_line); | |||
util_dump_member(stream, bool, state, offset_tri); | |||
util_dump_member(stream, bool, state, scissor); | |||
util_dump_member(stream, bool, state, poly_smooth); | |||
util_dump_member(stream, bool, state, poly_stipple_enable); |
@@ -1295,8 +1295,7 @@ util_create_gen_mipmap(struct pipe_context *pipe, | |||
/* rasterizer */ | |||
memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); | |||
ctx->rasterizer.front_winding = PIPE_WINDING_CW; | |||
ctx->rasterizer.cull_mode = PIPE_WINDING_NONE; | |||
ctx->rasterizer.cull_face = PIPE_FACE_NONE; | |||
ctx->rasterizer.gl_rasterization_rules = 1; | |||
/* sampler state */ |
@@ -686,17 +686,23 @@ i915_create_rasterizer_state(struct pipe_context *pipe, | |||
else | |||
cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT; | |||
switch (rasterizer->cull_mode) { | |||
case PIPE_WINDING_NONE: | |||
switch (rasterizer->cull_face) { | |||
case PIPE_FACE_NONE: | |||
cso->LIS4 |= S4_CULLMODE_NONE; | |||
break; | |||
case PIPE_WINDING_CW: | |||
cso->LIS4 |= S4_CULLMODE_CW; | |||
case PIPE_FACE_FRONT: | |||
if (rasterizer->front_ccw) | |||
cso->LIS4 |= S4_CULLMODE_CCW; | |||
else | |||
cso->LIS4 |= S4_CULLMODE_CW; | |||
break; | |||
case PIPE_WINDING_CCW: | |||
cso->LIS4 |= S4_CULLMODE_CCW; | |||
case PIPE_FACE_BACK: | |||
if (rasterizer->front_ccw) | |||
cso->LIS4 |= S4_CULLMODE_CW; | |||
else | |||
cso->LIS4 |= S4_CULLMODE_CCW; | |||
break; | |||
case PIPE_WINDING_BOTH: | |||
case PIPE_FACE_FRONT_AND_BACK: | |||
cso->LIS4 |= S4_CULLMODE_BOTH; | |||
break; | |||
} |
@@ -42,7 +42,7 @@ calculate_clip_key_rast( const struct brw_context *brw, | |||
key->do_flat_shading = templ->flatshade; | |||
if (templ->cull_mode == PIPE_WINDING_BOTH) { | |||
if (templ->cull_face == PIPE_FACE_FRONT_AND_BACK) { | |||
key->clip_mode = BRW_CLIPMODE_REJECT_ALL; | |||
return; | |||
} | |||
@@ -50,12 +50,18 @@ calculate_clip_key_rast( const struct brw_context *brw, | |||
key->fill_ccw = CLIP_CULL; | |||
key->fill_cw = CLIP_CULL; | |||
if (!(templ->cull_mode & PIPE_WINDING_CCW)) { | |||
key->fill_ccw = translate_fill(templ->fill_ccw); | |||
if (!(templ->cull_mode & PIPE_FACE_FRONT)) { | |||
if (templ->front_ccw) | |||
key->fill_ccw = translate_fill(templ->fill_front); | |||
else | |||
key->fill_cw = translate_fill(templ->fill_front); | |||
} | |||
if (!(templ->cull_mode & PIPE_WINDING_CW)) { | |||
key->fill_cw = translate_fill(templ->fill_cw); | |||
if (!(templ->cull_mode & PIPE_FACE_BACK)) { | |||
if (templ->front_ccw) | |||
key->fill_cw = translate_fill(templ->fill_back); | |||
else | |||
key->fill_ccw = translate_fill(templ->fill_back); | |||
} | |||
if (key->fill_cw == CLIP_LINE || | |||
@@ -66,8 +72,29 @@ calculate_clip_key_rast( const struct brw_context *brw, | |||
key->clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED; | |||
} | |||
key->offset_ccw = templ->offset_ccw; | |||
key->offset_cw = templ->offset_cw; | |||
switch (key->fill_cw) { | |||
case CLIP_POINT: | |||
key->offset_cw = templ->offset_point; | |||
break; | |||
case CLIP_LINE: | |||
key->offset_cw = templ->offset_line; | |||
break; | |||
case CLIP_FILL: | |||
key->offset_cw = templ->offset_tri; | |||
break; | |||
} | |||
switch (key->fill_ccw) { | |||
case CLIP_POINT: | |||
key->offset_ccw = templ->offset_point; | |||
break; | |||
case CLIP_LINE: | |||
key->offset_ccw = templ->offset_line; | |||
break; | |||
case CLIP_FILL: | |||
key->offset_ccw = templ->offset_tri; | |||
break; | |||
} | |||
if (templ->light_twoside && key->fill_cw != CLIP_CULL) | |||
key->copy_bfc_cw = 1; |
@@ -187,7 +187,7 @@ static enum pipe_error upload_sf_prog(struct brw_context *brw) | |||
key.do_twoside_color = rast->light_twoside; | |||
if (key.do_twoside_color) { | |||
key.frontface_ccw = (rast->front_winding == PIPE_WINDING_CCW); | |||
key.frontface_ccw = rast->front_ccw; | |||
} | |||
if (brw_search_cache(&brw->cache, BRW_SF_PROG, |
@@ -183,22 +183,22 @@ sf_unit_create_from_key(struct brw_context *brw, | |||
if (key->scissor) | |||
sf.sf6.scissor = 1; | |||
if (key->front_face == PIPE_WINDING_CCW) | |||
if (key->front_ccw) | |||
sf.sf5.front_winding = BRW_FRONTWINDING_CCW; | |||
else | |||
sf.sf5.front_winding = BRW_FRONTWINDING_CW; | |||
switch (key->cull_mode) { | |||
case PIPE_WINDING_CCW: | |||
case PIPE_WINDING_CW: | |||
sf.sf6.cull_mode = (key->front_face == key->cull_mode ? | |||
BRW_CULLMODE_FRONT : | |||
BRW_CULLMODE_BACK); | |||
switch (key->cull_face) { | |||
case PIPE_FACE_FRONT: | |||
sf.sf6.cull_mode = BRW_CULLMODE_FRONT; | |||
break; | |||
case PIPE_WINDING_BOTH: | |||
case PIPE_FACE_BACK: | |||
sf.sf6.cull_mode = BRW_CULLMODE_BACK; | |||
break; | |||
case PIPE_FACE_FRONT_AND_BACK: | |||
sf.sf6.cull_mode = BRW_CULLMODE_BOTH; | |||
break; | |||
case PIPE_WINDING_NONE: | |||
case PIPE_FACE_NONE: | |||
sf.sf6.cull_mode = BRW_CULLMODE_NONE; | |||
break; | |||
default: | |||
@@ -284,7 +284,7 @@ static enum pipe_error upload_sf_unit( struct brw_context *brw ) | |||
*/ | |||
total_grf = (align(key.total_grf, 16) / 16 - 1); | |||
viewport_transform = 1; | |||
front_winding = (key.front_face == PIPE_WINDING_CCW ? | |||
front_winding = (key.front_ccw ? | |||
BRW_FRONTWINDING_CCW : | |||
BRW_FRONTWINDING_CW); | |||
@@ -671,14 +671,14 @@ void | |||
lp_setup_choose_triangle( struct lp_setup_context *setup ) | |||
{ | |||
switch (setup->cullmode) { | |||
case PIPE_WINDING_NONE: | |||
case PIPE_FACE_NONE: | |||
setup->triangle = triangle_both; | |||
break; | |||
case PIPE_WINDING_CCW: | |||
setup->triangle = triangle_cw; | |||
case PIPE_FACE_FRONT: | |||
setup->triangle = setup->ccw_is_frontface ? triangle_ccw : triangle_cw; | |||
break; | |||
case PIPE_WINDING_CW: | |||
setup->triangle = triangle_ccw; | |||
case PIPE_FACE_BACK: | |||
setup->triangle = setup->ccw_is_frontface ? triangle_cw : triangle_ccw; | |||
break; | |||
default: | |||
setup->triangle = triangle_nop; |
@@ -67,8 +67,8 @@ llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle) | |||
*/ | |||
if (llvmpipe->rasterizer) { | |||
lp_setup_set_triangle_state( llvmpipe->setup, | |||
llvmpipe->rasterizer->cull_mode, | |||
llvmpipe->rasterizer->front_winding == PIPE_WINDING_CCW, | |||
llvmpipe->rasterizer->cull_face, | |||
llvmpipe->rasterizer->front_ccw, | |||
llvmpipe->rasterizer->scissor, | |||
llvmpipe->rasterizer->gl_rasterization_rules); | |||
lp_setup_set_flatshade_first( llvmpipe->setup, |
@@ -345,7 +345,7 @@ nv50_rasterizer_state_create(struct pipe_context *pipe, | |||
CALLOC_STRUCT(nv50_rasterizer_stateobj); | |||
/*XXX: ignored | |||
* - light_twosize | |||
* - light_twoside | |||
* - point_smooth | |||
* - multisample | |||
* - point_sprite / sprite_coord_mode | |||
@@ -385,72 +385,44 @@ nv50_rasterizer_state_create(struct pipe_context *pipe, | |||
so_data (so, cso->point_quad_rasterization ? 1 : 0); | |||
so_method(so, tesla, NV50TCL_POLYGON_MODE_FRONT, 3); | |||
if (cso->front_winding == PIPE_WINDING_CCW) { | |||
so_data(so, nvgl_polygon_mode(cso->fill_ccw)); | |||
so_data(so, nvgl_polygon_mode(cso->fill_cw)); | |||
} else { | |||
so_data(so, nvgl_polygon_mode(cso->fill_cw)); | |||
so_data(so, nvgl_polygon_mode(cso->fill_ccw)); | |||
} | |||
so_data(so, nvgl_polygon_mode(cso->fill_front)); | |||
so_data(so, nvgl_polygon_mode(cso->fill_back)); | |||
so_data(so, cso->poly_smooth ? 1 : 0); | |||
so_method(so, tesla, NV50TCL_CULL_FACE_ENABLE, 3); | |||
so_data (so, cso->cull_mode != PIPE_WINDING_NONE); | |||
if (cso->front_winding == PIPE_WINDING_CCW) { | |||
so_data (so, cso->cull_mode != PIPE_FACE_NONE); | |||
if (cso->front_ccw) { | |||
so_data(so, NV50TCL_FRONT_FACE_CCW); | |||
switch (cso->cull_mode) { | |||
case PIPE_WINDING_CCW: | |||
so_data(so, NV50TCL_CULL_FACE_FRONT); | |||
break; | |||
case PIPE_WINDING_CW: | |||
so_data(so, NV50TCL_CULL_FACE_BACK); | |||
break; | |||
case PIPE_WINDING_BOTH: | |||
so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK); | |||
break; | |||
default: | |||
so_data(so, NV50TCL_CULL_FACE_BACK); | |||
break; | |||
} | |||
} else { | |||
} | |||
else { | |||
so_data(so, NV50TCL_FRONT_FACE_CW); | |||
switch (cso->cull_mode) { | |||
case PIPE_WINDING_CCW: | |||
so_data(so, NV50TCL_CULL_FACE_BACK); | |||
break; | |||
case PIPE_WINDING_CW: | |||
so_data(so, NV50TCL_CULL_FACE_FRONT); | |||
break; | |||
case PIPE_WINDING_BOTH: | |||
so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK); | |||
break; | |||
default: | |||
so_data(so, NV50TCL_CULL_FACE_BACK); | |||
break; | |||
} | |||
} | |||
switch (cso->cull_face) { | |||
case PIPE_FACE_FRONT: | |||
so_data(so, NV50TCL_CULL_FACE_FRONT); | |||
break; | |||
case PIPE_FACE_BACK: | |||
so_data(so, NV50TCL_CULL_FACE_BACK); | |||
break; | |||
case PIPE_FACE_FRONT_AND_BACK: | |||
so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK); | |||
break; | |||
default: | |||
so_data(so, NV50TCL_CULL_FACE_BACK); | |||
break; | |||
} | |||
so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_ENABLE, 1); | |||
so_data (so, cso->poly_stipple_enable ? 1 : 0); | |||
so_method(so, tesla, NV50TCL_POLYGON_OFFSET_POINT_ENABLE, 3); | |||
if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) || | |||
(cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT)) | |||
so_data(so, 1); | |||
else | |||
so_data(so, 0); | |||
if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) || | |||
(cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE)) | |||
so_data(so, 1); | |||
else | |||
so_data(so, 0); | |||
if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) || | |||
(cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL)) | |||
so_data(so, 1); | |||
else | |||
so_data(so, 0); | |||
so_data(so, cso->offset_point); | |||
so_data(so, cso->offset_line); | |||
so_data(so, cso->offset_tri); | |||
if (cso->offset_cw || cso->offset_ccw) { | |||
if (cso->offset_point || | |||
cso->offset_line || | |||
cso->offset_tri) { | |||
so_method(so, tesla, NV50TCL_POLYGON_OFFSET_FACTOR, 1); | |||
so_data (so, fui(cso->offset_scale)); | |||
so_method(so, tesla, NV50TCL_POLYGON_OFFSET_UNITS, 1); |
@@ -216,66 +216,39 @@ nvfx_rasterizer_state_create(struct pipe_context *pipe, | |||
sb_data(sb, fui(cso->point_size)); | |||
sb_method(sb, NV34TCL_POLYGON_MODE_FRONT, 6); | |||
if (cso->front_winding == PIPE_WINDING_CCW) { | |||
sb_data(sb, nvgl_polygon_mode(cso->fill_ccw)); | |||
sb_data(sb, nvgl_polygon_mode(cso->fill_cw)); | |||
switch (cso->cull_mode) { | |||
case PIPE_WINDING_CCW: | |||
sb_data(sb, NV34TCL_CULL_FACE_FRONT); | |||
break; | |||
case PIPE_WINDING_CW: | |||
sb_data(sb, NV34TCL_CULL_FACE_BACK); | |||
break; | |||
case PIPE_WINDING_BOTH: | |||
sb_data(sb, NV34TCL_CULL_FACE_FRONT_AND_BACK); | |||
break; | |||
default: | |||
sb_data(sb, NV34TCL_CULL_FACE_BACK); | |||
break; | |||
} | |||
sb_data(sb, nvgl_polygon_mode(cso->fill_front)); | |||
sb_data(sb, nvgl_polygon_mode(cso->fill_back)); | |||
switch (cso->cull_mode) { | |||
case PIPE_FACE_FRONT: | |||
sb_data(sb, NV34TCL_CULL_FACE_FRONT); | |||
break; | |||
case PIPE_FACE_BACK: | |||
sb_data(sb, NV34TCL_CULL_FACE_BACK); | |||
break; | |||
case PIPE_FACE_FRONT_AND_BACK: | |||
sb_data(sb, NV34TCL_CULL_FACE_FRONT_AND_BACK); | |||
break; | |||
default: | |||
sb_data(sb, NV34TCL_CULL_FACE_BACK); | |||
break; | |||
} | |||
if (cso->front_ccw) { | |||
sb_data(sb, NV34TCL_FRONT_FACE_CCW); | |||
} else { | |||
sb_data(sb, nvgl_polygon_mode(cso->fill_cw)); | |||
sb_data(sb, nvgl_polygon_mode(cso->fill_ccw)); | |||
switch (cso->cull_mode) { | |||
case PIPE_WINDING_CCW: | |||
sb_data(sb, NV34TCL_CULL_FACE_BACK); | |||
break; | |||
case PIPE_WINDING_CW: | |||
sb_data(sb, NV34TCL_CULL_FACE_FRONT); | |||
break; | |||
case PIPE_WINDING_BOTH: | |||
sb_data(sb, NV34TCL_CULL_FACE_FRONT_AND_BACK); | |||
break; | |||
default: | |||
sb_data(sb, NV34TCL_CULL_FACE_BACK); | |||
break; | |||
} | |||
sb_data(sb, NV34TCL_FRONT_FACE_CW); | |||
} | |||
sb_data(sb, cso->poly_smooth ? 1 : 0); | |||
sb_data(sb, (cso->cull_mode != PIPE_WINDING_NONE) ? 1 : 0); | |||
sb_data(sb, (cso->cull_face != PIPE_FACE_NONE) ? 1 : 0); | |||
sb_method(sb, NV34TCL_POLYGON_STIPPLE_ENABLE, 1); | |||
sb_data(sb, cso->poly_stipple_enable ? 1 : 0); | |||
sb_method(sb, NV34TCL_POLYGON_OFFSET_POINT_ENABLE, 3); | |||
if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) || | |||
(cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT)) | |||
sb_data(sb, 1); | |||
else | |||
sb_data(sb, 0); | |||
if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) || | |||
(cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE)) | |||
sb_data(sb, 1); | |||
else | |||
sb_data(sb, 0); | |||
if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) || | |||
(cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL)) | |||
sb_data(sb, 1); | |||
else | |||
sb_data(sb, 0); | |||
if (cso->offset_cw || cso->offset_ccw) { | |||
sb_data(sb, cso->offset_point); | |||
sb_data(sb, cso->offset_line); | |||
sb_data(sb, cso->offset_tri); | |||
if (cso->offset_point || cso->offset_line || cso->offset_tri) { | |||
sb_method(sb, NV34TCL_POLYGON_OFFSET_FACTOR, 2); | |||
sb_data(sb, fui(cso->offset_scale)); | |||
sb_data(sb, fui(cso->offset_units * 2)); |
@@ -765,53 +765,37 @@ static void* r300_create_rs_state(struct pipe_context* pipe, | |||
R300_GA_LINE_CNTL_END_TYPE_COMP; | |||
/* Enable polygon mode */ | |||
if (state->fill_cw != PIPE_POLYGON_MODE_FILL || | |||
state->fill_ccw != PIPE_POLYGON_MODE_FILL) { | |||
if (state->fill_front != PIPE_POLYGON_MODE_FILL || | |||
state->fill_back != PIPE_POLYGON_MODE_FILL) { | |||
rs->polygon_mode = R300_GA_POLY_MODE_DUAL; | |||
} | |||
/* 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; | |||
/* Polygon offset */ | |||
if (state->offset_cw) { | |||
rs->polygon_offset_enable |= R300_FRONT_ENABLE; | |||
} | |||
if (state->offset_ccw) { | |||
rs->polygon_offset_enable |= R300_BACK_ENABLE; | |||
} | |||
/* Polygon mode */ | |||
if (rs->polygon_mode) { | |||
rs->polygon_mode |= | |||
r300_translate_polygon_mode_front(state->fill_cw); | |||
rs->polygon_mode |= | |||
r300_translate_polygon_mode_back(state->fill_ccw); | |||
} | |||
} else { | |||
/* Front face */ | |||
if (state->front_ccw) | |||
rs->cull_mode = R300_FRONT_FACE_CCW; | |||
else | |||
rs->cull_mode = R300_FRONT_FACE_CW; | |||
/* Polygon offset */ | |||
if (state->offset_ccw) { | |||
rs->polygon_offset_enable |= R300_FRONT_ENABLE; | |||
} | |||
if (state->offset_cw) { | |||
rs->polygon_offset_enable |= R300_BACK_ENABLE; | |||
} | |||
/* Polygon offset */ | |||
if (state->offset_front) { | |||
rs->polygon_offset_enable |= R300_FRONT_ENABLE; | |||
} | |||
if (state->offset_back) { | |||
rs->polygon_offset_enable |= R300_BACK_ENABLE; | |||
} | |||
/* Polygon mode */ | |||
if (rs->polygon_mode) { | |||
rs->polygon_mode |= | |||
r300_translate_polygon_mode_front(state->fill_ccw); | |||
rs->polygon_mode |= | |||
r300_translate_polygon_mode_back(state->fill_cw); | |||
} | |||
/* Polygon mode */ | |||
if (rs->polygon_mode) { | |||
rs->polygon_mode |= | |||
r300_translate_polygon_mode_front(state->fill_front); | |||
rs->polygon_mode |= | |||
r300_translate_polygon_mode_back(state->fill_back); | |||
} | |||
if (state->front_winding & state->cull_mode) { | |||
if (state->cull_face & PIPE_FACE_FRONT) { | |||
rs->cull_mode |= R300_CULL_FRONT; | |||
} | |||
if (~(state->front_winding) & state->cull_mode) { | |||
if (state->cull_face & PIPE_FACE_BACK) { | |||
rs->cull_mode |= R300_CULL_BACK; | |||
} | |||
@@ -109,6 +109,9 @@ struct softpipe_context { | |||
/** The reduced version of the primitive supplied by the state tracker */ | |||
unsigned reduced_api_prim; | |||
/** Derived information about which winding orders to cull */ | |||
unsigned cull_mode; | |||
/** | |||
* The reduced primitive after unfilled triangles, wide-line decomposition, | |||
* etc, are taken into account. This is the primitive type that's actually |
@@ -111,34 +111,12 @@ struct setup_context { | |||
uint numFragsWritten; /**< per primitive */ | |||
#endif | |||
unsigned winding; /* which winding to cull */ | |||
unsigned nr_vertex_attrs; | |||
}; | |||
/** | |||
* Do triangle cull test using tri determinant (sign indicates orientation) | |||
* \return true if triangle is to be culled. | |||
*/ | |||
static INLINE boolean | |||
cull_tri(const struct setup_context *setup, float det) | |||
{ | |||
if (det != 0) { | |||
/* if (det < 0 then Z points toward camera and triangle is | |||
* counter-clockwise winding. | |||
*/ | |||
unsigned winding = (det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW; | |||
if ((winding & setup->winding) == 0) | |||
return FALSE; | |||
} | |||
/* Culled: | |||
*/ | |||
return TRUE; | |||
} | |||
@@ -393,8 +371,8 @@ setup_sort_vertices(struct setup_context *setup, | |||
* 0 = front-facing, 1 = back-facing | |||
*/ | |||
setup->facing = | |||
((det > 0.0) ^ | |||
(setup->softpipe->rasterizer->front_winding == PIPE_WINDING_CW)); | |||
((det < 0.0) ^ | |||
(setup->softpipe->rasterizer->front_ccw)); | |||
/* Prepare pixel offset for rasterisation: | |||
* - pixel center (0.5, 0.5) for GL, or | |||
@@ -832,8 +810,8 @@ sp_setup_tri(struct setup_context *setup, | |||
setup->numFragsWritten = 0; | |||
#endif | |||
if (cull_tri( setup, det )) | |||
return; | |||
/* Culling already done by draw module. | |||
*/ | |||
if (!setup_sort_vertices( setup, det, v0, v1, v2 )) | |||
return; | |||
@@ -1418,17 +1396,6 @@ sp_setup_prepare(struct setup_context *setup) | |||
setup->nr_vertex_attrs = draw_num_shader_outputs(sp->draw); | |||
sp->quad.first->begin( sp->quad.first ); | |||
if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES && | |||
sp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && | |||
sp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) { | |||
/* we'll do culling */ | |||
setup->winding = sp->rasterizer->cull_mode; | |||
} | |||
else { | |||
/* 'draw' will do culling */ | |||
setup->winding = PIPE_WINDING_NONE; | |||
} | |||
} | |||
@@ -36,16 +36,17 @@ | |||
/* Hardware frontwinding is always set up as SVGA3D_FRONTWINDING_CW. | |||
*/ | |||
static SVGA3dFace svga_translate_cullmode( unsigned mode, | |||
unsigned front_winding ) | |||
unsigned front_ccw ) | |||
{ | |||
const int hw_front_ccw = 0; /* hardware is always CW */ | |||
switch (mode) { | |||
case PIPE_WINDING_NONE: | |||
case PIPE_FACE_NONE: | |||
return SVGA3D_FACE_NONE; | |||
case PIPE_WINDING_CCW: | |||
return SVGA3D_FACE_BACK; | |||
case PIPE_WINDING_CW: | |||
return SVGA3D_FACE_FRONT; | |||
case PIPE_WINDING_BOTH: | |||
case PIPE_FACE_FRONT: | |||
return front_ccw == hw_front_ccw ? SVGA3D_FACE_FRONT : SVGA3D_FACE_BACK; | |||
case PIPE_FACE_BACK: | |||
return front_ccw == hw_front_ccw ? SVGA3D_FACE_BACK : SVGA3D_FACE_FRONT; | |||
case PIPE_FACE_FRONT_AND_BACK: | |||
return SVGA3D_FACE_FRONT_BACK; | |||
default: | |||
assert(0); | |||
@@ -82,7 +83,7 @@ svga_create_rasterizer_state(struct pipe_context *pipe, | |||
rast->shademode = svga_translate_flatshade( templ->flatshade ); | |||
rast->cullmode = svga_translate_cullmode( templ->cull_mode, | |||
templ->front_winding ); | |||
templ->front_ccw ); | |||
rast->scissortestenable = templ->scissor; | |||
rast->multisampleantialias = templ->multisample; | |||
rast->antialiasedlineenable = templ->line_smooth; | |||
@@ -124,24 +125,24 @@ svga_create_rasterizer_state(struct pipe_context *pipe, | |||
int fill_ccw = templ->fill_ccw; | |||
int fill = PIPE_POLYGON_MODE_FILL; | |||
switch (templ->cull_mode) { | |||
case PIPE_WINDING_BOTH: | |||
switch (templ->cull_face) { | |||
case PIPE_FACE_FRONT_AND_BACK: | |||
offset = 0; | |||
fill = PIPE_POLYGON_MODE_FILL; | |||
break; | |||
case PIPE_WINDING_CW: | |||
offset = offset_ccw; | |||
fill = fill_ccw; | |||
case PIPE_FACE_FRONT: | |||
offset = offset_front; | |||
fill = fill_front; | |||
break; | |||
case PIPE_WINDING_CCW: | |||
offset = offset_cw; | |||
fill = fill_cw; | |||
case PIPE_FACE_BACK: | |||
offset = offset_back; | |||
fill = fill_back; | |||
break; | |||
case PIPE_WINDING_NONE: | |||
if (fill_cw != fill_ccw || offset_cw != offset_ccw) | |||
case PIPE_FACE_NONE: | |||
if (fill_front != fill_back || offset_front != offset_back) | |||
{ | |||
/* Always need the draw module to work out different | |||
* front/back fill modes: | |||
@@ -149,8 +150,8 @@ svga_create_rasterizer_state(struct pipe_context *pipe, | |||
rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; | |||
} | |||
else { | |||
offset = offset_ccw; | |||
fill = fill_ccw; | |||
offset = offset_front; | |||
fill = fill_front; | |||
} | |||
break; | |||
@@ -167,7 +168,7 @@ svga_create_rasterizer_state(struct pipe_context *pipe, | |||
(templ->flatshade || | |||
templ->light_twoside || | |||
offset || | |||
templ->cull_mode != PIPE_WINDING_NONE)) | |||
templ->cull_face != PIPE_FACE_NONE)) | |||
{ | |||
fill = PIPE_POLYGON_MODE_FILL; | |||
rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; |
@@ -131,8 +131,7 @@ static int make_fs_key( const struct svga_context *svga, | |||
/* SVGA_NEW_RAST | |||
*/ | |||
key->light_twoside = svga->curr.rast->templ.light_twoside; | |||
key->front_cw = (svga->curr.rast->templ.front_winding == | |||
PIPE_WINDING_CW); | |||
key->front_ccw = svga->curr.rast->templ.front_ccw; | |||
} | |||
/* The blend workaround for simulating logicop xor behaviour |
@@ -146,13 +146,13 @@ static int emit_rss( struct svga_context *svga, | |||
* then our definition of front face agrees with hardware. | |||
* Otherwise need to flip. | |||
*/ | |||
if (rast->templ.front_winding == PIPE_WINDING_CW) { | |||
cw = 0; | |||
ccw = 1; | |||
if (rast->templ.front_ccw) { | |||
ccw = 0; | |||
cw = 1; | |||
} | |||
else { | |||
cw = 1; | |||
ccw = 0; | |||
ccw = 1; | |||
cw = 0; | |||
} | |||
/* Twoside stencil |
@@ -48,7 +48,7 @@ struct svga_vs_compile_key | |||
struct svga_fs_compile_key | |||
{ | |||
unsigned light_twoside:1; | |||
unsigned front_cw:1; | |||
unsigned front_ccw:1; | |||
unsigned white_fragments:1; | |||
unsigned num_textures:8; | |||
unsigned num_unnormalized_coords:8; |
@@ -2588,10 +2588,10 @@ static boolean emit_light_twoside( struct svga_shader_emitter *emit ) | |||
if_token = inst_token( SVGA3DOP_IFC ); | |||
if (emit->key.fkey.front_cw) | |||
if_token.control = SVGA3DOPCOMP_GT; | |||
else | |||
if (emit->key.fkey.front_ccw) | |||
if_token.control = SVGA3DOPCOMP_LT; | |||
else | |||
if_token.control = SVGA3DOPCOMP_GT; | |||
zero = scalar(zero, TGSI_SWIZZLE_X); | |||
@@ -2639,12 +2639,12 @@ static boolean emit_frontface( struct svga_shader_emitter *emit ) | |||
temp = dst_register( SVGA3DREG_TEMP, | |||
emit->nr_hw_temp++ ); | |||
if (emit->key.fkey.front_cw) { | |||
pass = scalar( zero, TGSI_SWIZZLE_W ); | |||
fail = scalar( zero, TGSI_SWIZZLE_X ); | |||
} else { | |||
if (emit->key.fkey.front_ccw) { | |||
pass = scalar( zero, TGSI_SWIZZLE_X ); | |||
fail = scalar( zero, TGSI_SWIZZLE_W ); | |||
} else { | |||
pass = scalar( zero, TGSI_SWIZZLE_W ); | |||
fail = scalar( zero, TGSI_SWIZZLE_X ); | |||
} | |||
if (!emit_conditional(emit, PIPE_FUNC_GREATER, |
@@ -136,12 +136,13 @@ void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state) | |||
trace_dump_member(bool, state, flatshade); | |||
trace_dump_member(bool, state, light_twoside); | |||
trace_dump_member(uint, state, front_winding); | |||
trace_dump_member(uint, state, cull_mode); | |||
trace_dump_member(uint, state, fill_cw); | |||
trace_dump_member(uint, state, fill_ccw); | |||
trace_dump_member(bool, state, offset_cw); | |||
trace_dump_member(bool, state, offset_ccw); | |||
trace_dump_member(uint, state, front_ccw); | |||
trace_dump_member(uint, state, cull_face); | |||
trace_dump_member(uint, state, fill_front); | |||
trace_dump_member(uint, state, fill_back); | |||
trace_dump_member(bool, state, offset_point); | |||
trace_dump_member(bool, state, offset_line); | |||
trace_dump_member(bool, state, offset_tri); | |||
trace_dump_member(bool, state, scissor); | |||
trace_dump_member(bool, state, poly_smooth); | |||
trace_dump_member(bool, state, poly_stipple_enable); |
@@ -119,11 +119,11 @@ enum pipe_error { | |||
#define PIPE_POLYGON_MODE_LINE 1 | |||
#define PIPE_POLYGON_MODE_POINT 2 | |||
/** Polygon front/back window, also for culling */ | |||
#define PIPE_WINDING_NONE 0 | |||
#define PIPE_WINDING_CW 1 | |||
#define PIPE_WINDING_CCW 2 | |||
#define PIPE_WINDING_BOTH (PIPE_WINDING_CW | PIPE_WINDING_CCW) | |||
/** Polygon face specification, eg for culling */ | |||
#define PIPE_FACE_NONE 0 | |||
#define PIPE_FACE_FRONT 1 | |||
#define PIPE_FACE_BACK 2 | |||
#define PIPE_FACE_FRONT_AND_BACK (PIPE_FACE_FRONT | PIPE_FACE_BACK) | |||
/** Stencil ops */ | |||
#define PIPE_STENCIL_OP_KEEP 0 |
@@ -79,12 +79,13 @@ struct pipe_rasterizer_state | |||
{ | |||
unsigned flatshade:1; | |||
unsigned light_twoside:1; | |||
unsigned front_winding:2; /**< PIPE_WINDING_x */ | |||
unsigned cull_mode:2; /**< PIPE_WINDING_x */ | |||
unsigned fill_cw:2; /**< PIPE_POLYGON_MODE_x */ | |||
unsigned fill_ccw:2; /**< PIPE_POLYGON_MODE_x */ | |||
unsigned offset_cw:1; | |||
unsigned offset_ccw:1; | |||
unsigned front_ccw:1; | |||
unsigned cull_face:2; /**< PIPE_FACE_x */ | |||
unsigned fill_front:2; /**< PIPE_POLYGON_MODE_x */ | |||
unsigned fill_back:2; /**< PIPE_POLYGON_MODE_x */ | |||
unsigned offset_point:1; | |||
unsigned offset_line:1; | |||
unsigned offset_tri:1; | |||
unsigned scissor:1; | |||
unsigned poly_smooth:1; | |||
unsigned poly_stipple_enable:1; |