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
);
97 sb_method(sb
, NV34TCL_SHADE_MODEL
, 1);
98 sb_data(sb
, cso
->flatshade
? NV34TCL_SHADE_MODEL_FLAT
:
99 NV34TCL_SHADE_MODEL_SMOOTH
);
101 sb_method(sb
, NV34TCL_VERTEX_TWO_SIDE_ENABLE
, 1);
102 sb_data(sb
, cso
->light_twoside
);
104 sb_method(sb
, NV34TCL_LINE_WIDTH
, 2);
105 sb_data(sb
, (unsigned char)(cso
->line_width
* 8.0) & 0xff);
106 sb_data(sb
, cso
->line_smooth
? 1 : 0);
107 sb_method(sb
, NV34TCL_LINE_STIPPLE_ENABLE
, 2);
108 sb_data(sb
, cso
->line_stipple_enable
? 1 : 0);
109 sb_data(sb
, (cso
->line_stipple_pattern
<< 16) |
110 cso
->line_stipple_factor
);
112 sb_method(sb
, NV34TCL_POINT_SIZE
, 1);
113 sb_data(sb
, fui(cso
->point_size
));
115 sb_method(sb
, NV34TCL_POLYGON_MODE_FRONT
, 6);
116 sb_data(sb
, nvgl_polygon_mode(cso
->fill_front
));
117 sb_data(sb
, nvgl_polygon_mode(cso
->fill_back
));
118 switch (cso
->cull_face
) {
119 case PIPE_FACE_FRONT
:
120 sb_data(sb
, NV34TCL_CULL_FACE_FRONT
);
123 sb_data(sb
, NV34TCL_CULL_FACE_BACK
);
125 case PIPE_FACE_FRONT_AND_BACK
:
126 sb_data(sb
, NV34TCL_CULL_FACE_FRONT_AND_BACK
);
129 sb_data(sb
, NV34TCL_CULL_FACE_BACK
);
132 if (cso
->front_ccw
) {
133 sb_data(sb
, NV34TCL_FRONT_FACE_CCW
);
135 sb_data(sb
, NV34TCL_FRONT_FACE_CW
);
137 sb_data(sb
, cso
->poly_smooth
? 1 : 0);
138 sb_data(sb
, (cso
->cull_face
!= PIPE_FACE_NONE
) ? 1 : 0);
140 sb_method(sb
, NV34TCL_POLYGON_STIPPLE_ENABLE
, 1);
141 sb_data(sb
, cso
->poly_stipple_enable
? 1 : 0);
143 sb_method(sb
, NV34TCL_POLYGON_OFFSET_POINT_ENABLE
, 3);
144 sb_data(sb
, cso
->offset_point
);
145 sb_data(sb
, cso
->offset_line
);
146 sb_data(sb
, cso
->offset_tri
);
148 if (cso
->offset_point
|| cso
->offset_line
|| cso
->offset_tri
) {
149 sb_method(sb
, NV34TCL_POLYGON_OFFSET_FACTOR
, 2);
150 sb_data(sb
, fui(cso
->offset_scale
));
151 sb_data(sb
, fui(cso
->offset_units
* 2));
154 sb_method(sb
, NV34TCL_FLATSHADE_FIRST
, 1);
155 sb_data(sb
, cso
->flatshade_first
);
158 rsso
->sb_len
= sb_len(sb
, rsso
->sb
);
163 nvfx_rasterizer_state_bind(struct pipe_context
*pipe
, void *hwcso
)
165 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
167 if(nvfx
->rasterizer
&& hwcso
)
169 if(!nvfx
->rasterizer
|| ((struct nvfx_rasterizer_state
*)hwcso
)->pipe
.scissor
170 != nvfx
->rasterizer
->pipe
.scissor
)
172 nvfx
->dirty
|= NVFX_NEW_SCISSOR
;
173 nvfx
->draw_dirty
|= NVFX_NEW_SCISSOR
;
176 if(((struct nvfx_rasterizer_state
*)hwcso
)->pipe
.poly_stipple_enable
177 != nvfx
->rasterizer
->pipe
.poly_stipple_enable
)
179 nvfx
->dirty
|= NVFX_NEW_STIPPLE
;
180 nvfx
->draw_dirty
|= NVFX_NEW_STIPPLE
;
183 if(((struct nvfx_rasterizer_state
*)hwcso
)->pipe
.point_quad_rasterization
!= nvfx
->rasterizer
->pipe
.point_quad_rasterization
184 || ((struct nvfx_rasterizer_state
*)hwcso
)->pipe
.sprite_coord_enable
!= nvfx
->rasterizer
->pipe
.sprite_coord_enable
)
186 nvfx
->dirty
|= NVFX_NEW_SPRITE
;
190 nvfx
->rasterizer
= hwcso
;
191 nvfx
->dirty
|= NVFX_NEW_RAST
;
192 nvfx
->draw_dirty
|= NVFX_NEW_RAST
;
196 nvfx_rasterizer_state_delete(struct pipe_context
*pipe
, void *hwcso
)
198 struct nvfx_rasterizer_state
*rsso
= hwcso
;
204 nvfx_depth_stencil_alpha_state_create(struct pipe_context
*pipe
,
205 const struct pipe_depth_stencil_alpha_state
*cso
)
207 struct nvfx_zsa_state
*zsaso
= CALLOC(1, sizeof(*zsaso
));
208 struct nouveau_statebuf_builder sb
= sb_init(zsaso
->sb
);
210 sb_method(sb
, NV34TCL_DEPTH_FUNC
, 3);
211 sb_data (sb
, nvgl_comparison_op(cso
->depth
.func
));
212 sb_data (sb
, cso
->depth
.writemask
? 1 : 0);
213 sb_data (sb
, cso
->depth
.enabled
? 1 : 0);
215 sb_method(sb
, NV34TCL_ALPHA_FUNC_ENABLE
, 3);
216 sb_data (sb
, cso
->alpha
.enabled
? 1 : 0);
217 sb_data (sb
, nvgl_comparison_op(cso
->alpha
.func
));
218 sb_data (sb
, float_to_ubyte(cso
->alpha
.ref_value
));
220 if (cso
->stencil
[0].enabled
) {
221 sb_method(sb
, NV34TCL_STENCIL_FRONT_ENABLE
, 3);
222 sb_data (sb
, cso
->stencil
[0].enabled
? 1 : 0);
223 sb_data (sb
, cso
->stencil
[0].writemask
);
224 sb_data (sb
, nvgl_comparison_op(cso
->stencil
[0].func
));
225 sb_method(sb
, NV34TCL_STENCIL_FRONT_FUNC_MASK
, 4);
226 sb_data (sb
, cso
->stencil
[0].valuemask
);
227 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[0].fail_op
));
228 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[0].zfail_op
));
229 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[0].zpass_op
));
231 sb_method(sb
, NV34TCL_STENCIL_FRONT_ENABLE
, 1);
235 if (cso
->stencil
[1].enabled
) {
236 sb_method(sb
, NV34TCL_STENCIL_BACK_ENABLE
, 3);
237 sb_data (sb
, cso
->stencil
[1].enabled
? 1 : 0);
238 sb_data (sb
, cso
->stencil
[1].writemask
);
239 sb_data (sb
, nvgl_comparison_op(cso
->stencil
[1].func
));
240 sb_method(sb
, NV34TCL_STENCIL_BACK_FUNC_MASK
, 4);
241 sb_data (sb
, cso
->stencil
[1].valuemask
);
242 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[1].fail_op
));
243 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[1].zfail_op
));
244 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[1].zpass_op
));
246 sb_method(sb
, NV34TCL_STENCIL_BACK_ENABLE
, 1);
251 zsaso
->sb_len
= sb_len(sb
, zsaso
->sb
);
252 return (void *)zsaso
;
256 nvfx_depth_stencil_alpha_state_bind(struct pipe_context
*pipe
, void *hwcso
)
258 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
261 nvfx
->dirty
|= NVFX_NEW_ZSA
;
265 nvfx_depth_stencil_alpha_state_delete(struct pipe_context
*pipe
, void *hwcso
)
267 struct nvfx_zsa_state
*zsaso
= hwcso
;
273 nvfx_vp_state_create(struct pipe_context
*pipe
,
274 const struct pipe_shader_state
*cso
)
276 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
277 struct nvfx_vertex_program
*vp
;
279 // TODO: use a 64-bit atomic here!
280 static unsigned long long id
= 0;
282 vp
= CALLOC(1, sizeof(struct nvfx_vertex_program
));
283 vp
->pipe
.tokens
= tgsi_dup_tokens(cso
->tokens
);
284 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
;