r300_state.c revision a08a830fd3c22bdbad1ee840e4e56302152375f1
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
168static uint32_t translate_depth_stencil_function(int zs_func) {
169    switch (zs_func) {
170        case PIPE_FUNC_NEVER:
171            return R300_ZS_NEVER;
172        case PIPE_FUNC_LESS:
173            return R300_ZS_LESS;
174        case PIPE_FUNC_EQUAL:
175            return R300_ZS_EQUAL;
176        case PIPE_FUNC_LEQUAL:
177            return R300_ZS_LEQUAL;
178        case PIPE_FUNC_GREATER:
179            return R300_ZS_GREATER;
180        case PIPE_FUNC_NOTEQUAL:
181            return R300_ZS_NOTEQUAL;
182        case PIPE_FUNC_GEQUAL:
183            return R300_ZS_GEQUAL;
184        case PIPE_FUNC_ALWAYS:
185            return R300_ZS_ALWAYS;
186        default:
187            /* XXX shouldn't be reachable */
188            break;
189    }
190    return 0;
191}
192
193static uint32_t translate_stencil_op(int s_op) {
194    switch (s_op) {
195        case PIPE_STENCIL_OP_KEEP:
196            return R300_ZS_KEEP;
197        case PIPE_STENCIL_OP_ZERO:
198            return R300_ZS_ZERO;
199        case PIPE_STENCIL_OP_REPLACE:
200            return R300_ZS_REPLACE;
201        case PIPE_STENCIL_OP_INCR:
202            return R300_ZS_INCR;
203        case PIPE_STENCIL_OP_DECR:
204            return R300_ZS_DECR;
205        case PIPE_STENCIL_OP_INCR_WRAP:
206            return R300_ZS_INCR_WRAP;
207        case PIPE_STENCIL_OP_DECR_WRAP:
208            return R300_ZS_DECR_WRAP;
209        case PIPE_STENCIL_OP_INVERT:
210            return R300_ZS_INVERT;
211        default:
212            /* XXX shouldn't be reachable */
213            break;
214    }
215    return 0;
216}
217
218static uint32_t translate_alpha_function(int alpha_func) {
219    switch (alpha_func) {
220        case PIPE_FUNC_NEVER:
221            return R300_FG_ALPHA_FUNC_NEVER;
222        case PIPE_FUNC_LESS:
223            return R300_FG_ALPHA_FUNC_LESS;
224        case PIPE_FUNC_EQUAL:
225            return R300_FG_ALPHA_FUNC_EQUAL;
226        case PIPE_FUNC_LEQUAL:
227            return R300_FG_ALPHA_FUNC_LE;
228        case PIPE_FUNC_GREATER:
229            return R300_FG_ALPHA_FUNC_GREATER;
230        case PIPE_FUNC_NOTEQUAL:
231            return R300_FG_ALPHA_FUNC_NOTEQUAL;
232        case PIPE_FUNC_GEQUAL:
233            return R300_FG_ALPHA_FUNC_GE;
234        case PIPE_FUNC_ALWAYS:
235            return R300_FG_ALPHA_FUNC_ALWAYS;
236        default:
237            /* XXX shouldn't be reachable */
238            break;
239    }
240    return 0;
241}
242
243/* Create a new depth, stencil, and alpha state based on the CSO dsa state.
244 *
245 * This contains the depth buffer, stencil buffer, alpha test, and such.
246 * On the Radeon, depth and stencil buffer setup are intertwined, which is
247 * the reason for some of the strange-looking assignments across registers. */
248static void* r300_create_dsa_state(struct pipe_context* pipe,
249                                   struct pipe_depth_stencil_alpha_state* state)
250{
251    struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);
252
253    /* Depth test setup. */
254    if (state->depth.enabled) {
255        dsa->z_buffer_control |= R300_Z_ENABLE;
256
257        if (state->depth.writemask) {
258            dsa->z_buffer_control |= R300_Z_WRITE_ENABLE;
259        }
260
261        dsa->z_stencil_control |=
262                (translate_depth_stencil_function(state->depth.func) <<
263                    R300_Z_FUNC_SHIFT);
264    }
265
266    /* Stencil buffer setup. */
267    if (state->stencil[0].enabled) {
268        dsa->z_buffer_control |= R300_STENCIL_ENABLE;
269        dsa->z_stencil_control |=
270                (translate_depth_stencil_function(state->stencil[0].func) <<
271                    R300_S_FRONT_FUNC_SHIFT) |
272                (translate_stencil_op(state->stencil[0].fail_op) <<
273                    R300_S_FRONT_SFAIL_OP_SHIFT) |
274                (translate_stencil_op(state->stencil[0].zpass_op) <<
275                    R300_S_FRONT_ZPASS_OP_SHIFT) |
276                (translate_stencil_op(state->stencil[0].zfail_op) <<
277                    R300_S_FRONT_ZFAIL_OP_SHIFT);
278
279        dsa->stencil_ref_mask = (state->stencil[0].ref_value) |
280                (state->stencil[0].value_mask << R300_STENCILMASK_SHIFT) |
281                (state->stencil[0].write_mask << R300_STENCILWRITEMASK_SHIFT);
282
283        if (state->stencil[1].enabled) {
284            dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK;
285            dsa->z_stencil_control |=
286                    (translate_depth_stencil_function(state->stencil[1].func) <<
287                        R300_S_BACK_FUNC_SHIFT) |
288                    (translate_stencil_op(state->stencil[1].fail_op) <<
289                        R300_S_BACK_SFAIL_OP_SHIFT) |
290                    (translate_stencil_op(state->stencil[1].zpass_op) <<
291                        R300_S_BACK_ZPASS_OP_SHIFT) |
292                    (translate_stencil_op(state->stencil[1].zfail_op) <<
293                        R300_S_BACK_ZFAIL_OP_SHIFT);
294
295            dsa->stencil_ref_bf = (state->stencil[1].ref_value) |
296                    (state->stencil[1].value_mask << R300_STENCILMASK_SHIFT) |
297                    (state->stencil[1].write_mask << R300_STENCILWRITEMASK_SHIFT);
298        }
299    }
300
301    /* Alpha test setup. */
302    if (state->alpha.enabled) {
303        dsa->alpha_function = translate_alpha_function(state->alpha.func) |
304                R300_FG_ALPHA_FUNC_ENABLE;
305        dsa->alpha_reference = CLAMP(state->alpha.ref * 1023.0f, 0, 1023);
306    } else {
307        dsa->z_buffer_top = R300_ZTOP_ENABLE;
308    }
309
310    return (void*)dsa;
311}
312
313/* Bind DSA state. */
314static void r300_bind_dsa_state(struct pipe_context* pipe,
315                                  void* state)
316{
317    struct r300_context* r300 = r300_context(pipe);
318
319    r300->dsa_state = (struct r300_dsa_state*)state;
320    r300->dirty_state |= R300_NEW_DSA;
321}
322
323/* Free DSA state. */
324static void r300_delete_dsa_state(struct pipe_context* pipe,
325                                    void* state)
326{
327    FREE(state);
328}
329#if 0
330struct pipe_rasterizer_state
331{
332    unsigned flatshade:1;
333    unsigned light_twoside:1;
334    unsigned fill_cw:2;        /**< PIPE_POLYGON_MODE_x */
335    unsigned fill_ccw:2;       /**< PIPE_POLYGON_MODE_x */
336    unsigned scissor:1;
337    unsigned poly_smooth:1;
338    unsigned poly_stipple_enable:1;
339    unsigned point_smooth:1;
340    unsigned point_sprite:1;
341    unsigned point_size_per_vertex:1; /**< size computed in vertex shader */
342    unsigned multisample:1;         /* XXX maybe more ms state in future */
343    unsigned line_smooth:1;
344    unsigned line_stipple_enable:1;
345    unsigned line_stipple_factor:8;  /**< [1..256] actually */
346    unsigned line_stipple_pattern:16;
347    unsigned line_last_pixel:1;
348    unsigned bypass_clipping:1;
349    unsigned bypass_vs:1; /**< Skip the vertex shader.  Note that the shader is
350    still needed though, to indicate inputs/outputs */
351    unsigned origin_lower_left:1;  /**< Is (0,0) the lower-left corner? */
352    unsigned flatshade_first:1;   /**< take color attribute from the first vertex of a primitive */
353    unsigned gl_rasterization_rules:1; /**< enable tweaks for GL rasterization?  */
354
355    float line_width;
356    float point_size;           /**< used when no per-vertex size */
357    float point_size_min;        /* XXX - temporary, will go away */
358    float point_size_max;        /* XXX - temporary, will go away */
359    ubyte sprite_coord_mode[PIPE_MAX_SHADER_OUTPUTS]; /**< PIPE_SPRITE_COORD_ */
360};
361#endif
362/* Create a new rasterizer state based on the CSO rasterizer state.
363 *
364 * This is a very large chunk of state, and covers most of the graphics
365 * backend (GB), geometry assembly (GA), and setup unit (SU) blocks.
366 *
367 * In a not entirely unironic sidenote, this state has nearly nothing to do
368 * with the actual block on the Radeon called the rasterizer (RS). */
369static void* r300_create_rs_state(struct pipe_context* pipe,
370                                          struct pipe_rasterizer_state* state)
371{
372    struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state);
373
374    /* Radeons don't think in "CW/CCW", they think in "front/back". */
375    if (state->front_winding == PIPE_WINDING_CW) {
376        rs->cull_mode = R300_FRONT_FACE_CW;
377
378        if (state->offset_cw) {
379            rs->polygon_offset_enable |= R300_FRONT_ENABLE;
380        }
381        if (state->offset_ccw) {
382            rs->polygon_offset_enable |= R300_BACK_ENABLE;
383        }
384    } else {
385        rs->cull_mode = R300_FRONT_FACE_CCW;
386
387        if (state->offset_ccw) {
388            rs->polygon_offset_enable |= R300_FRONT_ENABLE;
389        }
390        if (state->offset_cw) {
391            rs->polygon_offset_enable |= R300_BACK_ENABLE;
392        }
393    }
394    if (state->front_winding & state->cull_mode) {
395        rs->cull_mode |= R300_CULL_FRONT;
396    }
397    if (~(state->front_winding) & state->cull_mode) {
398        rs->cull_mode |= R300_CULL_BACK;
399    }
400
401    if (rs->polygon_offset_enable) {
402        rs->depth_offset_front = rs->depth_offset_back =
403                pack_float_32(state->offset_units);
404        rs->depth_scale_front = rs->depth_scale_back =
405                pack_float_32(state->offset_scale);
406    }
407
408    return (void*)rs;
409}
410
411/* Bind rasterizer state. */
412static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
413{
414    struct r300_context* r300 = r300_context(pipe);
415
416    r300->rs_state = (struct r300_rs_state*)state;
417    r300->dirty_state |= R300_NEW_RS;
418}
419
420/* Free rasterizer state. */
421static void r300_delete_rs_state(struct pipe_context* pipe, void* state)
422{
423    FREE(state);
424}
425
426static void r300_set_scissor_state(struct pipe_context* pipe,
427                                   struct pipe_scissor_state* state)
428{
429    struct r300_context* r300 = r300_context(pipe);
430    draw_flush(r300->draw);
431
432    uint32_t left, top, right, bottom;
433
434    /* So, a bit of info. The scissors are offset by R300_SCISSORS_OFFSET in
435     * both directions for all values, and can only be 13 bits wide. Why?
436     * We may never know. */
437    left = (state->minx + R300_SCISSORS_OFFSET) & 0x1fff;
438    top = (state->miny + R300_SCISSORS_OFFSET) & 0x1fff;
439    right = (state->maxx + R300_SCISSORS_OFFSET) & 0x1fff;
440    bottom = (state->maxy + R300_SCISSORS_OFFSET) & 0x1fff;
441
442    r300->scissor_state->scissor_top_left = (left << R300_SCISSORS_X_SHIFT) |
443            (top << R300_SCISSORS_Y_SHIFT);
444    r300->scissor_state->scissor_bottom_right = (right << R300_SCISSORS_X_SHIFT) |
445            (bottom << R300_SCISSORS_Y_SHIFT);
446
447    r300->dirty_state |= R300_NEW_SCISSOR;
448}
449
450static void* r300_create_vs_state(struct pipe_context* pipe,
451                                  struct pipe_shader_state* state)
452{
453    struct r300_context* context = r300_context(pipe);
454    /* XXX handing this off to Draw for now */
455    return draw_create_vertex_shader(context->draw, state);
456}
457
458static void r300_bind_vs_state(struct pipe_context* pipe, void* state) {
459    struct r300_context* context = r300_context(pipe);
460    /* XXX handing this off to Draw for now */
461    draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
462}
463
464static void r300_delete_vs_state(struct pipe_context* pipe, void* state)
465{
466    struct r300_context* context = r300_context(pipe);
467    /* XXX handing this off to Draw for now */
468    draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
469}
470
471void r300_init_state_functions(struct r300_context* r300) {
472
473    r300->context.create_blend_state = r300_create_blend_state;
474    r300->context.bind_blend_state = r300_bind_blend_state;
475    r300->context.delete_blend_state = r300_delete_blend_state;
476
477    r300->context.create_rasterizer_state = r300_create_rs_state;
478    r300->context.bind_rasterizer_state = r300_bind_rs_state;
479    r300->context.delete_rasterizer_state = r300_delete_rs_state;
480
481    r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state;
482    r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state;
483    r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state;
484
485    r300->context.set_scissor_state = r300_set_scissor_state;
486
487    r300->context.create_vs_state = r300_create_vs_state;
488    r300->context.bind_vs_state = r300_bind_vs_state;
489    r300->context.delete_vs_state = r300_delete_vs_state;
490}