1 #include "pipe/p_state.h"
2 #include "pipe/p_defines.h"
3 #include "util/u_inlines.h"
4 #include "util/u_framebuffer.h"
6 #include "draw/draw_context.h"
8 #include "tgsi/tgsi_parse.h"
10 #include "nvfx_context.h"
11 #include "nvfx_state.h"
15 nvfx_blend_state_create(struct pipe_context
*pipe
,
16 const struct pipe_blend_state
*cso
)
18 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
19 struct nvfx_blend_state
*bso
= CALLOC(1, sizeof(*bso
));
20 struct nouveau_statebuf_builder sb
= sb_init(bso
->sb
);
22 if (cso
->rt
[0].blend_enable
) {
23 sb_method(sb
, NV34TCL_BLEND_FUNC_ENABLE
, 3);
25 sb_data(sb
, (nvgl_blend_func(cso
->rt
[0].alpha_src_factor
) << 16) |
26 nvgl_blend_func(cso
->rt
[0].rgb_src_factor
));
27 sb_data(sb
, nvgl_blend_func(cso
->rt
[0].alpha_dst_factor
) << 16 |
28 nvgl_blend_func(cso
->rt
[0].rgb_dst_factor
));
29 if(nvfx
->screen
->base
.device
->chipset
< 0x40) {
30 sb_method(sb
, NV34TCL_BLEND_EQUATION
, 1);
31 sb_data(sb
, nvgl_blend_eqn(cso
->rt
[0].rgb_func
));
33 sb_method(sb
, NV40TCL_BLEND_EQUATION
, 1);
34 sb_data(sb
, nvgl_blend_eqn(cso
->rt
[0].alpha_func
) << 16 |
35 nvgl_blend_eqn(cso
->rt
[0].rgb_func
));
38 sb_method(sb
, NV34TCL_BLEND_FUNC_ENABLE
, 1);
42 sb_method(sb
, NV34TCL_COLOR_MASK
, 1);
43 sb_data(sb
, (((cso
->rt
[0].colormask
& PIPE_MASK_A
) ? (0x01 << 24) : 0) |
44 ((cso
->rt
[0].colormask
& PIPE_MASK_R
) ? (0x01 << 16) : 0) |
45 ((cso
->rt
[0].colormask
& PIPE_MASK_G
) ? (0x01 << 8) : 0) |
46 ((cso
->rt
[0].colormask
& PIPE_MASK_B
) ? (0x01 << 0) : 0)));
48 /* TODO: add NV40 MRT color mask */
50 if (cso
->logicop_enable
) {
51 sb_method(sb
, NV34TCL_COLOR_LOGIC_OP_ENABLE
, 2);
53 sb_data(sb
, nvgl_logicop_func(cso
->logicop_func
));
55 sb_method(sb
, NV34TCL_COLOR_LOGIC_OP_ENABLE
, 1);
59 sb_method(sb
, NV34TCL_DITHER_ENABLE
, 1);
60 sb_data(sb
, cso
->dither
? 1 : 0);
62 bso
->sb_len
= sb_len(sb
, bso
->sb
);
68 nvfx_blend_state_bind(struct pipe_context
*pipe
, void *hwcso
)
70 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
73 nvfx
->dirty
|= NVFX_NEW_BLEND
;
77 nvfx_blend_state_delete(struct pipe_context
*pipe
, void *hwcso
)
79 struct nvfx_blend_state
*bso
= hwcso
;
85 nvfx_rasterizer_state_create(struct pipe_context
*pipe
,
86 const struct pipe_rasterizer_state
*cso
)
88 struct nvfx_rasterizer_state
*rsso
= CALLOC(1, sizeof(*rsso
));
89 struct nouveau_statebuf_builder sb
= sb_init(rsso
->sb
);
96 sb_method(sb
, NV34TCL_SHADE_MODEL
, 1);
97 sb_data(sb
, cso
->flatshade
? NV34TCL_SHADE_MODEL_FLAT
:
98 NV34TCL_SHADE_MODEL_SMOOTH
);
100 sb_method(sb
, NV34TCL_VERTEX_TWO_SIDE_ENABLE
, 1);
101 sb_data(sb
, cso
->light_twoside
);
103 sb_method(sb
, NV34TCL_LINE_WIDTH
, 2);
104 sb_data(sb
, (unsigned char)(cso
->line_width
* 8.0) & 0xff);
105 sb_data(sb
, cso
->line_smooth
? 1 : 0);
106 sb_method(sb
, NV34TCL_LINE_STIPPLE_ENABLE
, 2);
107 sb_data(sb
, cso
->line_stipple_enable
? 1 : 0);
108 sb_data(sb
, (cso
->line_stipple_pattern
<< 16) |
109 cso
->line_stipple_factor
);
111 sb_method(sb
, NV34TCL_POINT_SIZE
, 1);
112 sb_data(sb
, fui(cso
->point_size
));
114 sb_method(sb
, NV34TCL_POLYGON_MODE_FRONT
, 6);
115 sb_data(sb
, nvgl_polygon_mode(cso
->fill_front
));
116 sb_data(sb
, nvgl_polygon_mode(cso
->fill_back
));
117 switch (cso
->cull_face
) {
118 case PIPE_FACE_FRONT
:
119 sb_data(sb
, NV34TCL_CULL_FACE_FRONT
);
122 sb_data(sb
, NV34TCL_CULL_FACE_BACK
);
124 case PIPE_FACE_FRONT_AND_BACK
:
125 sb_data(sb
, NV34TCL_CULL_FACE_FRONT_AND_BACK
);
128 sb_data(sb
, NV34TCL_CULL_FACE_BACK
);
131 if (cso
->front_ccw
) {
132 sb_data(sb
, NV34TCL_FRONT_FACE_CCW
);
134 sb_data(sb
, NV34TCL_FRONT_FACE_CW
);
136 sb_data(sb
, cso
->poly_smooth
? 1 : 0);
137 sb_data(sb
, (cso
->cull_face
!= PIPE_FACE_NONE
) ? 1 : 0);
139 sb_method(sb
, NV34TCL_POLYGON_STIPPLE_ENABLE
, 1);
140 sb_data(sb
, cso
->poly_stipple_enable
? 1 : 0);
142 sb_method(sb
, NV34TCL_POLYGON_OFFSET_POINT_ENABLE
, 3);
143 sb_data(sb
, cso
->offset_point
);
144 sb_data(sb
, cso
->offset_line
);
145 sb_data(sb
, cso
->offset_tri
);
147 if (cso
->offset_point
|| cso
->offset_line
|| cso
->offset_tri
) {
148 sb_method(sb
, NV34TCL_POLYGON_OFFSET_FACTOR
, 2);
149 sb_data(sb
, fui(cso
->offset_scale
));
150 sb_data(sb
, fui(cso
->offset_units
* 2));
153 sb_method(sb
, NV34TCL_POINT_SPRITE
, 1);
154 if (cso
->point_quad_rasterization
) {
155 unsigned psctl
= (1 << 0), i
;
157 for (i
= 0; i
< 8; i
++) {
158 if ((cso
->sprite_coord_enable
>> i
) & 1)
159 psctl
|= (1 << (8 + i
));
168 rsso
->sb_len
= sb_len(sb
, rsso
->sb
);
173 nvfx_rasterizer_state_bind(struct pipe_context
*pipe
, void *hwcso
)
175 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
177 if(nvfx
->rasterizer
&& hwcso
)
179 if(!nvfx
->rasterizer
|| ((struct nvfx_rasterizer_state
*)hwcso
)->pipe
.scissor
180 != nvfx
->rasterizer
->pipe
.scissor
)
182 nvfx
->dirty
|= NVFX_NEW_SCISSOR
;
183 nvfx
->draw_dirty
|= NVFX_NEW_SCISSOR
;
186 if(((struct nvfx_rasterizer_state
*)hwcso
)->pipe
.poly_stipple_enable
187 != nvfx
->rasterizer
->pipe
.poly_stipple_enable
)
189 nvfx
->dirty
|= NVFX_NEW_STIPPLE
;
190 nvfx
->draw_dirty
|= NVFX_NEW_STIPPLE
;
194 nvfx
->rasterizer
= hwcso
;
195 nvfx
->dirty
|= NVFX_NEW_RAST
;
196 nvfx
->draw_dirty
|= NVFX_NEW_RAST
;
200 nvfx_rasterizer_state_delete(struct pipe_context
*pipe
, void *hwcso
)
202 struct nvfx_rasterizer_state
*rsso
= hwcso
;
208 nvfx_depth_stencil_alpha_state_create(struct pipe_context
*pipe
,
209 const struct pipe_depth_stencil_alpha_state
*cso
)
211 struct nvfx_zsa_state
*zsaso
= CALLOC(1, sizeof(*zsaso
));
212 struct nouveau_statebuf_builder sb
= sb_init(zsaso
->sb
);
214 sb_method(sb
, NV34TCL_DEPTH_FUNC
, 3);
215 sb_data (sb
, nvgl_comparison_op(cso
->depth
.func
));
216 sb_data (sb
, cso
->depth
.writemask
? 1 : 0);
217 sb_data (sb
, cso
->depth
.enabled
? 1 : 0);
219 sb_method(sb
, NV34TCL_ALPHA_FUNC_ENABLE
, 3);
220 sb_data (sb
, cso
->alpha
.enabled
? 1 : 0);
221 sb_data (sb
, nvgl_comparison_op(cso
->alpha
.func
));
222 sb_data (sb
, float_to_ubyte(cso
->alpha
.ref_value
));
224 if (cso
->stencil
[0].enabled
) {
225 sb_method(sb
, NV34TCL_STENCIL_FRONT_ENABLE
, 3);
226 sb_data (sb
, cso
->stencil
[0].enabled
? 1 : 0);
227 sb_data (sb
, cso
->stencil
[0].writemask
);
228 sb_data (sb
, nvgl_comparison_op(cso
->stencil
[0].func
));
229 sb_method(sb
, NV34TCL_STENCIL_FRONT_FUNC_MASK
, 4);
230 sb_data (sb
, cso
->stencil
[0].valuemask
);
231 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[0].fail_op
));
232 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[0].zfail_op
));
233 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[0].zpass_op
));
235 sb_method(sb
, NV34TCL_STENCIL_FRONT_ENABLE
, 1);
239 if (cso
->stencil
[1].enabled
) {
240 sb_method(sb
, NV34TCL_STENCIL_BACK_ENABLE
, 3);
241 sb_data (sb
, cso
->stencil
[1].enabled
? 1 : 0);
242 sb_data (sb
, cso
->stencil
[1].writemask
);
243 sb_data (sb
, nvgl_comparison_op(cso
->stencil
[1].func
));
244 sb_method(sb
, NV34TCL_STENCIL_BACK_FUNC_MASK
, 4);
245 sb_data (sb
, cso
->stencil
[1].valuemask
);
246 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[1].fail_op
));
247 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[1].zfail_op
));
248 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[1].zpass_op
));
250 sb_method(sb
, NV34TCL_STENCIL_BACK_ENABLE
, 1);
255 zsaso
->sb_len
= sb_len(sb
, zsaso
->sb
);
256 return (void *)zsaso
;
260 nvfx_depth_stencil_alpha_state_bind(struct pipe_context
*pipe
, void *hwcso
)
262 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
265 nvfx
->dirty
|= NVFX_NEW_ZSA
;
269 nvfx_depth_stencil_alpha_state_delete(struct pipe_context
*pipe
, void *hwcso
)
271 struct nvfx_zsa_state
*zsaso
= hwcso
;
277 nvfx_vp_state_create(struct pipe_context
*pipe
,
278 const struct pipe_shader_state
*cso
)
280 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
281 struct nvfx_vertex_program
*vp
;
283 vp
= CALLOC(1, sizeof(struct nvfx_vertex_program
));
284 vp
->pipe
.tokens
= tgsi_dup_tokens(cso
->tokens
);
285 vp
->draw
= draw_create_vertex_shader(nvfx
->draw
, &vp
->pipe
);
291 nvfx_vp_state_bind(struct pipe_context
*pipe
, void *hwcso
)
293 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
295 nvfx
->vertprog
= hwcso
;
296 nvfx
->dirty
|= NVFX_NEW_VERTPROG
;
297 nvfx
->draw_dirty
|= NVFX_NEW_VERTPROG
;
301 nvfx_vp_state_delete(struct pipe_context
*pipe
, void *hwcso
)
303 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
304 struct nvfx_vertex_program
*vp
= hwcso
;
306 draw_delete_vertex_shader(nvfx
->draw
, vp
->draw
);
307 nvfx_vertprog_destroy(nvfx
, vp
);
308 FREE((void*)vp
->pipe
.tokens
);
313 nvfx_fp_state_create(struct pipe_context
*pipe
,
314 const struct pipe_shader_state
*cso
)
316 struct nvfx_fragment_program
*fp
;
318 fp
= CALLOC(1, sizeof(struct nvfx_fragment_program
));
319 fp
->pipe
.tokens
= tgsi_dup_tokens(cso
->tokens
);
321 tgsi_scan_shader(fp
->pipe
.tokens
, &fp
->info
);
327 nvfx_fp_state_bind(struct pipe_context
*pipe
, void *hwcso
)
329 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
331 nvfx
->fragprog
= hwcso
;
332 nvfx
->dirty
|= NVFX_NEW_FRAGPROG
;
336 nvfx_fp_state_delete(struct pipe_context
*pipe
, void *hwcso
)
338 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
339 struct nvfx_fragment_program
*fp
= hwcso
;
341 nvfx_fragprog_destroy(nvfx
, fp
);
342 FREE((void*)fp
->pipe
.tokens
);
347 nvfx_set_blend_color(struct pipe_context
*pipe
,
348 const struct pipe_blend_color
*bcol
)
350 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
352 nvfx
->blend_colour
= *bcol
;
353 nvfx
->dirty
|= NVFX_NEW_BCOL
;
357 nvfx_set_stencil_ref(struct pipe_context
*pipe
,
358 const struct pipe_stencil_ref
*sr
)
360 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
362 nvfx
->stencil_ref
= *sr
;
363 nvfx
->dirty
|= NVFX_NEW_SR
;
367 nvfx_set_clip_state(struct pipe_context
*pipe
,
368 const struct pipe_clip_state
*clip
)
370 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
373 nvfx
->dirty
|= NVFX_NEW_UCP
;
374 nvfx
->draw_dirty
|= NVFX_NEW_UCP
;
378 nvfx_set_sample_mask(struct pipe_context
*pipe
,
379 unsigned sample_mask
)
384 nvfx_set_constant_buffer(struct pipe_context
*pipe
, uint shader
, uint index
,
385 struct pipe_resource
*buf
)
387 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
389 nvfx
->constbuf
[shader
] = buf
;
390 nvfx
->constbuf_nr
[shader
] = buf
->width0
/ (4 * sizeof(float));
392 if (shader
== PIPE_SHADER_VERTEX
) {
393 nvfx
->dirty
|= NVFX_NEW_VERTCONST
;
395 if (shader
== PIPE_SHADER_FRAGMENT
) {
396 nvfx
->dirty
|= NVFX_NEW_FRAGCONST
;
401 nvfx_set_framebuffer_state(struct pipe_context
*pipe
,
402 const struct pipe_framebuffer_state
*fb
)
404 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
407 util_copy_framebuffer_state(&nvfx
->framebuffer
, fb
);
409 util_unreference_framebuffer_state(&nvfx
->framebuffer
);
410 nvfx
->dirty
|= NVFX_NEW_FB
;
414 nvfx_set_polygon_stipple(struct pipe_context
*pipe
,
415 const struct pipe_poly_stipple
*stipple
)
417 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
419 memcpy(nvfx
->stipple
, stipple
->stipple
, 4 * 32);
420 nvfx
->dirty
|= NVFX_NEW_STIPPLE
;
424 nvfx_set_scissor_state(struct pipe_context
*pipe
,
425 const struct pipe_scissor_state
*s
)
427 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
430 nvfx
->dirty
|= NVFX_NEW_SCISSOR
;
434 nvfx_set_viewport_state(struct pipe_context
*pipe
,
435 const struct pipe_viewport_state
*vpt
)
437 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
439 nvfx
->viewport
= *vpt
;
440 nvfx
->dirty
|= NVFX_NEW_VIEWPORT
;
441 nvfx
->draw_dirty
|= NVFX_NEW_VIEWPORT
;
445 nvfx_init_state_functions(struct nvfx_context
*nvfx
)
447 nvfx
->pipe
.create_blend_state
= nvfx_blend_state_create
;
448 nvfx
->pipe
.bind_blend_state
= nvfx_blend_state_bind
;
449 nvfx
->pipe
.delete_blend_state
= nvfx_blend_state_delete
;
451 nvfx
->pipe
.create_rasterizer_state
= nvfx_rasterizer_state_create
;
452 nvfx
->pipe
.bind_rasterizer_state
= nvfx_rasterizer_state_bind
;
453 nvfx
->pipe
.delete_rasterizer_state
= nvfx_rasterizer_state_delete
;
455 nvfx
->pipe
.create_depth_stencil_alpha_state
=
456 nvfx_depth_stencil_alpha_state_create
;
457 nvfx
->pipe
.bind_depth_stencil_alpha_state
=
458 nvfx_depth_stencil_alpha_state_bind
;
459 nvfx
->pipe
.delete_depth_stencil_alpha_state
=
460 nvfx_depth_stencil_alpha_state_delete
;
462 nvfx
->pipe
.create_vs_state
= nvfx_vp_state_create
;
463 nvfx
->pipe
.bind_vs_state
= nvfx_vp_state_bind
;
464 nvfx
->pipe
.delete_vs_state
= nvfx_vp_state_delete
;
466 nvfx
->pipe
.create_fs_state
= nvfx_fp_state_create
;
467 nvfx
->pipe
.bind_fs_state
= nvfx_fp_state_bind
;
468 nvfx
->pipe
.delete_fs_state
= nvfx_fp_state_delete
;
470 nvfx
->pipe
.set_blend_color
= nvfx_set_blend_color
;
471 nvfx
->pipe
.set_stencil_ref
= nvfx_set_stencil_ref
;
472 nvfx
->pipe
.set_clip_state
= nvfx_set_clip_state
;
473 nvfx
->pipe
.set_sample_mask
= nvfx_set_sample_mask
;
474 nvfx
->pipe
.set_constant_buffer
= nvfx_set_constant_buffer
;
475 nvfx
->pipe
.set_framebuffer_state
= nvfx_set_framebuffer_state
;
476 nvfx
->pipe
.set_polygon_stipple
= nvfx_set_polygon_stipple
;
477 nvfx
->pipe
.set_scissor_state
= nvfx_set_scissor_state
;
478 nvfx
->pipe
.set_viewport_state
= nvfx_set_viewport_state
;