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