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 "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
->rt
[0].blend_enable
? 1 : 0;
21 cb
->b_src
= ((nvgl_blend_func(cso
->rt
[0].alpha_src_factor
)<<16) |
22 (nvgl_blend_func(cso
->rt
[0].rgb_src_factor
)));
23 cb
->b_dst
= ((nvgl_blend_func(cso
->rt
[0].alpha_dst_factor
)<<16) |
24 (nvgl_blend_func(cso
->rt
[0].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_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_REPEAT
;
55 case PIPE_TEX_WRAP_MIRROR_REPEAT
:
56 ret
= NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_MIRRORED_REPEAT
;
58 case PIPE_TEX_WRAP_CLAMP_TO_EDGE
:
59 ret
= NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_EDGE
;
61 case PIPE_TEX_WRAP_CLAMP_TO_BORDER
:
62 ret
= NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP_TO_BORDER
;
64 case PIPE_TEX_WRAP_CLAMP
:
65 ret
= NV04_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_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_CLAMP
;
74 return ret
>> NV04_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_TEXTURED_TRIANGLE_FORMAT_ADDRESSU_SHIFT
) |
88 (wrap_mode(cso
->wrap_t
) << NV04_TEXTURED_TRIANGLE_FORMAT_ADDRESSV_SHIFT
));
90 if (cso
->max_anisotropy
> 1.0) {
91 filter
|= NV04_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MINIFY_ENABLE
| NV04_TEXTURED_TRIANGLE_FILTER_ANISOTROPIC_MAGNIFY_ENABLE
;
94 switch (cso
->mag_img_filter
) {
95 case PIPE_TEX_FILTER_LINEAR
:
96 filter
|= NV04_TEXTURED_TRIANGLE_FILTER_MAGNIFY_LINEAR
;
98 case PIPE_TEX_FILTER_NEAREST
:
100 filter
|= NV04_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_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST
;
110 case PIPE_TEX_MIPFILTER_LINEAR
:
111 filter
|= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR
;
113 case PIPE_TEX_MIPFILTER_NONE
:
115 filter
|= NV04_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_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST
;
125 case PIPE_TEX_MIPFILTER_LINEAR
:
126 filter
|= NV04_TEXTURED_TRIANGLE_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR
;
128 case PIPE_TEX_MIPFILTER_NONE
:
130 filter
|= NV04_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_TEXTURED_TRIANGLE_BLEND_SHADE_MODE_FLAT
: NV04_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_value
);
232 hw
->control
|= ( nv04_compare_func(cso
->alpha
.func
) << NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_FUNC_SHIFT
);
233 hw
->control
|= cso
->alpha
.enabled
? NV04_TEXTURED_TRIANGLE_CONTROL_ALPHA_ENABLE
: 0;
234 hw
->control
|= NV04_TEXTURED_TRIANGLE_CONTROL_ORIGIN
;
235 hw
->control
|= cso
->depth
.enabled
? NV04_TEXTURED_TRIANGLE_CONTROL_Z_ENABLE
: 0;
236 hw
->control
|= ( nv04_compare_func(cso
->depth
.func
)<< NV04_TEXTURED_TRIANGLE_CONTROL_Z_FUNC_SHIFT
);
237 hw
->control
|= 1 << NV04_TEXTURED_TRIANGLE_CONTROL_CULL_MODE_SHIFT
; // no culling, handled by the draw module
238 hw
->control
|= NV04_TEXTURED_TRIANGLE_CONTROL_DITHER_ENABLE
;
239 hw
->control
|= NV04_TEXTURED_TRIANGLE_CONTROL_Z_PERSPECTIVE_ENABLE
;
240 hw
->control
|= cso
->depth
.writemask
? NV04_TEXTURED_TRIANGLE_CONTROL_Z_WRITE
: 0;
241 hw
->control
|= 1 << NV04_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 struct pipe_buffer
*buf
)
337 struct nv04_context
*nv04
= nv04_context(pipe
);
338 struct pipe_screen
*pscreen
= pipe
->screen
;
340 assert(shader
< PIPE_SHADER_TYPES
);
345 if (buf
&& buf
->size
&&
346 (mapped
= pipe_buffer_map(pscreen
, buf
, PIPE_BUFFER_USAGE_CPU_READ
)))
348 memcpy(nv04
->constbuf
[shader
], mapped
, buf
->size
);
349 nv04
->constbuf_nr
[shader
] =
350 buf
->size
/ (4 * sizeof(float));
351 pipe_buffer_unmap(pscreen
, buf
);
357 nv04_set_framebuffer_state(struct pipe_context
*pipe
,
358 const struct pipe_framebuffer_state
*fb
)
360 struct nv04_context
*nv04
= nv04_context(pipe
);
362 nv04
->framebuffer
= (struct pipe_framebuffer_state
*)fb
;
364 nv04
->dirty
|= NV04_NEW_FRAMEBUFFER
;
367 nv04_set_polygon_stipple(struct pipe_context
*pipe
,
368 const struct pipe_poly_stipple
*stipple
)
370 NOUVEAU_ERR("line stipple hahaha\n");
374 nv04_set_scissor_state(struct pipe_context
*pipe
,
375 const struct pipe_scissor_state
*s
)
377 /* struct nv04_context *nv04 = nv04_context(pipe);
380 BEGIN_RING(fahrenheit, NV04_TEXTURED_TRIANGLE_SCISSOR_HORIZ, 2);
381 OUT_RING (((s->maxx - s->minx) << 16) | s->minx);
382 OUT_RING (((s->maxy - s->miny) << 16) | s->miny);*/
386 nv04_set_viewport_state(struct pipe_context
*pipe
,
387 const struct pipe_viewport_state
*viewport
)
389 struct nv04_context
*nv04
= nv04_context(pipe
);
391 nv04
->viewport
= *viewport
;
393 draw_set_viewport_state(nv04
->draw
, &nv04
->viewport
);
397 nv04_set_vertex_buffers(struct pipe_context
*pipe
, unsigned count
,
398 const struct pipe_vertex_buffer
*buffers
)
400 struct nv04_context
*nv04
= nv04_context(pipe
);
402 memcpy(nv04
->vtxbuf
, buffers
, count
* sizeof(buffers
[0]));
403 nv04
->dirty
|= NV04_NEW_VTXARRAYS
;
405 draw_set_vertex_buffers(nv04
->draw
, count
, buffers
);
409 nv04_set_vertex_elements(struct pipe_context
*pipe
, unsigned count
,
410 const struct pipe_vertex_element
*elements
)
412 struct nv04_context
*nv04
= nv04_context(pipe
);
414 memcpy(nv04
->vtxelt
, elements
, sizeof(*elements
) * count
);
415 nv04
->dirty
|= NV04_NEW_VTXARRAYS
;
417 draw_set_vertex_elements(nv04
->draw
, count
, elements
);
421 nv04_init_state_functions(struct nv04_context
*nv04
)
423 nv04
->pipe
.create_blend_state
= nv04_blend_state_create
;
424 nv04
->pipe
.bind_blend_state
= nv04_blend_state_bind
;
425 nv04
->pipe
.delete_blend_state
= nv04_blend_state_delete
;
427 nv04
->pipe
.create_sampler_state
= nv04_sampler_state_create
;
428 nv04
->pipe
.bind_fragment_sampler_states
= nv04_sampler_state_bind
;
429 nv04
->pipe
.delete_sampler_state
= nv04_sampler_state_delete
;
430 nv04
->pipe
.set_fragment_sampler_textures
= nv04_set_sampler_texture
;
432 nv04
->pipe
.create_rasterizer_state
= nv04_rasterizer_state_create
;
433 nv04
->pipe
.bind_rasterizer_state
= nv04_rasterizer_state_bind
;
434 nv04
->pipe
.delete_rasterizer_state
= nv04_rasterizer_state_delete
;
436 nv04
->pipe
.create_depth_stencil_alpha_state
= nv04_depth_stencil_alpha_state_create
;
437 nv04
->pipe
.bind_depth_stencil_alpha_state
= nv04_depth_stencil_alpha_state_bind
;
438 nv04
->pipe
.delete_depth_stencil_alpha_state
= nv04_depth_stencil_alpha_state_delete
;
440 nv04
->pipe
.create_vs_state
= nv04_vp_state_create
;
441 nv04
->pipe
.bind_vs_state
= nv04_vp_state_bind
;
442 nv04
->pipe
.delete_vs_state
= nv04_vp_state_delete
;
444 nv04
->pipe
.create_fs_state
= nv04_fp_state_create
;
445 nv04
->pipe
.bind_fs_state
= nv04_fp_state_bind
;
446 nv04
->pipe
.delete_fs_state
= nv04_fp_state_delete
;
448 nv04
->pipe
.set_blend_color
= nv04_set_blend_color
;
449 nv04
->pipe
.set_clip_state
= nv04_set_clip_state
;
450 nv04
->pipe
.set_constant_buffer
= nv04_set_constant_buffer
;
451 nv04
->pipe
.set_framebuffer_state
= nv04_set_framebuffer_state
;
452 nv04
->pipe
.set_polygon_stipple
= nv04_set_polygon_stipple
;
453 nv04
->pipe
.set_scissor_state
= nv04_set_scissor_state
;
454 nv04
->pipe
.set_viewport_state
= nv04_set_viewport_state
;
456 nv04
->pipe
.set_vertex_buffers
= nv04_set_vertex_buffers
;
457 nv04
->pipe
.set_vertex_elements
= nv04_set_vertex_elements
;