Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2009 Joakim Sindholt <opensource@zhasha.com>
  3.  *                Corbin Simpson <MostAwesomeDude@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.