1 #include "draw/draw_context.h"
2 #include "pipe/p_state.h"
3 #include "pipe/p_defines.h"
4 #include "pipe/p_util.h"
5 #include "pipe/p_shader_tokens.h"
7 #include "tgsi/tgsi_parse.h"
9 #include "nv04_context.h"
10 #include "nv04_state.h"
13 nv04_blend_state_create(struct pipe_context
*pipe
,
14 const struct pipe_blend_state
*cso
)
16 struct nv04_blend_state
*cb
;
18 cb
= MALLOC(sizeof(struct nv04_blend_state
));
20 cb
->b_enable
= cso
->blend_enable
? 1 : 0;
21 cb
->b_src
= ((nvgl_blend_func(cso
->alpha_src_factor
)<<16) |
22 (nvgl_blend_func(cso
->rgb_src_factor
)));
23 cb
->b_dst
= ((nvgl_blend_func(cso
->alpha_dst_factor
)<<16) |
24 (nvgl_blend_func(cso
->rgb_dst_factor
)));
31 nv04_blend_state_bind(struct pipe_context
*pipe
, void *blend
)
33 struct nv04_context
*nv04
= nv04_context(pipe
);
35 nv04
->blend
= (struct nv04_blend_state
*)blend
;
37 nv04
->dirty
|= NV04_NEW_BLEND
;
41 nv04_blend_state_delete(struct pipe_context
*pipe
, void *hwcso
)
47 static INLINE
unsigned
48 wrap_mode(unsigned wrap
) {
52 case PIPE_TEX_WRAP_REPEAT
:
53 ret
= NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT
;
55 case PIPE_TEX_WRAP_MIRROR_REPEAT
:
56 ret
= NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_MIRRORED_REPEAT
;
58 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
:
59 ret
= NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE
;
61 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
:
62 ret
= NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_BORDER
;
64 case PIPE_TEX_WRAP_CLAMP
:
65 ret
= NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP
;
67 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE
:
68 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER
:
69 case PIPE_TEX_WRAP_MIRROR_CLAMP
:
71 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap
);
72 ret
= NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP
;
74 return ret
>> NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT
;
78 nv04_sampler_state_create(struct pipe_context
*pipe
,
79 const struct pipe_sampler_state
*cso
)
82 struct nv04_sampler_state
*ss
;
85 ss
= MALLOC(sizeof(struct nv04_sampler_state
));
87 ss
->format
= ((wrap_mode(cso
->wrap_s
) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT
) |
88 (wrap_mode(cso
->wrap_t
) << NV04_DX5_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_SHIFT
));
90 if (cso
->max_anisotropy
> 1.0) {
91 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MINIFY_ENABLE
| NV04_DX5_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MAGNIFY_ENABLE
;
94 switch (cso
->mag_img_filter
) {
95 case PIPE_TEX_FILTER_LINEAR
:
96 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_LINEAR
;
98 case PIPE_TEX_FILTER_NEAREST
:
100 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MAGNIFY_NEAREST
;
104 switch (cso
->min_img_filter
) {
105 case PIPE_TEX_FILTER_LINEAR
:
106 switch (cso
->min_mip_filter
) {
107 case PIPE_TEX_MIPFILTER_NEAREST
:
108 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST
;
110 case PIPE_TEX_MIPFILTER_LINEAR
:
111 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR
;
113 case PIPE_TEX_MIPFILTER_NONE
:
115 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR
;
119 case PIPE_TEX_FILTER_NEAREST
:
121 switch (cso
->min_mip_filter
) {
122 case PIPE_TEX_MIPFILTER_NEAREST
:
123 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST
;
125 case PIPE_TEX_MIPFILTER_LINEAR
:
126 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR
;
128 case PIPE_TEX_MIPFILTER_NONE
:
130 filter
|= NV04_DX5_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST
;
142 nv04_sampler_state_bind(struct pipe_context
*pipe
, unsigned nr
, void **sampler
)
144 struct nv04_context
*nv04
= nv04_context(pipe
);
147 for (unit
= 0; unit
< nr
; unit
++) {
148 nv04
->sampler
[unit
] = sampler
[unit
];
149 nv04
->dirty_samplers
|= (1 << unit
);
154 nv04_sampler_state_delete(struct pipe_context
*pipe
, void *hwcso
)
160 nv04_set_sampler_texture(struct pipe_context
*pipe
, unsigned nr
,
161 struct pipe_texture
**miptree
)
163 struct nv04_context
*nv04
= nv04_context(pipe
);
166 for (unit
= 0; unit
< nr
; unit
++) {
167 nv04
->tex_miptree
[unit
] = (struct nv04_miptree
*)miptree
[unit
];
168 nv04
->dirty_samplers
|= (1 << unit
);
173 nv04_rasterizer_state_create(struct pipe_context
*pipe
,
174 const struct pipe_rasterizer_state
*cso
)
176 struct nv04_rasterizer_state
*rs
;
180 * points/lines (no hw support, emulated with tris in gallium)
182 rs
= MALLOC(sizeof(struct nv04_rasterizer_state
));
184 rs
->blend
= cso
->flatshade
? NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT
: NV04_DX5_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_GOURAUD
;
190 nv04_rasterizer_state_bind(struct pipe_context
*pipe
, void *rast
)
192 struct nv04_context
*nv04
= nv04_context(pipe
);
194 nv04
->rast
= (struct nv04_rasterizer_state
*)rast
;
196 draw_set_rasterizer_state(nv04
->draw
, (nv04
->rast
? nv04
->rast
->templ
: NULL
));
198 nv04
->dirty
|= NV04_NEW_RAST
| NV04_NEW_BLEND
;
202 nv04_rasterizer_state_delete(struct pipe_context
*pipe
, void *hwcso
)
207 static INLINE
uint32_t nv04_compare_func(uint32_t f
)
210 case PIPE_FUNC_NEVER
: return 1;
211 case PIPE_FUNC_LESS
: return 2;
212 case PIPE_FUNC_EQUAL
: return 3;
213 case PIPE_FUNC_LEQUAL
: return 4;
214 case PIPE_FUNC_GREATER
: return 5;
215 case PIPE_FUNC_NOTEQUAL
: return 6;
216 case PIPE_FUNC_GEQUAL
: return 7;
217 case PIPE_FUNC_ALWAYS
: return 8;
219 NOUVEAU_MSG("Unable to find the function\n");
224 nv04_depth_stencil_alpha_state_create(struct pipe_context
*pipe
,
225 const struct pipe_depth_stencil_alpha_state
*cso
)
227 struct nv04_depth_stencil_alpha_state
*hw
;
229 hw
= MALLOC(sizeof(struct nv04_depth_stencil_alpha_state
));
231 hw
->control
= float_to_ubyte(cso
->alpha
.ref
);
232 hw
->control
|= ( nv04_compare_func(cso
->alpha
.func
) << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_FUNC_SHIFT
);
233 hw
->control
|= cso
->alpha
.enabled
? NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ALPHA_TEST_ENABLE
: 0;
234 hw
->control
|= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_ORIGIN
;
235 hw
->control
|= cso
->depth
.enabled
? (1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE_SHIFT
) : 0;
236 hw
->control
|= ( nv04_compare_func(cso
->depth
.func
)<< NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FUNC_SHIFT
);
237 hw
->control
|= 1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_SHIFT
; // no culling, handled by the draw module
238 hw
->control
|= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE
;
239 hw
->control
|= NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_PERSPECTIVE_ENABLE
;
240 hw
->control
|= cso
->depth
.writemask
? (1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_WRITE_ENABLE_SHIFT
) : 0;
241 hw
->control
|= 1 << NV04_DX5_TEXTURED_TRIANGLE_CONTROL_Z_FORMAT_SHIFT
; // integer zbuffer format
247 nv04_depth_stencil_alpha_state_bind(struct pipe_context
*pipe
, void *hwcso
)
249 struct nv04_context
*nv04
= nv04_context(pipe
);
252 nv04
->dirty
|= NV04_NEW_CONTROL
;
256 nv04_depth_stencil_alpha_state_delete(struct pipe_context
*pipe
, void *hwcso
)
262 nv04_vp_state_create(struct pipe_context
*pipe
,
263 const struct pipe_shader_state
*templ
)
265 struct nv04_context
*nv04
= nv04_context(pipe
);
267 return draw_create_vertex_shader(nv04
->draw
, templ
);
271 nv04_vp_state_bind(struct pipe_context
*pipe
, void *shader
)
273 struct nv04_context
*nv04
= nv04_context(pipe
);
275 draw_bind_vertex_shader(nv04
->draw
, (struct draw_vertex_shader
*) shader
);
277 nv04
->dirty
|= NV04_NEW_VERTPROG
;
281 nv04_vp_state_delete(struct pipe_context
*pipe
, void *shader
)
283 struct nv04_context
*nv04
= nv04_context(pipe
);
285 draw_delete_vertex_shader(nv04
->draw
, (struct draw_vertex_shader
*) shader
);
289 nv04_fp_state_create(struct pipe_context
*pipe
,
290 const struct pipe_shader_state
*cso
)
292 struct nv04_fragment_program
*fp
;
294 fp
= CALLOC(1, sizeof(struct nv04_fragment_program
));
295 fp
->pipe
.tokens
= tgsi_dup_tokens(cso
->tokens
);
301 nv04_fp_state_bind(struct pipe_context
*pipe
, void *hwcso
)
303 struct nv04_context
*nv04
= nv04_context(pipe
);
304 struct nv04_fragment_program
*fp
= hwcso
;
306 nv04
->fragprog
.current
= fp
;
307 nv04
->dirty
|= NV04_NEW_FRAGPROG
;
311 nv04_fp_state_delete(struct pipe_context
*pipe
, void *hwcso
)
313 struct nv04_context
*nv04
= nv04_context(pipe
);
314 struct nv04_fragment_program
*fp
= hwcso
;
316 nv04_fragprog_destroy(nv04
, fp
);
317 free((void*)fp
->pipe
.tokens
);
322 nv04_set_blend_color(struct pipe_context
*pipe
,
323 const struct pipe_blend_color
*bcol
)
328 nv04_set_clip_state(struct pipe_context
*pipe
,
329 const struct pipe_clip_state
*clip
)
334 nv04_set_constant_buffer(struct pipe_context
*pipe
, uint shader
, uint index
,
335 const struct pipe_constant_buffer
*buf
)
337 struct nv04_context
*nv04
= nv04_context(pipe
);
339 if (shader
== PIPE_SHADER_VERTEX
) {
340 nv04
->vertprog
.constant_buf
= buf
->buffer
;
341 nv04
->dirty
|= NV04_NEW_VERTPROG
;
343 if (shader
== PIPE_SHADER_FRAGMENT
) {
344 nv04
->fragprog
.constant_buf
= buf
->buffer
;
345 nv04
->dirty
|= NV04_NEW_FRAGPROG
;
350 nv04_set_framebuffer_state(struct pipe_context
*pipe
,
351 const struct pipe_framebuffer_state
*fb
)
353 struct nv04_context
*nv04
= nv04_context(pipe
);
354 struct pipe_surface
*rt
, *zeta
;
355 uint32_t rt_format
, w
, h
;
356 int colour_format
= 0, zeta_format
= 0;
358 w
= fb
->cbufs
[0]->width
;
359 h
= fb
->cbufs
[0]->height
;
360 colour_format
= fb
->cbufs
[0]->format
;
365 assert(w
== fb
->zsbuf
->width
);
366 assert(h
== fb
->zsbuf
->height
);
368 w
= fb
->zsbuf
->width
;
369 h
= fb
->zsbuf
->height
;
372 zeta_format
= fb
->zsbuf
->format
;
376 switch (colour_format
) {
377 case PIPE_FORMAT_A8R8G8B8_UNORM
:
381 case PIPE_FORMAT_R5G6B5_UNORM
:
388 BEGIN_RING(context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_FORMAT
, 1);
391 /* FIXME pitches have to be aligned ! */
392 BEGIN_RING(context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_PITCH
, 2);
393 OUT_RING(rt
->stride
|(zeta
->stride
<<16));
394 OUT_RELOCl(rt
->buffer
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
396 BEGIN_RING(context_surfaces_3d
, NV04_CONTEXT_SURFACES_3D_OFFSET_ZETA
, 1);
397 OUT_RELOCl(zeta
->buffer
, 0, NOUVEAU_BO_VRAM
| NOUVEAU_BO_WR
);
402 nv04_set_polygon_stipple(struct pipe_context
*pipe
,
403 const struct pipe_poly_stipple
*stipple
)
405 NOUVEAU_ERR("line stipple hahaha\n");
409 nv04_set_scissor_state(struct pipe_context
*pipe
,
410 const struct pipe_scissor_state
*s
)
412 /* struct nv04_context *nv04 = nv04_context(pipe);
415 BEGIN_RING(fahrenheit, NV04_DX5_TEXTURED_TRIANGLE_SCISSOR_HORIZ, 2);
416 OUT_RING (((s->maxx - s->minx) << 16) | s->minx);
417 OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/
421 nv04_set_viewport_state(struct pipe_context
*pipe
,
422 const struct pipe_viewport_state
*viewport
)
424 struct nv04_context
*nv04
= nv04_context(pipe
);
426 nv04
->viewport
= *viewport
;
428 draw_set_viewport_state(nv04
->draw
, &nv04
->viewport
);
432 nv04_set_vertex_buffers(struct pipe_context
*pipe
, unsigned count
,
433 const struct pipe_vertex_buffer
*buffers
)
435 struct nv04_context
*nv04
= nv04_context(pipe
);
437 draw_flush(nv04
->draw
);
439 memcpy(nv04
->vertex_buffer
, buffers
, count
* sizeof(buffers
[0]));
440 nv04
->num_vertex_buffers
= count
;
442 draw_set_vertex_buffers(nv04
->draw
, count
, buffers
);
446 nv04_set_vertex_elements(struct pipe_context
*pipe
, unsigned count
,
447 const struct pipe_vertex_element
*elements
)
449 struct nv04_context
*nv04
= nv04_context(pipe
);
451 draw_flush(nv04
->draw
);
453 nv04
->num_vertex_elements
= count
;
454 draw_set_vertex_elements(nv04
->draw
, count
, elements
);
458 nv04_init_state_functions(struct nv04_context
*nv04
)
460 nv04
->pipe
.create_blend_state
= nv04_blend_state_create
;
461 nv04
->pipe
.bind_blend_state
= nv04_blend_state_bind
;
462 nv04
->pipe
.delete_blend_state
= nv04_blend_state_delete
;
464 nv04
->pipe
.create_sampler_state
= nv04_sampler_state_create
;
465 nv04
->pipe
.bind_sampler_states
= nv04_sampler_state_bind
;
466 nv04
->pipe
.delete_sampler_state
= nv04_sampler_state_delete
;
467 nv04
->pipe
.set_sampler_textures
= nv04_set_sampler_texture
;
469 nv04
->pipe
.create_rasterizer_state
= nv04_rasterizer_state_create
;
470 nv04
->pipe
.bind_rasterizer_state
= nv04_rasterizer_state_bind
;
471 nv04
->pipe
.delete_rasterizer_state
= nv04_rasterizer_state_delete
;
473 nv04
->pipe
.create_depth_stencil_alpha_state
= nv04_depth_stencil_alpha_state_create
;
474 nv04
->pipe
.bind_depth_stencil_alpha_state
= nv04_depth_stencil_alpha_state_bind
;
475 nv04
->pipe
.delete_depth_stencil_alpha_state
= nv04_depth_stencil_alpha_state_delete
;
477 nv04
->pipe
.create_vs_state
= nv04_vp_state_create
;
478 nv04
->pipe
.bind_vs_state
= nv04_vp_state_bind
;
479 nv04
->pipe
.delete_vs_state
= nv04_vp_state_delete
;
481 nv04
->pipe
.create_fs_state
= nv04_fp_state_create
;
482 nv04
->pipe
.bind_fs_state
= nv04_fp_state_bind
;
483 nv04
->pipe
.delete_fs_state
= nv04_fp_state_delete
;
485 nv04
->pipe
.set_blend_color
= nv04_set_blend_color
;
486 nv04
->pipe
.set_clip_state
= nv04_set_clip_state
;
487 nv04
->pipe
.set_constant_buffer
= nv04_set_constant_buffer
;
488 nv04
->pipe
.set_framebuffer_state
= nv04_set_framebuffer_state
;
489 nv04
->pipe
.set_polygon_stipple
= nv04_set_polygon_stipple
;
490 nv04
->pipe
.set_scissor_state
= nv04_set_scissor_state
;
491 nv04
->pipe
.set_viewport_state
= nv04_set_viewport_state
;
493 nv04
->pipe
.set_vertex_buffers
= nv04_set_vertex_buffers
;
494 nv04
->pipe
.set_vertex_elements
= nv04_set_vertex_elements
;