r300_state.c revision bbb1c6f6298fcb1125a8170f22646f326b0ca74c
1603c4be006d8c53905d736bf1f19a49f5ce98276Alexey Samsonov/*
27ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
37ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany *
47ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * Permission is hereby granted, free of charge, to any person obtaining a
57ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * copy of this software and associated documentation files (the "Software"),
67ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * to deal in the Software without restriction, including without limitation
77ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * on the rights to use, copy, modify, merge, publish, distribute, sub
87ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * license, and/or sell copies of the Software, and to permit persons to whom
97ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * the Software is furnished to do so, subject to the following conditions:
107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany *
117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * The above copyright notice and this permission notice (including the next
127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * paragraph) shall be included in all copies or substantial portions of the
130969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov * Software.
147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany *
157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * USE OR OTHER DEALINGS IN THE SOFTWARE. */
227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "r300_context.h"
247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "r300_state.h"
257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic uint32_t translate_blend_function(int blend_func) {
277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    switch (blend_func) {
2886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines        case PIPE_BLEND_ADD:
297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_COMB_FCN_ADD_CLAMP;
307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLEND_SUBTRACT:
31f4e4f9393ed1cf9cbefaafc6ea8fd9b89fea4bcfDmitry Vyukov            return R300_COMB_FCN_SUB_CLAMP;
32f4e4f9393ed1cf9cbefaafc6ea8fd9b89fea4bcfDmitry Vyukov        case PIPE_BLEND_REVERSE_SUBTRACT:
33f4e4f9393ed1cf9cbefaafc6ea8fd9b89fea4bcfDmitry Vyukov            return R300_COMB_FCN_RSUB_CLAMP;
346a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines        case PIPE_BLEND_MIN:
3594d8b448e046f3976b13ab79130c389115754022Dmitry Vyukov            return R300_COMB_FCN_MIN;
362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        case PIPE_BLEND_MAX:
376a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines            return R300_COMB_FCN_MAX;
38f4e4f9393ed1cf9cbefaafc6ea8fd9b89fea4bcfDmitry Vyukov        default:
39f4e4f9393ed1cf9cbefaafc6ea8fd9b89fea4bcfDmitry Vyukov            /* XXX should be unreachable, handle this */
406a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines            break;
41f4e4f9393ed1cf9cbefaafc6ea8fd9b89fea4bcfDmitry Vyukov    }
42f4e4f9393ed1cf9cbefaafc6ea8fd9b89fea4bcfDmitry Vyukov    return 0;
432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines}
443d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
453d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar/* XXX we can also offer the D3D versions of some of these... */
467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic uint32_t translate_blend_factor(int blend_fact) {
477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    switch (blend_fact) {
487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_ONE:
49d62237995d0fc50697e375ea50f015e996162884Dmitry Vyukov            return R300_BLEND_GL_ONE;
507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_SRC_COLOR:
517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_BLEND_GL_SRC_COLOR;
5286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines        case PIPE_BLENDFACTOR_SRC_ALPHA:
537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_BLEND_GL_SRC_ALPHA;
547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_DST_ALPHA:
557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_BLEND_GL_DST_ALPHA;
567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_DST_COLOR:
577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_BLEND_GL_DST_COLOR;
587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_BLEND_GL_SRC_ALPHA_SATURATE;
602135d8a7f4ba30fe35ed02d5e6ffd59a95b26219Alexey Samsonov        case PIPE_BLENDFACTOR_CONST_COLOR:
617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_BLEND_GL_CONST_COLOR;
627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_CONST_ALPHA:
637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_BLEND_GL_CONST_ALPHA;
647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        /* XXX WTF are these?
657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_SRC1_COLOR:
667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_SRC1_ALPHA: */
677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_ZERO:
682135d8a7f4ba30fe35ed02d5e6ffd59a95b26219Alexey Samsonov            return R300_BLEND_GL_ZERO;
692135d8a7f4ba30fe35ed02d5e6ffd59a95b26219Alexey Samsonov        case PIPE_BLENDFACTOR_INV_SRC_COLOR:
707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_BLEND_GL_ONE_MINUS_SRC_COLOR;
717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA;
737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_INV_DST_ALPHA:
747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_BLEND_GL_ONE_MINUS_DST_ALPHA;
757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_INV_DST_COLOR:
767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_BLEND_GL_ONE_MINUS_DST_COLOR;
777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_INV_CONST_COLOR:
787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_BLEND_GL_ONE_MINUS_CONST_COLOR;
797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA;
817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        /* XXX see above
827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: */
847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        default:
857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            /* XXX the mythical 0x16 blend factor! */
867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            break;
877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    }
887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    return 0;
897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany/* Create a new blend state based on the CSO blend state.
927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany *
937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * This encompasses alpha blending, logic/raster ops, and blend dithering. */
947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void* r300_create_blend_state(struct pipe_context* pipe,
957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                                     struct pipe_blend_state* state)
967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany{
977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state);
987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    if (state->blend_enable) {
1007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        /* XXX for now, always do separate alpha...
1017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany         * is it faster to do it with one reg? */
1027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        blend->blend_control = R300_ALPHA_BLEND_ENABLE |
1037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                R300_SEPARATE_ALPHA_ENABLE |
104b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov                R300_READ_ENABLE |
1057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                translate_blend_function(state->rgb_func) |
1067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                (translate_blend_factor(state->rgb_src_factor) <<
107b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov                    R300_SRC_BLEND_SHIFT) |
1087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                (translate_blend_factor(state->rgb_dst_factor) <<
109b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov                    R300_DST_BLEND_SHIFT);
1107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        blend->alpha_blend_control =
111b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov                translate_blend_function(state->alpha_func) |
1127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                (translate_blend_factor(state->alpha_src_factor) <<
1137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                    R300_SRC_BLEND_SHIFT) |
114b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov                (translate_blend_factor(state->alpha_dst_factor) <<
1157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                    R300_DST_BLEND_SHIFT);
116b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov    }
1177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    /* PIPE_LOGICOP_* don't need to be translated, fortunately. */
1197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    /* XXX are logicops still allowed if blending's disabled?
1207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany     * Does Gallium take care of it for us? */
1217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    if (state->logicop_enable) {
122b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov        blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE |
1237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                (state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT;
1247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    }
1257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
126d62237995d0fc50697e375ea50f015e996162884Dmitry Vyukov    if (state->dither) {
1277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        blend->dither = R300_RB3D_DITHER_CTL_DITHER_MODE_LUT |
1287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT;
1292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines    }
1307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    return (void*)blend;
1327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
13386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
1342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines/* Bind blend state. */
135b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonovstatic void r300_bind_blend_state(struct pipe_context* pipe,
136ad9da372f962495b3487685232d09390be841b1cDmitry Vyukov                                  void* state)
137ad9da372f962495b3487685232d09390be841b1cDmitry Vyukov{
1387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    struct r300_context* r300 = r300_context(pipe);
1397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    r300->blend_state = (struct r300_blend_state*)state;
1417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    r300->dirty_state |= R300_NEW_BLEND;
1427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
1437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany/* Free blend state. */
1457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void r300_delete_blend_state(struct pipe_context* pipe,
1467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                                    void* state)
1477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany{
1487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    FREE(state);
1497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
1507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
1517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic uint32_t translate_depth_stencil_function(int zs_func) {
152b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov    switch (zs_func) {
1537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_FUNC_NEVER:
154b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov            return R300_ZS_NEVER;
155b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov        case PIPE_FUNC_LESS:
156e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov            return R300_ZS_LESS;
157ff35f1d82b4f145b3477ef27a7a2e7b63c486988Dmitry Vyukov        case PIPE_FUNC_EQUAL:
1587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_ZS_EQUAL;
1597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_FUNC_LEQUAL:
1607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_ZS_LEQUAL;
1612d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        case PIPE_FUNC_GREATER:
162b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov            return R300_ZS_GREATER;
1637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_FUNC_NOTEQUAL:
1647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_ZS_NOTEQUAL;
1657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_FUNC_GEQUAL:
1666a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines            return R300_ZS_GEQUAL;
1676a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines        case PIPE_FUNC_ALWAYS:
1686a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines            return R300_ZS_ALWAYS;
1696a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines        default:
1706a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines            /* XXX shouldn't be reachable */
1716a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines            break;
1726a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    }
1736a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines    return 0;
1746a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines}
17586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
1766a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hinesstatic uint32_t translate_stencil_op(int s_op) {
177d62237995d0fc50697e375ea50f015e996162884Dmitry Vyukov    switch (s_op) {
1786a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines        case PIPE_STENCIL_OP_KEEP:
1797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_ZS_KEEP;
1807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_STENCIL_OP_ZERO:
1817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_ZS_ZERO;
1827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_STENCIL_OP_REPLACE:
1837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_ZS_REPLACE;
1847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_STENCIL_OP_INCR:
1857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_ZS_INCR;
1867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_STENCIL_OP_DECR:
1877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_ZS_DECR;
1887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_STENCIL_OP_INCR_WRAP:
1897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_ZS_INCR_WRAP;
1907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_STENCIL_OP_DECR_WRAP:
1917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_ZS_DECR_WRAP;
1927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_STENCIL_OP_INVERT:
1937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_ZS_INVERT;
1940969bcf2c936126b1f6e636b978aade8fc207437Alexey Samsonov        default:
1957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            /* XXX shouldn't be reachable */
1967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            break;
1977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    }
1987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    return 0;
1997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
2007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
2017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic uint32_t translate_alpha_function(int alpha_func) {
2027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    switch (alpha_func) {
2037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_FUNC_NEVER:
2047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_FG_ALPHA_FUNC_NEVER;
2057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_FUNC_LESS:
2067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_FG_ALPHA_FUNC_LESS;
2077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_FUNC_EQUAL:
2087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_FG_ALPHA_FUNC_EQUAL;
2097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_FUNC_LEQUAL:
2107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_FG_ALPHA_FUNC_LE;
2117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_FUNC_GREATER:
2127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_FG_ALPHA_FUNC_GREATER;
21386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines        case PIPE_FUNC_NOTEQUAL:
2147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_FG_ALPHA_FUNC_NOTEQUAL;
2157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_FUNC_GEQUAL:
2167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_FG_ALPHA_FUNC_GE;
2177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        case PIPE_FUNC_ALWAYS:
2187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            return R300_FG_ALPHA_FUNC_ALWAYS;
2197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        default:
2207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            /* XXX shouldn't be reachable */
2217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            break;
2227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    }
2237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    return 0;
2247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}
2257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
2267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany/* Create a new depth, stencil, and alpha state based on the CSO dsa state.
22786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines *
2282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines * This contains the depth buffer, stencil buffer, alpha test, and such.
2297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * On the Radeon, depth and stencil buffer setup are intertwined, which is
2307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany * the reason for some of the strange-looking assignments across registers. */
2317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void* r300_create_dsa_state(struct pipe_context* pipe,
2327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                                     struct pipe_depth_stencil_alpha_state* state)
2337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany{
2347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state);
2357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
2367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    /* Depth test setup. */
2377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    if (state->depth.enabled) {
2387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        dsa->z_buffer_control |= R300_Z_ENABLE;
23986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
2407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        if (state->depth.writemask) {
2417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            dsa->z_buffer_control |= R300_Z_WRITE_ENABLE;
2427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        }
2437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
2447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        dsa->z_stencil_control |=
2457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                (translate_depth_stencil_function(state->depth.func) <<
2467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                    R300_Z_FUNC_SHIFT);
2477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    }
2487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
2497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    /* Stencil buffer setup. */
2507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    if (state->stencil[0].enabled) {
2517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        dsa->z_buffer_control |= R300_STENCIL_ENABLE;
25286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines        dsa->z_stencil_control |=
2532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                (translate_depth_stencil_function(state->stencil[0].func) <<
2547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                    R300_S_FRONT_FUNC_SHIFT) |
2557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                (translate_stencil_op(state->stencil[0].fail_op) <<
2567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                    R300_S_FRONT_SFAIL_OP_SHIFT) |
2577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                (translate_stencil_op(state->stencil[0].zpass_op) <<
25886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines                    R300_S_FRONT_ZPASS_OP_SHIFT) |
2592d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines                (translate_stencil_op(state->stencil[0].zfail_op) <<
2607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                    R300_S_FRONT_ZFAIL_OP_SHIFT);
2617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
2627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        dsa->stencil_ref_mask = (state->stencil[0].ref_value) |
2637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                (state->stencil[0].value_mask << R300_STENCILMASK_SHIFT) |
2647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                (state->stencil[0].write_mask << R300_STENCILWRITEMASK_SHIFT);
2657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
2667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany        if (state->stencil[1].enabled) {
26786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines            dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK;
2687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            dsa->z_stencil_control |=
2697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                    (translate_depth_stencil_function(state->stencil[1].func) <<
2707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                        R300_S_BACK_FUNC_SHIFT) |
2717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                    (translate_stencil_op(state->stencil[1].fail_op) <<
2727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                        R300_S_BACK_SFAIL_OP_SHIFT) |
2737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                    (translate_stencil_op(state->stencil[1].zpass_op) <<
2747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                        R300_S_BACK_ZPASS_OP_SHIFT) |
2757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                    (translate_stencil_op(state->stencil[1].zfail_op) <<
2767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                        R300_S_BACK_ZFAIL_OP_SHIFT);
2777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
2787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany            dsa->stencil_ref_bf = (state->stencil[1].ref_value) |
2797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany                    (state->stencil[1].value_mask << R300_STENCILMASK_SHIFT) |
28086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines                    (state->stencil[1].write_mask << R300_STENCILWRITEMASK_SHIFT);
2812d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines        }
2827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    }
2837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany
2847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    /* Alpha test setup. */
285ff35f1d82b4f145b3477ef27a7a2e7b63c486988Dmitry Vyukov    if (state->alpha.enabled) {
286ff35f1d82b4f145b3477ef27a7a2e7b63c486988Dmitry Vyukov        dsa->alpha_function = translate_alpha_function(state->alpha.func) |
287ff35f1d82b4f145b3477ef27a7a2e7b63c486988Dmitry Vyukov                R300_FG_ALPHA_FUNC_ENABLE;
288ff35f1d82b4f145b3477ef27a7a2e7b63c486988Dmitry Vyukov        dsa->alpha_reference = CLAMP(state->alpha.ref * 1023.0f, 0, 1023);
2897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany    } else {
290        dsa->z_buffer_top = R300_ZTOP_ENABLE;
291    }
292
293    return (void*)dsa;
294}
295
296/* Bind DSA state. */
297static void r300_bind_dsa_state(struct pipe_context* pipe,
298                                  void* state)
299{
300    struct r300_context* r300 = r300_context(pipe);
301
302    r300->dsa_state = (struct r300_dsa_state*)state;
303    r300->dirty_state |= R300_NEW_DSA;
304}
305
306/* Free DSA state. */
307static void r300_delete_dsa_state(struct pipe_context* pipe,
308                                    void* state)
309{
310    FREE(state);
311}
312
313/* Create a new scissor state based on the CSO scissor state.
314 *
315 * This is only for the fragment scissors. */
316static void* r300_create_scissor_state(struct pipe_context* pipe,
317                                    struct pipe_scissor_state* state)
318{
319    uint32_t left, top, right, bottom;
320    struct r300_scissor_state* scissor = CALLOC_STRUCT(r300_scissor_state);
321
322    /* So, a bit of info. The scissors are offset by R300_SCISSORS_OFFSET in
323     * both directions for all values, and can only be 13 bits wide. Why?
324     * We may never know. */
325    left = (state->minx + R300_SCISSORS_OFFSET) & 0x1fff;
326    top = (state->miny + R300_SCISSORS_OFFSET) & 0x1fff;
327    right = (state->maxx + R300_SCISSORS_OFFSET) & 0x1fff;
328    bottom = (state->maxy + R300_SCISSORS_OFFSET) & 0x1fff;
329
330    scissor->scissor_top_left = (left << R300_SCISSORS_X_SHIFT) |
331            (top << R300_SCISSORS_Y_SHIFT);
332    scissor->scissor_bottom_right = (right << R300_SCISSORS_X_SHIFT) |
333            (bottom << R300_SCISSORS_Y_SHIFT);
334
335    return (void*)scissor;
336}
337
338/* Bind scissor state.*/
339static void r300_bind_scissor_state(struct pipe_context* pipe,
340                                 void* state)
341{
342    struct r300_context* r300 = r300_context(pipe);
343
344    r300->scissor_state = (struct r300_scissor_state*)state;
345    r300->dirty_state |= R300_NEW_SCISSOR;
346}
347
348/* Delete scissor state. */
349static void r300_delete_scissor_state(struct pipe_context* pipe,
350                                   void* state)
351{
352    FREE(state);
353}
354
355static void* r300_create_vs_state(struct pipe_context* pipe,
356                                  struct pipe_shader_state* state)
357{
358    struct r300_context* context = r300_context(pipe);
359    /* XXX handing this off to Draw for now */
360    return draw_create_vertex_shader(context->draw, state);
361}
362
363static void r300_bind_vs_state(struct pipe_context* pipe, void* state) {
364    struct r300_context* context = r300_context(pipe);
365    /* XXX handing this off to Draw for now */
366    draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
367}
368
369static void r300_delete_vs_state(struct pipe_context* pipe, void* state)
370{
371    struct r300_context* context = r300_context(pipe);
372    /* XXX handing this off to Draw for now */
373    draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state);
374}