1 #include "pipe/p_state.h"
2 #include "pipe/p_defines.h"
3 #include "pipe/p_util.h"
5 #include "nv50_context.h"
7 #include "nouveau/nouveau_stateobj.h"
10 nv50_blend_state_create(struct pipe_context
*pipe
,
11 const struct pipe_blend_state
*cso
)
13 struct nouveau_stateobj
*so
= so_new(64, 0);
14 struct nouveau_grobj
*tesla
= nv50_context(pipe
)->screen
->tesla
;
15 struct nv50_blend_stateobj
*bso
= CALLOC_STRUCT(nv50_blend_stateobj
);
16 unsigned cmask
= 0, i
;
22 if (cso
->blend_enable
== 0) {
23 so_method(so
, tesla
, NV50TCL_BLEND_ENABLE(0), 8);
24 for (i
= 0; i
< 8; i
++)
27 so_method(so
, tesla
, NV50TCL_BLEND_ENABLE(0), 8);
28 for (i
= 0; i
< 8; i
++)
30 so_method(so
, tesla
, NV50TCL_BLEND_EQUATION_RGB
, 5);
31 so_data (so
, nvgl_blend_eqn(cso
->rgb_func
));
32 so_data (so
, 0x4000 | nvgl_blend_func(cso
->rgb_src_factor
));
33 so_data (so
, 0x4000 | nvgl_blend_func(cso
->rgb_dst_factor
));
34 so_data (so
, nvgl_blend_eqn(cso
->alpha_func
));
35 so_data (so
, 0x4000 | nvgl_blend_func(cso
->alpha_src_factor
));
36 so_method(so
, tesla
, NV50TCL_BLEND_FUNC_DST_ALPHA
, 1);
37 so_data (so
, 0x4000 | nvgl_blend_func(cso
->alpha_dst_factor
));
40 if (cso
->logicop_enable
== 0 ) {
41 so_method(so
, tesla
, NV50TCL_LOGIC_OP_ENABLE
, 1);
44 so_method(so
, tesla
, NV50TCL_LOGIC_OP_ENABLE
, 2);
46 so_data (so
, nvgl_logicop_func(cso
->logicop_func
));
49 if (cso
->colormask
& PIPE_MASK_R
)
51 if (cso
->colormask
& PIPE_MASK_G
)
53 if (cso
->colormask
& PIPE_MASK_B
)
55 if (cso
->colormask
& PIPE_MASK_A
)
57 so_method(so
, tesla
, NV50TCL_COLOR_MASK(0), 8);
58 for (i
= 0; i
< 8; i
++)
67 nv50_blend_state_bind(struct pipe_context
*pipe
, void *hwcso
)
69 struct nv50_context
*nv50
= nv50_context(pipe
);
72 nv50
->dirty
|= NV50_NEW_BLEND
;
76 nv50_blend_state_delete(struct pipe_context
*pipe
, void *hwcso
)
78 struct nv50_blend_stateobj
*bso
= hwcso
;
80 so_ref(NULL
, &bso
->so
);
85 nv50_sampler_state_create(struct pipe_context
*pipe
,
86 const struct pipe_sampler_state
*cso
)
92 nv50_sampler_state_bind(struct pipe_context
*pipe
, unsigned nr
, void **sampler
)
97 nv50_sampler_state_delete(struct pipe_context
*pipe
, void *hwcso
)
102 nv50_set_sampler_texture(struct pipe_context
*pipe
, unsigned nr
,
103 struct pipe_texture
**pt
)
108 nv50_rasterizer_state_create(struct pipe_context
*pipe
,
109 const struct pipe_rasterizer_state
*cso
)
111 struct nouveau_stateobj
*so
= so_new(64, 0);
112 struct nouveau_grobj
*tesla
= nv50_context(pipe
)->screen
->tesla
;
113 struct nv50_rasterizer_stateobj
*rso
=
114 CALLOC_STRUCT(nv50_rasterizer_stateobj
);
120 * - point_sprite / sprite_coord_mode
123 so_method(so
, tesla
, NV50TCL_SHADE_MODEL
, 1);
124 so_data (so
, cso
->flatshade
? NV50TCL_SHADE_MODEL_FLAT
:
125 NV50TCL_SHADE_MODEL_SMOOTH
);
127 so_method(so
, tesla
, NV50TCL_LINE_WIDTH
, 1);
128 so_data (so
, fui(cso
->line_width
));
129 so_method(so
, tesla
, NV50TCL_LINE_SMOOTH_ENABLE
, 1);
130 so_data (so
, cso
->line_smooth
? 1 : 0);
131 if (cso
->line_stipple_enable
) {
132 so_method(so
, tesla
, NV50TCL_LINE_STIPPLE_ENABLE
, 1);
134 so_method(so
, tesla
, NV50TCL_LINE_STIPPLE_PATTERN
, 1);
135 so_data (so
, (cso
->line_stipple_pattern
<< 16) |
136 cso
->line_stipple_factor
);
138 so_method(so
, tesla
, NV50TCL_LINE_STIPPLE_ENABLE
, 1);
142 so_method(so
, tesla
, NV50TCL_POINT_SIZE
, 1);
143 so_data (so
, fui(cso
->point_size
));
145 so_method(so
, tesla
, NV50TCL_POLYGON_MODE_FRONT
, 3);
146 if (cso
->front_winding
== PIPE_WINDING_CCW
) {
147 so_data(so
, nvgl_polygon_mode(cso
->fill_ccw
));
148 so_data(so
, nvgl_polygon_mode(cso
->fill_cw
));
150 so_data(so
, nvgl_polygon_mode(cso
->fill_cw
));
151 so_data(so
, nvgl_polygon_mode(cso
->fill_ccw
));
153 so_data(so
, cso
->poly_smooth
? 1 : 0);
155 so_method(so
, tesla
, NV50TCL_CULL_FACE_ENABLE
, 3);
156 so_data (so
, cso
->cull_mode
!= PIPE_WINDING_NONE
);
157 if (cso
->front_winding
== PIPE_WINDING_CCW
) {
158 so_data(so
, NV50TCL_FRONT_FACE_CCW
);
159 switch (cso
->cull_mode
) {
160 case PIPE_WINDING_CCW
:
161 so_data(so
, NV50TCL_CULL_FACE_FRONT
);
163 case PIPE_WINDING_CW
:
164 so_data(so
, NV50TCL_CULL_FACE_BACK
);
166 case PIPE_WINDING_BOTH
:
167 so_data(so
, NV50TCL_CULL_FACE_FRONT_AND_BACK
);
170 so_data(so
, NV50TCL_CULL_FACE_BACK
);
174 so_data(so
, NV50TCL_FRONT_FACE_CW
);
175 switch (cso
->cull_mode
) {
176 case PIPE_WINDING_CCW
:
177 so_data(so
, NV50TCL_CULL_FACE_BACK
);
179 case PIPE_WINDING_CW
:
180 so_data(so
, NV50TCL_CULL_FACE_FRONT
);
182 case PIPE_WINDING_BOTH
:
183 so_data(so
, NV50TCL_CULL_FACE_FRONT_AND_BACK
);
186 so_data(so
, NV50TCL_CULL_FACE_BACK
);
191 so_method(so
, tesla
, NV50TCL_POLYGON_STIPPLE_ENABLE
, 1);
192 so_data (so
, cso
->poly_stipple_enable
? 1 : 0);
194 so_method(so
, tesla
, NV50TCL_POLYGON_OFFSET_POINT_ENABLE
, 3);
195 if ((cso
->offset_cw
&& cso
->fill_cw
== PIPE_POLYGON_MODE_POINT
) ||
196 (cso
->offset_ccw
&& cso
->fill_ccw
== PIPE_POLYGON_MODE_POINT
))
200 if ((cso
->offset_cw
&& cso
->fill_cw
== PIPE_POLYGON_MODE_LINE
) ||
201 (cso
->offset_ccw
&& cso
->fill_ccw
== PIPE_POLYGON_MODE_LINE
))
205 if ((cso
->offset_cw
&& cso
->fill_cw
== PIPE_POLYGON_MODE_FILL
) ||
206 (cso
->offset_ccw
&& cso
->fill_ccw
== PIPE_POLYGON_MODE_FILL
))
211 if (cso
->offset_cw
|| cso
->offset_ccw
) {
212 so_method(so
, tesla
, NV50TCL_POLYGON_OFFSET_FACTOR
, 1);
213 so_data (so
, fui(cso
->offset_scale
));
214 so_method(so
, tesla
, NV50TCL_POLYGON_OFFSET_UNITS
, 1);
215 so_data (so
, fui(cso
->offset_units
* 2));
219 so_ref(so
, &rso
->so
);
224 nv50_rasterizer_state_bind(struct pipe_context
*pipe
, void *hwcso
)
226 struct nv50_context
*nv50
= nv50_context(pipe
);
228 nv50
->rasterizer
= hwcso
;
229 nv50
->dirty
|= NV50_NEW_RASTERIZER
;
233 nv50_rasterizer_state_delete(struct pipe_context
*pipe
, void *hwcso
)
235 struct nv50_rasterizer_stateobj
*rso
= hwcso
;
237 so_ref(NULL
, &rso
->so
);
242 nv50_depth_stencil_alpha_state_create(struct pipe_context
*pipe
,
243 const struct pipe_depth_stencil_alpha_state
*cso
)
245 struct nouveau_grobj
*tesla
= nv50_context(pipe
)->screen
->tesla
;
246 struct nv50_zsa_stateobj
*zsa
= CALLOC_STRUCT(nv50_zsa_stateobj
);
247 struct nouveau_stateobj
*so
= so_new(64, 0);
249 so_method(so
, tesla
, NV50TCL_DEPTH_WRITE_ENABLE
, 1);
250 so_data (so
, cso
->depth
.writemask
? 1 : 0);
251 if (cso
->depth
.enabled
) {
252 so_method(so
, tesla
, NV50TCL_DEPTH_TEST_ENABLE
, 1);
254 so_method(so
, tesla
, NV50TCL_DEPTH_TEST_FUNC
, 1);
255 so_data (so
, nvgl_comparison_op(cso
->depth
.func
));
257 so_method(so
, tesla
, NV50TCL_DEPTH_TEST_ENABLE
, 1);
261 if (cso
->stencil
[0].enabled
) {
262 so_method(so
, tesla
, NV50TCL_STENCIL_FRONT_ENABLE
, 5);
264 so_data (so
, nvgl_stencil_op(cso
->stencil
[0].fail_op
));
265 so_data (so
, nvgl_stencil_op(cso
->stencil
[0].zfail_op
));
266 so_data (so
, nvgl_stencil_op(cso
->stencil
[0].zpass_op
));
267 so_data (so
, nvgl_comparison_op(cso
->stencil
[0].func
));
268 so_method(so
, tesla
, NV50TCL_STENCIL_FRONT_FUNC_REF
, 3);
269 so_data (so
, cso
->stencil
[0].ref_value
);
270 so_data (so
, cso
->stencil
[0].write_mask
);
271 so_data (so
, cso
->stencil
[0].value_mask
);
273 so_method(so
, tesla
, NV50TCL_STENCIL_FRONT_ENABLE
, 1);
277 if (cso
->stencil
[1].enabled
) {
278 so_method(so
, tesla
, NV50TCL_STENCIL_BACK_ENABLE
, 8);
280 so_data (so
, nvgl_stencil_op(cso
->stencil
[1].fail_op
));
281 so_data (so
, nvgl_stencil_op(cso
->stencil
[1].zfail_op
));
282 so_data (so
, nvgl_stencil_op(cso
->stencil
[1].zpass_op
));
283 so_data (so
, nvgl_comparison_op(cso
->stencil
[1].func
));
284 so_data (so
, cso
->stencil
[1].ref_value
);
285 so_data (so
, cso
->stencil
[1].write_mask
);
286 so_data (so
, cso
->stencil
[1].value_mask
);
288 so_method(so
, tesla
, NV50TCL_STENCIL_BACK_ENABLE
, 1);
292 if (cso
->alpha
.enabled
) {
293 so_method(so
, tesla
, NV50TCL_ALPHA_TEST_ENABLE
, 1);
295 so_method(so
, tesla
, NV50TCL_ALPHA_TEST_REF
, 2);
296 so_data (so
, fui(cso
->alpha
.ref
));
297 so_data (so
, nvgl_comparison_op(cso
->alpha
.func
));
299 so_method(so
, tesla
, NV50TCL_ALPHA_TEST_ENABLE
, 1);
304 so_ref(so
, &zsa
->so
);
309 nv50_depth_stencil_alpha_state_bind(struct pipe_context
*pipe
, void *hwcso
)
311 struct nv50_context
*nv50
= nv50_context(pipe
);
314 nv50
->dirty
|= NV50_NEW_ZSA
;
318 nv50_depth_stencil_alpha_state_delete(struct pipe_context
*pipe
, void *hwcso
)
320 struct nv50_zsa_stateobj
*zsa
= hwcso
;
322 so_ref(NULL
, &zsa
->so
);
327 nv50_vp_state_create(struct pipe_context
*pipe
,
328 const struct pipe_shader_state
*cso
)
330 struct nv50_program
*p
= CALLOC_STRUCT(nv50_program
);
333 p
->type
= PIPE_SHADER_VERTEX
;
334 tgsi_scan_shader(p
->pipe
.tokens
, &p
->info
);
339 nv50_vp_state_bind(struct pipe_context
*pipe
, void *hwcso
)
341 struct nv50_context
*nv50
= nv50_context(pipe
);
343 nv50
->vertprog
= hwcso
;
344 nv50
->dirty
|= NV50_NEW_VERTPROG
;
348 nv50_vp_state_delete(struct pipe_context
*pipe
, void *hwcso
)
350 struct nv50_context
*nv50
= nv50_context(pipe
);
352 nv50_program_destroy(nv50
, hwcso
);
357 nv50_fp_state_create(struct pipe_context
*pipe
,
358 const struct pipe_shader_state
*cso
)
360 struct nv50_program
*p
= CALLOC_STRUCT(nv50_program
);
363 p
->type
= PIPE_SHADER_FRAGMENT
;
364 tgsi_scan_shader(p
->pipe
.tokens
, &p
->info
);
369 nv50_fp_state_bind(struct pipe_context
*pipe
, void *hwcso
)
371 struct nv50_context
*nv50
= nv50_context(pipe
);
373 nv50
->fragprog
= hwcso
;
374 nv50
->dirty
|= NV50_NEW_FRAGPROG
;
378 nv50_fp_state_delete(struct pipe_context
*pipe
, void *hwcso
)
380 struct nv50_context
*nv50
= nv50_context(pipe
);
382 nv50_program_destroy(nv50
, hwcso
);
387 nv50_set_blend_color(struct pipe_context
*pipe
,
388 const struct pipe_blend_color
*bcol
)
390 struct nv50_context
*nv50
= nv50_context(pipe
);
392 nv50
->blend_colour
= *bcol
;
393 nv50
->dirty
|= NV50_NEW_BLEND_COLOUR
;
397 nv50_set_clip_state(struct pipe_context
*pipe
,
398 const struct pipe_clip_state
*clip
)
403 nv50_set_constant_buffer(struct pipe_context
*pipe
, uint shader
, uint index
,
404 const struct pipe_constant_buffer
*buf
)
406 struct nv50_context
*nv50
= nv50_context(pipe
);
408 if (shader
== PIPE_SHADER_VERTEX
) {
409 nv50
->constbuf
[PIPE_SHADER_VERTEX
] = buf
->buffer
;
410 nv50
->dirty
|= NV50_NEW_VERTPROG_CB
;
412 if (shader
== PIPE_SHADER_FRAGMENT
) {
413 nv50
->constbuf
[PIPE_SHADER_FRAGMENT
] = buf
->buffer
;
414 nv50
->dirty
|= NV50_NEW_FRAGPROG_CB
;
419 nv50_set_framebuffer_state(struct pipe_context
*pipe
,
420 const struct pipe_framebuffer_state
*fb
)
422 struct nv50_context
*nv50
= nv50_context(pipe
);
424 nv50
->framebuffer
= *fb
;
425 nv50
->dirty
|= NV50_NEW_FRAMEBUFFER
;
429 nv50_set_polygon_stipple(struct pipe_context
*pipe
,
430 const struct pipe_poly_stipple
*stipple
)
432 struct nv50_context
*nv50
= nv50_context(pipe
);
434 nv50
->stipple
= *stipple
;
435 nv50
->dirty
|= NV50_NEW_STIPPLE
;
439 nv50_set_scissor_state(struct pipe_context
*pipe
,
440 const struct pipe_scissor_state
*s
)
442 struct nv50_context
*nv50
= nv50_context(pipe
);
445 nv50
->dirty
|= NV50_NEW_SCISSOR
;
449 nv50_set_viewport_state(struct pipe_context
*pipe
,
450 const struct pipe_viewport_state
*vpt
)
452 struct nv50_context
*nv50
= nv50_context(pipe
);
454 nv50
->viewport
= *vpt
;
455 nv50
->dirty
|= NV50_NEW_VIEWPORT
;
459 nv50_set_vertex_buffers(struct pipe_context
*pipe
, unsigned count
,
460 const struct pipe_vertex_buffer
*vb
)
462 struct nv50_context
*nv50
= nv50_context(pipe
);
464 memcpy(nv50
->vtxbuf
, vb
, sizeof(*vb
) * count
);
465 nv50
->vtxbuf_nr
= count
;
467 nv50
->dirty
|= NV50_NEW_ARRAYS
;
471 nv50_set_vertex_elements(struct pipe_context
*pipe
, unsigned count
,
472 const struct pipe_vertex_element
*ve
)
474 struct nv50_context
*nv50
= nv50_context(pipe
);
476 memcpy(nv50
->vtxelt
, ve
, sizeof(*ve
) * count
);
477 nv50
->vtxelt_nr
= count
;
479 nv50
->dirty
|= NV50_NEW_ARRAYS
;
483 nv50_init_state_functions(struct nv50_context
*nv50
)
485 nv50
->pipe
.create_blend_state
= nv50_blend_state_create
;
486 nv50
->pipe
.bind_blend_state
= nv50_blend_state_bind
;
487 nv50
->pipe
.delete_blend_state
= nv50_blend_state_delete
;
489 nv50
->pipe
.create_sampler_state
= nv50_sampler_state_create
;
490 nv50
->pipe
.bind_sampler_states
= nv50_sampler_state_bind
;
491 nv50
->pipe
.delete_sampler_state
= nv50_sampler_state_delete
;
492 nv50
->pipe
.set_sampler_textures
= nv50_set_sampler_texture
;
494 nv50
->pipe
.create_rasterizer_state
= nv50_rasterizer_state_create
;
495 nv50
->pipe
.bind_rasterizer_state
= nv50_rasterizer_state_bind
;
496 nv50
->pipe
.delete_rasterizer_state
= nv50_rasterizer_state_delete
;
498 nv50
->pipe
.create_depth_stencil_alpha_state
=
499 nv50_depth_stencil_alpha_state_create
;
500 nv50
->pipe
.bind_depth_stencil_alpha_state
=
501 nv50_depth_stencil_alpha_state_bind
;
502 nv50
->pipe
.delete_depth_stencil_alpha_state
=
503 nv50_depth_stencil_alpha_state_delete
;
505 nv50
->pipe
.create_vs_state
= nv50_vp_state_create
;
506 nv50
->pipe
.bind_vs_state
= nv50_vp_state_bind
;
507 nv50
->pipe
.delete_vs_state
= nv50_vp_state_delete
;
509 nv50
->pipe
.create_fs_state
= nv50_fp_state_create
;
510 nv50
->pipe
.bind_fs_state
= nv50_fp_state_bind
;
511 nv50
->pipe
.delete_fs_state
= nv50_fp_state_delete
;
513 nv50
->pipe
.set_blend_color
= nv50_set_blend_color
;
514 nv50
->pipe
.set_clip_state
= nv50_set_clip_state
;
515 nv50
->pipe
.set_constant_buffer
= nv50_set_constant_buffer
;
516 nv50
->pipe
.set_framebuffer_state
= nv50_set_framebuffer_state
;
517 nv50
->pipe
.set_polygon_stipple
= nv50_set_polygon_stipple
;
518 nv50
->pipe
.set_scissor_state
= nv50_set_scissor_state
;
519 nv50
->pipe
.set_viewport_state
= nv50_set_viewport_state
;
521 nv50
->pipe
.set_vertex_buffers
= nv50_set_vertex_buffers
;
522 nv50
->pipe
.set_vertex_elements
= nv50_set_vertex_elements
;