1 #include "pipe/p_state.h"
2 #include "pipe/p_defines.h"
3 #include "pipe/p_util.h"
4 #include "pipe/p_shader_tokens.h"
7 #include "nv10_context.h"
8 #include "nv10_state.h"
10 static void nv10_vertex_layout(struct pipe_context
* pipe
)
12 struct nv10_context
*nv10
= nv10_context(pipe
);
13 struct nv10_fragment_program
*fp
= nv10
->fragprog
.current
;
16 struct vertex_info vinfo
;
18 memset(&vinfo
, 0, sizeof(vinfo
));
20 for (i
= 0; i
< fp
->info
.num_inputs
; i
++) {
21 switch (fp
->info
.input_semantic_name
[i
]) {
22 case TGSI_SEMANTIC_POSITION
:
23 draw_emit_vertex_attr(&vinfo
, EMIT_4F
, INTERP_LINEAR
, src
++);
25 case TGSI_SEMANTIC_COLOR
:
26 draw_emit_vertex_attr(&vinfo
, EMIT_4F
, INTERP_LINEAR
, src
++);
29 case TGSI_SEMANTIC_GENERIC
:
30 draw_emit_vertex_attr(&vinfo
, EMIT_4F
, INTERP_PERSPECTIVE
, src
++);
32 case TGSI_SEMANTIC_FOG
:
33 draw_emit_vertex_attr(&vinfo
, EMIT_4F
, INTERP_PERSPECTIVE
, src
++);
37 draw_compute_vertex_size(&vinfo
);
39 nv10
->dirty
|= NV10_NEW_VTXFMT
;
43 nv10_blend_state_create(struct pipe_context
*pipe
,
44 const struct pipe_blend_state
*cso
)
46 struct nv10_blend_state
*cb
;
48 cb
= malloc(sizeof(struct nv10_blend_state
));
50 cb
->b_enable
= cso
->blend_enable
? 1 : 0;
51 cb
->b_srcfunc
= ((nvgl_blend_func(cso
->alpha_src_factor
)<<16) |
52 (nvgl_blend_func(cso
->rgb_src_factor
)));
53 cb
->b_dstfunc
= ((nvgl_blend_func(cso
->alpha_dst_factor
)<<16) |
54 (nvgl_blend_func(cso
->rgb_dst_factor
)));
56 cb
->c_mask
= (((cso
->colormask
& PIPE_MASK_A
) ? (0x01<<24) : 0) |
57 ((cso
->colormask
& PIPE_MASK_R
) ? (0x01<<16) : 0) |
58 ((cso
->colormask
& PIPE_MASK_G
) ? (0x01<< 8) : 0) |
59 ((cso
->colormask
& PIPE_MASK_B
) ? (0x01<< 0) : 0));
61 cb
->d_enable
= cso
->dither
? 1 : 0;
67 nv10_blend_state_bind(struct pipe_context
*pipe
, void *blend
)
69 struct nv10_context
*nv10
= nv10_context(pipe
);
71 nv10
->blend
= (struct nv10_blend_state
*)blend
;
73 nv10
->dirty
|= NV10_NEW_BLEND
;
77 nv10_blend_state_delete(struct pipe_context
*pipe
, void *hwcso
)
83 static INLINE
unsigned
84 wrap_mode(unsigned wrap
) {
88 case PIPE_TEX_WRAP_REPEAT
:
89 ret
= NV10TCL_TX_FORMAT_WRAP_S_REPEAT
;
91 case PIPE_TEX_WRAP_MIRROR_REPEAT
:
92 ret
= NV10TCL_TX_FORMAT_WRAP_S_MIRRORED_REPEAT
;
94 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
:
95 ret
= NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_EDGE
;
97 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
:
98 ret
= NV10TCL_TX_FORMAT_WRAP_S_CLAMP_TO_BORDER
;
100 case PIPE_TEX_WRAP_CLAMP
:
101 ret
= NV10TCL_TX_FORMAT_WRAP_S_CLAMP
;
103 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE
:
104 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER
:
105 case PIPE_TEX_WRAP_MIRROR_CLAMP
:
107 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap
);
108 ret
= NV10TCL_TX_FORMAT_WRAP_S_REPEAT
;
112 return ret
>> NV10TCL_TX_FORMAT_WRAP_S_SHIFT
;
116 nv10_sampler_state_create(struct pipe_context
*pipe
,
117 const struct pipe_sampler_state
*cso
)
119 struct nv10_sampler_state
*ps
;
122 ps
= malloc(sizeof(struct nv10_sampler_state
));
124 ps
->wrap
= ((wrap_mode(cso
->wrap_s
) << NV10TCL_TX_FORMAT_WRAP_S_SHIFT
) |
125 (wrap_mode(cso
->wrap_t
) << NV10TCL_TX_FORMAT_WRAP_T_SHIFT
));
128 if (cso
->max_anisotropy
> 1.0) {
129 /* no idea, binary driver sets it, works without it.. meh.. */
130 ps
->wrap
|= (1 << 5);
132 /* if (cso->max_anisotropy >= 16.0) {
133 ps->en |= NV10TCL_TX_ENABLE_ANISO_16X;
135 if (cso->max_anisotropy >= 12.0) {
136 ps->en |= NV10TCL_TX_ENABLE_ANISO_12X;
138 if (cso->max_anisotropy >= 10.0) {
139 ps->en |= NV10TCL_TX_ENABLE_ANISO_10X;
141 if (cso->max_anisotropy >= 8.0) {
142 ps->en |= NV10TCL_TX_ENABLE_ANISO_8X;
144 if (cso->max_anisotropy >= 6.0) {
145 ps->en |= NV10TCL_TX_ENABLE_ANISO_6X;
147 if (cso->max_anisotropy >= 4.0) {
148 ps->en |= NV10TCL_TX_ENABLE_ANISO_4X;
150 ps->en |= NV10TCL_TX_ENABLE_ANISO_2X;
154 switch (cso
->mag_img_filter
) {
155 case PIPE_TEX_FILTER_LINEAR
:
156 filter
|= NV10TCL_TX_FILTER_MAGNIFY_LINEAR
;
158 case PIPE_TEX_FILTER_NEAREST
:
160 filter
|= NV10TCL_TX_FILTER_MAGNIFY_NEAREST
;
164 switch (cso
->min_img_filter
) {
165 case PIPE_TEX_FILTER_LINEAR
:
166 switch (cso
->min_mip_filter
) {
167 case PIPE_TEX_MIPFILTER_NEAREST
:
168 filter
|= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST
;
170 case PIPE_TEX_MIPFILTER_LINEAR
:
171 filter
|= NV10TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR
;
173 case PIPE_TEX_MIPFILTER_NONE
:
175 filter
|= NV10TCL_TX_FILTER_MINIFY_LINEAR
;
179 case PIPE_TEX_FILTER_NEAREST
:
181 switch (cso
->min_mip_filter
) {
182 case PIPE_TEX_MIPFILTER_NEAREST
:
183 filter
|= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST
;
185 case PIPE_TEX_MIPFILTER_LINEAR
:
186 filter
|= NV10TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR
;
188 case PIPE_TEX_MIPFILTER_NONE
:
190 filter
|= NV10TCL_TX_FILTER_MINIFY_NEAREST
;
198 /* if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
199 switch (cso->compare_func) {
200 case PIPE_FUNC_NEVER:
201 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NEVER;
203 case PIPE_FUNC_GREATER:
204 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GREATER;
206 case PIPE_FUNC_EQUAL:
207 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_EQUAL;
209 case PIPE_FUNC_GEQUAL:
210 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GEQUAL;
213 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LESS;
215 case PIPE_FUNC_NOTEQUAL:
216 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NOTEQUAL;
218 case PIPE_FUNC_LEQUAL:
219 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LEQUAL;
221 case PIPE_FUNC_ALWAYS:
222 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_ALWAYS;
229 ps
->bcol
= ((float_to_ubyte(cso
->border_color
[3]) << 24) |
230 (float_to_ubyte(cso
->border_color
[0]) << 16) |
231 (float_to_ubyte(cso
->border_color
[1]) << 8) |
232 (float_to_ubyte(cso
->border_color
[2]) << 0));
238 nv10_sampler_state_bind(struct pipe_context
*pipe
, unsigned nr
, void **sampler
)
240 struct nv10_context
*nv10
= nv10_context(pipe
);
243 for (unit
= 0; unit
< nr
; unit
++) {
244 nv10
->tex_sampler
[unit
] = sampler
[unit
];
245 nv10
->dirty_samplers
|= (1 << unit
);
250 nv10_sampler_state_delete(struct pipe_context
*pipe
, void *hwcso
)
256 nv10_set_sampler_texture(struct pipe_context
*pipe
, unsigned nr
,
257 struct pipe_texture
**miptree
)
259 struct nv10_context
*nv10
= nv10_context(pipe
);
262 for (unit
= 0; unit
< nr
; unit
++) {
263 nv10
->tex_miptree
[unit
] = (struct nv10_miptree
*)miptree
[unit
];
264 nv10
->dirty_samplers
|= (1 << unit
);
269 nv10_rasterizer_state_create(struct pipe_context
*pipe
,
270 const struct pipe_rasterizer_state
*cso
)
272 struct nv10_rasterizer_state
*rs
;
277 * offset_cw/ccw -nohw
281 * offset_units / offset_scale
283 rs
= malloc(sizeof(struct nv10_rasterizer_state
));
287 rs
->shade_model
= cso
->flatshade
? 0x1d00 : 0x1d01;
289 rs
->line_width
= (unsigned char)(cso
->line_width
* 8.0) & 0xff;
290 rs
->line_smooth_en
= cso
->line_smooth
? 1 : 0;
292 rs
->point_size
= *(uint32_t*)&cso
->point_size
;
294 rs
->poly_smooth_en
= cso
->poly_smooth
? 1 : 0;
296 if (cso
->front_winding
== PIPE_WINDING_CCW
) {
297 rs
->front_face
= NV10TCL_FRONT_FACE_CCW
;
298 rs
->poly_mode_front
= nvgl_polygon_mode(cso
->fill_ccw
);
299 rs
->poly_mode_back
= nvgl_polygon_mode(cso
->fill_cw
);
301 rs
->front_face
= NV10TCL_FRONT_FACE_CW
;
302 rs
->poly_mode_front
= nvgl_polygon_mode(cso
->fill_cw
);
303 rs
->poly_mode_back
= nvgl_polygon_mode(cso
->fill_ccw
);
306 switch (cso
->cull_mode
) {
307 case PIPE_WINDING_CCW
:
308 rs
->cull_face_en
= 1;
309 if (cso
->front_winding
== PIPE_WINDING_CCW
)
310 rs
->cull_face
= NV10TCL_CULL_FACE_FRONT
;
312 rs
->cull_face
= NV10TCL_CULL_FACE_BACK
;
314 case PIPE_WINDING_CW
:
315 rs
->cull_face_en
= 1;
316 if (cso
->front_winding
== PIPE_WINDING_CW
)
317 rs
->cull_face
= NV10TCL_CULL_FACE_FRONT
;
319 rs
->cull_face
= NV10TCL_CULL_FACE_BACK
;
321 case PIPE_WINDING_BOTH
:
322 rs
->cull_face_en
= 1;
323 rs
->cull_face
= NV10TCL_CULL_FACE_FRONT_AND_BACK
;
325 case PIPE_WINDING_NONE
:
327 rs
->cull_face_en
= 0;
332 if (cso
->point_sprite
) {
333 rs
->point_sprite
= (1 << 0);
334 for (i
= 0; i
< 8; i
++) {
335 if (cso
->sprite_coord_mode
[i
] != PIPE_SPRITE_COORD_NONE
)
336 rs
->point_sprite
|= (1 << (8 + i
));
339 rs
->point_sprite
= 0;
346 nv10_rasterizer_state_bind(struct pipe_context
*pipe
, void *rast
)
348 struct nv10_context
*nv10
= nv10_context(pipe
);
350 nv10
->rast
= (struct nv10_rasterizer_state
*)rast
;
352 draw_set_rasterizer_state(nv10
->draw
, (nv10
->rast
? nv10
->rast
->templ
: NULL
));
354 nv10
->dirty
|= NV10_NEW_RAST
;
358 nv10_rasterizer_state_delete(struct pipe_context
*pipe
, void *hwcso
)
364 nv10_depth_stencil_alpha_state_create(struct pipe_context
*pipe
,
365 const struct pipe_depth_stencil_alpha_state
*cso
)
367 struct nv10_depth_stencil_alpha_state
*hw
;
369 hw
= malloc(sizeof(struct nv10_depth_stencil_alpha_state
));
371 hw
->depth
.func
= nvgl_comparison_op(cso
->depth
.func
);
372 hw
->depth
.write_enable
= cso
->depth
.writemask
? 1 : 0;
373 hw
->depth
.test_enable
= cso
->depth
.enabled
? 1 : 0;
375 hw
->stencil
.enable
= cso
->stencil
[0].enabled
? 1 : 0;
376 hw
->stencil
.wmask
= cso
->stencil
[0].write_mask
;
377 hw
->stencil
.func
= nvgl_comparison_op(cso
->stencil
[0].func
);
378 hw
->stencil
.ref
= cso
->stencil
[0].ref_value
;
379 hw
->stencil
.vmask
= cso
->stencil
[0].value_mask
;
380 hw
->stencil
.fail
= nvgl_stencil_op(cso
->stencil
[0].fail_op
);
381 hw
->stencil
.zfail
= nvgl_stencil_op(cso
->stencil
[0].zfail_op
);
382 hw
->stencil
.zpass
= nvgl_stencil_op(cso
->stencil
[0].zpass_op
);
384 hw
->alpha
.enabled
= cso
->alpha
.enabled
? 1 : 0;
385 hw
->alpha
.func
= nvgl_comparison_op(cso
->alpha
.func
);
386 hw
->alpha
.ref
= float_to_ubyte(cso
->alpha
.ref
);
392 nv10_depth_stencil_alpha_state_bind(struct pipe_context
*pipe
, void *dsa
)
394 struct nv10_context
*nv10
= nv10_context(pipe
);
396 nv10
->dsa
= (struct nv10_depth_stencil_alpha_state
*)dsa
;
398 nv10
->dirty
|= NV10_NEW_DSA
;
402 nv10_depth_stencil_alpha_state_delete(struct pipe_context
*pipe
, void *hwcso
)
408 nv10_vp_state_create(struct pipe_context
*pipe
,
409 const struct pipe_shader_state
*cso
)
411 struct nv10_vertex_program
*vp
;
413 vp
= CALLOC(1, sizeof(struct nv10_vertex_program
));
420 nv10_vp_state_bind(struct pipe_context
*pipe
, void *hwcso
)
422 struct nv10_context
*nv10
= nv10_context(pipe
);
423 struct nv10_vertex_program
*vp
= hwcso
;
425 nv10
->vertprog
.current
= vp
;
426 nv10
->dirty
|= NV10_NEW_VERTPROG
;
430 nv10_vp_state_delete(struct pipe_context
*pipe
, void *hwcso
)
432 //struct nv10_context *nv10 = nv10_context(pipe);
433 struct nv10_vertex_program
*vp
= hwcso
;
435 //nv10_vertprog_destroy(nv10, vp);
440 nv10_fp_state_create(struct pipe_context
*pipe
,
441 const struct pipe_shader_state
*cso
)
443 struct nv10_fragment_program
*fp
;
445 fp
= CALLOC(1, sizeof(struct nv10_fragment_program
));
448 tgsi_scan_shader(cso
->tokens
, &fp
->info
);
454 nv10_fp_state_bind(struct pipe_context
*pipe
, void *hwcso
)
456 struct nv10_context
*nv10
= nv10_context(pipe
);
457 struct nv10_fragment_program
*fp
= hwcso
;
459 nv10
->fragprog
.current
= fp
;
460 nv10
->dirty
|= NV10_NEW_FRAGPROG
;
464 nv10_fp_state_delete(struct pipe_context
*pipe
, void *hwcso
)
466 struct nv10_context
*nv10
= nv10_context(pipe
);
467 struct nv10_fragment_program
*fp
= hwcso
;
469 nv10_fragprog_destroy(nv10
, fp
);
474 nv10_set_blend_color(struct pipe_context
*pipe
,
475 const struct pipe_blend_color
*bcol
)
477 struct nv10_context
*nv10
= nv10_context(pipe
);
479 nv10
->blend_color
= (struct pipe_blend_color
*)bcol
;
481 nv10
->dirty
|= NV10_NEW_BLENDCOL
;
485 nv10_set_clip_state(struct pipe_context
*pipe
,
486 const struct pipe_clip_state
*clip
)
491 nv10_set_constant_buffer(struct pipe_context
*pipe
, uint shader
, uint index
,
492 const struct pipe_constant_buffer
*buf
)
494 struct nv10_context
*nv10
= nv10_context(pipe
);
496 if (shader
== PIPE_SHADER_VERTEX
) {
497 nv10
->vertprog
.constant_buf
= buf
->buffer
;
498 nv10
->dirty
|= NV10_NEW_VERTPROG
;
500 if (shader
== PIPE_SHADER_FRAGMENT
) {
501 nv10
->fragprog
.constant_buf
= buf
->buffer
;
502 nv10
->dirty
|= NV10_NEW_FRAGPROG
;
507 nv10_set_framebuffer_state(struct pipe_context
*pipe
,
508 const struct pipe_framebuffer_state
*fb
)
510 struct nv10_context
*nv10
= nv10_context(pipe
);
512 nv10
->framebuffer
= (struct pipe_framebuffer_state
*)fb
;
514 nv10
->dirty
|= NV10_NEW_FRAMEBUFFER
;
518 nv10_set_polygon_stipple(struct pipe_context
*pipe
,
519 const struct pipe_poly_stipple
*stipple
)
521 NOUVEAU_ERR("line stipple hahaha\n");
525 nv10_set_scissor_state(struct pipe_context
*pipe
,
526 const struct pipe_scissor_state
*s
)
528 struct nv10_context
*nv10
= nv10_context(pipe
);
530 nv10
->scissor
= (struct pipe_scissor_state
*)s
;
532 nv10
->dirty
|= NV10_NEW_SCISSOR
;
536 nv10_set_viewport_state(struct pipe_context
*pipe
,
537 const struct pipe_viewport_state
*vpt
)
539 struct nv10_context
*nv10
= nv10_context(pipe
);
541 nv10
->viewport
= (struct pipe_viewport_state
*)vpt
;
543 nv10
->dirty
|= NV10_NEW_VIEWPORT
;
547 nv10_set_vertex_buffers(struct pipe_context
*pipe
, unsigned count
,
548 const struct pipe_vertex_buffer
*vb
)
550 struct nv10_context
*nv10
= nv10_context(pipe
);
552 memcpy(nv10
->vtxbuf
, vb
, sizeof(*vb
) * count
);
553 nv10
->dirty
|= NV10_NEW_ARRAYS
;
557 nv10_set_vertex_elements(struct pipe_context
*pipe
, unsigned count
,
558 const struct pipe_vertex_element
*ve
)
560 struct nv10_context
*nv10
= nv10_context(pipe
);
562 memcpy(nv10
->vtxelt
, ve
, sizeof(*ve
) * count
);
563 nv10
->dirty
|= NV10_NEW_ARRAYS
;
567 nv10_init_state_functions(struct nv10_context
*nv10
)
569 nv10
->pipe
.create_blend_state
= nv10_blend_state_create
;
570 nv10
->pipe
.bind_blend_state
= nv10_blend_state_bind
;
571 nv10
->pipe
.delete_blend_state
= nv10_blend_state_delete
;
573 nv10
->pipe
.create_sampler_state
= nv10_sampler_state_create
;
574 nv10
->pipe
.bind_sampler_states
= nv10_sampler_state_bind
;
575 nv10
->pipe
.delete_sampler_state
= nv10_sampler_state_delete
;
576 nv10
->pipe
.set_sampler_textures
= nv10_set_sampler_texture
;
578 nv10
->pipe
.create_rasterizer_state
= nv10_rasterizer_state_create
;
579 nv10
->pipe
.bind_rasterizer_state
= nv10_rasterizer_state_bind
;
580 nv10
->pipe
.delete_rasterizer_state
= nv10_rasterizer_state_delete
;
582 nv10
->pipe
.create_depth_stencil_alpha_state
=
583 nv10_depth_stencil_alpha_state_create
;
584 nv10
->pipe
.bind_depth_stencil_alpha_state
=
585 nv10_depth_stencil_alpha_state_bind
;
586 nv10
->pipe
.delete_depth_stencil_alpha_state
=
587 nv10_depth_stencil_alpha_state_delete
;
589 nv10
->pipe
.create_vs_state
= nv10_vp_state_create
;
590 nv10
->pipe
.bind_vs_state
= nv10_vp_state_bind
;
591 nv10
->pipe
.delete_vs_state
= nv10_vp_state_delete
;
593 nv10
->pipe
.create_fs_state
= nv10_fp_state_create
;
594 nv10
->pipe
.bind_fs_state
= nv10_fp_state_bind
;
595 nv10
->pipe
.delete_fs_state
= nv10_fp_state_delete
;
597 nv10
->pipe
.set_blend_color
= nv10_set_blend_color
;
598 nv10
->pipe
.set_clip_state
= nv10_set_clip_state
;
599 nv10
->pipe
.set_constant_buffer
= nv10_set_constant_buffer
;
600 nv10
->pipe
.set_framebuffer_state
= nv10_set_framebuffer_state
;
601 nv10
->pipe
.set_polygon_stipple
= nv10_set_polygon_stipple
;
602 nv10
->pipe
.set_scissor_state
= nv10_set_scissor_state
;
603 nv10
->pipe
.set_viewport_state
= nv10_set_viewport_state
;
605 nv10
->pipe
.set_vertex_buffers
= nv10_set_vertex_buffers
;
606 nv10
->pipe
.set_vertex_elements
= nv10_set_vertex_elements
;