/* Calculates the key for triangle-mode clipping. Non-triangle * clipping keys use much less information and are computed on the * fly. */ static void calculate_clip_key_rast( const struct brw_context *brw, const struct pipe_rasterizer_state *templ, const struct brw_rasterizer_state *rast, struct brw_clip_prog_key *key) { memset(key, 0, sizeof *key); if (brw->chipset.is_igdng) key->clip_mode = BRW_CLIPMODE_KERNEL_CLIP; else key->clip_mode = BRW_CLIPMODE_NORMAL; key->do_flat_shading = templ->flatshade; if (templ->cull_mode == PIPE_WINDING_BOTH) { key->clip_mode = BRW_CLIPMODE_REJECT_ALL; return; } key->fill_ccw = CLIP_CULL; key->fill_cw = CLIP_CULL; if (!(templ->cull_mode & PIPE_WINDING_CCW)) { key->fill_ccw = translate_fill(templ->fill_ccw); } if (!(templ->cull_mode & PIPE_WINDING_CW)) { key->fill_cw = translate_fill(templ->fill_cw); } if (key->fill_cw == CLIP_LINE || key->fill_ccw == CLIP_LINE || key->fill_cw == CLIP_POINT || key->fill_ccw == CLIP_POINT) { key->do_unfilled = 1; key->clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED; } key->offset_ccw = templ->offset_ccw; key->offset_cw = templ->offset_cw; if (templ->light_twoside && key->fill_cw != CLIP_CULL) key->copy_bfc_cw = 1; if (templ->light_twoside && key->fill_ccw != CLIP_CULL) key->copy_bfc_ccw = 1; }
static void update_raster_state( struct st_context *st ) { struct gl_context *ctx = st->ctx; struct pipe_rasterizer_state *raster = &st->state.rasterizer; const struct gl_vertex_program *vertProg = ctx->VertexProgram._Current; const struct gl_fragment_program *fragProg = ctx->FragmentProgram._Current; uint i; memset(raster, 0, sizeof(*raster)); /* _NEW_POLYGON, _NEW_BUFFERS */ { raster->front_ccw = (ctx->Polygon.FrontFace == GL_CCW); /* * Gallium's surfaces are Y=0=TOP orientation. OpenGL is the * opposite. Window system surfaces are Y=0=TOP. Mesa's FBOs * must match OpenGL conventions so FBOs use Y=0=BOTTOM. In that * case, we must invert Y and flip the notion of front vs. back. */ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) { /* Drawing to an FBO. The viewport will be inverted. */ raster->front_ccw ^= 1; } } /* _NEW_LIGHT */ if (ctx->Light.ShadeModel == GL_FLAT) raster->flatshade = 1; if (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION_EXT) raster->flatshade_first = 1; /* _NEW_LIGHT | _NEW_PROGRAM */ raster->light_twoside = ctx->VertexProgram._TwoSideEnabled; /*_NEW_LIGHT | _NEW_BUFFERS */ raster->clamp_vertex_color = !st->clamp_vert_color_in_shader && ctx->Light._ClampVertexColor; /* _NEW_POLYGON */ if (ctx->Polygon.CullFlag) { 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 */ { raster->fill_front = translate_fill( ctx->Polygon.FrontMode ); raster->fill_back = translate_fill( ctx->Polygon.BackMode ); /* Simplify when culling is active: */ if (raster->cull_face & PIPE_FACE_FRONT) { raster->fill_front = raster->fill_back; } if (raster->cull_face & PIPE_FACE_BACK) { raster->fill_back = raster->fill_front; } } /* _NEW_POLYGON */ if (ctx->Polygon.OffsetUnits != 0.0 || ctx->Polygon.OffsetFactor != 0.0) { 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; } if (ctx->Polygon.SmoothFlag) raster->poly_smooth = 1; if (ctx->Polygon.StippleFlag) raster->poly_stipple_enable = 1; /* _NEW_POINT */ raster->point_size = ctx->Point.Size; if (!ctx->Point.PointSprite && ctx->Point.SmoothFlag) raster->point_smooth = 1; /* _NEW_POINT | _NEW_PROGRAM */ if (ctx->Point.PointSprite) { /* origin */ if ((ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^ (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM)) raster->sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT; else raster->sprite_coord_mode = PIPE_SPRITE_COORD_LOWER_LEFT; /* Coord replacement flags. If bit 'k' is set that means * that we need to replace GENERIC[k] attrib with an automatically * computed texture coord. */ for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { if (ctx->Point.CoordReplace[i]) { raster->sprite_coord_enable |= 1 << i; } } if (fragProg->Base.InputsRead & FRAG_BIT_PNTC) { raster->sprite_coord_enable |= 1 << (FRAG_ATTRIB_PNTC - FRAG_ATTRIB_TEX0); } raster->point_quad_rasterization = 1; } /* ST_NEW_VERTEX_PROGRAM */ if (vertProg) { if (vertProg->Base.Id == 0) { if (vertProg->Base.OutputsWritten & BITFIELD64_BIT(VERT_RESULT_PSIZ)) { /* generated program which emits point size */ raster->point_size_per_vertex = TRUE; } } else if (ctx->VertexProgram.PointSizeEnabled) { /* user-defined program and GL_VERTEX_PROGRAM_POINT_SIZE set */ raster->point_size_per_vertex = ctx->VertexProgram.PointSizeEnabled; } } if (!raster->point_size_per_vertex) { /* clamp size now */ raster->point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize); } /* _NEW_LINE */ raster->line_smooth = ctx->Line.SmoothFlag; if (ctx->Line.SmoothFlag) { raster->line_width = CLAMP(ctx->Line.Width, ctx->Const.MinLineWidthAA, ctx->Const.MaxLineWidthAA); } else { raster->line_width = CLAMP(ctx->Line.Width, ctx->Const.MinLineWidth, ctx->Const.MaxLineWidth); } raster->line_stipple_enable = ctx->Line.StippleFlag; raster->line_stipple_pattern = ctx->Line.StipplePattern; /* GL stipple factor is in [1,256], remap to [0, 255] here */ raster->line_stipple_factor = ctx->Line.StippleFactor - 1; /* _NEW_MULTISAMPLE */ if (ctx->Multisample._Enabled || st->force_msaa) raster->multisample = 1; /* _NEW_SCISSOR */ if (ctx->Scissor.Enabled) raster->scissor = 1; /* _NEW_FRAG_CLAMP */ raster->clamp_fragment_color = !st->clamp_frag_color_in_shader && ctx->Color._ClampFragmentColor; raster->gl_rasterization_rules = 1; /* _NEW_RASTERIZER_DISCARD */ raster->rasterizer_discard = ctx->RasterDiscard; /* _NEW_TRANSFORM */ raster->depth_clip = ctx->Transform.DepthClamp == GL_FALSE; raster->clip_plane_enable = ctx->Transform.ClipPlanesEnabled; cso_set_rasterizer(st->cso_context, raster); }
static void update_raster_state( struct st_context *st ) { struct gl_context *ctx = st->ctx; struct pipe_rasterizer_state *raster = &st->state.rasterizer; const struct gl_vertex_program *vertProg = ctx->VertexProgram._Current; const struct gl_fragment_program *fragProg = ctx->FragmentProgram._Current; uint i; memset(raster, 0, sizeof(*raster)); /* _NEW_POLYGON, _NEW_BUFFERS */ { raster->front_ccw = (ctx->Polygon.FrontFace == GL_CCW); /* _NEW_TRANSFORM */ if (ctx->Transform.ClipOrigin == GL_UPPER_LEFT) { raster->front_ccw ^= 1; } /* * Gallium's surfaces are Y=0=TOP orientation. OpenGL is the * opposite. Window system surfaces are Y=0=TOP. Mesa's FBOs * must match OpenGL conventions so FBOs use Y=0=BOTTOM. In that * case, we must invert Y and flip the notion of front vs. back. */ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM) { /* Drawing to an FBO. The viewport will be inverted. */ raster->front_ccw ^= 1; } } /* _NEW_LIGHT */ raster->flatshade = ctx->Light.ShadeModel == GL_FLAT; raster->flatshade_first = ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION_EXT; /* _NEW_LIGHT | _NEW_PROGRAM */ raster->light_twoside = ctx->VertexProgram._TwoSideEnabled; /*_NEW_LIGHT | _NEW_BUFFERS */ raster->clamp_vertex_color = !st->clamp_vert_color_in_shader && ctx->Light._ClampVertexColor; /* _NEW_POLYGON */ if (ctx->Polygon.CullFlag) { 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 */ { if (ST_DEBUG & DEBUG_WIREFRAME) { raster->fill_front = PIPE_POLYGON_MODE_LINE; raster->fill_back = PIPE_POLYGON_MODE_LINE; } else { raster->fill_front = translate_fill( ctx->Polygon.FrontMode ); raster->fill_back = translate_fill( ctx->Polygon.BackMode ); } /* Simplify when culling is active: */ if (raster->cull_face & PIPE_FACE_FRONT) { raster->fill_front = raster->fill_back; } if (raster->cull_face & PIPE_FACE_BACK) { raster->fill_back = raster->fill_front; } } /* _NEW_POLYGON */ if (ctx->Polygon.OffsetPoint || ctx->Polygon.OffsetLine || ctx->Polygon.OffsetFill) { raster->offset_point = ctx->Polygon.OffsetPoint; raster->offset_line = ctx->Polygon.OffsetLine; raster->offset_tri = ctx->Polygon.OffsetFill; raster->offset_units = ctx->Polygon.OffsetUnits; raster->offset_scale = ctx->Polygon.OffsetFactor; raster->offset_clamp = ctx->Polygon.OffsetClamp; } raster->poly_smooth = ctx->Polygon.SmoothFlag; raster->poly_stipple_enable = ctx->Polygon.StippleFlag; /* _NEW_POINT */ raster->point_size = ctx->Point.Size; raster->point_smooth = !ctx->Point.PointSprite && ctx->Point.SmoothFlag; /* _NEW_POINT | _NEW_PROGRAM */ if (ctx->Point.PointSprite) { /* origin */ if ((ctx->Point.SpriteOrigin == GL_UPPER_LEFT) ^ (st_fb_orientation(ctx->DrawBuffer) == Y_0_BOTTOM)) raster->sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT; else raster->sprite_coord_mode = PIPE_SPRITE_COORD_LOWER_LEFT; /* Coord replacement flags. If bit 'k' is set that means * that we need to replace GENERIC[k] attrib with an automatically * computed texture coord. */ for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { if (ctx->Point.CoordReplace[i]) { raster->sprite_coord_enable |= 1 << i; } } if (!st->needs_texcoord_semantic && fragProg->Base.InputsRead & VARYING_BIT_PNTC) { raster->sprite_coord_enable |= 1 << st_get_generic_varying_index(st, VARYING_SLOT_PNTC); } raster->point_quad_rasterization = 1; } /* ST_NEW_VERTEX_PROGRAM */ if (vertProg) { if (vertProg->Base.Id == 0) { if (vertProg->Base.OutputsWritten & BITFIELD64_BIT(VARYING_SLOT_PSIZ)) { /* generated program which emits point size */ raster->point_size_per_vertex = TRUE; } } else if (ctx->API != API_OPENGLES2) { /* PointSizeEnabled is always set in ES2 contexts */ raster->point_size_per_vertex = ctx->VertexProgram.PointSizeEnabled; } else { /* ST_NEW_TESSEVAL_PROGRAM | ST_NEW_GEOMETRY_PROGRAM */ /* We have to check the last bound stage and see if it writes psize */ struct gl_program *last = NULL; if (ctx->GeometryProgram._Current) last = &ctx->GeometryProgram._Current->Base; else if (ctx->TessEvalProgram._Current) last = &ctx->TessEvalProgram._Current->Base; else if (ctx->VertexProgram._Current) last = &ctx->VertexProgram._Current->Base; if (last) raster->point_size_per_vertex = !!(last->OutputsWritten & BITFIELD64_BIT(VARYING_SLOT_PSIZ)); } } if (!raster->point_size_per_vertex) { /* clamp size now */ raster->point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize); } /* _NEW_LINE */ raster->line_smooth = ctx->Line.SmoothFlag; if (ctx->Line.SmoothFlag) { raster->line_width = CLAMP(ctx->Line.Width, ctx->Const.MinLineWidthAA, ctx->Const.MaxLineWidthAA); } else { raster->line_width = CLAMP(ctx->Line.Width, ctx->Const.MinLineWidth, ctx->Const.MaxLineWidth); } raster->line_stipple_enable = ctx->Line.StippleFlag; raster->line_stipple_pattern = ctx->Line.StipplePattern; /* GL stipple factor is in [1,256], remap to [0, 255] here */ raster->line_stipple_factor = ctx->Line.StippleFactor - 1; /* _NEW_MULTISAMPLE */ raster->multisample = _mesa_is_multisample_enabled(ctx); /* _NEW_MULTISAMPLE | _NEW_BUFFERS */ raster->force_persample_interp = !st->force_persample_in_shader && _mesa_is_multisample_enabled(ctx) && ctx->Multisample.SampleShading && ctx->Multisample.MinSampleShadingValue * _mesa_geometric_samples(ctx->DrawBuffer) > 1; /* _NEW_SCISSOR */ raster->scissor = ctx->Scissor.EnableFlags; /* _NEW_FRAG_CLAMP */ raster->clamp_fragment_color = !st->clamp_frag_color_in_shader && ctx->Color._ClampFragmentColor; raster->half_pixel_center = 1; if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) raster->bottom_edge_rule = 1; /* _NEW_TRANSFORM */ if (ctx->Transform.ClipOrigin == GL_UPPER_LEFT) raster->bottom_edge_rule ^= 1; /* ST_NEW_RASTERIZER */ raster->rasterizer_discard = ctx->RasterDiscard; if (st->edgeflag_culls_prims) { /* All edge flags are FALSE. Cull the affected faces. */ if (raster->fill_front != PIPE_POLYGON_MODE_FILL) raster->cull_face |= PIPE_FACE_FRONT; if (raster->fill_back != PIPE_POLYGON_MODE_FILL) raster->cull_face |= PIPE_FACE_BACK; } /* _NEW_TRANSFORM */ raster->depth_clip = !ctx->Transform.DepthClamp; raster->clip_plane_enable = ctx->Transform.ClipPlanesEnabled; raster->clip_halfz = (ctx->Transform.ClipDepthMode == GL_ZERO_TO_ONE); cso_set_rasterizer(st->cso_context, raster); }