Merge branch 'gallium-front-ccw'

This commit is contained in:
Keith Whitwell
2010-05-21 15:41:06 +01:00
33 changed files with 402 additions and 412 deletions

View File

@@ -566,7 +566,7 @@ draw_get_rasterizer_no_cull( struct draw_context *draw,
memset(&rast, 0, sizeof(rast)); memset(&rast, 0, sizeof(rast));
rast.scissor = scissor; rast.scissor = scissor;
rast.flatshade = flatshade; rast.flatshade = flatshade;
rast.front_winding = PIPE_WINDING_CCW; rast.front_ccw = 1;
rast.gl_rasterization_rules = draw->rasterizer->gl_rasterization_rules; rast.gl_rasterization_rules = draw->rasterizer->gl_rasterization_rules;
draw->rasterizer_no_cull[scissor][flatshade] = draw->rasterizer_no_cull[scissor][flatshade] =

View File

@@ -40,7 +40,8 @@
struct cull_stage { struct cull_stage {
struct draw_stage 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 /* if det < 0 then Z points toward the camera and the triangle is
* counter-clockwise winding. * 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 */ /* triangle is not culled, pass to next stage */
stage->next->tri( stage->next, header ); 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); 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 = cull_tri;
stage->tri( stage, header ); stage->tri( stage, header );

View File

@@ -141,7 +141,7 @@ static void twoside_first_tri( struct draw_stage *stage,
* if the triangle is back-facing (negative). * if the triangle is back-facing (negative).
* sign = -1 for CCW, +1 for CW * 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 = twoside_tri;
stage->tri( stage, header ); stage->tri( stage, header );

View File

@@ -134,7 +134,8 @@ static void unfilled_tri( struct draw_stage *stage,
struct prim_header *header ) struct prim_header *header )
{ {
struct unfilled_stage *unfilled = unfilled_stage(stage); struct unfilled_stage *unfilled = unfilled_stage(stage);
unsigned mode = unfilled->mode[header->det >= 0.0]; unsigned cw = header->det >= 0.0;
unsigned mode = unfilled->mode[cw];
if (0) if (0)
print_header_flags(header->flags); print_header_flags(header->flags);
@@ -159,9 +160,10 @@ static void unfilled_first_tri( struct draw_stage *stage,
struct prim_header *header ) struct prim_header *header )
{ {
struct unfilled_stage *unfilled = unfilled_stage(stage); 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[0] = rast->front_ccw ? rast->fill_front : rast->fill_back;
unfilled->mode[1] = stage->draw->rasterizer->fill_cw; /* back */ unfilled->mode[1] = rast->front_ccw ? rast->fill_back : rast->fill_front;
stage->tri = unfilled_tri; stage->tri = unfilled_tri;
stage->tri( stage, header ); stage->tri( stage, header );

View File

@@ -122,12 +122,14 @@ draw_need_pipeline(const struct draw_context *draw,
return TRUE; return TRUE;
/* unfilled polygons */ /* unfilled polygons */
if (rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL || if (rasterizer->fill_front != PIPE_POLYGON_MODE_FILL ||
rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) rasterizer->fill_back != PIPE_POLYGON_MODE_FILL)
return TRUE; return TRUE;
/* polygon offset */ /* polygon offset */
if (rasterizer->offset_cw || rasterizer->offset_ccw) if (rasterizer->offset_point ||
rasterizer->offset_line ||
rasterizer->offset_tri)
return TRUE; return TRUE;
/* two-side lighting */ /* two-side lighting */
@@ -222,8 +224,8 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
next = draw->pipeline.pstipple; next = draw->pipeline.pstipple;
} }
if (rast->fill_cw != PIPE_POLYGON_MODE_FILL || if (rast->fill_front != PIPE_POLYGON_MODE_FILL ||
rast->fill_ccw != PIPE_POLYGON_MODE_FILL) { rast->fill_back != PIPE_POLYGON_MODE_FILL) {
draw->pipeline.unfilled->next = next; draw->pipeline.unfilled->next = next;
next = draw->pipeline.unfilled; next = draw->pipeline.unfilled;
precalc_flat = TRUE; /* only needed for triangles really */ 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; next = draw->pipeline.flatshade;
} }
if (rast->offset_cw || if (rast->offset_point ||
rast->offset_ccw) { rast->offset_line ||
rast->offset_tri) {
draw->pipeline.offset->next = next; draw->pipeline.offset->next = next;
next = draw->pipeline.offset; next = draw->pipeline.offset;
need_det = TRUE; 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. * to less work emitting vertices, smaller vertex buffers, etc.
* It's difficult to say whether this will be true in general. * 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; draw->pipeline.cull->next = next;
next = draw->pipeline.cull; next = draw->pipeline.cull;
} }

View File

@@ -101,8 +101,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
/* rasterizer */ /* rasterizer */
memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
ctx->rasterizer.front_winding = PIPE_WINDING_CW; ctx->rasterizer.cull_face = PIPE_FACE_NONE;
ctx->rasterizer.cull_mode = PIPE_WINDING_NONE;
ctx->rasterizer.gl_rasterization_rules = 1; ctx->rasterizer.gl_rasterization_rules = 1;
/* samplers */ /* samplers */

View File

@@ -175,8 +175,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
/* rasterizer state */ /* rasterizer state */
memset(&rs_state, 0, sizeof(rs_state)); memset(&rs_state, 0, sizeof(rs_state));
rs_state.front_winding = PIPE_WINDING_CW; rs_state.cull_face = PIPE_FACE_NONE;
rs_state.cull_mode = PIPE_WINDING_NONE;
rs_state.gl_rasterization_rules = 1; rs_state.gl_rasterization_rules = 1;
rs_state.flatshade = 1; rs_state.flatshade = 1;
ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state); ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);

View File

@@ -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, flatshade);
util_dump_member(stream, bool, state, light_twoside); util_dump_member(stream, bool, state, light_twoside);
util_dump_member(stream, uint, state, front_winding); util_dump_member(stream, uint, state, front_ccw);
util_dump_member(stream, uint, state, cull_mode); util_dump_member(stream, uint, state, cull_face);
util_dump_member(stream, uint, state, fill_cw); util_dump_member(stream, uint, state, fill_front);
util_dump_member(stream, uint, state, fill_ccw); util_dump_member(stream, uint, state, fill_back);
util_dump_member(stream, bool, state, offset_cw); util_dump_member(stream, bool, state, offset_point);
util_dump_member(stream, bool, state, offset_ccw); 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, scissor);
util_dump_member(stream, bool, state, poly_smooth); util_dump_member(stream, bool, state, poly_smooth);
util_dump_member(stream, bool, state, poly_stipple_enable); util_dump_member(stream, bool, state, poly_stipple_enable);

