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
, NV30_3D_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
, NV30_3D_BLEND_EQUATION
, 1);
31 sb_data(sb
, nvgl_blend_eqn(cso
->rt
[0].rgb_func
));
33 sb_method(sb
, NV40_3D_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
, NV30_3D_BLEND_FUNC_ENABLE
, 1);
42 sb_method(sb
, NV30_3D_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
, NV30_3D_COLOR_LOGIC_OP_ENABLE
, 2);
53 sb_data(sb
, nvgl_logicop_func(cso
->logicop_func
));
55 sb_method(sb
, NV30_3D_COLOR_LOGIC_OP_ENABLE
, 1);
59 sb_method(sb
, NV30_3D_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
, NV30_3D_SHADE_MODEL
, 1);
98 sb_data(sb
, cso
->flatshade
? NV30_3D_SHADE_MODEL_FLAT
:
99 NV30_3D_SHADE_MODEL_SMOOTH
);
101 sb_method(sb
, NV30_3D_VERTEX_TWO_SIDE_ENABLE
, 1);
102 sb_data(sb
, cso
->light_twoside
);
104 sb_method(sb
, NV30_3D_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
, NV30_3D_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
, NV30_3D_POINT_SIZE
, 1);
113 sb_data(sb
, fui(cso
->point_size
));
115 sb_method(sb
, NV30_3D_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
, NV30_3D_CULL_FACE_FRONT
);
123 sb_data(sb
, NV30_3D_CULL_FACE_BACK
);
125 case PIPE_FACE_FRONT_AND_BACK
:
126 sb_data(sb
, NV30_3D_CULL_FACE_FRONT_AND_BACK
);
129 sb_data(sb
, NV30_3D_CULL_FACE_BACK
);
132 if (cso
->front_ccw
) {
133 sb_data(sb
, NV30_3D_FRONT_FACE_CCW
);
135 sb_data(sb
, NV30_3D_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
, NV30_3D_POLYGON_STIPPLE_ENABLE
, 1);
141 sb_data(sb
, cso
->poly_stipple_enable
? 1 : 0);
143 sb_method(sb
, NV30_3D_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
, NV30_3D_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
, NV30_3D_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
.point_quad_rasterization
!= nvfx
->rasterizer
->pipe
.point_quad_rasterization
177 || ((struct nvfx_rasterizer_state
*)hwcso
)->pipe
.sprite_coord_enable
!= nvfx
->rasterizer
->pipe
.sprite_coord_enable
178 || ((struct nvfx_rasterizer_state
*)hwcso
)->pipe
.sprite_coord_mode
!= nvfx
->rasterizer
->pipe
.sprite_coord_mode
)
180 nvfx
->dirty
|= NVFX_NEW_SPRITE
;
184 nvfx
->rasterizer
= hwcso
;
185 nvfx
->dirty
|= NVFX_NEW_RAST
;
186 nvfx
->draw_dirty
|= NVFX_NEW_RAST
;
190 nvfx_rasterizer_state_delete(struct pipe_context
*pipe
, void *hwcso
)
192 struct nvfx_rasterizer_state
*rsso
= hwcso
;
198 nvfx_depth_stencil_alpha_state_create(struct pipe_context
*pipe
,
199 const struct pipe_depth_stencil_alpha_state
*cso
)
201 struct nvfx_zsa_state
*zsaso
= CALLOC(1, sizeof(*zsaso
));
202 struct nouveau_statebuf_builder sb
= sb_init(zsaso
->sb
);
204 sb_method(sb
, NV30_3D_DEPTH_FUNC
, 1);
205 sb_data (sb
, nvgl_comparison_op(cso
->depth
.func
));
207 sb_method(sb
, NV30_3D_ALPHA_FUNC_ENABLE
, 3);
208 sb_data (sb
, cso
->alpha
.enabled
? 1 : 0);
209 sb_data (sb
, nvgl_comparison_op(cso
->alpha
.func
));
210 sb_data (sb
, float_to_ubyte(cso
->alpha
.ref_value
));
212 if (cso
->stencil
[0].enabled
) {
213 sb_method(sb
, NV30_3D_STENCIL_ENABLE(0), 3);
214 sb_data (sb
, cso
->stencil
[0].enabled
? 1 : 0);
215 sb_data (sb
, cso
->stencil
[0].writemask
);
216 sb_data (sb
, nvgl_comparison_op(cso
->stencil
[0].func
));
217 sb_method(sb
, NV30_3D_STENCIL_FUNC_MASK(0), 4);
218 sb_data (sb
, cso
->stencil
[0].valuemask
);
219 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[0].fail_op
));
220 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[0].zfail_op
));
221 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[0].zpass_op
));
223 sb_method(sb
, NV30_3D_STENCIL_ENABLE(0), 1);
227 if (cso
->stencil
[1].enabled
) {
228 sb_method(sb
, NV30_3D_STENCIL_ENABLE(1), 3);
229 sb_data (sb
, cso
->stencil
[1].enabled
? 1 : 0);
230 sb_data (sb
, cso
->stencil
[1].writemask
);
231 sb_data (sb
, nvgl_comparison_op(cso
->stencil
[1].func
));
232 sb_method(sb
, NV30_3D_STENCIL_FUNC_MASK(1), 4);
233 sb_data (sb
, cso
->stencil
[1].valuemask
);
234 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[1].fail_op
));
235 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[1].zfail_op
));
236 sb_data (sb
, nvgl_stencil_op(cso
->stencil
[1].zpass_op
));
238 sb_method(sb
, NV30_3D_STENCIL_ENABLE(1), 1);
243 zsaso
->sb_len
= sb_len(sb
, zsaso
->sb
);
244 return (void *)zsaso
;
248 nvfx_depth_stencil_alpha_state_bind(struct pipe_context
*pipe
, void *hwcso
)
250 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
253 nvfx
->dirty
|= NVFX_NEW_ZSA
;
257 nvfx_depth_stencil_alpha_state_delete(struct pipe_context
*pipe
, void *hwcso
)
259 struct nvfx_zsa_state
*zsaso
= hwcso
;
265 nvfx_set_blend_color(struct pipe_context
*pipe
,
266 const struct pipe_blend_color
*bcol
)
268 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
270 nvfx
->blend_colour
= *bcol
;
271 nvfx
->dirty
|= NVFX_NEW_BCOL
;
275 nvfx_set_stencil_ref(struct pipe_context
*pipe
,
276 const struct pipe_stencil_ref
*sr
)
278 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
280 nvfx
->stencil_ref
= *sr
;
281 nvfx
->dirty
|= NVFX_NEW_SR
;
285 nvfx_set_clip_state(struct pipe_context
*pipe
,
286 const struct pipe_clip_state
*clip
)
288 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
291 nvfx
->dirty
|= NVFX_NEW_UCP
;
292 nvfx
->draw_dirty
|= NVFX_NEW_UCP
;
296 nvfx_set_sample_mask(struct pipe_context
*pipe
,
297 unsigned sample_mask
)
302 nvfx_set_constant_buffer(struct pipe_context
*pipe
, uint shader
, uint index
,
303 struct pipe_resource
*buf
)
305 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
307 pipe_resource_reference(&nvfx
->constbuf
[shader
], buf
);
308 nvfx
->constbuf_nr
[shader
] = buf
? (buf
->width0
/ (4 * sizeof(float))) : 0;
310 if (shader
== PIPE_SHADER_VERTEX
) {
311 nvfx
->dirty
|= NVFX_NEW_VERTCONST
;
313 if (shader
== PIPE_SHADER_FRAGMENT
) {
314 nvfx
->dirty
|= NVFX_NEW_FRAGCONST
;
319 nvfx_set_framebuffer_state(struct pipe_context
*pipe
,
320 const struct pipe_framebuffer_state
*fb
)
322 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
325 util_copy_framebuffer_state(&nvfx
->framebuffer
, fb
);
327 util_unreference_framebuffer_state(&nvfx
->framebuffer
);
328 nvfx
->dirty
|= NVFX_NEW_FB
;
332 nvfx_set_polygon_stipple(struct pipe_context
*pipe
,
333 const struct pipe_poly_stipple
*stipple
)
335 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
337 memcpy(nvfx
->stipple
, stipple
->stipple
, 4 * 32);
338 nvfx
->dirty
|= NVFX_NEW_STIPPLE
;
342 nvfx_set_scissor_state(struct pipe_context
*pipe
,
343 const struct pipe_scissor_state
*s
)
345 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
348 nvfx
->dirty
|= NVFX_NEW_SCISSOR
;
352 nvfx_set_viewport_state(struct pipe_context
*pipe
,
353 const struct pipe_viewport_state
*vpt
)
355 struct nvfx_context
*nvfx
= nvfx_context(pipe
);
357 nvfx
->viewport
= *vpt
;
358 nvfx
->dirty
|= NVFX_NEW_VIEWPORT
;
359 nvfx
->draw_dirty
|= NVFX_NEW_VIEWPORT
;
363 nvfx_init_state_functions(struct nvfx_context
*nvfx
)
365 nvfx
->pipe
.create_blend_state
= nvfx_blend_state_create
;
366 nvfx
->pipe
.bind_blend_state
= nvfx_blend_state_bind
;
367 nvfx
->pipe
.delete_blend_state
= nvfx_blend_state_delete
;
369 nvfx
->pipe
.create_rasterizer_state
= nvfx_rasterizer_state_create
;
370 nvfx
->pipe
.bind_rasterizer_state
= nvfx_rasterizer_state_bind
;
371 nvfx
->pipe
.delete_rasterizer_state
= nvfx_rasterizer_state_delete
;
373 nvfx
->pipe
.create_depth_stencil_alpha_state
=
374 nvfx_depth_stencil_alpha_state_create
;
375 nvfx
->pipe
.bind_depth_stencil_alpha_state
=
376 nvfx_depth_stencil_alpha_state_bind
;
377 nvfx
->pipe
.delete_depth_stencil_alpha_state
=
378 nvfx_depth_stencil_alpha_state_delete
;
380 nvfx
->pipe
.set_blend_color
= nvfx_set_blend_color
;
381 nvfx
->pipe
.set_stencil_ref
= nvfx_set_stencil_ref
;
382 nvfx
->pipe
.set_clip_state
= nvfx_set_clip_state
;
383 nvfx
->pipe
.set_sample_mask
= nvfx_set_sample_mask
;
384 nvfx
->pipe
.set_constant_buffer
= nvfx_set_constant_buffer
;
385 nvfx
->pipe
.set_framebuffer_state
= nvfx_set_framebuffer_state
;
386 nvfx
->pipe
.set_polygon_stipple
= nvfx_set_polygon_stipple
;
387 nvfx
->pipe
.set_scissor_state
= nvfx_set_scissor_state
;
388 nvfx
->pipe
.set_viewport_state
= nvfx_set_viewport_state
;