1 #include "pipe/p_state.h"
2 #include "pipe/p_defines.h"
3 #include "pipe/p_util.h"
5 #include "nv50_context.h"
6 #include "nv50_state.h"
8 #include "nouveau/nouveau_stateobj.h"
11 nv50_blend_state_create(struct pipe_context
*pipe
,
12 const struct pipe_blend_state
*cso
)
14 struct nouveau_stateobj
*so
= so_new(64, 0);
15 struct nouveau_grobj
*tesla
= nv50_context(pipe
)->screen
->tesla
;
16 struct nv50_blend_stateobj
*bso
= CALLOC_STRUCT(nv50_blend_stateobj
);
17 unsigned cmask
= 0, i
;
23 if (cso
->blend_enable
== 0) {
24 so_method(so
, tesla
, NV50TCL_BLEND_ENABLE(0), 8);
25 for (i
= 0; i
< 8; i
++)
28 so_method(so
, tesla
, NV50TCL_BLEND_ENABLE(0), 8);
29 for (i
= 0; i
< 8; i
++)
31 so_method(so
, tesla
, NV50TCL_BLEND_EQUATION_RGB
, 5);
32 so_data (so
, nvgl_blend_eqn(cso
->rgb_func
));
33 so_data (so
, nvgl_blend_func(cso
->rgb_src_factor
));
34 so_data (so
, nvgl_blend_func(cso
->rgb_dst_factor
));
35 so_data (so
, nvgl_blend_eqn(cso
->alpha_func
));
36 so_data (so
, nvgl_blend_func(cso
->alpha_src_factor
));
37 so_method(so
, tesla
, NV50TCL_BLEND_FUNC_DST_ALPHA
, 1);
38 so_data (so
, nvgl_blend_func(cso
->alpha_dst_factor
));
41 if (cso
->logicop_enable
== 0 ) {
42 so_method(so
, tesla
, NV50TCL_LOGIC_OP_ENABLE
, 1);
45 so_method(so
, tesla
, NV50TCL_LOGIC_OP_ENABLE
, 2);
47 so_data (so
, nvgl_logicop_func(cso
->logicop_func
));
50 if (cso
->colormask
& PIPE_MASK_R
)
52 if (cso
->colormask
& PIPE_MASK_G
)
54 if (cso
->colormask
& PIPE_MASK_B
)
56 if (cso
->colormask
& PIPE_MASK_A
)
58 so_method(so
, tesla
, NV50TCL_COLOR_MASK(0), 8);
59 for (i
= 0; i
< 8; i
++)
68 nv50_blend_state_bind(struct pipe_context
*pipe
, void *hwcso
)
70 struct nv50_context
*nv50
= nv50_context(pipe
);
73 nv50
->dirty
|= NV50_NEW_BLEND
;
77 nv50_blend_state_delete(struct pipe_context
*pipe
, void *hwcso
)
79 struct nv50_blend_stateobj
*bso
= hwcso
;
81 so_ref(NULL
, &bso
->so
);
86 nv50_sampler_state_create(struct pipe_context
*pipe
,
87 const struct pipe_sampler_state
*cso
)
93 nv50_sampler_state_bind(struct pipe_context
*pipe
, unsigned nr
, void **sampler
)
98 nv50_sampler_state_delete(struct pipe_context
*pipe
, void *hwcso
)
103 nv50_set_sampler_texture(struct pipe_context
*pipe
, unsigned nr
,
104 struct pipe_texture
**pt
)
109 nv50_rasterizer_state_create(struct pipe_context
*pipe
,
110 const struct pipe_rasterizer_state
*cso
)
112 struct nouveau_stateobj
*so
= so_new(64, 0);
113 struct nouveau_grobj
*tesla
= nv50_context(pipe
)->screen
->tesla
;
114 struct nv50_rasterizer_stateobj
*rso
=
115 CALLOC_STRUCT(nv50_rasterizer_stateobj
);
122 * - point_sprite / sprite_coord_mode
125 so_method(so
, tesla
, NV50TCL_SHADE_MODEL
, 1);
126 so_data (so
, cso
->flatshade
? NV50TCL_SHADE_MODEL_FLAT
:
127 NV50TCL_SHADE_MODEL_SMOOTH
);
129 so_method(so
, tesla
, NV50TCL_LINE_WIDTH
, 1);
130 so_data (so
, fui(cso
->line_width
));
131 so_method(so
, tesla
, NV50TCL_LINE_SMOOTH_ENABLE
, 1);
132 so_data (so
, cso
->line_smooth
? 1 : 0);
133 if (cso
->line_stipple_enable
) {
134 so_method(so
, tesla
, NV50TCL_LINE_STIPPLE_ENABLE
, 1);
136 so_method(so
, tesla
, NV50TCL_LINE_STIPPLE_PATTERN
, 1);
137 so_data (so
, (cso
->line_stipple_pattern
<< 16) |
138 cso
->line_stipple_factor
);
140 so_method(so
, tesla
, NV50TCL_LINE_STIPPLE_ENABLE
, 1);
144 so_method(so
, tesla
, NV50TCL_POINT_SIZE
, 1);
145 so_data (so
, fui(cso
->point_size
));
147 so_method(so
, tesla
, NV50TCL_POLYGON_MODE_FRONT
, 3);
148 if (cso
->front_winding
== PIPE_WINDING_CCW
) {
149 so_data(so
, nvgl_polygon_mode(cso
->fill_ccw
));
150 so_data(so
, nvgl_polygon_mode(cso
->fill_cw
));
152 so_data(so
, nvgl_polygon_mode(cso
->fill_cw
));
153 so_data(so
, nvgl_polygon_mode(cso
->fill_ccw
));
155 so_data(so
, cso
->poly_smooth
? 1 : 0);
157 so_method(so
, tesla
, NV50TCL_CULL_FACE_ENABLE
, 3);
158 so_data (so
, cso
->cull_mode
!= PIPE_WINDING_NONE
);
159 if (cso
->front_winding
== PIPE_WINDING_CCW
) {
160 so_data(so
, NV50TCL_FRONT_FACE_CCW
);
161 switch (cso
->cull_mode
) {
162 case PIPE_WINDING_CCW
:
163 so_data(so
, NV50TCL_CULL_FACE_FRONT
);
165 case PIPE_WINDING_CW
:
166 so_data(so
, NV50TCL_CULL_FACE_BACK
);
168 case PIPE_WINDING_BOTH
:
169 so_data(so
, NV50TCL_CULL_FACE_FRONT_AND_BACK
);
172 so_data(so
, NV50TCL_CULL_FACE_BACK
);
176 so_data(so
, NV50TCL_FRONT_FACE_CW
);
177 switch (cso
->cull_mode
) {
178 case PIPE_WINDING_CCW
:
179 so_data(so
, NV50TCL_CULL_FACE_BACK
);
181 case PIPE_WINDING_CW
:
182 so_data(so
, NV50TCL_CULL_FACE_FRONT
);
184 case PIPE_WINDING_BOTH
:
185 so_data(so
, NV50TCL_CULL_FACE_FRONT_AND_BACK
);
188 so_data(so
, NV50TCL_CULL_FACE_BACK
);
193 so_method(so
, tesla
, NV50TCL_POLYGON_STIPPLE_ENABLE
, 1);
194 so_data (so
, cso
->poly_stipple_enable
? 1 : 0);
196 so_method(so
, tesla
, NV50TCL_POLYGON_OFFSET_POINT_ENABLE
, 3);
197 if ((cso
->offset_cw
&& cso
->fill_cw
== PIPE_POLYGON_MODE_POINT
) ||
198 (cso
->offset_ccw
&& cso
->fill_ccw
== PIPE_POLYGON_MODE_POINT
))
202 if ((cso
->offset_cw
&& cso
->fill_cw
== PIPE_POLYGON_MODE_LINE
) ||
203 (cso
->offset_ccw
&& cso
->fill_ccw
== PIPE_POLYGON_MODE_LINE
))
207 if ((cso
->offset_cw
&& cso
->fill_cw
== PIPE_POLYGON_MODE_FILL
) ||
208 (cso
->offset_ccw
&& cso
->fill_ccw
== PIPE_POLYGON_MODE_FILL
))
213 if (cso
->offset_cw
|| cso
->offset_ccw
) {
214 so_method(so
, tesla
, NV50TCL_POLYGON_OFFSET_FACTOR
, 1);
215 so_data (so
, fui(cso
->offset_scale
));
216 so_method(so
, tesla
, NV50TCL_POLYGON_OFFSET_UNITS
, 1);
217 so_data (so
, fui(cso
->offset_units
* 2));
221 so_ref(so
, &rso
->so
);
226 nv50_rasterizer_state_bind(struct pipe_context
*pipe
, void *hwcso
)
228 struct nv50_context
*nv50
= nv50_context(pipe
);
230 nv50
->rasterizer
= hwcso
;
231 nv50
->dirty
|= NV50_NEW_RASTERIZER
;
235 nv50_rasterizer_state_delete(struct pipe_context
*pipe
, void *hwcso
)
237 struct nv50_rasterizer_stateobj
*rso
= hwcso
;
239 so_ref(NULL
, &rso
->so
);
244 nv50_depth_stencil_alpha_state_create(struct pipe_context
*pipe
,
245 const struct pipe_depth_stencil_alpha_state
*cso
)
247 struct nouveau_grobj
*tesla
= nv50_context(pipe
)->screen
->tesla
;
248 struct nv50_zsa_stateobj
*zsa
= CALLOC_STRUCT(nv50_zsa_stateobj
);
249 struct nouveau_stateobj
*so
= so_new(64, 0);
251 so_method(so
, tesla
, NV50TCL_DEPTH_WRITE_ENABLE
, 1);
252 so_data (so
, cso
->depth
.writemask
? 1 : 0);
253 if (cso
->depth
.enabled
) {
254 so_method(so
, tesla
, NV50TCL_DEPTH_TEST_ENABLE
, 1);
256 so_method(so
, tesla
, NV50TCL_DEPTH_TEST_FUNC
, 1);
257 so_data (so
, nvgl_comparison_op(cso
->depth
.func
));
259 so_method(so
, tesla
, NV50TCL_DEPTH_TEST_ENABLE
, 1);
263 if (cso
->stencil
[0].enabled
) {
264 so_method(so
, tesla
, NV50TCL_STENCIL_FRONT_ENABLE
, 5);
266 so_data (so
, nvgl_stencil_op(cso
->stencil
[0].fail_op
));
267 so_data (so
, nvgl_stencil_op(cso
->stencil
[0].zfail_op
));
268 so_data (so
, nvgl_stencil_op(cso
->stencil
[0].zpass_op
));
269 so_data (so
, nvgl_comparison_op(cso
->stencil
[0].func
));
270 so_method(so
, tesla
, NV50TCL_STENCIL_FRONT_FUNC_REF
, 3);
271 so_data (so
, cso
->stencil
[0].ref_value
);
272 so_data (so
, cso
->stencil
[0].write_mask
);
273 so_data (so
, cso
->stencil
[0].value_mask
);
275 so_method(so
, tesla
, NV50TCL_STENCIL_FRONT_ENABLE
, 1);
279 if (cso
->stencil
[1].enabled
) {
280 so_method(so
, tesla
, NV50TCL_STENCIL_BACK_ENABLE
, 8);
282 so_data (so
, nvgl_stencil_op(cso
->stencil
[1].fail_op
));
283 so_data (so
, nvgl_stencil_op(cso
->stencil
[1].zfail_op
));
284 so_data (so
, nvgl_stencil_op(cso
->stencil
[1].zpass_op
));
285 so_data (so
, nvgl_comparison_op(cso
->stencil
[1].func
));
286 so_data (so
, cso
->stencil
[1].ref_value
);
287 so_data (so
, cso
->stencil
[1].write_mask
);
288 so_data (so
, cso
->stencil
[1].value_mask
);
290 so_method(so
, tesla
, NV50TCL_STENCIL_BACK_ENABLE
, 1);
294 if (cso
->alpha
.enabled
) {
295 so_method(so
, tesla
, NV50TCL_ALPHA_TEST_ENABLE
, 1);
297 so_method(so
, tesla
, NV50TCL_ALPHA_TEST_REF
, 2);
298 so_data (so
, fui(cso
->alpha
.ref
));
299 so_data (so
, nvgl_comparison_op(cso
->alpha
.func
));
301 so_method(so
, tesla
, NV50TCL_ALPHA_TEST_ENABLE
, 1);
306 so_ref(so
, &zsa
->so
);
311 nv50_depth_stencil_alpha_state_bind(struct pipe_context
*pipe
, void *hwcso
)
313 struct nv50_context
*nv50
= nv50_context(pipe
);
316 nv50
->dirty
|= NV50_NEW_ZSA
;
320 nv50_depth_stencil_alpha_state_delete(struct pipe_context
*pipe
, void *hwcso
)
322 struct nv50_zsa_stateobj
*zsa
= hwcso
;
324 so_ref(NULL
, &zsa
->so
);
329 nv50_vp_state_create(struct pipe_context
*pipe
,
330 const struct pipe_shader_state
*cso
)
336 nv50_vp_state_bind(struct pipe_context
*pipe
, void *hwcso
)
341 nv50_vp_state_delete(struct pipe_context
*pipe
, void *hwcso
)
346 nv50_fp_state_create(struct pipe_context
*pipe
,
347 const struct pipe_shader_state
*cso
)
353 nv50_fp_state_bind(struct pipe_context
*pipe
, void *hwcso
)
358 nv50_fp_state_delete(struct pipe_context
*pipe
, void *hwcso
)
363 nv50_set_blend_color(struct pipe_context
*pipe
,
364 const struct pipe_blend_color
*bcol
)
366 struct nv50_context
*nv50
= nv50_context(pipe
);
368 nv50
->blend_colour
= *bcol
;
369 nv50
->dirty
|= NV50_NEW_BLEND_COLOUR
;
373 nv50_set_clip_state(struct pipe_context
*pipe
,
374 const struct pipe_clip_state
*clip
)
379 nv50_set_constant_buffer(struct pipe_context
*pipe
, uint shader
, uint index
,
380 const struct pipe_constant_buffer
*buf
)
385 nv50_set_framebuffer_state(struct pipe_context
*pipe
,
386 const struct pipe_framebuffer_state
*fb
)
388 struct nv50_context
*nv50
= nv50_context(pipe
);
390 nv50
->framebuffer
= *fb
;
391 nv50
->dirty
|= NV50_NEW_FRAMEBUFFER
;
395 nv50_set_polygon_stipple(struct pipe_context
*pipe
,
396 const struct pipe_poly_stipple
*stipple
)
398 struct nv50_context
*nv50
= nv50_context(pipe
);
400 nv50
->stipple
= *stipple
;
401 nv50
->dirty
|= NV50_NEW_STIPPLE
;
405 nv50_set_scissor_state(struct pipe_context
*pipe
,
406 const struct pipe_scissor_state
*s
)
408 struct nv50_context
*nv50
= nv50_context(pipe
);
411 nv50
->dirty
|= NV50_NEW_SCISSOR
;
415 nv50_set_viewport_state(struct pipe_context
*pipe
,
416 const struct pipe_viewport_state
*vpt
)
418 struct nv50_context
*nv50
= nv50_context(pipe
);
420 nv50
->viewport
= *vpt
;
421 nv50
->dirty
|= NV50_NEW_VIEWPORT
;
425 nv50_set_vertex_buffer(struct pipe_context
*pipe
, unsigned index
,
426 const struct pipe_vertex_buffer
*vb
)
431 nv50_set_vertex_element(struct pipe_context
*pipe
, unsigned index
,
432 const struct pipe_vertex_element
*ve
)
437 nv50_init_state_functions(struct nv50_context
*nv50
)
439 nv50
->pipe
.create_blend_state
= nv50_blend_state_create
;
440 nv50
->pipe
.bind_blend_state
= nv50_blend_state_bind
;
441 nv50
->pipe
.delete_blend_state
= nv50_blend_state_delete
;
443 nv50
->pipe
.create_sampler_state
= nv50_sampler_state_create
;
444 nv50
->pipe
.bind_sampler_states
= nv50_sampler_state_bind
;
445 nv50
->pipe
.delete_sampler_state
= nv50_sampler_state_delete
;
446 nv50
->pipe
.set_sampler_textures
= nv50_set_sampler_texture
;
448 nv50
->pipe
.create_rasterizer_state
= nv50_rasterizer_state_create
;
449 nv50
->pipe
.bind_rasterizer_state
= nv50_rasterizer_state_bind
;
450 nv50
->pipe
.delete_rasterizer_state
= nv50_rasterizer_state_delete
;
452 nv50
->pipe
.create_depth_stencil_alpha_state
=
453 nv50_depth_stencil_alpha_state_create
;
454 nv50
->pipe
.bind_depth_stencil_alpha_state
=
455 nv50_depth_stencil_alpha_state_bind
;
456 nv50
->pipe
.delete_depth_stencil_alpha_state
=
457 nv50_depth_stencil_alpha_state_delete
;
459 nv50
->pipe
.create_vs_state
= nv50_vp_state_create
;
460 nv50
->pipe
.bind_vs_state
= nv50_vp_state_bind
;
461 nv50
->pipe
.delete_vs_state
= nv50_vp_state_delete
;
463 nv50
->pipe
.create_fs_state
= nv50_fp_state_create
;
464 nv50
->pipe
.bind_fs_state
= nv50_fp_state_bind
;
465 nv50
->pipe
.delete_fs_state
= nv50_fp_state_delete
;
467 nv50
->pipe
.set_blend_color
= nv50_set_blend_color
;
468 nv50
->pipe
.set_clip_state
= nv50_set_clip_state
;
469 nv50
->pipe
.set_constant_buffer
= nv50_set_constant_buffer
;
470 nv50
->pipe
.set_framebuffer_state
= nv50_set_framebuffer_state
;
471 nv50
->pipe
.set_polygon_stipple
= nv50_set_polygon_stipple
;
472 nv50
->pipe
.set_scissor_state
= nv50_set_scissor_state
;
473 nv50
->pipe
.set_viewport_state
= nv50_set_viewport_state
;
475 nv50
->pipe
.set_vertex_buffer
= nv50_set_vertex_buffer
;
476 nv50
->pipe
.set_vertex_element
= nv50_set_vertex_element
;