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"
6 #include "tgsi/tgsi_parse.h"
8 #include "nv20_context.h"
9 #include "nv20_state.h"
12 nv20_blend_state_create(struct pipe_context
*pipe
,
13 const struct pipe_blend_state
*cso
)
15 struct nv20_blend_state
*cb
;
17 cb
= MALLOC(sizeof(struct nv20_blend_state
));
19 cb
->b_enable
= cso
->blend_enable
? 1 : 0;
20 cb
->b_srcfunc
= ((nvgl_blend_func(cso
->alpha_src_factor
)<<16) |
21 (nvgl_blend_func(cso
->rgb_src_factor
)));
22 cb
->b_dstfunc
= ((nvgl_blend_func(cso
->alpha_dst_factor
)<<16) |
23 (nvgl_blend_func(cso
->rgb_dst_factor
)));
25 cb
->c_mask
= (((cso
->colormask
& PIPE_MASK_A
) ? (0x01<<24) : 0) |
26 ((cso
->colormask
& PIPE_MASK_R
) ? (0x01<<16) : 0) |
27 ((cso
->colormask
& PIPE_MASK_G
) ? (0x01<< 8) : 0) |
28 ((cso
->colormask
& PIPE_MASK_B
) ? (0x01<< 0) : 0));
30 cb
->d_enable
= cso
->dither
? 1 : 0;
36 nv20_blend_state_bind(struct pipe_context
*pipe
, void *blend
)
38 struct nv20_context
*nv20
= nv20_context(pipe
);
40 nv20
->blend
= (struct nv20_blend_state
*)blend
;
42 nv20
->dirty
|= NV20_NEW_BLEND
;
46 nv20_blend_state_delete(struct pipe_context
*pipe
, void *hwcso
)
52 static INLINE
unsigned
53 wrap_mode(unsigned wrap
) {
57 case PIPE_TEX_WRAP_REPEAT
:
58 ret
= NV20TCL_TX_WRAP_S_REPEAT
;
60 case PIPE_TEX_WRAP_MIRROR_REPEAT
:
61 ret
= NV20TCL_TX_WRAP_S_MIRRORED_REPEAT
;
63 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
:
64 ret
= NV20TCL_TX_WRAP_S_CLAMP_TO_EDGE
;
66 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
:
67 ret
= NV20TCL_TX_WRAP_S_CLAMP_TO_BORDER
;
69 case PIPE_TEX_WRAP_CLAMP
:
70 ret
= NV20TCL_TX_WRAP_S_CLAMP
;
72 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE
:
73 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER
:
74 case PIPE_TEX_WRAP_MIRROR_CLAMP
:
76 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap
);
77 ret
= NV20TCL_TX_WRAP_S_REPEAT
;
81 return (ret
>> NV20TCL_TX_WRAP_S_SHIFT
);
85 nv20_sampler_state_create(struct pipe_context
*pipe
,
86 const struct pipe_sampler_state
*cso
)
88 struct nv20_sampler_state
*ps
;
91 ps
= MALLOC(sizeof(struct nv20_sampler_state
));
93 ps
->wrap
= ((wrap_mode(cso
->wrap_s
) << NV20TCL_TX_WRAP_S_SHIFT
) |
94 (wrap_mode(cso
->wrap_t
) << NV20TCL_TX_WRAP_T_SHIFT
));
97 if (cso
->max_anisotropy
> 1.0) {
98 /* no idea, binary driver sets it, works without it.. meh.. */
101 /* if (cso->max_anisotropy >= 8.0) {
102 ps->en |= NV20TCL_TX_ENABLE_ANISO_8X;
104 if (cso->max_anisotropy >= 4.0) {
105 ps->en |= NV20TCL_TX_ENABLE_ANISO_4X;
107 ps->en |= NV20TCL_TX_ENABLE_ANISO_2X;
111 switch (cso
->mag_img_filter
) {
112 case PIPE_TEX_FILTER_LINEAR
:
113 filter
|= NV20TCL_TX_FILTER_MAGNIFY_LINEAR
;
115 case PIPE_TEX_FILTER_NEAREST
:
117 filter
|= NV20TCL_TX_FILTER_MAGNIFY_NEAREST
;
121 switch (cso
->min_img_filter
) {
122 case PIPE_TEX_FILTER_LINEAR
:
123 switch (cso
->min_mip_filter
) {
124 case PIPE_TEX_MIPFILTER_NEAREST
:
126 NV20TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST
;
128 case PIPE_TEX_MIPFILTER_LINEAR
:
129 filter
|= NV20TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR
;
131 case PIPE_TEX_MIPFILTER_NONE
:
133 filter
|= NV20TCL_TX_FILTER_MINIFY_LINEAR
;
137 case PIPE_TEX_FILTER_NEAREST
:
139 switch (cso
->min_mip_filter
) {
140 case PIPE_TEX_MIPFILTER_NEAREST
:
142 NV20TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST
;
144 case PIPE_TEX_MIPFILTER_LINEAR
:
146 NV20TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR
;
148 case PIPE_TEX_MIPFILTER_NONE
:
150 filter
|= NV20TCL_TX_FILTER_MINIFY_NEAREST
;
158 /* if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
159 switch (cso->compare_func) {
160 case PIPE_FUNC_NEVER:
161 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NEVER;
163 case PIPE_FUNC_GREATER:
164 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GREATER;
166 case PIPE_FUNC_EQUAL:
167 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_EQUAL;
169 case PIPE_FUNC_GEQUAL:
170 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_GEQUAL;
173 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LESS;
175 case PIPE_FUNC_NOTEQUAL:
176 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_NOTEQUAL;
178 case PIPE_FUNC_LEQUAL:
179 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_LEQUAL;
181 case PIPE_FUNC_ALWAYS:
182 ps->wrap |= NV10TCL_TX_WRAP_RCOMP_ALWAYS;
189 ps
->bcol
= ((float_to_ubyte(cso
->border_color
[3]) << 24) |
190 (float_to_ubyte(cso
->border_color
[0]) << 16) |
191 (float_to_ubyte(cso
->border_color
[1]) << 8) |
192 (float_to_ubyte(cso
->border_color
[2]) << 0));
198 nv20_sampler_state_bind(struct pipe_context
*pipe
, unsigned nr
, void **sampler
)
200 struct nv20_context
*nv20
= nv20_context(pipe
);
203 for (unit
= 0; unit
< nr
; unit
++) {
204 nv20
->tex_sampler
[unit
] = sampler
[unit
];
205 nv20
->dirty_samplers
|= (1 << unit
);
210 nv20_sampler_state_delete(struct pipe_context
*pipe
, void *hwcso
)
216 nv20_set_sampler_texture(struct pipe_context
*pipe
, unsigned nr
,
217 struct pipe_texture
**miptree
)
219 struct nv20_context
*nv20
= nv20_context(pipe
);
222 for (unit
= 0; unit
< nr
; unit
++) {
223 nv20
->tex_miptree
[unit
] = (struct nv20_miptree
*)miptree
[unit
];
224 nv20
->dirty_samplers
|= (1 << unit
);
229 nv20_rasterizer_state_create(struct pipe_context
*pipe
,
230 const struct pipe_rasterizer_state
*cso
)
232 struct nv20_rasterizer_state
*rs
;
237 * offset_cw/ccw -nohw
241 * offset_units / offset_scale
243 rs
= MALLOC(sizeof(struct nv20_rasterizer_state
));
247 rs
->shade_model
= cso
->flatshade
? NV20TCL_SHADE_MODEL_FLAT
:
248 NV20TCL_SHADE_MODEL_SMOOTH
;
250 rs
->line_width
= (unsigned char)(cso
->line_width
* 8.0) & 0xff;
251 rs
->line_smooth_en
= cso
->line_smooth
? 1 : 0;
253 /* XXX: nv20 and nv25 different! */
254 rs
->point_size
= *(uint32_t*)&cso
->point_size
;
256 rs
->poly_smooth_en
= cso
->poly_smooth
? 1 : 0;
258 if (cso
->front_winding
== PIPE_WINDING_CCW
) {
259 rs
->front_face
= NV20TCL_FRONT_FACE_CCW
;
260 rs
->poly_mode_front
= nvgl_polygon_mode(cso
->fill_ccw
);
261 rs
->poly_mode_back
= nvgl_polygon_mode(cso
->fill_cw
);
263 rs
->front_face
= NV20TCL_FRONT_FACE_CW
;
264 rs
->poly_mode_front
= nvgl_polygon_mode(cso
->fill_cw
);
265 rs
->poly_mode_back
= nvgl_polygon_mode(cso
->fill_ccw
);
268 switch (cso
->cull_mode
) {
269 case PIPE_WINDING_CCW
:
270 rs
->cull_face_en
= 1;
271 if (cso
->front_winding
== PIPE_WINDING_CCW
)
272 rs
->cull_face
= NV20TCL_CULL_FACE_FRONT
;
274 rs
->cull_face
= NV20TCL_CULL_FACE_BACK
;
276 case PIPE_WINDING_CW
:
277 rs
->cull_face_en
= 1;
278 if (cso
->front_winding
== PIPE_WINDING_CW
)
279 rs
->cull_face
= NV20TCL_CULL_FACE_FRONT
;
281 rs
->cull_face
= NV20TCL_CULL_FACE_BACK
;
283 case PIPE_WINDING_BOTH
:
284 rs
->cull_face_en
= 1;
285 rs
->cull_face
= NV20TCL_CULL_FACE_FRONT_AND_BACK
;
287 case PIPE_WINDING_NONE
:
289 rs
->cull_face_en
= 0;
294 if (cso
->point_sprite
) {
295 rs
->point_sprite
= (1 << 0);
296 for (i
= 0; i
< 8; i
++) {
297 if (cso
->sprite_coord_mode
[i
] != PIPE_SPRITE_COORD_NONE
)
298 rs
->point_sprite
|= (1 << (8 + i
));
301 rs
->point_sprite
= 0;
308 nv20_rasterizer_state_bind(struct pipe_context
*pipe
, void *rast
)
310 struct nv20_context
*nv20
= nv20_context(pipe
);
312 nv20
->rast
= (struct nv20_rasterizer_state
*)rast
;
314 draw_set_rasterizer_state(nv20
->draw
, (nv20
->rast
? nv20
->rast
->templ
: NULL
));
316 nv20
->dirty
|= NV20_NEW_RAST
;
320 nv20_rasterizer_state_delete(struct pipe_context
*pipe
, void *hwcso
)
326 nv20_depth_stencil_alpha_state_create(struct pipe_context
*pipe
,
327 const struct pipe_depth_stencil_alpha_state
*cso
)
329 struct nv20_depth_stencil_alpha_state
*hw
;
331 hw
= MALLOC(sizeof(struct nv20_depth_stencil_alpha_state
));
333 hw
->depth
.func
= nvgl_comparison_op(cso
->depth
.func
);
334 hw
->depth
.write_enable
= cso
->depth
.writemask
? 1 : 0;
335 hw
->depth
.test_enable
= cso
->depth
.enabled
? 1 : 0;
337 hw
->stencil
.enable
= cso
->stencil
[0].enabled
? 1 : 0;
338 hw
->stencil
.wmask
= cso
->stencil
[0].write_mask
;
339 hw
->stencil
.func
= nvgl_comparison_op(cso
->stencil
[0].func
);
340 hw
->stencil
.ref
= cso
->stencil
[0].ref_value
;
341 hw
->stencil
.vmask
= cso
->stencil
[0].value_mask
;
342 hw
->stencil
.fail
= nvgl_stencil_op(cso
->stencil
[0].fail_op
);
343 hw
->stencil
.zfail
= nvgl_stencil_op(cso
->stencil
[0].zfail_op
);
344 hw
->stencil
.zpass
= nvgl_stencil_op(cso
->stencil
[0].zpass_op
);
346 hw
->alpha
.enabled
= cso
->alpha
.enabled
? 1 : 0;
347 hw
->alpha
.func
= nvgl_comparison_op(cso
->alpha
.func
);
348 hw
->alpha
.ref
= float_to_ubyte(cso
->alpha
.ref
);
354 nv20_depth_stencil_alpha_state_bind(struct pipe_context
*pipe
, void *dsa
)
356 struct nv20_context
*nv20
= nv20_context(pipe
);
358 nv20
->dsa
= (struct nv20_depth_stencil_alpha_state
*)dsa
;
360 nv20
->dirty
|= NV20_NEW_DSA
;
364 nv20_depth_stencil_alpha_state_delete(struct pipe_context
*pipe
, void *hwcso
)
370 nv20_vp_state_create(struct pipe_context
*pipe
,
371 const struct pipe_shader_state
*templ
)
373 struct nv20_context
*nv20
= nv20_context(pipe
);
375 return draw_create_vertex_shader(nv20
->draw
, templ
);
379 nv20_vp_state_bind(struct pipe_context
*pipe
, void *shader
)
381 struct nv20_context
*nv20
= nv20_context(pipe
);
383 draw_bind_vertex_shader(nv20
->draw
, (struct draw_vertex_shader
*) shader
);
385 nv20
->dirty
|= NV20_NEW_VERTPROG
;
389 nv20_vp_state_delete(struct pipe_context
*pipe
, void *shader
)
391 struct nv20_context
*nv20
= nv20_context(pipe
);
393 draw_delete_vertex_shader(nv20
->draw
, (struct draw_vertex_shader
*) shader
);
397 nv20_fp_state_create(struct pipe_context
*pipe
,
398 const struct pipe_shader_state
*cso
)
400 struct nv20_fragment_program
*fp
;
402 fp
= CALLOC(1, sizeof(struct nv20_fragment_program
));
403 fp
->pipe
.tokens
= tgsi_dup_tokens(cso
->tokens
);
405 tgsi_scan_shader(cso
->tokens
, &fp
->info
);
411 nv20_fp_state_bind(struct pipe_context
*pipe
, void *hwcso
)
413 struct nv20_context
*nv20
= nv20_context(pipe
);
414 struct nv20_fragment_program
*fp
= hwcso
;
416 nv20
->fragprog
.current
= fp
;
417 nv20
->dirty
|= NV20_NEW_FRAGPROG
;
421 nv20_fp_state_delete(struct pipe_context
*pipe
, void *hwcso
)
423 struct nv20_context
*nv20
= nv20_context(pipe
);
424 struct nv20_fragment_program
*fp
= hwcso
;
426 nv20_fragprog_destroy(nv20
, fp
);
427 FREE((void*)fp
->pipe
.tokens
);
432 nv20_set_blend_color(struct pipe_context
*pipe
,
433 const struct pipe_blend_color
*bcol
)
435 struct nv20_context
*nv20
= nv20_context(pipe
);
437 nv20
->blend_color
= (struct pipe_blend_color
*)bcol
;
439 nv20
->dirty
|= NV20_NEW_BLENDCOL
;
443 nv20_set_clip_state(struct pipe_context
*pipe
,
444 const struct pipe_clip_state
*clip
)
446 struct nv20_context
*nv20
= nv20_context(pipe
);
448 draw_set_clip_state(nv20
->draw
, clip
);
452 nv20_set_constant_buffer(struct pipe_context
*pipe
, uint shader
, uint index
,
453 const struct pipe_constant_buffer
*buf
)
455 struct nv20_context
*nv20
= nv20_context(pipe
);
456 struct pipe_winsys
*ws
= pipe
->winsys
;
458 assert(shader
< PIPE_SHADER_TYPES
);
463 if (buf
->size
&& (mapped
= ws
->buffer_map(ws
, buf
->buffer
, PIPE_BUFFER_USAGE_CPU_READ
)))
465 memcpy(nv20
->constbuf
[shader
], mapped
, buf
->size
);
466 nv20
->constbuf_nr
[shader
] =
467 buf
->size
/ (4 * sizeof(float));
468 ws
->buffer_unmap(ws
, buf
->buffer
);
474 nv20_set_framebuffer_state(struct pipe_context
*pipe
,
475 const struct pipe_framebuffer_state
*fb
)
477 struct nv20_context
*nv20
= nv20_context(pipe
);
479 nv20
->framebuffer
= (struct pipe_framebuffer_state
*)fb
;
481 nv20
->dirty
|= NV20_NEW_FRAMEBUFFER
;
485 nv20_set_polygon_stipple(struct pipe_context
*pipe
,
486 const struct pipe_poly_stipple
*stipple
)
488 NOUVEAU_ERR("line stipple hahaha\n");
492 nv20_set_scissor_state(struct pipe_context
*pipe
,
493 const struct pipe_scissor_state
*s
)
495 struct nv20_context
*nv20
= nv20_context(pipe
);
497 nv20
->scissor
= (struct pipe_scissor_state
*)s
;
499 nv20
->dirty
|= NV20_NEW_SCISSOR
;
503 nv20_set_viewport_state(struct pipe_context
*pipe
,
504 const struct pipe_viewport_state
*vpt
)
506 struct nv20_context
*nv20
= nv20_context(pipe
);
508 nv20
->viewport
= (struct pipe_viewport_state
*)vpt
;
510 draw_set_viewport_state(nv20
->draw
, nv20
->viewport
);
512 nv20
->dirty
|= NV20_NEW_VIEWPORT
;
516 nv20_set_vertex_buffers(struct pipe_context
*pipe
, unsigned count
,
517 const struct pipe_vertex_buffer
*vb
)
519 struct nv20_context
*nv20
= nv20_context(pipe
);
521 memcpy(nv20
->vtxbuf
, vb
, sizeof(*vb
) * count
);
522 nv20
->dirty
|= NV20_NEW_VTXARRAYS
;
524 draw_set_vertex_buffers(nv20
->draw
, count
, vb
);
528 nv20_set_vertex_elements(struct pipe_context
*pipe
, unsigned count
,
529 const struct pipe_vertex_element
*ve
)
531 struct nv20_context
*nv20
= nv20_context(pipe
);
533 memcpy(nv20
->vtxelt
, ve
, sizeof(*ve
) * count
);
534 nv20
->dirty
|= NV20_NEW_VTXARRAYS
;
536 draw_set_vertex_elements(nv20
->draw
, count
, ve
);
540 nv20_init_state_functions(struct nv20_context
*nv20
)
542 nv20
->pipe
.create_blend_state
= nv20_blend_state_create
;
543 nv20
->pipe
.bind_blend_state
= nv20_blend_state_bind
;
544 nv20
->pipe
.delete_blend_state
= nv20_blend_state_delete
;
546 nv20
->pipe
.create_sampler_state
= nv20_sampler_state_create
;
547 nv20
->pipe
.bind_sampler_states
= nv20_sampler_state_bind
;
548 nv20
->pipe
.delete_sampler_state
= nv20_sampler_state_delete
;
549 nv20
->pipe
.set_sampler_textures
= nv20_set_sampler_texture
;
551 nv20
->pipe
.create_rasterizer_state
= nv20_rasterizer_state_create
;
552 nv20
->pipe
.bind_rasterizer_state
= nv20_rasterizer_state_bind
;
553 nv20
->pipe
.delete_rasterizer_state
= nv20_rasterizer_state_delete
;
555 nv20
->pipe
.create_depth_stencil_alpha_state
=
556 nv20_depth_stencil_alpha_state_create
;
557 nv20
->pipe
.bind_depth_stencil_alpha_state
=
558 nv20_depth_stencil_alpha_state_bind
;
559 nv20
->pipe
.delete_depth_stencil_alpha_state
=
560 nv20_depth_stencil_alpha_state_delete
;
562 nv20
->pipe
.create_vs_state
= nv20_vp_state_create
;
563 nv20
->pipe
.bind_vs_state
= nv20_vp_state_bind
;
564 nv20
->pipe
.delete_vs_state
= nv20_vp_state_delete
;
566 nv20
->pipe
.create_fs_state
= nv20_fp_state_create
;
567 nv20
->pipe
.bind_fs_state
= nv20_fp_state_bind
;
568 nv20
->pipe
.delete_fs_state
= nv20_fp_state_delete
;
570 nv20
->pipe
.set_blend_color
= nv20_set_blend_color
;
571 nv20
->pipe
.set_clip_state
= nv20_set_clip_state
;
572 nv20
->pipe
.set_constant_buffer
= nv20_set_constant_buffer
;
573 nv20
->pipe
.set_framebuffer_state
= nv20_set_framebuffer_state
;
574 nv20
->pipe
.set_polygon_stipple
= nv20_set_polygon_stipple
;
575 nv20
->pipe
.set_scissor_state
= nv20_set_scissor_state
;
576 nv20
->pipe
.set_viewport_state
= nv20_set_viewport_state
;
578 nv20
->pipe
.set_vertex_buffers
= nv20_set_vertex_buffers
;
579 nv20
->pipe
.set_vertex_elements
= nv20_set_vertex_elements
;