Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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. /* XXX we can also offer the D3D versions of some of these... */
  64. static INLINE uint32_t r300_translate_blend_factor(int blend_fact)
  65. {
  66.     switch (blend_fact) {
  67.         case PIPE_BLENDFACTOR_ONE:
  68.             return R300_BLEND_GL_ONE;
  69.         case PIPE_BLENDFACTOR_SRC_COLOR:
  70.             return R300_BLEND_GL_SRC_COLOR;
  71.         case PIPE_BLENDFACTOR_SRC_ALPHA:
  72.             return R300_BLEND_GL_SRC_ALPHA;
  73.         case PIPE_BLENDFACTOR_DST_ALPHA:
  74.             return R300_BLEND_GL_DST_ALPHA;
  75.         case PIPE_BLENDFACTOR_DST_COLOR:
  76.             return R300_BLEND_GL_DST_COLOR;
  77.         case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
  78.             return R300_BLEND_GL_SRC_ALPHA_SATURATE;
  79.         case PIPE_BLENDFACTOR_CONST_COLOR:
  80.             return R300_BLEND_GL_CONST_COLOR;
  81.         case PIPE_BLENDFACTOR_CONST_ALPHA:
  82.             return R300_BLEND_GL_CONST_ALPHA;
  83.         case PIPE_BLENDFACTOR_ZERO:
  84.             return R300_BLEND_GL_ZERO;
  85.         case PIPE_BLENDFACTOR_INV_SRC_COLOR:
  86.             return R300_BLEND_GL_ONE_MINUS_SRC_COLOR;
  87.         case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
  88.             return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA;
  89.         case PIPE_BLENDFACTOR_INV_DST_ALPHA:
  90.             return R300_BLEND_GL_ONE_MINUS_DST_ALPHA;
  91.         case PIPE_BLENDFACTOR_INV_DST_COLOR:
  92.             return R300_BLEND_GL_ONE_MINUS_DST_COLOR;
  93.         case PIPE_BLENDFACTOR_INV_CONST_COLOR:
  94.             return R300_BLEND_GL_ONE_MINUS_CONST_COLOR;
  95.         case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
  96.             return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA;
  97.  
  98.         case PIPE_BLENDFACTOR_SRC1_COLOR:
  99.         case PIPE_BLENDFACTOR_SRC1_ALPHA:
  100.         case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
  101.         case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
  102.             fprintf(stderr, "r300: Implementation error: "
  103.                 "Bad blend factor %d not supported!\n", blend_fact);
  104.             assert(0);
  105.             break;
  106.  
  107.         default:
  108.             fprintf(stderr, "r300: Unknown blend factor %d\n", blend_fact);
  109.             assert(0);
  110.             break;
  111.     }
  112.     return 0;
  113. }
  114.  
  115. /* DSA state. */
  116.  
  117. static INLINE uint32_t r300_translate_depth_stencil_function(int zs_func)
  118. {
  119.     switch (zs_func) {
  120.         case PIPE_FUNC_NEVER:
  121.             return R300_ZS_NEVER;
  122.         case PIPE_FUNC_LESS:
  123.             return R300_ZS_LESS;
  124.         case PIPE_FUNC_EQUAL:
  125.             return R300_ZS_EQUAL;
  126.         case PIPE_FUNC_LEQUAL:
  127.             return R300_ZS_LEQUAL;
  128.         case PIPE_FUNC_GREATER:
  129.             return R300_ZS_GREATER;
  130.         case PIPE_FUNC_NOTEQUAL:
  131.             return R300_ZS_NOTEQUAL;
  132.         case PIPE_FUNC_GEQUAL:
  133.             return R300_ZS_GEQUAL;
  134.         case PIPE_FUNC_ALWAYS:
  135.             return R300_ZS_ALWAYS;
  136.         default:
  137.             fprintf(stderr, "r300: Unknown depth/stencil function %d\n",
  138.                 zs_func);
  139.             assert(0);
  140.             break;
  141.     }
  142.     return 0;
  143. }
  144.  
  145. static INLINE uint32_t r300_translate_stencil_op(int s_op)
  146. {
  147.     switch (s_op) {
  148.         case PIPE_STENCIL_OP_KEEP:
  149.             return R300_ZS_KEEP;
  150.         case PIPE_STENCIL_OP_ZERO:
  151.             return R300_ZS_ZERO;
  152.         case PIPE_STENCIL_OP_REPLACE:
  153.             return R300_ZS_REPLACE;
  154.         case PIPE_STENCIL_OP_INCR:
  155.             return R300_ZS_INCR;
  156.         case PIPE_STENCIL_OP_DECR:
  157.             return R300_ZS_DECR;
  158.         case PIPE_STENCIL_OP_INCR_WRAP:
  159.             return R300_ZS_INCR_WRAP;
  160.         case PIPE_STENCIL_OP_DECR_WRAP:
  161.             return R300_ZS_DECR_WRAP;
  162.         case PIPE_STENCIL_OP_INVERT:
  163.             return R300_ZS_INVERT;
  164.         default:
  165.             fprintf(stderr, "r300: Unknown stencil op %d", s_op);
  166.             assert(0);
  167.             break;
  168.     }
  169.     return 0;
  170. }
  171.  
  172. static INLINE uint32_t r300_translate_alpha_function(int alpha_func)
  173. {
  174.     switch (alpha_func) {
  175.         case PIPE_FUNC_NEVER:
  176.             return R300_FG_ALPHA_FUNC_NEVER;
  177.         case PIPE_FUNC_LESS:
  178.             return R300_FG_ALPHA_FUNC_LESS;
  179.         case PIPE_FUNC_EQUAL:
  180.             return R300_FG_ALPHA_FUNC_EQUAL;
  181.         case PIPE_FUNC_LEQUAL:
  182.             return R300_FG_ALPHA_FUNC_LE;
  183.         case PIPE_FUNC_GREATER:
  184.             return R300_FG_ALPHA_FUNC_GREATER;
  185.         case PIPE_FUNC_NOTEQUAL:
  186.             return R300_FG_ALPHA_FUNC_NOTEQUAL;
  187.         case PIPE_FUNC_GEQUAL:
  188.             return R300_FG_ALPHA_FUNC_GE;
  189.         case PIPE_FUNC_ALWAYS:
  190.             return R300_FG_ALPHA_FUNC_ALWAYS;
  191.         default:
  192.             fprintf(stderr, "r300: Unknown alpha function %d", alpha_func);
  193.             assert(0);
  194.             break;
  195.     }
  196.     return 0;
  197. }
  198.  
  199. static INLINE uint32_t
  200. r300_translate_polygon_mode_front(unsigned mode) {
  201.     switch (mode)
  202.     {
  203.         case PIPE_POLYGON_MODE_FILL:
  204.             return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
  205.         case PIPE_POLYGON_MODE_LINE:
  206.             return R300_GA_POLY_MODE_FRONT_PTYPE_LINE;
  207.         case PIPE_POLYGON_MODE_POINT:
  208.             return R300_GA_POLY_MODE_FRONT_PTYPE_POINT;
  209.  
  210.         default:
  211.             fprintf(stderr, "r300: Bad polygon mode %i in %s\n", mode,
  212.                 __FUNCTION__);
  213.             return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;
  214.     }
  215. }
  216.  
  217. static INLINE uint32_t
  218. r300_translate_polygon_mode_back(unsigned mode) {
  219.     switch (mode)
  220.     {
  221.         case PIPE_POLYGON_MODE_FILL:
  222.             return R300_GA_POLY_MODE_BACK_PTYPE_TRI;
  223.         case PIPE_POLYGON_MODE_LINE:
  224.             return R300_GA_POLY_MODE_BACK_PTYPE_LINE;
  225.         case PIPE_POLYGON_MODE_POINT:
  226.             return R300_GA_POLY_MODE_BACK_PTYPE_POINT;
  227.  
  228.         default:
  229.             fprintf(stderr, "r300: Bad polygon mode %i in %s\n", mode,
  230.                 __FUNCTION__);
  231.             return R300_GA_POLY_MODE_BACK_PTYPE_TRI;
  232.     }
  233. }
  234.  
  235. /* Texture sampler state. */
  236.  
  237. static INLINE uint32_t r300_translate_wrap(int wrap)
  238. {
  239.     switch (wrap) {
  240.         case PIPE_TEX_WRAP_REPEAT:
  241.             return R300_TX_REPEAT;
  242.         case PIPE_TEX_WRAP_CLAMP:
  243.             return R300_TX_CLAMP;
  244.         case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
  245.             return R300_TX_CLAMP_TO_EDGE;
  246.         case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
  247.             return R300_TX_CLAMP_TO_BORDER;
  248.         case PIPE_TEX_WRAP_MIRROR_REPEAT:
  249.             return R300_TX_REPEAT | R300_TX_MIRRORED;
  250.         case PIPE_TEX_WRAP_MIRROR_CLAMP:
  251.             return R300_TX_CLAMP | R300_TX_MIRRORED;
  252.         case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
  253.             return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;
  254.         case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
  255.             return R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED;
  256.         default:
  257.             fprintf(stderr, "r300: Unknown texture wrap %d", wrap);
  258.             assert(0);
  259.             return 0;
  260.     }
  261. }
  262.  
  263. static INLINE uint32_t r300_translate_tex_filters(int min, int mag, int mip,
  264.                                                   boolean is_anisotropic)
  265. {
  266.     uint32_t retval = 0;
  267.  
  268.     switch (min) {
  269.     case PIPE_TEX_FILTER_NEAREST:
  270.         retval |= R300_TX_MIN_FILTER_NEAREST;
  271.         break;
  272.     case PIPE_TEX_FILTER_LINEAR:
  273.         retval |= is_anisotropic ? R300_TX_MIN_FILTER_ANISO :
  274.                                    R300_TX_MIN_FILTER_LINEAR;
  275.         break;
  276.     default:
  277.         fprintf(stderr, "r300: Unknown texture filter %d\n", min);
  278.         assert(0);
  279.     }
  280.  
  281.     switch (mag) {
  282.     case PIPE_TEX_FILTER_NEAREST:
  283.         retval |= R300_TX_MAG_FILTER_NEAREST;
  284.         break;
  285.     case PIPE_TEX_FILTER_LINEAR:
  286.         retval |= is_anisotropic ? R300_TX_MAG_FILTER_ANISO :
  287.                                    R300_TX_MAG_FILTER_LINEAR;
  288.         break;
  289.     default:
  290.         fprintf(stderr, "r300: Unknown texture filter %d\n", mag);
  291.         assert(0);
  292.     }
  293.  
  294.     switch (mip) {
  295.     case PIPE_TEX_MIPFILTER_NONE:
  296.         retval |= R300_TX_MIN_FILTER_MIP_NONE;
  297.         break;
  298.     case PIPE_TEX_MIPFILTER_NEAREST:
  299.         retval |= R300_TX_MIN_FILTER_MIP_NEAREST;
  300.         break;
  301.     case PIPE_TEX_MIPFILTER_LINEAR:
  302.         retval |= R300_TX_MIN_FILTER_MIP_LINEAR;
  303.         break;
  304.     default:
  305.         fprintf(stderr, "r300: Unknown texture filter %d\n", mip);
  306.         assert(0);
  307.     }
  308.  
  309.     return retval;
  310. }
  311.  
  312. static INLINE uint32_t r300_anisotropy(unsigned max_aniso)
  313. {
  314.     if (max_aniso >= 16) {
  315.         return R300_TX_MAX_ANISO_16_TO_1;
  316.     } else if (max_aniso >= 8) {
  317.         return R300_TX_MAX_ANISO_8_TO_1;
  318.     } else if (max_aniso >= 4) {
  319.         return R300_TX_MAX_ANISO_4_TO_1;
  320.     } else if (max_aniso >= 2) {
  321.         return R300_TX_MAX_ANISO_2_TO_1;
  322.     } else {
  323.         return R300_TX_MAX_ANISO_1_TO_1;
  324.     }
  325. }
  326.  
  327. static INLINE uint32_t r500_anisotropy(unsigned max_aniso)
  328. {
  329.     if (!max_aniso) {
  330.         return 0;
  331.     }
  332.     max_aniso -= 1;
  333.  
  334.     // Map the range [0, 15] to [0, 63].
  335.     return R500_TX_MAX_ANISO(MIN2((unsigned)(max_aniso*4.2001), 63)) |
  336.            R500_TX_ANISO_HIGH_QUALITY;
  337. }
  338.  
  339. /* Translate pipe_formats into PSC vertex types. */
  340. static INLINE uint16_t
  341. r300_translate_vertex_data_type(enum pipe_format format) {
  342.     uint32_t result = 0;
  343.     const struct util_format_description *desc;
  344.     unsigned i;
  345.  
  346.     desc = util_format_description(format);
  347.  
  348.     if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
  349.         return R300_INVALID_FORMAT;
  350.     }
  351.  
  352.     /* Find the first non-VOID channel. */
  353.     for (i = 0; i < 4; i++) {
  354.         if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
  355.             break;
  356.         }
  357.     }
  358.  
  359.     switch (desc->channel[i].type) {
  360.         /* Half-floats, floats, doubles */
  361.         case UTIL_FORMAT_TYPE_FLOAT:
  362.             switch (desc->channel[i].size) {
  363.                 case 16:
  364.                     /* Supported only on RV350 and later. */
  365.                     if (desc->nr_channels > 2) {
  366.                         result = R300_DATA_TYPE_FLT16_4;
  367.                     } else {
  368.                         result = R300_DATA_TYPE_FLT16_2;
  369.                     }
  370.                     break;
  371.                 case 32:
  372.                     result = R300_DATA_TYPE_FLOAT_1 + (desc->nr_channels - 1);
  373.                     break;
  374.                 default:
  375.                     return R300_INVALID_FORMAT;
  376.             }
  377.             break;
  378.         /* Unsigned ints */
  379.         case UTIL_FORMAT_TYPE_UNSIGNED:
  380.         /* Signed ints */
  381.         case UTIL_FORMAT_TYPE_SIGNED:
  382.             switch (desc->channel[i].size) {
  383.                 case 8:
  384.                     result = R300_DATA_TYPE_BYTE;
  385.                     break;
  386.                 case 16:
  387.                     if (desc->nr_channels > 2) {
  388.                         result = R300_DATA_TYPE_SHORT_4;
  389.                     } else {
  390.                         result = R300_DATA_TYPE_SHORT_2;
  391.                     }
  392.                     break;
  393.                 default:
  394.                     return R300_INVALID_FORMAT;
  395.             }
  396.             break;
  397.         default:
  398.             return R300_INVALID_FORMAT;
  399.     }
  400.  
  401.     if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
  402.         result |= R300_SIGNED;
  403.     }
  404.     if (desc->channel[i].normalized) {
  405.         result |= R300_NORMALIZE;
  406.     }
  407.  
  408.     return result;
  409. }
  410.  
  411. static INLINE uint16_t
  412. r300_translate_vertex_data_swizzle(enum pipe_format format) {
  413.     const struct util_format_description *desc = util_format_description(format);
  414.     unsigned i, swizzle = 0;
  415.  
  416.     assert(format);
  417.  
  418.     if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
  419.         fprintf(stderr, "r300: Bad format %s in %s:%d\n",
  420.             util_format_short_name(format), __FUNCTION__, __LINE__);
  421.         return 0;
  422.     }
  423.  
  424.     for (i = 0; i < desc->nr_channels; i++) {
  425.         swizzle |=
  426.             MIN2(desc->swizzle[i], R300_SWIZZLE_SELECT_FP_ONE) << (3*i);
  427.     }
  428.     /* Set (0,0,0,1) in unused components. */
  429.     for (; i < 3; i++) {
  430.         swizzle |= R300_SWIZZLE_SELECT_FP_ZERO << (3*i);
  431.     }
  432.     for (; i < 4; i++) {
  433.         swizzle |= R300_SWIZZLE_SELECT_FP_ONE << (3*i);
  434.     }
  435.  
  436.     return swizzle | (0xf << R300_WRITE_ENA_SHIFT);
  437. }
  438.  
  439. #endif /* R300_STATE_INLINES_H */
  440.