+static unsigned
+translate_fill_mode(unsigned fill)
+{
+ switch (fill) {
+ case PIPE_POLYGON_MODE_POINT:
+ return SVGA3D_FILLMODE_POINT;
+ case PIPE_POLYGON_MODE_LINE:
+ return SVGA3D_FILLMODE_LINE;
+ case PIPE_POLYGON_MODE_FILL:
+ return SVGA3D_FILLMODE_FILL;
+ default:
+ assert(!"Bad fill mode");
+ return SVGA3D_FILLMODE_FILL;
+ }
+}
+
+
+static unsigned
+translate_cull_mode(unsigned cull)
+{
+ switch (cull) {
+ case PIPE_FACE_NONE:
+ return SVGA3D_CULL_NONE;
+ case PIPE_FACE_FRONT:
+ return SVGA3D_CULL_FRONT;
+ case PIPE_FACE_BACK:
+ return SVGA3D_CULL_BACK;
+ case PIPE_FACE_FRONT_AND_BACK:
+ /* NOTE: we simply no-op polygon drawing in svga_draw_vbo() */
+ return SVGA3D_CULL_NONE;
+ default:
+ assert(!"Bad cull mode");
+ return SVGA3D_CULL_NONE;
+ }
+}
+
+
+static void
+define_rasterizer_object(struct svga_context *svga,
+ struct svga_rasterizer_state *rast)
+{
+ struct svga_screen *svgascreen = svga_screen(svga->pipe.screen);
+ unsigned fill_mode = translate_fill_mode(rast->templ.fill_front);
+ const unsigned cull_mode = translate_cull_mode(rast->templ.cull_face);
+ const int depth_bias = rast->templ.offset_units;
+ const float slope_scaled_depth_bias = rast->templ.offset_scale;
+ /* PIPE_CAP_POLYGON_OFFSET_CLAMP not supported: */
+ const float depth_bias_clamp = 0.0;
+ const float line_width = rast->templ.line_width > 0.0f ?
+ rast->templ.line_width : 1.0f;
+ const uint8 line_factor = rast->templ.line_stipple_enable ?
+ rast->templ.line_stipple_factor : 0;
+ const uint16 line_pattern = rast->templ.line_stipple_enable ?
+ rast->templ.line_stipple_pattern : 0;
+ unsigned try;
+
+ rast->id = util_bitmask_add(svga->rast_object_id_bm);
+
+ if (rast->templ.fill_front != rast->templ.fill_back) {
+ /* The VGPU10 device can't handle different front/back fill modes.
+ * We'll handle that with a swtnl/draw fallback. But we need to
+ * make sure we always fill triangles in that case.
+ */
+ fill_mode = SVGA3D_FILLMODE_FILL;
+ }
+
+ for (try = 0; try < 2; try++) {
+ const uint8 pv_last = !rast->templ.flatshade_first &&
+ svgascreen->haveProvokingVertex;
+ enum pipe_error ret =
+ SVGA3D_vgpu10_DefineRasterizerState(svga->swc,
+ rast->id,
+ fill_mode,
+ cull_mode,
+ rast->templ.front_ccw,
+ depth_bias,
+ depth_bias_clamp,
+ slope_scaled_depth_bias,
+ rast->templ.depth_clip,
+ rast->templ.scissor,
+ rast->templ.multisample,
+ rast->templ.line_smooth,
+ line_width,
+ rast->templ.line_stipple_enable,
+ line_factor,
+ line_pattern,
+ pv_last);
+ if (ret == PIPE_OK)
+ return;
+ svga_context_flush(svga, NULL);
+ }
+}
+
+