1 #include "draw/draw_context.h"
2 #include "pipe/p_state.h"
3 #include "pipe/p_defines.h"
4 #include "pipe/p_shader_tokens.h"
5 #include "pipe/p_inlines.h"
7 #include "tgsi/tgsi_parse.h"
9 #include "nv20_context.h"
10 #include "nv20_state.h"
13 nv20_blend_state_create(struct pipe_context
*pipe
,
14 const struct pipe_blend_state
*cso
)
16 struct nv20_blend_state
*cb
;
18 cb
= MALLOC(sizeof(struct nv20_blend_state
));
20 cb
->b_enable
= cso
->blend_enable
? 1 : 0;
21 cb
->b_srcfunc
= ((nvgl_blend_func(cso
->alpha_src_factor
)<<16) |
22 (nvgl_blend_func(cso
->rgb_src_factor
)));
23 cb
->b_dstfunc
= ((nvgl_blend_func(cso
->alpha_dst_factor
)<<16) |
24 (nvgl_blend_func(cso
->rgb_dst_factor
)));
26 cb
->c_mask
= (((cso
->colormask
& PIPE_MASK_A
) ? (0x01<<24) : 0) |
27 ((cso
->colormask
& PIPE_MASK_R
) ? (0x01<<16) : 0) |
28 ((cso
->colormask
& PIPE_MASK_G
) ? (0x01<< 8) : 0) |
29 ((cso
->colormask
& PIPE_MASK_B
) ? (0x01<< 0) : 0));
31 cb
->d_enable
= cso
->dither
? 1 : 0;
37 nv20_blend_state_bind(struct pipe_context
*pipe
, void *blend
)
39 struct nv20_context
*nv20
= nv20_context(pipe
);
41 nv20
->blend
= (struct nv20_blend_state
*)blend
;
43 nv20
->dirty
|= NV20_NEW_BLEND
;
47 nv20_blend_state_delete(struct pipe_context
*pipe
, void *hwcso
)
53 static INLINE
unsigned
54 wrap_mode(unsigned wrap
) {
58 case PIPE_TEX_WRAP_REPEAT
:
59 ret
= NV20TCL_TX_WRAP_S_REPEAT
;
61 case PIPE_TEX_WRAP_MIRROR_REPEAT
:
62 ret
= NV20TCL_TX_WRAP_S_MIRRORED_REPEAT
;
64 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
:
65 ret
= NV20TCL_TX_WRAP_S_CLAMP_TO_EDGE
;
67 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
:
68 ret
= NV20TCL_TX_WRAP_S_CLAMP_TO_BORDER
;
70 case PIPE_TEX_WRAP_CLAMP
:
71 ret
= NV20TCL_TX_WRAP_S_CLAMP
;
73 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE
:
74 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER
:
75 case PIPE_TEX_WRAP_MIRROR_CLAMP
:
77 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap
);
78 ret
= NV20TCL_TX_WRAP_S_REPEAT
;
82 return (ret
>> NV20TCL_TX_WRAP_S_SHIFT
);
86 nv20_sampler_state_create(struct pipe_context
*pipe
,
87 const struct pipe_sampler_state
*cso
)
89 struct nv20_sampler_state
*ps
;
92 ps
= MALLOC(sizeof(struct nv20_sampler_state
));
94 ps
->wrap
= ((wrap_mode(cso
->wrap_s
) << NV20TCL_TX_WRAP_S_SHIFT
) |
95 (wrap_mode(cso
->wrap_t
) << NV20TCL_TX_WRAP_T_SHIFT
));
98 if (cso
->max_anisotropy
> 1.0) {
99 /* no idea, binary driver sets it, works without it.. meh.. */
100 ps
->wrap
|= (1 << 5);
102 /* if (cso->max_anisotropy >= 8.0) {
103 ps->en |= NV20TCL_TX_ENABLE_ANISO_8X;
105 if (cso->max_anisotropy >= 4.0) {
106 ps->en |= NV20TCL_TX_ENABLE_ANISO_4X;
108 ps->en |= NV20TCL_TX_ENABLE_ANISO_2X;
112 switch (cso
->mag_img_filter
) {
113 case PIPE_TEX_FILTER_LINEAR
:
114 filter
|= NV20TCL_TX_FILTER_MAGNIFY_LINEAR
;
116 case PIPE_TEX_FILTER_NEAREST
:
118 filter
|= NV20TCL_TX_FILTER_MAGNIFY_NEAREST
;
122 switch (cso
->min_img_filter
) {
123 case PIPE_TEX_FILTER_LINEAR
:
124 switch (cso
->min_mip_filter
) {
125 case PIPE_TEX_MIPFILTER_NEAREST
:
127 NV20TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST
;
129 case PIPE_TEX_MIPFILTER_LINEAR
:
130 filter
|= NV20TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR
;
132 case PIPE_TEX_MIPFILTER_NONE
:
134 filter
|= NV20TCL_TX_FILTER_MINIFY_LINEAR
;
138 case PIPE_TEX_FILTER_NEAREST
:
140 switch (cso
->min_mip_filter
) {
141 case PIPE_TEX_MIPFILTER_NEAREST
:
143 NV20TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST
;
145 case PIPE_TEX_MIPFILTER_LINEAR
:
147 NV20TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR
;
149 case PIPE_TEX_MIPFILTER_NONE
:
151 filter
|= NV20TCL_TX_FILTER_MINIFY_NEAREST
;
159 /* if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
160 switch (cso->compare_func) {
161 case PIPE_FUNC_NEVER:
162 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NEVER;
164 case PIPE_FUNC_GREATER:
165 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GREATER;
167 case PIPE_FUNC_EQUAL:
168 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_EQUAL;
170 case PIPE_FUNC_GEQUAL:
171 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GEQUAL;
174 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LESS;
176 case PIPE_FUNC_NOTEQUAL:
177 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NOTEQUAL;
179 case PIPE_FUNC_LEQUAL:
180 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LEQUAL;
182 case PIPE_FUNC_ALWAYS:
183 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_ALWAYS;
190 ps
->bcol
= ((float_to_ubyte(cso
->border_color
[3]) << 24) |
191 (float_to_ubyte(cso
->border_color
[0]) << 16) |
192 (float_to_ubyte(cso
->border_color
[1]) << 8) |
193 (float_to_ubyte(cso
->border_color
[2]) << 0));
199 nv20_sampler_state_bind(struct pipe_context
*pipe
, unsigned nr
, void **sampler
)
201 struct nv20_context
*nv20
= nv20_context(pipe
);
204 for (unit
= 0; unit
< nr
; unit
++) {
205 nv20
->tex_sampler
[unit
] = sampler
[unit
];
206 nv20
->dirty_samplers
|= (1 << unit
);
211 nv20_sampler_state_delete(struct pipe_context
*pipe
, void *hwcso
)
217 nv20_set_sampler_texture(struct pipe_context
*pipe
, unsigned nr
,
218 struct pipe_texture
**miptree
)
220 struct nv20_context
*nv20
= nv20_context(pipe
);
223 for (unit
= 0; unit
< nr
; unit
++) {
224 nv20
->tex_miptree
[unit
] = (struct nv20_miptree
*)miptree
[unit
];
225 nv20
->dirty_samplers
|= (1 << unit
);
230 nv20_rasterizer_state_create(struct pipe_context
*pipe
,
231 const struct pipe_rasterizer_state
*cso
)
233 struct nv20_rasterizer_state
*rs
;
238 * offset_cw/ccw -nohw
242 * offset_units / offset_scale
244 rs
= MALLOC(sizeof(struct nv20_rasterizer_state
));
248 rs
->shade_model
= cso
->flatshade
? NV20TCL_SHADE_MODEL_FLAT
:
249 NV20TCL_SHADE_MODEL_SMOOTH
;
251 rs
->line_width
= (unsigned char)(cso
->line_width
* 8.0) & 0xff;
252 rs
->line_smooth_en
= cso
->line_smooth
? 1 : 0;
254 /* XXX: nv20 and nv25 different! */
255 rs
->point_size
= *(uint32_t*)&cso
->point_size
;
257 rs
->poly_smooth_en
= cso
->poly_smooth
? 1 : 0;
259 if (cso
->front_winding
== PIPE_WINDING_CCW
) {
260 rs
->front_face
= NV20TCL_FRONT_FACE_CCW
;
261 rs
->poly_mode_front
= nvgl_polygon_mode(cso
->fill_ccw
);
262 rs
->poly_mode_back
= nvgl_polygon_mode(cso
->fill_cw
);
264 rs
->front_face
= NV20TCL_FRONT_FACE_CW
;
265 rs
->poly_mode_front
= nvgl_polygon_mode(cso
->fill_cw
);
266 rs
->poly_mode_back
= nvgl_polygon_mode(cso
->fill_ccw
);
269 switch (cso
->cull_mode
) {
270 case PIPE_WINDING_CCW
:
271 rs
->cull_face_en
= 1;
272 if (cso
->front_winding
== PIPE_WINDING_CCW
)
273 rs
->cull_face
= NV20TCL_CULL_FACE_FRONT
;
275 rs
->cull_face
= NV20TCL_CULL_FACE_BACK
;
277 case PIPE_WINDING_CW
:
278 rs
->cull_face_en
= 1;
279 if (cso
->front_winding
== PIPE_WINDING_CW
)
280 rs
->cull_face
= NV20TCL_CULL_FACE_FRONT
;
282 rs
->cull_face
= NV20TCL_CULL_FACE_BACK
;
284 case PIPE_WINDING_BOTH
:
285 rs
->cull_face_en
= 1;
286 rs
->cull_face
= NV20TCL_CULL_FACE_FRONT_AND_BACK
;
288 case PIPE_WINDING_NONE
:
290 rs
->cull_face_en
= 0;
295 if (cso
->point_sprite
) {
296 rs
->point_sprite
= (1 << 0);
297 for (i
= 0; i
< 8; i
++) {
298 if (cso
->sprite_coord_mode
[i
] != PIPE_SPRITE_COORD_NONE
)
299 rs
->point_sprite
|= (1 << (8 + i
));
302 rs
->point_sprite
= 0;
309 nv20_rasterizer_state_bind(struct pipe_context
*pipe
, void *rast
)
311 struct nv20_context
*nv20
= nv20_context(pipe
);
313 nv20
->rast
= (struct nv20_rasterizer_state
*)rast
;
315 draw_set_rasterizer_state(nv20
->draw
, (nv20
->rast
? nv20
->rast
->templ
: NULL
));
317 nv20
->dirty
|= NV20_NEW_RAST
;
321 nv20_rasterizer_state_delete(struct pipe_context
*pipe
, void *hwcso
)
327 nv20_depth_stencil_alpha_state_create(struct pipe_context
*pipe
,
328 const struct pipe_depth_stencil_alpha_state
*cso
)
330 struct nv20_depth_stencil_alpha_state
*hw
;
332 hw
= MALLOC(sizeof(struct nv20_depth_stencil_alpha_state
));
334 hw
->depth
.func
= nvgl_comparison_op(cso
->depth
.func
);
335 hw
->depth
.write_enable
= cso
->depth
.writemask
? 1 : 0;
336 hw
->depth
.test_enable
= cso
->depth
.enabled
? 1 : 0;
338 hw
->stencil
.enable
= cso
->stencil
[0].enabled
? 1 : 0;
339 hw
->stencil
.wmask
= cso
->stencil
[0].writemask
;
340 hw
->stencil
.func
= nvgl_comparison_op(cso
->stencil
[0].func
);
341 hw
->stencil
.ref
= cso
->stencil
[0].ref_value
;
342 hw
->stencil
.vmask
= cso
->stencil
[0].valuemask
;
343 hw
->stencil
.fail
= nvgl_stencil_op(cso
->stencil
[0].fail_op
);
344 hw
->stencil
.zfail
= nvgl_stencil_op(cso
->stencil
[0].zfail_op
);
345 hw
->stencil
.zpass
= nvgl_stencil_op(cso
->stencil
[0].zpass_op
);
347 hw
->alpha
.enabled
= cso
->alpha
.enabled
? 1 : 0;
348 hw
->alpha
.func
= nvgl_comparison_op(cso
->alpha
.func
);
349 hw
->alpha
.ref
= float_to_ubyte(cso
->alpha
.ref_value
);
355 nv20_depth_stencil_alpha_state_bind(struct pipe_context
*pipe
, void *dsa
)
357 struct nv20_context
*nv20
= nv20_context(pipe
);
359 nv20
->dsa
= (struct nv20_depth_stencil_alpha_state
*)dsa
;
361 nv20
->dirty
|= NV20_NEW_DSA
;
365 nv20_depth_stencil_alpha_state_delete(struct pipe_context
*pipe
, void *hwcso
)
371 nv20_vp_state_create(struct pipe_context
*pipe
,
372 const struct pipe_shader_state
*templ
)
374 struct nv20_context
*nv20
= nv20_context(pipe
);
376 return draw_create_vertex_shader(nv20
->draw
, templ
);
380 nv20_vp_state_bind(struct pipe_context
*pipe
, void *shader
)
382 struct nv20_context
*nv20
= nv20_context(pipe
);
384 draw_bind_vertex_shader(nv20
->draw
, (struct draw_vertex_shader
*) shader
);
386 nv20
->dirty
|= NV20_NEW_VERTPROG
;
390 nv20_vp_state_delete(struct pipe_context
*pipe
, void *shader
)
392 struct nv20_context
*nv20
= nv20_context(pipe
);
394 draw_delete_vertex_shader(nv20
->draw
, (struct draw_vertex_shader
*) shader
);
398 nv20_fp_state_create(struct pipe_context
*pipe
,
399 const struct pipe_shader_state
*cso
)
401 struct nv20_fragment_program
*fp
;
403 fp
= CALLOC(1, sizeof(struct nv20_fragment_program
));
404 fp
->pipe
.tokens
= tgsi_dup_tokens(cso
->tokens
);
406 tgsi_scan_shader(cso
->tokens
, &fp
->info
);
412 nv20_fp_state_bind(struct pipe_context
*pipe
, void *hwcso
)
414 struct nv20_context
*nv20
= nv20_context(pipe
);
415 struct nv20_fragment_program
*fp
= hwcso
;
417 nv20
->fragprog
.current
= fp
;
418 nv20
->dirty
|= NV20_NEW_FRAGPROG
;
422 nv20_fp_state_delete(struct pipe_context
*pipe
, void *hwcso
)
424 struct nv20_context
*nv20
= nv20_context(pipe
);
425 struct nv20_fragment_program
*fp
= hwcso
;
427 nv20_fragprog_destroy(nv20
, fp
);
428 FREE((void*)fp
->pipe
.tokens
);
433 nv20_set_blend_color(struct pipe_context
*pipe
,
434 const struct pipe_blend_color
*bcol
)
436 struct nv20_context
*nv20
= nv20_context(pipe
);
438 nv20
->blend_color
= (struct pipe_blend_color
*)bcol
;
440 nv20
->dirty
|= NV20_NEW_BLENDCOL
;
444 nv20_set_clip_state(struct pipe_context
*pipe
,
445 const struct pipe_clip_state
*clip
)
447 struct nv20_context
*nv20
= nv20_context(pipe
);
449 draw_set_clip_state(nv20
->draw
, clip
);
453 nv20_set_constant_buffer(struct pipe_context
*pipe
, uint shader
, uint index
,
454 const struct pipe_constant_buffer
*buf
)
456 struct nv20_context
*nv20
= nv20_context(pipe
);
457 struct pipe_screen
*pscreen
= pipe
->screen
;
459 assert(shader
< PIPE_SHADER_TYPES
);
464 if (buf
->buffer
&& buf
->buffer
->size
&&
465 (mapped
= pipe_buffer_map(pscreen
, buf
->buffer
, PIPE_BUFFER_USAGE_CPU_READ
)))
467 memcpy(nv20
->constbuf
[shader
], mapped
, buf
->buffer
->size
);
468 nv20
->constbuf_nr
[shader
] =
469 buf
->buffer
->size
/ (4 * sizeof(float));
470 pipe_buffer_unmap(pscreen
, buf
->buffer
);
476 nv20_set_framebuffer_state(struct pipe_context
*pipe
,
477 const struct pipe_framebuffer_state
*fb
)
479 struct nv20_context
*nv20
= nv20_context(pipe
);
481 nv20
->framebuffer
= (struct pipe_framebuffer_state
*)fb
;
483 nv20
->dirty
|= NV20_NEW_FRAMEBUFFER
;
487 nv20_set_polygon_stipple(struct pipe_context
*pipe
,
488 const struct pipe_poly_stipple
*stipple
)
490 NOUVEAU_ERR("line stipple hahaha\n");
494 nv20_set_scissor_state(struct pipe_context
*pipe
,
495 const struct pipe_scissor_state
*s
)
497 struct nv20_context
*nv20
= nv20_context(pipe
);
499 nv20
->scissor
= (struct pipe_scissor_state
*)s
;
501 nv20
->dirty
|= NV20_NEW_SCISSOR
;
505 nv20_set_viewport_state(struct pipe_context
*pipe
,
506 const struct pipe_viewport_state
*vpt
)
508 struct nv20_context
*nv20
= nv20_context(pipe
);
510 nv20
->viewport
= (struct pipe_viewport_state
*)vpt
;
512 draw_set_viewport_state(nv20
->draw
, nv20
->viewport
);
514 nv20
->dirty
|= NV20_NEW_VIEWPORT
;
518 nv20_set_vertex_buffers(struct pipe_context
*pipe
, unsigned count
,
519 const struct pipe_vertex_buffer
*vb
)
521 struct nv20_context
*nv20
= nv20_context(pipe
);
523 memcpy(nv20
->vtxbuf
, vb
, sizeof(*vb
) * count
);
524 nv20
->dirty
|= NV20_NEW_VTXARRAYS
;
526 draw_set_vertex_buffers(nv20
->draw
, count
, vb
);
530 nv20_set_vertex_elements(struct pipe_context
*pipe
, unsigned count
,
531 const struct pipe_vertex_element
*ve
)
533 struct nv20_context
*nv20
= nv20_context(pipe
);
535 memcpy(nv20
->vtxelt
, ve
, sizeof(*ve
) * count
);
536 nv20
->dirty
|= NV20_NEW_VTXARRAYS
;
538 draw_set_vertex_elements(nv20
->draw
, count
, ve
);
542 nv20_init_state_functions(struct nv20_context
*nv20
)
544 nv20
->pipe
.create_blend_state
= nv20_blend_state_create
;
545 nv20
->pipe
.bind_blend_state
= nv20_blend_state_bind
;
546 nv20
->pipe
.delete_blend_state
= nv20_blend_state_delete
;
548 nv20
->pipe
.create_sampler_state
= nv20_sampler_state_create
;
549 nv20
->pipe
.bind_sampler_states
= nv20_sampler_state_bind
;
550 nv20
->pipe
.delete_sampler_state
= nv20_sampler_state_delete
;
551 nv20
->pipe
.set_sampler_textures
= nv20_set_sampler_texture
;
553 nv20
->pipe
.create_rasterizer_state
= nv20_rasterizer_state_create
;
554 nv20
->pipe
.bind_rasterizer_state
= nv20_rasterizer_state_bind
;
555 nv20
->pipe
.delete_rasterizer_state
= nv20_rasterizer_state_delete
;
557 nv20
->pipe
.create_depth_stencil_alpha_state
=
558 nv20_depth_stencil_alpha_state_create
;
559 nv20
->pipe
.bind_depth_stencil_alpha_state
=
560 nv20_depth_stencil_alpha_state_bind
;
561 nv20
->pipe
.delete_depth_stencil_alpha_state
=
562 nv20_depth_stencil_alpha_state_delete
;
564 nv20
->pipe
.create_vs_state
= nv20_vp_state_create
;
565 nv20
->pipe
.bind_vs_state
= nv20_vp_state_bind
;
566 nv20
->pipe
.delete_vs_state
= nv20_vp_state_delete
;
568 nv20
->pipe
.create_fs_state
= nv20_fp_state_create
;
569 nv20
->pipe
.bind_fs_state
= nv20_fp_state_bind
;
570 nv20
->pipe
.delete_fs_state
= nv20_fp_state_delete
;
572 nv20
->pipe
.set_blend_color
= nv20_set_blend_color
;
573 nv20
->pipe
.set_clip_state
= nv20_set_clip_state
;
574 nv20
->pipe
.set_constant_buffer
= nv20_set_constant_buffer
;
575 nv20
->pipe
.set_framebuffer_state
= nv20_set_framebuffer_state
;
576 nv20
->pipe
.set_polygon_stipple
= nv20_set_polygon_stipple
;
577 nv20
->pipe
.set_scissor_state
= nv20_set_scissor_state
;
578 nv20
->pipe
.set_viewport_state
= nv20_set_viewport_state
;
580 nv20
->pipe
.set_vertex_buffers
= nv20_set_vertex_buffers
;
581 nv20
->pipe
.set_vertex_elements
= nv20_set_vertex_elements
;