r300-gallium: Be more Gallium-ish in some of the math.
[platform/upstream/mesa.git] / src / gallium / drivers / r300 / r300_state.c
1 /*
2  * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
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  * on the rights to use, copy, modify, merge, publish, distribute, sub
8  * license, and/or sell copies of the Software, and to permit persons to whom
9  * the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
22
23 #include "util/u_math.h"
24 #include "util/u_pack_color.h"
25
26 #include "util/u_debug.h"
27 #include "pipe/internal/p_winsys_screen.h"
28
29 #include "r300_context.h"
30 #include "r300_reg.h"
31 #include "r300_state_inlines.h"
32 #include "r300_state_shader.h"
33
34 /* r300_state: Functions used to intialize state context by translating
35  * Gallium state objects into semi-native r300 state objects. */
36
37 /* Create a new blend state based on the CSO blend state.
38  *
39  * This encompasses alpha blending, logic/raster ops, and blend dithering. */
40 static void* r300_create_blend_state(struct pipe_context* pipe,
41                                      const struct pipe_blend_state* state)
42 {
43     struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state);
44
45     if (state->blend_enable) {
46         /* XXX for now, always do separate alpha...
47          * is it faster to do it with one reg? */
48         blend->blend_control = R300_ALPHA_BLEND_ENABLE |
49                 R300_SEPARATE_ALPHA_ENABLE |
50                 R300_READ_ENABLE |
51                 r300_translate_blend_function(state->rgb_func) |
52                 (r300_translate_blend_factor(state->rgb_src_factor) <<
53                     R300_SRC_BLEND_SHIFT) |
54                 (r300_translate_blend_factor(state->rgb_dst_factor) <<
55                     R300_DST_BLEND_SHIFT);
56         blend->alpha_blend_control =
57                 r300_translate_blend_function(state->alpha_func) |
58                 (r300_translate_blend_factor(state->alpha_src_factor) <<
59                     R300_SRC_BLEND_SHIFT) |
60                 (r300_translate_blend_factor(state->alpha_dst_factor) <<
61                     R300_DST_BLEND_SHIFT);
62     }
63
64     /* PIPE_LOGICOP_* don't need to be translated, fortunately. */
65     /* XXX are logicops still allowed if blending's disabled?
66      * Does Gallium take care of it for us? */
67     if (state->logicop_enable) {
68         blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE |
69                 (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT;
70     }
71
72     if (state->dither) {
73         blend->dither = R300_RB3D_DITHER_CTL_DITHER_MODE_LUT |
74                 R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT;
75     }
76
77     return (void*)blend;
78 }
79
80 /* Bind blend state. */
81 static void r300_bind_blend_state(struct pipe_context* pipe,
82                                   void* state)
83 {
84     struct r300_context* r300 = r300_context(pipe);
85
86     r300->blend_state = (struct r300_blend_state*)state;
87     r300->dirty_state |= R300_NEW_BLEND;
88 }
89
90 /* Free blend state. */
91 static void r300_delete_blend_state(struct pipe_context* pipe,
92                                     void* state)
93 {
94     FREE(state);
95 }
96
97 /* Set blend color.
98  * Setup both R300 and R500 registers, figure out later which one to write. */
99 static void r300_set_blend_color(struct pipe_context* pipe,
100                                  const struct pipe_blend_color* color)
101 {
102     struct r300_context* r300 = r300_context(pipe);
103     ubyte ur, ug, ub, ua;
104
105     ur = float_to_ubyte(color->color[0]);
106     ug = float_to_ubyte(color->color[1]);
107     ub = float_to_ubyte(color->color[2]);
108     ua = float_to_ubyte(color->color[3]);
109
110     util_pack_color(color->color, PIPE_FORMAT_A8R8G8B8_UNORM,
111             &r300->blend_color_state->blend_color);
112
113     /* XXX this is wrong */
114     r300->blend_color_state->blend_color_red_alpha = ur | (ua << 16);
115     r300->blend_color_state->blend_color_green_blue = ub | (ug << 16);
116
117     r300->dirty_state |= R300_NEW_BLEND_COLOR;
118 }
119
120 static void r300_set_clip_state(struct pipe_context* pipe,
121                                 const struct pipe_clip_state* state)
122 {
123     struct r300_context* r300 = r300_context(pipe);
124     /* XXX Draw */
125     draw_flush(r300->draw);
126     draw_set_clip_state(r300->draw, state);
127 }
128
129 static void
130     r300_set_constant_buffer(struct pipe_context* pipe,
131                              uint shader, uint index,
132                              const struct pipe_constant_buffer* buffer)
133 {
134     struct r300_context* r300 = r300_context(pipe);
135
136     /* This entire chunk of code seems ever-so-slightly baked.
137      * It's as if I've got pipe_buffer* matryoshkas... */
138     if (buffer && buffer->buffer && buffer->buffer->size) {
139         void* map = pipe->winsys->buffer_map(pipe->winsys, buffer->buffer,
140                                              PIPE_BUFFER_USAGE_CPU_READ);
141         memcpy(r300->shader_constants[shader].constants,
142             map, buffer->buffer->size);
143         pipe->winsys->buffer_unmap(pipe->winsys, buffer->buffer);
144
145         r300->shader_constants[shader].user_count =
146             buffer->buffer->size / (sizeof(float) * 4);
147     } else {
148         r300->shader_constants[shader].user_count = 0;
149     }
150
151     r300->dirty_state |= R300_NEW_CONSTANTS;
152 }
153
154 /* Create a new depth, stencil, and alpha state based on the CSO dsa state.
155  *
156  * This contains the depth buffer, stencil buffer, alpha test, and such.
157  * On the Radeon, depth and stencil buffer setup are intertwined, which is
158  * the reason for some of the strange-looking assignments across registers. */
159 static void*
160         r300_create_dsa_state(struct pipe_context* pipe,
161                               const struct pipe_depth_stencil_alpha_state* state)
162 {
163     struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);
164
165     /* Depth test setup. */
166     if (state->depth.enabled) {
167         dsa->z_buffer_control |= R300_Z_ENABLE;
168
169         if (state->depth.writemask) {
170             dsa->z_buffer_control |= R300_Z_WRITE_ENABLE;
171         }
172
173         dsa->z_stencil_control |=
174             (r300_translate_depth_stencil_function(state->depth.func) <<
175                 R300_Z_FUNC_SHIFT);
176     }
177
178     /* Stencil buffer setup. */
179     if (state->stencil[0].enabled) {
180         dsa->z_buffer_control |= R300_STENCIL_ENABLE;
181         dsa->z_stencil_control |=
182             (r300_translate_depth_stencil_function(state->stencil[0].func) <<
183                 R300_S_FRONT_FUNC_SHIFT) |
184             (r300_translate_stencil_op(state->stencil[0].fail_op) <<
185                 R300_S_FRONT_SFAIL_OP_SHIFT) |
186             (r300_translate_stencil_op(state->stencil[0].zpass_op) <<
187                 R300_S_FRONT_ZPASS_OP_SHIFT) |
188             (r300_translate_stencil_op(state->stencil[0].zfail_op) <<
189                 R300_S_FRONT_ZFAIL_OP_SHIFT);
190
191         dsa->stencil_ref_mask = (state->stencil[0].ref_value) |
192                 (state->stencil[0].valuemask << R300_STENCILMASK_SHIFT) |
193                 (state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT);
194
195         if (state->stencil[1].enabled) {
196             dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK;
197             dsa->z_stencil_control |=
198             (r300_translate_depth_stencil_function(state->stencil[1].func) <<
199                 R300_S_BACK_FUNC_SHIFT) |
200             (r300_translate_stencil_op(state->stencil[1].fail_op) <<
201                 R300_S_BACK_SFAIL_OP_SHIFT) |
202             (r300_translate_stencil_op(state->stencil[1].zpass_op) <<
203                 R300_S_BACK_ZPASS_OP_SHIFT) |
204             (r300_translate_stencil_op(state->stencil[1].zfail_op) <<
205                 R300_S_BACK_ZFAIL_OP_SHIFT);
206
207             dsa->stencil_ref_bf = (state->stencil[1].ref_value) |
208                 (state->stencil[1].valuemask << R300_STENCILMASK_SHIFT) |
209                 (state->stencil[1].writemask << R300_STENCILWRITEMASK_SHIFT);
210         }
211     }
212
213     /* Alpha test setup. */
214     if (state->alpha.enabled) {
215         dsa->alpha_function =
216             r300_translate_alpha_function(state->alpha.func) |
217             R300_FG_ALPHA_FUNC_ENABLE;
218         dsa->alpha_reference = CLAMP(state->alpha.ref_value * 1023.0f,
219                                      0, 1023);
220     } else {
221         dsa->z_buffer_top = R300_ZTOP_ENABLE;
222     }
223
224     return (void*)dsa;
225 }
226
227 /* Bind DSA state. */
228 static void r300_bind_dsa_state(struct pipe_context* pipe,
229                                 void* state)
230 {
231     struct r300_context* r300 = r300_context(pipe);
232
233     r300->dsa_state = (struct r300_dsa_state*)state;
234     r300->dirty_state |= R300_NEW_DSA;
235 }
236
237 /* Free DSA state. */
238 static void r300_delete_dsa_state(struct pipe_context* pipe,
239                                   void* state)
240 {
241     FREE(state);
242 }
243
244 static void r300_set_edgeflags(struct pipe_context* pipe,
245                                const unsigned* bitfield)
246 {
247     /* XXX you know it's bad when i915 has this blank too */
248 }
249
250 static void
251     r300_set_framebuffer_state(struct pipe_context* pipe,
252                                const struct pipe_framebuffer_state* state)
253 {
254     struct r300_context* r300 = r300_context(pipe);
255
256     draw_flush(r300->draw);
257
258     r300->framebuffer_state = *state;
259
260     r300->dirty_state |= R300_NEW_FRAMEBUFFERS;
261 }
262
263 /* Create fragment shader state. */
264 static void* r300_create_fs_state(struct pipe_context* pipe,
265                                   const struct pipe_shader_state* shader)
266 {
267     struct r300_context* r300 = r300_context(pipe);
268     struct r3xx_fragment_shader* fs = NULL;
269
270     if (r300_screen(r300->context.screen)->caps->is_r500) {
271         fs =
272             (struct r3xx_fragment_shader*)CALLOC_STRUCT(r500_fragment_shader);
273     } else {
274         fs =
275             (struct r3xx_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader);
276     }
277
278     /* Copy state directly into shader. */
279     fs->state = *shader;
280
281     tgsi_scan_shader(shader->tokens, &fs->info);
282
283     return (void*)fs;
284 }
285
286 /* Bind fragment shader state. */
287 static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
288 {
289     struct r300_context* r300 = r300_context(pipe);
290     struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader;
291
292     if (fs == NULL) {
293         r300->fs = NULL;
294         return;
295     } else if (!fs->translated) {
296         if (r300_screen(r300->context.screen)->caps->is_r500) {
297             r500_translate_fragment_shader(r300, (struct r500_fragment_shader*)fs);
298         } else {
299             r300_translate_fragment_shader(r300, (struct r300_fragment_shader*)fs);
300         }
301     }
302
303     fs->translated = TRUE;
304     r300->fs = fs;
305
306     r300->dirty_state |= R300_NEW_FRAGMENT_SHADER;
307 }
308
309 /* Delete fragment shader state. */
310 static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)
311 {
312     FREE(shader);
313 }
314
315 static void r300_set_polygon_stipple(struct pipe_context* pipe,
316                                      const struct pipe_poly_stipple* state)
317 {
318     /* XXX */
319 }
320
321 static INLINE int pack_float_16_6x(float f) {
322     return ((int)(f * 6.0) & 0xffff);
323 }
324
325 /* Create a new rasterizer state based on the CSO rasterizer state.
326  *
327  * This is a very large chunk of state, and covers most of the graphics
328  * backend (GB), geometry assembly (GA), and setup unit (SU) blocks.
329  *
330  * In a not entirely unironic sidenote, this state has nearly nothing to do
331  * with the actual block on the Radeon called the rasterizer (RS). */
332 static void* r300_create_rs_state(struct pipe_context* pipe,
333                                   const struct pipe_rasterizer_state* state)
334 {
335     struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state);
336
337     /* XXX this is part of HW TCL */
338     /* XXX endian control */
339     rs->vap_control_status = R300_VAP_TCL_BYPASS;
340
341     rs->point_size = pack_float_16_6x(state->point_size) |
342         (pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT);
343
344     rs->line_control = pack_float_16_6x(state->line_width) |
345         R300_GA_LINE_CNTL_END_TYPE_COMP;
346
347     /* Radeons don't think in "CW/CCW", they think in "front/back". */
348     if (state->front_winding == PIPE_WINDING_CW) {
349         rs->cull_mode = R300_FRONT_FACE_CW;
350
351         if (state->offset_cw) {
352             rs->polygon_offset_enable |= R300_FRONT_ENABLE;
353         }
354         if (state->offset_ccw) {
355             rs->polygon_offset_enable |= R300_BACK_ENABLE;
356         }
357     } else {
358         rs->cull_mode = R300_FRONT_FACE_CCW;
359
360         if (state->offset_ccw) {
361             rs->polygon_offset_enable |= R300_FRONT_ENABLE;
362         }
363         if (state->offset_cw) {
364             rs->polygon_offset_enable |= R300_BACK_ENABLE;
365         }
366     }
367     if (state->front_winding & state->cull_mode) {
368         rs->cull_mode |= R300_CULL_FRONT;
369     }
370     if (~(state->front_winding) & state->cull_mode) {
371         rs->cull_mode |= R300_CULL_BACK;
372     }
373
374     if (rs->polygon_offset_enable) {
375         rs->depth_offset_front = rs->depth_offset_back =
376             fui(state->offset_units);
377         rs->depth_scale_front = rs->depth_scale_back =
378             fui(state->offset_scale);
379     }
380
381     if (state->line_stipple_enable) {
382         rs->line_stipple_config =
383             R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE |
384             (fui((float)state->line_stipple_factor) &
385                 R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK);
386         /* XXX this might need to be scaled up */
387         rs->line_stipple_value = state->line_stipple_pattern;
388     }
389
390     rs->rs = *state;
391
392     return (void*)rs;
393 }
394
395 /* Bind rasterizer state. */
396 static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
397 {
398     struct r300_context* r300 = r300_context(pipe);
399     struct r300_rs_state* rs = (struct r300_rs_state*)state;
400
401     draw_set_rasterizer_state(r300->draw, &rs->rs);
402
403     r300->rs_state = rs;
404     r300->dirty_state |= R300_NEW_RASTERIZER;
405 }
406
407 /* Free rasterizer state. */
408 static void r300_delete_rs_state(struct pipe_context* pipe, void* state)
409 {
410     FREE(state);
411 }
412
413 static void*
414         r300_create_sampler_state(struct pipe_context* pipe,
415                                   const struct pipe_sampler_state* state)
416 {
417     struct r300_context* r300 = r300_context(pipe);
418     struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state);
419     int lod_bias;
420
421     sampler->filter0 |=
422         (r300_translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) |
423         (r300_translate_wrap(state->wrap_t) << R300_TX_WRAP_T_SHIFT) |
424         (r300_translate_wrap(state->wrap_r) << R300_TX_WRAP_R_SHIFT);
425
426     sampler->filter0 |= r300_translate_tex_filters(state->min_img_filter,
427                                                    state->mag_img_filter,
428                                                    state->min_mip_filter);
429
430     lod_bias = CLAMP((int)(state->lod_bias * 32), -(1 << 9), (1 << 9) - 1);
431
432     sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT;
433
434     sampler->filter1 |= r300_anisotropy(state->max_anisotropy);
435
436     util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM,
437                     &sampler->border_color);
438
439     /* R500-specific fixups and optimizations */
440     if (r300_screen(r300->context.screen)->caps->is_r500) {
441         sampler->filter1 |= R500_BORDER_FIX;
442     }
443
444     return (void*)sampler;
445 }
446
447 static void r300_bind_sampler_states(struct pipe_context* pipe,
448                                      unsigned count,
449                                      void** states)
450 {
451     struct r300_context* r300 = r300_context(pipe);
452     int i;
453
454     if (count > 8) {
455         return;
456     }
457
458     for (i = 0; i < count; i++) {
459         if (r300->sampler_states[i] != states[i]) {
460             r300->sampler_states[i] = (struct r300_sampler_state*)states[i];
461             r300->dirty_state |= (R300_NEW_SAMPLER << i);
462         }
463     }
464
465     r300->sampler_count = count;
466 }
467
468 static void r300_delete_sampler_state(struct pipe_context* pipe, void* state)
469 {
470     FREE(state);
471 }
472
473 static void r300_set_sampler_textures(struct pipe_context* pipe,
474                                       unsigned count,
475                                       struct pipe_texture** texture)
476 {
477     struct r300_context* r300 = r300_context(pipe);
478     int i;
479
480     /* XXX magic num */
481     if (count > 8) {
482         return;
483     }
484
485     for (i = 0; i < count; i++) {
486         if (r300->textures[i] != (struct r300_texture*)texture[i]) {
487             pipe_texture_reference((struct pipe_texture**)&r300->textures[i],
488                 texture[i]);
489             r300->dirty_state |= (R300_NEW_TEXTURE << i);
490         }
491     }
492
493     for (i = count; i < 8; i++) {
494         if (r300->textures[i]) {
495             pipe_texture_reference((struct pipe_texture**)&r300->textures[i],
496                 NULL);
497             r300->dirty_state |= (R300_NEW_TEXTURE << i);
498         }
499     }
500
501     r300->texture_count = count;
502 }
503
504 static void r300_set_scissor_state(struct pipe_context* pipe,
505                                    const struct pipe_scissor_state* state)
506 {
507     struct r300_context* r300 = r300_context(pipe);
508     draw_flush(r300->draw);
509
510     r300->scissor_state->scissor_top_left =
511         (state->minx << R300_SCISSORS_X_SHIFT) |
512         (state->miny << R300_SCISSORS_Y_SHIFT);
513     r300->scissor_state->scissor_bottom_right =
514         (state->maxx << R300_SCISSORS_X_SHIFT) |
515         (state->maxy << R300_SCISSORS_Y_SHIFT);
516
517     r300->dirty_state |= R300_NEW_SCISSOR;
518 }
519
520 static void r300_set_viewport_state(struct pipe_context* pipe,
521                                     const struct pipe_viewport_state* state)
522 {
523     struct r300_context* r300 = r300_context(pipe);
524     /* XXX handing this off to Draw for now */
525     draw_set_viewport_state(r300->draw, state);
526 }
527
528 static void r300_set_vertex_buffers(struct pipe_context* pipe,
529                                     unsigned count,
530                                     const struct pipe_vertex_buffer* buffers)
531 {
532     struct r300_context* r300 = r300_context(pipe);
533
534     memcpy(r300->vertex_buffers, buffers,
535         sizeof(struct pipe_vertex_buffer) * count);
536
537     r300->vertex_buffer_count = count;
538
539     draw_flush(r300->draw);
540     draw_set_vertex_buffers(r300->draw, count, buffers);
541 }
542
543 static void r300_set_vertex_elements(struct pipe_context* pipe,
544                                     unsigned count,
545                                     const struct pipe_vertex_element* elements)
546 {
547     struct r300_context* r300 = r300_context(pipe);
548     /* XXX Draw */
549     draw_flush(r300->draw);
550     draw_set_vertex_elements(r300->draw, count, elements);
551 }
552
553 static void* r300_create_vs_state(struct pipe_context* pipe,
554                                   const struct pipe_shader_state* state)
555 {
556     struct r300_context* context = r300_context(pipe);
557     /* XXX handing this off to Draw for now */
558     return draw_create_vertex_shader(context->draw, state);
559 }
560
561 static void r300_bind_vs_state(struct pipe_context* pipe, void* state) {
562     struct r300_context* context = r300_context(pipe);
563     /* XXX handing this off to Draw for now */
564     draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
565 }
566
567 static void r300_delete_vs_state(struct pipe_context* pipe, void* state)
568 {
569     struct r300_context* context = r300_context(pipe);
570     /* XXX handing this off to Draw for now */
571     draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
572 }
573
574 void r300_init_state_functions(struct r300_context* r300)
575 {
576     r300->context.create_blend_state = r300_create_blend_state;
577     r300->context.bind_blend_state = r300_bind_blend_state;
578     r300->context.delete_blend_state = r300_delete_blend_state;
579
580     r300->context.set_blend_color = r300_set_blend_color;
581
582     r300->context.set_clip_state = r300_set_clip_state;
583
584     r300->context.set_constant_buffer = r300_set_constant_buffer;
585
586     r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state;
587     r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state;
588     r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state;
589
590     r300->context.set_edgeflags = r300_set_edgeflags;
591
592     r300->context.set_framebuffer_state = r300_set_framebuffer_state;
593
594     r300->context.create_fs_state = r300_create_fs_state;
595     r300->context.bind_fs_state = r300_bind_fs_state;
596     r300->context.delete_fs_state = r300_delete_fs_state;
597
598     r300->context.set_polygon_stipple = r300_set_polygon_stipple;
599
600     r300->context.create_rasterizer_state = r300_create_rs_state;
601     r300->context.bind_rasterizer_state = r300_bind_rs_state;
602     r300->context.delete_rasterizer_state = r300_delete_rs_state;
603
604     r300->context.create_sampler_state = r300_create_sampler_state;
605     r300->context.bind_sampler_states = r300_bind_sampler_states;
606     r300->context.delete_sampler_state = r300_delete_sampler_state;
607
608     r300->context.set_sampler_textures = r300_set_sampler_textures;
609
610     r300->context.set_scissor_state = r300_set_scissor_state;
611
612     r300->context.set_viewport_state = r300_set_viewport_state;
613
614     r300->context.set_vertex_buffers = r300_set_vertex_buffers;
615     r300->context.set_vertex_elements = r300_set_vertex_elements;
616
617     r300->context.create_vs_state = r300_create_vs_state;
618     r300->context.bind_vs_state = r300_bind_vs_state;
619     r300->context.delete_vs_state = r300_delete_vs_state;
620 }