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 "nv04_context.h"
9 #include "nv04_state.h"
12 nv04_blend_state_create(struct pipe_context
*pipe
,
13 const struct pipe_blend_state
*cso
)
15 struct nv04_blend_state
*cb
;
17 cb
= MALLOC(sizeof(struct nv04_blend_state
));
19 cb
->b_enable
= cso
->blend_enable
? 1 : 0;
20 cb
->b_src
= ((nvgl_blend_func(cso
->alpha_src_factor
)<<16) |
21 (nvgl_blend_func(cso
->rgb_src_factor
)));
22 cb
->b_dst
= ((nvgl_blend_func(cso
->alpha_dst_factor
)<<16) |
23 (nvgl_blend_func(cso
->rgb_dst_factor
)));
30 nv04_blend_state_bind(struct pipe_context
*pipe
, void *blend
)
32 struct nv04_context
*nv04
= nv04_context(pipe
);
34 nv04
->blend
= (struct nv04_blend_state
*)blend
;
36 nv04
->dirty
|= NV04_NEW_BLEND
;
40 nv04_blend_state_delete(struct pipe_context
*pipe
, void *hwcso
)
46 static INLINE
unsigned
47 wrap_mode(unsigned wrap
) {
51 case PIPE_TEX_WRAP_REPEAT
:
52 ret
= NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT
;
54 case PIPE_TEX_WRAP_MIRROR_REPEAT
:
55 ret
= NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_MIRRORED_REPEAT
;
57 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
:
58 ret
= NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE
;
60 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
:
61 ret
= NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_BORDER
;
63 case PIPE_TEX_WRAP_CLAMP
:
64 ret
= NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP
;
66 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE
:
67 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER
:
68 case PIPE_TEX_WRAP_MIRROR_CLAMP
:
70 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap
);
71 ret
= NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP
;
73 return ret
>> NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT
;
77 nv04_sampler_state_create(struct pipe_context
*pipe
,
78 const struct pipe_sampler_state
*cso
)
81 struct nv04_sampler_state
*ss
;
84 ss
= MALLOC(sizeof(struct nv04_sampler_state
));
86 ss
->format
= ((wrap_mode(cso
->wrap_s
) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT
) |
87 (wrap_mode(cso
->wrap_t
) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_SHIFT
));
89 if (cso
->max_anisotropy
> 1.0) {
90 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MINIFY_ENABLE
| NV04_DX5_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MAGNIFY_ENABLE
;
93 switch (cso
->mag_img_filter
) {
94 case PIPE_TEX_FILTER_LINEAR
:
95 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_LINEAR
;
97 case PIPE_TEX_FILTER_NEAREST
:
99 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST
;
103 switch (cso
->min_img_filter
) {
104 case PIPE_TEX_FILTER_LINEAR
:
105 switch (cso
->min_mip_filter
) {
106 case PIPE_TEX_MIPFILTER_NEAREST
:
107 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST
;
109 case PIPE_TEX_MIPFILTER_LINEAR
:
110 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR
;
112 case PIPE_TEX_MIPFILTER_NONE
:
114 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR
;
118 case PIPE_TEX_FILTER_NEAREST
:
120 switch (cso
->min_mip_filter
) {
121 case PIPE_TEX_MIPFILTER_NEAREST
:
122 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST
;
124 case PIPE_TEX_MIPFILTER_LINEAR
:
125 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR
;
127 case PIPE_TEX_MIPFILTER_NONE
:
129 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST
;
141 nv04_sampler_state_bind(struct pipe_context
*pipe
, unsigned nr
, void **sampler
)
143 struct nv04_context
*nv04
= nv04_context(pipe
);
146 for (unit
= 0; unit
< nr
; unit
++) {
147 nv04
->sampler
[unit
] = sampler
[unit
];
148 nv04
->dirty_samplers
|= (1 << unit
);
153 nv04_sampler_state_delete(struct pipe_context
*pipe
, void *hwcso
)
159 nv04_set_sampler_texture(struct pipe_context
*pipe
, unsigned nr
,
160 struct pipe_texture
**miptree
)
162 struct nv04_context
*nv04
= nv04_context(pipe
);
165 for (unit
= 0; unit
< nr
; unit
++) {
166 nv04
->tex_miptree
[unit
] = (struct nv04_miptree
*)miptree
[unit
];
167 nv04
->dirty_samplers
|= (1 << unit
);
172 nv04_rasterizer_state_create(struct pipe_context
*pipe
,
173 const struct pipe_rasterizer_state
*cso
)
175 struct nv04_rasterizer_state
*rs
;
179 * points/lines (no hw support, emulated with tris in gallium)
181 rs
= MALLOC(sizeof(struct nv04_rasterizer_state
));
183 rs
->blend
= cso
->flatshade
? NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT
: NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD
;
189 nv04_rasterizer_state_bind(struct pipe_context
*pipe
, void *rast
)
191 struct nv04_context
*nv04
= nv04_context(pipe
);
193 nv04
->rast
= (struct nv04_rasterizer_state
*)rast
;
195 draw_set_rasterizer_state(nv04
->draw
, (nv04
->rast
? nv04
->rast
->templ
: NULL
));
197 nv04
->dirty
|= NV04_NEW_RAST
| NV04_NEW_BLEND
;
201 nv04_rasterizer_state_delete(struct pipe_context
*pipe
, void *hwcso
)
206 static INLINE
uint32_t nv04_compare_func(uint32_t f
)
209 case PIPE_FUNC_NEVER
: return 1;
210 case PIPE_FUNC_LESS
: return 2;
211 case PIPE_FUNC_EQUAL
: return 3;
212 case PIPE_FUNC_LEQUAL
: return 4;
213 case PIPE_FUNC_GREATER
: return 5;
214 case PIPE_FUNC_NOTEQUAL
: return 6;
215 case PIPE_FUNC_GEQUAL
: return 7;
216 case PIPE_FUNC_ALWAYS
: return 8;
218 NOUVEAU_MSG("Unable to find the function\n");
223 nv04_depth_stencil_alpha_state_create(struct pipe_context
*pipe
,
224 const struct pipe_depth_stencil_alpha_state
*cso
)
226 struct nv04_depth_stencil_alpha_state
*hw
;
228 hw
= MALLOC(sizeof(struct nv04_depth_stencil_alpha_state
));
230 hw
->control
= float_to_ubyte(cso
->alpha
.ref
);
231 hw
->control
|= ( nv04_compare_func(cso
->alpha
.func
) << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_FUNC_SHIFT
);
232 hw
->control
|= cso
->alpha
.enabled
? NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_TEST_ENABLE
: 0;
233 hw
->control
|= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ORIGIN
;
234 hw
->control
|= cso
->depth
.enabled
? (1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE_SHIFT
) : 0;
235 hw
->control
|= ( nv04_compare_func(cso
->depth
.func
)<< NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FUNC_SHIFT
);
236 hw
->control
|= 1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_SHIFT
; // no culling, handled by the draw module
237 hw
->control
|= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE
;
238 hw
->control
|= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_PERSPECTIVE_ENABLE
;
239 hw
->control
|= cso
->depth
.writemask
? (1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_WRITE_ENABLE_SHIFT
) : 0;
240 hw
->control
|= 1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_SHIFT
; // integer zbuffer format
246 nv04_depth_stencil_alpha_state_bind(struct pipe_context
*pipe
, void *hwcso
)
248 struct nv04_context
*nv04
= nv04_context(pipe
);
251 nv04
->dirty
|= NV04_NEW_CONTROL
;
255 nv04_depth_stencil_alpha_state_delete(struct pipe_context
*pipe
, void *hwcso
)
261 nv04_vp_state_create(struct pipe_context
*pipe
,
262 const struct pipe_shader_state
*templ
)
264 struct nv04_context
*nv04
= nv04_context(pipe
);
266 return draw_create_vertex_shader(nv04
->draw
, templ
);
270 nv04_vp_state_bind(struct pipe_context
*pipe
, void *shader
)
272 struct nv04_context
*nv04
= nv04_context(pipe
);
274 draw_bind_vertex_shader(nv04
->draw
, (struct draw_vertex_shader
*) shader
);
276 nv04
->dirty
|= NV04_NEW_VERTPROG
;
280 nv04_vp_state_delete(struct pipe_context
*pipe
, void *shader
)
282 struct nv04_context
*nv04
= nv04_context(pipe
);
284 draw_delete_vertex_shader(nv04
->draw
, (struct draw_vertex_shader
*) shader
);
288 nv04_fp_state_create(struct pipe_context
*pipe
,
289 const struct pipe_shader_state
*cso
)
291 struct nv04_fragment_program
*fp
;
293 fp
= CALLOC(1, sizeof(struct nv04_fragment_program
));
294 fp
->pipe
.tokens
= tgsi_dup_tokens(cso
->tokens
);
300 nv04_fp_state_bind(struct pipe_context
*pipe
, void *hwcso
)
302 struct nv04_context
*nv04
= nv04_context(pipe
);
303 struct nv04_fragment_program
*fp
= hwcso
;
305 nv04
->fragprog
.current
= fp
;
306 nv04
->dirty
|= NV04_NEW_FRAGPROG
;
310 nv04_fp_state_delete(struct pipe_context
*pipe
, void *hwcso
)
312 struct nv04_context
*nv04
= nv04_context(pipe
);
313 struct nv04_fragment_program
*fp
= hwcso
;
315 nv04_fragprog_destroy(nv04
, fp
);
316 free((void*)fp
->pipe
.tokens
);
321 nv04_set_blend_color(struct pipe_context
*pipe
,
322 const struct pipe_blend_color
*bcol
)
327 nv04_set_clip_state(struct pipe_context
*pipe
,
328 const struct pipe_clip_state
*clip
)
333 nv04_set_constant_buffer(struct pipe_context
*pipe
, uint shader
, uint index
,
334 const struct pipe_constant_buffer
*buf
)
336 struct nv04_context
*nv04
= nv04_context(pipe
);
338 if (shader
== PIPE_SHADER_VERTEX
) {
339 nv04
->vertprog
.constant_buf
= buf
->buffer
;
340 nv04
->dirty
|= NV04_NEW_VERTPROG
;
342 if (shader
== PIPE_SHADER_FRAGMENT
) {
343 nv04
->fragprog
.constant_buf
= buf
->buffer
;
344 nv04
->dirty
|= NV04_NEW_FRAGPROG
;
349 nv04_set_framebuffer_state(struct pipe_context
*pipe
,
350 const struct pipe_framebuffer_state
*fb
)
352 struct nv04_context
*nv04
= nv04_context(pipe
);
353 struct pipe_surface
*rt
, *zeta
;
354 uint32_t rt_format
, w
, h
;
355 int colour_format
= 0, zeta_format
= 0;
357 w
= fb
->cbufs
[0]->width
;
358 h
= fb
->cbufs
[0]->height
;
359 colour_format
= fb
->cbufs
[0]->format
;
364 assert(w
== fb
->zsbuf
->width
);
365 assert(h
== fb
->zsbuf
->height
);
367 w
= fb
->zsbuf
->width
;
368 h
= fb
->zsbuf
->height
;
371 zeta_format
= fb
->zsbuf
->format
;
375 switch (colour_format
) {
376 case PIPE_FORMAT_A8R8G8B8_UNORM
:
380 case PIPE_FORMAT_R5G6B5_UNORM
:
387 BEGIN_RING(context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_FORMAT
, 1);
390 /* FIXME pitches have to be aligned ! */
391 BEGIN_RING(context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_PITCH
, 2);
392 OUT_RING(rt
->stride
|(zeta
->stride
<<16));
393 OUT_RELOCl(rt
->buffer
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
395 BEGIN_RING(context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA
, 1);
396 OUT_RELOCl(zeta
->buffer
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
401 nv04_set_polygon_stipple(struct pipe_context
*pipe
,
402 const struct pipe_poly_stipple
*stipple
)
404 NOUVEAU_ERR("line stipple hahaha\n");
408 nv04_set_scissor_state(struct pipe_context
*pipe
,
409 const struct pipe_scissor_state
*s
)
411 /* struct nv04_context *nv04 = nv04_context(pipe);
414 BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_SCISSOR_HORIZ, 2);
415 OUT_RING (((s->maxx - s->minx) << 16) | s->minx);
416 OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/
420 nv04_set_viewport_state(struct pipe_context
*pipe
,
421 const struct pipe_viewport_state
*viewport
)
423 struct nv04_context
*nv04
= nv04_context(pipe
);
425 nv04
->viewport
= *viewport
;
427 draw_set_viewport_state(nv04
->draw
, &nv04
->viewport
);
431 nv04_set_vertex_buffers(struct pipe_context
*pipe
, unsigned count
,
432 const struct pipe_vertex_buffer
*buffers
)
434 struct nv04_context
*nv04
= nv04_context(pipe
);
436 draw_flush(nv04
->draw
);
438 memcpy(nv04
->vertex_buffer
, buffers
, count
* sizeof(buffers
[0]));
439 nv04
->num_vertex_buffers
= count
;
441 draw_set_vertex_buffers(nv04
->draw
, count
, buffers
);
445 nv04_set_vertex_elements(struct pipe_context
*pipe
, unsigned count
,
446 const struct pipe_vertex_element
*elements
)
448 struct nv04_context
*nv04
= nv04_context(pipe
);
450 draw_flush(nv04
->draw
);
452 nv04
->num_vertex_elements
= count
;
453 draw_set_vertex_elements(nv04
->draw
, count
, elements
);
457 nv04_init_state_functions(struct nv04_context
*nv04
)
459 nv04
->pipe
.create_blend_state
= nv04_blend_state_create
;
460 nv04
->pipe
.bind_blend_state
= nv04_blend_state_bind
;
461 nv04
->pipe
.delete_blend_state
= nv04_blend_state_delete
;
463 nv04
->pipe
.create_sampler_state
= nv04_sampler_state_create
;
464 nv04
->pipe
.bind_sampler_states
= nv04_sampler_state_bind
;
465 nv04
->pipe
.delete_sampler_state
= nv04_sampler_state_delete
;
466 nv04
->pipe
.set_sampler_textures
= nv04_set_sampler_texture
;
468 nv04
->pipe
.create_rasterizer_state
= nv04_rasterizer_state_create
;
469 nv04
->pipe
.bind_rasterizer_state
= nv04_rasterizer_state_bind
;
470 nv04
->pipe
.delete_rasterizer_state
= nv04_rasterizer_state_delete
;
472 nv04
->pipe
.create_depth_stencil_alpha_state
= nv04_depth_stencil_alpha_state_create
;
473 nv04
->pipe
.bind_depth_stencil_alpha_state
= nv04_depth_stencil_alpha_state_bind
;
474 nv04
->pipe
.delete_depth_stencil_alpha_state
= nv04_depth_stencil_alpha_state_delete
;
476 nv04
->pipe
.create_vs_state
= nv04_vp_state_create
;
477 nv04
->pipe
.bind_vs_state
= nv04_vp_state_bind
;
478 nv04
->pipe
.delete_vs_state
= nv04_vp_state_delete
;
480 nv04
->pipe
.create_fs_state
= nv04_fp_state_create
;
481 nv04
->pipe
.bind_fs_state
= nv04_fp_state_bind
;
482 nv04
->pipe
.delete_fs_state
= nv04_fp_state_delete
;
484 nv04
->pipe
.set_blend_color
= nv04_set_blend_color
;
485 nv04
->pipe
.set_clip_state
= nv04_set_clip_state
;
486 nv04
->pipe
.set_constant_buffer
= nv04_set_constant_buffer
;
487 nv04
->pipe
.set_framebuffer_state
= nv04_set_framebuffer_state
;
488 nv04
->pipe
.set_polygon_stipple
= nv04_set_polygon_stipple
;
489 nv04
->pipe
.set_scissor_state
= nv04_set_scissor_state
;
490 nv04
->pipe
.set_viewport_state
= nv04_set_viewport_state
;
492 nv04
->pipe
.set_vertex_buffers
= nv04_set_vertex_buffers
;
493 nv04
->pipe
.set_vertex_elements
= nv04_set_vertex_elements
;