r300_state.c revision 3aabfa46083daf60859bb26b65568de4cf40915f
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            debug_printf("r300: Unknown blend function %d\n", blend_func);
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            debug_printf("r300: Unknown blend factor %d\n", blend_fact);
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            debug_printf("r300: Unknown depth/stencil function %d\n",
235                zs_func);
236            break;
237    }
238    return 0;
239}
240
241static uint32_t translate_stencil_op(int s_op) {
242    switch (s_op) {
243        case PIPE_STENCIL_OP_KEEP:
244            return R300_ZS_KEEP;
245        case PIPE_STENCIL_OP_ZERO:
246            return R300_ZS_ZERO;
247        case PIPE_STENCIL_OP_REPLACE:
248            return R300_ZS_REPLACE;
249        case PIPE_STENCIL_OP_INCR:
250            return R300_ZS_INCR;
251        case PIPE_STENCIL_OP_DECR:
252            return R300_ZS_DECR;
253        case PIPE_STENCIL_OP_INCR_WRAP:
254            return R300_ZS_INCR_WRAP;
255        case PIPE_STENCIL_OP_DECR_WRAP:
256            return R300_ZS_DECR_WRAP;
257        case PIPE_STENCIL_OP_INVERT:
258            return R300_ZS_INVERT;
259        default:
260            debug_printf("r300: Unknown stencil op %d", s_op);
261            break;
262    }
263    return 0;
264}
265
266static uint32_t translate_alpha_function(int alpha_func) {
267    switch (alpha_func) {
268        case PIPE_FUNC_NEVER:
269            return R300_FG_ALPHA_FUNC_NEVER;
270        case PIPE_FUNC_LESS:
271            return R300_FG_ALPHA_FUNC_LESS;
272        case PIPE_FUNC_EQUAL:
273            return R300_FG_ALPHA_FUNC_EQUAL;
274        case PIPE_FUNC_LEQUAL:
275            return R300_FG_ALPHA_FUNC_LE;
276        case PIPE_FUNC_GREATER:
277            return R300_FG_ALPHA_FUNC_GREATER;
278        case PIPE_FUNC_NOTEQUAL:
279            return R300_FG_ALPHA_FUNC_NOTEQUAL;
280        case PIPE_FUNC_GEQUAL:
281            return R300_FG_ALPHA_FUNC_GE;
282        case PIPE_FUNC_ALWAYS:
283            return R300_FG_ALPHA_FUNC_ALWAYS;
284        default:
285            debug_printf("r300: Unknown alpha function %d", alpha_func);
286            break;
287    }
288    return 0;
289}
290
291/* Create a new depth, stencil, and alpha state based on the CSO dsa state.
292 *
293 * This contains the depth buffer, stencil buffer, alpha test, and such.
294 * On the Radeon, depth and stencil buffer setup are intertwined, which is
295 * the reason for some of the strange-looking assignments across registers. */
296static void*
297        r300_create_dsa_state(struct pipe_context* pipe,
298                              const struct pipe_depth_stencil_alpha_state* state)
299{
300    struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);
301
302    /* Depth test setup. */
303    if (state->depth.enabled) {
304        dsa->z_buffer_control |= R300_Z_ENABLE;
305
306        if (state->depth.writemask) {
307            dsa->z_buffer_control |= R300_Z_WRITE_ENABLE;
308        }
309
310        dsa->z_stencil_control |=
311            (translate_depth_stencil_function(state->depth.func) <<
312                R300_Z_FUNC_SHIFT);
313    }
314
315    /* Stencil buffer setup. */
316    if (state->stencil[0].enabled) {
317        dsa->z_buffer_control |= R300_STENCIL_ENABLE;
318        dsa->z_stencil_control |=
319                (translate_depth_stencil_function(state->stencil[0].func) <<
320                    R300_S_FRONT_FUNC_SHIFT) |
321                (translate_stencil_op(state->stencil[0].fail_op) <<
322                    R300_S_FRONT_SFAIL_OP_SHIFT) |
323                (translate_stencil_op(state->stencil[0].zpass_op) <<
324                    R300_S_FRONT_ZPASS_OP_SHIFT) |
325                (translate_stencil_op(state->stencil[0].zfail_op) <<
326                    R300_S_FRONT_ZFAIL_OP_SHIFT);
327
328        dsa->stencil_ref_mask = (state->stencil[0].ref_value) |
329                (state->stencil[0].valuemask << R300_STENCILMASK_SHIFT) |
330                (state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT);
331
332        if (state->stencil[1].enabled) {
333            dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK;
334            dsa->z_stencil_control |=
335                (translate_depth_stencil_function(state->stencil[1].func) <<
336                    R300_S_BACK_FUNC_SHIFT) |
337                (translate_stencil_op(state->stencil[1].fail_op) <<
338                    R300_S_BACK_SFAIL_OP_SHIFT) |
339                (translate_stencil_op(state->stencil[1].zpass_op) <<
340                    R300_S_BACK_ZPASS_OP_SHIFT) |
341                (translate_stencil_op(state->stencil[1].zfail_op) <<
342                    R300_S_BACK_ZFAIL_OP_SHIFT);
343
344            dsa->stencil_ref_bf = (state->stencil[1].ref_value) |
345                (state->stencil[1].valuemask << R300_STENCILMASK_SHIFT) |
346                (state->stencil[1].writemask << R300_STENCILWRITEMASK_SHIFT);
347        }
348    }
349
350    /* Alpha test setup. */
351    if (state->alpha.enabled) {
352        dsa->alpha_function = translate_alpha_function(state->alpha.func) |
353            R300_FG_ALPHA_FUNC_ENABLE;
354        dsa->alpha_reference = CLAMP(state->alpha.ref_value * 1023.0f,
355                                     0, 1023);
356    } else {
357        dsa->z_buffer_top = R300_ZTOP_ENABLE;
358    }
359
360    return (void*)dsa;
361}
362
363/* Bind DSA state. */
364static void r300_bind_dsa_state(struct pipe_context* pipe,
365                                void* state)
366{
367    struct r300_context* r300 = r300_context(pipe);
368
369    r300->dsa_state = (struct r300_dsa_state*)state;
370    r300->dirty_state |= R300_NEW_DSA;
371}
372
373/* Free DSA state. */
374static void r300_delete_dsa_state(struct pipe_context* pipe,
375                                  void* state)
376{
377    FREE(state);
378}
379
380static void r300_set_edgeflags(struct pipe_context* pipe,
381                               const unsigned* bitfield)
382{
383    /* XXX you know it's bad when i915 has this blank too */
384}
385
386static void
387    r300_set_framebuffer_state(struct pipe_context* pipe,
388                               const struct pipe_framebuffer_state* state)
389{
390    struct r300_context* r300 = r300_context(pipe);
391
392    draw_flush(r300->draw);
393
394    r300->framebuffer_state = *state;
395
396    /* XXX do we need to mark dirty state? */
397}
398
399/* Create fragment shader state. */
400static void* r300_create_fs_state(struct pipe_context* pipe,
401                                  const struct pipe_shader_state* state)
402{
403    struct r300_fs_state* fs = CALLOC_STRUCT(r300_fs_state);
404
405    return (void*)fs;
406}
407
408/* Bind fragment shader state. */
409static void r300_bind_fs_state(struct pipe_context* pipe, void* state)
410{
411    struct r300_context* r300 = r300_context(pipe);
412
413    r300->fs_state = (struct r300_fs_state*)state;
414
415    r300->dirty_state |= R300_NEW_FRAGMENT_SHADER;
416}
417
418/* Delect fragment shader state. */
419static void r300_delete_fs_state(struct pipe_context* pipe, void* state)
420{
421    FREE(state);
422}
423
424static void r300_set_polygon_stipple(struct pipe_context* pipe,
425                                     const struct pipe_poly_stipple* state)
426{
427    /* XXX */
428}
429
430#if 0
431struct pipe_rasterizer_state
432{
433    unsigned flatshade:1;
434    unsigned light_twoside:1;
435    unsigned fill_cw:2;        /**< PIPE_POLYGON_MODE_x */
436    unsigned fill_ccw:2;       /**< PIPE_POLYGON_MODE_x */
437    unsigned scissor:1;
438    unsigned poly_smooth:1;
439    unsigned poly_stipple_enable:1;
440    unsigned point_smooth:1;
441    unsigned point_sprite:1;
442    unsigned multisample:1;         /* XXX maybe more ms state in future */
443    unsigned line_smooth:1;
444    unsigned line_last_pixel:1;
445    unsigned bypass_clipping:1;
446    unsigned bypass_vs:1; /**< Skip the vertex shader.  Note that the shader is
447    still needed though, to indicate inputs/outputs */
448    unsigned origin_lower_left:1;  /**< Is (0,0) the lower-left corner? */
449    unsigned flatshade_first:1;   /**< take color attribute from the first vertex of a primitive */
450    unsigned gl_rasterization_rules:1; /**< enable tweaks for GL rasterization?  */
451    ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */
452};
453#endif
454
455static INLINE int pack_float_16_6x(float f) {
456    return ((int)(f * 6.0) & 0xffff);
457}
458
459/* Create a new rasterizer state based on the CSO rasterizer state.
460 *
461 * This is a very large chunk of state, and covers most of the graphics
462 * backend (GB), geometry assembly (GA), and setup unit (SU) blocks.
463 *
464 * In a not entirely unironic sidenote, this state has nearly nothing to do
465 * with the actual block on the Radeon called the rasterizer (RS). */
466static void* r300_create_rs_state(struct pipe_context* pipe,
467                                  const struct pipe_rasterizer_state* state)
468{
469    struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state);
470
471    /* XXX this is part of HW TCL */
472    /* XXX endian control */
473    rs->vap_control_status = R300_VAP_TCL_BYPASS;
474
475    rs->point_size = pack_float_16_6x(state->point_size) |
476        (pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT);
477
478    rs->line_control = pack_float_16_6x(state->line_width) |
479        R300_GA_LINE_CNTL_END_TYPE_COMP;
480
481    /* Radeons don't think in "CW/CCW", they think in "front/back". */
482    if (state->front_winding == PIPE_WINDING_CW) {
483        rs->cull_mode = R300_FRONT_FACE_CW;
484
485        if (state->offset_cw) {
486            rs->polygon_offset_enable |= R300_FRONT_ENABLE;
487        }
488        if (state->offset_ccw) {
489            rs->polygon_offset_enable |= R300_BACK_ENABLE;
490        }
491    } else {
492        rs->cull_mode = R300_FRONT_FACE_CCW;
493
494        if (state->offset_ccw) {
495            rs->polygon_offset_enable |= R300_FRONT_ENABLE;
496        }
497        if (state->offset_cw) {
498            rs->polygon_offset_enable |= R300_BACK_ENABLE;
499        }
500    }
501    if (state->front_winding & state->cull_mode) {
502        rs->cull_mode |= R300_CULL_FRONT;
503    }
504    if (~(state->front_winding) & state->cull_mode) {
505        rs->cull_mode |= R300_CULL_BACK;
506    }
507
508    if (rs->polygon_offset_enable) {
509        rs->depth_offset_front = rs->depth_offset_back =
510                pack_float_32(state->offset_units);
511        rs->depth_scale_front = rs->depth_scale_back =
512                pack_float_32(state->offset_scale);
513    }
514
515    if (state->line_stipple_enable) {
516        rs->line_stipple_config =
517            R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE |
518            (pack_float_32((float)state->line_stipple_factor) &
519                R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK);
520        /* XXX this might need to be scaled up */
521        rs->line_stipple_value = state->line_stipple_pattern;
522    }
523
524    return (void*)rs;
525}
526
527/* Bind rasterizer state. */
528static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
529{
530    struct r300_context* r300 = r300_context(pipe);
531
532    r300->rs_state = (struct r300_rs_state*)state;
533    r300->dirty_state |= R300_NEW_RASTERIZER;
534}
535
536/* Free rasterizer state. */
537static void r300_delete_rs_state(struct pipe_context* pipe, void* state)
538{
539    FREE(state);
540}
541
542static uint32_t translate_wrap(int wrap) {
543    switch (wrap) {
544        case PIPE_TEX_WRAP_REPEAT:
545            return R300_TX_REPEAT;
546        case PIPE_TEX_WRAP_CLAMP:
547            return R300_TX_CLAMP;
548        case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
549            return R300_TX_CLAMP_TO_EDGE;
550        case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
551            return R300_TX_CLAMP_TO_BORDER;
552        case PIPE_TEX_WRAP_MIRROR_REPEAT:
553            return R300_TX_REPEAT | R300_TX_MIRRORED;
554        case PIPE_TEX_WRAP_MIRROR_CLAMP:
555            return R300_TX_CLAMP | R300_TX_MIRRORED;
556        case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
557            return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
558        case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
559            return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
560        default:
561            debug_printf("r300: Unknown texture wrap %d", wrap);
562            return 0;
563    }
564}
565
566static uint32_t translate_tex_filters(int min, int mag, int mip) {
567    uint32_t retval = 0;
568    switch (min) {
569        case PIPE_TEX_FILTER_NEAREST:
570            retval |= R300_TX_MIN_FILTER_NEAREST;
571        case PIPE_TEX_FILTER_LINEAR:
572            retval |= R300_TX_MIN_FILTER_LINEAR;
573        case PIPE_TEX_FILTER_ANISO:
574            retval |= R300_TX_MIN_FILTER_ANISO;
575        default:
576            debug_printf("r300: Unknown texture filter %d", min);
577            break;
578    }
579    switch (mag) {
580        case PIPE_TEX_FILTER_NEAREST:
581            retval |= R300_TX_MAG_FILTER_NEAREST;
582        case PIPE_TEX_FILTER_LINEAR:
583            retval |= R300_TX_MAG_FILTER_LINEAR;
584        case PIPE_TEX_FILTER_ANISO:
585            retval |= R300_TX_MAG_FILTER_ANISO;
586        default:
587            debug_printf("r300: Unknown texture filter %d", mag);
588            break;
589    }
590    switch (mip) {
591        case PIPE_TEX_MIPFILTER_NONE:
592            retval |= R300_TX_MIN_FILTER_MIP_NONE;
593        case PIPE_TEX_MIPFILTER_NEAREST:
594            retval |= R300_TX_MIN_FILTER_MIP_NEAREST;
595        case PIPE_TEX_MIPFILTER_LINEAR:
596            retval |= R300_TX_MIN_FILTER_MIP_LINEAR;
597        default:
598            debug_printf("r300: Unknown texture filter %d", mip);
599            break;
600    }
601
602    return retval;
603}
604
605static uint32_t anisotropy(float max_aniso) {
606    if (max_aniso >= 16.0f) {
607        return R300_TX_MAX_ANISO_16_TO_1;
608    } else if (max_aniso >= 8.0f) {
609        return R300_TX_MAX_ANISO_8_TO_1;
610    } else if (max_aniso >= 4.0f) {
611        return R300_TX_MAX_ANISO_4_TO_1;
612    } else if (max_aniso >= 2.0f) {
613        return R300_TX_MAX_ANISO_2_TO_1;
614    } else {
615        return R300_TX_MAX_ANISO_1_TO_1;
616    }
617}
618
619static void*
620        r300_create_sampler_state(struct pipe_context* pipe,
621                                  const struct pipe_sampler_state* state)
622{
623    struct r300_context* r300 = r300_context(pipe);
624    struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state);
625    int lod_bias;
626
627    sampler->filter0 |=
628        (translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) |
629        (translate_wrap(state->wrap_t) << R300_TX_WRAP_T_SHIFT) |
630        (translate_wrap(state->wrap_r) << R300_TX_WRAP_R_SHIFT);
631
632    sampler->filter0 |= translate_tex_filters(state->min_img_filter,
633                                              state->mag_img_filter,
634                                              state->min_mip_filter);
635
636    lod_bias = CLAMP((int)(state->lod_bias * 32), -(1 << 9), (1 << 9) - 1);
637
638    sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT;
639
640    sampler->filter1 |= anisotropy(state->max_anisotropy);
641
642    util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM,
643                    &sampler->border_color);
644
645    /* R500-specific fixups and optimizations */
646    if (r300_screen(r300->context.screen)->caps->is_r500) {
647        sampler->filter1 |= R500_BORDER_FIX;
648    }
649
650    return (void*)sampler;
651}
652
653static void r300_bind_sampler_states(struct pipe_context* pipe,
654                                     unsigned count,
655                                     void** states)
656{
657    struct r300_context* r300 = r300_context(pipe);
658    int i;
659
660    if (count > 8) {
661        return;
662    }
663
664    for (i = 0; i < count; i++) {
665        if (r300->sampler_states[i] != states[i]) {
666            r300->sampler_states[i] = (struct r300_sampler_state*)states[i];
667            r300->dirty_state |= (R300_NEW_SAMPLER << i);
668        }
669    }
670
671    r300->sampler_count = count;
672}
673
674static void r300_delete_sampler_state(struct pipe_context* pipe, void* state)
675{
676    FREE(state);
677}
678
679static void r300_set_sampler_textures(struct pipe_context* pipe,
680                                      unsigned count,
681                                      struct pipe_texture** texture)
682{
683    struct r300_context* r300 = r300_context(pipe);
684    int i;
685
686    /* XXX magic num */
687    if (count > 8) {
688        return;
689    }
690
691    for (i = 0; i < count; i++) {
692        if (r300->textures[i] != (struct r300_texture*)texture[i]) {
693            pipe_texture_reference((struct pipe_texture**)&r300->textures[i],
694                texture[i]);
695            /* XXX NEW_TEXTURE instead? */
696            r300->dirty_state |= (R300_NEW_SAMPLER << i);
697        }
698    }
699
700    for (i = count; i < 8; i++) {
701        /* XXX also state change? */
702        pipe_texture_reference((struct pipe_texture**)&r300->textures[i],
703            NULL);
704    }
705
706    r300->texture_count = count;
707}
708
709static void r300_set_scissor_state(struct pipe_context* pipe,
710                                   const struct pipe_scissor_state* state)
711{
712    struct r300_context* r300 = r300_context(pipe);
713    draw_flush(r300->draw);
714
715    uint32_t left, top, right, bottom;
716
717    /* So, a bit of info. The scissors are offset by R300_SCISSORS_OFFSET in
718     * both directions for all values, and can only be 13 bits wide. Why?
719     * We may never know. */
720    left = (state->minx + R300_SCISSORS_OFFSET) & 0x1fff;
721    top = (state->miny + R300_SCISSORS_OFFSET) & 0x1fff;
722    right = (state->maxx + R300_SCISSORS_OFFSET) & 0x1fff;
723    bottom = (state->maxy + R300_SCISSORS_OFFSET) & 0x1fff;
724
725    r300->scissor_state->scissor_top_left = (left << R300_SCISSORS_X_SHIFT) |
726            (top << R300_SCISSORS_Y_SHIFT);
727    r300->scissor_state->scissor_bottom_right =
728        (right << R300_SCISSORS_X_SHIFT) | (bottom << R300_SCISSORS_Y_SHIFT);
729
730    r300->dirty_state |= R300_NEW_SCISSOR;
731}
732
733static void r300_set_viewport_state(struct pipe_context* pipe,
734                                    const struct pipe_viewport_state* state)
735{
736    struct r300_context* r300 = r300_context(pipe);
737    /* XXX handing this off to Draw for now */
738    draw_set_viewport_state(r300->draw, state);
739}
740
741static void r300_set_vertex_buffers(struct pipe_context* pipe,
742                                    unsigned count,
743                                    const struct pipe_vertex_buffer* buffers)
744{
745    struct r300_context* r300 = r300_context(pipe);
746    /* XXX Draw */
747    draw_flush(r300->draw);
748    draw_set_vertex_buffers(r300->draw, count, buffers);
749}
750
751static void r300_set_vertex_elements(struct pipe_context* pipe,
752                                    unsigned count,
753                                    const struct pipe_vertex_element* elements)
754{
755    struct r300_context* r300 = r300_context(pipe);
756    /* XXX Draw */
757    draw_flush(r300->draw);
758    draw_set_vertex_elements(r300->draw, count, elements);
759}
760
761static void* r300_create_vs_state(struct pipe_context* pipe,
762                                  const struct pipe_shader_state* state)
763{
764    struct r300_context* context = r300_context(pipe);
765    /* XXX handing this off to Draw for now */
766    return draw_create_vertex_shader(context->draw, state);
767}
768
769static void r300_bind_vs_state(struct pipe_context* pipe, void* state) {
770    struct r300_context* context = r300_context(pipe);
771    /* XXX handing this off to Draw for now */
772    draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
773}
774
775static void r300_delete_vs_state(struct pipe_context* pipe, void* state)
776{
777    struct r300_context* context = r300_context(pipe);
778    /* XXX handing this off to Draw for now */
779    draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
780}
781
782void r300_init_state_functions(struct r300_context* r300)
783{
784    r300->context.create_blend_state = r300_create_blend_state;
785    r300->context.bind_blend_state = r300_bind_blend_state;
786    r300->context.delete_blend_state = r300_delete_blend_state;
787
788    r300->context.set_blend_color = r300_set_blend_color;
789
790    r300->context.set_clip_state = r300_set_clip_state;
791
792    r300->context.set_constant_buffer = r300_set_constant_buffer;
793
794    r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state;
795    r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state;
796    r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state;
797
798    r300->context.set_edgeflags = r300_set_edgeflags;
799
800    r300->context.set_framebuffer_state = r300_set_framebuffer_state;
801
802    r300->context.create_fs_state = r300_create_fs_state;
803    r300->context.bind_fs_state = r300_bind_fs_state;
804    r300->context.delete_fs_state = r300_delete_fs_state;
805
806    r300->context.set_polygon_stipple = r300_set_polygon_stipple;
807
808    r300->context.create_rasterizer_state = r300_create_rs_state;
809    r300->context.bind_rasterizer_state = r300_bind_rs_state;
810    r300->context.delete_rasterizer_state = r300_delete_rs_state;
811
812    r300->context.create_sampler_state = r300_create_sampler_state;
813    r300->context.bind_sampler_states = r300_bind_sampler_states;
814    r300->context.delete_sampler_state = r300_delete_sampler_state;
815
816    r300->context.set_sampler_textures = r300_set_sampler_textures;
817
818    r300->context.set_scissor_state = r300_set_scissor_state;
819
820    r300->context.set_viewport_state = r300_set_viewport_state;
821
822    r300->context.set_vertex_buffers = r300_set_vertex_buffers;
823    r300->context.set_vertex_elements = r300_set_vertex_elements;
824
825    r300->context.create_vs_state = r300_create_vs_state;
826    r300->context.bind_vs_state = r300_bind_vs_state;
827    r300->context.delete_vs_state = r300_delete_vs_state;
828}
829