17ec681f3Smrg/* 27ec681f3Smrg * Copyright 2011 Joakim Sindholt <opensource@zhasha.com> 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * on the rights to use, copy, modify, merge, publish, distribute, sub 87ec681f3Smrg * license, and/or sell copies of the Software, and to permit persons to whom 97ec681f3Smrg * the Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice (including the next 127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 137ec681f3Smrg * Software. 147ec681f3Smrg * 157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 187ec681f3Smrg * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 197ec681f3Smrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 207ec681f3Smrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 217ec681f3Smrg * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 227ec681f3Smrg 237ec681f3Smrg#ifndef _NINE_PIPE_H_ 247ec681f3Smrg#define _NINE_PIPE_H_ 257ec681f3Smrg 267ec681f3Smrg#include "d3d9.h" 277ec681f3Smrg#include "pipe/p_format.h" 287ec681f3Smrg#include "pipe/p_screen.h" 297ec681f3Smrg#include "pipe/p_state.h" /* pipe_box */ 307ec681f3Smrg#include "util/macros.h" 317ec681f3Smrg#include "util/u_rect.h" 327ec681f3Smrg#include "util/format/u_format.h" 337ec681f3Smrg#include "nine_helpers.h" 347ec681f3Smrg 357ec681f3Smrgstruct cso_context; 367ec681f3Smrg 377ec681f3Smrgextern const enum pipe_format nine_d3d9_to_pipe_format_map[120]; 387ec681f3Smrgextern const D3DFORMAT nine_pipe_to_d3d9_format_map[PIPE_FORMAT_COUNT]; 397ec681f3Smrg 407ec681f3Smrgvoid nine_convert_dsa_state(struct pipe_depth_stencil_alpha_state *, const DWORD *); 417ec681f3Smrgvoid nine_convert_rasterizer_state(struct NineDevice9 *, struct pipe_rasterizer_state *, const DWORD *); 427ec681f3Smrgvoid nine_convert_blend_state(struct pipe_blend_state *, const DWORD *); 437ec681f3Smrgvoid nine_convert_sampler_state(struct cso_context *, int idx, const DWORD *); 447ec681f3Smrg 457ec681f3Smrg#define is_ATI1_ATI2(format) (format == PIPE_FORMAT_RGTC1_UNORM || format == PIPE_FORMAT_RGTC2_UNORM) 467ec681f3Smrg 477ec681f3Smrgstatic inline void 487ec681f3Smrgrect_to_pipe_box(struct pipe_box *dst, const RECT *src) 497ec681f3Smrg{ 507ec681f3Smrg dst->x = src->left; 517ec681f3Smrg dst->y = src->top; 527ec681f3Smrg dst->z = 0; 537ec681f3Smrg dst->width = src->right - src->left; 547ec681f3Smrg dst->height = src->bottom - src->top; 557ec681f3Smrg dst->depth = 1; 567ec681f3Smrg} 577ec681f3Smrg 587ec681f3Smrgstatic inline void 597ec681f3Smrgpipe_box_to_rect(RECT *dst, const struct pipe_box *src) 607ec681f3Smrg{ 617ec681f3Smrg dst->left = src->x; 627ec681f3Smrg dst->right = src->x + src->width; 637ec681f3Smrg dst->top = src->y; 647ec681f3Smrg dst->bottom = src->y + src->height; 657ec681f3Smrg} 667ec681f3Smrg 677ec681f3Smrgstatic inline void 687ec681f3Smrgrect_minify_inclusive(RECT *rect) 697ec681f3Smrg{ 707ec681f3Smrg rect->left = rect->left >> 2; 717ec681f3Smrg rect->top = rect->top >> 2; 727ec681f3Smrg rect->right = DIV_ROUND_UP(rect->right, 2); 737ec681f3Smrg rect->bottom = DIV_ROUND_UP(rect->bottom, 2); 747ec681f3Smrg} 757ec681f3Smrg 767ec681f3Smrg/* We suppose: 777ec681f3Smrg * 0 <= rect->left < rect->right 787ec681f3Smrg * 0 <= rect->top < rect->bottom 797ec681f3Smrg */ 807ec681f3Smrgstatic inline void 817ec681f3Smrgfit_rect_format_inclusive(enum pipe_format format, RECT *rect, int width, int height) 827ec681f3Smrg{ 837ec681f3Smrg const unsigned w = util_format_get_blockwidth(format); 847ec681f3Smrg const unsigned h = util_format_get_blockheight(format); 857ec681f3Smrg 867ec681f3Smrg if (util_format_is_compressed(format)) { 877ec681f3Smrg rect->left = rect->left - rect->left % w; 887ec681f3Smrg rect->top = rect->top - rect->top % h; 897ec681f3Smrg rect->right = (rect->right % w) == 0 ? 907ec681f3Smrg rect->right : 917ec681f3Smrg rect->right - (rect->right % w) + w; 927ec681f3Smrg rect->bottom = (rect->bottom % h) == 0 ? 937ec681f3Smrg rect->bottom : 947ec681f3Smrg rect->bottom - (rect->bottom % h) + h; 957ec681f3Smrg } 967ec681f3Smrg 977ec681f3Smrg rect->right = MIN2(rect->right, width); 987ec681f3Smrg rect->bottom = MIN2(rect->bottom, height); 997ec681f3Smrg} 1007ec681f3Smrg 1017ec681f3Smrgstatic inline boolean 1027ec681f3Smrgrect_to_pipe_box_clamp(struct pipe_box *dst, const RECT *src) 1037ec681f3Smrg{ 1047ec681f3Smrg rect_to_pipe_box(dst, src); 1057ec681f3Smrg 1067ec681f3Smrg if (dst->width <= 0 || dst->height <= 0) { 1077ec681f3Smrg DBG_FLAG(DBG_UNKNOWN, "Warning: NULL box"); 1087ec681f3Smrg dst->width = MAX2(dst->width, 0); 1097ec681f3Smrg dst->height = MAX2(dst->height, 0); 1107ec681f3Smrg return TRUE; 1117ec681f3Smrg } 1127ec681f3Smrg return FALSE; 1137ec681f3Smrg} 1147ec681f3Smrg 1157ec681f3Smrgstatic inline boolean 1167ec681f3Smrgrect_to_pipe_box_flip(struct pipe_box *dst, const RECT *src) 1177ec681f3Smrg{ 1187ec681f3Smrg rect_to_pipe_box(dst, src); 1197ec681f3Smrg 1207ec681f3Smrg if (dst->width >= 0 && dst->height >= 0) 1217ec681f3Smrg return FALSE; 1227ec681f3Smrg if (dst->width < 0) dst->width = -dst->width; 1237ec681f3Smrg if (dst->height < 0) dst->height = -dst->height; 1247ec681f3Smrg return TRUE; 1257ec681f3Smrg} 1267ec681f3Smrg 1277ec681f3Smrgstatic inline void 1287ec681f3Smrgrect_to_pipe_box_xy_only(struct pipe_box *dst, const RECT *src) 1297ec681f3Smrg{ 1307ec681f3Smrg user_warn(src->left > src->right || src->top > src->bottom); 1317ec681f3Smrg 1327ec681f3Smrg dst->x = src->left; 1337ec681f3Smrg dst->y = src->top; 1347ec681f3Smrg dst->width = src->right - src->left; 1357ec681f3Smrg dst->height = src->bottom - src->top; 1367ec681f3Smrg} 1377ec681f3Smrg 1387ec681f3Smrgstatic inline boolean 1397ec681f3Smrgrect_to_pipe_box_xy_only_clamp(struct pipe_box *dst, const RECT *src) 1407ec681f3Smrg{ 1417ec681f3Smrg rect_to_pipe_box_xy_only(dst, src); 1427ec681f3Smrg 1437ec681f3Smrg if (dst->width <= 0 || dst->height <= 0) { 1447ec681f3Smrg DBG_FLAG(DBG_UNKNOWN, "Warning: NULL box"); 1457ec681f3Smrg dst->width = MAX2(dst->width, 0); 1467ec681f3Smrg dst->height = MAX2(dst->height, 0); 1477ec681f3Smrg return TRUE; 1487ec681f3Smrg } 1497ec681f3Smrg return FALSE; 1507ec681f3Smrg} 1517ec681f3Smrg 1527ec681f3Smrgstatic inline void 1537ec681f3Smrgrect_to_g3d_u_rect(struct u_rect *dst, const RECT *src) 1547ec681f3Smrg{ 1557ec681f3Smrg user_warn(src->left > src->right || src->top > src->bottom); 1567ec681f3Smrg 1577ec681f3Smrg dst->x0 = src->left; 1587ec681f3Smrg dst->x1 = src->right; 1597ec681f3Smrg dst->y0 = src->top; 1607ec681f3Smrg dst->y1 = src->bottom; 1617ec681f3Smrg} 1627ec681f3Smrg 1637ec681f3Smrgstatic inline void 1647ec681f3Smrgd3dbox_to_pipe_box(struct pipe_box *dst, const D3DBOX *src) 1657ec681f3Smrg{ 1667ec681f3Smrg user_warn(src->Left > src->Right); 1677ec681f3Smrg user_warn(src->Top > src->Bottom); 1687ec681f3Smrg user_warn(src->Front > src->Back); 1697ec681f3Smrg 1707ec681f3Smrg dst->x = src->Left; 1717ec681f3Smrg dst->y = src->Top; 1727ec681f3Smrg dst->z = src->Front; 1737ec681f3Smrg dst->width = src->Right - src->Left; 1747ec681f3Smrg dst->height = src->Bottom - src->Top; 1757ec681f3Smrg dst->depth = src->Back - src->Front; 1767ec681f3Smrg} 1777ec681f3Smrg 1787ec681f3Smrgstatic inline D3DFORMAT 1797ec681f3Smrgpipe_to_d3d9_format(enum pipe_format format) 1807ec681f3Smrg{ 1817ec681f3Smrg return nine_pipe_to_d3d9_format_map[format]; 1827ec681f3Smrg} 1837ec681f3Smrg 1847ec681f3Smrgstatic inline boolean 1857ec681f3Smrgfetch4_compatible_format( D3DFORMAT fmt ) 1867ec681f3Smrg{ 1877ec681f3Smrg /* Basically formats with only red channel are allowed (with some exceptions) */ 1887ec681f3Smrg static const D3DFORMAT allowed[] = { /* TODO: list incomplete */ 1897ec681f3Smrg D3DFMT_L8, 1907ec681f3Smrg D3DFMT_L16, 1917ec681f3Smrg D3DFMT_R16F, 1927ec681f3Smrg D3DFMT_R32F, 1937ec681f3Smrg D3DFMT_A8, 1947ec681f3Smrg D3DFMT_DF16, 1957ec681f3Smrg D3DFMT_DF24, 1967ec681f3Smrg D3DFMT_INTZ 1977ec681f3Smrg }; 1987ec681f3Smrg unsigned i; 1997ec681f3Smrg 2007ec681f3Smrg for (i = 0; i < sizeof(allowed)/sizeof(D3DFORMAT); i++) { 2017ec681f3Smrg if (fmt == allowed[i]) { return TRUE; } 2027ec681f3Smrg } 2037ec681f3Smrg return FALSE; 2047ec681f3Smrg} 2057ec681f3Smrg 2067ec681f3Smrg/* ATI1 and ATI2 are not officially compressed in d3d9 */ 2077ec681f3Smrgstatic inline boolean 2087ec681f3Smrgcompressed_format( D3DFORMAT fmt ) 2097ec681f3Smrg{ 2107ec681f3Smrg switch (fmt) { 2117ec681f3Smrg case D3DFMT_DXT1: 2127ec681f3Smrg case D3DFMT_DXT2: 2137ec681f3Smrg case D3DFMT_DXT3: 2147ec681f3Smrg case D3DFMT_DXT4: 2157ec681f3Smrg case D3DFMT_DXT5: 2167ec681f3Smrg return TRUE; 2177ec681f3Smrg default: 2187ec681f3Smrg break; 2197ec681f3Smrg } 2207ec681f3Smrg return FALSE; 2217ec681f3Smrg} 2227ec681f3Smrg 2237ec681f3Smrgstatic inline boolean 2247ec681f3Smrgdepth_stencil_format( D3DFORMAT fmt ) 2257ec681f3Smrg{ 2267ec681f3Smrg static const D3DFORMAT allowed[] = { 2277ec681f3Smrg D3DFMT_D16_LOCKABLE, 2287ec681f3Smrg D3DFMT_D32, 2297ec681f3Smrg D3DFMT_D15S1, 2307ec681f3Smrg D3DFMT_D24S8, 2317ec681f3Smrg D3DFMT_D24X8, 2327ec681f3Smrg D3DFMT_D24X4S4, 2337ec681f3Smrg D3DFMT_D16, 2347ec681f3Smrg D3DFMT_D32F_LOCKABLE, 2357ec681f3Smrg D3DFMT_D24FS8, 2367ec681f3Smrg D3DFMT_D32_LOCKABLE, 2377ec681f3Smrg D3DFMT_DF16, 2387ec681f3Smrg D3DFMT_DF24, 2397ec681f3Smrg D3DFMT_INTZ 2407ec681f3Smrg }; 2417ec681f3Smrg unsigned i; 2427ec681f3Smrg 2437ec681f3Smrg for (i = 0; i < sizeof(allowed)/sizeof(D3DFORMAT); i++) { 2447ec681f3Smrg if (fmt == allowed[i]) { return TRUE; } 2457ec681f3Smrg } 2467ec681f3Smrg return FALSE; 2477ec681f3Smrg} 2487ec681f3Smrg 2497ec681f3Smrgstatic inline unsigned 2507ec681f3Smrgd3d9_get_pipe_depth_format_bindings(D3DFORMAT format) 2517ec681f3Smrg{ 2527ec681f3Smrg switch (format) { 2537ec681f3Smrg case D3DFMT_D32: 2547ec681f3Smrg case D3DFMT_D15S1: 2557ec681f3Smrg case D3DFMT_D24S8: 2567ec681f3Smrg case D3DFMT_D24X8: 2577ec681f3Smrg case D3DFMT_D24X4S4: 2587ec681f3Smrg case D3DFMT_D16: 2597ec681f3Smrg case D3DFMT_D24FS8: 2607ec681f3Smrg return PIPE_BIND_DEPTH_STENCIL; 2617ec681f3Smrg case D3DFMT_D32F_LOCKABLE: 2627ec681f3Smrg case D3DFMT_D16_LOCKABLE: 2637ec681f3Smrg case D3DFMT_D32_LOCKABLE: 2647ec681f3Smrg return PIPE_BIND_DEPTH_STENCIL; 2657ec681f3Smrg case D3DFMT_DF16: 2667ec681f3Smrg case D3DFMT_DF24: 2677ec681f3Smrg case D3DFMT_INTZ: 2687ec681f3Smrg return PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_SAMPLER_VIEW; 2697ec681f3Smrg default: unreachable("Unexpected format"); 2707ec681f3Smrg } 2717ec681f3Smrg} 2727ec681f3Smrg 2737ec681f3Smrgstatic inline enum pipe_format 2747ec681f3Smrgd3d9_to_pipe_format_internal(D3DFORMAT format) 2757ec681f3Smrg{ 2767ec681f3Smrg if (format <= D3DFMT_A2B10G10R10_XR_BIAS) 2777ec681f3Smrg return nine_d3d9_to_pipe_format_map[format]; 2787ec681f3Smrg switch (format) { 2797ec681f3Smrg case D3DFMT_INTZ: return PIPE_FORMAT_S8_UINT_Z24_UNORM; 2807ec681f3Smrg case D3DFMT_DF16: return PIPE_FORMAT_Z16_UNORM; 2817ec681f3Smrg case D3DFMT_DF24: return PIPE_FORMAT_X8Z24_UNORM; 2827ec681f3Smrg case D3DFMT_DXT1: return PIPE_FORMAT_DXT1_RGBA; 2837ec681f3Smrg case D3DFMT_DXT2: return PIPE_FORMAT_DXT3_RGBA; /* XXX */ 2847ec681f3Smrg case D3DFMT_DXT3: return PIPE_FORMAT_DXT3_RGBA; 2857ec681f3Smrg case D3DFMT_DXT4: return PIPE_FORMAT_DXT5_RGBA; /* XXX */ 2867ec681f3Smrg case D3DFMT_DXT5: return PIPE_FORMAT_DXT5_RGBA; 2877ec681f3Smrg case D3DFMT_ATI1: return PIPE_FORMAT_RGTC1_UNORM; 2887ec681f3Smrg case D3DFMT_ATI2: return PIPE_FORMAT_RGTC2_UNORM; 2897ec681f3Smrg case D3DFMT_UYVY: return PIPE_FORMAT_UYVY; 2907ec681f3Smrg case D3DFMT_YUY2: return PIPE_FORMAT_YUYV; /* XXX check */ 2917ec681f3Smrg case D3DFMT_NV12: return PIPE_FORMAT_NV12; 2927ec681f3Smrg case D3DFMT_G8R8_G8B8: return PIPE_FORMAT_G8R8_G8B8_UNORM; /* XXX order ? */ 2937ec681f3Smrg case D3DFMT_R8G8_B8G8: return PIPE_FORMAT_R8G8_B8G8_UNORM; /* XXX order ? */ 2947ec681f3Smrg case D3DFMT_BINARYBUFFER: return PIPE_FORMAT_NONE; /* not a format */ 2957ec681f3Smrg case D3DFMT_MULTI2_ARGB8: return PIPE_FORMAT_NONE; /* not supported */ 2967ec681f3Smrg case D3DFMT_Y210: /* XXX */ 2977ec681f3Smrg case D3DFMT_Y216: 2987ec681f3Smrg case D3DFMT_NV11: 2997ec681f3Smrg case D3DFMT_NULL: /* special cased, only for surfaces */ 3007ec681f3Smrg return PIPE_FORMAT_NONE; 3017ec681f3Smrg default: 3027ec681f3Smrg DBG_FLAG(DBG_UNKNOWN, "unknown D3DFORMAT: 0x%x/%c%c%c%c\n", 3037ec681f3Smrg format, (char)format, (char)(format >> 8), 3047ec681f3Smrg (char)(format >> 16), (char)(format >> 24)); 3057ec681f3Smrg return PIPE_FORMAT_NONE; 3067ec681f3Smrg } 3077ec681f3Smrg} 3087ec681f3Smrg 3097ec681f3Smrg#define format_check_internal(pipe_format) \ 3107ec681f3Smrg screen->is_format_supported(screen, pipe_format, target, \ 3117ec681f3Smrg sample_count, sample_count, bindings) 3127ec681f3Smrg 3137ec681f3Smrgstatic inline enum pipe_format 3147ec681f3Smrgd3d9_to_pipe_format_checked(struct pipe_screen *screen, 3157ec681f3Smrg D3DFORMAT format, 3167ec681f3Smrg enum pipe_texture_target target, 3177ec681f3Smrg unsigned sample_count, 3187ec681f3Smrg unsigned bindings, 3197ec681f3Smrg boolean srgb, 3207ec681f3Smrg boolean bypass_check) 3217ec681f3Smrg{ 3227ec681f3Smrg enum pipe_format result; 3237ec681f3Smrg 3247ec681f3Smrg /* We cannot render to depth textures as a render target */ 3257ec681f3Smrg if (depth_stencil_format(format) && (bindings & PIPE_BIND_RENDER_TARGET)) 3267ec681f3Smrg return PIPE_FORMAT_NONE; 3277ec681f3Smrg 3287ec681f3Smrg result = d3d9_to_pipe_format_internal(format); 3297ec681f3Smrg if (result == PIPE_FORMAT_NONE) 3307ec681f3Smrg return PIPE_FORMAT_NONE; 3317ec681f3Smrg 3327ec681f3Smrg if (srgb) 3337ec681f3Smrg result = util_format_srgb(result); 3347ec681f3Smrg 3357ec681f3Smrg /* bypass_check: Used for D3DPOOL_SCRATCH, which 3367ec681f3Smrg * isn't limited to the formats supported by the 3377ec681f3Smrg * device, and to check we are not using a format 3387ec681f3Smrg * fallback. */ 3397ec681f3Smrg if (bypass_check || format_check_internal(result)) 3407ec681f3Smrg return result; 3417ec681f3Smrg 3427ec681f3Smrg /* fallback to another format for formats 3437ec681f3Smrg * that match several pipe_format */ 3447ec681f3Smrg switch(format) { 3457ec681f3Smrg /* depth buffer formats are not lockable (except those for which it 3467ec681f3Smrg * is precised in the name), so it is ok to match to another similar 3477ec681f3Smrg * format. In all cases, if the app reads the texture with a shader, 3487ec681f3Smrg * it gets depth on r and doesn't get stencil.*/ 3497ec681f3Smrg case D3DFMT_INTZ: 3507ec681f3Smrg case D3DFMT_D24S8: 3517ec681f3Smrg if (format_check_internal(PIPE_FORMAT_Z24_UNORM_S8_UINT)) 3527ec681f3Smrg return PIPE_FORMAT_Z24_UNORM_S8_UINT; 3537ec681f3Smrg break; 3547ec681f3Smrg case D3DFMT_DF24: 3557ec681f3Smrg case D3DFMT_D24X8: 3567ec681f3Smrg if (format_check_internal(PIPE_FORMAT_Z24X8_UNORM)) 3577ec681f3Smrg return PIPE_FORMAT_Z24X8_UNORM; 3587ec681f3Smrg break; 3597ec681f3Smrg /* Support for X8L8V8U8 bumpenvmap format with lighting bits. 3607ec681f3Smrg * X8L8V8U8 is commonly supported among dx9 cards. 3617ec681f3Smrg * To avoid precision loss, we use PIPE_FORMAT_R32G32B32X32_FLOAT, 3627ec681f3Smrg * however using PIPE_FORMAT_R8G8B8A8_SNORM should be ok */ 3637ec681f3Smrg case D3DFMT_X8L8V8U8: 3647ec681f3Smrg if (bindings & PIPE_BIND_RENDER_TARGET) 3657ec681f3Smrg return PIPE_FORMAT_NONE; 3667ec681f3Smrg if (format_check_internal(PIPE_FORMAT_R32G32B32X32_FLOAT)) 3677ec681f3Smrg return PIPE_FORMAT_R32G32B32X32_FLOAT; 3687ec681f3Smrg break; 3697ec681f3Smrg /* Fallback for YUV formats */ 3707ec681f3Smrg case D3DFMT_UYVY: 3717ec681f3Smrg case D3DFMT_YUY2: 3727ec681f3Smrg case D3DFMT_NV12: 3737ec681f3Smrg if (bindings & PIPE_BIND_RENDER_TARGET) 3747ec681f3Smrg return PIPE_FORMAT_NONE; 3757ec681f3Smrg if (format_check_internal(PIPE_FORMAT_R8G8B8X8_UNORM)) 3767ec681f3Smrg return PIPE_FORMAT_R8G8B8X8_UNORM; 3777ec681f3Smrg default: 3787ec681f3Smrg break; 3797ec681f3Smrg } 3807ec681f3Smrg return PIPE_FORMAT_NONE; 3817ec681f3Smrg} 3827ec681f3Smrg 3837ec681f3Smrg/* The quality levels are vendor dependent, so we set our own. 3847ec681f3Smrg * Every quality level has its own sample count and sample 3857ec681f3Smrg * position matrix. 3867ec681f3Smrg * The exact mapping might differ from system to system but thats OK, 3877ec681f3Smrg * as there's no way to gather more information about quality levels 3887ec681f3Smrg * in D3D9. 3897ec681f3Smrg * In case of NONMASKABLE multisample map every quality-level 3907ec681f3Smrg * to a MASKABLE MultiSampleType: 3917ec681f3Smrg * 0: no MSAA 3927ec681f3Smrg * 1: 2x MSAA 3937ec681f3Smrg * 2: 4x MSAA 3947ec681f3Smrg * ... 3957ec681f3Smrg * If the requested quality level is not available to nearest 3967ec681f3Smrg * matching quality level is used. 3977ec681f3Smrg * If no multisample is available the function sets 3987ec681f3Smrg * multisample to D3DMULTISAMPLE_NONE and returns zero. 3997ec681f3Smrg */ 4007ec681f3Smrgstatic inline HRESULT 4017ec681f3Smrgd3dmultisample_type_check(struct pipe_screen *screen, 4027ec681f3Smrg D3DFORMAT format, 4037ec681f3Smrg D3DMULTISAMPLE_TYPE *multisample, 4047ec681f3Smrg DWORD multisamplequality, 4057ec681f3Smrg DWORD *levels) 4067ec681f3Smrg{ 4077ec681f3Smrg unsigned bind, i; 4087ec681f3Smrg 4097ec681f3Smrg assert(multisample); 4107ec681f3Smrg 4117ec681f3Smrg if (levels) 4127ec681f3Smrg *levels = 1; 4137ec681f3Smrg 4147ec681f3Smrg /* Ignores multisamplequality */ 4157ec681f3Smrg if (*multisample == D3DMULTISAMPLE_NONE) 4167ec681f3Smrg return D3D_OK; 4177ec681f3Smrg 4187ec681f3Smrg if (*multisample == D3DMULTISAMPLE_NONMASKABLE) { 4197ec681f3Smrg if (depth_stencil_format(format)) 4207ec681f3Smrg bind = d3d9_get_pipe_depth_format_bindings(format); 4217ec681f3Smrg else /* render-target */ 4227ec681f3Smrg bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; 4237ec681f3Smrg 4247ec681f3Smrg *multisample = 0; 4257ec681f3Smrg for (i = D3DMULTISAMPLE_2_SAMPLES; i < D3DMULTISAMPLE_16_SAMPLES && 4267ec681f3Smrg multisamplequality; ++i) { 4277ec681f3Smrg if (d3d9_to_pipe_format_checked(screen, format, PIPE_TEXTURE_2D, 4287ec681f3Smrg i, bind, FALSE, FALSE) != PIPE_FORMAT_NONE) { 4297ec681f3Smrg multisamplequality--; 4307ec681f3Smrg if (levels) 4317ec681f3Smrg (*levels)++; 4327ec681f3Smrg *multisample = i; 4337ec681f3Smrg } 4347ec681f3Smrg } 4357ec681f3Smrg } 4367ec681f3Smrg /* Make sure to get an exact match */ 4377ec681f3Smrg if (multisamplequality) 4387ec681f3Smrg return D3DERR_INVALIDCALL; 4397ec681f3Smrg return D3D_OK; 4407ec681f3Smrg} 4417ec681f3Smrg 4427ec681f3Smrgstatic inline const char * 4437ec681f3Smrgd3dformat_to_string(D3DFORMAT fmt) 4447ec681f3Smrg{ 4457ec681f3Smrg switch (fmt) { 4467ec681f3Smrg case D3DFMT_UNKNOWN: return "D3DFMT_UNKNOWN"; 4477ec681f3Smrg case D3DFMT_R8G8B8: return "D3DFMT_R8G8B8"; 4487ec681f3Smrg case D3DFMT_A8R8G8B8: return "D3DFMT_A8R8G8B8"; 4497ec681f3Smrg case D3DFMT_X8R8G8B8: return "D3DFMT_X8R8G8B8"; 4507ec681f3Smrg case D3DFMT_R5G6B5: return "D3DFMT_R5G6B5"; 4517ec681f3Smrg case D3DFMT_X1R5G5B5: return "D3DFMT_X1R5G5B5"; 4527ec681f3Smrg case D3DFMT_A1R5G5B5: return "D3DFMT_A1R5G5B5"; 4537ec681f3Smrg case D3DFMT_A4R4G4B4: return "D3DFMT_A4R4G4B4"; 4547ec681f3Smrg case D3DFMT_R3G3B2: return "D3DFMT_R3G3B2"; 4557ec681f3Smrg case D3DFMT_A8: return "D3DFMT_A8"; 4567ec681f3Smrg case D3DFMT_A8R3G3B2: return "D3DFMT_A8R3G3B2"; 4577ec681f3Smrg case D3DFMT_X4R4G4B4: return "D3DFMT_X4R4G4B4"; 4587ec681f3Smrg case D3DFMT_A2B10G10R10: return "D3DFMT_A2B10G10R10"; 4597ec681f3Smrg case D3DFMT_A8B8G8R8: return "D3DFMT_A8B8G8R8"; 4607ec681f3Smrg case D3DFMT_X8B8G8R8: return "D3DFMT_X8B8G8R8"; 4617ec681f3Smrg case D3DFMT_G16R16: return "D3DFMT_G16R16"; 4627ec681f3Smrg case D3DFMT_A2R10G10B10: return "D3DFMT_A2R10G10B10"; 4637ec681f3Smrg case D3DFMT_A16B16G16R16: return "D3DFMT_A16B16G16R16"; 4647ec681f3Smrg case D3DFMT_A8P8: return "D3DFMT_A8P8"; 4657ec681f3Smrg case D3DFMT_P8: return "D3DFMT_P8"; 4667ec681f3Smrg case D3DFMT_L8: return "D3DFMT_L8"; 4677ec681f3Smrg case D3DFMT_A8L8: return "D3DFMT_A8L8"; 4687ec681f3Smrg case D3DFMT_A4L4: return "D3DFMT_A4L4"; 4697ec681f3Smrg case D3DFMT_V8U8: return "D3DFMT_V8U8"; 4707ec681f3Smrg case D3DFMT_L6V5U5: return "D3DFMT_L6V5U5"; 4717ec681f3Smrg case D3DFMT_X8L8V8U8: return "D3DFMT_X8L8V8U8"; 4727ec681f3Smrg case D3DFMT_Q8W8V8U8: return "D3DFMT_Q8W8V8U8"; 4737ec681f3Smrg case D3DFMT_V16U16: return "D3DFMT_V16U16"; 4747ec681f3Smrg case D3DFMT_A2W10V10U10: return "D3DFMT_A2W10V10U10"; 4757ec681f3Smrg case D3DFMT_UYVY: return "D3DFMT_UYVY"; 4767ec681f3Smrg case D3DFMT_R8G8_B8G8: return "D3DFMT_R8G8_B8G8"; 4777ec681f3Smrg case D3DFMT_YUY2: return "D3DFMT_YUY2"; 4787ec681f3Smrg case D3DFMT_G8R8_G8B8: return "D3DFMT_G8R8_G8B8"; 4797ec681f3Smrg case D3DFMT_DXT1: return "D3DFMT_DXT1"; 4807ec681f3Smrg case D3DFMT_DXT2: return "D3DFMT_DXT2"; 4817ec681f3Smrg case D3DFMT_DXT3: return "D3DFMT_DXT3"; 4827ec681f3Smrg case D3DFMT_DXT4: return "D3DFMT_DXT4"; 4837ec681f3Smrg case D3DFMT_DXT5: return "D3DFMT_DXT5"; 4847ec681f3Smrg case D3DFMT_ATI1: return "D3DFMT_ATI1"; 4857ec681f3Smrg case D3DFMT_ATI2: return "D3DFMT_ATI2"; 4867ec681f3Smrg case D3DFMT_D16_LOCKABLE: return "D3DFMT_D16_LOCKABLE"; 4877ec681f3Smrg case D3DFMT_D32: return "D3DFMT_D32"; 4887ec681f3Smrg case D3DFMT_D15S1: return "D3DFMT_D15S1"; 4897ec681f3Smrg case D3DFMT_D24S8: return "D3DFMT_D24S8"; 4907ec681f3Smrg case D3DFMT_D24X8: return "D3DFMT_D24X8"; 4917ec681f3Smrg case D3DFMT_D24X4S4: return "D3DFMT_D24X4S4"; 4927ec681f3Smrg case D3DFMT_D16: return "D3DFMT_D16"; 4937ec681f3Smrg case D3DFMT_D32F_LOCKABLE: return "D3DFMT_D32F_LOCKABLE"; 4947ec681f3Smrg case D3DFMT_D24FS8: return "D3DFMT_D24FS8"; 4957ec681f3Smrg case D3DFMT_D32_LOCKABLE: return "D3DFMT_D32_LOCKABLE"; 4967ec681f3Smrg case D3DFMT_S8_LOCKABLE: return "D3DFMT_S8_LOCKABLE"; 4977ec681f3Smrg case D3DFMT_L16: return "D3DFMT_L16"; 4987ec681f3Smrg case D3DFMT_VERTEXDATA: return "D3DFMT_VERTEXDATA"; 4997ec681f3Smrg case D3DFMT_INDEX16: return "D3DFMT_INDEX16"; 5007ec681f3Smrg case D3DFMT_INDEX32: return "D3DFMT_INDEX32"; 5017ec681f3Smrg case D3DFMT_Q16W16V16U16: return "D3DFMT_Q16W16V16U16"; 5027ec681f3Smrg case D3DFMT_MULTI2_ARGB8: return "D3DFMT_MULTI2_ARGB8"; 5037ec681f3Smrg case D3DFMT_R16F: return "D3DFMT_R16F"; 5047ec681f3Smrg case D3DFMT_G16R16F: return "D3DFMT_G16R16F"; 5057ec681f3Smrg case D3DFMT_A16B16G16R16F: return "D3DFMT_A16B16G16R16F"; 5067ec681f3Smrg case D3DFMT_R32F: return "D3DFMT_R32F"; 5077ec681f3Smrg case D3DFMT_G32R32F: return "D3DFMT_G32R32F"; 5087ec681f3Smrg case D3DFMT_A32B32G32R32F: return "D3DFMT_A32B32G32R32F"; 5097ec681f3Smrg case D3DFMT_CxV8U8: return "D3DFMT_CxV8U8"; 5107ec681f3Smrg case D3DFMT_A1: return "D3DFMT_A1"; 5117ec681f3Smrg case D3DFMT_A2B10G10R10_XR_BIAS: return "D3DFMT_A2B10G10R10_XR_BIAS"; 5127ec681f3Smrg case D3DFMT_BINARYBUFFER: return "D3DFMT_BINARYBUFFER"; 5137ec681f3Smrg case D3DFMT_DF16: return "D3DFMT_DF16"; 5147ec681f3Smrg case D3DFMT_DF24: return "D3DFMT_DF24"; 5157ec681f3Smrg case D3DFMT_INTZ: return "D3DFMT_INTZ"; 5167ec681f3Smrg case D3DFMT_NVDB: return "D3DFMT_NVDB"; 5177ec681f3Smrg case D3DFMT_RESZ: return "D3DFMT_RESZ"; 5187ec681f3Smrg case D3DFMT_NULL: return "D3DFMT_NULL"; 5197ec681f3Smrg case D3DFMT_ATOC: return "D3DFMT_ATOC"; 5207ec681f3Smrg default: 5217ec681f3Smrg break; 5227ec681f3Smrg } 5237ec681f3Smrg return "Unknown"; 5247ec681f3Smrg} 5257ec681f3Smrg 5267ec681f3Smrgstatic inline unsigned 5277ec681f3Smrgnine_fvf_stride( DWORD fvf ) 5287ec681f3Smrg{ 5297ec681f3Smrg unsigned texcount, i, size = 0; 5307ec681f3Smrg 5317ec681f3Smrg switch (fvf & D3DFVF_POSITION_MASK) { 5327ec681f3Smrg case D3DFVF_XYZ: size += 3*4; break; 5337ec681f3Smrg case D3DFVF_XYZRHW: size += 4*4; break; 5347ec681f3Smrg case D3DFVF_XYZB1: size += 4*4; break; 5357ec681f3Smrg case D3DFVF_XYZB2: size += 5*4; break; 5367ec681f3Smrg case D3DFVF_XYZB3: size += 6*4; break; 5377ec681f3Smrg case D3DFVF_XYZB4: size += 7*4; break; 5387ec681f3Smrg case D3DFVF_XYZB5: size += 8*4; break; 5397ec681f3Smrg case D3DFVF_XYZW: size += 4*4; break; 5407ec681f3Smrg default: 5417ec681f3Smrg user_warn("Position doesn't match any known combination."); 5427ec681f3Smrg break; 5437ec681f3Smrg } 5447ec681f3Smrg 5457ec681f3Smrg if (fvf & D3DFVF_NORMAL) { size += 3*4; } 5467ec681f3Smrg if (fvf & D3DFVF_PSIZE) { size += 1*4; } 5477ec681f3Smrg if (fvf & D3DFVF_DIFFUSE) { size += 1*4; } 5487ec681f3Smrg if (fvf & D3DFVF_SPECULAR) { size += 1*4; } 5497ec681f3Smrg 5507ec681f3Smrg texcount = (fvf >> D3DFVF_TEXCOUNT_SHIFT) & D3DFVF_TEXCOUNT_MASK; 5517ec681f3Smrg if (user_error(texcount <= 8)) 5527ec681f3Smrg texcount = 8; 5537ec681f3Smrg 5547ec681f3Smrg for (i = 0; i < texcount; ++i) { 5557ec681f3Smrg unsigned texformat = (fvf>>(16+i*2))&0x3; 5567ec681f3Smrg /* texformats are defined having been shifted around so 1=3,2=0,3=1,4=2 5577ec681f3Smrg * meaning we can just do this instead of the switch below */ 5587ec681f3Smrg size += (((texformat+1)&0x3)+1)*4; 5597ec681f3Smrg 5607ec681f3Smrg /* 5617ec681f3Smrg switch (texformat) { 5627ec681f3Smrg case D3DFVF_TEXTUREFORMAT1: size += 1*4; 5637ec681f3Smrg case D3DFVF_TEXTUREFORMAT2: size += 2*4; 5647ec681f3Smrg case D3DFVF_TEXTUREFORMAT3: size += 3*4; 5657ec681f3Smrg case D3DFVF_TEXTUREFORMAT4: size += 4*4; 5667ec681f3Smrg } 5677ec681f3Smrg */ 5687ec681f3Smrg } 5697ec681f3Smrg 5707ec681f3Smrg return size; 5717ec681f3Smrg} 5727ec681f3Smrg 5737ec681f3Smrgstatic inline void 5747ec681f3Smrgd3dcolor_to_rgba(float *rgba, D3DCOLOR color) 5757ec681f3Smrg{ 5767ec681f3Smrg rgba[0] = (float)((color >> 16) & 0xFF) / 0xFF; 5777ec681f3Smrg rgba[1] = (float)((color >> 8) & 0xFF) / 0xFF; 5787ec681f3Smrg rgba[2] = (float)((color >> 0) & 0xFF) / 0xFF; 5797ec681f3Smrg rgba[3] = (float)((color >> 24) & 0xFF) / 0xFF; 5807ec681f3Smrg} 5817ec681f3Smrg 5827ec681f3Smrgstatic inline void 5837ec681f3Smrgd3dcolor_to_pipe_color_union(union pipe_color_union *rgba, D3DCOLOR color) 5847ec681f3Smrg{ 5857ec681f3Smrg d3dcolor_to_rgba(&rgba->f[0], color); 5867ec681f3Smrg} 5877ec681f3Smrg 5887ec681f3Smrgstatic inline unsigned 5897ec681f3Smrgd3dprimitivetype_to_pipe_prim(D3DPRIMITIVETYPE prim) 5907ec681f3Smrg{ 5917ec681f3Smrg switch (prim) { 5927ec681f3Smrg case D3DPT_POINTLIST: return PIPE_PRIM_POINTS; 5937ec681f3Smrg case D3DPT_LINELIST: return PIPE_PRIM_LINES; 5947ec681f3Smrg case D3DPT_LINESTRIP: return PIPE_PRIM_LINE_STRIP; 5957ec681f3Smrg case D3DPT_TRIANGLELIST: return PIPE_PRIM_TRIANGLES; 5967ec681f3Smrg case D3DPT_TRIANGLESTRIP: return PIPE_PRIM_TRIANGLE_STRIP; 5977ec681f3Smrg case D3DPT_TRIANGLEFAN: return PIPE_PRIM_TRIANGLE_FAN; 5987ec681f3Smrg default: 5997ec681f3Smrg assert(0); 6007ec681f3Smrg return PIPE_PRIM_POINTS; 6017ec681f3Smrg } 6027ec681f3Smrg} 6037ec681f3Smrg 6047ec681f3Smrgstatic inline unsigned 6057ec681f3Smrgprim_count_to_vertex_count(D3DPRIMITIVETYPE prim, UINT count) 6067ec681f3Smrg{ 6077ec681f3Smrg switch (prim) { 6087ec681f3Smrg case D3DPT_POINTLIST: return count; 6097ec681f3Smrg case D3DPT_LINELIST: return count * 2; 6107ec681f3Smrg case D3DPT_LINESTRIP: return count + 1; 6117ec681f3Smrg case D3DPT_TRIANGLELIST: return count * 3; 6127ec681f3Smrg case D3DPT_TRIANGLESTRIP: return count + 2; 6137ec681f3Smrg case D3DPT_TRIANGLEFAN: return count + 2; 6147ec681f3Smrg default: 6157ec681f3Smrg assert(0); 6167ec681f3Smrg return 0; 6177ec681f3Smrg } 6187ec681f3Smrg} 6197ec681f3Smrg 6207ec681f3Smrgstatic inline unsigned 6217ec681f3Smrgd3dcmpfunc_to_pipe_func(D3DCMPFUNC func) 6227ec681f3Smrg{ 6237ec681f3Smrg switch (func) { 6247ec681f3Smrg case D3DCMP_NEVER: return PIPE_FUNC_NEVER; 6257ec681f3Smrg case D3DCMP_LESS: return PIPE_FUNC_LESS; 6267ec681f3Smrg case D3DCMP_EQUAL: return PIPE_FUNC_EQUAL; 6277ec681f3Smrg case D3DCMP_LESSEQUAL: return PIPE_FUNC_LEQUAL; 6287ec681f3Smrg case D3DCMP_GREATER: return PIPE_FUNC_GREATER; 6297ec681f3Smrg case D3DCMP_NOTEQUAL: return PIPE_FUNC_NOTEQUAL; 6307ec681f3Smrg case D3DCMP_GREATEREQUAL: return PIPE_FUNC_GEQUAL; 6317ec681f3Smrg case D3DCMP_ALWAYS: return PIPE_FUNC_ALWAYS; 6327ec681f3Smrg case D3DCMP_NEVER_ZERO: return PIPE_FUNC_NEVER; // Tested on windows + ATI HD5770 6337ec681f3Smrg default: 6347ec681f3Smrg assert(0); 6357ec681f3Smrg return PIPE_FUNC_NEVER; 6367ec681f3Smrg } 6377ec681f3Smrg} 6387ec681f3Smrg 6397ec681f3Smrgstatic inline unsigned 6407ec681f3Smrgd3dstencilop_to_pipe_stencil_op(D3DSTENCILOP op) 6417ec681f3Smrg{ 6427ec681f3Smrg switch (op) { 6437ec681f3Smrg case D3DSTENCILOP_KEEP: return PIPE_STENCIL_OP_KEEP; 6447ec681f3Smrg case D3DSTENCILOP_ZERO: return PIPE_STENCIL_OP_ZERO; 6457ec681f3Smrg case D3DSTENCILOP_REPLACE: return PIPE_STENCIL_OP_REPLACE; 6467ec681f3Smrg case D3DSTENCILOP_INCRSAT: return PIPE_STENCIL_OP_INCR; 6477ec681f3Smrg case D3DSTENCILOP_DECRSAT: return PIPE_STENCIL_OP_DECR; 6487ec681f3Smrg case D3DSTENCILOP_INVERT: return PIPE_STENCIL_OP_INVERT; 6497ec681f3Smrg case D3DSTENCILOP_INCR: return PIPE_STENCIL_OP_INCR_WRAP; 6507ec681f3Smrg case D3DSTENCILOP_DECR: return PIPE_STENCIL_OP_DECR_WRAP; 6517ec681f3Smrg default: 6527ec681f3Smrg return PIPE_STENCIL_OP_ZERO; 6537ec681f3Smrg } 6547ec681f3Smrg} 6557ec681f3Smrg 6567ec681f3Smrgstatic inline unsigned 6577ec681f3Smrgd3dcull_to_pipe_face(D3DCULL cull) 6587ec681f3Smrg{ 6597ec681f3Smrg switch (cull) { 6607ec681f3Smrg case D3DCULL_NONE: return PIPE_FACE_NONE; 6617ec681f3Smrg case D3DCULL_CW: return PIPE_FACE_FRONT; 6627ec681f3Smrg case D3DCULL_CCW: return PIPE_FACE_BACK; 6637ec681f3Smrg default: 6647ec681f3Smrg assert(0); 6657ec681f3Smrg return PIPE_FACE_NONE; 6667ec681f3Smrg } 6677ec681f3Smrg} 6687ec681f3Smrg 6697ec681f3Smrgstatic inline unsigned 6707ec681f3Smrgd3dfillmode_to_pipe_polygon_mode(D3DFILLMODE mode) 6717ec681f3Smrg{ 6727ec681f3Smrg switch (mode) { 6737ec681f3Smrg case D3DFILL_POINT: return PIPE_POLYGON_MODE_POINT; 6747ec681f3Smrg case D3DFILL_WIREFRAME: return PIPE_POLYGON_MODE_LINE; 6757ec681f3Smrg case D3DFILL_SOLID: return PIPE_POLYGON_MODE_FILL; 6767ec681f3Smrg case D3DFILL_SOLID_ZERO:return PIPE_POLYGON_MODE_FILL; 6777ec681f3Smrg default: 6787ec681f3Smrg assert(0); 6797ec681f3Smrg return PIPE_POLYGON_MODE_FILL; 6807ec681f3Smrg } 6817ec681f3Smrg} 6827ec681f3Smrg 6837ec681f3Smrgstatic inline unsigned 6847ec681f3Smrgd3dblendop_to_pipe_blend(D3DBLENDOP op) 6857ec681f3Smrg{ 6867ec681f3Smrg switch (op) { 6877ec681f3Smrg case D3DBLENDOP_ADD: return PIPE_BLEND_ADD; 6887ec681f3Smrg case D3DBLENDOP_SUBTRACT: return PIPE_BLEND_SUBTRACT; 6897ec681f3Smrg case D3DBLENDOP_REVSUBTRACT: return PIPE_BLEND_REVERSE_SUBTRACT; 6907ec681f3Smrg case D3DBLENDOP_MIN: return PIPE_BLEND_MIN; 6917ec681f3Smrg case D3DBLENDOP_MAX: return PIPE_BLEND_MAX; 6927ec681f3Smrg default: 6937ec681f3Smrg assert(0); 6947ec681f3Smrg return PIPE_BLEND_ADD; 6957ec681f3Smrg } 6967ec681f3Smrg} 6977ec681f3Smrg 6987ec681f3Smrg/* NOTE: The COLOR factors for are equal to the ALPHA ones for alpha. 6997ec681f3Smrg * Drivers may check RGB and ALPHA factors for equality so we should not 7007ec681f3Smrg * simply substitute the ALPHA variants. 7017ec681f3Smrg */ 7027ec681f3Smrgstatic inline unsigned 7037ec681f3Smrgd3dblend_alpha_to_pipe_blendfactor(D3DBLEND b) 7047ec681f3Smrg{ 7057ec681f3Smrg switch (b) { 7067ec681f3Smrg case D3DBLEND_ZERO: return PIPE_BLENDFACTOR_ZERO; 7077ec681f3Smrg case D3DBLEND_ONE: return PIPE_BLENDFACTOR_ONE; 7087ec681f3Smrg case D3DBLEND_SRCCOLOR: return PIPE_BLENDFACTOR_SRC_COLOR/*ALPHA*/; 7097ec681f3Smrg case D3DBLEND_INVSRCCOLOR: return PIPE_BLENDFACTOR_INV_SRC_COLOR/*ALPHA*/; 7107ec681f3Smrg case D3DBLEND_SRCALPHA: return PIPE_BLENDFACTOR_SRC_ALPHA; 7117ec681f3Smrg case D3DBLEND_INVSRCALPHA: return PIPE_BLENDFACTOR_INV_SRC_ALPHA; 7127ec681f3Smrg case D3DBLEND_DESTALPHA: return PIPE_BLENDFACTOR_DST_ALPHA; 7137ec681f3Smrg case D3DBLEND_INVDESTALPHA: return PIPE_BLENDFACTOR_INV_DST_ALPHA; 7147ec681f3Smrg case D3DBLEND_DESTCOLOR: return PIPE_BLENDFACTOR_DST_COLOR/*ALPHA*/; 7157ec681f3Smrg case D3DBLEND_INVDESTCOLOR: return PIPE_BLENDFACTOR_INV_DST_COLOR/*ALPHA*/; 7167ec681f3Smrg case D3DBLEND_SRCALPHASAT: return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE; 7177ec681f3Smrg case D3DBLEND_BOTHSRCALPHA: return PIPE_BLENDFACTOR_SRC_ALPHA; 7187ec681f3Smrg case D3DBLEND_BOTHINVSRCALPHA: return PIPE_BLENDFACTOR_INV_SRC_ALPHA; 7197ec681f3Smrg case D3DBLEND_BLENDFACTOR: return PIPE_BLENDFACTOR_CONST_COLOR/*ALPHA*/; 7207ec681f3Smrg case D3DBLEND_INVBLENDFACTOR: return PIPE_BLENDFACTOR_INV_CONST_COLOR/*ALPHA*/; 7217ec681f3Smrg case D3DBLEND_SRCCOLOR2: return PIPE_BLENDFACTOR_ONE; /* XXX */ 7227ec681f3Smrg case D3DBLEND_INVSRCCOLOR2: return PIPE_BLENDFACTOR_ZERO; /* XXX */ 7237ec681f3Smrg default: 7247ec681f3Smrg DBG_FLAG(DBG_UNKNOWN, "Unhandled blend factor %d\n", b); 7257ec681f3Smrg return PIPE_BLENDFACTOR_ZERO; 7267ec681f3Smrg } 7277ec681f3Smrg} 7287ec681f3Smrg 7297ec681f3Smrgstatic inline unsigned 7307ec681f3Smrgd3dblend_color_to_pipe_blendfactor(D3DBLEND b) 7317ec681f3Smrg{ 7327ec681f3Smrg switch (b) { 7337ec681f3Smrg case D3DBLEND_ZERO: return PIPE_BLENDFACTOR_ZERO; 7347ec681f3Smrg case D3DBLEND_ONE: return PIPE_BLENDFACTOR_ONE; 7357ec681f3Smrg case D3DBLEND_SRCCOLOR: return PIPE_BLENDFACTOR_SRC_COLOR; 7367ec681f3Smrg case D3DBLEND_INVSRCCOLOR: return PIPE_BLENDFACTOR_INV_SRC_COLOR; 7377ec681f3Smrg case D3DBLEND_SRCALPHA: return PIPE_BLENDFACTOR_SRC_ALPHA; 7387ec681f3Smrg case D3DBLEND_INVSRCALPHA: return PIPE_BLENDFACTOR_INV_SRC_ALPHA; 7397ec681f3Smrg case D3DBLEND_DESTALPHA: return PIPE_BLENDFACTOR_DST_ALPHA; 7407ec681f3Smrg case D3DBLEND_INVDESTALPHA: return PIPE_BLENDFACTOR_INV_DST_ALPHA; 7417ec681f3Smrg case D3DBLEND_DESTCOLOR: return PIPE_BLENDFACTOR_DST_COLOR; 7427ec681f3Smrg case D3DBLEND_INVDESTCOLOR: return PIPE_BLENDFACTOR_INV_DST_COLOR; 7437ec681f3Smrg case D3DBLEND_SRCALPHASAT: return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE; 7447ec681f3Smrg case D3DBLEND_BOTHSRCALPHA: return PIPE_BLENDFACTOR_SRC_ALPHA; 7457ec681f3Smrg case D3DBLEND_BOTHINVSRCALPHA: return PIPE_BLENDFACTOR_INV_SRC_ALPHA; 7467ec681f3Smrg case D3DBLEND_BLENDFACTOR: return PIPE_BLENDFACTOR_CONST_COLOR; 7477ec681f3Smrg case D3DBLEND_INVBLENDFACTOR: return PIPE_BLENDFACTOR_INV_CONST_COLOR; 7487ec681f3Smrg case D3DBLEND_SRCCOLOR2: return PIPE_BLENDFACTOR_SRC1_COLOR; 7497ec681f3Smrg case D3DBLEND_INVSRCCOLOR2: return PIPE_BLENDFACTOR_INV_SRC1_COLOR; 7507ec681f3Smrg default: 7517ec681f3Smrg DBG_FLAG(DBG_UNKNOWN, "Unhandled blend factor %d\n", b); 7527ec681f3Smrg return PIPE_BLENDFACTOR_ZERO; 7537ec681f3Smrg } 7547ec681f3Smrg} 7557ec681f3Smrg 7567ec681f3Smrgstatic inline unsigned 7577ec681f3Smrgd3dtextureaddress_to_pipe_tex_wrap(D3DTEXTUREADDRESS addr) 7587ec681f3Smrg{ 7597ec681f3Smrg switch (addr) { 7607ec681f3Smrg case D3DTADDRESS_WRAP: return PIPE_TEX_WRAP_REPEAT; 7617ec681f3Smrg case D3DTADDRESS_MIRROR: return PIPE_TEX_WRAP_MIRROR_REPEAT; 7627ec681f3Smrg case D3DTADDRESS_CLAMP: return PIPE_TEX_WRAP_CLAMP_TO_EDGE; 7637ec681f3Smrg case D3DTADDRESS_BORDER: return PIPE_TEX_WRAP_CLAMP_TO_BORDER; 7647ec681f3Smrg case D3DTADDRESS_MIRRORONCE: return PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE; 7657ec681f3Smrg default: 7667ec681f3Smrg assert(0); 7677ec681f3Smrg return PIPE_TEX_WRAP_CLAMP_TO_EDGE; 7687ec681f3Smrg } 7697ec681f3Smrg} 7707ec681f3Smrg 7717ec681f3Smrgstatic inline unsigned 7727ec681f3Smrgd3dtexturefiltertype_to_pipe_tex_filter(D3DTEXTUREFILTERTYPE filter) 7737ec681f3Smrg{ 7747ec681f3Smrg switch (filter) { 7757ec681f3Smrg case D3DTEXF_POINT: return PIPE_TEX_FILTER_NEAREST; 7767ec681f3Smrg case D3DTEXF_LINEAR: return PIPE_TEX_FILTER_LINEAR; 7777ec681f3Smrg case D3DTEXF_ANISOTROPIC: return PIPE_TEX_FILTER_LINEAR; 7787ec681f3Smrg 7797ec681f3Smrg case D3DTEXF_NONE: 7807ec681f3Smrg case D3DTEXF_PYRAMIDALQUAD: 7817ec681f3Smrg case D3DTEXF_GAUSSIANQUAD: 7827ec681f3Smrg case D3DTEXF_CONVOLUTIONMONO: 7837ec681f3Smrg default: 7847ec681f3Smrg assert(0); 7857ec681f3Smrg return PIPE_TEX_FILTER_NEAREST; 7867ec681f3Smrg } 7877ec681f3Smrg} 7887ec681f3Smrg 7897ec681f3Smrgstatic inline unsigned 7907ec681f3Smrgd3dtexturefiltertype_to_pipe_tex_mipfilter(D3DTEXTUREFILTERTYPE filter) 7917ec681f3Smrg{ 7927ec681f3Smrg switch (filter) { 7937ec681f3Smrg case D3DTEXF_NONE: return PIPE_TEX_MIPFILTER_NONE; 7947ec681f3Smrg case D3DTEXF_POINT: return PIPE_TEX_FILTER_NEAREST; 7957ec681f3Smrg case D3DTEXF_LINEAR: return PIPE_TEX_FILTER_LINEAR; 7967ec681f3Smrg case D3DTEXF_ANISOTROPIC: return PIPE_TEX_FILTER_LINEAR; 7977ec681f3Smrg 7987ec681f3Smrg case D3DTEXF_PYRAMIDALQUAD: 7997ec681f3Smrg case D3DTEXF_GAUSSIANQUAD: 8007ec681f3Smrg case D3DTEXF_CONVOLUTIONMONO: 8017ec681f3Smrg default: 8027ec681f3Smrg assert(0); 8037ec681f3Smrg return PIPE_TEX_MIPFILTER_NONE; 8047ec681f3Smrg } 8057ec681f3Smrg} 8067ec681f3Smrg 8077ec681f3Smrgstatic inline unsigned nine_format_get_stride(enum pipe_format format, 8087ec681f3Smrg unsigned width) 8097ec681f3Smrg{ 8107ec681f3Smrg unsigned stride = util_format_get_stride(format, width); 8117ec681f3Smrg 8127ec681f3Smrg return align(stride, 4); 8137ec681f3Smrg} 8147ec681f3Smrg 8157ec681f3Smrgstatic inline unsigned nine_format_get_level_alloc_size(enum pipe_format format, 8167ec681f3Smrg unsigned width, 8177ec681f3Smrg unsigned height, 8187ec681f3Smrg unsigned level) 8197ec681f3Smrg{ 8207ec681f3Smrg unsigned w, h, size; 8217ec681f3Smrg 8227ec681f3Smrg w = u_minify(width, level); 8237ec681f3Smrg h = u_minify(height, level); 8247ec681f3Smrg if (is_ATI1_ATI2(format)) { 8257ec681f3Smrg /* For "unknown" formats like ATIx use width * height bytes */ 8267ec681f3Smrg size = w * h; 8277ec681f3Smrg } else if (format == PIPE_FORMAT_NONE) { /* D3DFMT_NULL */ 8287ec681f3Smrg size = w * h * 4; 8297ec681f3Smrg } else { 8307ec681f3Smrg size = nine_format_get_stride(format, w) * 8317ec681f3Smrg util_format_get_nblocksy(format, h); 8327ec681f3Smrg } 8337ec681f3Smrg 8347ec681f3Smrg return size; 8357ec681f3Smrg} 8367ec681f3Smrg 8377ec681f3Smrgstatic inline unsigned nine_format_get_size_and_offsets(enum pipe_format format, 8387ec681f3Smrg unsigned *offsets, 8397ec681f3Smrg unsigned width, 8407ec681f3Smrg unsigned height, 8417ec681f3Smrg unsigned last_level) 8427ec681f3Smrg{ 8437ec681f3Smrg unsigned l, w, h, size = 0; 8447ec681f3Smrg 8457ec681f3Smrg for (l = 0; l <= last_level; ++l) { 8467ec681f3Smrg w = u_minify(width, l); 8477ec681f3Smrg h = u_minify(height, l); 8487ec681f3Smrg offsets[l] = size; 8497ec681f3Smrg if (is_ATI1_ATI2(format)) { 8507ec681f3Smrg /* For "unknown" formats like ATIx use width * height bytes */ 8517ec681f3Smrg size += w * h; 8527ec681f3Smrg } else { 8537ec681f3Smrg size += nine_format_get_stride(format, w) * 8547ec681f3Smrg util_format_get_nblocksy(format, h); 8557ec681f3Smrg } 8567ec681f3Smrg } 8577ec681f3Smrg 8587ec681f3Smrg return size; 8597ec681f3Smrg} 8607ec681f3Smrg 8617ec681f3Smrg#endif /* _NINE_PIPE_H_ */ 862