Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**********************************************************
  2.  * Copyright 2008-2009 VMware, Inc.  All rights reserved.
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person
  5.  * obtaining a copy of this software and associated documentation
  6.  * files (the "Software"), to deal in the Software without
  7.  * restriction, including without limitation the rights to use, copy,
  8.  * modify, merge, publish, distribute, sublicense, and/or sell copies
  9.  * of the Software, and to permit persons to whom the Software is
  10.  * furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice shall be
  13.  * included in all copies or substantial portions of the Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18.  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  19.  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  20.  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22.  * SOFTWARE.
  23.  *
  24.  **********************************************************/
  25.  
  26. #include "util/u_inlines.h"
  27. #include "pipe/p_defines.h"
  28. #include "util/u_math.h"
  29. #include "util/u_memory.h"
  30.  
  31. #include "svga_context.h"
  32.  
  33. #include "svga_hw_reg.h"
  34.  
  35.  
  36. static INLINE unsigned
  37. svga_translate_blend_factor(unsigned factor)
  38. {
  39.    switch (factor) {
  40.    case PIPE_BLENDFACTOR_ZERO:            return SVGA3D_BLENDOP_ZERO;
  41.    case PIPE_BLENDFACTOR_SRC_ALPHA:       return SVGA3D_BLENDOP_SRCALPHA;
  42.    case PIPE_BLENDFACTOR_ONE:             return SVGA3D_BLENDOP_ONE;
  43.    case PIPE_BLENDFACTOR_SRC_COLOR:       return SVGA3D_BLENDOP_SRCCOLOR;
  44.    case PIPE_BLENDFACTOR_INV_SRC_COLOR:   return SVGA3D_BLENDOP_INVSRCCOLOR;
  45.    case PIPE_BLENDFACTOR_DST_COLOR:       return SVGA3D_BLENDOP_DESTCOLOR;
  46.    case PIPE_BLENDFACTOR_INV_DST_COLOR:   return SVGA3D_BLENDOP_INVDESTCOLOR;
  47.    case PIPE_BLENDFACTOR_INV_SRC_ALPHA:   return SVGA3D_BLENDOP_INVSRCALPHA;
  48.    case PIPE_BLENDFACTOR_DST_ALPHA:       return SVGA3D_BLENDOP_DESTALPHA;
  49.    case PIPE_BLENDFACTOR_INV_DST_ALPHA:   return SVGA3D_BLENDOP_INVDESTALPHA;
  50.    case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return SVGA3D_BLENDOP_SRCALPHASAT;
  51.    case PIPE_BLENDFACTOR_CONST_COLOR:     return SVGA3D_BLENDOP_BLENDFACTOR;
  52.    case PIPE_BLENDFACTOR_INV_CONST_COLOR: return SVGA3D_BLENDOP_INVBLENDFACTOR;
  53.    case PIPE_BLENDFACTOR_CONST_ALPHA:     return SVGA3D_BLENDOP_BLENDFACTOR; /* ? */
  54.    case PIPE_BLENDFACTOR_INV_CONST_ALPHA: return SVGA3D_BLENDOP_INVBLENDFACTOR; /* ? */
  55.    default:
  56.       assert(0);
  57.       return SVGA3D_BLENDOP_ZERO;
  58.    }
  59. }
  60.  
  61. static INLINE unsigned
  62. svga_translate_blend_func(unsigned mode)
  63. {
  64.    switch (mode) {
  65.    case PIPE_BLEND_ADD:              return SVGA3D_BLENDEQ_ADD;
  66.    case PIPE_BLEND_SUBTRACT:         return SVGA3D_BLENDEQ_SUBTRACT;
  67.    case PIPE_BLEND_REVERSE_SUBTRACT: return SVGA3D_BLENDEQ_REVSUBTRACT;
  68.    case PIPE_BLEND_MIN:              return SVGA3D_BLENDEQ_MINIMUM;
  69.    case PIPE_BLEND_MAX:              return SVGA3D_BLENDEQ_MAXIMUM;
  70.    default:
  71.       assert(0);
  72.       return SVGA3D_BLENDEQ_ADD;
  73.    }
  74. }
  75.  
  76.  
  77. static void *
  78. svga_create_blend_state(struct pipe_context *pipe,
  79.                         const struct pipe_blend_state *templ)
  80. {
  81.    struct svga_blend_state *blend = CALLOC_STRUCT( svga_blend_state );
  82.    unsigned i;
  83.  
  84.  
  85.    /* Fill in the per-rendertarget blend state.  We currently only
  86.     * have one rendertarget.
  87.     */
  88.    for (i = 0; i < 1; i++) {
  89.       /* No way to set this in SVGA3D, and no way to correctly implement it on
  90.        * top of D3D9 API.  Instead we try to simulate with various blend modes.
  91.        */
  92.       if (templ->logicop_enable) {
  93.          switch (templ->logicop_func) {
  94.          case PIPE_LOGICOP_XOR:
  95.          case PIPE_LOGICOP_INVERT:
  96.             blend->need_white_fragments = TRUE;
  97.             blend->rt[i].blend_enable = TRUE;
  98.             blend->rt[i].srcblend       = SVGA3D_BLENDOP_ONE;
  99.             blend->rt[i].dstblend       = SVGA3D_BLENDOP_ONE;
  100.             blend->rt[i].blendeq        = SVGA3D_BLENDEQ_SUBTRACT;
  101.             break;
  102.          case PIPE_LOGICOP_CLEAR:
  103.             blend->rt[i].blend_enable = TRUE;
  104.             blend->rt[i].srcblend       = SVGA3D_BLENDOP_ZERO;
  105.             blend->rt[i].dstblend       = SVGA3D_BLENDOP_ZERO;
  106.             blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
  107.             break;
  108.          case PIPE_LOGICOP_COPY:
  109.             blend->rt[i].blend_enable = FALSE;
  110.             break;
  111.          case PIPE_LOGICOP_COPY_INVERTED:
  112.             blend->rt[i].blend_enable   = TRUE;
  113.             blend->rt[i].srcblend       = SVGA3D_BLENDOP_INVSRCCOLOR;
  114.             blend->rt[i].dstblend       = SVGA3D_BLENDOP_ZERO;
  115.             blend->rt[i].blendeq        = SVGA3D_BLENDEQ_ADD;
  116.             break;
  117.          case PIPE_LOGICOP_NOOP:
  118.             blend->rt[i].blend_enable   = TRUE;
  119.             blend->rt[i].srcblend       = SVGA3D_BLENDOP_ZERO;
  120.             blend->rt[i].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
  121.             blend->rt[i].blendeq        = SVGA3D_BLENDEQ_ADD;
  122.             break;
  123.          case PIPE_LOGICOP_SET:
  124.             blend->rt[i].blend_enable = TRUE;
  125.             blend->rt[i].srcblend       = SVGA3D_BLENDOP_ONE;
  126.             blend->rt[i].dstblend       = SVGA3D_BLENDOP_ONE;
  127.             blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
  128.             break;
  129.          case PIPE_LOGICOP_AND:
  130.             /* Approximate with minimum - works for the 0 & anything case: */
  131.             blend->rt[i].blend_enable = TRUE;
  132.             blend->rt[i].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
  133.             blend->rt[i].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
  134.             blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
  135.             break;
  136.          case PIPE_LOGICOP_AND_REVERSE:
  137.             blend->rt[i].blend_enable = TRUE;
  138.             blend->rt[i].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
  139.             blend->rt[i].dstblend       = SVGA3D_BLENDOP_INVDESTCOLOR;
  140.             blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
  141.             break;
  142.          case PIPE_LOGICOP_AND_INVERTED:
  143.             blend->rt[i].blend_enable = TRUE;
  144.             blend->rt[i].srcblend       = SVGA3D_BLENDOP_INVSRCCOLOR;
  145.             blend->rt[i].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
  146.             blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
  147.             break;
  148.          case PIPE_LOGICOP_OR:
  149.             /* Approximate with maximum - works for the 1 | anything case: */
  150.             blend->rt[i].blend_enable = TRUE;
  151.             blend->rt[i].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
  152.             blend->rt[i].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
  153.             blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
  154.             break;
  155.          case PIPE_LOGICOP_OR_REVERSE:
  156.             blend->rt[i].blend_enable = TRUE;
  157.             blend->rt[i].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
  158.             blend->rt[i].dstblend       = SVGA3D_BLENDOP_INVDESTCOLOR;
  159.             blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
  160.             break;
  161.          case PIPE_LOGICOP_OR_INVERTED:
  162.             blend->rt[i].blend_enable = TRUE;
  163.             blend->rt[i].srcblend       = SVGA3D_BLENDOP_INVSRCCOLOR;
  164.             blend->rt[i].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
  165.             blend->rt[i].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
  166.             break;
  167.          case PIPE_LOGICOP_NAND:
  168.          case PIPE_LOGICOP_NOR:
  169.          case PIPE_LOGICOP_EQUIV:
  170.             /* Fill these in with plausible values */
  171.             blend->rt[i].blend_enable = FALSE;
  172.             break;
  173.          default:
  174.             assert(0);
  175.             break;
  176.          }
  177.       }
  178.       else {
  179.          blend->rt[i].blend_enable   = templ->rt[0].blend_enable;
  180.  
  181.          if (templ->rt[0].blend_enable) {
  182.             blend->rt[i].srcblend       = svga_translate_blend_factor(templ->rt[0].rgb_src_factor);
  183.             blend->rt[i].dstblend       = svga_translate_blend_factor(templ->rt[0].rgb_dst_factor);
  184.             blend->rt[i].blendeq        = svga_translate_blend_func(templ->rt[0].rgb_func);
  185.             blend->rt[i].srcblend_alpha = svga_translate_blend_factor(templ->rt[0].alpha_src_factor);
  186.             blend->rt[i].dstblend_alpha = svga_translate_blend_factor(templ->rt[0].alpha_dst_factor);
  187.             blend->rt[i].blendeq_alpha  = svga_translate_blend_func(templ->rt[0].alpha_func);
  188.  
  189.             if (blend->rt[i].srcblend_alpha != blend->rt[i].srcblend ||
  190.                 blend->rt[i].dstblend_alpha != blend->rt[i].dstblend ||
  191.                 blend->rt[i].blendeq_alpha  != blend->rt[i].blendeq)
  192.             {
  193.                blend->rt[i].separate_alpha_blend_enable = TRUE;
  194.             }
  195.          }
  196.       }
  197.  
  198.       blend->rt[i].writemask = templ->rt[0].colormask;
  199.    }
  200.  
  201.    return blend;
  202. }
  203.  
  204. static void svga_bind_blend_state(struct pipe_context *pipe,
  205.                                   void *blend)
  206. {
  207.    struct svga_context *svga = svga_context(pipe);
  208.  
  209.    svga->curr.blend = (struct svga_blend_state*)blend;
  210.    svga->dirty |= SVGA_NEW_BLEND;
  211. }
  212.  
  213.  
  214. static void svga_delete_blend_state(struct pipe_context *pipe, void *blend)
  215. {
  216.    FREE(blend);
  217. }
  218.  
  219. static void svga_set_blend_color( struct pipe_context *pipe,
  220.                                   const struct pipe_blend_color *blend_color )
  221. {
  222.    struct svga_context *svga = svga_context(pipe);
  223.  
  224.    svga->curr.blend_color = *blend_color;
  225.  
  226.    svga->dirty |= SVGA_NEW_BLEND_COLOR;
  227. }
  228.  
  229.  
  230. void svga_init_blend_functions( struct svga_context *svga )
  231. {
  232.    svga->pipe.create_blend_state = svga_create_blend_state;
  233.    svga->pipe.bind_blend_state = svga_bind_blend_state;
  234.    svga->pipe.delete_blend_state = svga_delete_blend_state;
  235.  
  236.    svga->pipe.set_blend_color = svga_set_blend_color;
  237. }
  238.  
  239.  
  240.  
  241.