Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2011 Joakim Sindholt <opensource@zhasha.com>
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  8.  * license, and/or sell copies of the Software, and to permit persons to whom
  9.  * the Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  18.  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  21.  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
  22.  
  23. #ifndef _NINE_PIPE_H_
  24. #define _NINE_PIPE_H_
  25.  
  26. #include "d3d9.h"
  27. #include "pipe/p_format.h"
  28. #include "pipe/p_screen.h"
  29. #include "pipe/p_state.h" /* pipe_box */
  30. #include "util/u_rect.h"
  31. #include "util/u_format.h"
  32. #include "nine_helpers.h"
  33.  
  34. struct cso_context;
  35.  
  36. extern const enum pipe_format nine_d3d9_to_pipe_format_map[120];
  37. extern const D3DFORMAT nine_pipe_to_d3d9_format_map[PIPE_FORMAT_COUNT];
  38.  
  39. void nine_convert_dsa_state(struct cso_context *, const DWORD *);
  40. void nine_convert_rasterizer_state(struct cso_context *, const DWORD *);
  41. void nine_convert_blend_state(struct cso_context *, const DWORD *);
  42. void nine_convert_sampler_state(struct cso_context *, int idx, const DWORD *);
  43.  
  44. void nine_pipe_context_clear(struct NineDevice9 *);
  45.  
  46. static INLINE unsigned d3dlock_buffer_to_pipe_transfer_usage(DWORD Flags)
  47. {
  48.     unsigned usage;
  49.  
  50.     if (Flags & D3DLOCK_DISCARD)
  51.         usage = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
  52.     else
  53.     if (Flags & D3DLOCK_READONLY)
  54.         usage = PIPE_TRANSFER_READ;
  55.     else
  56.         usage = PIPE_TRANSFER_READ_WRITE;
  57.  
  58.     if (Flags & D3DLOCK_NOOVERWRITE)
  59.         usage = (PIPE_TRANSFER_UNSYNCHRONIZED |
  60.                  PIPE_TRANSFER_DISCARD_RANGE | usage) & ~PIPE_TRANSFER_READ;
  61.     else
  62.     if (Flags & D3DLOCK_DONOTWAIT)
  63.         usage |= PIPE_TRANSFER_DONTBLOCK;
  64.  
  65.     /*
  66.     if (Flags & D3DLOCK_NO_DIRTY_UPDATE)
  67.         usage |= PIPE_TRANSFER_FLUSH_EXPLICIT;
  68.     */
  69.  
  70.     return usage;
  71. }
  72.  
  73. static INLINE void
  74. rect_to_pipe_box(struct pipe_box *dst, const RECT *src)
  75. {
  76.     dst->x = src->left;
  77.     dst->y = src->top;
  78.     dst->z = 0;
  79.     dst->width = src->right - src->left;
  80.     dst->height = src->bottom - src->top;
  81.     dst->depth = 1;
  82. }
  83.  
  84. static INLINE boolean
  85. rect_to_pipe_box_clamp(struct pipe_box *dst, const RECT *src)
  86. {
  87.     rect_to_pipe_box(dst, src);
  88.  
  89.     if (dst->width <= 0 || dst->height <= 0) {
  90.         DBG_FLAG(DBG_UNKNOWN, "Warning: NULL box");
  91.         dst->width = MAX2(dst->width, 0);
  92.         dst->height = MAX2(dst->height, 0);
  93.         return TRUE;
  94.     }
  95.     return FALSE;
  96. }
  97.  
  98. static INLINE boolean
  99. rect_to_pipe_box_flip(struct pipe_box *dst, const RECT *src)
  100. {
  101.     rect_to_pipe_box(dst, src);
  102.  
  103.     if (dst->width >= 0 && dst->height >= 0)
  104.         return FALSE;
  105.     if (dst->width < 0) dst->width = -dst->width;
  106.     if (dst->height < 0) dst->height = -dst->height;
  107.     return TRUE;
  108. }
  109.  
  110. static INLINE void
  111. rect_to_pipe_box_xy_only(struct pipe_box *dst, const RECT *src)
  112. {
  113.     user_warn(src->left > src->right || src->top > src->bottom);
  114.  
  115.     dst->x = src->left;
  116.     dst->y = src->top;
  117.     dst->width = src->right - src->left;
  118.     dst->height = src->bottom - src->top;
  119. }
  120.  
  121. static INLINE boolean
  122. rect_to_pipe_box_xy_only_clamp(struct pipe_box *dst, const RECT *src)
  123. {
  124.     rect_to_pipe_box_xy_only(dst, src);
  125.  
  126.     if (dst->width <= 0 || dst->height <= 0) {
  127.         DBG_FLAG(DBG_UNKNOWN, "Warning: NULL box");
  128.         dst->width = MAX2(dst->width, 0);
  129.         dst->height = MAX2(dst->height, 0);
  130.         return TRUE;
  131.     }
  132.     return FALSE;
  133. }
  134.  
  135. static INLINE void
  136. rect_to_g3d_u_rect(struct u_rect *dst, const RECT *src)
  137. {
  138.     user_warn(src->left > src->right || src->top > src->bottom);
  139.  
  140.     dst->x0 = src->left;
  141.     dst->x1 = src->right;
  142.     dst->y0 = src->top;
  143.     dst->y1 = src->bottom;
  144. }
  145.  
  146. static INLINE void
  147. d3dbox_to_pipe_box(struct pipe_box *dst, const D3DBOX *src)
  148. {
  149.     user_warn(src->Left > src->Right);
  150.     user_warn(src->Top > src->Bottom);
  151.     user_warn(src->Front > src->Back);
  152.  
  153.     dst->x = src->Left;
  154.     dst->y = src->Top;
  155.     dst->z = src->Front;
  156.     dst->width = src->Right - src->Left;
  157.     dst->height = src->Bottom - src->Top;
  158.     dst->depth = src->Back - src->Front;
  159. }
  160.  
  161. static INLINE D3DFORMAT
  162. pipe_to_d3d9_format(enum pipe_format format)
  163. {
  164.     return nine_pipe_to_d3d9_format_map[format];
  165. }
  166.  
  167. static INLINE boolean
  168. depth_stencil_format( D3DFORMAT fmt )
  169. {
  170.     static D3DFORMAT allowed[] = {
  171.         D3DFMT_D16_LOCKABLE,
  172.         D3DFMT_D32,
  173.         D3DFMT_D15S1,
  174.         D3DFMT_D24S8,
  175.         D3DFMT_D24X8,
  176.         D3DFMT_D24X4S4,
  177.         D3DFMT_D16,
  178.         D3DFMT_D32F_LOCKABLE,
  179.         D3DFMT_D24FS8,
  180.         D3DFMT_D32_LOCKABLE,
  181.         D3DFMT_DF16,
  182.         D3DFMT_DF24,
  183.         D3DFMT_INTZ
  184.     };
  185.     unsigned i;
  186.  
  187.     for (i = 0; i < sizeof(allowed)/sizeof(D3DFORMAT); i++) {
  188.         if (fmt == allowed[i]) { return TRUE; }
  189.     }
  190.     return FALSE;
  191. }
  192.  
  193. static INLINE unsigned
  194. d3d9_get_pipe_depth_format_bindings(D3DFORMAT format)
  195. {
  196.     switch (format) {
  197.     case D3DFMT_D32:
  198.     case D3DFMT_D15S1:
  199.     case D3DFMT_D24S8:
  200.     case D3DFMT_D24X8:
  201.     case D3DFMT_D24X4S4:
  202.     case D3DFMT_D16:
  203.     case D3DFMT_D24FS8:
  204.         return PIPE_BIND_DEPTH_STENCIL;
  205.     case D3DFMT_D32F_LOCKABLE:
  206.     case D3DFMT_D16_LOCKABLE:
  207.     case D3DFMT_D32_LOCKABLE:
  208.         return PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_TRANSFER_READ |
  209.                PIPE_BIND_TRANSFER_WRITE;
  210.     case D3DFMT_DF16:
  211.     case D3DFMT_DF24:
  212.     case D3DFMT_INTZ:
  213.         return PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_SAMPLER_VIEW;
  214.     default: unreachable("Unexpected format");
  215.     }
  216. }
  217.  
  218. static INLINE enum pipe_format
  219. d3d9_to_pipe_format_internal(D3DFORMAT format)
  220. {
  221.     if (format <= D3DFMT_A2B10G10R10_XR_BIAS)
  222.         return nine_d3d9_to_pipe_format_map[format];
  223.     switch (format) {
  224.     case D3DFMT_INTZ: return PIPE_FORMAT_S8_UINT_Z24_UNORM;
  225.     case D3DFMT_DF16: return PIPE_FORMAT_Z16_UNORM;
  226.     case D3DFMT_DXT1: return PIPE_FORMAT_DXT1_RGBA;
  227.     case D3DFMT_DXT2: return PIPE_FORMAT_DXT3_RGBA; /* XXX */
  228.     case D3DFMT_DXT3: return PIPE_FORMAT_DXT3_RGBA;
  229.     case D3DFMT_DXT4: return PIPE_FORMAT_DXT5_RGBA; /* XXX */
  230.     case D3DFMT_DXT5: return PIPE_FORMAT_DXT5_RGBA;
  231.     case D3DFMT_ATI1: return PIPE_FORMAT_RGTC1_UNORM;
  232.     case D3DFMT_ATI2: return PIPE_FORMAT_RGTC2_UNORM;
  233.     case D3DFMT_UYVY: return PIPE_FORMAT_UYVY;
  234.     case D3DFMT_YUY2: return PIPE_FORMAT_YUYV; /* XXX check */
  235.     case D3DFMT_NV12: return PIPE_FORMAT_NV12;
  236.     case D3DFMT_G8R8_G8B8: return PIPE_FORMAT_G8R8_G8B8_UNORM; /* XXX order ? */
  237.     case D3DFMT_R8G8_B8G8: return PIPE_FORMAT_R8G8_B8G8_UNORM; /* XXX order ? */
  238.     case D3DFMT_BINARYBUFFER: return PIPE_FORMAT_NONE; /* not a format */
  239.     case D3DFMT_MULTI2_ARGB8: return PIPE_FORMAT_NONE; /* not supported */
  240.     case D3DFMT_Y210: /* XXX */
  241.     case D3DFMT_Y216:
  242.     case D3DFMT_NV11:
  243.     case D3DFMT_DF24: /* Similar to D3DFMT_DF16 but for 24-bits.
  244.         We don't advertise it because when it is supported, Fetch-4 is
  245.         supposed to be supported, which we don't support yet. */
  246.     case D3DFMT_NULL: /* special cased, only for surfaces */
  247.         return PIPE_FORMAT_NONE;
  248.     default:
  249.         DBG_FLAG(DBG_UNKNOWN, "unknown D3DFORMAT: 0x%x/%c%c%c%c\n",
  250.                  format, (char)format, (char)(format >> 8),
  251.                  (char)(format >> 16), (char)(format >> 24));
  252.         return PIPE_FORMAT_NONE;
  253.     }
  254. }
  255.  
  256. #define format_check_internal(pipe_format) \
  257.     screen->is_format_supported(screen, pipe_format, target, \
  258.                                 sample_count, bindings)
  259.  
  260. static INLINE enum pipe_format
  261. d3d9_to_pipe_format_checked(struct pipe_screen *screen,
  262.                             D3DFORMAT format,
  263.                             enum pipe_texture_target target,
  264.                             unsigned sample_count,
  265.                             unsigned bindings,
  266.                             boolean srgb)
  267. {
  268.     enum pipe_format result;
  269.  
  270.     result = d3d9_to_pipe_format_internal(format);
  271.     if (result == PIPE_FORMAT_NONE)
  272.         return PIPE_FORMAT_NONE;
  273.  
  274.     if (srgb)
  275.         result = util_format_srgb(result);
  276.  
  277.     if (format_check_internal(result))
  278.         return result;
  279.  
  280.     /* fallback to another format for formats
  281.      * that match several pipe_format */
  282.     switch(format) {
  283.         /* depth buffer formats are not lockable (except those for which it
  284.          * is precised in the name), so it is ok to match to another similar
  285.          * format. In all cases, if the app reads the texture with a shader,
  286.          * it gets depth on r and doesn't get stencil.*/
  287.         case D3DFMT_INTZ:
  288.         case D3DFMT_D24S8:
  289.             if (format_check_internal(PIPE_FORMAT_Z24_UNORM_S8_UINT))
  290.                 return PIPE_FORMAT_Z24_UNORM_S8_UINT;
  291.             break;
  292.         case D3DFMT_D24X8:
  293.             if (format_check_internal(PIPE_FORMAT_Z24X8_UNORM))
  294.                 return PIPE_FORMAT_Z24X8_UNORM;
  295.         default:
  296.             break;
  297.     }
  298.     return PIPE_FORMAT_NONE;
  299. }
  300.  
  301. static INLINE const char *
  302. d3dformat_to_string(D3DFORMAT fmt)
  303. {
  304.     switch (fmt) {
  305.     case D3DFMT_UNKNOWN: return "D3DFMT_UNKNOWN";
  306.     case D3DFMT_R8G8B8: return "D3DFMT_R8G8B8";
  307.     case D3DFMT_A8R8G8B8: return "D3DFMT_A8R8G8B8";
  308.     case D3DFMT_X8R8G8B8: return "D3DFMT_X8R8G8B8";
  309.     case D3DFMT_R5G6B5: return "D3DFMT_R5G6B5";
  310.     case D3DFMT_X1R5G5B5: return "D3DFMT_X1R5G5B5";
  311.     case D3DFMT_A1R5G5B5: return "D3DFMT_A1R5G5B5";
  312.     case D3DFMT_A4R4G4B4: return "D3DFMT_A4R4G4B4";
  313.     case D3DFMT_R3G3B2: return "D3DFMT_R3G3B2";
  314.     case D3DFMT_A8: return "D3DFMT_A8";
  315.     case D3DFMT_A8R3G3B2: return "D3DFMT_A8R3G3B2";
  316.     case D3DFMT_X4R4G4B4: return "D3DFMT_X4R4G4B4";
  317.     case D3DFMT_A2B10G10R10: return "D3DFMT_A2B10G10R10";
  318.     case D3DFMT_A8B8G8R8: return "D3DFMT_A8B8G8R8";
  319.     case D3DFMT_X8B8G8R8: return "D3DFMT_X8B8G8R8";
  320.     case D3DFMT_G16R16: return "D3DFMT_G16R16";
  321.     case D3DFMT_A2R10G10B10: return "D3DFMT_A2R10G10B10";
  322.     case D3DFMT_A16B16G16R16: return "D3DFMT_A16B16G16R16";
  323.     case D3DFMT_A8P8: return "D3DFMT_A8P8";
  324.     case D3DFMT_P8: return "D3DFMT_P8";
  325.     case D3DFMT_L8: return "D3DFMT_L8";
  326.     case D3DFMT_A8L8: return "D3DFMT_A8L8";
  327.     case D3DFMT_A4L4: return "D3DFMT_A4L4";
  328.     case D3DFMT_V8U8: return "D3DFMT_V8U8";
  329.     case D3DFMT_L6V5U5: return "D3DFMT_L6V5U5";
  330.     case D3DFMT_X8L8V8U8: return "D3DFMT_X8L8V8U8";
  331.     case D3DFMT_Q8W8V8U8: return "D3DFMT_Q8W8V8U8";
  332.     case D3DFMT_V16U16: return "D3DFMT_V16U16";
  333.     case D3DFMT_A2W10V10U10: return "D3DFMT_A2W10V10U10";
  334.     case D3DFMT_UYVY: return "D3DFMT_UYVY";
  335.     case D3DFMT_R8G8_B8G8: return "D3DFMT_R8G8_B8G8";
  336.     case D3DFMT_YUY2: return "D3DFMT_YUY2";
  337.     case D3DFMT_G8R8_G8B8: return "D3DFMT_G8R8_G8B8";
  338.     case D3DFMT_DXT1: return "D3DFMT_DXT1";
  339.     case D3DFMT_DXT2: return "D3DFMT_DXT2";
  340.     case D3DFMT_DXT3: return "D3DFMT_DXT3";
  341.     case D3DFMT_DXT4: return "D3DFMT_DXT4";
  342.     case D3DFMT_DXT5: return "D3DFMT_DXT5";
  343.     case D3DFMT_ATI1: return "D3DFMT_ATI1";
  344.     case D3DFMT_ATI2: return "D3DFMT_ATI2";
  345.     case D3DFMT_D16_LOCKABLE: return "D3DFMT_D16_LOCKABLE";
  346.     case D3DFMT_D32: return "D3DFMT_D32";
  347.     case D3DFMT_D15S1: return "D3DFMT_D15S1";
  348.     case D3DFMT_D24S8: return "D3DFMT_D24S8";
  349.     case D3DFMT_D24X8: return "D3DFMT_D24X8";
  350.     case D3DFMT_D24X4S4: return "D3DFMT_D24X4S4";
  351.     case D3DFMT_D16: return "D3DFMT_D16";
  352.     case D3DFMT_D32F_LOCKABLE: return "D3DFMT_D32F_LOCKABLE";
  353.     case D3DFMT_D24FS8: return "D3DFMT_D24FS8";
  354.     case D3DFMT_D32_LOCKABLE: return "D3DFMT_D32_LOCKABLE";
  355.     case D3DFMT_S8_LOCKABLE: return "D3DFMT_S8_LOCKABLE";
  356.     case D3DFMT_L16: return "D3DFMT_L16";
  357.     case D3DFMT_VERTEXDATA: return "D3DFMT_VERTEXDATA";
  358.     case D3DFMT_INDEX16: return "D3DFMT_INDEX16";
  359.     case D3DFMT_INDEX32: return "D3DFMT_INDEX32";
  360.     case D3DFMT_Q16W16V16U16: return "D3DFMT_Q16W16V16U16";
  361.     case D3DFMT_MULTI2_ARGB8: return "D3DFMT_MULTI2_ARGB8";
  362.     case D3DFMT_R16F: return "D3DFMT_R16F";
  363.     case D3DFMT_G16R16F: return "D3DFMT_G16R16F";
  364.     case D3DFMT_A16B16G16R16F: return "D3DFMT_A16B16G16R16F";
  365.     case D3DFMT_R32F: return "D3DFMT_R32F";
  366.     case D3DFMT_G32R32F: return "D3DFMT_G32R32F";
  367.     case D3DFMT_A32B32G32R32F: return "D3DFMT_A32B32G32R32F";
  368.     case D3DFMT_CxV8U8: return "D3DFMT_CxV8U8";
  369.     case D3DFMT_A1: return "D3DFMT_A1";
  370.     case D3DFMT_A2B10G10R10_XR_BIAS: return "D3DFMT_A2B10G10R10_XR_BIAS";
  371.     case D3DFMT_BINARYBUFFER: return "D3DFMT_BINARYBUFFER";
  372.     case D3DFMT_DF16: return "D3DFMT_DF16";
  373.     case D3DFMT_DF24: return "D3DFMT_DF24";
  374.     case D3DFMT_INTZ: return "D3DFMT_INTZ";
  375.     case D3DFMT_NVDB: return "D3DFMT_NVDB";
  376.     case D3DFMT_RESZ: return "D3DFMT_RESZ";
  377.     case D3DFMT_NULL: return "D3DFMT_NULL";
  378.     default:
  379.         break;
  380.     }
  381.     return "Unknown";
  382. }
  383.  
  384. static INLINE unsigned
  385. nine_fvf_stride( DWORD fvf )
  386. {
  387.     unsigned texcount, i, size = 0;
  388.  
  389.     switch (fvf & D3DFVF_POSITION_MASK) {
  390.     case D3DFVF_XYZ:    size += 3*4; break;
  391.     case D3DFVF_XYZRHW: size += 4*4; break;
  392.     case D3DFVF_XYZB1:  size += 4*4; break;
  393.     case D3DFVF_XYZB2:  size += 5*4; break;
  394.     case D3DFVF_XYZB3:  size += 6*4; break;
  395.     case D3DFVF_XYZB4:  size += 7*4; break;
  396.     case D3DFVF_XYZB5:  size += 8*4; break;
  397.     case D3DFVF_XYZW:   size += 4*4; break;
  398.     default:
  399.         user_warn("Position doesn't match any known combination.");
  400.         break;
  401.     }
  402.  
  403.     if (fvf & D3DFVF_NORMAL)   { size += 3*4; }
  404.     if (fvf & D3DFVF_PSIZE)    { size += 1*4; }
  405.     if (fvf & D3DFVF_DIFFUSE)  { size += 1*4; }
  406.     if (fvf & D3DFVF_SPECULAR) { size += 1*4; }
  407.  
  408.     texcount = (fvf >> D3DFVF_TEXCOUNT_SHIFT) & D3DFVF_TEXCOUNT_MASK;
  409.     if (user_error(texcount <= 8))
  410.         texcount = 8;
  411.  
  412.     for (i = 0; i < texcount; ++i) {
  413.         unsigned texformat = (fvf>>(16+i*2))&0x3;
  414.         /* texformats are defined having been shifted around so 1=3,2=0,3=1,4=2
  415.          * meaning we can just do this instead of the switch below */
  416.         size += (((texformat+1)&0x3)+1)*4;
  417.  
  418.         /*
  419.         switch (texformat) {
  420.         case D3DFVF_TEXTUREFORMAT1: size += 1*4;
  421.         case D3DFVF_TEXTUREFORMAT2: size += 2*4;
  422.         case D3DFVF_TEXTUREFORMAT3: size += 3*4;
  423.         case D3DFVF_TEXTUREFORMAT4: size += 4*4;
  424.         }
  425.         */
  426.     }
  427.  
  428.     return size;
  429. }
  430.  
  431. static INLINE void
  432. d3dcolor_to_rgba(float *rgba, D3DCOLOR color)
  433. {
  434.     rgba[0] = (float)((color >> 16) & 0xFF) / 0xFF;
  435.     rgba[1] = (float)((color >>  8) & 0xFF) / 0xFF;
  436.     rgba[2] = (float)((color >>  0) & 0xFF) / 0xFF;
  437.     rgba[3] = (float)((color >> 24) & 0xFF) / 0xFF;
  438. }
  439.  
  440. static INLINE void
  441. d3dcolor_to_pipe_color_union(union pipe_color_union *rgba, D3DCOLOR color)
  442. {
  443.     d3dcolor_to_rgba(&rgba->f[0], color);
  444. }
  445.  
  446. static INLINE unsigned
  447. d3dprimitivetype_to_pipe_prim(D3DPRIMITIVETYPE prim)
  448. {
  449.     switch (prim) {
  450.     case D3DPT_POINTLIST:     return PIPE_PRIM_POINTS;
  451.     case D3DPT_LINELIST:      return PIPE_PRIM_LINES;
  452.     case D3DPT_LINESTRIP:     return PIPE_PRIM_LINE_STRIP;
  453.     case D3DPT_TRIANGLELIST:  return PIPE_PRIM_TRIANGLES;
  454.     case D3DPT_TRIANGLESTRIP: return PIPE_PRIM_TRIANGLE_STRIP;
  455.     case D3DPT_TRIANGLEFAN:   return PIPE_PRIM_TRIANGLE_FAN;
  456.     default:
  457.         assert(0);
  458.         return PIPE_PRIM_POINTS;
  459.     }
  460. }
  461.  
  462. static INLINE unsigned
  463. prim_count_to_vertex_count(D3DPRIMITIVETYPE prim, UINT count)
  464. {
  465.     switch (prim) {
  466.     case D3DPT_POINTLIST:     return count;
  467.     case D3DPT_LINELIST:      return count * 2;
  468.     case D3DPT_LINESTRIP:     return count + 1;
  469.     case D3DPT_TRIANGLELIST:  return count * 3;
  470.     case D3DPT_TRIANGLESTRIP: return count + 2;
  471.     case D3DPT_TRIANGLEFAN:   return count + 2;
  472.     default:
  473.         assert(0);
  474.         return 0;
  475.     }
  476. }
  477.  
  478. static INLINE unsigned
  479. d3dcmpfunc_to_pipe_func(D3DCMPFUNC func)
  480. {
  481.     switch (func) {
  482.     case D3DCMP_NEVER:        return PIPE_FUNC_NEVER;
  483.     case D3DCMP_LESS:         return PIPE_FUNC_LESS;
  484.     case D3DCMP_EQUAL:        return PIPE_FUNC_EQUAL;
  485.     case D3DCMP_LESSEQUAL:    return PIPE_FUNC_LEQUAL;
  486.     case D3DCMP_GREATER:      return PIPE_FUNC_GREATER;
  487.     case D3DCMP_NOTEQUAL:     return PIPE_FUNC_NOTEQUAL;
  488.     case D3DCMP_GREATEREQUAL: return PIPE_FUNC_GEQUAL;
  489.     case D3DCMP_ALWAYS:       return PIPE_FUNC_ALWAYS;
  490.     case D3DCMP_NEVER_ZERO:   return PIPE_FUNC_NEVER; // Tested on windows + ATI HD5770
  491.     default:
  492.         assert(0);
  493.         return PIPE_FUNC_NEVER;
  494.     }
  495. }
  496.  
  497. static INLINE unsigned
  498. d3dstencilop_to_pipe_stencil_op(D3DSTENCILOP op)
  499. {
  500.     switch (op) {
  501.     case D3DSTENCILOP_KEEP:    return PIPE_STENCIL_OP_KEEP;
  502.     case D3DSTENCILOP_ZERO:    return PIPE_STENCIL_OP_ZERO;
  503.     case D3DSTENCILOP_REPLACE: return PIPE_STENCIL_OP_REPLACE;
  504.     case D3DSTENCILOP_INCRSAT: return PIPE_STENCIL_OP_INCR;
  505.     case D3DSTENCILOP_DECRSAT: return PIPE_STENCIL_OP_DECR;
  506.     case D3DSTENCILOP_INVERT:  return PIPE_STENCIL_OP_INVERT;
  507.     case D3DSTENCILOP_INCR:    return PIPE_STENCIL_OP_INCR_WRAP;
  508.     case D3DSTENCILOP_DECR:    return PIPE_STENCIL_OP_DECR_WRAP;
  509.     default:
  510.         return PIPE_STENCIL_OP_ZERO;
  511.     }
  512. }
  513.  
  514. static INLINE unsigned
  515. d3dcull_to_pipe_face(D3DCULL cull)
  516. {
  517.     switch (cull) {
  518.     case D3DCULL_NONE: return PIPE_FACE_NONE;
  519.     case D3DCULL_CW:   return PIPE_FACE_FRONT;
  520.     case D3DCULL_CCW:  return PIPE_FACE_BACK;
  521.     default:
  522.         assert(0);
  523.         return PIPE_FACE_NONE;
  524.     }
  525. }
  526.  
  527. static INLINE unsigned
  528. d3dfillmode_to_pipe_polygon_mode(D3DFILLMODE mode)
  529. {
  530.     switch (mode) {
  531.     case D3DFILL_POINT:     return PIPE_POLYGON_MODE_POINT;
  532.     case D3DFILL_WIREFRAME: return PIPE_POLYGON_MODE_LINE;
  533.     case D3DFILL_SOLID:     return PIPE_POLYGON_MODE_FILL;
  534.     case D3DFILL_SOLID_ZERO:return PIPE_POLYGON_MODE_FILL;
  535.     default:
  536.         assert(0);
  537.         return PIPE_POLYGON_MODE_FILL;
  538.     }
  539. }
  540.  
  541. static INLINE unsigned
  542. d3dblendop_to_pipe_blend(D3DBLENDOP op)
  543. {
  544.     switch (op) {
  545.     case D3DBLENDOP_ADD:         return PIPE_BLEND_ADD;
  546.     case D3DBLENDOP_SUBTRACT:    return PIPE_BLEND_SUBTRACT;
  547.     case D3DBLENDOP_REVSUBTRACT: return PIPE_BLEND_REVERSE_SUBTRACT;
  548.     case D3DBLENDOP_MIN:         return PIPE_BLEND_MIN;
  549.     case D3DBLENDOP_MAX:         return PIPE_BLEND_MAX;
  550.     default:
  551.         assert(0);
  552.         return PIPE_BLEND_ADD;
  553.     }
  554. }
  555.  
  556. /* NOTE: The COLOR factors for are equal to the ALPHA ones for alpha.
  557.  * Drivers may check RGB and ALPHA factors for equality so we should not
  558.  * simply substitute the ALPHA variants.
  559.  */
  560. static INLINE unsigned
  561. d3dblend_alpha_to_pipe_blendfactor(D3DBLEND b)
  562. {
  563.     switch (b) {
  564.     case D3DBLEND_ZERO:            return PIPE_BLENDFACTOR_ZERO;
  565.     case D3DBLEND_ONE:             return PIPE_BLENDFACTOR_ONE;
  566.     case D3DBLEND_SRCCOLOR:        return PIPE_BLENDFACTOR_SRC_COLOR/*ALPHA*/;
  567.     case D3DBLEND_INVSRCCOLOR:     return PIPE_BLENDFACTOR_INV_SRC_COLOR/*ALPHA*/;
  568.     case D3DBLEND_SRCALPHA:        return PIPE_BLENDFACTOR_SRC_ALPHA;
  569.     case D3DBLEND_INVSRCALPHA:     return PIPE_BLENDFACTOR_INV_SRC_ALPHA;
  570.     case D3DBLEND_DESTALPHA:       return PIPE_BLENDFACTOR_DST_ALPHA;
  571.     case D3DBLEND_INVDESTALPHA:    return PIPE_BLENDFACTOR_INV_DST_ALPHA;
  572.     case D3DBLEND_DESTCOLOR:       return PIPE_BLENDFACTOR_DST_COLOR/*ALPHA*/;
  573.     case D3DBLEND_INVDESTCOLOR:    return PIPE_BLENDFACTOR_INV_DST_COLOR/*ALPHA*/;
  574.     case D3DBLEND_SRCALPHASAT:     return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE;
  575.     case D3DBLEND_BOTHSRCALPHA:    return PIPE_BLENDFACTOR_SRC_ALPHA;
  576.     case D3DBLEND_BOTHINVSRCALPHA: return PIPE_BLENDFACTOR_INV_SRC_ALPHA;
  577.     case D3DBLEND_BLENDFACTOR:     return PIPE_BLENDFACTOR_CONST_COLOR/*ALPHA*/;
  578.     case D3DBLEND_INVBLENDFACTOR:  return PIPE_BLENDFACTOR_INV_CONST_COLOR/*ALPHA*/;
  579.     case D3DBLEND_SRCCOLOR2:       return PIPE_BLENDFACTOR_ONE; /* XXX */
  580.     case D3DBLEND_INVSRCCOLOR2:    return PIPE_BLENDFACTOR_ZERO; /* XXX */
  581.     default:
  582.        DBG_FLAG(DBG_UNKNOWN, "Unhandled blend factor %d\n", b);
  583.        return PIPE_BLENDFACTOR_ZERO;
  584.     }
  585. }
  586.  
  587. static INLINE unsigned
  588. d3dblend_color_to_pipe_blendfactor(D3DBLEND b)
  589. {
  590.     switch (b) {
  591.     case D3DBLEND_ZERO:            return PIPE_BLENDFACTOR_ZERO;
  592.     case D3DBLEND_ONE:             return PIPE_BLENDFACTOR_ONE;
  593.     case D3DBLEND_SRCCOLOR:        return PIPE_BLENDFACTOR_SRC_COLOR;
  594.     case D3DBLEND_INVSRCCOLOR:     return PIPE_BLENDFACTOR_INV_SRC_COLOR;
  595.     case D3DBLEND_SRCALPHA:        return PIPE_BLENDFACTOR_SRC_ALPHA;
  596.     case D3DBLEND_INVSRCALPHA:     return PIPE_BLENDFACTOR_INV_SRC_ALPHA;
  597.     case D3DBLEND_DESTALPHA:       return PIPE_BLENDFACTOR_DST_ALPHA;
  598.     case D3DBLEND_INVDESTALPHA:    return PIPE_BLENDFACTOR_INV_DST_ALPHA;
  599.     case D3DBLEND_DESTCOLOR:       return PIPE_BLENDFACTOR_DST_COLOR;
  600.     case D3DBLEND_INVDESTCOLOR:    return PIPE_BLENDFACTOR_INV_DST_COLOR;
  601.     case D3DBLEND_SRCALPHASAT:     return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE;
  602.     case D3DBLEND_BOTHSRCALPHA:    return PIPE_BLENDFACTOR_SRC_ALPHA;
  603.     case D3DBLEND_BOTHINVSRCALPHA: return PIPE_BLENDFACTOR_INV_SRC_ALPHA;
  604.     case D3DBLEND_BLENDFACTOR:     return PIPE_BLENDFACTOR_CONST_COLOR;
  605.     case D3DBLEND_INVBLENDFACTOR:  return PIPE_BLENDFACTOR_INV_CONST_COLOR;
  606.     case D3DBLEND_SRCCOLOR2:       return PIPE_BLENDFACTOR_SRC1_COLOR;
  607.     case D3DBLEND_INVSRCCOLOR2:    return PIPE_BLENDFACTOR_INV_SRC1_COLOR;
  608.     default:
  609.        DBG_FLAG(DBG_UNKNOWN, "Unhandled blend factor %d\n", b);
  610.        return PIPE_BLENDFACTOR_ZERO;
  611.     }
  612. }
  613.  
  614. static INLINE unsigned
  615. d3dtextureaddress_to_pipe_tex_wrap(D3DTEXTUREADDRESS addr)
  616. {
  617.     switch (addr) {
  618.     case D3DTADDRESS_WRAP:       return PIPE_TEX_WRAP_REPEAT;
  619.     case D3DTADDRESS_MIRROR:     return PIPE_TEX_WRAP_MIRROR_REPEAT;
  620.     case D3DTADDRESS_CLAMP:      return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  621.     case D3DTADDRESS_BORDER:     return PIPE_TEX_WRAP_CLAMP_TO_BORDER;
  622.     case D3DTADDRESS_MIRRORONCE: return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;
  623.     default:
  624.         assert(0);
  625.         return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
  626.     }
  627. }
  628.  
  629. static INLINE unsigned
  630. d3dtexturefiltertype_to_pipe_tex_filter(D3DTEXTUREFILTERTYPE filter)
  631. {
  632.     switch (filter) {
  633.     case D3DTEXF_POINT:       return PIPE_TEX_FILTER_NEAREST;
  634.     case D3DTEXF_LINEAR:      return PIPE_TEX_FILTER_LINEAR;
  635.     case D3DTEXF_ANISOTROPIC: return PIPE_TEX_FILTER_LINEAR;
  636.  
  637.     case D3DTEXF_NONE:
  638.     case D3DTEXF_PYRAMIDALQUAD:
  639.     case D3DTEXF_GAUSSIANQUAD:
  640.     case D3DTEXF_CONVOLUTIONMONO:
  641.     default:
  642.         assert(0);
  643.         return PIPE_TEX_FILTER_NEAREST;
  644.     }
  645. }
  646.  
  647. static INLINE unsigned
  648. d3dtexturefiltertype_to_pipe_tex_mipfilter(D3DTEXTUREFILTERTYPE filter)
  649. {
  650.     switch (filter) {
  651.     case D3DTEXF_NONE:        return PIPE_TEX_MIPFILTER_NONE;
  652.     case D3DTEXF_POINT:       return PIPE_TEX_FILTER_NEAREST;
  653.     case D3DTEXF_LINEAR:      return PIPE_TEX_FILTER_LINEAR;
  654.     case D3DTEXF_ANISOTROPIC: return PIPE_TEX_FILTER_LINEAR;
  655.  
  656.     case D3DTEXF_PYRAMIDALQUAD:
  657.     case D3DTEXF_GAUSSIANQUAD:
  658.     case D3DTEXF_CONVOLUTIONMONO:
  659.     default:
  660.         assert(0);
  661.         return PIPE_TEX_MIPFILTER_NONE;
  662.     }
  663. }
  664.  
  665. static INLINE unsigned nine_format_get_stride(enum pipe_format format,
  666.                                               unsigned width)
  667. {
  668.     unsigned stride = util_format_get_stride(format, width);
  669.  
  670.     return align(stride, 4);
  671. }
  672.  
  673. static INLINE unsigned nine_format_get_level_alloc_size(enum pipe_format format,
  674.                                                         unsigned width,
  675.                                                         unsigned height,
  676.                                                         unsigned level)
  677. {
  678.     unsigned w, h, size;
  679.  
  680.     w = u_minify(width, level);
  681.     h = u_minify(height, level);
  682.     size = nine_format_get_stride(format, w) *
  683.         util_format_get_nblocksy(format, h);
  684.     return size;
  685. }
  686.  
  687. static INLINE unsigned nine_format_get_size_and_offsets(enum pipe_format format,
  688.                                                         unsigned *offsets,
  689.                                                         unsigned width,
  690.                                                         unsigned height,
  691.                                                         unsigned last_level)
  692. {
  693.     unsigned l, w, h, size = 0;
  694.  
  695.     for (l = 0; l <= last_level; ++l) {
  696.         w = u_minify(width, l);
  697.         h = u_minify(height, l);
  698.         offsets[l] = size;
  699.         size += nine_format_get_stride(format, w) *
  700.             util_format_get_nblocksy(format, h);
  701.     }
  702.  
  703.     return size;
  704. }
  705.  
  706. #endif /* _NINE_PIPE_H_ */
  707.