Home | History | Annotate | Download | only in r300
      1 /*
      2  * Copyright 2009 Joakim Sindholt <opensource (at) zhasha.com>
      3  *                Corbin Simpson <MostAwesomeDude (at) gmail.com>
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * on the rights to use, copy, modify, merge, publish, distribute, sub
      9  * license, and/or sell copies of the Software, and to permit persons to whom
     10  * the Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice (including the next
     13  * paragraph) shall be included in all copies or substantial portions of the
     14  * Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     19  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
     20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     22  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
     23 
     24 #ifndef R300_STATE_INLINES_H
     25 #define R300_STATE_INLINES_H
     26 
     27 #include "draw/draw_vertex.h"
     28 #include "pipe/p_format.h"
     29 #include "util/u_format.h"
     30 #include "r300_reg.h"
     31 #include <stdio.h>
     32 
     33 /* Some maths. These should probably find their way to u_math, if needed. */
     34 
     35 static inline int pack_float_16_6x(float f) {
     36     return ((int)(f * 6.0) & 0xffff);
     37 }
     38 
     39 /* Blend state. */
     40 
     41 static inline uint32_t r300_translate_blend_function(int blend_func,
     42                                                      boolean clamp)
     43 {
     44     switch (blend_func) {
     45     case PIPE_BLEND_ADD:
     46         return clamp ? R300_COMB_FCN_ADD_CLAMP : R300_COMB_FCN_ADD_NOCLAMP;
     47     case PIPE_BLEND_SUBTRACT:
     48         return clamp ? R300_COMB_FCN_SUB_CLAMP : R300_COMB_FCN_SUB_NOCLAMP;
     49     case PIPE_BLEND_REVERSE_SUBTRACT:
     50         return clamp ? R300_COMB_FCN_RSUB_CLAMP : R300_COMB_FCN_RSUB_NOCLAMP;
     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         fprintf(stderr, "r300: Unknown blend function %d\n", blend_func);
     57         assert(0);
     58         break;
     59     }
     60     return 0;
     61 }
     62 
     63 static inline uint32_t r300_translate_blend_factor(int blend_fact)
     64 {
     65     switch (blend_fact) {
     66         case PIPE_BLENDFACTOR_ONE:
     67             return R300_BLEND_GL_ONE;
     68         case PIPE_BLENDFACTOR_SRC_COLOR:
     69             return R300_BLEND_GL_SRC_COLOR;
     70         case PIPE_BLENDFACTOR_SRC_ALPHA:
     71             return R300_BLEND_GL_SRC_ALPHA;
     72         case PIPE_BLENDFACTOR_DST_ALPHA:
     73             return R300_BLEND_GL_DST_ALPHA;
     74         case PIPE_BLENDFACTOR_DST_COLOR:
     75             return R300_BLEND_GL_DST_COLOR;
     76         case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
     77             return R300_BLEND_GL_SRC_ALPHA_SATURATE;
     78         case PIPE_BLENDFACTOR_CONST_COLOR:
     79             return R300_BLEND_GL_CONST_COLOR;
     80         case PIPE_BLENDFACTOR_CONST_ALPHA:
     81             return R300_BLEND_GL_CONST_ALPHA;
     82         case PIPE_BLENDFACTOR_ZERO:
     83             return R300_BLEND_GL_ZERO;
     84         case PIPE_BLENDFACTOR_INV_SRC_COLOR:
     85             return R300_BLEND_GL_ONE_MINUS_SRC_COLOR;
     86         case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
     87             return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA;
     88         case PIPE_BLENDFACTOR_INV_DST_ALPHA:
     89             return R300_BLEND_GL_ONE_MINUS_DST_ALPHA;
     90         case PIPE_BLENDFACTOR_INV_DST_COLOR:
     91             return R300_BLEND_GL_ONE_MINUS_DST_COLOR;
     92         case PIPE_BLENDFACTOR_INV_CONST_COLOR:
     93             return R300_BLEND_GL_ONE_MINUS_CONST_COLOR;
     94         case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
     95             return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA;
     96 
     97         case PIPE_BLENDFACTOR_SRC1_COLOR:
     98         case PIPE_BLENDFACTOR_SRC1_ALPHA:
     99         case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
    100         case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
    101             fprintf(stderr, "r300: Implementation error: "
    102                 "Bad blend factor %d not supported!\n", blend_fact);
    103             assert(0);
    104             break;
    105 
    106         default:
    107             fprintf(stderr, "r300: Unknown blend factor %d\n", blend_fact);
    108             assert(0);
    109             break;
    110     }
    111     return 0;
    112 }
    113 
    114 /* DSA state. */
    115 
    116 static inline uint32_t r300_translate_depth_stencil_function(int zs_func)
    117 {
    118     switch (zs_func) {
    119         case PIPE_FUNC_NEVER:
    120             return R300_ZS_NEVER;
    121         case PIPE_FUNC_LESS:
    122             return R300_ZS_LESS;
    123         case PIPE_FUNC_EQUAL:
    124             return R300_ZS_EQUAL;
    125         case PIPE_FUNC_LEQUAL:
    126             return R300_ZS_LEQUAL;
    127         case PIPE_FUNC_GREATER:
    128             return R300_ZS_GREATER;
    129         case PIPE_FUNC_NOTEQUAL:
    130             return R300_ZS_NOTEQUAL;
    131         case PIPE_FUNC_GEQUAL:
    132             return R300_ZS_GEQUAL;
    133         case PIPE_FUNC_ALWAYS:
    134             return R300_ZS_ALWAYS;
    135         default:
    136             fprintf(stderr, "r300: Unknown depth/stencil function %d\n",
    137                 zs_func);
    138             assert(0);
    139             break;
    140     }
    141     return 0;
    142 }
    143 
    144 static inline uint32_t r300_translate_stencil_op(int s_op)
    145 {
    146     switch (s_op) {
    147         case PIPE_STENCIL_OP_KEEP:
    148             return R300_ZS_KEEP;
    149         case PIPE_STENCIL_OP_ZERO:
    150             return R300_ZS_ZERO;
    151         case PIPE_STENCIL_OP_REPLACE:
    152             return R300_ZS_REPLACE;
    153         case PIPE_STENCIL_OP_INCR:
    154             return R300_ZS_INCR;
    155         case PIPE_STENCIL_OP_DECR:
    156             return R300_ZS_DECR;
    157         case PIPE_STENCIL_OP_INCR_WRAP:
    158             return R300_ZS_INCR_WRAP;
    159         case PIPE_STENCIL_OP_DECR_WRAP:
    160             return R300_ZS_DECR_WRAP;
    161         case PIPE_STENCIL_OP_INVERT:
    162             return R300_ZS_INVERT;
    163         default:
    164             fprintf(stderr, "r300: Unknown stencil op %d", s_op);
    165             assert(0);
    166             break;
    167     }
    168     return 0;
    169 }
    170 
    171 static inline uint32_t r300_translate_alpha_function(int alpha_func)
    172 {
    173     switch (alpha_func) {
    174         case PIPE_FUNC_NEVER:
    175             return R300_FG_ALPHA_FUNC_NEVER;
    176         case PIPE_FUNC_LESS:
    177             return R300_FG_ALPHA_FUNC_LESS;
    178         case PIPE_FUNC_EQUAL:
    179             return R300_FG_ALPHA_FUNC_EQUAL;
    180         case PIPE_FUNC_LEQUAL:
    181             return R300_FG_ALPHA_FUNC_LE;
    182         case PIPE_FUNC_GREATER:
    183             return R300_FG_ALPHA_FUNC_GREATER;
    184         case PIPE_FUNC_NOTEQUAL:
    185             return R300_FG_ALPHA_FUNC_NOTEQUAL;
    186         case PIPE_FUNC_GEQUAL:
    187             return R300_FG_ALPHA_FUNC_GE;
    188         case PIPE_FUNC_ALWAYS:
    189             return R300_FG_ALPHA_FUNC_ALWAYS;
    190         default:
    191             fprintf(stderr, "r300: Unknown alpha function %d", alpha_func);
    192             assert(0);
    193             break;
    194     }
    195     return 0;
    196 }
    197 
    198 static inline uint32_t
    199 r300_translate_polygon_mode_front(unsigned mode) {
    200     switch (mode)
    201     {
    202         case PIPE_POLYGON_MODE_FILL:
    203             return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
    204         case PIPE_POLYGON_MODE_LINE:
    205             return R300_GA_POLY_MODE_FRONT_PTYPE_LINE;
    206         case PIPE_POLYGON_MODE_POINT:
    207             return R300_GA_POLY_MODE_FRONT_PTYPE_POINT;
    208 
    209         default:
    210             fprintf(stderr, "r300: Bad polygon mode %i in %s\n", mode,
    211                 __FUNCTION__);
    212             return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
    213     }
    214 }
    215 
    216 static inline uint32_t
    217 r300_translate_polygon_mode_back(unsigned mode) {
    218     switch (mode)
    219     {
    220         case PIPE_POLYGON_MODE_FILL:
    221             return R300_GA_POLY_MODE_BACK_PTYPE_TRI;
    222         case PIPE_POLYGON_MODE_LINE:
    223             return R300_GA_POLY_MODE_BACK_PTYPE_LINE;
    224         case PIPE_POLYGON_MODE_POINT:
    225             return R300_GA_POLY_MODE_BACK_PTYPE_POINT;
    226 
    227         default:
    228             fprintf(stderr, "r300: Bad polygon mode %i in %s\n", mode,
    229                 __FUNCTION__);
    230             return R300_GA_POLY_MODE_BACK_PTYPE_TRI;
    231     }
    232 }
    233 
    234 /* Texture sampler state. */
    235 
    236 static inline uint32_t r300_translate_wrap(int wrap)
    237 {
    238     switch (wrap) {
    239         case PIPE_TEX_WRAP_REPEAT:
    240             return R300_TX_REPEAT;
    241         case PIPE_TEX_WRAP_CLAMP:
    242             return R300_TX_CLAMP;
    243         case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
    244             return R300_TX_CLAMP_TO_EDGE;
    245         case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
    246             return R300_TX_CLAMP_TO_BORDER;
    247         case PIPE_TEX_WRAP_MIRROR_REPEAT:
    248             return R300_TX_REPEAT | R300_TX_MIRRORED;
    249         case PIPE_TEX_WRAP_MIRROR_CLAMP:
    250             return R300_TX_CLAMP | R300_TX_MIRRORED;
    251         case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
    252             return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
    253         case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
    254             return R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED;
    255         default:
    256             fprintf(stderr, "r300: Unknown texture wrap %d", wrap);
    257             assert(0);
    258             return 0;
    259     }
    260 }
    261 
    262 static inline uint32_t r300_translate_tex_filters(int min, int mag, int mip,
    263                                                   boolean is_anisotropic)
    264 {
    265     uint32_t retval = 0;
    266 
    267     switch (min) {
    268     case PIPE_TEX_FILTER_NEAREST:
    269         retval |= R300_TX_MIN_FILTER_NEAREST;
    270         break;
    271     case PIPE_TEX_FILTER_LINEAR:
    272         retval |= is_anisotropic ? R300_TX_MIN_FILTER_ANISO :
    273                                    R300_TX_MIN_FILTER_LINEAR;
    274         break;
    275     default:
    276         fprintf(stderr, "r300: Unknown texture filter %d\n", min);
    277         assert(0);
    278     }
    279 
    280     switch (mag) {
    281     case PIPE_TEX_FILTER_NEAREST:
    282         retval |= R300_TX_MAG_FILTER_NEAREST;
    283         break;
    284     case PIPE_TEX_FILTER_LINEAR:
    285         retval |= is_anisotropic ? R300_TX_MAG_FILTER_ANISO :
    286                                    R300_TX_MAG_FILTER_LINEAR;
    287         break;
    288     default:
    289         fprintf(stderr, "r300: Unknown texture filter %d\n", mag);
    290         assert(0);
    291     }
    292 
    293     switch (mip) {
    294     case PIPE_TEX_MIPFILTER_NONE:
    295         retval |= R300_TX_MIN_FILTER_MIP_NONE;
    296         break;
    297     case PIPE_TEX_MIPFILTER_NEAREST:
    298         retval |= R300_TX_MIN_FILTER_MIP_NEAREST;
    299         break;
    300     case PIPE_TEX_MIPFILTER_LINEAR:
    301         retval |= R300_TX_MIN_FILTER_MIP_LINEAR;
    302         break;
    303     default:
    304         fprintf(stderr, "r300: Unknown texture filter %d\n", mip);
    305         assert(0);
    306     }
    307 
    308     return retval;
    309 }
    310 
    311 static inline uint32_t r300_anisotropy(unsigned max_aniso)
    312 {
    313     if (max_aniso >= 16) {
    314         return R300_TX_MAX_ANISO_16_TO_1;
    315     } else if (max_aniso >= 8) {
    316         return R300_TX_MAX_ANISO_8_TO_1;
    317     } else if (max_aniso >= 4) {
    318         return R300_TX_MAX_ANISO_4_TO_1;
    319     } else if (max_aniso >= 2) {
    320         return R300_TX_MAX_ANISO_2_TO_1;
    321     } else {
    322         return R300_TX_MAX_ANISO_1_TO_1;
    323     }
    324 }
    325 
    326 static inline uint32_t r500_anisotropy(unsigned max_aniso)
    327 {
    328     if (!max_aniso) {
    329         return 0;
    330     }
    331     max_aniso -= 1;
    332 
    333     // Map the range [0, 15] to [0, 63].
    334     return R500_TX_MAX_ANISO(MIN2((unsigned)(max_aniso*4.2001), 63)) |
    335            R500_TX_ANISO_HIGH_QUALITY;
    336 }
    337 
    338 /* Translate pipe_formats into PSC vertex types. */
    339 static inline uint16_t
    340 r300_translate_vertex_data_type(enum pipe_format format) {
    341     uint32_t result = 0;
    342     const struct util_format_description *desc;
    343     unsigned i;
    344 
    345     if (!format)
    346         format = PIPE_FORMAT_R32_FLOAT;
    347 
    348     desc = util_format_description(format);
    349 
    350     if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
    351         return R300_INVALID_FORMAT;
    352     }
    353 
    354     /* Find the first non-VOID channel. */
    355     for (i = 0; i < 4; i++) {
    356         if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
    357             break;
    358         }
    359     }
    360 
    361     switch (desc->channel[i].type) {
    362         /* Half-floats, floats, doubles */
    363         case UTIL_FORMAT_TYPE_FLOAT:
    364             switch (desc->channel[i].size) {
    365                 case 16:
    366                     /* Supported only on RV350 and later. */
    367                     if (desc->nr_channels > 2) {
    368                         result = R300_DATA_TYPE_FLT16_4;
    369                     } else {
    370                         result = R300_DATA_TYPE_FLT16_2;
    371                     }
    372                     break;
    373                 case 32:
    374                     result = R300_DATA_TYPE_FLOAT_1 + (desc->nr_channels - 1);
    375                     break;
    376                 default:
    377                     return R300_INVALID_FORMAT;
    378             }
    379             break;
    380         /* Unsigned ints */
    381         case UTIL_FORMAT_TYPE_UNSIGNED:
    382         /* Signed ints */
    383         case UTIL_FORMAT_TYPE_SIGNED:
    384             switch (desc->channel[i].size) {
    385                 case 8:
    386                     result = R300_DATA_TYPE_BYTE;
    387                     break;
    388                 case 16:
    389                     if (desc->nr_channels > 2) {
    390                         result = R300_DATA_TYPE_SHORT_4;
    391                     } else {
    392                         result = R300_DATA_TYPE_SHORT_2;
    393                     }
    394                     break;
    395                 default:
    396                     return R300_INVALID_FORMAT;
    397             }
    398             break;
    399         default:
    400             return R300_INVALID_FORMAT;
    401     }
    402 
    403     if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
    404         result |= R300_SIGNED;
    405     }
    406     if (desc->channel[i].normalized) {
    407         result |= R300_NORMALIZE;
    408     }
    409 
    410     return result;
    411 }
    412 
    413 static inline uint16_t
    414 r300_translate_vertex_data_swizzle(enum pipe_format format) {
    415     const struct util_format_description *desc;
    416     unsigned i, swizzle = 0;
    417 
    418     if (!format)
    419         return (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_X_SHIFT) |
    420                (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Y_SHIFT) |
    421                (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_SHIFT) |
    422                (R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_SHIFT);
    423 
    424     desc = util_format_description(format);
    425 
    426     if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
    427         fprintf(stderr, "r300: Bad format %s in %s:%d\n",
    428             util_format_short_name(format), __FUNCTION__, __LINE__);
    429         return 0;
    430     }
    431 
    432     for (i = 0; i < desc->nr_channels; i++) {
    433         swizzle |=
    434             MIN2(desc->swizzle[i], R300_SWIZZLE_SELECT_FP_ONE) << (3*i);
    435     }
    436     /* Set (0,0,0,1) in unused components. */
    437     for (; i < 3; i++) {
    438         swizzle |= R300_SWIZZLE_SELECT_FP_ZERO << (3*i);
    439     }
    440     for (; i < 4; i++) {
    441         swizzle |= R300_SWIZZLE_SELECT_FP_ONE << (3*i);
    442     }
    443 
    444     return swizzle | (0xf << R300_WRITE_ENA_SHIFT);
    445 }
    446 
    447 #endif /* R300_STATE_INLINES_H */
    448