View File

@@ -1295,8 +1295,7 @@ util_create_gen_mipmap(struct pipe_context *pipe,
/* rasterizer */ /* rasterizer */
memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
ctx->rasterizer.front_winding = PIPE_WINDING_CW; ctx->rasterizer.cull_face = PIPE_FACE_NONE;
ctx->rasterizer.cull_mode = PIPE_WINDING_NONE;
ctx->rasterizer.gl_rasterization_rules = 1; ctx->rasterizer.gl_rasterization_rules = 1;
/* sampler state */ /* sampler state */

View File

@@ -369,6 +369,24 @@ pipe_transfer_destroy( struct pipe_context *context,
} }
static INLINE boolean util_get_offset(
const struct pipe_rasterizer_state *templ,
unsigned fill_mode)
{
switch(fill_mode) {
case PIPE_POLYGON_MODE_POINT:
return templ->offset_point;
case PIPE_POLYGON_MODE_LINE:
return templ->offset_line;
case PIPE_POLYGON_MODE_FILL:
return templ->offset_tri;
default:
assert(0);
return FALSE;
}
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -46,6 +46,78 @@ There are several important exceptions to the specification of this rule.
second vertex, not the first. This permits each segment of the fan to have second vertex, not the first. This permits each segment of the fan to have
a different color. a different color.
Polygons
--------
light_twoside
^^^^^^^^^^^^^
If set, there are per-vertex back-facing colors. The hardware
(perhaps assisted by :ref:`Draw`) should be set up to use this state
along with the front/back information to set the final vertex colors
prior to rasterization.
The frontface vertex shader color output is marked with TGSI semantic
COLOR[0], and backface COLOR[1].
front_ccw
Indicates whether the window order of front-facing polygons is
counter-clockwise (TRUE) or clockwise (FALSE).
cull_mode
Indicates which faces of polygons to cull, either PIPE_FACE_NONE
(cull no polygons), PIPE_FACE_FRONT (cull front-facing polygons),
PIPE_FACE_BACK (cull back-facing polygons), or
PIPE_FACE_FRONT_AND_BACK (cull all polygons).
fill_front
Indicates how to fill front-facing polygons, either
PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE or
PIPE_POLYGON_MODE_POINT.
fill_back
Indicates how to fill back-facing polygons, either
PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE or
PIPE_POLYGON_MODE_POINT.
poly_stipple_enable
Whether polygon stippling is enabled.
poly_smooth
Controls OpenGL-style polygon smoothing/antialiasing
offset_point
If set, point-filled polygons will have polygon offset factors applied
offset_line
If set, line-filled polygons will have polygon offset factors applied
offset_tri
If set, filled polygons will have polygon offset factors applied
offset_units
Specifies the polygon offset bias
offset_scale
Specifies the polygon offset scale
Lines
-----
line_width
The width of lines.
line_smooth
Whether lines should be smoothed. Line smoothing is simply anti-aliasing.
line_stipple_enable
Whether line stippling is enabled.
line_stipple_pattern
16-bit bitfield of on/off flags, used to pattern the line stipple.
line_stipple_factor
When drawing a stippled line, each bit in the stipple pattern is
repeated N times, where N = line_stipple_factor + 1.
line_last_pixel
Controls whether the last pixel in a line is drawn or not. OpenGL
omits the last pixel to avoid double-drawing pixels at the ends of lines
when drawing connected lines.
Points Points
------ ------
@@ -89,68 +161,21 @@ coordinates are not generated.
Some renderers always internally translate points into quads; this state Some renderers always internally translate points into quads; this state
still affects those renderers by overriding other rasterization state. still affects those renderers by overriding other rasterization state.
Other Members
^^^^^^^^^^^^^
light_twoside
If set, there are per-vertex back-facing colors. :ref:`Draw`
uses this state along with the front/back information to set the
final vertex colors prior to rasterization.
front_winding
Indicates the window order of front-facing polygons, either
PIPE_WINDING_CW or PIPE_WINDING_CCW
cull_mode
Indicates which polygons to cull, either PIPE_WINDING_NONE (cull no
polygons), PIPE_WINDING_CW (cull clockwise-winding polygons),
PIPE_WINDING_CCW (cull counter clockwise-winding polygons), or
PIPE_WINDING_BOTH (cull all polygons).
fill_cw
Indicates how to fill clockwise polygons, either PIPE_POLYGON_MODE_FILL,
PIPE_POLYGON_MODE_LINE or PIPE_POLYGON_MODE_POINT.
fill_ccw
Indicates how to fill counter clockwise polygons, either
PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE or PIPE_POLYGON_MODE_POINT.
poly_stipple_enable
Whether polygon stippling is enabled.
poly_smooth
Controls OpenGL-style polygon smoothing/antialiasing
offset_cw
If set, clockwise polygons will have polygon offset factors applied
offset_ccw
If set, counter clockwise polygons will have polygon offset factors applied
offset_units
Specifies the polygon offset bias
offset_scale
Specifies the polygon offset scale
line_width
The width of lines.
line_smooth
Whether lines should be smoothed. Line smoothing is simply anti-aliasing.
line_stipple_enable
Whether line stippling is enabled.
line_stipple_pattern
16-bit bitfield of on/off flags, used to pattern the line stipple.
line_stipple_factor
When drawing a stippled line, each bit in the stipple pattern is
repeated N times, where N = line_stipple_factor + 1.
line_last_pixel
Controls whether the last pixel in a line is drawn or not. OpenGL
omits the last pixel to avoid double-drawing pixels at the ends of lines
when drawing connected lines.
point_smooth point_smooth
Whether points should be smoothed. Point smoothing turns rectangular Whether points should be smoothed. Point smoothing turns rectangular
points into circles or ovals. points into circles or ovals.
point_size_per_vertex point_size_per_vertex
Whether vertices have a point size element. Whether the vertex shader is expected to have a point size output.
Undefined behaviour is permitted if there is disagreement between
this flag and the actual bound shader.
point_size point_size
The size of points, if not specified per-vertex. The size of points, if not specified per-vertex.
Other Members
-------------
scissor scissor
Whether the scissor test is enabled. Whether the scissor test is enabled.

View File

@@ -686,17 +686,23 @@ i915_create_rasterizer_state(struct pipe_context *pipe,
else else
cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT; cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT;
switch (rasterizer->cull_mode) { switch (rasterizer->cull_face) {
case PIPE_WINDING_NONE: case PIPE_FACE_NONE:
cso->LIS4 |= S4_CULLMODE_NONE; cso->LIS4 |= S4_CULLMODE_NONE;
break; break;
case PIPE_WINDING_CW: case PIPE_FACE_FRONT:
cso->LIS4 |= S4_CULLMODE_CW; if (rasterizer->front_ccw)
cso->LIS4 |= S4_CULLMODE_CCW;
else
cso->LIS4 |= S4_CULLMODE_CW;
break; break;
case PIPE_WINDING_CCW: case PIPE_FACE_BACK:
cso->LIS4 |= S4_CULLMODE_CCW; if (rasterizer->front_ccw)
cso->LIS4 |= S4_CULLMODE_CW;
else
cso->LIS4 |= S4_CULLMODE_CCW;
break; break;
case PIPE_WINDING_BOTH: case PIPE_FACE_FRONT_AND_BACK:
cso->LIS4 |= S4_CULLMODE_BOTH; cso->LIS4 |= S4_CULLMODE_BOTH;
break; break;
} }

View File

@@ -42,7 +42,7 @@ calculate_clip_key_rast( const struct brw_context *brw,
key->do_flat_shading = templ->flatshade; 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; key->clip_mode = BRW_CLIPMODE_REJECT_ALL;
return; return;
} }
@@ -50,12 +50,18 @@ calculate_clip_key_rast( const struct brw_context *brw,
key->fill_ccw = CLIP_CULL; key->fill_ccw = CLIP_CULL;
key->fill_cw = CLIP_CULL; key->fill_cw = CLIP_CULL;
if (!(templ->cull_mode & PIPE_WINDING_CCW)) { if (!(templ->cull_face & PIPE_FACE_FRONT)) {
key->fill_ccw = translate_fill(templ->fill_ccw); 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)) { if (!(templ->cull_face & PIPE_FACE_BACK)) {
key->fill_cw = translate_fill(templ->fill_cw); 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 || 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->clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED;
} }
key->offset_ccw = templ->offset_ccw; switch (key->fill_cw) {
key->offset_cw = templ->offset_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) if (templ->light_twoside && key->fill_cw != CLIP_CULL)
key->copy_bfc_cw = 1; key->copy_bfc_cw = 1;
@@ -111,12 +138,12 @@ static void *brw_create_rasterizer_state( struct pipe_context *pipe,
/* Caclculate lookup value for WM IZ table. /* Caclculate lookup value for WM IZ table.
*/ */
if (templ->line_smooth) { if (templ->line_smooth) {
if (templ->fill_cw == PIPE_POLYGON_MODE_LINE && if (templ->fill_front == PIPE_POLYGON_MODE_LINE &&
templ->fill_ccw == PIPE_POLYGON_MODE_LINE) { templ->fill_back == PIPE_POLYGON_MODE_LINE) {
rast->unfilled_aa_line = AA_ALWAYS; rast->unfilled_aa_line = AA_ALWAYS;
} }
else if (templ->fill_cw == PIPE_POLYGON_MODE_LINE || else if (templ->fill_front == PIPE_POLYGON_MODE_LINE ||
templ->fill_ccw == PIPE_POLYGON_MODE_LINE) { templ->fill_back == PIPE_POLYGON_MODE_LINE) {
rast->unfilled_aa_line = AA_SOMETIMES; rast->unfilled_aa_line = AA_SOMETIMES;
} }
else { else {

View File

@@ -166,8 +166,8 @@ static enum pipe_error upload_sf_prog(struct brw_context *brw)
case PIPE_PRIM_TRIANGLES: case PIPE_PRIM_TRIANGLES:
/* PIPE_NEW_RAST /* PIPE_NEW_RAST
*/ */
if (rast->fill_cw != PIPE_POLYGON_MODE_FILL || if (rast->fill_front != PIPE_POLYGON_MODE_FILL ||
rast->fill_ccw != PIPE_POLYGON_MODE_FILL) rast->fill_back != PIPE_POLYGON_MODE_FILL)
key.primitive = SF_UNFILLED_TRIS; key.primitive = SF_UNFILLED_TRIS;
else else
key.primitive = SF_TRIANGLES; key.primitive = SF_TRIANGLES;
@@ -187,7 +187,7 @@ static enum pipe_error upload_sf_prog(struct brw_context *brw)
key.do_twoside_color = rast->light_twoside; key.do_twoside_color = rast->light_twoside;
if (key.do_twoside_color) { 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 (brw_search_cache(&brw->cache, BRW_SF_PROG,

View File

@@ -89,8 +89,8 @@ struct brw_sf_unit_key {
unsigned line_smooth:1; unsigned line_smooth:1;
unsigned point_sprite:1; unsigned point_sprite:1;
unsigned point_attenuated:1; unsigned point_attenuated:1;
unsigned front_face:2; unsigned front_ccw:1;
unsigned cull_mode:2; unsigned cull_face:2;
unsigned flatshade_first:1; unsigned flatshade_first:1;
unsigned gl_rasterization_rules:1; unsigned gl_rasterization_rules:1;
unsigned line_last_pixel_enable:1; unsigned line_last_pixel_enable:1;
@@ -115,8 +115,8 @@ sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key)
/* PIPE_NEW_RAST */ /* PIPE_NEW_RAST */
key->scissor = rast->scissor; key->scissor = rast->scissor;
key->front_face = rast->front_winding; key->front_ccw = rast->front_ccw;
key->cull_mode = rast->cull_mode; key->cull_face = rast->cull_face;
key->line_smooth = rast->line_smooth; key->line_smooth = rast->line_smooth;
key->line_width = rast->line_width; key->line_width = rast->line_width;
key->flatshade_first = rast->flatshade_first; key->flatshade_first = rast->flatshade_first;
@@ -183,22 +183,22 @@ sf_unit_create_from_key(struct brw_context *brw,
if (key->scissor) if (key->scissor)
sf.sf6.scissor = 1; sf.sf6.scissor = 1;
if (key->front_face == PIPE_WINDING_CCW) if (key->front_ccw)
sf.sf5.front_winding = BRW_FRONTWINDING_CCW; sf.sf5.front_winding = BRW_FRONTWINDING_CCW;
else else
sf.sf5.front_winding = BRW_FRONTWINDING_CW; sf.sf5.front_winding = BRW_FRONTWINDING_CW;
switch (key->cull_mode) { switch (key->cull_face) {
case PIPE_WINDING_CCW: case PIPE_FACE_FRONT:
case PIPE_WINDING_CW: sf.sf6.cull_mode = BRW_CULLMODE_FRONT;
sf.sf6.cull_mode = (key->front_face == key->cull_mode ?
BRW_CULLMODE_FRONT :
BRW_CULLMODE_BACK);
break; 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; sf.sf6.cull_mode = BRW_CULLMODE_BOTH;
break; break;
case PIPE_WINDING_NONE: case PIPE_FACE_NONE:
sf.sf6.cull_mode = BRW_CULLMODE_NONE; sf.sf6.cull_mode = BRW_CULLMODE_NONE;
break; break;
default: 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); total_grf = (align(key.total_grf, 16) / 16 - 1);
viewport_transform = 1; viewport_transform = 1;
front_winding = (key.front_face == PIPE_WINDING_CCW ? front_winding = (key.front_ccw ?
BRW_FRONTWINDING_CCW : BRW_FRONTWINDING_CCW :
BRW_FRONTWINDING_CW); BRW_FRONTWINDING_CW);

View File

@@ -128,8 +128,9 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
key->line_stipple = brw->curr.rast->templ.line_stipple_enable; key->line_stipple = brw->curr.rast->templ.line_stipple_enable;
key->offset_enable = (brw->curr.rast->templ.offset_cw || key->offset_enable = (brw->curr.rast->templ.offset_point ||
brw->curr.rast->templ.offset_ccw); brw->curr.rast->templ.offset_line ||
brw->curr.rast->templ.offset_tri);
key->offset_units = brw->curr.rast->templ.offset_units; key->offset_units = brw->curr.rast->templ.offset_units;
key->offset_factor = brw->curr.rast->templ.offset_scale; key->offset_factor = brw->curr.rast->templ.offset_scale;

View File

@@ -671,14 +671,14 @@ void
lp_setup_choose_triangle( struct lp_setup_context *setup ) lp_setup_choose_triangle( struct lp_setup_context *setup )
{ {
switch (setup->cullmode) { switch (setup->cullmode) {
case PIPE_WINDING_NONE: case PIPE_FACE_NONE:
setup->triangle = triangle_both; setup->triangle = triangle_both;
break; break;
case PIPE_WINDING_CCW: case PIPE_FACE_BACK:
setup->triangle = triangle_cw; setup->triangle = setup->ccw_is_frontface ? triangle_ccw : triangle_cw;
break; break;
case PIPE_WINDING_CW: case PIPE_FACE_FRONT:
setup->triangle = triangle_ccw; setup->triangle = setup->ccw_is_frontface ? triangle_cw : triangle_ccw;
break; break;
default: default:
setup->triangle = triangle_nop; setup->triangle = triangle_nop;

View File

@@ -67,8 +67,8 @@ llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
*/ */
if (llvmpipe->rasterizer) { if (llvmpipe->rasterizer) {
lp_setup_set_triangle_state( llvmpipe->setup, lp_setup_set_triangle_state( llvmpipe->setup,
llvmpipe->rasterizer->cull_mode, llvmpipe->rasterizer->cull_face,
llvmpipe->rasterizer->front_winding == PIPE_WINDING_CCW, llvmpipe->rasterizer->front_ccw,
llvmpipe->rasterizer->scissor, llvmpipe->rasterizer->scissor,
llvmpipe->rasterizer->gl_rasterization_rules); llvmpipe->rasterizer->gl_rasterization_rules);
lp_setup_set_flatshade_first( llvmpipe->setup, lp_setup_set_flatshade_first( llvmpipe->setup,

View File

@@ -345,7 +345,7 @@ nv50_rasterizer_state_create(struct pipe_context *pipe,
CALLOC_STRUCT(nv50_rasterizer_stateobj); CALLOC_STRUCT(nv50_rasterizer_stateobj);
/*XXX: ignored /*XXX: ignored
* - light_twosize * - light_twoside
* - point_smooth * - point_smooth
* - multisample * - multisample
* - point_sprite / sprite_coord_mode * - 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_data (so, cso->point_quad_rasterization ? 1 : 0);
so_method(so, tesla, NV50TCL_POLYGON_MODE_FRONT, 3); so_method(so, tesla, NV50TCL_POLYGON_MODE_FRONT, 3);
if (cso->front_winding == PIPE_WINDING_CCW) { so_data(so, nvgl_polygon_mode(cso->fill_front));
so_data(so, nvgl_polygon_mode(cso->fill_ccw)); so_data(so, nvgl_polygon_mode(cso->fill_back));
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, cso->poly_smooth ? 1 : 0); so_data(so, cso->poly_smooth ? 1 : 0);
so_method(so, tesla, NV50TCL_CULL_FACE_ENABLE, 3); so_method(so, tesla, NV50TCL_CULL_FACE_ENABLE, 3);
so_data (so, cso->cull_mode != PIPE_WINDING_NONE); so_data (so, cso->cull_face != PIPE_FACE_NONE);
if (cso->front_winding == PIPE_WINDING_CCW) { if (cso->front_ccw) {
so_data(so, NV50TCL_FRONT_FACE_CCW); so_data(so, NV50TCL_FRONT_FACE_CCW);
switch (cso->cull_mode) { }
case PIPE_WINDING_CCW: else {
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 {
so_data(so, NV50TCL_FRONT_FACE_CW); so_data(so, NV50TCL_FRONT_FACE_CW);
switch (cso->cull_mode) { }
case PIPE_WINDING_CCW: switch (cso->cull_face) {
so_data(so, NV50TCL_CULL_FACE_BACK); case PIPE_FACE_FRONT:
break; so_data(so, NV50TCL_CULL_FACE_FRONT);
case PIPE_WINDING_CW: break;
so_data(so, NV50TCL_CULL_FACE_FRONT); case PIPE_FACE_BACK:
break; so_data(so, NV50TCL_CULL_FACE_BACK);
case PIPE_WINDING_BOTH: break;
so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK); case PIPE_FACE_FRONT_AND_BACK:
break; so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK);
default: break;
so_data(so, NV50TCL_CULL_FACE_BACK); default:
break; so_data(so, NV50TCL_CULL_FACE_BACK);
} break;
} }
so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_ENABLE, 1); so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_ENABLE, 1);
so_data (so, cso->poly_stipple_enable ? 1 : 0); so_data (so, cso->poly_stipple_enable ? 1 : 0);
so_method(so, tesla, NV50TCL_POLYGON_OFFSET_POINT_ENABLE, 3); so_method(so, tesla, NV50TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) || so_data(so, cso->offset_point);
(cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT)) so_data(so, cso->offset_line);
so_data(so, 1); so_data(so, cso->offset_tri);
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);
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_method(so, tesla, NV50TCL_POLYGON_OFFSET_FACTOR, 1);
so_data (so, fui(cso->offset_scale)); so_data (so, fui(cso->offset_scale));
so_method(so, tesla, NV50TCL_POLYGON_OFFSET_UNITS, 1); so_method(so, tesla, NV50TCL_POLYGON_OFFSET_UNITS, 1);

View File

@@ -216,66 +216,39 @@ nvfx_rasterizer_state_create(struct pipe_context *pipe,
sb_data(sb, fui(cso->point_size)); sb_data(sb, fui(cso->point_size));
sb_method(sb, NV34TCL_POLYGON_MODE_FRONT, 6); sb_method(sb, NV34TCL_POLYGON_MODE_FRONT, 6);
if (cso->front_winding == PIPE_WINDING_CCW) { sb_data(sb, nvgl_polygon_mode(cso->fill_front));
sb_data(sb, nvgl_polygon_mode(cso->fill_ccw)); sb_data(sb, nvgl_polygon_mode(cso->fill_back));
sb_data(sb, nvgl_polygon_mode(cso->fill_cw)); switch (cso->cull_face) {
switch (cso->cull_mode) { case PIPE_FACE_FRONT:
case PIPE_WINDING_CCW: sb_data(sb, NV34TCL_CULL_FACE_FRONT);
sb_data(sb, NV34TCL_CULL_FACE_FRONT); break;
break; case PIPE_FACE_BACK:
case PIPE_WINDING_CW: sb_data(sb, NV34TCL_CULL_FACE_BACK);
sb_data(sb, NV34TCL_CULL_FACE_BACK); break;
break; case PIPE_FACE_FRONT_AND_BACK:
case PIPE_WINDING_BOTH: sb_data(sb, NV34TCL_CULL_FACE_FRONT_AND_BACK);
sb_data(sb, NV34TCL_CULL_FACE_FRONT_AND_BACK); break;
break; default:
default: sb_data(sb, NV34TCL_CULL_FACE_BACK);
sb_data(sb, NV34TCL_CULL_FACE_BACK); break;
break; }
} if (cso->front_ccw) {
sb_data(sb, NV34TCL_FRONT_FACE_CCW); sb_data(sb, NV34TCL_FRONT_FACE_CCW);
} else { } 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, NV34TCL_FRONT_FACE_CW);
} }
sb_data(sb, cso->poly_smooth ? 1 : 0); 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_method(sb, NV34TCL_POLYGON_STIPPLE_ENABLE, 1);
sb_data(sb, cso->poly_stipple_enable ? 1 : 0); sb_data(sb, cso->poly_stipple_enable ? 1 : 0);
sb_method(sb, NV34TCL_POLYGON_OFFSET_POINT_ENABLE, 3); sb_method(sb, NV34TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) || sb_data(sb, cso->offset_point);
(cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT)) sb_data(sb, cso->offset_line);
sb_data(sb, 1); sb_data(sb, cso->offset_tri);
else
sb_data(sb, 0); if (cso->offset_point || cso->offset_line || cso->offset_tri) {
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_method(sb, NV34TCL_POLYGON_OFFSET_FACTOR, 2); sb_method(sb, NV34TCL_POLYGON_OFFSET_FACTOR, 2);
sb_data(sb, fui(cso->offset_scale)); sb_data(sb, fui(cso->offset_scale));
sb_data(sb, fui(cso->offset_units * 2)); sb_data(sb, fui(cso->offset_units * 2));

View File

@@ -801,53 +801,37 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
R300_GA_LINE_CNTL_END_TYPE_COMP; R300_GA_LINE_CNTL_END_TYPE_COMP;
/* Enable polygon mode */ /* Enable polygon mode */
if (state->fill_cw != PIPE_POLYGON_MODE_FILL || if (state->fill_front != PIPE_POLYGON_MODE_FILL ||
state->fill_ccw != PIPE_POLYGON_MODE_FILL) { state->fill_back != PIPE_POLYGON_MODE_FILL) {
rs->polygon_mode = R300_GA_POLY_MODE_DUAL; rs->polygon_mode = R300_GA_POLY_MODE_DUAL;
} }
/* Radeons don't think in "CW/CCW", they think in "front/back". */ /* Front face */
if (state->front_winding == PIPE_WINDING_CW) { if (state->front_ccw)
rs->cull_mode = R300_FRONT_FACE_CCW;
else
rs->cull_mode = R300_FRONT_FACE_CW; rs->cull_mode = R300_FRONT_FACE_CW;
/* Polygon offset */ /* Polygon offset */
if (state->offset_cw) { if (util_get_offset(state, state->fill_front)) {
rs->polygon_offset_enable |= R300_FRONT_ENABLE; 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 {
rs->cull_mode = R300_FRONT_FACE_CCW;
/* 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 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);
}
} }
if (state->front_winding & state->cull_mode) { if (util_get_offset(state, state->fill_back)) {
rs->polygon_offset_enable |= R300_BACK_ENABLE;
}
/* 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->cull_face & PIPE_FACE_FRONT) {
rs->cull_mode |= R300_CULL_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; rs->cull_mode |= R300_CULL_BACK;
} }
@@ -914,7 +898,9 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
} }
if (rs) { if (rs) {
r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw; r300->polygon_offset_enabled = (rs->rs.offset_point ||
rs->rs.offset_line ||
rs->rs.offset_tri);
r300->sprite_coord_enable = rs->rs.sprite_coord_enable; r300->sprite_coord_enable = rs->rs.sprite_coord_enable;
r300->two_sided_color = rs->rs.light_twoside; r300->two_sided_color = rs->rs.light_twoside;
} else { } else {

View File

@@ -109,6 +109,9 @@ struct softpipe_context {
/** The reduced version of the primitive supplied by the state tracker */ /** The reduced version of the primitive supplied by the state tracker */
unsigned reduced_api_prim; unsigned reduced_api_prim;
/** Derived information about which winding orders to cull */
unsigned cull_mode;
/** /**
* The reduced primitive after unfilled triangles, wide-line decomposition, * The reduced primitive after unfilled triangles, wide-line decomposition,
* etc, are taken into account. This is the primitive type that's actually * etc, are taken into account. This is the primitive type that's actually

View File

@@ -111,34 +111,13 @@ struct setup_context {
uint numFragsWritten; /**< per primitive */ uint numFragsWritten; /**< per primitive */
#endif #endif
unsigned winding; /* which winding to cull */ unsigned cull_face; /* which faces cull */
unsigned nr_vertex_attrs; 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 +372,16 @@ setup_sort_vertices(struct setup_context *setup,
* 0 = front-facing, 1 = back-facing * 0 = front-facing, 1 = back-facing
*/ */
setup->facing = setup->facing =
((det > 0.0) ^ ((det < 0.0) ^
(setup->softpipe->rasterizer->front_winding == PIPE_WINDING_CW)); (setup->softpipe->rasterizer->front_ccw));
{
unsigned face = setup->facing == 0 ? PIPE_FACE_FRONT : PIPE_FACE_BACK;
if (face & setup->cull_face)
return FALSE;
}
/* Prepare pixel offset for rasterisation: /* Prepare pixel offset for rasterisation:
* - pixel center (0.5, 0.5) for GL, or * - pixel center (0.5, 0.5) for GL, or
@@ -832,11 +819,9 @@ sp_setup_tri(struct setup_context *setup,
setup->numFragsWritten = 0; setup->numFragsWritten = 0;
#endif #endif
if (cull_tri( setup, det ))
return;
if (!setup_sort_vertices( setup, det, v0, v1, v2 )) if (!setup_sort_vertices( setup, det, v0, v1, v2 ))
return; return;
setup_tri_coefficients( setup ); setup_tri_coefficients( setup );
setup_tri_edges( setup ); setup_tri_edges( setup );
@@ -1420,14 +1405,14 @@ sp_setup_prepare(struct setup_context *setup)
sp->quad.first->begin( sp->quad.first ); sp->quad.first->begin( sp->quad.first );
if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES && if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES &&
sp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL && sp->rasterizer->fill_front == PIPE_POLYGON_MODE_FILL &&
sp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) { sp->rasterizer->fill_back == PIPE_POLYGON_MODE_FILL) {
/* we'll do culling */ /* we'll do culling */
setup->winding = sp->rasterizer->cull_mode; setup->cull_face = sp->rasterizer->cull_face;
} }
else { else {
/* 'draw' will do culling */ /* 'draw' will do culling */
setup->winding = PIPE_WINDING_NONE; setup->cull_face = PIPE_FACE_NONE;
} }
} }

View File

@@ -36,16 +36,17 @@
/* Hardware frontwinding is always set up as SVGA3D_FRONTWINDING_CW. /* Hardware frontwinding is always set up as SVGA3D_FRONTWINDING_CW.
*/ */
static SVGA3dFace svga_translate_cullmode( unsigned mode, 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) { switch (mode) {
case PIPE_WINDING_NONE: case PIPE_FACE_NONE:
return SVGA3D_FACE_NONE; return SVGA3D_FACE_NONE;
case PIPE_WINDING_CCW: case PIPE_FACE_FRONT:
return SVGA3D_FACE_BACK; return front_ccw == hw_front_ccw ? SVGA3D_FACE_FRONT : SVGA3D_FACE_BACK;
case PIPE_WINDING_CW: case PIPE_FACE_BACK:
return SVGA3D_FACE_FRONT; return front_ccw == hw_front_ccw ? SVGA3D_FACE_BACK : SVGA3D_FACE_FRONT;
case PIPE_WINDING_BOTH: case PIPE_FACE_FRONT_AND_BACK:
return SVGA3D_FACE_FRONT_BACK; return SVGA3D_FACE_FRONT_BACK;
default: default:
assert(0); assert(0);
@@ -81,8 +82,8 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
/* fill_cw, fill_ccw - draw module or index translation */ /* fill_cw, fill_ccw - draw module or index translation */
rast->shademode = svga_translate_flatshade( templ->flatshade ); rast->shademode = svga_translate_flatshade( templ->flatshade );
rast->cullmode = svga_translate_cullmode( templ->cull_mode, rast->cullmode = svga_translate_cullmode( templ->cull_face,
templ->front_winding ); templ->front_ccw );
rast->scissortestenable = templ->scissor; rast->scissortestenable = templ->scissor;
rast->multisampleantialias = templ->multisample; rast->multisampleantialias = templ->multisample;
rast->antialiasedlineenable = templ->line_smooth; rast->antialiasedlineenable = templ->line_smooth;
@@ -117,31 +118,31 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
rast->need_pipeline |= SVGA_PIPELINE_FLAG_POINTS; rast->need_pipeline |= SVGA_PIPELINE_FLAG_POINTS;
{ {
boolean offset_cw = templ->offset_cw; int fill_front = templ->fill_front;
boolean offset_ccw = templ->offset_ccw; int fill_back = templ->fill_back;
boolean offset = 0;
int fill_cw = templ->fill_cw;
int fill_ccw = templ->fill_ccw;
int fill = PIPE_POLYGON_MODE_FILL; int fill = PIPE_POLYGON_MODE_FILL;
boolean offset_front = util_get_offset(templ, fill_front);
boolean offset_back = util_get_offset(templ, fill_back);
boolean offset = 0;
switch (templ->cull_mode) { switch (templ->cull_face) {
case PIPE_WINDING_BOTH: case PIPE_FACE_FRONT_AND_BACK:
offset = 0; offset = 0;
fill = PIPE_POLYGON_MODE_FILL; fill = PIPE_POLYGON_MODE_FILL;
break; break;
case PIPE_WINDING_CW: case PIPE_FACE_FRONT:
offset = offset_ccw; offset = offset_front;
fill = fill_ccw; fill = fill_front;
break; break;
case PIPE_WINDING_CCW: case PIPE_FACE_BACK:
offset = offset_cw; offset = offset_back;
fill = fill_cw; fill = fill_back;
break; break;
case PIPE_WINDING_NONE: case PIPE_FACE_NONE:
if (fill_cw != fill_ccw || offset_cw != offset_ccw) if (fill_front != fill_back || offset_front != offset_back)
{ {
/* Always need the draw module to work out different /* Always need the draw module to work out different
* front/back fill modes: * front/back fill modes:
@@ -149,8 +150,8 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;
} }
else { else {
offset = offset_ccw; offset = offset_front;
fill = fill_ccw; fill = fill_front;
} }
break; break;
@@ -167,7 +168,7 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
(templ->flatshade || (templ->flatshade ||
templ->light_twoside || templ->light_twoside ||
offset || offset ||
templ->cull_mode != PIPE_WINDING_NONE)) templ->cull_face != PIPE_FACE_NONE))
{ {
fill = PIPE_POLYGON_MODE_FILL; fill = PIPE_POLYGON_MODE_FILL;
rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS;

View File

@@ -131,8 +131,7 @@ static int make_fs_key( const struct svga_context *svga,
/* SVGA_NEW_RAST /* SVGA_NEW_RAST
*/ */
key->light_twoside = svga->curr.rast->templ.light_twoside; key->light_twoside = svga->curr.rast->templ.light_twoside;
key->front_cw = (svga->curr.rast->templ.front_winding == key->front_ccw = svga->curr.rast->templ.front_ccw;
PIPE_WINDING_CW);
} }
/* The blend workaround for simulating logicop xor behaviour /* The blend workaround for simulating logicop xor behaviour

View File

@@ -146,13 +146,13 @@ static int emit_rss( struct svga_context *svga,
* then our definition of front face agrees with hardware. * then our definition of front face agrees with hardware.
* Otherwise need to flip. * Otherwise need to flip.
*/ */
if (rast->templ.front_winding == PIPE_WINDING_CW) { if (rast->templ.front_ccw) {
cw = 0; ccw = 0;
ccw = 1; cw = 1;
} }
else { else {
cw = 1; ccw = 1;
ccw = 0; cw = 0;
} }
/* Twoside stencil /* Twoside stencil

View File

@@ -48,7 +48,7 @@ struct svga_vs_compile_key
struct svga_fs_compile_key struct svga_fs_compile_key
{ {
unsigned light_twoside:1; unsigned light_twoside:1;
unsigned front_cw:1; unsigned front_ccw:1;
unsigned white_fragments:1; unsigned white_fragments:1;
unsigned num_textures:8; unsigned num_textures:8;
unsigned num_unnormalized_coords:8; unsigned num_unnormalized_coords:8;

View File

@@ -2588,10 +2588,10 @@ static boolean emit_light_twoside( struct svga_shader_emitter *emit )
if_token = inst_token( SVGA3DOP_IFC ); if_token = inst_token( SVGA3DOP_IFC );
if (emit->key.fkey.front_cw) if (emit->key.fkey.front_ccw)
if_token.control = SVGA3DOPCOMP_GT;
else
if_token.control = SVGA3DOPCOMP_LT; if_token.control = SVGA3DOPCOMP_LT;
else
if_token.control = SVGA3DOPCOMP_GT;
zero = scalar(zero, TGSI_SWIZZLE_X); zero = scalar(zero, TGSI_SWIZZLE_X);
@@ -2639,12 +2639,12 @@ static boolean emit_frontface( struct svga_shader_emitter *emit )
temp = dst_register( SVGA3DREG_TEMP, temp = dst_register( SVGA3DREG_TEMP,
emit->nr_hw_temp++ ); emit->nr_hw_temp++ );
if (emit->key.fkey.front_cw) { if (emit->key.fkey.front_ccw) {
pass = scalar( zero, TGSI_SWIZZLE_W );
fail = scalar( zero, TGSI_SWIZZLE_X );
} else {
pass = scalar( zero, TGSI_SWIZZLE_X ); pass = scalar( zero, TGSI_SWIZZLE_X );
fail = scalar( zero, TGSI_SWIZZLE_W ); 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, if (!emit_conditional(emit, PIPE_FUNC_GREATER,

View File

@@ -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, flatshade);
trace_dump_member(bool, state, light_twoside); trace_dump_member(bool, state, light_twoside);
trace_dump_member(uint, state, front_winding); trace_dump_member(uint, state, front_ccw);
trace_dump_member(uint, state, cull_mode); trace_dump_member(uint, state, cull_face);
trace_dump_member(uint, state, fill_cw); trace_dump_member(uint, state, fill_front);
trace_dump_member(uint, state, fill_ccw); trace_dump_member(uint, state, fill_back);
trace_dump_member(bool, state, offset_cw); trace_dump_member(bool, state, offset_point);
trace_dump_member(bool, state, offset_ccw); 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, scissor);
trace_dump_member(bool, state, poly_smooth); trace_dump_member(bool, state, poly_smooth);
trace_dump_member(bool, state, poly_stipple_enable); trace_dump_member(bool, state, poly_stipple_enable);

View File

@@ -119,11 +119,11 @@ enum pipe_error {
#define PIPE_POLYGON_MODE_LINE 1 #define PIPE_POLYGON_MODE_LINE 1
#define PIPE_POLYGON_MODE_POINT 2 #define PIPE_POLYGON_MODE_POINT 2
/** Polygon front/back window, also for culling */ /** Polygon face specification, eg for culling */
#define PIPE_WINDING_NONE 0 #define PIPE_FACE_NONE 0
#define PIPE_WINDING_CW 1 #define PIPE_FACE_FRONT 1
#define PIPE_WINDING_CCW 2 #define PIPE_FACE_BACK 2
#define PIPE_WINDING_BOTH (PIPE_WINDING_CW | PIPE_WINDING_CCW) #define PIPE_FACE_FRONT_AND_BACK (PIPE_FACE_FRONT | PIPE_FACE_BACK)
/** Stencil ops */ /** Stencil ops */
#define PIPE_STENCIL_OP_KEEP 0 #define PIPE_STENCIL_OP_KEEP 0

View File

@@ -79,12 +79,13 @@ struct pipe_rasterizer_state
{ {
unsigned flatshade:1; unsigned flatshade:1;
unsigned light_twoside:1; unsigned light_twoside:1;
unsigned front_winding:2; /**< PIPE_WINDING_x */ unsigned front_ccw:1;
unsigned cull_mode:2; /**< PIPE_WINDING_x */ unsigned cull_face:2; /**< PIPE_FACE_x */
unsigned fill_cw:2; /**< PIPE_POLYGON_MODE_x */ unsigned fill_front:2; /**< PIPE_POLYGON_MODE_x */
unsigned fill_ccw:2; /**< PIPE_POLYGON_MODE_x */ unsigned fill_back:2; /**< PIPE_POLYGON_MODE_x */
unsigned offset_cw:1; unsigned offset_point:1;
unsigned offset_ccw:1; unsigned offset_line:1;
unsigned offset_tri:1;
unsigned scissor:1; unsigned scissor:1;
unsigned poly_smooth:1; unsigned poly_smooth:1;
unsigned poly_stipple_enable:1; unsigned poly_stipple_enable:1;

View File

@@ -379,7 +379,7 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx)
dsa.stencil[0].func = PIPE_FUNC_ALWAYS; dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
dsa.stencil[0].valuemask = ~0; dsa.stencil[0].valuemask = ~0;
raster.cull_mode = raster.front_winding ^ PIPE_WINDING_BOTH; raster.cull_face = PIPE_FACE_BACK;
dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP; dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
@@ -389,7 +389,7 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx)
cso_set_rasterizer(ctx->cso_context, &raster); cso_set_rasterizer(ctx->cso_context, &raster);
draw_polygon(ctx, poly); draw_polygon(ctx, poly);
raster.cull_mode = raster.front_winding; raster.cull_face = PIPE_FACE_FRONT;
dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP; dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
@@ -501,7 +501,7 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx)
dsa.stencil[0].func = PIPE_FUNC_ALWAYS; dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
dsa.stencil[0].valuemask = ~0; dsa.stencil[0].valuemask = ~0;
raster.cull_mode = raster.front_winding ^ PIPE_WINDING_BOTH; raster.cull_face = PIPE_FACE_BACK;
dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP; dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP;
@@ -514,7 +514,7 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx)
draw_polygon(ctx, poly); draw_polygon(ctx, poly);
} }
raster.cull_mode = raster.front_winding; raster.cull_face = PIPE_FACE_FRONT;
dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP; dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;

View File

@@ -53,21 +53,6 @@ static GLuint translate_fill( GLenum mode )
} }
} }
static GLboolean get_offset_flag( GLuint fill_mode,
const struct gl_polygon_attrib *p )
{
switch (fill_mode) {
case PIPE_POLYGON_MODE_POINT:
return p->OffsetPoint;
case PIPE_POLYGON_MODE_LINE:
return p->OffsetLine;
case PIPE_POLYGON_MODE_FILL:
return p->OffsetFill;
default:
assert(0);
return 0;
}
}
static void update_raster_state( struct st_context *st ) static void update_raster_state( struct st_context *st )
@@ -82,10 +67,7 @@ static void update_raster_state( struct st_context *st )
/* _NEW_POLYGON, _NEW_BUFFERS /* _NEW_POLYGON, _NEW_BUFFERS
*/ */
{ {
if (ctx->Polygon.FrontFace == GL_CCW) raster->front_ccw = (ctx->Polygon.FrontFace == GL_CCW);
raster->front_winding = PIPE_WINDING_CCW;
else
raster->front_winding = PIPE_WINDING_CW;
/* XXX /* XXX
* I think the intention here is that user-created framebuffer objects * I think the intention here is that user-created framebuffer objects
@@ -94,7 +76,7 @@ static void update_raster_state( struct st_context *st )
* But this is an implementation/driver-specific artifact - remove... * But this is an implementation/driver-specific artifact - remove...
*/ */
if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0) if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0)
raster->front_winding ^= PIPE_WINDING_BOTH; raster->front_ccw ^= 1;
} }
/* _NEW_LIGHT /* _NEW_LIGHT
@@ -131,40 +113,36 @@ static void update_raster_state( struct st_context *st )
/* _NEW_POLYGON /* _NEW_POLYGON
*/ */
if (ctx->Polygon.CullFlag) { if (ctx->Polygon.CullFlag) {
if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) { switch (ctx->Polygon.CullFaceMode) {
raster->cull_mode = PIPE_WINDING_BOTH; case GL_FRONT:
} raster->cull_face = PIPE_FACE_FRONT;
else if (ctx->Polygon.CullFaceMode == GL_FRONT) { break;
raster->cull_mode = raster->front_winding; case GL_BACK:
} raster->cull_face = PIPE_FACE_BACK;
else { break;
raster->cull_mode = raster->front_winding ^ PIPE_WINDING_BOTH; case GL_FRONT_AND_BACK:
raster->cull_face = PIPE_FACE_FRONT_AND_BACK;
break;
} }
} }
else {
raster->cull_face = PIPE_FACE_NONE;
}
/* _NEW_POLYGON /* _NEW_POLYGON
*/ */
{ {
GLuint fill_front = translate_fill( ctx->Polygon.FrontMode ); raster->fill_front = translate_fill( ctx->Polygon.FrontMode );
GLuint fill_back = translate_fill( ctx->Polygon.BackMode ); raster->fill_back = translate_fill( ctx->Polygon.BackMode );
if (raster->front_winding == PIPE_WINDING_CW) {
raster->fill_cw = fill_front;
raster->fill_ccw = fill_back;
}
else {
raster->fill_cw = fill_back;
raster->fill_ccw = fill_front;
}
/* Simplify when culling is active: /* Simplify when culling is active:
*/ */
if (raster->cull_mode & PIPE_WINDING_CW) { if (raster->cull_face & PIPE_FACE_FRONT) {
raster->fill_cw = raster->fill_ccw; raster->fill_front = raster->fill_back;
} }
if (raster->cull_mode & PIPE_WINDING_CCW) { if (raster->cull_face & PIPE_FACE_BACK) {
raster->fill_ccw = raster->fill_cw; raster->fill_back = raster->fill_front;
} }
} }
@@ -172,8 +150,14 @@ static void update_raster_state( struct st_context *st )
*/ */
if (ctx->Polygon.OffsetUnits != 0.0 || if (ctx->Polygon.OffsetUnits != 0.0 ||
ctx->Polygon.OffsetFactor != 0.0) { ctx->Polygon.OffsetFactor != 0.0) {
raster->offset_cw = get_offset_flag( raster->fill_cw, &ctx->Polygon ); raster->offset_point = ctx->Polygon.OffsetPoint;
raster->offset_ccw = get_offset_flag( raster->fill_ccw, &ctx->Polygon ); raster->offset_line = ctx->Polygon.OffsetLine;
raster->offset_tri = ctx->Polygon.OffsetFill;
}
if (ctx->Polygon.OffsetPoint ||
ctx->Polygon.OffsetLine ||
ctx->Polygon.OffsetFill) {
raster->offset_units = ctx->Polygon.OffsetUnits; raster->offset_units = ctx->Polygon.OffsetUnits;
raster->offset_scale = ctx->Polygon.OffsetFactor; raster->offset_scale = ctx->Polygon.OffsetFactor;
} }