Path: blob/21.2-virgl/src/gallium/frontends/nine/nine_pipe.h
4561 views
/*1* Copyright 2011 Joakim Sindholt <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* on the rights to use, copy, modify, merge, publish, distribute, sub7* license, and/or sell copies of the Software, and to permit persons to whom8* the Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL17* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,18* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR19* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE20* USE OR OTHER DEALINGS IN THE SOFTWARE. */2122#ifndef _NINE_PIPE_H_23#define _NINE_PIPE_H_2425#include "d3d9.h"26#include "pipe/p_format.h"27#include "pipe/p_screen.h"28#include "pipe/p_state.h" /* pipe_box */29#include "util/macros.h"30#include "util/u_rect.h"31#include "util/format/u_format.h"32#include "nine_helpers.h"3334struct cso_context;3536extern const enum pipe_format nine_d3d9_to_pipe_format_map[120];37extern const D3DFORMAT nine_pipe_to_d3d9_format_map[PIPE_FORMAT_COUNT];3839void nine_convert_dsa_state(struct pipe_depth_stencil_alpha_state *, const DWORD *);40void nine_convert_rasterizer_state(struct NineDevice9 *, struct pipe_rasterizer_state *, const DWORD *);41void nine_convert_blend_state(struct pipe_blend_state *, const DWORD *);42void nine_convert_sampler_state(struct cso_context *, int idx, const DWORD *);4344#define is_ATI1_ATI2(format) (format == PIPE_FORMAT_RGTC1_UNORM || format == PIPE_FORMAT_RGTC2_UNORM)4546static inline void47rect_to_pipe_box(struct pipe_box *dst, const RECT *src)48{49dst->x = src->left;50dst->y = src->top;51dst->z = 0;52dst->width = src->right - src->left;53dst->height = src->bottom - src->top;54dst->depth = 1;55}5657static inline void58pipe_box_to_rect(RECT *dst, const struct pipe_box *src)59{60dst->left = src->x;61dst->right = src->x + src->width;62dst->top = src->y;63dst->bottom = src->y + src->height;64}6566static inline void67rect_minify_inclusive(RECT *rect)68{69rect->left = rect->left >> 2;70rect->top = rect->top >> 2;71rect->right = DIV_ROUND_UP(rect->right, 2);72rect->bottom = DIV_ROUND_UP(rect->bottom, 2);73}7475/* We suppose:76* 0 <= rect->left < rect->right77* 0 <= rect->top < rect->bottom78*/79static inline void80fit_rect_format_inclusive(enum pipe_format format, RECT *rect, int width, int height)81{82const unsigned w = util_format_get_blockwidth(format);83const unsigned h = util_format_get_blockheight(format);8485if (util_format_is_compressed(format)) {86rect->left = rect->left - rect->left % w;87rect->top = rect->top - rect->top % h;88rect->right = (rect->right % w) == 0 ?89rect->right :90rect->right - (rect->right % w) + w;91rect->bottom = (rect->bottom % h) == 0 ?92rect->bottom :93rect->bottom - (rect->bottom % h) + h;94}9596rect->right = MIN2(rect->right, width);97rect->bottom = MIN2(rect->bottom, height);98}99100static inline boolean101rect_to_pipe_box_clamp(struct pipe_box *dst, const RECT *src)102{103rect_to_pipe_box(dst, src);104105if (dst->width <= 0 || dst->height <= 0) {106DBG_FLAG(DBG_UNKNOWN, "Warning: NULL box");107dst->width = MAX2(dst->width, 0);108dst->height = MAX2(dst->height, 0);109return TRUE;110}111return FALSE;112}113114static inline boolean115rect_to_pipe_box_flip(struct pipe_box *dst, const RECT *src)116{117rect_to_pipe_box(dst, src);118119if (dst->width >= 0 && dst->height >= 0)120return FALSE;121if (dst->width < 0) dst->width = -dst->width;122if (dst->height < 0) dst->height = -dst->height;123return TRUE;124}125126static inline void127rect_to_pipe_box_xy_only(struct pipe_box *dst, const RECT *src)128{129user_warn(src->left > src->right || src->top > src->bottom);130131dst->x = src->left;132dst->y = src->top;133dst->width = src->right - src->left;134dst->height = src->bottom - src->top;135}136137static inline boolean138rect_to_pipe_box_xy_only_clamp(struct pipe_box *dst, const RECT *src)139{140rect_to_pipe_box_xy_only(dst, src);141142if (dst->width <= 0 || dst->height <= 0) {143DBG_FLAG(DBG_UNKNOWN, "Warning: NULL box");144dst->width = MAX2(dst->width, 0);145dst->height = MAX2(dst->height, 0);146return TRUE;147}148return FALSE;149}150151static inline void152rect_to_g3d_u_rect(struct u_rect *dst, const RECT *src)153{154user_warn(src->left > src->right || src->top > src->bottom);155156dst->x0 = src->left;157dst->x1 = src->right;158dst->y0 = src->top;159dst->y1 = src->bottom;160}161162static inline void163d3dbox_to_pipe_box(struct pipe_box *dst, const D3DBOX *src)164{165user_warn(src->Left > src->Right);166user_warn(src->Top > src->Bottom);167user_warn(src->Front > src->Back);168169dst->x = src->Left;170dst->y = src->Top;171dst->z = src->Front;172dst->width = src->Right - src->Left;173dst->height = src->Bottom - src->Top;174dst->depth = src->Back - src->Front;175}176177static inline D3DFORMAT178pipe_to_d3d9_format(enum pipe_format format)179{180return nine_pipe_to_d3d9_format_map[format];181}182183static inline boolean184fetch4_compatible_format( D3DFORMAT fmt )185{186/* Basically formats with only red channel are allowed (with some exceptions) */187static const D3DFORMAT allowed[] = { /* TODO: list incomplete */188D3DFMT_L8,189D3DFMT_L16,190D3DFMT_R16F,191D3DFMT_R32F,192D3DFMT_A8,193D3DFMT_DF16,194D3DFMT_DF24,195D3DFMT_INTZ196};197unsigned i;198199for (i = 0; i < sizeof(allowed)/sizeof(D3DFORMAT); i++) {200if (fmt == allowed[i]) { return TRUE; }201}202return FALSE;203}204205/* ATI1 and ATI2 are not officially compressed in d3d9 */206static inline boolean207compressed_format( D3DFORMAT fmt )208{209switch (fmt) {210case D3DFMT_DXT1:211case D3DFMT_DXT2:212case D3DFMT_DXT3:213case D3DFMT_DXT4:214case D3DFMT_DXT5:215return TRUE;216default:217break;218}219return FALSE;220}221222static inline boolean223depth_stencil_format( D3DFORMAT fmt )224{225static const D3DFORMAT allowed[] = {226D3DFMT_D16_LOCKABLE,227D3DFMT_D32,228D3DFMT_D15S1,229D3DFMT_D24S8,230D3DFMT_D24X8,231D3DFMT_D24X4S4,232D3DFMT_D16,233D3DFMT_D32F_LOCKABLE,234D3DFMT_D24FS8,235D3DFMT_D32_LOCKABLE,236D3DFMT_DF16,237D3DFMT_DF24,238D3DFMT_INTZ239};240unsigned i;241242for (i = 0; i < sizeof(allowed)/sizeof(D3DFORMAT); i++) {243if (fmt == allowed[i]) { return TRUE; }244}245return FALSE;246}247248static inline unsigned249d3d9_get_pipe_depth_format_bindings(D3DFORMAT format)250{251switch (format) {252case D3DFMT_D32:253case D3DFMT_D15S1:254case D3DFMT_D24S8:255case D3DFMT_D24X8:256case D3DFMT_D24X4S4:257case D3DFMT_D16:258case D3DFMT_D24FS8:259return PIPE_BIND_DEPTH_STENCIL;260case D3DFMT_D32F_LOCKABLE:261case D3DFMT_D16_LOCKABLE:262case D3DFMT_D32_LOCKABLE:263return PIPE_BIND_DEPTH_STENCIL;264case D3DFMT_DF16:265case D3DFMT_DF24:266case D3DFMT_INTZ:267return PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_SAMPLER_VIEW;268default: unreachable("Unexpected format");269}270}271272static inline enum pipe_format273d3d9_to_pipe_format_internal(D3DFORMAT format)274{275if (format <= D3DFMT_A2B10G10R10_XR_BIAS)276return nine_d3d9_to_pipe_format_map[format];277switch (format) {278case D3DFMT_INTZ: return PIPE_FORMAT_S8_UINT_Z24_UNORM;279case D3DFMT_DF16: return PIPE_FORMAT_Z16_UNORM;280case D3DFMT_DF24: return PIPE_FORMAT_X8Z24_UNORM;281case D3DFMT_DXT1: return PIPE_FORMAT_DXT1_RGBA;282case D3DFMT_DXT2: return PIPE_FORMAT_DXT3_RGBA; /* XXX */283case D3DFMT_DXT3: return PIPE_FORMAT_DXT3_RGBA;284case D3DFMT_DXT4: return PIPE_FORMAT_DXT5_RGBA; /* XXX */285case D3DFMT_DXT5: return PIPE_FORMAT_DXT5_RGBA;286case D3DFMT_ATI1: return PIPE_FORMAT_RGTC1_UNORM;287case D3DFMT_ATI2: return PIPE_FORMAT_RGTC2_UNORM;288case D3DFMT_UYVY: return PIPE_FORMAT_UYVY;289case D3DFMT_YUY2: return PIPE_FORMAT_YUYV; /* XXX check */290case D3DFMT_NV12: return PIPE_FORMAT_NV12;291case D3DFMT_G8R8_G8B8: return PIPE_FORMAT_G8R8_G8B8_UNORM; /* XXX order ? */292case D3DFMT_R8G8_B8G8: return PIPE_FORMAT_R8G8_B8G8_UNORM; /* XXX order ? */293case D3DFMT_BINARYBUFFER: return PIPE_FORMAT_NONE; /* not a format */294case D3DFMT_MULTI2_ARGB8: return PIPE_FORMAT_NONE; /* not supported */295case D3DFMT_Y210: /* XXX */296case D3DFMT_Y216:297case D3DFMT_NV11:298case D3DFMT_NULL: /* special cased, only for surfaces */299return PIPE_FORMAT_NONE;300default:301DBG_FLAG(DBG_UNKNOWN, "unknown D3DFORMAT: 0x%x/%c%c%c%c\n",302format, (char)format, (char)(format >> 8),303(char)(format >> 16), (char)(format >> 24));304return PIPE_FORMAT_NONE;305}306}307308#define format_check_internal(pipe_format) \309screen->is_format_supported(screen, pipe_format, target, \310sample_count, sample_count, bindings)311312static inline enum pipe_format313d3d9_to_pipe_format_checked(struct pipe_screen *screen,314D3DFORMAT format,315enum pipe_texture_target target,316unsigned sample_count,317unsigned bindings,318boolean srgb,319boolean bypass_check)320{321enum pipe_format result;322323/* We cannot render to depth textures as a render target */324if (depth_stencil_format(format) && (bindings & PIPE_BIND_RENDER_TARGET))325return PIPE_FORMAT_NONE;326327result = d3d9_to_pipe_format_internal(format);328if (result == PIPE_FORMAT_NONE)329return PIPE_FORMAT_NONE;330331if (srgb)332result = util_format_srgb(result);333334/* bypass_check: Used for D3DPOOL_SCRATCH, which335* isn't limited to the formats supported by the336* device, and to check we are not using a format337* fallback. */338if (bypass_check || format_check_internal(result))339return result;340341/* fallback to another format for formats342* that match several pipe_format */343switch(format) {344/* depth buffer formats are not lockable (except those for which it345* is precised in the name), so it is ok to match to another similar346* format. In all cases, if the app reads the texture with a shader,347* it gets depth on r and doesn't get stencil.*/348case D3DFMT_INTZ:349case D3DFMT_D24S8:350if (format_check_internal(PIPE_FORMAT_Z24_UNORM_S8_UINT))351return PIPE_FORMAT_Z24_UNORM_S8_UINT;352break;353case D3DFMT_DF24:354case D3DFMT_D24X8:355if (format_check_internal(PIPE_FORMAT_Z24X8_UNORM))356return PIPE_FORMAT_Z24X8_UNORM;357break;358/* Support for X8L8V8U8 bumpenvmap format with lighting bits.359* X8L8V8U8 is commonly supported among dx9 cards.360* To avoid precision loss, we use PIPE_FORMAT_R32G32B32X32_FLOAT,361* however using PIPE_FORMAT_R8G8B8A8_SNORM should be ok */362case D3DFMT_X8L8V8U8:363if (bindings & PIPE_BIND_RENDER_TARGET)364return PIPE_FORMAT_NONE;365if (format_check_internal(PIPE_FORMAT_R32G32B32X32_FLOAT))366return PIPE_FORMAT_R32G32B32X32_FLOAT;367break;368/* Fallback for YUV formats */369case D3DFMT_UYVY:370case D3DFMT_YUY2:371case D3DFMT_NV12:372if (bindings & PIPE_BIND_RENDER_TARGET)373return PIPE_FORMAT_NONE;374if (format_check_internal(PIPE_FORMAT_R8G8B8X8_UNORM))375return PIPE_FORMAT_R8G8B8X8_UNORM;376default:377break;378}379return PIPE_FORMAT_NONE;380}381382/* The quality levels are vendor dependent, so we set our own.383* Every quality level has its own sample count and sample384* position matrix.385* The exact mapping might differ from system to system but thats OK,386* as there's no way to gather more information about quality levels387* in D3D9.388* In case of NONMASKABLE multisample map every quality-level389* to a MASKABLE MultiSampleType:390* 0: no MSAA391* 1: 2x MSAA392* 2: 4x MSAA393* ...394* If the requested quality level is not available to nearest395* matching quality level is used.396* If no multisample is available the function sets397* multisample to D3DMULTISAMPLE_NONE and returns zero.398*/399static inline HRESULT400d3dmultisample_type_check(struct pipe_screen *screen,401D3DFORMAT format,402D3DMULTISAMPLE_TYPE *multisample,403DWORD multisamplequality,404DWORD *levels)405{406unsigned bind, i;407408assert(multisample);409410if (levels)411*levels = 1;412413/* Ignores multisamplequality */414if (*multisample == D3DMULTISAMPLE_NONE)415return D3D_OK;416417if (*multisample == D3DMULTISAMPLE_NONMASKABLE) {418if (depth_stencil_format(format))419bind = d3d9_get_pipe_depth_format_bindings(format);420else /* render-target */421bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;422423*multisample = 0;424for (i = D3DMULTISAMPLE_2_SAMPLES; i < D3DMULTISAMPLE_16_SAMPLES &&425multisamplequality; ++i) {426if (d3d9_to_pipe_format_checked(screen, format, PIPE_TEXTURE_2D,427i, bind, FALSE, FALSE) != PIPE_FORMAT_NONE) {428multisamplequality--;429if (levels)430(*levels)++;431*multisample = i;432}433}434}435/* Make sure to get an exact match */436if (multisamplequality)437return D3DERR_INVALIDCALL;438return D3D_OK;439}440441static inline const char *442d3dformat_to_string(D3DFORMAT fmt)443{444switch (fmt) {445case D3DFMT_UNKNOWN: return "D3DFMT_UNKNOWN";446case D3DFMT_R8G8B8: return "D3DFMT_R8G8B8";447case D3DFMT_A8R8G8B8: return "D3DFMT_A8R8G8B8";448case D3DFMT_X8R8G8B8: return "D3DFMT_X8R8G8B8";449case D3DFMT_R5G6B5: return "D3DFMT_R5G6B5";450case D3DFMT_X1R5G5B5: return "D3DFMT_X1R5G5B5";451case D3DFMT_A1R5G5B5: return "D3DFMT_A1R5G5B5";452case D3DFMT_A4R4G4B4: return "D3DFMT_A4R4G4B4";453case D3DFMT_R3G3B2: return "D3DFMT_R3G3B2";454case D3DFMT_A8: return "D3DFMT_A8";455case D3DFMT_A8R3G3B2: return "D3DFMT_A8R3G3B2";456case D3DFMT_X4R4G4B4: return "D3DFMT_X4R4G4B4";457case D3DFMT_A2B10G10R10: return "D3DFMT_A2B10G10R10";458case D3DFMT_A8B8G8R8: return "D3DFMT_A8B8G8R8";459case D3DFMT_X8B8G8R8: return "D3DFMT_X8B8G8R8";460case D3DFMT_G16R16: return "D3DFMT_G16R16";461case D3DFMT_A2R10G10B10: return "D3DFMT_A2R10G10B10";462case D3DFMT_A16B16G16R16: return "D3DFMT_A16B16G16R16";463case D3DFMT_A8P8: return "D3DFMT_A8P8";464case D3DFMT_P8: return "D3DFMT_P8";465case D3DFMT_L8: return "D3DFMT_L8";466case D3DFMT_A8L8: return "D3DFMT_A8L8";467case D3DFMT_A4L4: return "D3DFMT_A4L4";468case D3DFMT_V8U8: return "D3DFMT_V8U8";469case D3DFMT_L6V5U5: return "D3DFMT_L6V5U5";470case D3DFMT_X8L8V8U8: return "D3DFMT_X8L8V8U8";471case D3DFMT_Q8W8V8U8: return "D3DFMT_Q8W8V8U8";472case D3DFMT_V16U16: return "D3DFMT_V16U16";473case D3DFMT_A2W10V10U10: return "D3DFMT_A2W10V10U10";474case D3DFMT_UYVY: return "D3DFMT_UYVY";475case D3DFMT_R8G8_B8G8: return "D3DFMT_R8G8_B8G8";476case D3DFMT_YUY2: return "D3DFMT_YUY2";477case D3DFMT_G8R8_G8B8: return "D3DFMT_G8R8_G8B8";478case D3DFMT_DXT1: return "D3DFMT_DXT1";479case D3DFMT_DXT2: return "D3DFMT_DXT2";480case D3DFMT_DXT3: return "D3DFMT_DXT3";481case D3DFMT_DXT4: return "D3DFMT_DXT4";482case D3DFMT_DXT5: return "D3DFMT_DXT5";483case D3DFMT_ATI1: return "D3DFMT_ATI1";484case D3DFMT_ATI2: return "D3DFMT_ATI2";485case D3DFMT_D16_LOCKABLE: return "D3DFMT_D16_LOCKABLE";486case D3DFMT_D32: return "D3DFMT_D32";487case D3DFMT_D15S1: return "D3DFMT_D15S1";488case D3DFMT_D24S8: return "D3DFMT_D24S8";489case D3DFMT_D24X8: return "D3DFMT_D24X8";490case D3DFMT_D24X4S4: return "D3DFMT_D24X4S4";491case D3DFMT_D16: return "D3DFMT_D16";492case D3DFMT_D32F_LOCKABLE: return "D3DFMT_D32F_LOCKABLE";493case D3DFMT_D24FS8: return "D3DFMT_D24FS8";494case D3DFMT_D32_LOCKABLE: return "D3DFMT_D32_LOCKABLE";495case D3DFMT_S8_LOCKABLE: return "D3DFMT_S8_LOCKABLE";496case D3DFMT_L16: return "D3DFMT_L16";497case D3DFMT_VERTEXDATA: return "D3DFMT_VERTEXDATA";498case D3DFMT_INDEX16: return "D3DFMT_INDEX16";499case D3DFMT_INDEX32: return "D3DFMT_INDEX32";500case D3DFMT_Q16W16V16U16: return "D3DFMT_Q16W16V16U16";501case D3DFMT_MULTI2_ARGB8: return "D3DFMT_MULTI2_ARGB8";502case D3DFMT_R16F: return "D3DFMT_R16F";503case D3DFMT_G16R16F: return "D3DFMT_G16R16F";504case D3DFMT_A16B16G16R16F: return "D3DFMT_A16B16G16R16F";505case D3DFMT_R32F: return "D3DFMT_R32F";506case D3DFMT_G32R32F: return "D3DFMT_G32R32F";507case D3DFMT_A32B32G32R32F: return "D3DFMT_A32B32G32R32F";508case D3DFMT_CxV8U8: return "D3DFMT_CxV8U8";509case D3DFMT_A1: return "D3DFMT_A1";510case D3DFMT_A2B10G10R10_XR_BIAS: return "D3DFMT_A2B10G10R10_XR_BIAS";511case D3DFMT_BINARYBUFFER: return "D3DFMT_BINARYBUFFER";512case D3DFMT_DF16: return "D3DFMT_DF16";513case D3DFMT_DF24: return "D3DFMT_DF24";514case D3DFMT_INTZ: return "D3DFMT_INTZ";515case D3DFMT_NVDB: return "D3DFMT_NVDB";516case D3DFMT_RESZ: return "D3DFMT_RESZ";517case D3DFMT_NULL: return "D3DFMT_NULL";518case D3DFMT_ATOC: return "D3DFMT_ATOC";519default:520break;521}522return "Unknown";523}524525static inline unsigned526nine_fvf_stride( DWORD fvf )527{528unsigned texcount, i, size = 0;529530switch (fvf & D3DFVF_POSITION_MASK) {531case D3DFVF_XYZ: size += 3*4; break;532case D3DFVF_XYZRHW: size += 4*4; break;533case D3DFVF_XYZB1: size += 4*4; break;534case D3DFVF_XYZB2: size += 5*4; break;535case D3DFVF_XYZB3: size += 6*4; break;536case D3DFVF_XYZB4: size += 7*4; break;537case D3DFVF_XYZB5: size += 8*4; break;538case D3DFVF_XYZW: size += 4*4; break;539default:540user_warn("Position doesn't match any known combination.");541break;542}543544if (fvf & D3DFVF_NORMAL) { size += 3*4; }545if (fvf & D3DFVF_PSIZE) { size += 1*4; }546if (fvf & D3DFVF_DIFFUSE) { size += 1*4; }547if (fvf & D3DFVF_SPECULAR) { size += 1*4; }548549texcount = (fvf >> D3DFVF_TEXCOUNT_SHIFT) & D3DFVF_TEXCOUNT_MASK;550if (user_error(texcount <= 8))551texcount = 8;552553for (i = 0; i < texcount; ++i) {554unsigned texformat = (fvf>>(16+i*2))&0x3;555/* texformats are defined having been shifted around so 1=3,2=0,3=1,4=2556* meaning we can just do this instead of the switch below */557size += (((texformat+1)&0x3)+1)*4;558559/*560switch (texformat) {561case D3DFVF_TEXTUREFORMAT1: size += 1*4;562case D3DFVF_TEXTUREFORMAT2: size += 2*4;563case D3DFVF_TEXTUREFORMAT3: size += 3*4;564case D3DFVF_TEXTUREFORMAT4: size += 4*4;565}566*/567}568569return size;570}571572static inline void573d3dcolor_to_rgba(float *rgba, D3DCOLOR color)574{575rgba[0] = (float)((color >> 16) & 0xFF) / 0xFF;576rgba[1] = (float)((color >> 8) & 0xFF) / 0xFF;577rgba[2] = (float)((color >> 0) & 0xFF) / 0xFF;578rgba[3] = (float)((color >> 24) & 0xFF) / 0xFF;579}580581static inline void582d3dcolor_to_pipe_color_union(union pipe_color_union *rgba, D3DCOLOR color)583{584d3dcolor_to_rgba(&rgba->f[0], color);585}586587static inline unsigned588d3dprimitivetype_to_pipe_prim(D3DPRIMITIVETYPE prim)589{590switch (prim) {591case D3DPT_POINTLIST: return PIPE_PRIM_POINTS;592case D3DPT_LINELIST: return PIPE_PRIM_LINES;593case D3DPT_LINESTRIP: return PIPE_PRIM_LINE_STRIP;594case D3DPT_TRIANGLELIST: return PIPE_PRIM_TRIANGLES;595case D3DPT_TRIANGLESTRIP: return PIPE_PRIM_TRIANGLE_STRIP;596case D3DPT_TRIANGLEFAN: return PIPE_PRIM_TRIANGLE_FAN;597default:598assert(0);599return PIPE_PRIM_POINTS;600}601}602603static inline unsigned604prim_count_to_vertex_count(D3DPRIMITIVETYPE prim, UINT count)605{606switch (prim) {607case D3DPT_POINTLIST: return count;608case D3DPT_LINELIST: return count * 2;609case D3DPT_LINESTRIP: return count + 1;610case D3DPT_TRIANGLELIST: return count * 3;611case D3DPT_TRIANGLESTRIP: return count + 2;612case D3DPT_TRIANGLEFAN: return count + 2;613default:614assert(0);615return 0;616}617}618619static inline unsigned620d3dcmpfunc_to_pipe_func(D3DCMPFUNC func)621{622switch (func) {623case D3DCMP_NEVER: return PIPE_FUNC_NEVER;624case D3DCMP_LESS: return PIPE_FUNC_LESS;625case D3DCMP_EQUAL: return PIPE_FUNC_EQUAL;626case D3DCMP_LESSEQUAL: return PIPE_FUNC_LEQUAL;627case D3DCMP_GREATER: return PIPE_FUNC_GREATER;628case D3DCMP_NOTEQUAL: return PIPE_FUNC_NOTEQUAL;629case D3DCMP_GREATEREQUAL: return PIPE_FUNC_GEQUAL;630case D3DCMP_ALWAYS: return PIPE_FUNC_ALWAYS;631case D3DCMP_NEVER_ZERO: return PIPE_FUNC_NEVER; // Tested on windows + ATI HD5770632default:633assert(0);634return PIPE_FUNC_NEVER;635}636}637638static inline unsigned639d3dstencilop_to_pipe_stencil_op(D3DSTENCILOP op)640{641switch (op) {642case D3DSTENCILOP_KEEP: return PIPE_STENCIL_OP_KEEP;643case D3DSTENCILOP_ZERO: return PIPE_STENCIL_OP_ZERO;644case D3DSTENCILOP_REPLACE: return PIPE_STENCIL_OP_REPLACE;645case D3DSTENCILOP_INCRSAT: return PIPE_STENCIL_OP_INCR;646case D3DSTENCILOP_DECRSAT: return PIPE_STENCIL_OP_DECR;647case D3DSTENCILOP_INVERT: return PIPE_STENCIL_OP_INVERT;648case D3DSTENCILOP_INCR: return PIPE_STENCIL_OP_INCR_WRAP;649case D3DSTENCILOP_DECR: return PIPE_STENCIL_OP_DECR_WRAP;650default:651return PIPE_STENCIL_OP_ZERO;652}653}654655static inline unsigned656d3dcull_to_pipe_face(D3DCULL cull)657{658switch (cull) {659case D3DCULL_NONE: return PIPE_FACE_NONE;660case D3DCULL_CW: return PIPE_FACE_FRONT;661case D3DCULL_CCW: return PIPE_FACE_BACK;662default:663assert(0);664return PIPE_FACE_NONE;665}666}667668static inline unsigned669d3dfillmode_to_pipe_polygon_mode(D3DFILLMODE mode)670{671switch (mode) {672case D3DFILL_POINT: return PIPE_POLYGON_MODE_POINT;673case D3DFILL_WIREFRAME: return PIPE_POLYGON_MODE_LINE;674case D3DFILL_SOLID: return PIPE_POLYGON_MODE_FILL;675case D3DFILL_SOLID_ZERO:return PIPE_POLYGON_MODE_FILL;676default:677assert(0);678return PIPE_POLYGON_MODE_FILL;679}680}681682static inline unsigned683d3dblendop_to_pipe_blend(D3DBLENDOP op)684{685switch (op) {686case D3DBLENDOP_ADD: return PIPE_BLEND_ADD;687case D3DBLENDOP_SUBTRACT: return PIPE_BLEND_SUBTRACT;688case D3DBLENDOP_REVSUBTRACT: return PIPE_BLEND_REVERSE_SUBTRACT;689case D3DBLENDOP_MIN: return PIPE_BLEND_MIN;690case D3DBLENDOP_MAX: return PIPE_BLEND_MAX;691default:692assert(0);693return PIPE_BLEND_ADD;694}695}696697/* NOTE: The COLOR factors for are equal to the ALPHA ones for alpha.698* Drivers may check RGB and ALPHA factors for equality so we should not699* simply substitute the ALPHA variants.700*/701static inline unsigned702d3dblend_alpha_to_pipe_blendfactor(D3DBLEND b)703{704switch (b) {705case D3DBLEND_ZERO: return PIPE_BLENDFACTOR_ZERO;706case D3DBLEND_ONE: return PIPE_BLENDFACTOR_ONE;707case D3DBLEND_SRCCOLOR: return PIPE_BLENDFACTOR_SRC_COLOR/*ALPHA*/;708case D3DBLEND_INVSRCCOLOR: return PIPE_BLENDFACTOR_INV_SRC_COLOR/*ALPHA*/;709case D3DBLEND_SRCALPHA: return PIPE_BLENDFACTOR_SRC_ALPHA;710case D3DBLEND_INVSRCALPHA: return PIPE_BLENDFACTOR_INV_SRC_ALPHA;711case D3DBLEND_DESTALPHA: return PIPE_BLENDFACTOR_DST_ALPHA;712case D3DBLEND_INVDESTALPHA: return PIPE_BLENDFACTOR_INV_DST_ALPHA;713case D3DBLEND_DESTCOLOR: return PIPE_BLENDFACTOR_DST_COLOR/*ALPHA*/;714case D3DBLEND_INVDESTCOLOR: return PIPE_BLENDFACTOR_INV_DST_COLOR/*ALPHA*/;715case D3DBLEND_SRCALPHASAT: return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE;716case D3DBLEND_BOTHSRCALPHA: return PIPE_BLENDFACTOR_SRC_ALPHA;717case D3DBLEND_BOTHINVSRCALPHA: return PIPE_BLENDFACTOR_INV_SRC_ALPHA;718case D3DBLEND_BLENDFACTOR: return PIPE_BLENDFACTOR_CONST_COLOR/*ALPHA*/;719case D3DBLEND_INVBLENDFACTOR: return PIPE_BLENDFACTOR_INV_CONST_COLOR/*ALPHA*/;720case D3DBLEND_SRCCOLOR2: return PIPE_BLENDFACTOR_ONE; /* XXX */721case D3DBLEND_INVSRCCOLOR2: return PIPE_BLENDFACTOR_ZERO; /* XXX */722default:723DBG_FLAG(DBG_UNKNOWN, "Unhandled blend factor %d\n", b);724return PIPE_BLENDFACTOR_ZERO;725}726}727728static inline unsigned729d3dblend_color_to_pipe_blendfactor(D3DBLEND b)730{731switch (b) {732case D3DBLEND_ZERO: return PIPE_BLENDFACTOR_ZERO;733case D3DBLEND_ONE: return PIPE_BLENDFACTOR_ONE;734case D3DBLEND_SRCCOLOR: return PIPE_BLENDFACTOR_SRC_COLOR;735case D3DBLEND_INVSRCCOLOR: return PIPE_BLENDFACTOR_INV_SRC_COLOR;736case D3DBLEND_SRCALPHA: return PIPE_BLENDFACTOR_SRC_ALPHA;737case D3DBLEND_INVSRCALPHA: return PIPE_BLENDFACTOR_INV_SRC_ALPHA;738case D3DBLEND_DESTALPHA: return PIPE_BLENDFACTOR_DST_ALPHA;739case D3DBLEND_INVDESTALPHA: return PIPE_BLENDFACTOR_INV_DST_ALPHA;740case D3DBLEND_DESTCOLOR: return PIPE_BLENDFACTOR_DST_COLOR;741case D3DBLEND_INVDESTCOLOR: return PIPE_BLENDFACTOR_INV_DST_COLOR;742case D3DBLEND_SRCALPHASAT: return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE;743case D3DBLEND_BOTHSRCALPHA: return PIPE_BLENDFACTOR_SRC_ALPHA;744case D3DBLEND_BOTHINVSRCALPHA: return PIPE_BLENDFACTOR_INV_SRC_ALPHA;745case D3DBLEND_BLENDFACTOR: return PIPE_BLENDFACTOR_CONST_COLOR;746case D3DBLEND_INVBLENDFACTOR: return PIPE_BLENDFACTOR_INV_CONST_COLOR;747case D3DBLEND_SRCCOLOR2: return PIPE_BLENDFACTOR_SRC1_COLOR;748case D3DBLEND_INVSRCCOLOR2: return PIPE_BLENDFACTOR_INV_SRC1_COLOR;749default:750DBG_FLAG(DBG_UNKNOWN, "Unhandled blend factor %d\n", b);751return PIPE_BLENDFACTOR_ZERO;752}753}754755static inline unsigned756d3dtextureaddress_to_pipe_tex_wrap(D3DTEXTUREADDRESS addr)757{758switch (addr) {759case D3DTADDRESS_WRAP: return PIPE_TEX_WRAP_REPEAT;760case D3DTADDRESS_MIRROR: return PIPE_TEX_WRAP_MIRROR_REPEAT;761case D3DTADDRESS_CLAMP: return PIPE_TEX_WRAP_CLAMP_TO_EDGE;762case D3DTADDRESS_BORDER: return PIPE_TEX_WRAP_CLAMP_TO_BORDER;763case D3DTADDRESS_MIRRORONCE: return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE;764default:765assert(0);766return PIPE_TEX_WRAP_CLAMP_TO_EDGE;767}768}769770static inline unsigned771d3dtexturefiltertype_to_pipe_tex_filter(D3DTEXTUREFILTERTYPE filter)772{773switch (filter) {774case D3DTEXF_POINT: return PIPE_TEX_FILTER_NEAREST;775case D3DTEXF_LINEAR: return PIPE_TEX_FILTER_LINEAR;776case D3DTEXF_ANISOTROPIC: return PIPE_TEX_FILTER_LINEAR;777778case D3DTEXF_NONE:779case D3DTEXF_PYRAMIDALQUAD:780case D3DTEXF_GAUSSIANQUAD:781case D3DTEXF_CONVOLUTIONMONO:782default:783assert(0);784return PIPE_TEX_FILTER_NEAREST;785}786}787788static inline unsigned789d3dtexturefiltertype_to_pipe_tex_mipfilter(D3DTEXTUREFILTERTYPE filter)790{791switch (filter) {792case D3DTEXF_NONE: return PIPE_TEX_MIPFILTER_NONE;793case D3DTEXF_POINT: return PIPE_TEX_FILTER_NEAREST;794case D3DTEXF_LINEAR: return PIPE_TEX_FILTER_LINEAR;795case D3DTEXF_ANISOTROPIC: return PIPE_TEX_FILTER_LINEAR;796797case D3DTEXF_PYRAMIDALQUAD:798case D3DTEXF_GAUSSIANQUAD:799case D3DTEXF_CONVOLUTIONMONO:800default:801assert(0);802return PIPE_TEX_MIPFILTER_NONE;803}804}805806static inline unsigned nine_format_get_stride(enum pipe_format format,807unsigned width)808{809unsigned stride = util_format_get_stride(format, width);810811return align(stride, 4);812}813814static inline unsigned nine_format_get_level_alloc_size(enum pipe_format format,815unsigned width,816unsigned height,817unsigned level)818{819unsigned w, h, size;820821w = u_minify(width, level);822h = u_minify(height, level);823if (is_ATI1_ATI2(format)) {824/* For "unknown" formats like ATIx use width * height bytes */825size = w * h;826} else if (format == PIPE_FORMAT_NONE) { /* D3DFMT_NULL */827size = w * h * 4;828} else {829size = nine_format_get_stride(format, w) *830util_format_get_nblocksy(format, h);831}832833return size;834}835836static inline unsigned nine_format_get_size_and_offsets(enum pipe_format format,837unsigned *offsets,838unsigned width,839unsigned height,840unsigned last_level)841{842unsigned l, w, h, size = 0;843844for (l = 0; l <= last_level; ++l) {845w = u_minify(width, l);846h = u_minify(height, l);847offsets[l] = size;848if (is_ATI1_ATI2(format)) {849/* For "unknown" formats like ATIx use width * height bytes */850size += w * h;851} else {852size += nine_format_get_stride(format, w) *853util_format_get_nblocksy(format, h);854}855}856857return size;858}859860#endif /* _NINE_PIPE_H_ */861862863