static void * nvc0_zsa_state_create(struct pipe_context *pipe, const struct pipe_depth_stencil_alpha_state *cso) { struct nvc0_zsa_stateobj *so = CALLOC_STRUCT(nvc0_zsa_stateobj); so->pipe = *cso; SB_IMMED_3D(so, DEPTH_TEST_ENABLE, cso->depth.enabled); if (cso->depth.enabled) { SB_IMMED_3D(so, DEPTH_WRITE_ENABLE, cso->depth.writemask); SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1); SB_DATA (so, nvgl_comparison_op(cso->depth.func)); } SB_IMMED_3D(so, DEPTH_BOUNDS_EN, cso->depth.bounds_test); if (cso->depth.bounds_test) { SB_BEGIN_3D(so, DEPTH_BOUNDS(0), 2); SB_DATA (so, fui(cso->depth.bounds_min)); SB_DATA (so, fui(cso->depth.bounds_max)); } if (cso->stencil[0].enabled) { SB_BEGIN_3D(so, STENCIL_ENABLE, 5); SB_DATA (so, 1); SB_DATA (so, nvgl_stencil_op(cso->stencil[0].fail_op)); SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zpass_op)); SB_DATA (so, nvgl_comparison_op(cso->stencil[0].func)); SB_BEGIN_3D(so, STENCIL_FRONT_FUNC_MASK, 2); SB_DATA (so, cso->stencil[0].valuemask); SB_DATA (so, cso->stencil[0].writemask); } else { SB_IMMED_3D(so, STENCIL_ENABLE, 0); } if (cso->stencil[1].enabled) { assert(cso->stencil[0].enabled); SB_BEGIN_3D(so, STENCIL_TWO_SIDE_ENABLE, 5); SB_DATA (so, 1); SB_DATA (so, nvgl_stencil_op(cso->stencil[1].fail_op)); SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zpass_op)); SB_DATA (so, nvgl_comparison_op(cso->stencil[1].func)); SB_BEGIN_3D(so, STENCIL_BACK_MASK, 2); SB_DATA (so, cso->stencil[1].writemask); SB_DATA (so, cso->stencil[1].valuemask); } else if (cso->stencil[0].enabled) { SB_IMMED_3D(so, STENCIL_TWO_SIDE_ENABLE, 0); } SB_IMMED_3D(so, ALPHA_TEST_ENABLE, cso->alpha.enabled); if (cso->alpha.enabled) { SB_BEGIN_3D(so, ALPHA_TEST_REF, 2); SB_DATA (so, fui(cso->alpha.ref_value)); SB_DATA (so, nvgl_comparison_op(cso->alpha.func)); } assert(so->size <= ARRAY_SIZE(so->state)); return (void *)so; }
static void * nvc0_blend_state_create(struct pipe_context *pipe, const struct pipe_blend_state *cso) { struct nvc0_blend_stateobj *so = CALLOC_STRUCT(nvc0_blend_stateobj); int i; int r; /* reference */ uint32_t ms; uint8_t blend_en = 0; bool indep_masks = false; bool indep_funcs = false; so->pipe = *cso; /* check which states actually have differing values */ if (cso->independent_blend_enable) { for (r = 0; r < 8 && !cso->rt[r].blend_enable; ++r); blend_en |= 1 << r; for (i = r + 1; i < 8; ++i) { if (!cso->rt[i].blend_enable) continue; blend_en |= 1 << i; if (cso->rt[i].rgb_func != cso->rt[r].rgb_func || cso->rt[i].rgb_src_factor != cso->rt[r].rgb_src_factor || cso->rt[i].rgb_dst_factor != cso->rt[r].rgb_dst_factor || cso->rt[i].alpha_func != cso->rt[r].alpha_func || cso->rt[i].alpha_src_factor != cso->rt[r].alpha_src_factor || cso->rt[i].alpha_dst_factor != cso->rt[r].alpha_dst_factor) { indep_funcs = true; break; } } for (; i < 8; ++i) blend_en |= (cso->rt[i].blend_enable ? 1 : 0) << i; for (i = 1; i < 8; ++i) { if (cso->rt[i].colormask != cso->rt[0].colormask) { indep_masks = true; break; } } } else { r = 0; if (cso->rt[0].blend_enable) blend_en = 0xff; } if (cso->logicop_enable) { SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2); SB_DATA (so, 1); SB_DATA (so, nvgl_logicop_func(cso->logicop_func)); SB_IMMED_3D(so, MACRO_BLEND_ENABLES, 0); } else { SB_IMMED_3D(so, LOGIC_OP_ENABLE, 0); SB_IMMED_3D(so, BLEND_INDEPENDENT, indep_funcs); SB_IMMED_3D(so, MACRO_BLEND_ENABLES, blend_en); if (indep_funcs) { for (i = 0; i < 8; ++i) { if (cso->rt[i].blend_enable) { SB_BEGIN_3D(so, IBLEND_EQUATION_RGB(i), 6); SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func)); SB_DATA (so, nvc0_blend_fac(cso->rt[i].rgb_src_factor)); SB_DATA (so, nvc0_blend_fac(cso->rt[i].rgb_dst_factor)); SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func)); SB_DATA (so, nvc0_blend_fac(cso->rt[i].alpha_src_factor)); SB_DATA (so, nvc0_blend_fac(cso->rt[i].alpha_dst_factor)); } } } else if (blend_en) { SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5); SB_DATA (so, nvgl_blend_eqn(cso->rt[r].rgb_func)); SB_DATA (so, nvc0_blend_fac(cso->rt[r].rgb_src_factor)); SB_DATA (so, nvc0_blend_fac(cso->rt[r].rgb_dst_factor)); SB_DATA (so, nvgl_blend_eqn(cso->rt[r].alpha_func)); SB_DATA (so, nvc0_blend_fac(cso->rt[r].alpha_src_factor)); SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1); SB_DATA (so, nvc0_blend_fac(cso->rt[r].alpha_dst_factor)); } SB_IMMED_3D(so, COLOR_MASK_COMMON, !indep_masks); if (indep_masks) { SB_BEGIN_3D(so, COLOR_MASK(0), 8); for (i = 0; i < 8; ++i) SB_DATA(so, nvc0_colormask(cso->rt[i].colormask)); } else { SB_BEGIN_3D(so, COLOR_MASK(0), 1); SB_DATA (so, nvc0_colormask(cso->rt[0].colormask)); } } ms = 0; if (cso->alpha_to_coverage) ms |= NVC0_3D_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE; if (cso->alpha_to_one) ms |= NVC0_3D_MULTISAMPLE_CTRL_ALPHA_TO_ONE; SB_BEGIN_3D(so, MULTISAMPLE_CTRL, 1); SB_DATA (so, ms); assert(so->size <= ARRAY_SIZE(so->state)); return so; }
/* NOTE: ignoring line_last_pixel, using FALSE (set on screen init) */ 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); 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; 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); 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); 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) 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 * nv50_blend_state_create(struct pipe_context *pipe, const struct pipe_blend_state *cso) { struct nv50_blend_stateobj *so = CALLOC_STRUCT(nv50_blend_stateobj); int i; bool emit_common_func = cso->rt[0].blend_enable; if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) { SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1); SB_DATA (so, cso->independent_blend_enable); } so->pipe = *cso; SB_BEGIN_3D(so, COLOR_MASK_COMMON, 1); SB_DATA (so, !cso->independent_blend_enable); SB_BEGIN_3D(so, BLEND_ENABLE_COMMON, 1); SB_DATA (so, !cso->independent_blend_enable); if (cso->independent_blend_enable) { SB_BEGIN_3D(so, BLEND_ENABLE(0), 8); for (i = 0; i < 8; ++i) { SB_DATA(so, cso->rt[i].blend_enable); if (cso->rt[i].blend_enable) emit_common_func = true; } if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) { emit_common_func = false; for (i = 0; i < 8; ++i) { if (!cso->rt[i].blend_enable) continue; SB_BEGIN_3D_(so, NVA3_3D_IBLEND_EQUATION_RGB(i), 6); SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func)); SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_src_factor)); SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_dst_factor)); SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func)); SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_src_factor)); SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_dst_factor)); } } } else { SB_BEGIN_3D(so, BLEND_ENABLE(0), 1); SB_DATA (so, cso->rt[0].blend_enable); } if (emit_common_func) { SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5); SB_DATA (so, nvgl_blend_eqn(cso->rt[0].rgb_func)); SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_src_factor)); SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_dst_factor)); SB_DATA (so, nvgl_blend_eqn(cso->rt[0].alpha_func)); SB_DATA (so, nv50_blend_fac(cso->rt[0].alpha_src_factor)); SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1); SB_DATA (so, nv50_blend_fac(cso->rt[0].alpha_dst_factor)); } if (cso->logicop_enable) { SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2); SB_DATA (so, 1); SB_DATA (so, nvgl_logicop_func(cso->logicop_func)); } else { SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 1); SB_DATA (so, 0); } if (cso->independent_blend_enable) { SB_BEGIN_3D(so, COLOR_MASK(0), 8); for (i = 0; i < 8; ++i) SB_DATA(so, nv50_colormask(cso->rt[i].colormask)); } else { SB_BEGIN_3D(so, COLOR_MASK(0), 1); SB_DATA (so, nv50_colormask(cso->rt[0].colormask)); } assert(so->size <= ARRAY_SIZE(so->state)); return so; }
static void * nv50_blend_state_create(struct pipe_context *pipe, const struct pipe_blend_state *cso) { struct nv50_blend_stateobj *so = CALLOC_STRUCT(nv50_blend_stateobj); int i; boolean emit_common_func = cso->rt[0].blend_enable; uint32_t ms; if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) { SB_BEGIN_3D(so, BLEND_INDEPENDENT, 1); SB_DATA (so, cso->independent_blend_enable); } so->pipe = *cso; SB_BEGIN_3D(so, COLOR_MASK_COMMON, 1); SB_DATA (so, !cso->independent_blend_enable); SB_BEGIN_3D(so, BLEND_ENABLE_COMMON, 1); SB_DATA (so, !cso->independent_blend_enable); if (cso->independent_blend_enable) { SB_BEGIN_3D(so, BLEND_ENABLE(0), 8); for (i = 0; i < 8; ++i) { SB_DATA(so, cso->rt[i].blend_enable); if (cso->rt[i].blend_enable) emit_common_func = TRUE; } if (nv50_context(pipe)->screen->tesla->oclass >= NVA3_3D_CLASS) { emit_common_func = FALSE; for (i = 0; i < 8; ++i) { if (!cso->rt[i].blend_enable) continue; SB_BEGIN_3D_(so, NVA3_3D_IBLEND_EQUATION_RGB(i), 6); SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func)); SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_src_factor)); SB_DATA (so, nv50_blend_fac(cso->rt[i].rgb_dst_factor)); SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func)); SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_src_factor)); SB_DATA (so, nv50_blend_fac(cso->rt[i].alpha_dst_factor)); } } } else { SB_BEGIN_3D(so, BLEND_ENABLE(0), 1); SB_DATA (so, cso->rt[0].blend_enable); } if (emit_common_func) { SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5); SB_DATA (so, nvgl_blend_eqn(cso->rt[0].rgb_func)); SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_src_factor)); SB_DATA (so, nv50_blend_fac(cso->rt[0].rgb_dst_factor)); SB_DATA (so, nvgl_blend_eqn(cso->rt[0].alpha_func)); SB_DATA (so, nv50_blend_fac(cso->rt[0].alpha_src_factor)); SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1); SB_DATA (so, nv50_blend_fac(cso->rt[0].alpha_dst_factor)); } if (cso->logicop_enable) { SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2); SB_DATA (so, 1); SB_DATA (so, nvgl_logicop_func(cso->logicop_func)); } else { SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 1); SB_DATA (so, 0); } if (cso->independent_blend_enable) { SB_BEGIN_3D(so, COLOR_MASK(0), 8); for (i = 0; i < 8; ++i) SB_DATA(so, nv50_colormask(cso->rt[i].colormask)); } else { SB_BEGIN_3D(so, COLOR_MASK(0), 1); SB_DATA (so, nv50_colormask(cso->rt[0].colormask)); } ms = 0; if (cso->alpha_to_coverage) ms |= NV50_3D_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE; if (cso->alpha_to_one) ms |= NV50_3D_MULTISAMPLE_CTRL_ALPHA_TO_ONE; SB_BEGIN_3D(so, MULTISAMPLE_CTRL, 1); SB_DATA (so, ms); assert(so->size <= (sizeof(so->state) / sizeof(so->state[0]))); return so; }
static void * nv30_blend_state_create(struct pipe_context *pipe, const struct pipe_blend_state *cso) { struct nouveau_object *eng3d = nv30_context(pipe)->screen->eng3d; struct nv30_blend_stateobj *so; uint32_t blend[2], cmask[2]; int i; so = CALLOC_STRUCT(nv30_blend_stateobj); if (!so) return NULL; so->pipe = *cso; if (cso->logicop_enable) { SB_MTHD30(so, COLOR_LOGIC_OP_ENABLE, 2); SB_DATA (so, 1); SB_DATA (so, nvgl_logicop_func(cso->logicop_func)); } else { SB_MTHD30(so, COLOR_LOGIC_OP_ENABLE, 1); SB_DATA (so, 0); } SB_MTHD30(so, DITHER_ENABLE, 1); SB_DATA (so, cso->dither); blend[0] = cso->rt[0].blend_enable; cmask[0] = !!(cso->rt[0].colormask & PIPE_MASK_A) << 24 | !!(cso->rt[0].colormask & PIPE_MASK_R) << 16 | !!(cso->rt[0].colormask & PIPE_MASK_G) << 8 | !!(cso->rt[0].colormask & PIPE_MASK_B); if (cso->independent_blend_enable) { blend[1] = 0; cmask[1] = 0; for (i = 1; i < 4; i++) { blend[1] |= cso->rt[i].blend_enable << i; cmask[1] |= !!(cso->rt[i].colormask & PIPE_MASK_A) << (0 + (i * 4)) | !!(cso->rt[i].colormask & PIPE_MASK_R) << (1 + (i * 4)) | !!(cso->rt[i].colormask & PIPE_MASK_G) << (2 + (i * 4)) | !!(cso->rt[i].colormask & PIPE_MASK_B) << (3 + (i * 4)); } } else { blend[1] = 0x0000000e * (blend[0] & 0x00000001); cmask[1] = 0x00001110 * !!(cmask[0] & 0x01000000); cmask[1] |= 0x00002220 * !!(cmask[0] & 0x00010000); cmask[1] |= 0x00004440 * !!(cmask[0] & 0x00000100); cmask[1] |= 0x00008880 * !!(cmask[0] & 0x00000001); } if (eng3d->oclass >= NV40_3D_CLASS) { SB_MTHD40(so, MRT_BLEND_ENABLE, 2); SB_DATA (so, blend[1]); SB_DATA (so, cmask[1]); } if (blend[0] || blend[1]) { SB_MTHD30(so, BLEND_FUNC_ENABLE, 3); SB_DATA (so, blend[0]); SB_DATA (so, (nvgl_blend_func(cso->rt[0].alpha_src_factor) << 16) | nvgl_blend_func(cso->rt[0].rgb_src_factor)); SB_DATA (so, (nvgl_blend_func(cso->rt[0].alpha_dst_factor) << 16) | nvgl_blend_func(cso->rt[0].rgb_dst_factor)); if (eng3d->oclass < NV40_3D_CLASS) { SB_MTHD30(so, BLEND_EQUATION, 1); SB_DATA (so, nvgl_blend_eqn(cso->rt[0].rgb_func)); } else { SB_MTHD40(so, BLEND_EQUATION, 1); SB_DATA (so, (nvgl_blend_eqn(cso->rt[0].alpha_func) << 16) | nvgl_blend_eqn(cso->rt[0].rgb_func)); } } else { SB_MTHD30(so, BLEND_FUNC_ENABLE, 1); SB_DATA (so, blend[0]); } SB_MTHD30(so, COLOR_MASK, 1); SB_DATA (so, cmask[0]); return so; }
static void * nv30_zsa_state_create(struct pipe_context *pipe, const struct pipe_depth_stencil_alpha_state *cso) { struct nouveau_object *eng3d = nv30_context(pipe)->screen->eng3d; struct nv30_zsa_stateobj *so; so = CALLOC_STRUCT(nv30_zsa_stateobj); if (!so) return NULL; so->pipe = *cso; SB_MTHD30(so, DEPTH_FUNC, 3); SB_DATA (so, nvgl_comparison_op(cso->depth.func)); SB_DATA (so, cso->depth.writemask); SB_DATA (so, cso->depth.enabled); if (eng3d->oclass == NV35_3D_CLASS || eng3d->oclass >= NV40_3D_CLASS) { SB_MTHD35(so, DEPTH_BOUNDS_TEST_ENABLE, 3); SB_DATA (so, cso->depth.bounds_test); SB_DATA (so, fui(cso->depth.bounds_min)); SB_DATA (so, fui(cso->depth.bounds_max)); } if (cso->stencil[0].enabled) { SB_MTHD30(so, STENCIL_ENABLE(0), 3); SB_DATA (so, 1); SB_DATA (so, cso->stencil[0].writemask); SB_DATA (so, nvgl_comparison_op(cso->stencil[0].func)); SB_MTHD30(so, STENCIL_FUNC_MASK(0), 4); SB_DATA (so, cso->stencil[0].valuemask); SB_DATA (so, nvgl_stencil_op(cso->stencil[0].fail_op)); SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); SB_DATA (so, nvgl_stencil_op(cso->stencil[0].zpass_op)); } else { SB_MTHD30(so, STENCIL_ENABLE(0), 2); SB_DATA (so, 0); SB_DATA (so, 0x000000ff); } if (cso->stencil[1].enabled) { SB_MTHD30(so, STENCIL_ENABLE(1), 3); SB_DATA (so, 1); SB_DATA (so, cso->stencil[1].writemask); SB_DATA (so, nvgl_comparison_op(cso->stencil[1].func)); SB_MTHD30(so, STENCIL_FUNC_MASK(1), 4); SB_DATA (so, cso->stencil[1].valuemask); SB_DATA (so, nvgl_stencil_op(cso->stencil[1].fail_op)); SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); SB_DATA (so, nvgl_stencil_op(cso->stencil[1].zpass_op)); } else { SB_MTHD30(so, STENCIL_ENABLE(1), 1); SB_DATA (so, 0); } SB_MTHD30(so, ALPHA_FUNC_ENABLE, 3); SB_DATA (so, cso->alpha.enabled ? 1 : 0); SB_DATA (so, nvgl_comparison_op(cso->alpha.func)); SB_DATA (so, float_to_ubyte(cso->alpha.ref_value)); return so; }
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; }
static void * nvc0_blend_state_create(struct pipe_context *pipe, const struct pipe_blend_state *cso) { struct nvc0_blend_stateobj *so = CALLOC_STRUCT(nvc0_blend_stateobj); int i; uint32_t ms; so->pipe = *cso; SB_IMMED_3D(so, BLEND_INDEPENDENT, cso->independent_blend_enable); if (!cso->logicop_enable) SB_IMMED_3D(so, LOGIC_OP_ENABLE, 0); if (cso->logicop_enable) { SB_BEGIN_3D(so, LOGIC_OP_ENABLE, 2); SB_DATA (so, 1); SB_DATA (so, nvgl_logicop_func(cso->logicop_func)); SB_IMMED_3D(so, BLEND_ENABLES, 0); } else if (!cso->independent_blend_enable) { SB_IMMED_3D(so, BLEND_ENABLES, cso->rt[0].blend_enable ? 0xff : 0); if (cso->rt[0].blend_enable) { SB_BEGIN_3D(so, BLEND_EQUATION_RGB, 5); SB_DATA (so, nvgl_blend_eqn(cso->rt[0].rgb_func)); SB_DATA (so, nvc0_blend_fac(cso->rt[0].rgb_src_factor)); SB_DATA (so, nvc0_blend_fac(cso->rt[0].rgb_dst_factor)); SB_DATA (so, nvgl_blend_eqn(cso->rt[0].alpha_func)); SB_DATA (so, nvc0_blend_fac(cso->rt[0].alpha_src_factor)); SB_BEGIN_3D(so, BLEND_FUNC_DST_ALPHA, 1); SB_DATA (so, nvc0_blend_fac(cso->rt[0].alpha_dst_factor)); } SB_IMMED_3D(so, COLOR_MASK_COMMON, 1); SB_BEGIN_3D(so, COLOR_MASK(0), 1); SB_DATA (so, nvc0_colormask(cso->rt[0].colormask)); } else { uint8_t en = 0; for (i = 0; i < 8; ++i) { if (!cso->rt[i].blend_enable) continue; en |= 1 << i; SB_BEGIN_3D(so, IBLEND_EQUATION_RGB(i), 6); SB_DATA (so, nvgl_blend_eqn(cso->rt[i].rgb_func)); SB_DATA (so, nvc0_blend_fac(cso->rt[i].rgb_src_factor)); SB_DATA (so, nvc0_blend_fac(cso->rt[i].rgb_dst_factor)); SB_DATA (so, nvgl_blend_eqn(cso->rt[i].alpha_func)); SB_DATA (so, nvc0_blend_fac(cso->rt[i].alpha_src_factor)); SB_DATA (so, nvc0_blend_fac(cso->rt[i].alpha_dst_factor)); } SB_IMMED_3D(so, BLEND_ENABLES, en); SB_IMMED_3D(so, COLOR_MASK_COMMON, 0); SB_BEGIN_3D(so, COLOR_MASK(0), 8); for (i = 0; i < 8; ++i) SB_DATA(so, nvc0_colormask(cso->rt[i].colormask)); } ms = 0; if (cso->alpha_to_coverage) ms |= NVC0_3D_MULTISAMPLE_CTRL_ALPHA_TO_COVERAGE; if (cso->alpha_to_one) ms |= NVC0_3D_MULTISAMPLE_CTRL_ALPHA_TO_ONE; SB_BEGIN_3D(so, MULTISAMPLE_CTRL, 1); SB_DATA (so, ms); assert(so->size <= (sizeof(so->state) / sizeof(so->state[0]))); return so; }
/* NOTE: ignoring line_last_pixel, using FALSE (set on screen init) */ 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_BEGIN_3D(so, SHADE_MODEL, 1); SB_DATA (so, cso->flatshade ? NVC0_3D_SHADE_MODEL_FLAT : NVC0_3D_SHADE_MODEL_SMOOTH); 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) 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_EN, 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, POLYGON_MODE_FRONT, 1); SB_DATA (so, nvgl_polygon_mode(cso->fill_front)); SB_BEGIN_3D(so, 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)); } assert(so->size <= (sizeof(so->state) / sizeof(so->state[0]))); return (void *)so; }