Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / gallium / drivers / nv50 / nv50_state.c
1 /*
2 * Copyright 2008 Ben Skeggs
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23 #include "pipe/p_state.h"
24 #include "pipe/p_defines.h"
25 #include "pipe/p_inlines.h"
26
27 #include "tgsi/tgsi_parse.h"
28
29 #include "nv50_context.h"
30 #include "nv50_texture.h"
31
32 #include "nouveau/nouveau_stateobj.h"
33
34 static void *
35 nv50_blend_state_create(struct pipe_context *pipe,
36 const struct pipe_blend_state *cso)
37 {
38 struct nouveau_stateobj *so = so_new(64, 0);
39 struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
40 struct nv50_blend_stateobj *bso = CALLOC_STRUCT(nv50_blend_stateobj);
41 unsigned cmask = 0, i;
42
43 /*XXX ignored:
44 * - dither
45 */
46
47 if (cso->blend_enable == 0) {
48 so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8);
49 for (i = 0; i < 8; i++)
50 so_data(so, 0);
51 } else {
52 so_method(so, tesla, NV50TCL_BLEND_ENABLE(0), 8);
53 for (i = 0; i < 8; i++)
54 so_data(so, 1);
55 so_method(so, tesla, NV50TCL_BLEND_EQUATION_RGB, 5);
56 so_data (so, nvgl_blend_eqn(cso->rgb_func));
57 so_data (so, 0x4000 | nvgl_blend_func(cso->rgb_src_factor));
58 so_data (so, 0x4000 | nvgl_blend_func(cso->rgb_dst_factor));
59 so_data (so, nvgl_blend_eqn(cso->alpha_func));
60 so_data (so, 0x4000 | nvgl_blend_func(cso->alpha_src_factor));
61 so_method(so, tesla, NV50TCL_BLEND_FUNC_DST_ALPHA, 1);
62 so_data (so, 0x4000 | nvgl_blend_func(cso->alpha_dst_factor));
63 }
64
65 if (cso->logicop_enable == 0 ) {
66 so_method(so, tesla, NV50TCL_LOGIC_OP_ENABLE, 1);
67 so_data (so, 0);
68 } else {
69 so_method(so, tesla, NV50TCL_LOGIC_OP_ENABLE, 2);
70 so_data (so, 1);
71 so_data (so, nvgl_logicop_func(cso->logicop_func));
72 }
73
74 if (cso->colormask & PIPE_MASK_R)
75 cmask |= (1 << 0);
76 if (cso->colormask & PIPE_MASK_G)
77 cmask |= (1 << 4);
78 if (cso->colormask & PIPE_MASK_B)
79 cmask |= (1 << 8);
80 if (cso->colormask & PIPE_MASK_A)
81 cmask |= (1 << 12);
82 so_method(so, tesla, NV50TCL_COLOR_MASK(0), 8);
83 for (i = 0; i < 8; i++)
84 so_data(so, cmask);
85
86 bso->pipe = *cso;
87 so_ref(so, &bso->so);
88 return (void *)bso;
89 }
90
91 static void
92 nv50_blend_state_bind(struct pipe_context *pipe, void *hwcso)
93 {
94 struct nv50_context *nv50 = nv50_context(pipe);
95
96 nv50->blend = hwcso;
97 nv50->dirty |= NV50_NEW_BLEND;
98 }
99
100 static void
101 nv50_blend_state_delete(struct pipe_context *pipe, void *hwcso)
102 {
103 struct nv50_blend_stateobj *bso = hwcso;
104
105 so_ref(NULL, &bso->so);
106 FREE(bso);
107 }
108
109 static INLINE unsigned
110 wrap_mode(unsigned wrap)
111 {
112 switch (wrap) {
113 case PIPE_TEX_WRAP_REPEAT:
114 return NV50TSC_1_0_WRAPS_REPEAT;
115 case PIPE_TEX_WRAP_MIRROR_REPEAT:
116 return NV50TSC_1_0_WRAPS_MIRROR_REPEAT;
117 case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
118 return NV50TSC_1_0_WRAPS_CLAMP_TO_EDGE;
119 case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
120 return NV50TSC_1_0_WRAPS_CLAMP_TO_BORDER;
121 case PIPE_TEX_WRAP_CLAMP:
122 return NV50TSC_1_0_WRAPS_CLAMP;
123 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
124 return NV50TSC_1_0_WRAPS_MIRROR_CLAMP_TO_EDGE;
125 case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
126 return NV50TSC_1_0_WRAPS_MIRROR_CLAMP_TO_BORDER;
127 case PIPE_TEX_WRAP_MIRROR_CLAMP:
128 return NV50TSC_1_0_WRAPS_MIRROR_CLAMP;
129 default:
130 NOUVEAU_ERR("unknown wrap mode: %d\n", wrap);
131 return NV50TSC_1_0_WRAPS_REPEAT;
132 }
133 }
134 static void *
135 nv50_sampler_state_create(struct pipe_context *pipe,
136 const struct pipe_sampler_state *cso)
137 {
138 unsigned *tsc = CALLOC(8, sizeof(unsigned));
139
140 tsc[0] = (0x00024000 |
141 (wrap_mode(cso->wrap_s) << 0) |
142 (wrap_mode(cso->wrap_t) << 3) |
143 (wrap_mode(cso->wrap_r) << 6));
144
145 switch (cso->mag_img_filter) {
146 case PIPE_TEX_FILTER_LINEAR:
147 tsc[1] |= NV50TSC_1_1_MAGF_LINEAR;
148 break;
149 case PIPE_TEX_FILTER_NEAREST:
150 default:
151 tsc[1] |= NV50TSC_1_1_MAGF_NEAREST;
152 break;
153 }
154
155 switch (cso->min_img_filter) {
156 case PIPE_TEX_FILTER_LINEAR:
157 tsc[1] |= NV50TSC_1_1_MINF_LINEAR;
158 break;
159 case PIPE_TEX_FILTER_NEAREST:
160 default:
161 tsc[1] |= NV50TSC_1_1_MINF_NEAREST;
162 break;
163 }
164
165 switch (cso->min_mip_filter) {
166 case PIPE_TEX_MIPFILTER_LINEAR:
167 tsc[1] |= NV50TSC_1_1_MIPF_LINEAR;
168 break;
169 case PIPE_TEX_MIPFILTER_NEAREST:
170 tsc[1] |= NV50TSC_1_1_MIPF_NEAREST;
171 break;
172 case PIPE_TEX_MIPFILTER_NONE:
173 default:
174 tsc[1] |= NV50TSC_1_1_MIPF_NONE;
175 break;
176 }
177
178 return (void *)tsc;
179 }
180
181 static void
182 nv50_sampler_state_bind(struct pipe_context *pipe, unsigned nr, void **sampler)
183 {
184 struct nv50_context *nv50 = nv50_context(pipe);
185 int i;
186
187 nv50->sampler_nr = nr;
188 for (i = 0; i < nv50->sampler_nr; i++)
189 nv50->sampler[i] = sampler[i];
190
191 nv50->dirty |= NV50_NEW_SAMPLER;
192 }
193
194 static void
195 nv50_sampler_state_delete(struct pipe_context *pipe, void *hwcso)
196 {
197 FREE(hwcso);
198 }
199
200 static void
201 nv50_set_sampler_texture(struct pipe_context *pipe, unsigned nr,
202 struct pipe_texture **pt)
203 {
204 struct nv50_context *nv50 = nv50_context(pipe);
205 int i;
206
207 for (i = 0; i < nr; i++)
208 pipe_texture_reference((void *)&nv50->miptree[i], pt[i]);
209 for (i = nr; i < nv50->miptree_nr; i++)
210 pipe_texture_reference((void *)&nv50->miptree[i], NULL);
211
212 nv50->miptree_nr = nr;
213 nv50->dirty |= NV50_NEW_TEXTURE;
214 }
215
216 static void *
217 nv50_rasterizer_state_create(struct pipe_context *pipe,
218 const struct pipe_rasterizer_state *cso)
219 {
220 struct nouveau_stateobj *so = so_new(64, 0);
221 struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
222 struct nv50_rasterizer_stateobj *rso =
223 CALLOC_STRUCT(nv50_rasterizer_stateobj);
224
225 /*XXX: ignored
226 * - light_twosize
227 * - point_smooth
228 * - multisample
229 * - point_sprite / sprite_coord_mode
230 */
231
232 so_method(so, tesla, NV50TCL_SHADE_MODEL, 1);
233 so_data (so, cso->flatshade ? NV50TCL_SHADE_MODEL_FLAT :
234 NV50TCL_SHADE_MODEL_SMOOTH);
235
236 so_method(so, tesla, NV50TCL_LINE_WIDTH, 1);
237 so_data (so, fui(cso->line_width));
238 so_method(so, tesla, NV50TCL_LINE_SMOOTH_ENABLE, 1);
239 so_data (so, cso->line_smooth ? 1 : 0);
240 if (cso->line_stipple_enable) {
241 so_method(so, tesla, NV50TCL_LINE_STIPPLE_ENABLE, 1);
242 so_data (so, 1);
243 so_method(so, tesla, NV50TCL_LINE_STIPPLE_PATTERN, 1);
244 so_data (so, (cso->line_stipple_pattern << 8) |
245 cso->line_stipple_factor);
246 } else {
247 so_method(so, tesla, NV50TCL_LINE_STIPPLE_ENABLE, 1);
248 so_data (so, 0);
249 }
250
251 so_method(so, tesla, NV50TCL_POINT_SIZE, 1);
252 so_data (so, fui(cso->point_size));
253
254 so_method(so, tesla, NV50TCL_POLYGON_MODE_FRONT, 3);
255 if (cso->front_winding == PIPE_WINDING_CCW) {
256 so_data(so, nvgl_polygon_mode(cso->fill_ccw));
257 so_data(so, nvgl_polygon_mode(cso->fill_cw));
258 } else {
259 so_data(so, nvgl_polygon_mode(cso->fill_cw));
260 so_data(so, nvgl_polygon_mode(cso->fill_ccw));
261 }
262 so_data(so, cso->poly_smooth ? 1 : 0);
263
264 so_method(so, tesla, NV50TCL_CULL_FACE_ENABLE, 3);
265 so_data (so, cso->cull_mode != PIPE_WINDING_NONE);
266 if (cso->front_winding == PIPE_WINDING_CCW) {
267 so_data(so, NV50TCL_FRONT_FACE_CCW);
268 switch (cso->cull_mode) {
269 case PIPE_WINDING_CCW:
270 so_data(so, NV50TCL_CULL_FACE_FRONT);
271 break;
272 case PIPE_WINDING_CW:
273 so_data(so, NV50TCL_CULL_FACE_BACK);
274 break;
275 case PIPE_WINDING_BOTH:
276 so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK);
277 break;
278 default:
279 so_data(so, NV50TCL_CULL_FACE_BACK);
280 break;
281 }
282 } else {
283 so_data(so, NV50TCL_FRONT_FACE_CW);
284 switch (cso->cull_mode) {
285 case PIPE_WINDING_CCW:
286 so_data(so, NV50TCL_CULL_FACE_BACK);
287 break;
288 case PIPE_WINDING_CW:
289 so_data(so, NV50TCL_CULL_FACE_FRONT);
290 break;
291 case PIPE_WINDING_BOTH:
292 so_data(so, NV50TCL_CULL_FACE_FRONT_AND_BACK);
293 break;
294 default:
295 so_data(so, NV50TCL_CULL_FACE_BACK);
296 break;
297 }
298 }
299
300 so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_ENABLE, 1);
301 so_data (so, cso->poly_stipple_enable ? 1 : 0);
302
303 so_method(so, tesla, NV50TCL_POLYGON_OFFSET_POINT_ENABLE, 3);
304 if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_POINT) ||
305 (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_POINT))
306 so_data(so, 1);
307 else
308 so_data(so, 0);
309 if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_LINE) ||
310 (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_LINE))
311 so_data(so, 1);
312 else
313 so_data(so, 0);
314 if ((cso->offset_cw && cso->fill_cw == PIPE_POLYGON_MODE_FILL) ||
315 (cso->offset_ccw && cso->fill_ccw == PIPE_POLYGON_MODE_FILL))
316 so_data(so, 1);
317 else
318 so_data(so, 0);
319
320 if (cso->offset_cw || cso->offset_ccw) {
321 so_method(so, tesla, NV50TCL_POLYGON_OFFSET_FACTOR, 1);
322 so_data (so, fui(cso->offset_scale));
323 so_method(so, tesla, NV50TCL_POLYGON_OFFSET_UNITS, 1);
324 so_data (so, fui(cso->offset_units));
325 }
326
327 rso->pipe = *cso;
328 so_ref(so, &rso->so);
329 return (void *)rso;
330 }
331
332 static void
333 nv50_rasterizer_state_bind(struct pipe_context *pipe, void *hwcso)
334 {
335 struct nv50_context *nv50 = nv50_context(pipe);
336
337 nv50->rasterizer = hwcso;
338 nv50->dirty |= NV50_NEW_RASTERIZER;
339 }
340
341 static void
342 nv50_rasterizer_state_delete(struct pipe_context *pipe, void *hwcso)
343 {
344 struct nv50_rasterizer_stateobj *rso = hwcso;
345
346 so_ref(NULL, &rso->so);
347 FREE(rso);
348 }
349
350 static void *
351 nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe,
352 const struct pipe_depth_stencil_alpha_state *cso)
353 {
354 struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla;
355 struct nv50_zsa_stateobj *zsa = CALLOC_STRUCT(nv50_zsa_stateobj);
356 struct nouveau_stateobj *so = so_new(64, 0);
357
358 so_method(so, tesla, NV50TCL_DEPTH_WRITE_ENABLE, 1);
359 so_data (so, cso->depth.writemask ? 1 : 0);
360 if (cso->depth.enabled) {
361 so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1);
362 so_data (so, 1);
363 so_method(so, tesla, NV50TCL_DEPTH_TEST_FUNC, 1);
364 so_data (so, nvgl_comparison_op(cso->depth.func));
365 } else {
366 so_method(so, tesla, NV50TCL_DEPTH_TEST_ENABLE, 1);
367 so_data (so, 0);
368 }
369
370 /*XXX: yes, I know they're backwards.. header needs fixing */
371 if (cso->stencil[0].enabled) {
372 so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 5);
373 so_data (so, 1);
374 so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op));
375 so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
376 so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
377 so_data (so, nvgl_comparison_op(cso->stencil[0].func));
378 so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 3);
379 so_data (so, cso->stencil[0].ref_value);
380 so_data (so, cso->stencil[0].write_mask);
381 so_data (so, cso->stencil[0].value_mask);
382 } else {
383 so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 1);
384 so_data (so, 0);
385 }
386
387 if (cso->stencil[1].enabled) {
388 so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 8);
389 so_data (so, 1);
390 so_data (so, nvgl_stencil_op(cso->stencil[1].fail_op));
391 so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
392 so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
393 so_data (so, nvgl_comparison_op(cso->stencil[1].func));
394 so_data (so, cso->stencil[1].ref_value);
395 so_data (so, cso->stencil[1].write_mask);
396 so_data (so, cso->stencil[1].value_mask);
397 } else {
398 so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 1);
399 so_data (so, 0);
400 }
401
402 if (cso->alpha.enabled) {
403 so_method(so, tesla, NV50TCL_ALPHA_TEST_ENABLE, 1);
404 so_data (so, 1);
405 so_method(so, tesla, NV50TCL_ALPHA_TEST_REF, 2);
406 so_data (so, fui(cso->alpha.ref));
407 so_data (so, nvgl_comparison_op(cso->alpha.func));
408 } else {
409 so_method(so, tesla, NV50TCL_ALPHA_TEST_ENABLE, 1);
410 so_data (so, 0);
411 }
412
413 zsa->pipe = *cso;
414 so_ref(so, &zsa->so);
415 return (void *)zsa;
416 }
417
418 static void
419 nv50_depth_stencil_alpha_state_bind(struct pipe_context *pipe, void *hwcso)
420 {
421 struct nv50_context *nv50 = nv50_context(pipe);
422
423 nv50->zsa = hwcso;
424 nv50->dirty |= NV50_NEW_ZSA;
425 }
426
427 static void
428 nv50_depth_stencil_alpha_state_delete(struct pipe_context *pipe, void *hwcso)
429 {
430 struct nv50_zsa_stateobj *zsa = hwcso;
431
432 so_ref(NULL, &zsa->so);
433 FREE(zsa);
434 }
435
436 static void *
437 nv50_vp_state_create(struct pipe_context *pipe,
438 const struct pipe_shader_state *cso)
439 {
440 struct nv50_program *p = CALLOC_STRUCT(nv50_program);
441
442 p->pipe.tokens = tgsi_dup_tokens(cso->tokens);
443 p->type = PIPE_SHADER_VERTEX;
444 tgsi_scan_shader(p->pipe.tokens, &p->info);
445 return (void *)p;
446 }
447
448 static void
449 nv50_vp_state_bind(struct pipe_context *pipe, void *hwcso)
450 {
451 struct nv50_context *nv50 = nv50_context(pipe);
452
453 nv50->vertprog = hwcso;
454 nv50->dirty |= NV50_NEW_VERTPROG;
455 }
456
457 static void
458 nv50_vp_state_delete(struct pipe_context *pipe, void *hwcso)
459 {
460 struct nv50_context *nv50 = nv50_context(pipe);
461 struct nv50_program *p = hwcso;
462
463 nv50_program_destroy(nv50, p);
464 FREE((void*)p->pipe.tokens);
465 FREE(p);
466 }
467
468 static void *
469 nv50_fp_state_create(struct pipe_context *pipe,
470 const struct pipe_shader_state *cso)
471 {
472 struct nv50_program *p = CALLOC_STRUCT(nv50_program);
473
474 p->pipe.tokens = tgsi_dup_tokens(cso->tokens);
475 p->type = PIPE_SHADER_FRAGMENT;
476 tgsi_scan_shader(p->pipe.tokens, &p->info);
477 return (void *)p;
478 }
479
480 static void
481 nv50_fp_state_bind(struct pipe_context *pipe, void *hwcso)
482 {
483 struct nv50_context *nv50 = nv50_context(pipe);
484
485 nv50->fragprog = hwcso;
486 nv50->dirty |= NV50_NEW_FRAGPROG;
487 }
488
489 static void
490 nv50_fp_state_delete(struct pipe_context *pipe, void *hwcso)
491 {
492 struct nv50_context *nv50 = nv50_context(pipe);
493 struct nv50_program *p = hwcso;
494
495 nv50_program_destroy(nv50, p);
496 FREE((void*)p->pipe.tokens);
497 FREE(p);
498 }
499
500 static void
501 nv50_set_blend_color(struct pipe_context *pipe,
502 const struct pipe_blend_color *bcol)
503 {
504 struct nv50_context *nv50 = nv50_context(pipe);
505
506 nv50->blend_colour = *bcol;
507 nv50->dirty |= NV50_NEW_BLEND_COLOUR;
508 }
509
510 static void
511 nv50_set_clip_state(struct pipe_context *pipe,
512 const struct pipe_clip_state *clip)
513 {
514 }
515
516 static void
517 nv50_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
518 const struct pipe_constant_buffer *buf )
519 {
520 struct nv50_context *nv50 = nv50_context(pipe);
521
522 if (shader == PIPE_SHADER_VERTEX) {
523 nv50->constbuf[PIPE_SHADER_VERTEX] = buf->buffer;
524 nv50->dirty |= NV50_NEW_VERTPROG_CB;
525 } else
526 if (shader == PIPE_SHADER_FRAGMENT) {
527 nv50->constbuf[PIPE_SHADER_FRAGMENT] = buf->buffer;
528 nv50->dirty |= NV50_NEW_FRAGPROG_CB;
529 }
530 }
531
532 static void
533 nv50_set_framebuffer_state(struct pipe_context *pipe,
534 const struct pipe_framebuffer_state *fb)
535 {
536 struct nv50_context *nv50 = nv50_context(pipe);
537
538 nv50->framebuffer = *fb;
539 nv50->dirty |= NV50_NEW_FRAMEBUFFER;
540 }
541
542 static void
543 nv50_set_polygon_stipple(struct pipe_context *pipe,
544 const struct pipe_poly_stipple *stipple)
545 {
546 struct nv50_context *nv50 = nv50_context(pipe);
547
548 nv50->stipple = *stipple;
549 nv50->dirty |= NV50_NEW_STIPPLE;
550 }
551
552 static void
553 nv50_set_scissor_state(struct pipe_context *pipe,
554 const struct pipe_scissor_state *s)
555 {
556 struct nv50_context *nv50 = nv50_context(pipe);
557
558 nv50->scissor = *s;
559 nv50->dirty |= NV50_NEW_SCISSOR;
560 }
561
562 static void
563 nv50_set_viewport_state(struct pipe_context *pipe,
564 const struct pipe_viewport_state *vpt)
565 {
566 struct nv50_context *nv50 = nv50_context(pipe);
567
568 nv50->viewport = *vpt;
569 nv50->dirty |= NV50_NEW_VIEWPORT;
570 }
571
572 static void
573 nv50_set_vertex_buffers(struct pipe_context *pipe, unsigned count,
574 const struct pipe_vertex_buffer *vb)
575 {
576 struct nv50_context *nv50 = nv50_context(pipe);
577
578 memcpy(nv50->vtxbuf, vb, sizeof(*vb) * count);
579 nv50->vtxbuf_nr = count;
580
581 nv50->dirty |= NV50_NEW_ARRAYS;
582 }
583
584 static void
585 nv50_set_vertex_elements(struct pipe_context *pipe, unsigned count,
586 const struct pipe_vertex_element *ve)
587 {
588 struct nv50_context *nv50 = nv50_context(pipe);
589
590 memcpy(nv50->vtxelt, ve, sizeof(*ve) * count);
591 nv50->vtxelt_nr = count;
592
593 nv50->dirty |= NV50_NEW_ARRAYS;
594 }
595
596 void
597 nv50_init_state_functions(struct nv50_context *nv50)
598 {
599 nv50->pipe.create_blend_state = nv50_blend_state_create;
600 nv50->pipe.bind_blend_state = nv50_blend_state_bind;
601 nv50->pipe.delete_blend_state = nv50_blend_state_delete;
602
603 nv50->pipe.create_sampler_state = nv50_sampler_state_create;
604 nv50->pipe.bind_sampler_states = nv50_sampler_state_bind;
605 nv50->pipe.delete_sampler_state = nv50_sampler_state_delete;
606 nv50->pipe.set_sampler_textures = nv50_set_sampler_texture;
607
608 nv50->pipe.create_rasterizer_state = nv50_rasterizer_state_create;
609 nv50->pipe.bind_rasterizer_state = nv50_rasterizer_state_bind;
610 nv50->pipe.delete_rasterizer_state = nv50_rasterizer_state_delete;
611
612 nv50->pipe.create_depth_stencil_alpha_state =
613 nv50_depth_stencil_alpha_state_create;
614 nv50->pipe.bind_depth_stencil_alpha_state =
615 nv50_depth_stencil_alpha_state_bind;
616 nv50->pipe.delete_depth_stencil_alpha_state =
617 nv50_depth_stencil_alpha_state_delete;
618
619 nv50->pipe.create_vs_state = nv50_vp_state_create;
620 nv50->pipe.bind_vs_state = nv50_vp_state_bind;
621 nv50->pipe.delete_vs_state = nv50_vp_state_delete;
622
623 nv50->pipe.create_fs_state = nv50_fp_state_create;
624 nv50->pipe.bind_fs_state = nv50_fp_state_bind;
625 nv50->pipe.delete_fs_state = nv50_fp_state_delete;
626
627 nv50->pipe.set_blend_color = nv50_set_blend_color;
628 nv50->pipe.set_clip_state = nv50_set_clip_state;
629 nv50->pipe.set_constant_buffer = nv50_set_constant_buffer;
630 nv50->pipe.set_framebuffer_state = nv50_set_framebuffer_state;
631 nv50->pipe.set_polygon_stipple = nv50_set_polygon_stipple;
632 nv50->pipe.set_scissor_state = nv50_set_scissor_state;
633 nv50->pipe.set_viewport_state = nv50_set_viewport_state;
634
635 nv50->pipe.set_vertex_buffers = nv50_set_vertex_buffers;
636 nv50->pipe.set_vertex_elements = nv50_set_vertex_elements;
637 }
638