nv30_state.c revision 2419a5fe3601851989506a11b0bd4e3cfb071035
1#include "pipe/p_state.h"
2#include "pipe/p_defines.h"
3#include "pipe/p_util.h"
4#include "pipe/p_inlines.h"
5
6#include "nv30_context.h"
7#include "nv30_state.h"
8
9static void *
10nv30_blend_state_create(struct pipe_context *pipe,
11			const struct pipe_blend_state *cso)
12{
13	struct nv30_context *nv30 = nv30_context(pipe);
14	struct nouveau_grobj *rankine = nv30->screen->rankine;
15	struct nv30_blend_state *bso = CALLOC(1, sizeof(*bso));
16	struct nouveau_stateobj *so = so_new(16, 0);
17
18	if (cso->blend_enable) {
19		so_method(so, rankine, NV34TCL_BLEND_FUNC_ENABLE, 3);
20		so_data  (so, 1);
21		so_data  (so, (nvgl_blend_func(cso->alpha_src_factor) << 16) |
22			       nvgl_blend_func(cso->rgb_src_factor));
23		so_data  (so, nvgl_blend_func(cso->alpha_dst_factor) << 16 |
24			      nvgl_blend_func(cso->rgb_dst_factor));
25		so_method(so, rankine, NV34TCL_BLEND_EQUATION, 1);
26		so_data  (so, nvgl_blend_eqn(cso->alpha_func) << 16 |
27			      nvgl_blend_eqn(cso->rgb_func));
28	} else {
29		so_method(so, rankine, NV34TCL_BLEND_FUNC_ENABLE, 1);
30		so_data  (so, 0);
31	}
32
33	so_method(so, rankine, NV34TCL_COLOR_MASK, 1);
34	so_data  (so, (((cso->colormask & PIPE_MASK_A) ? (0x01 << 24) : 0) |
35		       ((cso->colormask & PIPE_MASK_R) ? (0x01 << 16) : 0) |
36		       ((cso->colormask & PIPE_MASK_G) ? (0x01 <<  8) : 0) |
37		       ((cso->colormask & PIPE_MASK_B) ? (0x01 <<  0) : 0)));
38
39	if (cso->logicop_enable) {
40		so_method(so, rankine, NV34TCL_COLOR_LOGIC_OP_ENABLE, 2);
41		so_data  (so, 1);
42		so_data  (so, nvgl_logicop_func(cso->logicop_func));
43	} else {
44		so_method(so, rankine, NV34TCL_COLOR_LOGIC_OP_ENABLE, 1);
45		so_data  (so, 0);
46	}
47
48	so_method(so, rankine, NV34TCL_DITHER_ENABLE, 1);
49	so_data  (so, cso->dither ? 1 : 0);
50
51	so_ref(so, &bso->so);
52	bso->pipe = *cso;
53	return (void *)bso;
54}
55
56static void
57nv30_blend_state_bind(struct pipe_context *pipe, void *hwcso)
58{
59	struct nv30_context *nv30 = nv30_context(pipe);
60
61	nv30->blend = hwcso;
62	nv30->dirty |= NV30_NEW_BLEND;
63}
64
65static void
66nv30_blend_state_delete(struct pipe_context *pipe, void *hwcso)
67{
68	struct nv30_blend_state *bso = hwcso;
69
70	so_ref(NULL, &bso->so);
71	FREE(bso);
72}
73
74
75static INLINE unsigned
76wrap_mode(unsigned wrap) {
77	unsigned ret;
78
79	switch (wrap) {
80	case PIPE_TEX_WRAP_REPEAT:
81		ret = NV34TCL_TX_WRAP_S_REPEAT;
82		break;
83	case PIPE_TEX_WRAP_MIRROR_REPEAT:
84		ret = NV34TCL_TX_WRAP_S_MIRRORED_REPEAT;
85		break;
86	case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
87		ret = NV34TCL_TX_WRAP_S_CLAMP_TO_EDGE;
88		break;
89	case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
90		ret = NV34TCL_TX_WRAP_S_CLAMP_TO_BORDER;
91		break;
92	case PIPE_TEX_WRAP_CLAMP:
93		ret = NV34TCL_TX_WRAP_S_CLAMP;
94		break;
95/*	case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
96		ret = NV34TCL_TX_WRAP_S_MIRROR_CLAMP_TO_EDGE;
97		break;
98	case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
99		ret = NV34TCL_TX_WRAP_S_MIRROR_CLAMP_TO_BORDER;
100		break;
101	case PIPE_TEX_WRAP_MIRROR_CLAMP:
102		ret = NV34TCL_TX_WRAP_S_MIRROR_CLAMP;
103		break;*/
104	default:
105		NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
106		ret = NV34TCL_TX_WRAP_S_REPEAT;
107		break;
108	}
109
110	return ret >> NV34TCL_TX_WRAP_S_SHIFT;
111}
112
113static void *
114nv30_sampler_state_create(struct pipe_context *pipe,
115			  const struct pipe_sampler_state *cso)
116{
117	struct nv30_sampler_state *ps;
118	uint32_t filter = 0;
119
120	ps = MALLOC(sizeof(struct nv30_sampler_state));
121
122	ps->fmt = 0;
123	/* TODO: Not all RECTs formats have this bit set, bits 15-8 of format
124	   are the tx format to use. We should store normalized coord flag
125	   in sampler state structure, and set appropriate format in
126	   nvxx_fragtex_build()
127	 */
128	if (!cso->normalized_coords)
129		ps->fmt |= (1<<14) /*NV34TCL_TX_FORMAT_RECT*/;
130
131	ps->wrap = ((wrap_mode(cso->wrap_s) << NV34TCL_TX_WRAP_S_SHIFT) |
132		    (wrap_mode(cso->wrap_t) << NV34TCL_TX_WRAP_T_SHIFT) |
133		    (wrap_mode(cso->wrap_r) << NV34TCL_TX_WRAP_R_SHIFT));
134
135	ps->en = 0;
136
137	if (cso->max_anisotropy >= 8.0) {
138		ps->en |= NV34TCL_TX_ENABLE_ANISO_8X;
139	} else
140	if (cso->max_anisotropy >= 4.0) {
141		ps->en |= NV34TCL_TX_ENABLE_ANISO_4X;
142	} else
143	if (cso->max_anisotropy >= 2.0) {
144		ps->en |= NV34TCL_TX_ENABLE_ANISO_2X;
145	}
146
147	switch (cso->mag_img_filter) {
148	case PIPE_TEX_FILTER_LINEAR:
149		filter |= NV34TCL_TX_FILTER_MAGNIFY_LINEAR;
150		break;
151	case PIPE_TEX_FILTER_NEAREST:
152	default:
153		filter |= NV34TCL_TX_FILTER_MAGNIFY_NEAREST;
154		break;
155	}
156
157	switch (cso->min_img_filter) {
158	case PIPE_TEX_FILTER_LINEAR:
159		switch (cso->min_mip_filter) {
160		case PIPE_TEX_MIPFILTER_NEAREST:
161			filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_NEAREST;
162			break;
163		case PIPE_TEX_MIPFILTER_LINEAR:
164			filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR_MIPMAP_LINEAR;
165			break;
166		case PIPE_TEX_MIPFILTER_NONE:
167		default:
168			filter |= NV34TCL_TX_FILTER_MINIFY_LINEAR;
169			break;
170		}
171		break;
172	case PIPE_TEX_FILTER_NEAREST:
173	default:
174		switch (cso->min_mip_filter) {
175		case PIPE_TEX_MIPFILTER_NEAREST:
176			filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_NEAREST;
177		break;
178		case PIPE_TEX_MIPFILTER_LINEAR:
179			filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST_MIPMAP_LINEAR;
180			break;
181		case PIPE_TEX_MIPFILTER_NONE:
182		default:
183			filter |= NV34TCL_TX_FILTER_MINIFY_NEAREST;
184			break;
185		}
186		break;
187	}
188
189	ps->filt = filter;
190
191	{
192		float limit;
193
194		limit = CLAMP(cso->lod_bias, -16.0, 15.0);
195		ps->filt |= (int)(cso->lod_bias * 256.0) & 0x1fff;
196
197		limit = CLAMP(cso->max_lod, 0.0, 15.0);
198		ps->en |= (int)(limit * 256.0) << 7;
199
200		limit = CLAMP(cso->min_lod, 0.0, 15.0);
201		ps->en |= (int)(limit * 256.0) << 19;
202	}
203
204	if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
205		switch (cso->compare_func) {
206		case PIPE_FUNC_NEVER:
207			ps->wrap |= NV34TCL_TX_WRAP_RCOMP_NEVER;
208			break;
209		case PIPE_FUNC_GREATER:
210			ps->wrap |= NV34TCL_TX_WRAP_RCOMP_GREATER;
211			break;
212		case PIPE_FUNC_EQUAL:
213			ps->wrap |= NV34TCL_TX_WRAP_RCOMP_EQUAL;
214			break;
215		case PIPE_FUNC_GEQUAL:
216			ps->wrap |= NV34TCL_TX_WRAP_RCOMP_GEQUAL;
217			break;
218		case PIPE_FUNC_LESS:
219			ps->wrap |= NV34TCL_TX_WRAP_RCOMP_LESS;
220			break;
221		case PIPE_FUNC_NOTEQUAL:
222			ps->wrap |= NV34TCL_TX_WRAP_RCOMP_NOTEQUAL;
223			break;
224		case PIPE_FUNC_LEQUAL:
225			ps->wrap |= NV34TCL_TX_WRAP_RCOMP_LEQUAL;
226			break;
227		case PIPE_FUNC_ALWAYS:
228			ps->wrap |= NV34TCL_TX_WRAP_RCOMP_ALWAYS;
229			break;
230		default:
231			break;
232		}
233	}
234
235	ps->bcol = ((float_to_ubyte(cso->border_color[3]) << 24) |
236		    (float_to_ubyte(cso->border_color[0]) << 16) |
237		    (float_to_ubyte(cso->border_color[1]) <<  8) |
238		    (float_to_ubyte(cso->border_color[2]) <<  0));
239
240	return (void *)ps;
241}
242
243static void
244nv30_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
245{
246	struct nv30_context *nv30 = nv30_context(pipe);
247	unsigned unit;
248
249	for (unit = 0; unit < nr; unit++) {
250		nv30->tex_sampler[unit] = sampler[unit];
251		nv30->dirty_samplers |= (1 << unit);
252	}
253
254	for (unit = nr; unit < nv30->nr_samplers; unit++) {
255		nv30->tex_sampler[unit] = NULL;
256		nv30->dirty_samplers |= (1 << unit);
257	}
258
259	nv30->nr_samplers = nr;
260	nv30->dirty |= NV30_NEW_SAMPLER;
261}
262
263static void
264nv30_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
265{
266	FREE(hwcso);
267}
268
269static void
270nv30_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
271			 struct pipe_texture **miptree)
272{
273	struct nv30_context *nv30 = nv30_context(pipe);
274	unsigned unit;
275
276	for (unit = 0; unit < nr; unit++) {
277		pipe_texture_reference((struct pipe_texture **)
278				       &nv30->tex_miptree[unit], miptree[unit]);
279		nv30->dirty_samplers |= (1 << unit);
280	}
281
282	for (unit = nr; unit < nv30->nr_textures; unit++) {
283		pipe_texture_reference((struct pipe_texture **)
284				       &nv30->tex_miptree[unit], NULL);
285		nv30->dirty_samplers |= (1 << unit);
286	}
287
288	nv30->nr_textures = nr;
289	nv30->dirty |= NV30_NEW_SAMPLER;
290}
291
292static void *
293nv30_rasterizer_state_create(struct pipe_context *pipe,
294			     const struct pipe_rasterizer_state *cso)
295{
296	struct nv30_context *nv30 = nv30_context(pipe);
297	struct nv30_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso));
298	struct nouveau_stateobj *so = so_new(32, 0);
299	struct nouveau_grobj *rankine = nv30->screen->rankine;
300
301	/*XXX: ignored:
302	 * 	light_twoside
303	 * 	point_smooth -nohw
304	 * 	multisample
305	 */
306
307	so_method(so, rankine, NV34TCL_SHADE_MODEL, 1);
308	so_data  (so, cso->flatshade ? NV34TCL_SHADE_MODEL_FLAT :
309				       NV34TCL_SHADE_MODEL_SMOOTH);
310
311	so_method(so, rankine, NV34TCL_LINE_WIDTH, 2);
312	so_data  (so, (unsigned char)(cso->line_width * 8.0) & 0xff);
313	so_data  (so, cso->line_smooth ? 1 : 0);
314	so_method(so, rankine, NV34TCL_LINE_STIPPLE_ENABLE, 2);
315	so_data  (so, cso->line_stipple_enable ? 1 : 0);
316	so_data  (so, (cso->line_stipple_pattern << 16) |
317		       cso->line_stipple_factor);
318
319	so_method(so, rankine, NV34TCL_POINT_SIZE, 1);
320	so_data  (so, fui(cso->point_size));
321
322	so_method(so, rankine, NV34TCL_POLYGON_MODE_FRONT, 6);
323	if (cso->front_winding == PIPE_WINDING_CCW) {
324		so_data(so, nvgl_polygon_mode(cso->fill_ccw));
325		so_data(so, nvgl_polygon_mode(cso->fill_cw));
326		switch (cso->cull_mode) {
327		case PIPE_WINDING_CCW:
328			so_data(so, NV34TCL_CULL_FACE_FRONT);
329			break;
330		case PIPE_WINDING_CW:
331			so_data(so, NV34TCL_CULL_FACE_BACK);
332			break;
333		case PIPE_WINDING_BOTH:
334			so_data(so, NV34TCL_CULL_FACE_FRONT_AND_BACK);
335			break;
336		default:
337			so_data(so, NV34TCL_CULL_FACE_BACK);
338			break;
339		}
340		so_data(so, NV34TCL_FRONT_FACE_CCW);
341	} else {
342		so_data(so, nvgl_polygon_mode(cso->fill_cw));
343		so_data(so, nvgl_polygon_mode(cso->fill_ccw));
344		switch (cso->cull_mode) {
345		case PIPE_WINDING_CCW:
346			so_data(so, NV34TCL_CULL_FACE_BACK);
347			break;
348		case PIPE_WINDING_CW:
349			so_data(so, NV34TCL_CULL_FACE_FRONT);
350			break;
351		case PIPE_WINDING_BOTH:
352			so_data(so, NV34TCL_CULL_FACE_FRONT_AND_BACK);
353			break;
354		default:
355			so_data(so, NV34TCL_CULL_FACE_BACK);
356			break;
357		}
358		so_data(so, NV34TCL_FRONT_FACE_CW);
359	}
360	so_data(so, cso->poly_smooth ? 1 : 0);
361	so_data(so, (cso->cull_mode != PIPE_WINDING_NONE) ? 1 : 0);
362
363	so_method(so, rankine, NV34TCL_POLYGON_STIPPLE_ENABLE, 1);
364	so_data  (so, cso->poly_stipple_enable ? 1 : 0);
365
366	so_method(so, rankine, NV34TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
367	if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) ||
368	    (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT))
369		so_data(so, 1);
370	else
371		so_data(so, 0);
372	if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) ||
373	    (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE))
374		so_data(so, 1);
375	else
376		so_data(so, 0);
377	if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) ||
378	    (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL))
379		so_data(so, 1);
380	else
381		so_data(so, 0);
382	if (cso->offset_cw || cso->offset_ccw) {
383		so_method(so, rankine, NV34TCL_POLYGON_OFFSET_FACTOR, 2);
384		so_data  (so, fui(cso->offset_scale));
385		so_data  (so, fui(cso->offset_units * 2));
386	}
387
388	so_method(so, rankine, NV34TCL_POINT_SPRITE, 1);
389	if (cso->point_sprite) {
390		unsigned psctl = (1 << 0), i;
391
392		for (i = 0; i < 8; i++) {
393			if (cso->sprite_coord_mode[i] != PIPE_SPRITE_COORD_NONE)
394				psctl |= (1 << (8 + i));
395		}
396
397		so_data(so, psctl);
398	} else {
399		so_data(so, 0);
400	}
401
402	so_ref(so, &rsso->so);
403	rsso->pipe = *cso;
404	return (void *)rsso;
405}
406
407static void
408nv30_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
409{
410	struct nv30_context *nv30 = nv30_context(pipe);
411
412	nv30->rasterizer = hwcso;
413	nv30->dirty |= NV30_NEW_RAST;
414	/*nv30->draw_dirty |= NV30_NEW_RAST;*/
415}
416
417static void
418nv30_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
419{
420	struct nv30_rasterizer_state *rsso = hwcso;
421
422	so_ref(NULL, &rsso->so);
423	FREE(rsso);
424}
425
426static void *
427nv30_depth_stencil_alpha_state_create(struct pipe_context *pipe,
428			const struct pipe_depth_stencil_alpha_state *cso)
429{
430	struct nv30_context *nv30 = nv30_context(pipe);
431	struct nv30_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso));
432	struct nouveau_stateobj *so = so_new(32, 0);
433	struct nouveau_grobj *rankine = nv30->screen->rankine;
434
435	so_method(so, rankine, NV34TCL_DEPTH_FUNC, 3);
436	so_data  (so, nvgl_comparison_op(cso->depth.func));
437	so_data  (so, cso->depth.writemask ? 1 : 0);
438	so_data  (so, cso->depth.enabled ? 1 : 0);
439
440	so_method(so, rankine, NV34TCL_ALPHA_FUNC_ENABLE, 3);
441	so_data  (so, cso->alpha.enabled ? 1 : 0);
442	so_data  (so, nvgl_comparison_op(cso->alpha.func));
443	so_data  (so, float_to_ubyte(cso->alpha.ref));
444
445	if (cso->stencil[0].enabled) {
446		so_method(so, rankine, NV34TCL_STENCIL_FRONT_ENABLE, 8);
447		so_data  (so, cso->stencil[0].enabled ? 1 : 0);
448		so_data  (so, cso->stencil[0].write_mask);
449		so_data  (so, nvgl_comparison_op(cso->stencil[0].func));
450		so_data  (so, cso->stencil[0].ref_value);
451		so_data  (so, cso->stencil[0].value_mask);
452		so_data  (so, nvgl_stencil_op(cso->stencil[0].fail_op));
453		so_data  (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
454		so_data  (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
455	} else {
456		so_method(so, rankine, NV34TCL_STENCIL_FRONT_ENABLE, 1);
457		so_data  (so, 0);
458	}
459
460	if (cso->stencil[1].enabled) {
461		so_method(so, rankine, NV34TCL_STENCIL_BACK_ENABLE, 8);
462		so_data  (so, cso->stencil[1].enabled ? 1 : 0);
463		so_data  (so, cso->stencil[1].write_mask);
464		so_data  (so, nvgl_comparison_op(cso->stencil[1].func));
465		so_data  (so, cso->stencil[1].ref_value);
466		so_data  (so, cso->stencil[1].value_mask);
467		so_data  (so, nvgl_stencil_op(cso->stencil[1].fail_op));
468		so_data  (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
469		so_data  (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
470	} else {
471		so_method(so, rankine, NV34TCL_STENCIL_BACK_ENABLE, 1);
472		so_data  (so, 0);
473	}
474
475	so_ref(so, &zsaso->so);
476	zsaso->pipe = *cso;
477	return (void *)zsaso;
478}
479
480static void
481nv30_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso)
482{
483	struct nv30_context *nv30 = nv30_context(pipe);
484
485	nv30->zsa = hwcso;
486	nv30->dirty |= NV30_NEW_ZSA;
487}
488
489static void
490nv30_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
491{
492	struct nv30_zsa_state *zsaso = hwcso;
493
494	so_ref(NULL, &zsaso->so);
495	FREE(zsaso);
496}
497
498static void *
499nv30_vp_state_create(struct pipe_context *pipe,
500		     const struct pipe_shader_state *cso)
501{
502	/*struct nv30_context *nv30 = nv30_context(pipe);*/
503	struct nv30_vertex_program *vp;
504
505	vp = CALLOC(1, sizeof(struct nv30_vertex_program));
506	vp->pipe = *cso;
507	/*vp->draw = draw_create_vertex_shader(nv30->draw, &vp->pipe);*/
508
509	return (void *)vp;
510}
511
512static void
513nv30_vp_state_bind(struct pipe_context *pipe, void *hwcso)
514{
515	struct nv30_context *nv30 = nv30_context(pipe);
516
517	nv30->vertprog = hwcso;
518	nv30->dirty |= NV30_NEW_VERTPROG;
519	/*nv30->draw_dirty |= NV30_NEW_VERTPROG;*/
520}
521
522static void
523nv30_vp_state_delete(struct pipe_context *pipe, void *hwcso)
524{
525	struct nv30_context *nv30 = nv30_context(pipe);
526	struct nv30_vertex_program *vp = hwcso;
527
528	/*draw_delete_vertex_shader(nv30->draw, vp->draw);*/
529	nv30_vertprog_destroy(nv30, vp);
530	FREE(vp);
531}
532
533static void *
534nv30_fp_state_create(struct pipe_context *pipe,
535		     const struct pipe_shader_state *cso)
536{
537	struct nv30_fragment_program *fp;
538
539	fp = CALLOC(1, sizeof(struct nv30_fragment_program));
540	fp->pipe = *cso;
541
542	return (void *)fp;
543}
544
545static void
546nv30_fp_state_bind(struct pipe_context *pipe, void *hwcso)
547{
548	struct nv30_context *nv30 = nv30_context(pipe);
549	struct nv30_fragment_program *fp = hwcso;
550
551	if (!hwcso) {
552		return;
553	}
554
555	nv30->fragprog.current = fp;
556	nv30->dirty |= NV30_NEW_FRAGPROG;
557}
558
559static void
560nv30_fp_state_delete(struct pipe_context *pipe, void *hwcso)
561{
562	struct nv30_context *nv30 = nv30_context(pipe);
563	struct nv30_fragment_program *fp = hwcso;
564
565	nv30_fragprog_destroy(nv30, fp);
566	FREE(fp);
567}
568
569static void
570nv30_set_blend_color(struct pipe_context *pipe,
571		     const struct pipe_blend_color *bcol)
572{
573	struct nv30_context *nv30 = nv30_context(pipe);
574
575	nv30->blend_colour = *bcol;
576	nv30->dirty |= NV30_NEW_BCOL;
577}
578
579static void
580nv30_set_clip_state(struct pipe_context *pipe,
581		    const struct pipe_clip_state *clip)
582{
583}
584
585static void
586nv30_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
587			 const struct pipe_constant_buffer *buf )
588{
589	struct nv30_context *nv30 = nv30_context(pipe);
590
591	nv30->constbuf[shader] = buf->buffer;
592	nv30->constbuf_nr[shader] = buf->size / (4 * sizeof(float));
593
594	if (shader == PIPE_SHADER_VERTEX) {
595		nv30->dirty |= NV30_NEW_VERTPROG;
596	} else
597	if (shader == PIPE_SHADER_FRAGMENT) {
598		nv30->dirty |= NV30_NEW_FRAGPROG;
599	}
600}
601
602static void
603nv30_set_framebuffer_state(struct pipe_context *pipe,
604			   const struct pipe_framebuffer_state *fb)
605{
606	struct nv30_context *nv30 = nv30_context(pipe);
607
608	nv30->framebuffer = *fb;
609	nv30->dirty |= NV30_NEW_FB;
610}
611
612static void
613nv30_set_polygon_stipple(struct pipe_context *pipe,
614			 const struct pipe_poly_stipple *stipple)
615{
616	struct nv30_context *nv30 = nv30_context(pipe);
617
618	memcpy(nv30->stipple, stipple->stipple, 4 * 32);
619	nv30->dirty |= NV30_NEW_STIPPLE;
620}
621
622static void
623nv30_set_scissor_state(struct pipe_context *pipe,
624		       const struct pipe_scissor_state *s)
625{
626	struct nv30_context *nv30 = nv30_context(pipe);
627
628	nv30->scissor = *s;
629	nv30->dirty |= NV30_NEW_SCISSOR;
630}
631
632static void
633nv30_set_viewport_state(struct pipe_context *pipe,
634			const struct pipe_viewport_state *vpt)
635{
636	struct nv30_context *nv30 = nv30_context(pipe);
637
638	nv30->viewport = *vpt;
639	nv30->dirty |= NV30_NEW_VIEWPORT;
640	/*nv30->draw_dirty |= NV30_NEW_VIEWPORT;*/
641}
642
643static void
644nv30_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
645			const struct pipe_vertex_buffer *vb)
646{
647	struct nv30_context *nv30 = nv30_context(pipe);
648
649	memcpy(nv30->vtxbuf, vb, sizeof(*vb) * count);
650	nv30->dirty |= NV30_NEW_ARRAYS;
651}
652
653static void
654nv30_set_vertex_elements(struct pipe_context *pipe, unsigned count,
655			 const struct pipe_vertex_element *ve)
656{
657	struct nv30_context *nv30 = nv30_context(pipe);
658
659	memcpy(nv30->vtxelt, ve, sizeof(*ve) * count);
660	nv30->dirty |= NV30_NEW_ARRAYS;
661}
662
663void
664nv30_init_state_functions(struct nv30_context *nv30)
665{
666	nv30->pipe.create_blend_state = nv30_blend_state_create;
667	nv30->pipe.bind_blend_state = nv30_blend_state_bind;
668	nv30->pipe.delete_blend_state = nv30_blend_state_delete;
669
670	nv30->pipe.create_sampler_state = nv30_sampler_state_create;
671	nv30->pipe.bind_sampler_states = nv30_sampler_state_bind;
672	nv30->pipe.delete_sampler_state = nv30_sampler_state_delete;
673	nv30->pipe.set_sampler_textures = nv30_set_sampler_texture;
674
675	nv30->pipe.create_rasterizer_state = nv30_rasterizer_state_create;
676	nv30->pipe.bind_rasterizer_state = nv30_rasterizer_state_bind;
677	nv30->pipe.delete_rasterizer_state = nv30_rasterizer_state_delete;
678
679	nv30->pipe.create_depth_stencil_alpha_state =
680		nv30_depth_stencil_alpha_state_create;
681	nv30->pipe.bind_depth_stencil_alpha_state =
682		nv30_depth_stencil_alpha_state_bind;
683	nv30->pipe.delete_depth_stencil_alpha_state =
684		nv30_depth_stencil_alpha_state_delete;
685
686	nv30->pipe.create_vs_state = nv30_vp_state_create;
687	nv30->pipe.bind_vs_state = nv30_vp_state_bind;
688	nv30->pipe.delete_vs_state = nv30_vp_state_delete;
689
690	nv30->pipe.create_fs_state = nv30_fp_state_create;
691	nv30->pipe.bind_fs_state = nv30_fp_state_bind;
692	nv30->pipe.delete_fs_state = nv30_fp_state_delete;
693
694	nv30->pipe.set_blend_color = nv30_set_blend_color;
695	nv30->pipe.set_clip_state = nv30_set_clip_state;
696	nv30->pipe.set_constant_buffer = nv30_set_constant_buffer;
697	nv30->pipe.set_framebuffer_state = nv30_set_framebuffer_state;
698	nv30->pipe.set_polygon_stipple = nv30_set_polygon_stipple;
699	nv30->pipe.set_scissor_state = nv30_set_scissor_state;
700	nv30->pipe.set_viewport_state = nv30_set_viewport_state;
701
702	nv30->pipe.set_vertex_buffers = nv30_set_vertex_buffers;
703	nv30->pipe.set_vertex_elements = nv30_set_vertex_elements;
704}
705
706