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