void nv10_emit_polygon_mode(GLcontext *ctx, int emit) { struct nouveau_channel *chan = context_chan(ctx); struct nouveau_grobj *celsius = context_eng3d(ctx); BEGIN_RING(chan, celsius, NV10TCL_POLYGON_MODE_FRONT, 2); OUT_RING(chan, nvgl_polygon_mode(ctx->Polygon.FrontMode)); OUT_RING(chan, nvgl_polygon_mode(ctx->Polygon.BackMode)); BEGIN_RING(chan, celsius, NV10TCL_POLYGON_SMOOTH_ENABLE, 1); OUT_RING(chan, ctx->Polygon.SmoothFlag ? 1 : 0); }
/* NOTE: ignoring line_last_pixel */ static void * nv50_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) { struct nv50_rasterizer_stateobj *so; uint32_t reg; so = CALLOC_STRUCT(nv50_rasterizer_stateobj); if (!so) return NULL; so->pipe = *cso; #ifndef NV50_SCISSORS_CLIPPING for (int i = 0; i < NV50_MAX_VIEWPORTS; i++) { SB_BEGIN_3D(so, SCISSOR_ENABLE(i), 1); SB_DATA (so, cso->scissor); } #endif SB_BEGIN_3D(so, SHADE_MODEL, 1); SB_DATA (so, cso->flatshade ? NV50_3D_SHADE_MODEL_FLAT : NV50_3D_SHADE_MODEL_SMOOTH); SB_BEGIN_3D(so, PROVOKING_VERTEX_LAST, 1); SB_DATA (so, !cso->flatshade_first); SB_BEGIN_3D(so, VERTEX_TWO_SIDE_ENABLE, 1); SB_DATA (so, cso->light_twoside); SB_BEGIN_3D(so, FRAG_COLOR_CLAMP_EN, 1); SB_DATA (so, cso->clamp_fragment_color ? 0x11111111 : 0x00000000); SB_BEGIN_3D(so, MULTISAMPLE_ENABLE, 1); SB_DATA (so, cso->multisample); SB_BEGIN_3D(so, LINE_WIDTH, 1); SB_DATA (so, fui(cso->line_width)); SB_BEGIN_3D(so, LINE_SMOOTH_ENABLE, 1); SB_DATA (so, cso->line_smooth); SB_BEGIN_3D(so, LINE_STIPPLE_ENABLE, 1); if (cso->line_stipple_enable) { SB_DATA (so, 1); SB_BEGIN_3D(so, LINE_STIPPLE, 1); SB_DATA (so, (cso->line_stipple_pattern << 8) | cso->line_stipple_factor); } else { SB_DATA (so, 0); } if (!cso->point_size_per_vertex) { SB_BEGIN_3D(so, POINT_SIZE, 1); SB_DATA (so, fui(cso->point_size)); } SB_BEGIN_3D(so, POINT_SPRITE_ENABLE, 1); SB_DATA (so, cso->point_quad_rasterization); SB_BEGIN_3D(so, POINT_SMOOTH_ENABLE, 1); SB_DATA (so, cso->point_smooth); SB_BEGIN_3D(so, POLYGON_MODE_FRONT, 3); SB_DATA (so, nvgl_polygon_mode(cso->fill_front)); SB_DATA (so, nvgl_polygon_mode(cso->fill_back)); SB_DATA (so, cso->poly_smooth); SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3); SB_DATA (so, cso->cull_face != PIPE_FACE_NONE); SB_DATA (so, cso->front_ccw ? NV50_3D_FRONT_FACE_CCW : NV50_3D_FRONT_FACE_CW); switch (cso->cull_face) { case PIPE_FACE_FRONT_AND_BACK: SB_DATA(so, NV50_3D_CULL_FACE_FRONT_AND_BACK); break; case PIPE_FACE_FRONT: SB_DATA(so, NV50_3D_CULL_FACE_FRONT); break; case PIPE_FACE_BACK: default: SB_DATA(so, NV50_3D_CULL_FACE_BACK); break; } SB_BEGIN_3D(so, POLYGON_STIPPLE_ENABLE, 1); SB_DATA (so, cso->poly_stipple_enable); SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3); SB_DATA (so, cso->offset_point); SB_DATA (so, cso->offset_line); SB_DATA (so, cso->offset_tri); if (cso->offset_point || cso->offset_line || cso->offset_tri) { SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1); SB_DATA (so, fui(cso->offset_scale)); SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1); SB_DATA (so, fui(cso->offset_units * 2.0f)); SB_BEGIN_3D(so, POLYGON_OFFSET_CLAMP, 1); SB_DATA (so, fui(cso->offset_clamp)); } if (cso->depth_clip) { reg = 0; } else { reg = NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR | NV50_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR | NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1; } #ifndef NV50_SCISSORS_CLIPPING reg |= NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK7 | NV50_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK1; #endif SB_BEGIN_3D(so, VIEW_VOLUME_CLIP_CTRL, 1); SB_DATA (so, reg); SB_BEGIN_3D(so, DEPTH_CLIP_NEGATIVE_Z, 1); SB_DATA (so, cso->clip_halfz); SB_BEGIN_3D(so, PIXEL_CENTER_INTEGER, 1); SB_DATA (so, !cso->half_pixel_center); assert(so->size <= (sizeof(so->state) / sizeof(so->state[0]))); return (void *)so; }
/* NOTE: ignoring line_last_pixel */ static void * nvc0_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) { struct nvc0_rasterizer_stateobj *so; uint32_t reg; so = CALLOC_STRUCT(nvc0_rasterizer_stateobj); if (!so) return NULL; so->pipe = *cso; /* Scissor enables are handled in scissor state, we will not want to * always emit 16 commands, one for each scissor rectangle, here. */ SB_IMMED_3D(so, PROVOKING_VERTEX_LAST, !cso->flatshade_first); SB_IMMED_3D(so, VERTEX_TWO_SIDE_ENABLE, cso->light_twoside); SB_IMMED_3D(so, VERT_COLOR_CLAMP_EN, cso->clamp_vertex_color); SB_BEGIN_3D(so, FRAG_COLOR_CLAMP_EN, 1); SB_DATA (so, cso->clamp_fragment_color ? 0x11111111 : 0x00000000); SB_IMMED_3D(so, MULTISAMPLE_ENABLE, cso->multisample); SB_IMMED_3D(so, LINE_SMOOTH_ENABLE, cso->line_smooth); if (cso->line_smooth || cso->multisample) SB_BEGIN_3D(so, LINE_WIDTH_SMOOTH, 1); else SB_BEGIN_3D(so, LINE_WIDTH_ALIASED, 1); SB_DATA (so, fui(cso->line_width)); SB_IMMED_3D(so, LINE_STIPPLE_ENABLE, cso->line_stipple_enable); if (cso->line_stipple_enable) { SB_BEGIN_3D(so, LINE_STIPPLE_PATTERN, 1); SB_DATA (so, (cso->line_stipple_pattern << 8) | cso->line_stipple_factor); } SB_IMMED_3D(so, VP_POINT_SIZE, cso->point_size_per_vertex); if (!cso->point_size_per_vertex) { SB_BEGIN_3D(so, POINT_SIZE, 1); SB_DATA (so, fui(cso->point_size)); } reg = (cso->sprite_coord_mode == PIPE_SPRITE_COORD_UPPER_LEFT) ? NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_UPPER_LEFT : NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_LOWER_LEFT; SB_BEGIN_3D(so, POINT_COORD_REPLACE, 1); SB_DATA (so, ((cso->sprite_coord_enable & 0xff) << 3) | reg); SB_IMMED_3D(so, POINT_SPRITE_ENABLE, cso->point_quad_rasterization); SB_IMMED_3D(so, POINT_SMOOTH_ENABLE, cso->point_smooth); SB_BEGIN_3D(so, MACRO_POLYGON_MODE_FRONT, 1); SB_DATA (so, nvgl_polygon_mode(cso->fill_front)); SB_BEGIN_3D(so, MACRO_POLYGON_MODE_BACK, 1); SB_DATA (so, nvgl_polygon_mode(cso->fill_back)); SB_IMMED_3D(so, POLYGON_SMOOTH_ENABLE, cso->poly_smooth); SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3); SB_DATA (so, cso->cull_face != PIPE_FACE_NONE); SB_DATA (so, cso->front_ccw ? NVC0_3D_FRONT_FACE_CCW : NVC0_3D_FRONT_FACE_CW); switch (cso->cull_face) { case PIPE_FACE_FRONT_AND_BACK: SB_DATA(so, NVC0_3D_CULL_FACE_FRONT_AND_BACK); break; case PIPE_FACE_FRONT: SB_DATA(so, NVC0_3D_CULL_FACE_FRONT); break; case PIPE_FACE_BACK: default: SB_DATA(so, NVC0_3D_CULL_FACE_BACK); break; } SB_IMMED_3D(so, POLYGON_STIPPLE_ENABLE, cso->poly_stipple_enable); SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3); SB_DATA (so, cso->offset_point); SB_DATA (so, cso->offset_line); SB_DATA (so, cso->offset_tri); if (cso->offset_point || cso->offset_line || cso->offset_tri) { SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1); SB_DATA (so, fui(cso->offset_scale)); SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1); SB_DATA (so, fui(cso->offset_units * 2.0f)); SB_BEGIN_3D(so, POLYGON_OFFSET_CLAMP, 1); SB_DATA (so, fui(cso->offset_clamp)); } if (cso->depth_clip) reg = NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1; else reg = NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1 | NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR | NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR | NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK2; SB_BEGIN_3D(so, VIEW_VOLUME_CLIP_CTRL, 1); SB_DATA (so, reg); SB_IMMED_3D(so, DEPTH_CLIP_NEGATIVE_Z, cso->clip_halfz); SB_IMMED_3D(so, PIXEL_CENTER_INTEGER, !cso->half_pixel_center); assert(so->size <= ARRAY_SIZE(so->state)); return (void *)so; }
static void * nv40_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) { struct nv40_context *nv40 = nv40_context(pipe); struct nv40_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso)); struct nouveau_stateobj *so = so_new(32, 0); struct nouveau_grobj *curie = nv40->screen->curie; /*XXX: ignored: * light_twoside * point_smooth -nohw * multisample */ so_method(so, curie, NV40TCL_SHADE_MODEL, 1); so_data (so, cso->flatshade ? NV40TCL_SHADE_MODEL_FLAT : NV40TCL_SHADE_MODEL_SMOOTH); so_method(so, curie, NV40TCL_LINE_WIDTH, 2); so_data (so, (unsigned char)(cso->line_width * 8.0) & 0xff); so_data (so, cso->line_smooth ? 1 : 0); so_method(so, curie, NV40TCL_LINE_STIPPLE_ENABLE, 2); so_data (so, cso->line_stipple_enable ? 1 : 0); so_data (so, (cso->line_stipple_pattern << 16) | cso->line_stipple_factor); so_method(so, curie, NV40TCL_POINT_SIZE, 1); so_data (so, fui(cso->point_size)); so_method(so, curie, NV40TCL_POLYGON_MODE_FRONT, 6); 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)); switch (cso->cull_mode) { case PIPE_WINDING_CCW: so_data(so, NV40TCL_CULL_FACE_FRONT); break; case PIPE_WINDING_CW: so_data(so, NV40TCL_CULL_FACE_BACK); break; case PIPE_WINDING_BOTH: so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK); break; default: so_data(so, NV40TCL_CULL_FACE_BACK); break; } so_data(so, NV40TCL_FRONT_FACE_CCW); } else { so_data(so, nvgl_polygon_mode(cso->fill_cw)); so_data(so, nvgl_polygon_mode(cso->fill_ccw)); switch (cso->cull_mode) { case PIPE_WINDING_CCW: so_data(so, NV40TCL_CULL_FACE_BACK); break; case PIPE_WINDING_CW: so_data(so, NV40TCL_CULL_FACE_FRONT); break; case PIPE_WINDING_BOTH: so_data(so, NV40TCL_CULL_FACE_FRONT_AND_BACK); break; default: so_data(so, NV40TCL_CULL_FACE_BACK); break; } so_data(so, NV40TCL_FRONT_FACE_CW); } so_data(so, cso->poly_smooth ? 1 : 0); so_data(so, (cso->cull_mode != PIPE_WINDING_NONE) ? 1 : 0); so_method(so, curie, NV40TCL_POLYGON_STIPPLE_ENABLE, 1); so_data (so, cso->poly_stipple_enable ? 1 : 0); so_method(so, curie, NV40TCL_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); if (cso->offset_cw || cso->offset_ccw) { so_method(so, curie, NV40TCL_POLYGON_OFFSET_FACTOR, 2); so_data (so, fui(cso->offset_scale)); so_data (so, fui(cso->offset_units * 2)); } so_method(so, curie, NV40TCL_POINT_SPRITE, 1); if (cso->point_sprite) { unsigned psctl = (1 << 0), i; for (i = 0; i < 8; i++) { if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE) psctl |= (1 << (8 + i)); } so_data(so, psctl); } else { so_data(so, 0); } so_ref(so, &rsso->so); so_ref(NULL, &so); rsso->pipe = *cso; return (void *)rsso; }
static void * nv50_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) { struct nouveau_stateobj *so = so_new(15, 21, 0); struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla; struct nv50_rasterizer_stateobj *rso = CALLOC_STRUCT(nv50_rasterizer_stateobj); /*XXX: ignored * - light_twosize * - point_smooth * - multisample * - point_sprite / sprite_coord_mode */ so_method(so, tesla, NV50TCL_SHADE_MODEL, 1); so_data (so, cso->flatshade ? NV50TCL_SHADE_MODEL_FLAT : NV50TCL_SHADE_MODEL_SMOOTH); so_method(so, tesla, NV50TCL_PROVOKING_VERTEX_LAST, 1); so_data (so, cso->flatshade_first ? 0 : 1); so_method(so, tesla, NV50TCL_VERTEX_TWO_SIDE_ENABLE, 1); so_data (so, cso->light_twoside); so_method(so, tesla, NV50TCL_LINE_WIDTH, 1); so_data (so, fui(cso->line_width)); so_method(so, tesla, NV50TCL_LINE_SMOOTH_ENABLE, 1); so_data (so, cso->line_smooth ? 1 : 0); if (cso->line_stipple_enable) { so_method(so, tesla, NV50TCL_LINE_STIPPLE_ENABLE, 1); so_data (so, 1); so_method(so, tesla, NV50TCL_LINE_STIPPLE_PATTERN, 1); so_data (so, (cso->line_stipple_pattern << 8) | cso->line_stipple_factor); } else { so_method(so, tesla, NV50TCL_LINE_STIPPLE_ENABLE, 1); so_data (so, 0); } so_method(so, tesla, NV50TCL_POINT_SIZE, 1); so_data (so, fui(cso->point_size)); so_method(so, tesla, NV50TCL_POINT_SPRITE_ENABLE, 1); 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, 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, 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 { 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; } } 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); if (cso->offset_cw || cso->offset_ccw) { 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); so_data (so, fui(cso->offset_units * 2.0f)); } rso->pipe = *cso; so_ref(so, &rso->so); so_ref(NULL, &so); return (void *)rso; }
static void * nv30_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) { struct nv30_rasterizer_stateobj *so; so = CALLOC_STRUCT(nv30_rasterizer_stateobj); if (!so) return NULL; so->pipe = *cso; SB_MTHD30(so, SHADE_MODEL, 1); SB_DATA (so, cso->flatshade ? NV30_3D_SHADE_MODEL_FLAT : NV30_3D_SHADE_MODEL_SMOOTH); SB_MTHD30(so, POLYGON_MODE_FRONT, 6); SB_DATA (so, nvgl_polygon_mode(cso->fill_front)); SB_DATA (so, nvgl_polygon_mode(cso->fill_back)); if (cso->cull_face == PIPE_FACE_FRONT_AND_BACK) SB_DATA (so, NV30_3D_CULL_FACE_FRONT_AND_BACK); else if (cso->cull_face == PIPE_FACE_FRONT) SB_DATA (so, NV30_3D_CULL_FACE_FRONT); else SB_DATA (so, NV30_3D_CULL_FACE_BACK); SB_DATA (so, cso->front_ccw ? NV30_3D_FRONT_FACE_CCW : NV30_3D_FRONT_FACE_CW); SB_DATA (so, cso->poly_smooth); SB_DATA (so, cso->cull_face != PIPE_FACE_NONE); SB_MTHD30(so, POLYGON_OFFSET_POINT_ENABLE, 3); SB_DATA (so, cso->offset_point); SB_DATA (so, cso->offset_line); SB_DATA (so, cso->offset_tri); if (cso->offset_point || cso->offset_line || cso->offset_tri) { SB_MTHD30(so, POLYGON_OFFSET_FACTOR, 2); SB_DATA (so, fui(cso->offset_scale)); SB_DATA (so, fui(cso->offset_units * 2.0)); } SB_MTHD30(so, LINE_WIDTH, 2); SB_DATA (so, (unsigned char)(cso->line_width * 8.0) & 0xff); SB_DATA (so, cso->line_smooth); SB_MTHD30(so, LINE_STIPPLE_ENABLE, 2); SB_DATA (so, cso->line_stipple_enable); SB_DATA (so, (cso->line_stipple_pattern << 16) | cso->line_stipple_factor); SB_MTHD30(so, VERTEX_TWO_SIDE_ENABLE, 1); SB_DATA (so, cso->light_twoside); SB_MTHD30(so, POLYGON_STIPPLE_ENABLE, 1); SB_DATA (so, cso->poly_stipple_enable); SB_MTHD30(so, POINT_SIZE, 1); SB_DATA (so, fui(cso->point_size)); SB_MTHD30(so, FLATSHADE_FIRST, 1); SB_DATA (so, cso->flatshade_first); SB_MTHD30(so, DEPTH_CONTROL, 1); SB_DATA (so, cso->depth_clip ? 0x00000001 : 0x00000010); return so; }
/* NOTE: ignoring line_last_pixel */ static void * nvc0_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) { struct nvc0_rasterizer_stateobj *so; uint16_t class_3d = nouveau_screen(pipe->screen)->class_3d; uint32_t reg; so = CALLOC_STRUCT(nvc0_rasterizer_stateobj); if (!so) return NULL; so->pipe = *cso; /* Scissor enables are handled in scissor state, we will not want to * always emit 16 commands, one for each scissor rectangle, here. */ SB_IMMED_3D(so, PROVOKING_VERTEX_LAST, !cso->flatshade_first); SB_IMMED_3D(so, VERTEX_TWO_SIDE_ENABLE, cso->light_twoside); SB_IMMED_3D(so, VERT_COLOR_CLAMP_EN, cso->clamp_vertex_color); SB_BEGIN_3D(so, FRAG_COLOR_CLAMP_EN, 1); SB_DATA (so, cso->clamp_fragment_color ? 0x11111111 : 0x00000000); SB_IMMED_3D(so, MULTISAMPLE_ENABLE, cso->multisample); SB_IMMED_3D(so, LINE_SMOOTH_ENABLE, cso->line_smooth); /* On GM20x+, LINE_WIDTH_SMOOTH controls both aliased and smooth * rendering and LINE_WIDTH_ALIASED seems to be ignored */ if (cso->line_smooth || cso->multisample || class_3d >= GM200_3D_CLASS) SB_BEGIN_3D(so, LINE_WIDTH_SMOOTH, 1); else SB_BEGIN_3D(so, LINE_WIDTH_ALIASED, 1); SB_DATA (so, fui(cso->line_width)); SB_IMMED_3D(so, LINE_STIPPLE_ENABLE, cso->line_stipple_enable); if (cso->line_stipple_enable) { SB_BEGIN_3D(so, LINE_STIPPLE_PATTERN, 1); SB_DATA (so, (cso->line_stipple_pattern << 8) | cso->line_stipple_factor); } SB_IMMED_3D(so, VP_POINT_SIZE, cso->point_size_per_vertex); if (!cso->point_size_per_vertex) { SB_BEGIN_3D(so, POINT_SIZE, 1); SB_DATA (so, fui(cso->point_size)); } reg = (cso->sprite_coord_mode == PIPE_SPRITE_COORD_UPPER_LEFT) ? NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_UPPER_LEFT : NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_LOWER_LEFT; SB_BEGIN_3D(so, POINT_COORD_REPLACE, 1); SB_DATA (so, ((cso->sprite_coord_enable & 0xff) << 3) | reg); SB_IMMED_3D(so, POINT_SPRITE_ENABLE, cso->point_quad_rasterization); SB_IMMED_3D(so, POINT_SMOOTH_ENABLE, cso->point_smooth); if (class_3d >= GM200_3D_CLASS) { SB_IMMED_3D(so, FILL_RECTANGLE, cso->fill_front == PIPE_POLYGON_MODE_FILL_RECTANGLE ? NVC0_3D_FILL_RECTANGLE_ENABLE : 0); } SB_BEGIN_3D(so, MACRO_POLYGON_MODE_FRONT, 1); SB_DATA (so, nvgl_polygon_mode(cso->fill_front)); SB_BEGIN_3D(so, MACRO_POLYGON_MODE_BACK, 1); SB_DATA (so, nvgl_polygon_mode(cso->fill_back)); SB_IMMED_3D(so, POLYGON_SMOOTH_ENABLE, cso->poly_smooth); SB_BEGIN_3D(so, CULL_FACE_ENABLE, 3); SB_DATA (so, cso->cull_face != PIPE_FACE_NONE); SB_DATA (so, cso->front_ccw ? NVC0_3D_FRONT_FACE_CCW : NVC0_3D_FRONT_FACE_CW); switch (cso->cull_face) { case PIPE_FACE_FRONT_AND_BACK: SB_DATA(so, NVC0_3D_CULL_FACE_FRONT_AND_BACK); break; case PIPE_FACE_FRONT: SB_DATA(so, NVC0_3D_CULL_FACE_FRONT); break; case PIPE_FACE_BACK: default: SB_DATA(so, NVC0_3D_CULL_FACE_BACK); break; } SB_IMMED_3D(so, POLYGON_STIPPLE_ENABLE, cso->poly_stipple_enable); SB_BEGIN_3D(so, POLYGON_OFFSET_POINT_ENABLE, 3); SB_DATA (so, cso->offset_point); SB_DATA (so, cso->offset_line); SB_DATA (so, cso->offset_tri); if (cso->offset_point || cso->offset_line || cso->offset_tri) { SB_BEGIN_3D(so, POLYGON_OFFSET_FACTOR, 1); SB_DATA (so, fui(cso->offset_scale)); if (!cso->offset_units_unscaled) { SB_BEGIN_3D(so, POLYGON_OFFSET_UNITS, 1); SB_DATA (so, fui(cso->offset_units * 2.0f)); } SB_BEGIN_3D(so, POLYGON_OFFSET_CLAMP, 1); SB_DATA (so, fui(cso->offset_clamp)); } if (cso->depth_clip_near) reg = NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1; else reg = NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK1_UNK1 | NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_NEAR | NVC0_3D_VIEW_VOLUME_CLIP_CTRL_DEPTH_CLAMP_FAR | NVC0_3D_VIEW_VOLUME_CLIP_CTRL_UNK12_UNK2; SB_BEGIN_3D(so, VIEW_VOLUME_CLIP_CTRL, 1); SB_DATA (so, reg); SB_IMMED_3D(so, DEPTH_CLIP_NEGATIVE_Z, cso->clip_halfz); SB_IMMED_3D(so, PIXEL_CENTER_INTEGER, !cso->half_pixel_center); if (class_3d >= GM200_3D_CLASS) { if (cso->conservative_raster_mode != PIPE_CONSERVATIVE_RASTER_OFF) { bool post_snap = cso->conservative_raster_mode == PIPE_CONSERVATIVE_RASTER_POST_SNAP; uint32_t state = cso->subpixel_precision_x; state |= cso->subpixel_precision_y << 4; state |= (uint32_t)(cso->conservative_raster_dilate * 4) << 8; state |= (post_snap || class_3d < GP100_3D_CLASS) ? 1 << 10 : 0; SB_IMMED_3D(so, MACRO_CONSERVATIVE_RASTER_STATE, state); } else { SB_IMMED_3D(so, CONSERVATIVE_RASTER, 0); } } assert(so->size <= ARRAY_SIZE(so->state)); return (void *)so; }