r300_state.c revision f3b53a5cb6a04b86ccd75cc38c73c8e3dd117894
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 "r300_context.h"
24#include "r300_state.h"
25
26/* r300_state: Functions used to intialize state context by translating
27 * Gallium state objects into semi-native r300 state objects.
28 *
29 * XXX break this file up into pieces if it gets too big! */
30
31/* Pack a float into a dword. */
32static uint32_t pack_float_32(float f)
33{
34    union {
35        float f;
36        uint32_t u;
37    } u;
38
39    u.f = f;
40    return u.u;
41}
42
43static uint32_t translate_blend_function(int blend_func) {
44    switch (blend_func) {
45        case PIPE_BLEND_ADD:
46            return R300_COMB_FCN_ADD_CLAMP;
47        case PIPE_BLEND_SUBTRACT:
48            return R300_COMB_FCN_SUB_CLAMP;
49        case PIPE_BLEND_REVERSE_SUBTRACT:
50            return R300_COMB_FCN_RSUB_CLAMP;
51        case PIPE_BLEND_MIN:
52            return R300_COMB_FCN_MIN;
53        case PIPE_BLEND_MAX:
54            return R300_COMB_FCN_MAX;
55        default:
56            /* XXX should be unreachable, handle this */
57            break;
58    }
59    return 0;
60}
61
62/* XXX we can also offer the D3D versions of some of these... */
63static uint32_t translate_blend_factor(int blend_fact) {
64    switch (blend_fact) {
65        case PIPE_BLENDFACTOR_ONE:
66            return R300_BLEND_GL_ONE;
67        case PIPE_BLENDFACTOR_SRC_COLOR:
68            return R300_BLEND_GL_SRC_COLOR;
69        case PIPE_BLENDFACTOR_SRC_ALPHA:
70            return R300_BLEND_GL_SRC_ALPHA;
71        case PIPE_BLENDFACTOR_DST_ALPHA:
72            return R300_BLEND_GL_DST_ALPHA;
73        case PIPE_BLENDFACTOR_DST_COLOR:
74            return R300_BLEND_GL_DST_COLOR;
75        case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
76            return R300_BLEND_GL_SRC_ALPHA_SATURATE;
77        case PIPE_BLENDFACTOR_CONST_COLOR:
78            return R300_BLEND_GL_CONST_COLOR;
79        case PIPE_BLENDFACTOR_CONST_ALPHA:
80            return R300_BLEND_GL_CONST_ALPHA;
81        /* XXX WTF are these?
82        case PIPE_BLENDFACTOR_SRC1_COLOR:
83        case PIPE_BLENDFACTOR_SRC1_ALPHA: */
84        case PIPE_BLENDFACTOR_ZERO:
85            return R300_BLEND_GL_ZERO;
86        case PIPE_BLENDFACTOR_INV_SRC_COLOR:
87            return R300_BLEND_GL_ONE_MINUS_SRC_COLOR;
88        case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
89            return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA;
90        case PIPE_BLENDFACTOR_INV_DST_ALPHA:
91            return R300_BLEND_GL_ONE_MINUS_DST_ALPHA;
92        case PIPE_BLENDFACTOR_INV_DST_COLOR:
93            return R300_BLEND_GL_ONE_MINUS_DST_COLOR;
94        case PIPE_BLENDFACTOR_INV_CONST_COLOR:
95            return R300_BLEND_GL_ONE_MINUS_CONST_COLOR;
96        case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
97            return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA;
98        /* XXX see above
99        case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
100        case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: */
101        default:
102            /* XXX the mythical 0x16 blend factor! */
103            break;
104    }
105    return 0;
106}
107
108/* Create a new blend state based on the CSO blend state.
109 *
110 * This encompasses alpha blending, logic/raster ops, and blend dithering. */
111static void* r300_create_blend_state(struct pipe_context* pipe,
112                                     const struct pipe_blend_state* state)
113{
114    struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state);
115
116    if (state->blend_enable) {
117        /* XXX for now, always do separate alpha...
118         * is it faster to do it with one reg? */
119        blend->blend_control = R300_ALPHA_BLEND_ENABLE |
120                R300_SEPARATE_ALPHA_ENABLE |
121                R300_READ_ENABLE |
122                translate_blend_function(state->rgb_func) |
123                (translate_blend_factor(state->rgb_src_factor) <<
124                    R300_SRC_BLEND_SHIFT) |
125                (translate_blend_factor(state->rgb_dst_factor) <<
126                    R300_DST_BLEND_SHIFT);
127        blend->alpha_blend_control =
128                translate_blend_function(state->alpha_func) |
129                (translate_blend_factor(state->alpha_src_factor) <<
130                    R300_SRC_BLEND_SHIFT) |
131                (translate_blend_factor(state->alpha_dst_factor) <<
132                    R300_DST_BLEND_SHIFT);
133    }
134
135    /* PIPE_LOGICOP_* don't need to be translated, fortunately. */
136    /* XXX are logicops still allowed if blending's disabled?
137     * Does Gallium take care of it for us? */
138    if (state->logicop_enable) {
139        blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE |
140                (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT;
141    }
142
143    if (state->dither) {
144        blend->dither = R300_RB3D_DITHER_CTL_DITHER_MODE_LUT |
145                R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT;
146    }
147
148    return (void*)blend;
149}
150
151/* Bind blend state. */
152static void r300_bind_blend_state(struct pipe_context* pipe,
153                                  void* state)
154{
155    struct r300_context* r300 = r300_context(pipe);
156
157    r300->blend_state = (struct r300_blend_state*)state;
158    r300->dirty_state |= R300_NEW_BLEND;
159}
160
161/* Free blend state. */
162static void r300_delete_blend_state(struct pipe_context* pipe,
163                                    void* state)
164{
165    FREE(state);
166}
167
168/* Set blend color.
169 * Setup both R300 and R500 registers, figure out later which one to write. */
170static void r300_set_blend_color(struct pipe_context* pipe,
171                                 const struct pipe_blend_color* color)
172{
173    struct r300_context* r300 = r300_context(pipe);
174    uint32_t r, g, b, a;
175    ubyte ur, ug, ub, ua;
176
177    r = util_iround(color->color[0] * 1023.0f);
178    g = util_iround(color->color[1] * 1023.0f);
179    b = util_iround(color->color[2] * 1023.0f);
180    a = util_iround(color->color[3] * 1023.0f);
181
182    ur = float_to_ubyte(color->color[0]);
183    ug = float_to_ubyte(color->color[1]);
184    ub = float_to_ubyte(color->color[2]);
185    ua = float_to_ubyte(color->color[3]);
186
187    r300->blend_color_state->blend_color = (a << 24) | (r << 16) | (g << 8) | b;
188
189    r300->blend_color_state->blend_color_red_alpha = ur | (ua << 16);
190    r300->blend_color_state->blend_color_green_blue = ub | (ug << 16);
191
192    r300->dirty_state |= R300_NEW_BLEND_COLOR;
193}
194
195static uint32_t translate_depth_stencil_function(int zs_func) {
196    switch (zs_func) {
197        case PIPE_FUNC_NEVER:
198            return R300_ZS_NEVER;
199        case PIPE_FUNC_LESS:
200            return R300_ZS_LESS;
201        case PIPE_FUNC_EQUAL:
202            return R300_ZS_EQUAL;
203        case PIPE_FUNC_LEQUAL:
204            return R300_ZS_LEQUAL;
205        case PIPE_FUNC_GREATER:
206            return R300_ZS_GREATER;
207        case PIPE_FUNC_NOTEQUAL:
208            return R300_ZS_NOTEQUAL;
209        case PIPE_FUNC_GEQUAL:
210            return R300_ZS_GEQUAL;
211        case PIPE_FUNC_ALWAYS:
212            return R300_ZS_ALWAYS;
213        default:
214            /* XXX shouldn't be reachable */
215            break;
216    }
217    return 0;
218}
219
220static uint32_t translate_stencil_op(int s_op) {
221    switch (s_op) {
222        case PIPE_STENCIL_OP_KEEP:
223            return R300_ZS_KEEP;
224        case PIPE_STENCIL_OP_ZERO:
225            return R300_ZS_ZERO;
226        case PIPE_STENCIL_OP_REPLACE:
227            return R300_ZS_REPLACE;
228        case PIPE_STENCIL_OP_INCR:
229            return R300_ZS_INCR;
230        case PIPE_STENCIL_OP_DECR:
231            return R300_ZS_DECR;
232        case PIPE_STENCIL_OP_INCR_WRAP:
233            return R300_ZS_INCR_WRAP;
234        case PIPE_STENCIL_OP_DECR_WRAP:
235            return R300_ZS_DECR_WRAP;
236        case PIPE_STENCIL_OP_INVERT:
237            return R300_ZS_INVERT;
238        default:
239            /* XXX shouldn't be reachable */
240            break;
241    }
242    return 0;
243}
244
245static uint32_t translate_alpha_function(int alpha_func) {
246    switch (alpha_func) {
247        case PIPE_FUNC_NEVER:
248            return R300_FG_ALPHA_FUNC_NEVER;
249        case PIPE_FUNC_LESS:
250            return R300_FG_ALPHA_FUNC_LESS;
251        case PIPE_FUNC_EQUAL:
252            return R300_FG_ALPHA_FUNC_EQUAL;
253        case PIPE_FUNC_LEQUAL:
254            return R300_FG_ALPHA_FUNC_LE;
255        case PIPE_FUNC_GREATER:
256            return R300_FG_ALPHA_FUNC_GREATER;
257        case PIPE_FUNC_NOTEQUAL:
258            return R300_FG_ALPHA_FUNC_NOTEQUAL;
259        case PIPE_FUNC_GEQUAL:
260            return R300_FG_ALPHA_FUNC_GE;
261        case PIPE_FUNC_ALWAYS:
262            return R300_FG_ALPHA_FUNC_ALWAYS;
263        default:
264            /* XXX shouldn't be reachable */
265            break;
266    }
267    return 0;
268}
269
270/* Create a new depth, stencil, and alpha state based on the CSO dsa state.
271 *
272 * This contains the depth buffer, stencil buffer, alpha test, and such.
273 * On the Radeon, depth and stencil buffer setup are intertwined, which is
274 * the reason for some of the strange-looking assignments across registers. */
275static void* r300_create_dsa_state(struct pipe_context* pipe,
276                                   struct pipe_depth_stencil_alpha_state* state)
277{
278    struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);
279
280    /* Depth test setup. */
281    if (state->depth.enabled) {
282        dsa->z_buffer_control |= R300_Z_ENABLE;
283
284        if (state->depth.writemask) {
285            dsa->z_buffer_control |= R300_Z_WRITE_ENABLE;
286        }
287
288        dsa->z_stencil_control |=
289                (translate_depth_stencil_function(state->depth.func) <<
290                    R300_Z_FUNC_SHIFT);
291    }
292
293    /* Stencil buffer setup. */
294    if (state->stencil[0].enabled) {
295        dsa->z_buffer_control |= R300_STENCIL_ENABLE;
296        dsa->z_stencil_control |=
297                (translate_depth_stencil_function(state->stencil[0].func) <<
298                    R300_S_FRONT_FUNC_SHIFT) |
299                (translate_stencil_op(state->stencil[0].fail_op) <<
300                    R300_S_FRONT_SFAIL_OP_SHIFT) |
301                (translate_stencil_op(state->stencil[0].zpass_op) <<
302                    R300_S_FRONT_ZPASS_OP_SHIFT) |
303                (translate_stencil_op(state->stencil[0].zfail_op) <<
304                    R300_S_FRONT_ZFAIL_OP_SHIFT);
305
306        dsa->stencil_ref_mask = (state->stencil[0].ref_value) |
307                (state->stencil[0].value_mask << R300_STENCILMASK_SHIFT) |
308                (state->stencil[0].write_mask << R300_STENCILWRITEMASK_SHIFT);
309
310        if (state->stencil[1].enabled) {
311            dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK;
312            dsa->z_stencil_control |=
313                    (translate_depth_stencil_function(state->stencil[1].func) <<
314                        R300_S_BACK_FUNC_SHIFT) |
315                    (translate_stencil_op(state->stencil[1].fail_op) <<
316                        R300_S_BACK_SFAIL_OP_SHIFT) |
317                    (translate_stencil_op(state->stencil[1].zpass_op) <<
318                        R300_S_BACK_ZPASS_OP_SHIFT) |
319                    (translate_stencil_op(state->stencil[1].zfail_op) <<
320                        R300_S_BACK_ZFAIL_OP_SHIFT);
321
322            dsa->stencil_ref_bf = (state->stencil[1].ref_value) |
323                    (state->stencil[1].value_mask << R300_STENCILMASK_SHIFT) |
324                    (state->stencil[1].write_mask << R300_STENCILWRITEMASK_SHIFT);
325        }
326    }
327
328    /* Alpha test setup. */
329    if (state->alpha.enabled) {
330        dsa->alpha_function = translate_alpha_function(state->alpha.func) |
331                R300_FG_ALPHA_FUNC_ENABLE;
332        dsa->alpha_reference = CLAMP(state->alpha.ref * 1023.0f, 0, 1023);
333    } else {
334        dsa->z_buffer_top = R300_ZTOP_ENABLE;
335    }
336
337    return (void*)dsa;
338}
339
340/* Bind DSA state. */
341static void r300_bind_dsa_state(struct pipe_context* pipe,
342                                  void* state)
343{
344    struct r300_context* r300 = r300_context(pipe);
345
346    r300->dsa_state = (struct r300_dsa_state*)state;
347    r300->dirty_state |= R300_NEW_DSA;
348}
349
350/* Free DSA state. */
351static void r300_delete_dsa_state(struct pipe_context* pipe,
352                                    void* state)
353{
354    FREE(state);
355}
356#if 0
357struct pipe_rasterizer_state
358{
359    unsigned flatshade:1;
360    unsigned light_twoside:1;
361    unsigned fill_cw:2;        /**< PIPE_POLYGON_MODE_x */
362    unsigned fill_ccw:2;       /**< PIPE_POLYGON_MODE_x */
363    unsigned scissor:1;
364    unsigned poly_smooth:1;
365    unsigned poly_stipple_enable:1;
366    unsigned point_smooth:1;
367    unsigned point_sprite:1;
368    unsigned point_size_per_vertex:1; /**< size computed in vertex shader */
369    unsigned multisample:1;         /* XXX maybe more ms state in future */
370    unsigned line_smooth:1;
371    unsigned line_stipple_enable:1;
372    unsigned line_stipple_factor:8;  /**< [1..256] actually */
373    unsigned line_stipple_pattern:16;
374    unsigned line_last_pixel:1;
375    unsigned bypass_clipping:1;
376    unsigned bypass_vs:1; /**< Skip the vertex shader.  Note that the shader is
377    still needed though, to indicate inputs/outputs */
378    unsigned origin_lower_left:1;  /**< Is (0,0) the lower-left corner? */
379    unsigned flatshade_first:1;   /**< take color attribute from the first vertex of a primitive */
380    unsigned gl_rasterization_rules:1; /**< enable tweaks for GL rasterization?  */
381
382    float line_width;
383    float point_size;           /**< used when no per-vertex size */
384    float point_size_min;        /* XXX - temporary, will go away */
385    float point_size_max;        /* XXX - temporary, will go away */
386    ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */
387};
388#endif
389/* Create a new rasterizer state based on the CSO rasterizer state.
390 *
391 * This is a very large chunk of state, and covers most of the graphics
392 * backend (GB), geometry assembly (GA), and setup unit (SU) blocks.
393 *
394 * In a not entirely unironic sidenote, this state has nearly nothing to do
395 * with the actual block on the Radeon called the rasterizer (RS). */
396static void* r300_create_rs_state(struct pipe_context* pipe,
397                                          struct pipe_rasterizer_state* state)
398{
399    struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state);
400
401    /* Radeons don't think in "CW/CCW", they think in "front/back". */
402    if (state->front_winding == PIPE_WINDING_CW) {
403        rs->cull_mode = R300_FRONT_FACE_CW;
404
405        if (state->offset_cw) {
406            rs->polygon_offset_enable |= R300_FRONT_ENABLE;
407        }
408        if (state->offset_ccw) {
409            rs->polygon_offset_enable |= R300_BACK_ENABLE;
410        }
411    } else {
412        rs->cull_mode = R300_FRONT_FACE_CCW;
413
414        if (state->offset_ccw) {
415            rs->polygon_offset_enable |= R300_FRONT_ENABLE;
416        }
417        if (state->offset_cw) {
418            rs->polygon_offset_enable |= R300_BACK_ENABLE;
419        }
420    }
421    if (state->front_winding & state->cull_mode) {
422        rs->cull_mode |= R300_CULL_FRONT;
423    }
424    if (~(state->front_winding) & state->cull_mode) {
425        rs->cull_mode |= R300_CULL_BACK;
426    }
427
428    if (rs->polygon_offset_enable) {
429        rs->depth_offset_front = rs->depth_offset_back =
430                pack_float_32(state->offset_units);
431        rs->depth_scale_front = rs->depth_scale_back =
432                pack_float_32(state->offset_scale);
433    }
434
435    return (void*)rs;
436}
437
438/* Bind rasterizer state. */
439static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
440{
441    struct r300_context* r300 = r300_context(pipe);
442
443    r300->rs_state = (struct r300_rs_state*)state;
444    r300->dirty_state |= R300_NEW_RS;
445}
446
447/* Free rasterizer state. */
448static void r300_delete_rs_state(struct pipe_context* pipe, void* state)
449{
450    FREE(state);
451}
452
453static void r300_set_scissor_state(struct pipe_context* pipe,
454                                   struct pipe_scissor_state* state)
455{
456    struct r300_context* r300 = r300_context(pipe);
457    draw_flush(r300->draw);
458
459    uint32_t left, top, right, bottom;
460
461    /* So, a bit of info. The scissors are offset by R300_SCISSORS_OFFSET in
462     * both directions for all values, and can only be 13 bits wide. Why?
463     * We may never know. */
464    left = (state->minx + R300_SCISSORS_OFFSET) & 0x1fff;
465    top = (state->miny + R300_SCISSORS_OFFSET) & 0x1fff;
466    right = (state->maxx + R300_SCISSORS_OFFSET) & 0x1fff;
467    bottom = (state->maxy + R300_SCISSORS_OFFSET) & 0x1fff;
468
469    r300->scissor_state->scissor_top_left = (left << R300_SCISSORS_X_SHIFT) |
470            (top << R300_SCISSORS_Y_SHIFT);
471    r300->scissor_state->scissor_bottom_right = (right << R300_SCISSORS_X_SHIFT) |
472            (bottom << R300_SCISSORS_Y_SHIFT);
473
474    r300->dirty_state |= R300_NEW_SCISSOR;
475}
476
477static void* r300_create_vs_state(struct pipe_context* pipe,
478                                  struct pipe_shader_state* state)
479{
480    struct r300_context* context = r300_context(pipe);
481    /* XXX handing this off to Draw for now */
482    return draw_create_vertex_shader(context->draw, state);
483}
484
485static void r300_bind_vs_state(struct pipe_context* pipe, void* state) {
486    struct r300_context* context = r300_context(pipe);
487    /* XXX handing this off to Draw for now */
488    draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
489}
490
491static void r300_delete_vs_state(struct pipe_context* pipe, void* state)
492{
493    struct r300_context* context = r300_context(pipe);
494    /* XXX handing this off to Draw for now */
495    draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
496}
497
498void r300_init_state_functions(struct r300_context* r300) {
499
500    r300->context.create_blend_state = r300_create_blend_state;
501    r300->context.bind_blend_state = r300_bind_blend_state;
502    r300->context.delete_blend_state = r300_delete_blend_state;
503
504    r300->context.set_blend_color = r300_set_blend_color;
505
506    r300->context.create_rasterizer_state = r300_create_rs_state;
507    r300->context.bind_rasterizer_state = r300_bind_rs_state;
508    r300->context.delete_rasterizer_state = r300_delete_rs_state;
509
510    r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state;
511    r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state;
512    r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state;
513
514    r300->context.set_scissor_state = r300_set_scissor_state;
515
516    r300->context.create_vs_state = r300_create_vs_state;
517    r300->context.bind_vs_state = r300_bind_vs_state;
518    r300->context.delete_vs_state = r300_delete_vs_state;
519}