Merge branch 'gallium-front-ccw'
This commit is contained in:
@@ -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 );
|
||||
|
@@ -134,7 +134,8 @@ static void unfilled_tri( struct draw_stage *stage,
|
||||
struct prim_header *header )
|
||||
{
|
||||
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)
|
||||
print_header_flags(header->flags);
|
||||
@@ -159,9 +160,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[0] = rast->front_ccw ? rast->fill_front : rast->fill_back;
|
||||
unfilled->mode[1] = rast->front_ccw ? rast->fill_back : rast->fill_front;
|
||||
|
||||
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_back != 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 */
|
||||
|
@@ -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
|
||||
}
|
||||
#endif
|
||||
|
@@ -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
|
||||
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
|
||||
------
|
||||
|
||||
@@ -89,68 +161,21 @@ coordinates are not generated.
|
||||
Some renderers always internally translate points into quads; this 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
|
||||
Whether points should be smoothed. Point smoothing turns rectangular
|
||||
points into circles or ovals.
|
||||
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
|
||||
The size of points, if not specified per-vertex.
|
||||
|
||||
|
||||
|
||||
Other Members
|
||||
-------------
|
||||
|
||||
scissor
|
||||
Whether the scissor test is enabled.
|
||||
|
||||
|
@@ -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_face & 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_face & 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;
|
||||
@@ -111,12 +138,12 @@ static void *brw_create_rasterizer_state( struct pipe_context *pipe,
|
||||
/* Caclculate lookup value for WM IZ table.
|
||||
*/
|
||||
if (templ->line_smooth) {
|
||||
if (templ->fill_cw == PIPE_POLYGON_MODE_LINE &&
|
||||
templ->fill_ccw == PIPE_POLYGON_MODE_LINE) {
|
||||
if (templ->fill_front == PIPE_POLYGON_MODE_LINE &&
|
||||
templ->fill_back == PIPE_POLYGON_MODE_LINE) {
|
||||
rast->unfilled_aa_line = AA_ALWAYS;
|
||||
}
|
||||
else if (templ->fill_cw == PIPE_POLYGON_MODE_LINE ||
|
||||
templ->fill_ccw == PIPE_POLYGON_MODE_LINE) {
|
||||
else if (templ->fill_front == PIPE_POLYGON_MODE_LINE ||
|
||||
templ->fill_back == PIPE_POLYGON_MODE_LINE) {
|
||||
rast->unfilled_aa_line = AA_SOMETIMES;
|
||||
}
|
||||
else {
|
||||
|
@@ -166,8 +166,8 @@ static enum pipe_error upload_sf_prog(struct brw_context *brw)
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
/* PIPE_NEW_RAST
|
||||
*/
|
||||
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)
|
||||
key.primitive = SF_UNFILLED_TRIS;
|
||||
else
|
||||
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;
|
||||
|
||||
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,
|
||||
|
@@ -89,8 +89,8 @@ struct brw_sf_unit_key {
|
||||
unsigned line_smooth:1;
|
||||
unsigned point_sprite:1;
|
||||
unsigned point_attenuated:1;
|
||||
unsigned front_face:2;
|
||||
unsigned cull_mode:2;
|
||||
unsigned front_ccw:1;
|
||||
unsigned cull_face:2;
|
||||
unsigned flatshade_first:1;
|
||||
unsigned gl_rasterization_rules: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 */
|
||||
key->scissor = rast->scissor;
|
||||
key->front_face = rast->front_winding;
|
||||
key->cull_mode = rast->cull_mode;
|
||||
key->front_ccw = rast->front_ccw;
|
||||
key->cull_face = rast->cull_face;
|
||||
key->line_smooth = rast->line_smooth;
|
||||
key->line_width = rast->line_width;
|
||||
key->flatshade_first = rast->flatshade_first;
|
||||
@@ -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);
|
||||
|
||||
|
@@ -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->offset_enable = (brw->curr.rast->templ.offset_cw ||
|
||||
brw->curr.rast->templ.offset_ccw);
|
||||
key->offset_enable = (brw->curr.rast->templ.offset_point ||
|
||||
brw->curr.rast->templ.offset_line ||
|
||||
brw->curr.rast->templ.offset_tri);
|
||||
|
||||
key->offset_units = brw->curr.rast->templ.offset_units;
|
||||
key->offset_factor = brw->curr.rast->templ.offset_scale;
|
||||
|
@@ -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_BACK:
|
||||
setup->triangle = setup->ccw_is_frontface ? triangle_ccw : triangle_cw;
|
||||
break;
|
||||
case PIPE_WINDING_CW:
|
||||
setup->triangle = triangle_ccw;
|
||||
case PIPE_FACE_FRONT:
|
||||
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_face != 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_face) {
|
||||
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));
|
||||
|
@@ -801,53 +801,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) {
|
||||
/* 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_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 {
|
||||
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);
|
||||
}
|
||||
/* Polygon offset */
|
||||
if (util_get_offset(state, state->fill_front)) {
|
||||
rs->polygon_offset_enable |= R300_FRONT_ENABLE;
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (~(state->front_winding) & state->cull_mode) {
|
||||
if (state->cull_face & PIPE_FACE_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) {
|
||||
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->two_sided_color = rs->rs.light_twoside;
|
||||
} else {
|
||||
|
@@ -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,13 @@ struct setup_context {
|
||||
uint numFragsWritten; /**< per primitive */
|
||||
#endif
|
||||
|
||||
unsigned winding; /* which winding to cull */
|
||||
unsigned cull_face; /* which faces 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 +372,16 @@ 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));
|
||||
|
||||
{
|
||||
unsigned face = setup->facing == 0 ? PIPE_FACE_FRONT : PIPE_FACE_BACK;
|
||||
|
||||
if (face & setup->cull_face)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Prepare pixel offset for rasterisation:
|
||||
* - pixel center (0.5, 0.5) for GL, or
|
||||
@@ -832,11 +819,9 @@ sp_setup_tri(struct setup_context *setup,
|
||||
setup->numFragsWritten = 0;
|
||||
#endif
|
||||
|
||||
if (cull_tri( setup, det ))
|
||||
return;
|
||||
|
||||
if (!setup_sort_vertices( setup, det, v0, v1, v2 ))
|
||||
return;
|
||||
|
||||
setup_tri_coefficients( setup );
|
||||
setup_tri_edges( setup );
|
||||
|
||||
@@ -1420,14 +1405,14 @@ sp_setup_prepare(struct setup_context *setup)
|
||||
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) {
|
||||
sp->rasterizer->fill_front == PIPE_POLYGON_MODE_FILL &&
|
||||
sp->rasterizer->fill_back == PIPE_POLYGON_MODE_FILL) {
|
||||
/* we'll do culling */
|
||||
setup->winding = sp->rasterizer->cull_mode;
|
||||
setup->cull_face = sp->rasterizer->cull_face;
|
||||
}
|
||||
else {
|
||||
/* 'draw' will do culling */
|
||||
setup->winding = PIPE_WINDING_NONE;
|
||||
setup->cull_face = PIPE_FACE_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);
|
||||
@@ -81,8 +82,8 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
|
||||
/* fill_cw, fill_ccw - draw module or index translation */
|
||||
|
||||
rast->shademode = svga_translate_flatshade( templ->flatshade );
|
||||
rast->cullmode = svga_translate_cullmode( templ->cull_mode,
|
||||
templ->front_winding );
|
||||
rast->cullmode = svga_translate_cullmode( templ->cull_face,
|
||||
templ->front_ccw );
|
||||
rast->scissortestenable = templ->scissor;
|
||||
rast->multisampleantialias = templ->multisample;
|
||||
rast->antialiasedlineenable = templ->line_smooth;
|
||||
@@ -117,31 +118,31 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
|
||||
rast->need_pipeline |= SVGA_PIPELINE_FLAG_POINTS;
|
||||
|
||||
{
|
||||
boolean offset_cw = templ->offset_cw;
|
||||
boolean offset_ccw = templ->offset_ccw;
|
||||
boolean offset = 0;
|
||||
int fill_cw = templ->fill_cw;
|
||||
int fill_ccw = templ->fill_ccw;
|
||||
int fill_front = templ->fill_front;
|
||||
int fill_back = templ->fill_back;
|
||||
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) {
|
||||
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;
|
||||
|
@@ -379,7 +379,7 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx)
|
||||
dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
|
||||
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].zfail_op = PIPE_STENCIL_OP_KEEP;
|
||||
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);
|
||||
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].zfail_op = PIPE_STENCIL_OP_KEEP;
|
||||
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].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].zfail_op = PIPE_STENCIL_OP_KEEP;
|
||||
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);
|
||||
}
|
||||
|
||||
raster.cull_mode = raster.front_winding;
|
||||
raster.cull_face = PIPE_FACE_FRONT;
|
||||
dsa.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP;
|
||||
dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP;
|
||||
dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_DECR_WRAP;
|
||||
|
@@ -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 )
|
||||
@@ -82,10 +67,7 @@ static void update_raster_state( struct st_context *st )
|
||||
/* _NEW_POLYGON, _NEW_BUFFERS
|
||||
*/
|
||||
{
|
||||
if (ctx->Polygon.FrontFace == GL_CCW)
|
||||
raster->front_winding = PIPE_WINDING_CCW;
|
||||
else
|
||||
raster->front_winding = PIPE_WINDING_CW;
|
||||
raster->front_ccw = (ctx->Polygon.FrontFace == GL_CCW);
|
||||
|
||||
/* XXX
|
||||
* 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...
|
||||
*/
|
||||
if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0)
|
||||
raster->front_winding ^= PIPE_WINDING_BOTH;
|
||||
raster->front_ccw ^= 1;
|
||||
}
|
||||
|
||||
/* _NEW_LIGHT
|
||||
@@ -131,40 +113,36 @@ static void update_raster_state( struct st_context *st )
|
||||
/* _NEW_POLYGON
|
||||
*/
|
||||
if (ctx->Polygon.CullFlag) {
|
||||
if (ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) {
|
||||
raster->cull_mode = PIPE_WINDING_BOTH;
|
||||
}
|
||||
else if (ctx->Polygon.CullFaceMode == GL_FRONT) {
|
||||
raster->cull_mode = raster->front_winding;
|
||||
}
|
||||
else {
|
||||
raster->cull_mode = raster->front_winding ^ PIPE_WINDING_BOTH;
|
||||
switch (ctx->Polygon.CullFaceMode) {
|
||||
case GL_FRONT:
|
||||
raster->cull_face = PIPE_FACE_FRONT;
|
||||
break;
|
||||
case GL_BACK:
|
||||
raster->cull_face = PIPE_FACE_BACK;
|
||||
break;
|
||||
case GL_FRONT_AND_BACK:
|
||||
raster->cull_face = PIPE_FACE_FRONT_AND_BACK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
raster->cull_face = PIPE_FACE_NONE;
|
||||
}
|
||||
|
||||
/* _NEW_POLYGON
|
||||
*/
|
||||
{
|
||||
GLuint fill_front = translate_fill( ctx->Polygon.FrontMode );
|
||||
GLuint 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;
|
||||
}
|
||||
raster->fill_front = translate_fill( ctx->Polygon.FrontMode );
|
||||
raster->fill_back = translate_fill( ctx->Polygon.BackMode );
|
||||
|
||||
/* Simplify when culling is active:
|
||||
*/
|
||||
if (raster->cull_mode & PIPE_WINDING_CW) {
|
||||
raster->fill_cw = raster->fill_ccw;
|
||||
if (raster->cull_face & PIPE_FACE_FRONT) {
|
||||
raster->fill_front = raster->fill_back;
|
||||
}
|
||||
|
||||
if (raster->cull_mode & PIPE_WINDING_CCW) {
|
||||
raster->fill_ccw = raster->fill_cw;
|
||||
if (raster->cull_face & PIPE_FACE_BACK) {
|
||||
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 ||
|
||||
ctx->Polygon.OffsetFactor != 0.0) {
|
||||
raster->offset_cw = get_offset_flag( raster->fill_cw, &ctx->Polygon );
|
||||
raster->offset_ccw = get_offset_flag( raster->fill_ccw, &ctx->Polygon );
|
||||
raster->offset_point = ctx->Polygon.OffsetPoint;
|
||||
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_scale = ctx->Polygon.OffsetFactor;
|
||||
}
|
||||
|
Reference in New Issue
Block a user