r300_state.c revision 8c8bdcde6d9eb1cda7bf268cd75ca7676e220075
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 "r300_context.h"
27#include "r300_reg.h"
28
29/* r300_state: Functions used to intialize state context by translating
30 * Gallium state objects into semi-native r300 state objects.
31 *
32 * XXX break this file up into pieces if it gets too big! */
33
34/* Pack a float into a dword. */
35static uint32_t pack_float_32(float f)
36{
37    union {
38        float f;
39        uint32_t u;
40    } u;
41
42    u.f = f;
43    return u.u;
44}
45
46static uint32_t translate_blend_function(int blend_func) {
47    switch (blend_func) {
48        case PIPE_BLEND_ADD:
49            return R300_COMB_FCN_ADD_CLAMP;
50        case PIPE_BLEND_SUBTRACT:
51            return R300_COMB_FCN_SUB_CLAMP;
52        case PIPE_BLEND_REVERSE_SUBTRACT:
53            return R300_COMB_FCN_RSUB_CLAMP;
54        case PIPE_BLEND_MIN:
55            return R300_COMB_FCN_MIN;
56        case PIPE_BLEND_MAX:
57            return R300_COMB_FCN_MAX;
58        default:
59            /* XXX should be unreachable, handle this */
60            break;
61    }
62    return 0;
63}
64
65/* XXX we can also offer the D3D versions of some of these... */
66static uint32_t translate_blend_factor(int blend_fact) {
67    switch (blend_fact) {
68        case PIPE_BLENDFACTOR_ONE:
69            return R300_BLEND_GL_ONE;
70        case PIPE_BLENDFACTOR_SRC_COLOR:
71            return R300_BLEND_GL_SRC_COLOR;
72        case PIPE_BLENDFACTOR_SRC_ALPHA:
73            return R300_BLEND_GL_SRC_ALPHA;
74        case PIPE_BLENDFACTOR_DST_ALPHA:
75            return R300_BLEND_GL_DST_ALPHA;
76        case PIPE_BLENDFACTOR_DST_COLOR:
77            return R300_BLEND_GL_DST_COLOR;
78        case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
79            return R300_BLEND_GL_SRC_ALPHA_SATURATE;
80        case PIPE_BLENDFACTOR_CONST_COLOR:
81            return R300_BLEND_GL_CONST_COLOR;
82        case PIPE_BLENDFACTOR_CONST_ALPHA:
83            return R300_BLEND_GL_CONST_ALPHA;
84        /* XXX WTF are these?
85        case PIPE_BLENDFACTOR_SRC1_COLOR:
86        case PIPE_BLENDFACTOR_SRC1_ALPHA: */
87        case PIPE_BLENDFACTOR_ZERO:
88            return R300_BLEND_GL_ZERO;
89        case PIPE_BLENDFACTOR_INV_SRC_COLOR:
90            return R300_BLEND_GL_ONE_MINUS_SRC_COLOR;
91        case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
92            return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA;
93        case PIPE_BLENDFACTOR_INV_DST_ALPHA:
94            return R300_BLEND_GL_ONE_MINUS_DST_ALPHA;
95        case PIPE_BLENDFACTOR_INV_DST_COLOR:
96            return R300_BLEND_GL_ONE_MINUS_DST_COLOR;
97        case PIPE_BLENDFACTOR_INV_CONST_COLOR:
98            return R300_BLEND_GL_ONE_MINUS_CONST_COLOR;
99        case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
100            return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA;
101        /* XXX see above
102        case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
103        case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: */
104        default:
105            /* XXX the mythical 0x16 blend factor! */
106            break;
107    }
108    return 0;
109}
110
111/* Create a new blend state based on the CSO blend state.
112 *
113 * This encompasses alpha blending, logic/raster ops, and blend dithering. */
114static void* r300_create_blend_state(struct pipe_context* pipe,
115                                     const struct pipe_blend_state* state)
116{
117    struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state);
118
119    if (state->blend_enable) {
120        /* XXX for now, always do separate alpha...
121         * is it faster to do it with one reg? */
122        blend->blend_control = R300_ALPHA_BLEND_ENABLE |
123                R300_SEPARATE_ALPHA_ENABLE |
124                R300_READ_ENABLE |
125                translate_blend_function(state->rgb_func) |
126                (translate_blend_factor(state->rgb_src_factor) <<
127                    R300_SRC_BLEND_SHIFT) |
128                (translate_blend_factor(state->rgb_dst_factor) <<
129                    R300_DST_BLEND_SHIFT);
130        blend->alpha_blend_control =
131                translate_blend_function(state->alpha_func) |
132                (translate_blend_factor(state->alpha_src_factor) <<
133                    R300_SRC_BLEND_SHIFT) |
134                (translate_blend_factor(state->alpha_dst_factor) <<
135                    R300_DST_BLEND_SHIFT);
136    }
137
138    /* PIPE_LOGICOP_* don't need to be translated, fortunately. */
139    /* XXX are logicops still allowed if blending's disabled?
140     * Does Gallium take care of it for us? */
141    if (state->logicop_enable) {
142        blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE |
143                (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT;
144    }
145
146    if (state->dither) {
147        blend->dither = R300_RB3D_DITHER_CTL_DITHER_MODE_LUT |
148                R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT;
149    }
150
151    return (void*)blend;
152}
153
154/* Bind blend state. */
155static void r300_bind_blend_state(struct pipe_context* pipe,
156                                  void* state)
157{
158    struct r300_context* r300 = r300_context(pipe);
159
160    r300->blend_state = (struct r300_blend_state*)state;
161    r300->dirty_state |= R300_NEW_BLEND;
162}
163
164/* Free blend state. */
165static void r300_delete_blend_state(struct pipe_context* pipe,
166                                    void* state)
167{
168    FREE(state);
169}
170
171/* Set blend color.
172 * Setup both R300 and R500 registers, figure out later which one to write. */
173static void r300_set_blend_color(struct pipe_context* pipe,
174                                 const struct pipe_blend_color* color)
175{
176    struct r300_context* r300 = r300_context(pipe);
177    uint32_t r, g, b, a;
178    ubyte ur, ug, ub, ua;
179
180    r = util_iround(color->color[0] * 1023.0f);
181    g = util_iround(color->color[1] * 1023.0f);
182    b = util_iround(color->color[2] * 1023.0f);
183    a = util_iround(color->color[3] * 1023.0f);
184
185    ur = float_to_ubyte(color->color[0]);
186    ug = float_to_ubyte(color->color[1]);
187    ub = float_to_ubyte(color->color[2]);
188    ua = float_to_ubyte(color->color[3]);
189
190    r300->blend_color_state->blend_color = (a << 24) | (r << 16) | (g << 8) | b;
191
192    r300->blend_color_state->blend_color_red_alpha = ur | (ua << 16);
193    r300->blend_color_state->blend_color_green_blue = ub | (ug << 16);
194
195    r300->dirty_state |= R300_NEW_BLEND_COLOR;
196}
197
198static void r300_set_clip_state(struct pipe_context* pipe,
199                                const struct pipe_clip_state* state)
200{
201    struct r300_context* r300 = r300_context(pipe);
202    /* XXX Draw */
203    draw_flush(r300->draw);
204    draw_set_clip_state(r300->draw, state);
205}
206
207static void
208    r300_set_constant_buffer(struct pipe_context* pipe,
209                             uint shader, uint index,
210                             const struct pipe_constant_buffer* buffer)
211{
212    /* XXX */
213}
214
215static uint32_t translate_depth_stencil_function(int zs_func) {
216    switch (zs_func) {
217        case PIPE_FUNC_NEVER:
218            return R300_ZS_NEVER;
219        case PIPE_FUNC_LESS:
220            return R300_ZS_LESS;
221        case PIPE_FUNC_EQUAL:
222            return R300_ZS_EQUAL;
223        case PIPE_FUNC_LEQUAL:
224            return R300_ZS_LEQUAL;
225        case PIPE_FUNC_GREATER:
226            return R300_ZS_GREATER;
227        case PIPE_FUNC_NOTEQUAL:
228            return R300_ZS_NOTEQUAL;
229        case PIPE_FUNC_GEQUAL:
230            return R300_ZS_GEQUAL;
231        case PIPE_FUNC_ALWAYS:
232            return R300_ZS_ALWAYS;
233        default:
234            /* XXX shouldn't be reachable */
235            break;
236    }
237    return 0;
238}
239
240static uint32_t translate_stencil_op(int s_op) {
241    switch (s_op) {
242        case PIPE_STENCIL_OP_KEEP:
243            return R300_ZS_KEEP;
244        case PIPE_STENCIL_OP_ZERO:
245            return R300_ZS_ZERO;
246        case PIPE_STENCIL_OP_REPLACE:
247            return R300_ZS_REPLACE;
248        case PIPE_STENCIL_OP_INCR:
249            return R300_ZS_INCR;
250        case PIPE_STENCIL_OP_DECR:
251            return R300_ZS_DECR;
252        case PIPE_STENCIL_OP_INCR_WRAP:
253            return R300_ZS_INCR_WRAP;
254        case PIPE_STENCIL_OP_DECR_WRAP:
255            return R300_ZS_DECR_WRAP;
256        case PIPE_STENCIL_OP_INVERT:
257            return R300_ZS_INVERT;
258        default:
259            /* XXX shouldn't be reachable */
260            break;
261    }
262    return 0;
263}
264
265static uint32_t translate_alpha_function(int alpha_func) {
266    switch (alpha_func) {
267        case PIPE_FUNC_NEVER:
268            return R300_FG_ALPHA_FUNC_NEVER;
269        case PIPE_FUNC_LESS:
270            return R300_FG_ALPHA_FUNC_LESS;
271        case PIPE_FUNC_EQUAL:
272            return R300_FG_ALPHA_FUNC_EQUAL;
273        case PIPE_FUNC_LEQUAL:
274            return R300_FG_ALPHA_FUNC_LE;
275        case PIPE_FUNC_GREATER:
276            return R300_FG_ALPHA_FUNC_GREATER;
277        case PIPE_FUNC_NOTEQUAL:
278            return R300_FG_ALPHA_FUNC_NOTEQUAL;
279        case PIPE_FUNC_GEQUAL:
280            return R300_FG_ALPHA_FUNC_GE;
281        case PIPE_FUNC_ALWAYS:
282            return R300_FG_ALPHA_FUNC_ALWAYS;
283        default:
284            /* XXX shouldn't be reachable */
285            break;
286    }
287    return 0;
288}
289
290/* Create a new depth, stencil, and alpha state based on the CSO dsa state.
291 *
292 * This contains the depth buffer, stencil buffer, alpha test, and such.
293 * On the Radeon, depth and stencil buffer setup are intertwined, which is
294 * the reason for some of the strange-looking assignments across registers. */
295static void*
296        r300_create_dsa_state(struct pipe_context* pipe,
297                              const struct pipe_depth_stencil_alpha_state* state)
298{
299    struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);
300
301    /* Depth test setup. */
302    if (state->depth.enabled) {
303        dsa->z_buffer_control |= R300_Z_ENABLE;
304
305        if (state->depth.writemask) {
306            dsa->z_buffer_control |= R300_Z_WRITE_ENABLE;
307        }
308
309        dsa->z_stencil_control |=
310                (translate_depth_stencil_function(state->depth.func) <<
311                    R300_Z_FUNC_SHIFT);
312    }
313
314    /* Stencil buffer setup. */
315    if (state->stencil[0].enabled) {
316        dsa->z_buffer_control |= R300_STENCIL_ENABLE;
317        dsa->z_stencil_control |=
318                (translate_depth_stencil_function(state->stencil[0].func) <<
319                    R300_S_FRONT_FUNC_SHIFT) |
320                (translate_stencil_op(state->stencil[0].fail_op) <<
321                    R300_S_FRONT_SFAIL_OP_SHIFT) |
322                (translate_stencil_op(state->stencil[0].zpass_op) <<
323                    R300_S_FRONT_ZPASS_OP_SHIFT) |
324                (translate_stencil_op(state->stencil[0].zfail_op) <<
325                    R300_S_FRONT_ZFAIL_OP_SHIFT);
326
327        dsa->stencil_ref_mask = (state->stencil[0].ref_value) |
328                (state->stencil[0].value_mask << R300_STENCILMASK_SHIFT) |
329                (state->stencil[0].write_mask << R300_STENCILWRITEMASK_SHIFT);
330
331        if (state->stencil[1].enabled) {
332            dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK;
333            dsa->z_stencil_control |=
334                    (translate_depth_stencil_function(state->stencil[1].func) <<
335                        R300_S_BACK_FUNC_SHIFT) |
336                    (translate_stencil_op(state->stencil[1].fail_op) <<
337                        R300_S_BACK_SFAIL_OP_SHIFT) |
338                    (translate_stencil_op(state->stencil[1].zpass_op) <<
339                        R300_S_BACK_ZPASS_OP_SHIFT) |
340                    (translate_stencil_op(state->stencil[1].zfail_op) <<
341                        R300_S_BACK_ZFAIL_OP_SHIFT);
342
343            dsa->stencil_ref_bf = (state->stencil[1].ref_value) |
344                    (state->stencil[1].value_mask << R300_STENCILMASK_SHIFT) |
345                    (state->stencil[1].write_mask << R300_STENCILWRITEMASK_SHIFT);
346        }
347    }
348
349    /* Alpha test setup. */
350    if (state->alpha.enabled) {
351        dsa->alpha_function = translate_alpha_function(state->alpha.func) |
352                R300_FG_ALPHA_FUNC_ENABLE;
353        dsa->alpha_reference = CLAMP(state->alpha.ref * 1023.0f, 0, 1023);
354    } else {
355        dsa->z_buffer_top = R300_ZTOP_ENABLE;
356    }
357
358    return (void*)dsa;
359}
360
361/* Bind DSA state. */
362static void r300_bind_dsa_state(struct pipe_context* pipe,
363                                void* state)
364{
365    struct r300_context* r300 = r300_context(pipe);
366
367    r300->dsa_state = (struct r300_dsa_state*)state;
368    r300->dirty_state |= R300_NEW_DSA;
369}
370
371/* Free DSA state. */
372static void r300_delete_dsa_state(struct pipe_context* pipe,
373                                  void* state)
374{
375    FREE(state);
376}
377
378static void r300_set_edgeflags(struct pipe_context* pipe,
379                               const unsigned* bitfield)
380{
381    /* XXX you know it's bad when i915 has this blank too */
382}
383
384static void
385    r300_set_framebuffer_state(struct pipe_context* pipe,
386                               const struct pipe_framebuffer_state* state)
387{
388    struct r300_context* r300 = r300_context(pipe);
389
390    draw_flush(r300->draw);
391
392    r300->framebuffer_state = *state;
393
394    /* XXX do we need to mark dirty state? */
395}
396
397/* Create fragment shader state. */
398static void* r300_create_fs_state(struct pipe_context* pipe,
399                                  const struct pipe_shader_state* state)
400{
401    struct r300_fs_state* fs = CALLOC_STRUCT(r300_fs_state);
402
403    return (void*)fs;
404}
405
406/* Bind fragment shader state. */
407static void r300_bind_fs_state(struct pipe_context* pipe, void* state)
408{
409    struct r300_context* r300 = r300_context(pipe);
410
411    r300->fs_state = (struct r300_fs_state*)state;
412
413    r300->dirty_state |= R300_NEW_FRAGMENT_SHADER;
414}
415
416/* Delect fragment shader state. */
417static void r300_delete_fs_state(struct pipe_context* pipe, void* state)
418{
419    FREE(state);
420}
421
422static void r300_set_polygon_stipple(struct pipe_context* pipe,
423                                     const struct pipe_poly_stipple* state)
424{
425    /* XXX */
426}
427
428#if 0
429struct pipe_rasterizer_state
430{
431    unsigned flatshade:1;
432    unsigned light_twoside:1;
433    unsigned fill_cw:2;        /**< PIPE_POLYGON_MODE_x */
434    unsigned fill_ccw:2;       /**< PIPE_POLYGON_MODE_x */
435    unsigned scissor:1;
436    unsigned poly_smooth:1;
437    unsigned poly_stipple_enable:1;
438    unsigned point_smooth:1;
439    unsigned point_sprite:1;
440    unsigned point_size_per_vertex:1; /**< size computed in vertex shader */
441    unsigned multisample:1;         /* XXX maybe more ms state in future */
442    unsigned line_smooth:1;
443    unsigned line_last_pixel:1;
444    unsigned bypass_clipping:1;
445    unsigned bypass_vs:1; /**< Skip the vertex shader.  Note that the shader is
446    still needed though, to indicate inputs/outputs */
447    unsigned origin_lower_left:1;  /**< Is (0,0) the lower-left corner? */
448    unsigned flatshade_first:1;   /**< take color attribute from the first vertex of a primitive */
449    unsigned gl_rasterization_rules:1; /**< enable tweaks for GL rasterization?  */
450
451    float line_width;
452    float point_size;           /**< used when no per-vertex size */
453    float point_size_min;        /* XXX - temporary, will go away */
454    float point_size_max;        /* XXX - temporary, will go away */
455    ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */
456};
457#endif
458/* Create a new rasterizer state based on the CSO rasterizer state.
459 *
460 * This is a very large chunk of state, and covers most of the graphics
461 * backend (GB), geometry assembly (GA), and setup unit (SU) blocks.
462 *
463 * In a not entirely unironic sidenote, this state has nearly nothing to do
464 * with the actual block on the Radeon called the rasterizer (RS). */
465static void* r300_create_rs_state(struct pipe_context* pipe,
466                                  const struct pipe_rasterizer_state* state)
467{
468    struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state);
469
470    /* Radeons don't think in "CW/CCW", they think in "front/back". */
471    if (state->front_winding == PIPE_WINDING_CW) {
472        rs->cull_mode = R300_FRONT_FACE_CW;
473
474        if (state->offset_cw) {
475            rs->polygon_offset_enable |= R300_FRONT_ENABLE;
476        }
477        if (state->offset_ccw) {
478            rs->polygon_offset_enable |= R300_BACK_ENABLE;
479        }
480    } else {
481        rs->cull_mode = R300_FRONT_FACE_CCW;
482
483        if (state->offset_ccw) {
484            rs->polygon_offset_enable |= R300_FRONT_ENABLE;
485        }
486        if (state->offset_cw) {
487            rs->polygon_offset_enable |= R300_BACK_ENABLE;
488        }
489    }
490    if (state->front_winding & state->cull_mode) {
491        rs->cull_mode |= R300_CULL_FRONT;
492    }
493    if (~(state->front_winding) & state->cull_mode) {
494        rs->cull_mode |= R300_CULL_BACK;
495    }
496
497    if (rs->polygon_offset_enable) {
498        rs->depth_offset_front = rs->depth_offset_back =
499                pack_float_32(state->offset_units);
500        rs->depth_scale_front = rs->depth_scale_back =
501                pack_float_32(state->offset_scale);
502    }
503
504    if (state->line_stipple_enable) {
505        rs->line_stipple_config =
506            R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE |
507            (pack_float_32((float)state->line_stipple_factor) &
508                R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK);
509        /* XXX this might need to be scaled up */
510        rs->line_stipple_value = state->line_stipple_pattern;
511    }
512
513    /* XXX this is part of HW TCL */
514    /* XXX endian control */
515    rs->vap_control_status = R300_VAP_TCL_BYPASS;
516
517    return (void*)rs;
518}
519
520/* Bind rasterizer state. */
521static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
522{
523    struct r300_context* r300 = r300_context(pipe);
524
525    r300->rs_state = (struct r300_rs_state*)state;
526    r300->dirty_state |= R300_NEW_RASTERIZER;
527}
528
529/* Free rasterizer state. */
530static void r300_delete_rs_state(struct pipe_context* pipe, void* state)
531{
532    FREE(state);
533}
534
535static uint32_t translate_wrap(int wrap) {
536    switch (wrap) {
537        case PIPE_TEX_WRAP_REPEAT:
538            return R300_TX_REPEAT;
539        case PIPE_TEX_WRAP_CLAMP:
540            return R300_TX_CLAMP;
541        case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
542            return R300_TX_CLAMP_TO_EDGE;
543        case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
544            return R300_TX_CLAMP_TO_BORDER;
545        case PIPE_TEX_WRAP_MIRROR_REPEAT:
546            return R300_TX_REPEAT | R300_TX_MIRRORED;
547        case PIPE_TEX_WRAP_MIRROR_CLAMP:
548            return R300_TX_CLAMP | R300_TX_MIRRORED;
549        case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
550            return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
551        case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
552            return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
553        default:
554            /* XXX handle this? */
555            return 0;
556    }
557}
558
559static uint32_t translate_tex_filters(int min, int mag, int mip) {
560    uint32_t retval = 0;
561    switch (min) {
562        case PIPE_TEX_FILTER_NEAREST:
563            retval |= R300_TX_MIN_FILTER_NEAREST;
564        case PIPE_TEX_FILTER_LINEAR:
565            retval |= R300_TX_MIN_FILTER_LINEAR;
566        case PIPE_TEX_FILTER_ANISO:
567            retval |= R300_TX_MIN_FILTER_ANISO;
568        default:
569            /* XXX WTF?! */
570            break;
571    }
572    switch (mag) {
573        case PIPE_TEX_FILTER_NEAREST:
574            retval |= R300_TX_MAG_FILTER_NEAREST;
575        case PIPE_TEX_FILTER_LINEAR:
576            retval |= R300_TX_MAG_FILTER_LINEAR;
577        case PIPE_TEX_FILTER_ANISO:
578            retval |= R300_TX_MAG_FILTER_ANISO;
579        default:
580            /* XXX WTF?! */
581            break;
582    }
583    switch (mip) {
584        case PIPE_TEX_MIPFILTER_NONE:
585            retval |= R300_TX_MIN_FILTER_MIP_NONE;
586        case PIPE_TEX_MIPFILTER_NEAREST:
587            retval |= R300_TX_MIN_FILTER_MIP_NEAREST;
588        case PIPE_TEX_MIPFILTER_LINEAR:
589            retval |= R300_TX_MIN_FILTER_MIP_LINEAR;
590        default:
591            /* XXX WTF?! */
592            break;
593    }
594
595    return retval;
596}
597
598static uint32_t anisotropy(float max_aniso) {
599    if (max_aniso >= 16.0f) {
600        return R300_TX_MAX_ANISO_16_TO_1;
601    } else if (max_aniso >= 8.0f) {
602        return R300_TX_MAX_ANISO_8_TO_1;
603    } else if (max_aniso >= 4.0f) {
604        return R300_TX_MAX_ANISO_4_TO_1;
605    } else if (max_aniso >= 2.0f) {
606        return R300_TX_MAX_ANISO_2_TO_1;
607    } else {
608        return R300_TX_MAX_ANISO_1_TO_1;
609    }
610}
611
612static void*
613        r300_create_sampler_state(struct pipe_context* pipe,
614                                  const struct pipe_sampler_state* state)
615{
616    struct r300_context* r300 = r300_context(pipe);
617    struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state);
618    int lod_bias;
619
620    sampler->filter0 |=
621        (translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) |
622        (translate_wrap(state->wrap_t) << R300_TX_WRAP_T_SHIFT) |
623        (translate_wrap(state->wrap_r) << R300_TX_WRAP_R_SHIFT);
624
625    sampler->filter0 |= translate_tex_filters(state->min_img_filter,
626                                              state->mag_img_filter,
627                                              state->min_mip_filter);
628
629    lod_bias = CLAMP((int)(state->lod_bias * 32), -(1 << 9), (1 << 9) - 1);
630
631    sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT;
632
633    sampler->filter1 |= anisotropy(state->max_anisotropy);
634
635    util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM,
636                    &sampler->border_color);
637
638    /* R500-specific fixups and optimizations */
639    if (r300_screen(r300->context.screen)->caps->is_r500) {
640        sampler->filter1 |= R500_BORDER_FIX;
641    }
642
643    return (void*)sampler;
644}
645
646static void r300_bind_sampler_states(struct pipe_context* pipe,
647                                     unsigned count,
648                                     void** states)
649{
650    struct r300_context* r300 = r300_context(pipe);
651    int i;
652
653    if (count > 8) {
654        return;
655    }
656
657    for (i = 0; i < count; i++) {
658        if (r300->sampler_states[i] != states[i]) {
659            r300->sampler_states[i] = (struct r300_sampler_state*)states[i];
660            r300->dirty_state |= (R300_NEW_SAMPLER << i);
661        }
662    }
663
664    r300->sampler_count = count;
665}
666
667static void r300_delete_sampler_state(struct pipe_context* pipe, void* state)
668{
669    FREE(state);
670}
671
672static void r300_set_sampler_textures(struct pipe_context* pipe,
673                                      unsigned count,
674                                      struct pipe_texture** texture)
675{
676    struct r300_context* r300 = r300_context(pipe);
677    int i;
678
679    /* XXX magic num */
680    if (count > 8) {
681        return;
682    }
683
684    for (i = 0; i < count; i++) {
685        if (r300->textures[i] != (struct r300_texture*)texture[i]) {
686            pipe_texture_reference((struct pipe_texture**)&r300->textures[i],
687                texture[i]);
688            /* XXX NEW_TEXTURE instead? */
689            r300->dirty_state |= (R300_NEW_SAMPLER << i);
690        }
691    }
692
693    for (i = count; i < 8; i++) {
694        /* XXX also state change? */
695        pipe_texture_reference((struct pipe_texture**)&r300->textures[i],
696            NULL);
697    }
698
699    r300->texture_count = count;
700}
701
702static void r300_set_scissor_state(struct pipe_context* pipe,
703                                   const struct pipe_scissor_state* state)
704{
705    struct r300_context* r300 = r300_context(pipe);
706    draw_flush(r300->draw);
707
708    uint32_t left, top, right, bottom;
709
710    /* So, a bit of info. The scissors are offset by R300_SCISSORS_OFFSET in
711     * both directions for all values, and can only be 13 bits wide. Why?
712     * We may never know. */
713    left = (state->minx + R300_SCISSORS_OFFSET) & 0x1fff;
714    top = (state->miny + R300_SCISSORS_OFFSET) & 0x1fff;
715    right = (state->maxx + R300_SCISSORS_OFFSET) & 0x1fff;
716    bottom = (state->maxy + R300_SCISSORS_OFFSET) & 0x1fff;
717
718    r300->scissor_state->scissor_top_left = (left << R300_SCISSORS_X_SHIFT) |
719            (top << R300_SCISSORS_Y_SHIFT);
720    r300->scissor_state->scissor_bottom_right =
721        (right << R300_SCISSORS_X_SHIFT) | (bottom << R300_SCISSORS_Y_SHIFT);
722
723    r300->dirty_state |= R300_NEW_SCISSOR;
724}
725
726static void r300_set_viewport_state(struct pipe_context* pipe,
727                                    const struct pipe_viewport_state* state)
728{
729    struct r300_context* r300 = r300_context(pipe);
730    /* XXX handing this off to Draw for now */
731    draw_set_viewport_state(r300->draw, state);
732}
733
734static void r300_set_vertex_buffers(struct pipe_context* pipe,
735                                    unsigned count,
736                                    const struct pipe_vertex_buffer* buffers)
737{
738    struct r300_context* r300 = r300_context(pipe);
739    /* XXX Draw */
740    draw_flush(r300->draw);
741    draw_set_vertex_buffers(r300->draw, count, buffers);
742}
743
744static void r300_set_vertex_elements(struct pipe_context* pipe,
745                                    unsigned count,
746                                    const struct pipe_vertex_element* elements)
747{
748    struct r300_context* r300 = r300_context(pipe);
749    /* XXX Draw */
750    draw_flush(r300->draw);
751    draw_set_vertex_elements(r300->draw, count, elements);
752}
753
754static void* r300_create_vs_state(struct pipe_context* pipe,
755                                  const struct pipe_shader_state* state)
756{
757    struct r300_context* context = r300_context(pipe);
758    /* XXX handing this off to Draw for now */
759    return draw_create_vertex_shader(context->draw, state);
760}
761
762static void r300_bind_vs_state(struct pipe_context* pipe, void* state) {
763    struct r300_context* context = r300_context(pipe);
764    /* XXX handing this off to Draw for now */
765    draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
766}
767
768static void r300_delete_vs_state(struct pipe_context* pipe, void* state)
769{
770    struct r300_context* context = r300_context(pipe);
771    /* XXX handing this off to Draw for now */
772    draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
773}
774
775void r300_init_state_functions(struct r300_context* r300)
776{
777    r300->context.create_blend_state = r300_create_blend_state;
778    r300->context.bind_blend_state = r300_bind_blend_state;
779    r300->context.delete_blend_state = r300_delete_blend_state;
780
781    r300->context.set_blend_color = r300_set_blend_color;
782
783    r300->context.set_clip_state = r300_set_clip_state;
784
785    r300->context.set_constant_buffer = r300_set_constant_buffer;
786
787    r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state;
788    r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state;
789    r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state;
790
791    r300->context.set_edgeflags = r300_set_edgeflags;
792
793    r300->context.set_framebuffer_state = r300_set_framebuffer_state;
794
795    r300->context.create_fs_state = r300_create_fs_state;
796    r300->context.bind_fs_state = r300_bind_fs_state;
797    r300->context.delete_fs_state = r300_delete_fs_state;
798
799    r300->context.set_polygon_stipple = r300_set_polygon_stipple;
800
801    r300->context.create_rasterizer_state = r300_create_rs_state;
802    r300->context.bind_rasterizer_state = r300_bind_rs_state;
803    r300->context.delete_rasterizer_state = r300_delete_rs_state;
804
805    r300->context.create_sampler_state = r300_create_sampler_state;
806    r300->context.bind_sampler_states = r300_bind_sampler_states;
807    r300->context.delete_sampler_state = r300_delete_sampler_state;
808
809    r300->context.set_sampler_textures = r300_set_sampler_textures;
810
811    r300->context.set_scissor_state = r300_set_scissor_state;
812
813    r300->context.set_viewport_state = r300_set_viewport_state;
814
815    r300->context.set_vertex_buffers = r300_set_vertex_buffers;
816    r300->context.set_vertex_elements = r300_set_vertex_elements;
817
818    r300->context.create_vs_state = r300_create_vs_state;
819    r300->context.bind_vs_state = r300_bind_vs_state;
820    r300->context.delete_vs_state = r300_delete_vs_state;
821}
822