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.
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] =
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;
};
/* 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 );
}
{
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 );
* 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 );
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 );
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 */
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 */
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;
* 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;
}
/* 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 */
/* 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);
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);
/* 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 */
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;
}
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;
}
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 ||
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;
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,
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:
*/
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);
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;
*/
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,
CALLOC_STRUCT(nv50_rasterizer_stateobj);
/*XXX: ignored
- * - light_twosize
+ * - light_twoside
* - point_smooth
* - multisample
* - point_sprite / sprite_coord_mode
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);
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));
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;
}
/** 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
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;
-}
* 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
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;
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;
- }
}
/* 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);
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;
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:
rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
}
else {
- offset = offset_ccw;
- fill = fill_ccw;
+ offset = offset_front;
+ fill = fill_front;
}
break;
(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;
/* 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
* 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
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;
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);
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,
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);
#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
{
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;