ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

utils.c
Go to the documentation of this file.
00001 /*
00002  * Utility functions for the WineD3D Library
00003  *
00004  * Copyright 2002-2004 Jason Edmeades
00005  * Copyright 2003-2004 Raphael Junqueira
00006  * Copyright 2004 Christian Costa
00007  * Copyright 2005 Oliver Stieber
00008  * Copyright 2006-2008 Henri Verbeet
00009  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
00010  * Copyright 2009-2010 Henri Verbeet for CodeWeavers
00011  *
00012  * This library is free software; you can redistribute it and/or
00013  * modify it under the terms of the GNU Lesser General Public
00014  * License as published by the Free Software Foundation; either
00015  * version 2.1 of the License, or (at your option) any later version.
00016  *
00017  * This library is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  * Lesser General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU Lesser General Public
00023  * License along with this library; if not, write to the Free Software
00024  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00025  */
00026 
00027 #include "config.h"
00028 #include "wined3d_private.h"
00029 
00030 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
00031 
00032 struct StaticPixelFormatDesc
00033 {
00034     enum wined3d_format_id id;
00035     DWORD alphaMask, redMask, greenMask, blueMask;
00036     UINT bpp;
00037     BYTE depthSize, stencilSize;
00038 };
00039 
00040 /*****************************************************************************
00041  * Pixel format array
00042  *
00043  * For the formats WINED3DFMT_A32B32G32R32F, WINED3DFMT_A16B16G16R16F,
00044  * and WINED3DFMT_A16B16G16R16 do not have correct alpha masks, because the
00045  * high masks do not fit into the 32 bit values needed for ddraw. It is only
00046  * used for ddraw mostly, and to figure out if the format has alpha at all, so
00047  * setting a mask like 0x1 for those surfaces is correct. The 64 and 128 bit
00048  * formats are not usable in 2D rendering because ddraw doesn't support them.
00049  */
00050 static const struct StaticPixelFormatDesc formats[] =
00051 {
00052   /* format id                           alphamask    redmask    greenmask    bluemask     bpp    depth  stencil */
00053     {WINED3DFMT_UNKNOWN,                    0x0,        0x0,        0x0,        0x0,        0,      0,      0},
00054     /* FourCC formats */
00055     {WINED3DFMT_UYVY,                       0x0,        0x0,        0x0,        0x0,        2,      0,      0},
00056     {WINED3DFMT_YUY2,                       0x0,        0x0,        0x0,        0x0,        2,      0,      0},
00057     {WINED3DFMT_YV12,                       0x0,        0x0,        0x0,        0x0,        1,      0,      0},
00058     {WINED3DFMT_DXT1,                       0x0,        0x0,        0x0,        0x0,        1,      0,      0},
00059     {WINED3DFMT_DXT2,                       0x0,        0x0,        0x0,        0x0,        1,      0,      0},
00060     {WINED3DFMT_DXT3,                       0x0,        0x0,        0x0,        0x0,        1,      0,      0},
00061     {WINED3DFMT_DXT4,                       0x0,        0x0,        0x0,        0x0,        1,      0,      0},
00062     {WINED3DFMT_DXT5,                       0x0,        0x0,        0x0,        0x0,        1,      0,      0},
00063     {WINED3DFMT_MULTI2_ARGB8,               0x0,        0x0,        0x0,        0x0,        1/*?*/, 0,      0},
00064     {WINED3DFMT_G8R8_G8B8,                  0x0,        0x0,        0x0,        0x0,        1/*?*/, 0,      0},
00065     {WINED3DFMT_R8G8_B8G8,                  0x0,        0x0,        0x0,        0x0,        1/*?*/, 0,      0},
00066     /* IEEE formats */
00067     {WINED3DFMT_R32_FLOAT,                  0x0,        0x0,        0x0,        0x0,        4,      0,      0},
00068     {WINED3DFMT_R32G32_FLOAT,               0x0,        0x0,        0x0,        0x0,        8,      0,      0},
00069     {WINED3DFMT_R32G32B32_FLOAT,            0x0,        0x0,        0x0,        0x0,        12,     0,      0},
00070     {WINED3DFMT_R32G32B32A32_FLOAT,         0x1,        0x0,        0x0,        0x0,        16,     0,      0},
00071     /* Hmm? */
00072     {WINED3DFMT_R8G8_SNORM_Cx,              0x0,        0x0,        0x0,        0x0,        2,      0,      0},
00073     /* Float */
00074     {WINED3DFMT_R16_FLOAT,                  0x0,        0x0,        0x0,        0x0,        2,      0,      0},
00075     {WINED3DFMT_R16G16_FLOAT,               0x0,        0x0,        0x0,        0x0,        4,      0,      0},
00076     {WINED3DFMT_R16G16_SINT,                0x0,        0x0,        0x0,        0x0,        4,      0,      0},
00077     {WINED3DFMT_R16G16B16A16_FLOAT,         0x1,        0x0,        0x0,        0x0,        8,      0,      0},
00078     {WINED3DFMT_R16G16B16A16_SINT,          0x1,        0x0,        0x0,        0x0,        8,      0,      0},
00079     /* Palettized formats */
00080     {WINED3DFMT_P8_UINT_A8_UNORM,           0x0000ff00, 0x0,        0x0,        0x0,        2,      0,      0},
00081     {WINED3DFMT_P8_UINT,                    0x0,        0x0,        0x0,        0x0,        1,      0,      0},
00082     /* Standard ARGB formats. */
00083     {WINED3DFMT_B8G8R8_UNORM,               0x0,        0x00ff0000, 0x0000ff00, 0x000000ff, 3,      0,      0},
00084     {WINED3DFMT_B8G8R8A8_UNORM,             0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 4,      0,      0},
00085     {WINED3DFMT_B8G8R8X8_UNORM,             0x0,        0x00ff0000, 0x0000ff00, 0x000000ff, 4,      0,      0},
00086     {WINED3DFMT_B5G6R5_UNORM,               0x0,        0x0000f800, 0x000007e0, 0x0000001f, 2,      0,      0},
00087     {WINED3DFMT_B5G5R5X1_UNORM,             0x0,        0x00007c00, 0x000003e0, 0x0000001f, 2,      0,      0},
00088     {WINED3DFMT_B5G5R5A1_UNORM,             0x00008000, 0x00007c00, 0x000003e0, 0x0000001f, 2,      0,      0},
00089     {WINED3DFMT_B4G4R4A4_UNORM,             0x0000f000, 0x00000f00, 0x000000f0, 0x0000000f, 2,      0,      0},
00090     {WINED3DFMT_B2G3R3_UNORM,               0x0,        0x000000e0, 0x0000001c, 0x00000003, 1,      0,      0},
00091     {WINED3DFMT_A8_UNORM,                   0x000000ff, 0x0,        0x0,        0x0,        1,      0,      0},
00092     {WINED3DFMT_B2G3R3A8_UNORM,             0x0000ff00, 0x000000e0, 0x0000001c, 0x00000003, 2,      0,      0},
00093     {WINED3DFMT_B4G4R4X4_UNORM,             0x0,        0x00000f00, 0x000000f0, 0x0000000f, 2,      0,      0},
00094     {WINED3DFMT_R10G10B10A2_UNORM,          0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4,      0,      0},
00095     {WINED3DFMT_R10G10B10A2_UINT,           0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4,      0,      0},
00096     {WINED3DFMT_R10G10B10A2_SNORM,          0xc0000000, 0x000003ff, 0x000ffc00, 0x3ff00000, 4,      0,      0},
00097     {WINED3DFMT_R8G8B8A8_UNORM,             0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4,      0,      0},
00098     {WINED3DFMT_R8G8B8A8_UINT,              0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4,      0,      0},
00099     {WINED3DFMT_R8G8B8X8_UNORM,             0x0,        0x000000ff, 0x0000ff00, 0x00ff0000, 4,      0,      0},
00100     {WINED3DFMT_R16G16_UNORM,               0x0,        0x0000ffff, 0xffff0000, 0x0,        4,      0,      0},
00101     {WINED3DFMT_B10G10R10A2_UNORM,          0xc0000000, 0x3ff00000, 0x000ffc00, 0x000003ff, 4,      0,      0},
00102     {WINED3DFMT_R16G16B16A16_UNORM,         0x1,        0x0000ffff, 0xffff0000, 0x0,        8,      0,      0},
00103     /* Luminance */
00104     {WINED3DFMT_L8_UNORM,                   0x0,        0x0,        0x0,        0x0,        1,      0,      0},
00105     {WINED3DFMT_L8A8_UNORM,                 0x0000ff00, 0x0,        0x0,        0x0,        2,      0,      0},
00106     {WINED3DFMT_L4A4_UNORM,                 0x000000f0, 0x0,        0x0,        0x0,        1,      0,      0},
00107     {WINED3DFMT_L16_UNORM,                  0x0,        0x0,        0x0,        0x0,        2,      16,     0},
00108     /* Bump mapping stuff */
00109     {WINED3DFMT_R8G8_SNORM,                 0x0,        0x0,        0x0,        0x0,        2,      0,      0},
00110     {WINED3DFMT_R5G5_SNORM_L6_UNORM,        0x0,        0x0,        0x0,        0x0,        2,      0,      0},
00111     {WINED3DFMT_R8G8_SNORM_L8X8_UNORM,      0x0,        0x0,        0x0,        0x0,        4,      0,      0},
00112     {WINED3DFMT_R8G8B8A8_SNORM,             0x0,        0x0,        0x0,        0x0,        4,      0,      0},
00113     {WINED3DFMT_R16G16_SNORM,               0x0,        0x0,        0x0,        0x0,        4,      0,      0},
00114     {WINED3DFMT_R10G11B11_SNORM,            0x0,        0x0,        0x0,        0x0,        4,      0,      0},
00115     {WINED3DFMT_R10G10B10_SNORM_A2_UNORM,   0xb0000000, 0x0,        0x0,        0x0,        4,      0,      0},
00116     /* Depth stencil formats */
00117     {WINED3DFMT_D16_LOCKABLE,               0x0,        0x0,        0x0,        0x0,        2,      16,     0},
00118     {WINED3DFMT_D32_UNORM,                  0x0,        0x0,        0x0,        0x0,        4,      32,     0},
00119     {WINED3DFMT_S1_UINT_D15_UNORM,          0x0,        0x0,        0x0,        0x0,        2,      15,     1},
00120     {WINED3DFMT_D24_UNORM_S8_UINT,          0x0,        0x0,        0x0,        0x0,        4,      24,     8},
00121     {WINED3DFMT_X8D24_UNORM,                0x0,        0x0,        0x0,        0x0,        4,      24,     0},
00122     {WINED3DFMT_S4X4_UINT_D24_UNORM,        0x0,        0x0,        0x0,        0x0,        4,      24,     4},
00123     {WINED3DFMT_D16_UNORM,                  0x0,        0x0,        0x0,        0x0,        2,      16,     0},
00124     {WINED3DFMT_D32_FLOAT,                  0x0,        0x0,        0x0,        0x0,        4,      32,     0},
00125     {WINED3DFMT_S8_UINT_D24_FLOAT,          0x0,        0x0,        0x0,        0x0,        4,      24,     8},
00126     {WINED3DFMT_VERTEXDATA,                 0x0,        0x0,        0x0,        0x0,        0,      0,      0},
00127     {WINED3DFMT_R16_UINT,                   0x0,        0x0,        0x0,        0x0,        2,      0,      0},
00128     {WINED3DFMT_R32_UINT,                   0x0,        0x0,        0x0,        0x0,        4,      0,      0},
00129     {WINED3DFMT_R16G16B16A16_SNORM,         0x0,        0x0,        0x0,        0x0,        8,      0,      0},
00130     /* Vendor-specific formats */
00131     {WINED3DFMT_ATI2N,                      0x0,        0x0,        0x0,        0x0,        1,      0,      0},
00132     {WINED3DFMT_NVDB,                       0x0,        0x0,        0x0,        0x0,        0,      0,      0},
00133     {WINED3DFMT_INTZ,                       0x0,        0x0,        0x0,        0x0,        4,      24,     8},
00134     {WINED3DFMT_NVHU,                       0x0,        0x0,        0x0,        0x0,        2,      0,      0},
00135     {WINED3DFMT_NVHS,                       0x0,        0x0,        0x0,        0x0,        2,      0,      0},
00136     {WINED3DFMT_NULL,                       0xff000000, 0x000000ff, 0x0000ff00, 0x00ff0000, 4,      0,      0},
00137     /* Unsure about them, could not find a Windows driver that supports them */
00138     {WINED3DFMT_R16,                        0x0,        0x0000ffff, 0x0,        0x0,        2,      0,      0},
00139     {WINED3DFMT_AL16,                       0xffff0000, 0x0,        0x0,        0x0,        4,      0,      0},
00140 };
00141 
00142 struct wined3d_format_base_flags
00143 {
00144     enum wined3d_format_id id;
00145     DWORD flags;
00146 };
00147 
00148 /* The ATI2N format behaves like an uncompressed format in LockRect(), but
00149  * still needs to use the correct block based calculation for e.g. the
00150  * resource size. */
00151 static const struct wined3d_format_base_flags format_base_flags[] =
00152 {
00153     {WINED3DFMT_UYVY,               WINED3DFMT_FLAG_FOURCC},
00154     {WINED3DFMT_YUY2,               WINED3DFMT_FLAG_FOURCC},
00155     {WINED3DFMT_YV12,               WINED3DFMT_FLAG_FOURCC},
00156     {WINED3DFMT_DXT1,               WINED3DFMT_FLAG_FOURCC},
00157     {WINED3DFMT_DXT2,               WINED3DFMT_FLAG_FOURCC},
00158     {WINED3DFMT_DXT3,               WINED3DFMT_FLAG_FOURCC},
00159     {WINED3DFMT_DXT4,               WINED3DFMT_FLAG_FOURCC},
00160     {WINED3DFMT_DXT5,               WINED3DFMT_FLAG_FOURCC},
00161     {WINED3DFMT_MULTI2_ARGB8,       WINED3DFMT_FLAG_FOURCC},
00162     {WINED3DFMT_G8R8_G8B8,          WINED3DFMT_FLAG_FOURCC},
00163     {WINED3DFMT_R8G8_B8G8,          WINED3DFMT_FLAG_FOURCC},
00164     {WINED3DFMT_INTZ,               WINED3DFMT_FLAG_FOURCC},
00165     {WINED3DFMT_NULL,               WINED3DFMT_FLAG_FOURCC},
00166     {WINED3DFMT_P8_UINT,            WINED3DFMT_FLAG_GETDC},
00167     {WINED3DFMT_B8G8R8_UNORM,       WINED3DFMT_FLAG_GETDC},
00168     {WINED3DFMT_B8G8R8A8_UNORM,     WINED3DFMT_FLAG_GETDC},
00169     {WINED3DFMT_B8G8R8X8_UNORM,     WINED3DFMT_FLAG_GETDC},
00170     {WINED3DFMT_B5G6R5_UNORM,       WINED3DFMT_FLAG_GETDC},
00171     {WINED3DFMT_B5G5R5X1_UNORM,     WINED3DFMT_FLAG_GETDC},
00172     {WINED3DFMT_B5G5R5A1_UNORM,     WINED3DFMT_FLAG_GETDC},
00173     {WINED3DFMT_B4G4R4A4_UNORM,     WINED3DFMT_FLAG_GETDC},
00174     {WINED3DFMT_B4G4R4X4_UNORM,     WINED3DFMT_FLAG_GETDC},
00175     {WINED3DFMT_R8G8B8A8_UNORM,     WINED3DFMT_FLAG_GETDC},
00176     {WINED3DFMT_R8G8B8X8_UNORM,     WINED3DFMT_FLAG_GETDC},
00177     {WINED3DFMT_ATI2N,              WINED3DFMT_FLAG_FOURCC | WINED3DFMT_FLAG_BROKEN_PITCH},
00178     {WINED3DFMT_NVDB,               WINED3DFMT_FLAG_FOURCC},
00179     {WINED3DFMT_NVHU,               WINED3DFMT_FLAG_FOURCC},
00180     {WINED3DFMT_NVHS,               WINED3DFMT_FLAG_FOURCC},
00181     {WINED3DFMT_R32_FLOAT,          WINED3DFMT_FLAG_FLOAT},
00182     {WINED3DFMT_R32G32_FLOAT,       WINED3DFMT_FLAG_FLOAT},
00183     {WINED3DFMT_R32G32B32_FLOAT,    WINED3DFMT_FLAG_FLOAT},
00184     {WINED3DFMT_R32G32B32A32_FLOAT, WINED3DFMT_FLAG_FLOAT},
00185     {WINED3DFMT_R16_FLOAT,          WINED3DFMT_FLAG_FLOAT},
00186     {WINED3DFMT_R16G16_FLOAT,       WINED3DFMT_FLAG_FLOAT},
00187     {WINED3DFMT_R16G16B16A16_FLOAT, WINED3DFMT_FLAG_FLOAT},
00188     {WINED3DFMT_D32_FLOAT,          WINED3DFMT_FLAG_FLOAT},
00189     {WINED3DFMT_S8_UINT_D24_FLOAT,  WINED3DFMT_FLAG_FLOAT},
00190 };
00191 
00192 struct wined3d_format_block_info
00193 {
00194     enum wined3d_format_id id;
00195     UINT block_width;
00196     UINT block_height;
00197     UINT block_byte_count;
00198 };
00199 
00200 static const struct wined3d_format_block_info format_block_info[] =
00201 {
00202     {WINED3DFMT_DXT1,   4,  4,  8},
00203     {WINED3DFMT_DXT2,   4,  4,  16},
00204     {WINED3DFMT_DXT3,   4,  4,  16},
00205     {WINED3DFMT_DXT4,   4,  4,  16},
00206     {WINED3DFMT_DXT5,   4,  4,  16},
00207     {WINED3DFMT_ATI2N,  4,  4,  16},
00208     {WINED3DFMT_YUY2,   2,  1,  4},
00209     {WINED3DFMT_UYVY,   2,  1,  4},
00210 };
00211 
00212 struct wined3d_format_vertex_info
00213 {
00214     enum wined3d_format_id id;
00215     enum wined3d_ffp_emit_idx emit_idx;
00216     GLint component_count;
00217     GLenum gl_vtx_type;
00218     GLint gl_vtx_format;
00219     GLboolean gl_normalized;
00220     unsigned int component_size;
00221 };
00222 
00223 static const struct wined3d_format_vertex_info format_vertex_info[] =
00224 {
00225     {WINED3DFMT_R32_FLOAT,          WINED3D_FFP_EMIT_FLOAT1,    1, GL_FLOAT,          1, GL_FALSE, sizeof(float)},
00226     {WINED3DFMT_R32G32_FLOAT,       WINED3D_FFP_EMIT_FLOAT2,    2, GL_FLOAT,          2, GL_FALSE, sizeof(float)},
00227     {WINED3DFMT_R32G32B32_FLOAT,    WINED3D_FFP_EMIT_FLOAT3,    3, GL_FLOAT,          3, GL_FALSE, sizeof(float)},
00228     {WINED3DFMT_R32G32B32A32_FLOAT, WINED3D_FFP_EMIT_FLOAT4,    4, GL_FLOAT,          4, GL_FALSE, sizeof(float)},
00229     {WINED3DFMT_B8G8R8A8_UNORM,     WINED3D_FFP_EMIT_D3DCOLOR,  4, GL_UNSIGNED_BYTE,  4, GL_TRUE,  sizeof(BYTE)},
00230     {WINED3DFMT_R8G8B8A8_UINT,      WINED3D_FFP_EMIT_UBYTE4,    4, GL_UNSIGNED_BYTE,  4, GL_FALSE, sizeof(BYTE)},
00231     {WINED3DFMT_R16G16_SINT,        WINED3D_FFP_EMIT_SHORT2,    2, GL_SHORT,          2, GL_FALSE, sizeof(short int)},
00232     {WINED3DFMT_R16G16B16A16_SINT,  WINED3D_FFP_EMIT_SHORT4,    4, GL_SHORT,          4, GL_FALSE, sizeof(short int)},
00233     {WINED3DFMT_R8G8B8A8_UNORM,     WINED3D_FFP_EMIT_UBYTE4N,   4, GL_UNSIGNED_BYTE,  4, GL_TRUE,  sizeof(BYTE)},
00234     {WINED3DFMT_R16G16_SNORM,       WINED3D_FFP_EMIT_SHORT2N,   2, GL_SHORT,          2, GL_TRUE,  sizeof(short int)},
00235     {WINED3DFMT_R16G16B16A16_SNORM, WINED3D_FFP_EMIT_SHORT4N,   4, GL_SHORT,          4, GL_TRUE,  sizeof(short int)},
00236     {WINED3DFMT_R16G16_UNORM,       WINED3D_FFP_EMIT_USHORT2N,  2, GL_UNSIGNED_SHORT, 2, GL_TRUE,  sizeof(short int)},
00237     {WINED3DFMT_R16G16B16A16_UNORM, WINED3D_FFP_EMIT_USHORT4N,  4, GL_UNSIGNED_SHORT, 4, GL_TRUE,  sizeof(short int)},
00238     {WINED3DFMT_R10G10B10A2_UINT,   WINED3D_FFP_EMIT_UDEC3,     3, GL_UNSIGNED_SHORT, 3, GL_FALSE, sizeof(short int)},
00239     {WINED3DFMT_R10G10B10A2_SNORM,  WINED3D_FFP_EMIT_DEC3N,     3, GL_SHORT,          3, GL_TRUE,  sizeof(short int)},
00240     {WINED3DFMT_R16G16_FLOAT,       WINED3D_FFP_EMIT_FLOAT16_2, 2, GL_FLOAT,          2, GL_FALSE, sizeof(GLhalfNV)},
00241     {WINED3DFMT_R16G16B16A16_FLOAT, WINED3D_FFP_EMIT_FLOAT16_4, 4, GL_FLOAT,          4, GL_FALSE, sizeof(GLhalfNV)}
00242 };
00243 
00244 struct wined3d_format_texture_info
00245 {
00246     enum wined3d_format_id id;
00247     GLint gl_internal;
00248     GLint gl_srgb_internal;
00249     GLint gl_rt_internal;
00250     GLint gl_format;
00251     GLint gl_type;
00252     unsigned int conv_byte_count;
00253     unsigned int flags;
00254     enum wined3d_gl_extension extension;
00255     void (*convert)(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height);
00256 };
00257 
00258 static void convert_l4a4_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
00259 {
00260     /* WINED3DFMT_L4A4_UNORM exists as an internal gl format, but for some reason there is not
00261      * format+type combination to load it. Thus convert it to A8L8, then load it
00262      * with A4L4 internal, but A8L8 format+type
00263      */
00264     unsigned int x, y;
00265     const unsigned char *Source;
00266     unsigned char *Dest;
00267     UINT outpitch = pitch * 2;
00268 
00269     for(y = 0; y < height; y++) {
00270         Source = src + y * pitch;
00271         Dest = dst + y * outpitch;
00272         for (x = 0; x < width; x++ ) {
00273             unsigned char color = (*Source++);
00274             /* A */ Dest[1] = (color & 0xf0) << 0;
00275             /* L */ Dest[0] = (color & 0x0f) << 4;
00276             Dest += 2;
00277         }
00278     }
00279 }
00280 
00281 static void convert_r5g5_snorm_l6_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
00282 {
00283     unsigned int x, y;
00284     const WORD *Source;
00285 
00286     for(y = 0; y < height; y++)
00287     {
00288         unsigned short *Dest_s = (unsigned short *) (dst + y * pitch);
00289         Source = (const WORD *)(src + y * pitch);
00290         for (x = 0; x < width; x++ )
00291         {
00292             short color = (*Source++);
00293             unsigned char l = ((color >> 10) & 0xfc);
00294                     short v = ((color >>  5) & 0x3e);
00295                     short u = ((color      ) & 0x1f);
00296             short v_conv = v + 16;
00297             short u_conv = u + 16;
00298 
00299             *Dest_s = ((v_conv << 11) & 0xf800) | ((l << 5) & 0x7e0) | (u_conv & 0x1f);
00300             Dest_s += 1;
00301         }
00302     }
00303 }
00304 
00305 static void convert_r5g5_snorm_l6_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
00306 {
00307     unsigned int x, y;
00308     const WORD *Source;
00309     unsigned char *Dest;
00310     UINT outpitch = (pitch * 3)/2;
00311 
00312     /* This makes the gl surface bigger(24 bit instead of 16), but it works with
00313      * fixed function and shaders without further conversion once the surface is
00314      * loaded
00315      */
00316     for(y = 0; y < height; y++) {
00317         Source = (const WORD *)(src + y * pitch);
00318         Dest = dst + y * outpitch;
00319         for (x = 0; x < width; x++ ) {
00320             short color = (*Source++);
00321             unsigned char l = ((color >> 10) & 0xfc);
00322                      char v = ((color >>  5) & 0x3e);
00323                      char u = ((color      ) & 0x1f);
00324 
00325             /* 8 bits destination, 6 bits source, 8th bit is the sign. gl ignores the sign
00326              * and doubles the positive range. Thus shift left only once, gl does the 2nd
00327              * shift. GL reads a signed value and converts it into an unsigned value.
00328              */
00329             /* M */ Dest[2] = l << 1;
00330 
00331             /* Those are read as signed, but kept signed. Just left-shift 3 times to scale
00332              * from 5 bit values to 8 bit values.
00333              */
00334             /* V */ Dest[1] = v << 3;
00335             /* U */ Dest[0] = u << 3;
00336             Dest += 3;
00337         }
00338     }
00339 }
00340 
00341 static void convert_r8g8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
00342 {
00343     unsigned int x, y;
00344     const short *Source;
00345     unsigned char *Dest;
00346     UINT outpitch = (pitch * 3)/2;
00347 
00348     for(y = 0; y < height; y++)
00349     {
00350         Source = (const short *)(src + y * pitch);
00351         Dest = dst + y * outpitch;
00352         for (x = 0; x < width; x++ )
00353         {
00354             const short color = (*Source++);
00355             /* B */ Dest[0] = 0xff;
00356             /* G */ Dest[1] = (color >> 8) + 128; /* V */
00357             /* R */ Dest[2] = (color & 0xff) + 128;      /* U */
00358             Dest += 3;
00359         }
00360     }
00361 }
00362 
00363 static void convert_r8g8_snorm_l8x8_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
00364 {
00365     unsigned int x, y;
00366     const DWORD *Source;
00367     unsigned char *Dest;
00368 
00369     /* Doesn't work correctly with the fixed function pipeline, but can work in
00370      * shaders if the shader is adjusted. (There's no use for this format in gl's
00371      * standard fixed function pipeline anyway).
00372      */
00373     for(y = 0; y < height; y++)
00374     {
00375         Source = (const DWORD *)(src + y * pitch);
00376         Dest = dst + y * pitch;
00377         for (x = 0; x < width; x++ )
00378         {
00379             LONG color = (*Source++);
00380             /* B */ Dest[0] = ((color >> 16) & 0xff);       /* L */
00381             /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
00382             /* R */ Dest[2] = (color         & 0xff) + 128; /* U */
00383             Dest += 4;
00384         }
00385     }
00386 }
00387 
00388 static void convert_r8g8_snorm_l8x8_unorm_nv(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
00389 {
00390     unsigned int x, y;
00391     const DWORD *Source;
00392     unsigned char *Dest;
00393 
00394     /* This implementation works with the fixed function pipeline and shaders
00395      * without further modification after converting the surface.
00396      */
00397     for(y = 0; y < height; y++)
00398     {
00399         Source = (const DWORD *)(src + y * pitch);
00400         Dest = dst + y * pitch;
00401         for (x = 0; x < width; x++ )
00402         {
00403             LONG color = (*Source++);
00404             /* L */ Dest[2] = ((color >> 16) & 0xff);   /* L */
00405             /* V */ Dest[1] = ((color >> 8 ) & 0xff);   /* V */
00406             /* U */ Dest[0] = (color         & 0xff);   /* U */
00407             /* I */ Dest[3] = 255;                      /* X */
00408             Dest += 4;
00409         }
00410     }
00411 }
00412 
00413 static void convert_r8g8b8a8_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
00414 {
00415     unsigned int x, y;
00416     const DWORD *Source;
00417     unsigned char *Dest;
00418 
00419     for(y = 0; y < height; y++)
00420     {
00421         Source = (const DWORD *)(src + y * pitch);
00422         Dest = dst + y * pitch;
00423         for (x = 0; x < width; x++ )
00424         {
00425             LONG color = (*Source++);
00426             /* B */ Dest[0] = ((color >> 16) & 0xff) + 128; /* W */
00427             /* G */ Dest[1] = ((color >> 8 ) & 0xff) + 128; /* V */
00428             /* R */ Dest[2] = (color         & 0xff) + 128; /* U */
00429             /* A */ Dest[3] = ((color >> 24) & 0xff) + 128; /* Q */
00430             Dest += 4;
00431         }
00432     }
00433 }
00434 
00435 static void convert_r16g16_snorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
00436 {
00437     unsigned int x, y;
00438     const DWORD *Source;
00439     unsigned short *Dest;
00440     UINT outpitch = (pitch * 3)/2;
00441 
00442     for(y = 0; y < height; y++)
00443     {
00444         Source = (const DWORD *)(src + y * pitch);
00445         Dest = (unsigned short *) (dst + y * outpitch);
00446         for (x = 0; x < width; x++ )
00447         {
00448             const DWORD color = (*Source++);
00449             /* B */ Dest[0] = 0xffff;
00450             /* G */ Dest[1] = (color >> 16) + 32768; /* V */
00451             /* R */ Dest[2] = (color & 0xffff) + 32768; /* U */
00452             Dest += 3;
00453         }
00454     }
00455 }
00456 
00457 static void convert_r16g16(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
00458 {
00459     unsigned int x, y;
00460     const WORD *Source;
00461     WORD *Dest;
00462     UINT outpitch = (pitch * 3)/2;
00463 
00464     for(y = 0; y < height; y++)
00465     {
00466         Source = (const WORD *)(src + y * pitch);
00467         Dest = (WORD *) (dst + y * outpitch);
00468         for (x = 0; x < width; x++ )
00469         {
00470             WORD green = (*Source++);
00471             WORD red = (*Source++);
00472             Dest[0] = green;
00473             Dest[1] = red;
00474             /* Strictly speaking not correct for R16G16F, but it doesn't matter because the
00475              * shader overwrites it anyway
00476              */
00477             Dest[2] = 0xffff;
00478             Dest += 3;
00479         }
00480     }
00481 }
00482 
00483 static void convert_r32g32_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
00484 {
00485     unsigned int x, y;
00486     const float *Source;
00487     float *Dest;
00488     UINT outpitch = (pitch * 3)/2;
00489 
00490     for(y = 0; y < height; y++)
00491     {
00492         Source = (const float *)(src + y * pitch);
00493         Dest = (float *) (dst + y * outpitch);
00494         for (x = 0; x < width; x++ )
00495         {
00496             float green = (*Source++);
00497             float red = (*Source++);
00498             Dest[0] = green;
00499             Dest[1] = red;
00500             Dest[2] = 1.0f;
00501             Dest += 3;
00502         }
00503     }
00504 }
00505 
00506 static void convert_s1_uint_d15_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
00507 {
00508     unsigned int x, y;
00509     UINT outpitch = pitch * 2;
00510 
00511     for (y = 0; y < height; ++y)
00512     {
00513         const WORD *source = (const WORD *)(src + y * pitch);
00514         DWORD *dest = (DWORD *)(dst + y * outpitch);
00515 
00516         for (x = 0; x < width; ++x)
00517         {
00518             /* The depth data is normalized, so needs to be scaled,
00519              * the stencil data isn't.  Scale depth data by
00520              *      (2^24-1)/(2^15-1) ~~ (2^9 + 2^-6). */
00521             WORD d15 = source[x] >> 1;
00522             DWORD d24 = (d15 << 9) + (d15 >> 6);
00523             dest[x] = (d24 << 8) | (source[x] & 0x1);
00524         }
00525     }
00526 }
00527 
00528 static void convert_s4x4_uint_d24_unorm(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
00529 {
00530     unsigned int x, y;
00531 
00532     for (y = 0; y < height; ++y)
00533     {
00534         const DWORD *source = (const DWORD *)(src + y * pitch);
00535         DWORD *dest = (DWORD *)(dst + y * pitch);
00536 
00537         for (x = 0; x < width; ++x)
00538         {
00539             /* Just need to clear out the X4 part. */
00540             dest[x] = source[x] & ~0xf0;
00541         }
00542     }
00543 }
00544 
00545 static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT pitch, UINT width, UINT height)
00546 {
00547     unsigned int x, y;
00548     UINT outpitch = pitch * 2;
00549 
00550     for (y = 0; y < height; ++y)
00551     {
00552         const DWORD *source = (const DWORD *)(src + y * pitch);
00553         float *dest_f = (float *)(dst + y * outpitch);
00554         DWORD *dest_s = (DWORD *)(dst + y * outpitch);
00555 
00556         for (x = 0; x < width; ++x)
00557         {
00558             dest_f[x * 2] = float_24_to_32((source[x] & 0xffffff00) >> 8);
00559             dest_s[x * 2 + 1] = source[x] & 0xff;
00560         }
00561     }
00562 }
00563 
00564 static const struct wined3d_format_texture_info format_texture_info[] =
00565 {
00566     /* format id                        internal                          srgbInternal                       rtInternal
00567             format                      type
00568             flags
00569             extension */
00570     /* FourCC formats */
00571     /* GL_APPLE_ycbcr_422 claims that its '2YUV' format, which is supported via the UNSIGNED_SHORT_8_8_REV_APPLE type
00572      * is equivalent to 'UYVY' format on Windows, and the 'YUVS' via UNSIGNED_SHORT_8_8_APPLE equates to 'YUY2'. The
00573      * d3d9 test however shows that the opposite is true. Since the extension is from 2002, it predates the x86 based
00574      * Macs, so probably the endianness differs. This could be tested as soon as we have a Windows and MacOS on a big
00575      * endian machine
00576      */
00577     {WINED3DFMT_UYVY,                   GL_LUMINANCE_ALPHA,               GL_LUMINANCE_ALPHA,                     0,
00578             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
00579             WINED3DFMT_FLAG_FILTERING,
00580             WINED3D_GL_EXT_NONE,        NULL},
00581     {WINED3DFMT_UYVY,                   GL_RGB,                           GL_RGB,                                 0,
00582             GL_YCBCR_422_APPLE,         UNSIGNED_SHORT_8_8_APPLE,         0,
00583             WINED3DFMT_FLAG_FILTERING,
00584             APPLE_YCBCR_422,            NULL},
00585     {WINED3DFMT_YUY2,                   GL_LUMINANCE_ALPHA,               GL_LUMINANCE_ALPHA,                     0,
00586             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
00587             WINED3DFMT_FLAG_FILTERING,
00588             WINED3D_GL_EXT_NONE,        NULL},
00589     {WINED3DFMT_YUY2,                   GL_RGB,                           GL_RGB,                                 0,
00590             GL_YCBCR_422_APPLE,         UNSIGNED_SHORT_8_8_REV_APPLE,     0,
00591             WINED3DFMT_FLAG_FILTERING,
00592             APPLE_YCBCR_422,            NULL},
00593     {WINED3DFMT_YV12,                   GL_ALPHA,                         GL_ALPHA,                               0,
00594             GL_ALPHA,                   GL_UNSIGNED_BYTE,                 0,
00595             WINED3DFMT_FLAG_FILTERING,
00596             WINED3D_GL_EXT_NONE,        NULL},
00597     {WINED3DFMT_DXT1,                   GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
00598             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
00599             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
00600             | WINED3DFMT_FLAG_COMPRESSED,
00601             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
00602     {WINED3DFMT_DXT2,                   GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
00603             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
00604             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
00605             | WINED3DFMT_FLAG_COMPRESSED,
00606             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
00607     {WINED3DFMT_DXT3,                   GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
00608             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
00609             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
00610             | WINED3DFMT_FLAG_COMPRESSED,
00611             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
00612     {WINED3DFMT_DXT4,                   GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
00613             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
00614             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
00615             | WINED3DFMT_FLAG_COMPRESSED,
00616             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
00617     {WINED3DFMT_DXT5,                   GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
00618             GL_RGBA,                    GL_UNSIGNED_BYTE,                 0,
00619             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ
00620             | WINED3DFMT_FLAG_COMPRESSED,
00621             EXT_TEXTURE_COMPRESSION_S3TC, NULL},
00622     /* IEEE formats */
00623     {WINED3DFMT_R32_FLOAT,              GL_RGB32F_ARB,                    GL_RGB32F_ARB,                          0,
00624             GL_RED,                     GL_FLOAT,                         0,
00625             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
00626             ARB_TEXTURE_FLOAT,          NULL},
00627     {WINED3DFMT_R32_FLOAT,              GL_R32F,                          GL_R32F,                                0,
00628             GL_RED,                     GL_FLOAT,                         0,
00629             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
00630             ARB_TEXTURE_RG,             NULL},
00631     {WINED3DFMT_R32G32_FLOAT,           GL_RGB32F_ARB,                    GL_RGB32F_ARB,                          0,
00632             GL_RGB,                     GL_FLOAT,                         12,
00633             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
00634             ARB_TEXTURE_FLOAT,          convert_r32g32_float},
00635     {WINED3DFMT_R32G32_FLOAT,           GL_RG32F,                         GL_RG32F,                               0,
00636             GL_RG,                      GL_FLOAT,                         0,
00637             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
00638             ARB_TEXTURE_RG,             NULL},
00639     {WINED3DFMT_R32G32B32A32_FLOAT,     GL_RGBA32F_ARB,                   GL_RGBA32F_ARB,                         0,
00640             GL_RGBA,                    GL_FLOAT,                         0,
00641             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
00642             ARB_TEXTURE_FLOAT,          NULL},
00643     /* Float */
00644     {WINED3DFMT_R16_FLOAT,              GL_RGB16F_ARB,                    GL_RGB16F_ARB,                          0,
00645             GL_RED,                     GL_HALF_FLOAT_ARB,                0,
00646             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
00647             ARB_TEXTURE_FLOAT,          NULL},
00648     {WINED3DFMT_R16_FLOAT,              GL_R16F,                          GL_R16F,                                0,
00649             GL_RED,                     GL_HALF_FLOAT_ARB,                0,
00650             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
00651             ARB_TEXTURE_RG,             NULL},
00652     {WINED3DFMT_R16G16_FLOAT,           GL_RGB16F_ARB,                    GL_RGB16F_ARB,                          0,
00653             GL_RGB,                     GL_HALF_FLOAT_ARB,                6,
00654             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
00655             ARB_TEXTURE_FLOAT,          convert_r16g16},
00656     {WINED3DFMT_R16G16_FLOAT,           GL_RG16F,                         GL_RG16F,                               0,
00657             GL_RG,                      GL_HALF_FLOAT_ARB,                0,
00658             WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
00659             ARB_TEXTURE_RG,             NULL},
00660     {WINED3DFMT_R16G16B16A16_FLOAT,     GL_RGBA16F_ARB,                   GL_RGBA16F_ARB,                         0,
00661             GL_RGBA,                    GL_HALF_FLOAT_ARB,                0,
00662             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_RENDERTARGET | WINED3DFMT_FLAG_VTF,
00663             ARB_TEXTURE_FLOAT,          NULL},
00664     /* Palettized formats */
00665     {WINED3DFMT_P8_UINT,                GL_RGBA,                          GL_RGBA,                                0,
00666             GL_ALPHA,                   GL_UNSIGNED_BYTE,                 0,
00667             0,
00668             ARB_FRAGMENT_PROGRAM,       NULL},
00669     {WINED3DFMT_P8_UINT,                GL_COLOR_INDEX8_EXT,              GL_COLOR_INDEX8_EXT,                    0,
00670             GL_COLOR_INDEX,             GL_UNSIGNED_BYTE,                 0,
00671             0,
00672             EXT_PALETTED_TEXTURE,       NULL},
00673     /* Standard ARGB formats */
00674     {WINED3DFMT_B8G8R8_UNORM,           GL_RGB8,                          GL_RGB8,                                0,
00675             GL_BGR,                     GL_UNSIGNED_BYTE,                 0,
00676             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
00677             WINED3D_GL_EXT_NONE,        NULL},
00678     {WINED3DFMT_B8G8R8A8_UNORM,         GL_RGBA8,                         GL_SRGB8_ALPHA8_EXT,                    0,
00679             GL_BGRA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
00680             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
00681             | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE | WINED3DFMT_FLAG_VTF,
00682             WINED3D_GL_EXT_NONE,        NULL},
00683     {WINED3DFMT_B8G8R8X8_UNORM,         GL_RGB8,                          GL_SRGB8_EXT,                           0,
00684             GL_BGRA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
00685             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET
00686             | WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE,
00687             WINED3D_GL_EXT_NONE,        NULL},
00688     {WINED3DFMT_B5G6R5_UNORM,           GL_RGB5,                          GL_RGB5,                          GL_RGB8,
00689             GL_RGB,                     GL_UNSIGNED_SHORT_5_6_5,          0,
00690             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
00691             WINED3D_GL_EXT_NONE,        NULL},
00692     {WINED3DFMT_B5G5R5X1_UNORM,         GL_RGB5,                          GL_RGB5_A1,                             0,
00693             GL_BGRA,                    GL_UNSIGNED_SHORT_1_5_5_5_REV,    0,
00694             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
00695             WINED3D_GL_EXT_NONE,        NULL},
00696     {WINED3DFMT_B5G5R5A1_UNORM,         GL_RGB5_A1,                       GL_RGB5_A1,                             0,
00697             GL_BGRA,                    GL_UNSIGNED_SHORT_1_5_5_5_REV,    0,
00698             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
00699             WINED3D_GL_EXT_NONE,        NULL},
00700     {WINED3DFMT_B4G4R4A4_UNORM,         GL_RGBA4,                         GL_SRGB8_ALPHA8_EXT,                    0,
00701             GL_BGRA,                    GL_UNSIGNED_SHORT_4_4_4_4_REV,    0,
00702             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
00703             WINED3D_GL_EXT_NONE,        NULL},
00704     {WINED3DFMT_B2G3R3_UNORM,           GL_R3_G3_B2,                      GL_R3_G3_B2,                            0,
00705             GL_RGB,                     GL_UNSIGNED_BYTE_3_3_2,           0,
00706             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
00707             WINED3D_GL_EXT_NONE,        NULL},
00708     {WINED3DFMT_A8_UNORM,               GL_ALPHA8,                        GL_ALPHA8,                              0,
00709             GL_ALPHA,                   GL_UNSIGNED_BYTE,                 0,
00710             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
00711             WINED3D_GL_EXT_NONE,        NULL},
00712     {WINED3DFMT_B4G4R4X4_UNORM,         GL_RGB4,                          GL_RGB4,                                0,
00713             GL_BGRA,                    GL_UNSIGNED_SHORT_4_4_4_4_REV,    0,
00714             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
00715             WINED3D_GL_EXT_NONE,        NULL},
00716     {WINED3DFMT_R10G10B10A2_UNORM,      GL_RGB10_A2,                      GL_RGB10_A2,                            0,
00717             GL_RGBA,                    GL_UNSIGNED_INT_2_10_10_10_REV,   0,
00718             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
00719             WINED3D_GL_EXT_NONE,        NULL},
00720     {WINED3DFMT_R8G8B8A8_UNORM,         GL_RGBA8,                         GL_RGBA8,                               0,
00721             GL_RGBA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
00722             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
00723             WINED3D_GL_EXT_NONE,        NULL},
00724     {WINED3DFMT_R8G8B8X8_UNORM,         GL_RGB8,                          GL_RGB8,                                0,
00725             GL_RGBA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
00726             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
00727             WINED3D_GL_EXT_NONE,        NULL},
00728     {WINED3DFMT_R16G16_UNORM,           GL_RGB16,                         GL_RGB16,                       GL_RGBA16,
00729             GL_RGB,                     GL_UNSIGNED_SHORT,                6,
00730             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
00731             WINED3D_GL_EXT_NONE,        convert_r16g16},
00732     {WINED3DFMT_B10G10R10A2_UNORM,      GL_RGB10_A2,                      GL_RGB10_A2,                            0,
00733             GL_BGRA,                    GL_UNSIGNED_INT_2_10_10_10_REV,   0,
00734             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
00735             WINED3D_GL_EXT_NONE,        NULL},
00736     {WINED3DFMT_R16G16B16A16_UNORM,     GL_RGBA16,                        GL_RGBA16,                              0,
00737             GL_RGBA,                    GL_UNSIGNED_SHORT,                0,
00738             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_RENDERTARGET,
00739             WINED3D_GL_EXT_NONE,        NULL},
00740     /* Luminance */
00741     {WINED3DFMT_L8_UNORM,               GL_LUMINANCE8,                    GL_SLUMINANCE8_EXT,                     0,
00742             GL_LUMINANCE,               GL_UNSIGNED_BYTE,                 0,
00743             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
00744             WINED3D_GL_EXT_NONE,        NULL},
00745     {WINED3DFMT_L8A8_UNORM,             GL_LUMINANCE8_ALPHA8,             GL_SLUMINANCE8_ALPHA8_EXT,              0,
00746             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
00747             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_SRGB_READ,
00748             WINED3D_GL_EXT_NONE,        NULL},
00749     {WINED3DFMT_L4A4_UNORM,             GL_LUMINANCE4_ALPHA4,             GL_LUMINANCE4_ALPHA4,                   0,
00750             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 2,
00751             WINED3DFMT_FLAG_FILTERING,
00752             WINED3D_GL_EXT_NONE,        convert_l4a4_unorm},
00753     /* Bump mapping stuff */
00754     {WINED3DFMT_R8G8_SNORM,             GL_RGB8,                          GL_RGB8,                                0,
00755             GL_BGR,                     GL_UNSIGNED_BYTE,                 3,
00756             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
00757             WINED3D_GL_EXT_NONE,        convert_r8g8_snorm},
00758     {WINED3DFMT_R8G8_SNORM,             GL_DSDT8_NV,                      GL_DSDT8_NV,                            0,
00759             GL_DSDT_NV,                 GL_BYTE,                          0,
00760             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
00761             NV_TEXTURE_SHADER,          NULL},
00762     {WINED3DFMT_R5G5_SNORM_L6_UNORM,    GL_RGB5,                          GL_RGB5,                                0,
00763             GL_RGB,                     GL_UNSIGNED_SHORT_5_6_5,          2,
00764             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
00765             WINED3D_GL_EXT_NONE,        convert_r5g5_snorm_l6_unorm},
00766     {WINED3DFMT_R5G5_SNORM_L6_UNORM,    GL_DSDT8_MAG8_NV,                 GL_DSDT8_MAG8_NV,                       0,
00767             GL_DSDT_MAG_NV,             GL_BYTE,                          3,
00768             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
00769             NV_TEXTURE_SHADER,          convert_r5g5_snorm_l6_unorm_nv},
00770     {WINED3DFMT_R8G8_SNORM_L8X8_UNORM,  GL_RGB8,                          GL_RGB8,                                0,
00771             GL_BGRA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      4,
00772             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
00773             WINED3D_GL_EXT_NONE,        convert_r8g8_snorm_l8x8_unorm},
00774     {WINED3DFMT_R8G8_SNORM_L8X8_UNORM,  GL_DSDT8_MAG8_INTENSITY8_NV,      GL_DSDT8_MAG8_INTENSITY8_NV,            0,
00775             GL_DSDT_MAG_VIB_NV,         GL_UNSIGNED_INT_8_8_S8_S8_REV_NV, 4,
00776             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
00777             NV_TEXTURE_SHADER,          convert_r8g8_snorm_l8x8_unorm_nv},
00778     {WINED3DFMT_R8G8B8A8_SNORM,         GL_RGBA8,                         GL_RGBA8,                               0,
00779             GL_BGRA,                    GL_UNSIGNED_BYTE,                 4,
00780             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
00781             WINED3D_GL_EXT_NONE,        convert_r8g8b8a8_snorm},
00782     {WINED3DFMT_R8G8B8A8_SNORM,         GL_SIGNED_RGBA8_NV,               GL_SIGNED_RGBA8_NV,                     0,
00783             GL_RGBA,                    GL_BYTE,                          0,
00784             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
00785             NV_TEXTURE_SHADER,          NULL},
00786     {WINED3DFMT_R16G16_SNORM,           GL_RGB16,                         GL_RGB16,                               0,
00787             GL_BGR,                     GL_UNSIGNED_SHORT,                6,
00788             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
00789             WINED3D_GL_EXT_NONE,        convert_r16g16_snorm},
00790     {WINED3DFMT_R16G16_SNORM,           GL_SIGNED_HILO16_NV,              GL_SIGNED_HILO16_NV,                    0,
00791             GL_HILO_NV,                 GL_SHORT,                         0,
00792             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_BUMPMAP,
00793             NV_TEXTURE_SHADER,          NULL},
00794     /* Depth stencil formats */
00795     {WINED3DFMT_D16_LOCKABLE,           GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
00796             GL_DEPTH_COMPONENT,         GL_UNSIGNED_SHORT,                0,
00797             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
00798             ARB_DEPTH_TEXTURE,          NULL},
00799     {WINED3DFMT_D32_UNORM,              GL_DEPTH_COMPONENT32_ARB,         GL_DEPTH_COMPONENT32_ARB,               0,
00800             GL_DEPTH_COMPONENT,         GL_UNSIGNED_INT,                  0,
00801             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
00802             ARB_DEPTH_TEXTURE,          NULL},
00803     {WINED3DFMT_S1_UINT_D15_UNORM,      GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
00804             GL_DEPTH_COMPONENT,         GL_UNSIGNED_SHORT,                0,
00805             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
00806             ARB_DEPTH_TEXTURE,          NULL},
00807     {WINED3DFMT_S1_UINT_D15_UNORM,      GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
00808             GL_DEPTH_STENCIL_EXT,       GL_UNSIGNED_INT_24_8_EXT,         4,
00809             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
00810             EXT_PACKED_DEPTH_STENCIL,   convert_s1_uint_d15_unorm},
00811     {WINED3DFMT_S1_UINT_D15_UNORM,      GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
00812             GL_DEPTH_STENCIL,           GL_UNSIGNED_INT_24_8,             4,
00813             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
00814             ARB_FRAMEBUFFER_OBJECT,     convert_s1_uint_d15_unorm},
00815     {WINED3DFMT_D24_UNORM_S8_UINT,      GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
00816             GL_DEPTH_COMPONENT,         GL_UNSIGNED_INT,                  0,
00817             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
00818             | WINED3DFMT_FLAG_SHADOW,
00819             ARB_DEPTH_TEXTURE,          NULL},
00820     {WINED3DFMT_D24_UNORM_S8_UINT,      GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
00821             GL_DEPTH_STENCIL_EXT,       GL_UNSIGNED_INT_24_8_EXT,         0,
00822             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
00823             | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
00824             EXT_PACKED_DEPTH_STENCIL,   NULL},
00825     {WINED3DFMT_D24_UNORM_S8_UINT,      GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
00826             GL_DEPTH_STENCIL,           GL_UNSIGNED_INT_24_8,             0,
00827             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
00828             | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
00829             ARB_FRAMEBUFFER_OBJECT,     NULL},
00830     {WINED3DFMT_X8D24_UNORM,            GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
00831             GL_DEPTH_COMPONENT,         GL_UNSIGNED_INT,                  0,
00832             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
00833             | WINED3DFMT_FLAG_SHADOW,
00834             ARB_DEPTH_TEXTURE,          NULL},
00835     {WINED3DFMT_S4X4_UINT_D24_UNORM,    GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
00836             GL_DEPTH_COMPONENT,         GL_UNSIGNED_INT,                  0,
00837             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
00838             ARB_DEPTH_TEXTURE,          NULL},
00839     {WINED3DFMT_S4X4_UINT_D24_UNORM,    GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
00840             GL_DEPTH_STENCIL_EXT,       GL_UNSIGNED_INT_24_8_EXT,         4,
00841             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
00842             EXT_PACKED_DEPTH_STENCIL,   convert_s4x4_uint_d24_unorm},
00843     {WINED3DFMT_S4X4_UINT_D24_UNORM,    GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
00844             GL_DEPTH_STENCIL,           GL_UNSIGNED_INT_24_8,             4,
00845             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
00846             ARB_FRAMEBUFFER_OBJECT,     convert_s4x4_uint_d24_unorm},
00847     {WINED3DFMT_D16_UNORM,              GL_DEPTH_COMPONENT24_ARB,         GL_DEPTH_COMPONENT24_ARB,               0,
00848             GL_DEPTH_COMPONENT,         GL_UNSIGNED_SHORT,                0,
00849             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
00850             | WINED3DFMT_FLAG_SHADOW,
00851             ARB_DEPTH_TEXTURE,          NULL},
00852     {WINED3DFMT_L16_UNORM,              GL_LUMINANCE16,                   GL_LUMINANCE16,                         0,
00853             GL_LUMINANCE,               GL_UNSIGNED_SHORT,                0,
00854             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING,
00855             WINED3D_GL_EXT_NONE,        NULL},
00856     {WINED3DFMT_D32_FLOAT,              GL_DEPTH_COMPONENT32F,            GL_DEPTH_COMPONENT32F,                  0,
00857             GL_DEPTH_COMPONENT,         GL_FLOAT,                         0,
00858             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_SHADOW,
00859             ARB_DEPTH_BUFFER_FLOAT,     NULL},
00860     {WINED3DFMT_S8_UINT_D24_FLOAT,      GL_DEPTH32F_STENCIL8,             GL_DEPTH32F_STENCIL8,                   0,
00861             GL_DEPTH_STENCIL,           GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 8,
00862             WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL | WINED3DFMT_FLAG_SHADOW,
00863             ARB_DEPTH_BUFFER_FLOAT,     convert_s8_uint_d24_float},
00864     /* Vendor-specific formats */
00865     {WINED3DFMT_ATI2N,                  GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0,
00866             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
00867             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED,
00868             ATI_TEXTURE_COMPRESSION_3DC, NULL},
00869     {WINED3DFMT_ATI2N,                  GL_COMPRESSED_RED_GREEN_RGTC2,    GL_COMPRESSED_RED_GREEN_RGTC2,         0,
00870             GL_LUMINANCE_ALPHA,         GL_UNSIGNED_BYTE,                 0,
00871             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_COMPRESSED,
00872             ARB_TEXTURE_COMPRESSION_RGTC, NULL},
00873     {WINED3DFMT_INTZ,                   GL_DEPTH24_STENCIL8_EXT,          GL_DEPTH24_STENCIL8_EXT,                0,
00874             GL_DEPTH_STENCIL_EXT,       GL_UNSIGNED_INT_24_8_EXT,         0,
00875             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
00876             | WINED3DFMT_FLAG_STENCIL,
00877             EXT_PACKED_DEPTH_STENCIL,   NULL},
00878     {WINED3DFMT_INTZ,                   GL_DEPTH24_STENCIL8,              GL_DEPTH24_STENCIL8,                    0,
00879             GL_DEPTH_STENCIL,           GL_UNSIGNED_INT_24_8,             0,
00880             WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING | WINED3DFMT_FLAG_DEPTH
00881             | WINED3DFMT_FLAG_STENCIL,
00882             ARB_FRAMEBUFFER_OBJECT,     NULL},
00883     {WINED3DFMT_NULL,                   GL_RGBA8,                         GL_RGBA8,                               0,
00884             GL_RGBA,                    GL_UNSIGNED_INT_8_8_8_8_REV,      0,
00885             WINED3DFMT_FLAG_RENDERTARGET,
00886             ARB_FRAMEBUFFER_OBJECT,     NULL},
00887 };
00888 
00889 static inline int getFmtIdx(enum wined3d_format_id format_id)
00890 {
00891     /* First check if the format is at the position of its value.
00892      * This will catch the argb formats before the loop is entered. */
00893     if (format_id < (sizeof(formats) / sizeof(*formats))
00894             && formats[format_id].id == format_id)
00895     {
00896         return format_id;
00897     }
00898     else
00899     {
00900         unsigned int i;
00901 
00902         for (i = 0; i < (sizeof(formats) / sizeof(*formats)); ++i)
00903         {
00904             if (formats[i].id == format_id) return i;
00905         }
00906     }
00907     return -1;
00908 }
00909 
00910 static BOOL init_format_base_info(struct wined3d_gl_info *gl_info)
00911 {
00912     UINT format_count = sizeof(formats) / sizeof(*formats);
00913     UINT i;
00914 
00915     gl_info->formats = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, format_count * sizeof(*gl_info->formats));
00916     if (!gl_info->formats)
00917     {
00918         ERR("Failed to allocate memory.\n");
00919         return FALSE;
00920     }
00921 
00922     for (i = 0; i < format_count; ++i)
00923     {
00924         struct wined3d_format *format = &gl_info->formats[i];
00925         format->id = formats[i].id;
00926         format->red_mask = formats[i].redMask;
00927         format->green_mask = formats[i].greenMask;
00928         format->blue_mask = formats[i].blueMask;
00929         format->alpha_mask = formats[i].alphaMask;
00930         format->byte_count = formats[i].bpp;
00931         format->depth_size = formats[i].depthSize;
00932         format->stencil_size = formats[i].stencilSize;
00933         format->block_width = 1;
00934         format->block_height = 1;
00935         format->block_byte_count = formats[i].bpp;
00936     }
00937 
00938     for (i = 0; i < (sizeof(format_base_flags) / sizeof(*format_base_flags)); ++i)
00939     {
00940         int fmt_idx = getFmtIdx(format_base_flags[i].id);
00941 
00942         if (fmt_idx == -1)
00943         {
00944             ERR("Format %s (%#x) not found.\n",
00945                     debug_d3dformat(format_base_flags[i].id), format_base_flags[i].id);
00946             HeapFree(GetProcessHeap(), 0, gl_info->formats);
00947             return FALSE;
00948         }
00949 
00950         gl_info->formats[fmt_idx].flags |= format_base_flags[i].flags;
00951     }
00952 
00953     return TRUE;
00954 }
00955 
00956 static BOOL init_format_block_info(struct wined3d_gl_info *gl_info)
00957 {
00958     unsigned int i;
00959 
00960     for (i = 0; i < (sizeof(format_block_info) / sizeof(*format_block_info)); ++i)
00961     {
00962         struct wined3d_format *format;
00963         int fmt_idx = getFmtIdx(format_block_info[i].id);
00964 
00965         if (fmt_idx == -1)
00966         {
00967             ERR("Format %s (%#x) not found.\n",
00968                     debug_d3dformat(format_block_info[i].id), format_block_info[i].id);
00969             return FALSE;
00970         }
00971 
00972         format = &gl_info->formats[fmt_idx];
00973         format->block_width = format_block_info[i].block_width;
00974         format->block_height = format_block_info[i].block_height;
00975         format->block_byte_count = format_block_info[i].block_byte_count;
00976         format->flags |= WINED3DFMT_FLAG_BLOCKS;
00977     }
00978 
00979     return TRUE;
00980 }
00981 
00982 /* Context activation is done by the caller. */
00983 static void check_fbo_compat(const struct wined3d_gl_info *gl_info, struct wined3d_format *format)
00984 {
00985     /* Check if the default internal format is supported as a frame buffer
00986      * target, otherwise fall back to the render target internal.
00987      *
00988      * Try to stick to the standard format if possible, this limits precision differences. */
00989     GLenum status;
00990     GLuint tex;
00991 
00992     ENTER_GL();
00993 
00994     while(glGetError());
00995     glDisable(GL_BLEND);
00996 
00997     glGenTextures(1, &tex);
00998     glBindTexture(GL_TEXTURE_2D, tex);
00999 
01000     glTexImage2D(GL_TEXTURE_2D, 0, format->glInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
01001     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
01002     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
01003 
01004     gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
01005 
01006     status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
01007     checkGLcall("Framebuffer format check");
01008 
01009     if (status == GL_FRAMEBUFFER_COMPLETE)
01010     {
01011         TRACE("Format %s is supported as FBO color attachment.\n", debug_d3dformat(format->id));
01012         format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE;
01013         format->rtInternal = format->glInternal;
01014     }
01015     else
01016     {
01017         if (!format->rtInternal)
01018         {
01019             if (format->flags & WINED3DFMT_FLAG_RENDERTARGET)
01020             {
01021                 FIXME("Format %s with rendertarget flag is not supported as FBO color attachment,"
01022                         " and no fallback specified.\n", debug_d3dformat(format->id));
01023                 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
01024             }
01025             else
01026             {
01027                 TRACE("Format %s is not supported as FBO color attachment.\n", debug_d3dformat(format->id));
01028             }
01029             format->rtInternal = format->glInternal;
01030         }
01031         else
01032         {
01033             TRACE("Format %s is not supported as FBO color attachment, trying rtInternal format as fallback.\n",
01034                     debug_d3dformat(format->id));
01035 
01036             while(glGetError());
01037 
01038             gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
01039 
01040             glTexImage2D(GL_TEXTURE_2D, 0, format->rtInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
01041             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
01042             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
01043 
01044             gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
01045 
01046             status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
01047             checkGLcall("Framebuffer format check");
01048 
01049             if (status == GL_FRAMEBUFFER_COMPLETE)
01050             {
01051                 TRACE("Format %s rtInternal format is supported as FBO color attachment.\n",
01052                         debug_d3dformat(format->id));
01053             }
01054             else
01055             {
01056                 FIXME("Format %s rtInternal format is not supported as FBO color attachment.\n",
01057                         debug_d3dformat(format->id));
01058                 format->flags &= ~WINED3DFMT_FLAG_RENDERTARGET;
01059             }
01060         }
01061     }
01062 
01063     if (status == GL_FRAMEBUFFER_COMPLETE && ((format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
01064             || !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
01065             && format->id != WINED3DFMT_NULL && format->id != WINED3DFMT_P8_UINT
01066             && format->glFormat != GL_LUMINANCE && format->glFormat != GL_LUMINANCE_ALPHA)
01067     {
01068         GLuint rb, tex2;
01069         DWORD readback[16 * 16], color;
01070         BYTE r, a;
01071         BOOL match = TRUE;
01072 
01073         if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
01074                 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
01075         {
01076             gl_info->fbo_ops.glGenRenderbuffers(1, &rb);
01077             gl_info->fbo_ops.glBindRenderbuffer(GL_RENDERBUFFER, rb);
01078             gl_info->fbo_ops.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
01079             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb);
01080             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb);
01081             checkGLcall("RB attachment");
01082         }
01083 
01084         glEnable(GL_BLEND);
01085         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
01086         glClear(GL_COLOR_BUFFER_BIT);
01087         if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION)
01088         {
01089             while(glGetError());
01090             TRACE("Format doesn't support post-pixelshader blending.\n");
01091             format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
01092         }
01093         else
01094         {
01095             glViewport(0, 0, 16, 16);
01096             glDisable(GL_LIGHTING);
01097             glMatrixMode(GL_MODELVIEW);
01098             glLoadIdentity();
01099             glMatrixMode(GL_PROJECTION);
01100             glLoadIdentity();
01101 
01102             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01103 
01104             /* Draw a full-black quad */
01105             glBegin(GL_TRIANGLE_STRIP);
01106             glColor4ub(0x00, 0x00, 0x00, 0xff);
01107             glVertex3f(-1.0f, -1.0f, 0.0f);
01108             glColor4ub(0x00, 0x00, 0x00, 0xff);
01109             glVertex3f(1.0f, -1.0f, 0.0f);
01110             glColor4ub(0x00, 0x00, 0x00, 0xff);
01111             glVertex3f(-1.0f, 1.0f, 0.0f);
01112             glColor4ub(0x00, 0x00, 0x00, 0xff);
01113             glVertex3f(1.0f, 1.0f, 0.0f);
01114             glEnd();
01115 
01116             /* Draw a half-transparent red quad */
01117             glBegin(GL_TRIANGLE_STRIP);
01118             glColor4ub(0xff, 0x00, 0x00, 0x80);
01119             glVertex3f(-1.0f, -1.0f, 0.0f);
01120             glColor4ub(0xff, 0x00, 0x00, 0x80);
01121             glVertex3f(1.0f, -1.0f, 0.0f);
01122             glColor4ub(0xff, 0x00, 0x00, 0x80);
01123             glVertex3f(-1.0f, 1.0f, 0.0f);
01124             glColor4ub(0xff, 0x00, 0x00, 0x80);
01125             glVertex3f(1.0f, 1.0f, 0.0f);
01126             glEnd();
01127 
01128             glGenTextures(1, &tex2);
01129             glBindTexture(GL_TEXTURE_2D, tex2);
01130 
01131             glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, 16, 16, 0);
01132             glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
01133             checkGLcall("Post-pixelshader blending check");
01134 
01135             color = readback[7 * 16 + 7];
01136             a = color >> 24;
01137             r = (color & 0x00ff0000) >> 16;
01138 
01139             if (format->red_mask && (r < 0x7b || r > 0x84))
01140             match = FALSE;
01141             /* If the alpha component is more than 1 bit */
01142             else if ((format->alpha_mask & (format->alpha_mask - 1)) && (a < 0x9f || a > 0xdf))
01143                 match = FALSE;
01144             if (!match)
01145             {
01146                 TRACE("Format doesn't support post-pixelshader blending.\n");
01147                 TRACE("Color output: %#x\n", color);
01148                 format->flags &= ~WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
01149             }
01150             else
01151             {
01152                 TRACE("Format supports post-pixelshader blending.\n");
01153                 format->flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
01154             }
01155 
01156             glBindTexture(GL_TEXTURE_2D, tex);
01157             glDeleteTextures(1, &tex2);
01158         }
01159 
01160         if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT]
01161                 || gl_info->supported[EXT_PACKED_DEPTH_STENCIL])
01162         {
01163             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
01164             gl_info->fbo_ops.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
01165             gl_info->fbo_ops.glDeleteRenderbuffers(1, &rb);
01166             checkGLcall("RB cleanup");
01167         }
01168     }
01169 
01170     if (format->glInternal != format->glGammaInternal)
01171     {
01172         glTexImage2D(GL_TEXTURE_2D, 0, format->glGammaInternal, 16, 16, 0, format->glFormat, format->glType, NULL);
01173         gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
01174 
01175         status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
01176         checkGLcall("Framebuffer format check");
01177 
01178         if (status == GL_FRAMEBUFFER_COMPLETE)
01179         {
01180             TRACE("Format %s's sRGB format is FBO attachable.\n", debug_d3dformat(format->id));
01181             format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
01182         }
01183         else
01184         {
01185             WARN("Format %s's sRGB format is not FBO attachable.\n", debug_d3dformat(format->id));
01186         }
01187     }
01188     else if (status == GL_FRAMEBUFFER_COMPLETE)
01189         format->flags |= WINED3DFMT_FLAG_FBO_ATTACHABLE_SRGB;
01190 
01191     glDeleteTextures(1, &tex);
01192 
01193     LEAVE_GL();
01194 }
01195 
01196 /* Context activation is done by the caller. */
01197 static void init_format_fbo_compat_info(struct wined3d_gl_info *gl_info)
01198 {
01199     unsigned int i;
01200     GLuint fbo;
01201 
01202     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
01203     {
01204         ENTER_GL();
01205 
01206         gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
01207         gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
01208         glDrawBuffer(GL_COLOR_ATTACHMENT0);
01209         glReadBuffer(GL_COLOR_ATTACHMENT0);
01210 
01211         LEAVE_GL();
01212     }
01213 
01214     for (i = 0; i < sizeof(formats) / sizeof(*formats); ++i)
01215     {
01216         struct wined3d_format *format = &gl_info->formats[i];
01217 
01218         if (!format->glInternal) continue;
01219 
01220         if (format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
01221         {
01222             TRACE("Skipping format %s because it's a depth/stencil format.\n",
01223                     debug_d3dformat(format->id));
01224             continue;
01225         }
01226 
01227         if (format->flags & WINED3DFMT_FLAG_COMPRESSED)
01228         {
01229             TRACE("Skipping format %s because it's a compressed format.\n",
01230                     debug_d3dformat(format->id));
01231             continue;
01232         }
01233 
01234         if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
01235         {
01236             TRACE("Checking if format %s is supported as FBO color attachment...\n", debug_d3dformat(format->id));
01237             check_fbo_compat(gl_info, format);
01238         }
01239         else
01240         {
01241             format->rtInternal = format->glInternal;
01242         }
01243     }
01244 
01245     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
01246     {
01247         ENTER_GL();
01248 
01249         gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
01250 
01251         LEAVE_GL();
01252     }
01253 }
01254 
01255 static BOOL init_format_texture_info(struct wined3d_gl_info *gl_info)
01256 {
01257     unsigned int i;
01258 
01259     for (i = 0; i < sizeof(format_texture_info) / sizeof(*format_texture_info); ++i)
01260     {
01261         int fmt_idx = getFmtIdx(format_texture_info[i].id);
01262         struct wined3d_format *format;
01263 
01264         if (fmt_idx == -1)
01265         {
01266             ERR("Format %s (%#x) not found.\n",
01267                     debug_d3dformat(format_texture_info[i].id), format_texture_info[i].id);
01268             return FALSE;
01269         }
01270 
01271         if (!gl_info->supported[format_texture_info[i].extension]) continue;
01272 
01273         format = &gl_info->formats[fmt_idx];
01274 
01275         /* ARB_texture_rg defines floating point formats, but only if
01276          * ARB_texture_float is also supported. */
01277         if (!gl_info->supported[ARB_TEXTURE_FLOAT]
01278                 && (format->flags & WINED3DFMT_FLAG_FLOAT))
01279             continue;
01280 
01281         format->glInternal = format_texture_info[i].gl_internal;
01282         format->glGammaInternal = format_texture_info[i].gl_srgb_internal;
01283         format->rtInternal = format_texture_info[i].gl_rt_internal;
01284         format->glFormat = format_texture_info[i].gl_format;
01285         format->glType = format_texture_info[i].gl_type;
01286         format->color_fixup = COLOR_FIXUP_IDENTITY;
01287         format->flags |= format_texture_info[i].flags;
01288         format->heightscale = 1.0f;
01289 
01290         if (format->glGammaInternal != format->glInternal)
01291         {
01292             /* Filter sRGB capabilities if EXT_texture_sRGB is not supported. */
01293             if (!gl_info->supported[EXT_TEXTURE_SRGB])
01294             {
01295                 format->glGammaInternal = format->glInternal;
01296                 format->flags &= ~(WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_SRGB_WRITE);
01297             }
01298             else if (gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
01299             {
01300                 format->glInternal = format->glGammaInternal;
01301             }
01302         }
01303 
01304         /* Texture conversion stuff */
01305         format->convert = format_texture_info[i].convert;
01306         format->conv_byte_count = format_texture_info[i].conv_byte_count;
01307     }
01308 
01309     return TRUE;
01310 }
01311 
01312 static BOOL color_match(DWORD c1, DWORD c2, BYTE max_diff)
01313 {
01314     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
01315     c1 >>= 8; c2 >>= 8;
01316     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
01317     c1 >>= 8; c2 >>= 8;
01318     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
01319     c1 >>= 8; c2 >>= 8;
01320     if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
01321     return TRUE;
01322 }
01323 
01324 /* A context is provided by the caller */
01325 static BOOL check_filter(const struct wined3d_gl_info *gl_info, GLenum internal)
01326 {
01327     static const DWORD data[] = {0x00000000, 0xffffffff};
01328     GLuint tex, fbo, buffer;
01329     DWORD readback[16 * 1];
01330     BOOL ret = FALSE;
01331 
01332     /* Render a filtered texture and see what happens. This is intended to detect the lack of
01333      * float16 filtering on ATI X1000 class cards. The drivers disable filtering instead of
01334      * falling back to software. If this changes in the future this code will get fooled and
01335      * apps might hit the software path due to incorrectly advertised caps.
01336      *
01337      * Its unlikely that this changes however. GL Games like Mass Effect depend on the filter
01338      * disable fallback, if Apple or ATI ever change the driver behavior they will break more
01339      * than Wine. The Linux binary <= r500 driver is not maintained any more anyway
01340      */
01341 
01342     ENTER_GL();
01343     while(glGetError());
01344 
01345     glGenTextures(1, &buffer);
01346     glBindTexture(GL_TEXTURE_2D, buffer);
01347     memset(readback, 0x7e, sizeof(readback));
01348     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 16, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, readback);
01349     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
01350     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
01351     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
01352     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
01353     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
01354 
01355     glGenTextures(1, &tex);
01356     glBindTexture(GL_TEXTURE_2D, tex);
01357     glTexImage2D(GL_TEXTURE_2D, 0, internal, 2, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
01358     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
01359     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
01360     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
01361     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
01362     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
01363     glEnable(GL_TEXTURE_2D);
01364 
01365     gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
01366     gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
01367     gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, buffer, 0);
01368     glDrawBuffer(GL_COLOR_ATTACHMENT0);
01369 
01370     glViewport(0, 0, 16, 1);
01371     glDisable(GL_LIGHTING);
01372     glMatrixMode(GL_MODELVIEW);
01373     glLoadIdentity();
01374     glMatrixMode(GL_PROJECTION);
01375     glLoadIdentity();
01376 
01377     glClearColor(0, 1, 0, 0);
01378     glClear(GL_COLOR_BUFFER_BIT);
01379 
01380     glBegin(GL_TRIANGLE_STRIP);
01381     glTexCoord2f(0.0, 0.0);
01382     glVertex2f(-1.0f, -1.0f);
01383     glTexCoord2f(1.0, 0.0);
01384     glVertex2f(1.0f, -1.0f);
01385     glTexCoord2f(0.0, 1.0);
01386     glVertex2f(-1.0f, 1.0f);
01387     glTexCoord2f(1.0, 1.0);
01388     glVertex2f(1.0f, 1.0f);
01389     glEnd();
01390 
01391     glBindTexture(GL_TEXTURE_2D, buffer);
01392     memset(readback, 0x7f, sizeof(readback));
01393     glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, readback);
01394     if(color_match(readback[6], 0xffffffff, 5) || color_match(readback[6], 0x00000000, 5) ||
01395        color_match(readback[9], 0xffffffff, 5) || color_match(readback[9], 0x00000000, 5))
01396     {
01397         TRACE("Read back colors 0x%08x and 0x%08x close to unfiltered color, asuming no filtering\n",
01398               readback[6], readback[9]);
01399         ret = FALSE;
01400     }
01401     else
01402     {
01403         TRACE("Read back colors are 0x%08x and 0x%08x, assuming texture is filtered\n",
01404               readback[6], readback[9]);
01405         ret = TRUE;
01406     }
01407 
01408     gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
01409     gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
01410     glDeleteTextures(1, &tex);
01411     glDeleteTextures(1, &buffer);
01412 
01413     if(glGetError())
01414     {
01415         FIXME("Error during filtering test for format %x, returning no filtering\n", internal);
01416         ret = FALSE;
01417     }
01418     LEAVE_GL();
01419     return ret;
01420 }
01421 
01422 static void init_format_filter_info(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
01423 {
01424     struct wined3d_format *format;
01425     unsigned int fmt_idx, i;
01426     static const enum wined3d_format_id fmts16[] =
01427     {
01428         WINED3DFMT_R16_FLOAT,
01429         WINED3DFMT_R16G16_FLOAT,
01430         WINED3DFMT_R16G16B16A16_FLOAT,
01431     };
01432     BOOL filtered;
01433 
01434     if(wined3d_settings.offscreen_rendering_mode != ORM_FBO)
01435     {
01436         WARN("No FBO support, or no FBO ORM, guessing filter info from GL caps\n");
01437         if (vendor == HW_VENDOR_NVIDIA && gl_info->supported[ARB_TEXTURE_FLOAT])
01438         {
01439             TRACE("Nvidia card with texture_float support: Assuming float16 blending\n");
01440             filtered = TRUE;
01441         }
01442         else if (gl_info->limits.glsl_varyings > 44)
01443         {
01444             TRACE("More than 44 GLSL varyings - assuming d3d10 card with float16 blending\n");
01445             filtered = TRUE;
01446         }
01447         else
01448         {
01449             TRACE("Assuming no float16 blending\n");
01450             filtered = FALSE;
01451         }
01452 
01453         if(filtered)
01454         {
01455             for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
01456             {
01457                 fmt_idx = getFmtIdx(fmts16[i]);
01458                 gl_info->formats[fmt_idx].flags |= WINED3DFMT_FLAG_FILTERING;
01459             }
01460         }
01461         return;
01462     }
01463 
01464     for(i = 0; i < (sizeof(fmts16) / sizeof(*fmts16)); i++)
01465     {
01466         fmt_idx = getFmtIdx(fmts16[i]);
01467         format = &gl_info->formats[fmt_idx];
01468         if (!format->glInternal) continue; /* Not supported by GL */
01469 
01470         filtered = check_filter(gl_info, gl_info->formats[fmt_idx].glInternal);
01471         if(filtered)
01472         {
01473             TRACE("Format %s supports filtering\n", debug_d3dformat(fmts16[i]));
01474             format->flags |= WINED3DFMT_FLAG_FILTERING;
01475         }
01476         else
01477         {
01478             TRACE("Format %s does not support filtering\n", debug_d3dformat(fmts16[i]));
01479         }
01480     }
01481 }
01482 
01483 static void apply_format_fixups(struct wined3d_gl_info *gl_info)
01484 {
01485     int idx;
01486 
01487     idx = getFmtIdx(WINED3DFMT_R16_FLOAT);
01488     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
01489             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
01490 
01491     idx = getFmtIdx(WINED3DFMT_R32_FLOAT);
01492     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
01493             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
01494 
01495     idx = getFmtIdx(WINED3DFMT_R16G16_UNORM);
01496     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
01497             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
01498 
01499     idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
01500     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
01501             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
01502 
01503     idx = getFmtIdx(WINED3DFMT_R32G32_FLOAT);
01504     gl_info->formats[idx].color_fixup = create_color_fixup_desc(
01505             0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_W);
01506 
01507     /* V8U8 is supported natively by GL_ATI_envmap_bumpmap and GL_NV_texture_shader.
01508      * V16U16 is only supported by GL_NV_texture_shader. The formats need fixup if
01509      * their extensions are not available. GL_ATI_envmap_bumpmap is not used because
01510      * the only driver that implements it(fglrx) has a buggy implementation.
01511      *
01512      * V8U8 and V16U16 need a fixup of the undefined blue channel. OpenGL
01513      * returns 0.0 when sampling from it, DirectX 1.0. So we always have in-shader
01514      * conversion for this format.
01515      */
01516     if (!gl_info->supported[NV_TEXTURE_SHADER])
01517     {
01518         idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
01519         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
01520                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
01521         idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
01522         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
01523                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
01524     }
01525     else
01526     {
01527         idx = getFmtIdx(WINED3DFMT_R8G8_SNORM);
01528         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
01529                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
01530 
01531         idx = getFmtIdx(WINED3DFMT_R16G16_SNORM);
01532         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
01533                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
01534     }
01535 
01536     if (!gl_info->supported[NV_TEXTURE_SHADER])
01537     {
01538         /* If GL_NV_texture_shader is not supported, those formats are converted, incompatibly
01539          * with each other
01540          */
01541         idx = getFmtIdx(WINED3DFMT_R5G5_SNORM_L6_UNORM);
01542         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
01543                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_ONE);
01544         idx = getFmtIdx(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
01545         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
01546                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_Z, 0, CHANNEL_SOURCE_W);
01547         idx = getFmtIdx(WINED3DFMT_R8G8B8A8_SNORM);
01548         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
01549                 1, CHANNEL_SOURCE_X, 1, CHANNEL_SOURCE_Y, 1, CHANNEL_SOURCE_Z, 1, CHANNEL_SOURCE_W);
01550     }
01551     else
01552     {
01553         /* If GL_NV_texture_shader is supported, WINED3DFMT_L6V5U5 and WINED3DFMT_X8L8V8U8
01554          * are converted at surface loading time, but they do not need any modification in
01555          * the shader, thus they are compatible with all WINED3DFMT_UNKNOWN group formats.
01556          * WINED3DFMT_Q8W8V8U8 doesn't even need load-time conversion
01557          */
01558     }
01559 
01560     if (gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
01561     {
01562         idx = getFmtIdx(WINED3DFMT_ATI2N);
01563         gl_info->formats[idx].color_fixup = create_color_fixup_desc(
01564                 0, CHANNEL_SOURCE_Y, 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
01565     }
01566     else if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC])
01567     {
01568         idx = getFmtIdx(WINED3DFMT_ATI2N);
01569         gl_info->formats[idx].color_fixup= create_color_fixup_desc(
01570                 0, CHANNEL_SOURCE_X, 0, CHANNEL_SOURCE_W, 0, CHANNEL_SOURCE_ONE, 0, CHANNEL_SOURCE_ONE);
01571     }
01572 
01573     if (!gl_info->supported[APPLE_YCBCR_422])
01574     {
01575         idx = getFmtIdx(WINED3DFMT_YUY2);
01576         gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YUY2);
01577 
01578         idx = getFmtIdx(WINED3DFMT_UYVY);
01579         gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_UYVY);
01580     }
01581 
01582     idx = getFmtIdx(WINED3DFMT_YV12);
01583     gl_info->formats[idx].heightscale = 1.5f;
01584     gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
01585 
01586     if (gl_info->supported[EXT_PALETTED_TEXTURE] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
01587     {
01588         idx = getFmtIdx(WINED3DFMT_P8_UINT);
01589         gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_P8);
01590     }
01591 
01592     if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
01593     {
01594         idx = getFmtIdx(WINED3DFMT_B8G8R8A8_UNORM);
01595         gl_info->formats[idx].gl_vtx_format = GL_BGRA;
01596     }
01597 
01598     if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
01599     {
01600         /* Do not change the size of the type, it is CPU side. We have to change the GPU-side information though.
01601          * It is the job of the vertex buffer code to make sure that the vbos have the right format */
01602         idx = getFmtIdx(WINED3DFMT_R16G16_FLOAT);
01603         gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT; /* == GL_HALF_FLOAT_NV */
01604 
01605         idx = getFmtIdx(WINED3DFMT_R16G16B16A16_FLOAT);
01606         gl_info->formats[idx].gl_vtx_type = GL_HALF_FLOAT;
01607     }
01608 }
01609 
01610 static BOOL init_format_vertex_info(struct wined3d_gl_info *gl_info)
01611 {
01612     unsigned int i;
01613 
01614     for (i = 0; i < (sizeof(format_vertex_info) / sizeof(*format_vertex_info)); ++i)
01615     {
01616         struct wined3d_format *format;
01617         int fmt_idx = getFmtIdx(format_vertex_info[i].id);
01618 
01619         if (fmt_idx == -1)
01620         {
01621             ERR("Format %s (%#x) not found.\n",
01622                     debug_d3dformat(format_vertex_info[i].id), format_vertex_info[i].id);
01623             return FALSE;
01624         }
01625 
01626         format = &gl_info->formats[fmt_idx];
01627         format->emit_idx = format_vertex_info[i].emit_idx;
01628         format->component_count = format_vertex_info[i].component_count;
01629         format->gl_vtx_type = format_vertex_info[i].gl_vtx_type;
01630         format->gl_vtx_format = format_vertex_info[i].gl_vtx_format;
01631         format->gl_normalized = format_vertex_info[i].gl_normalized;
01632         format->component_size = format_vertex_info[i].component_size;
01633     }
01634 
01635     return TRUE;
01636 }
01637 
01638 BOOL initPixelFormatsNoGL(struct wined3d_gl_info *gl_info)
01639 {
01640     if (!init_format_base_info(gl_info)) return FALSE;
01641 
01642     if (!init_format_block_info(gl_info))
01643     {
01644         HeapFree(GetProcessHeap(), 0, gl_info->formats);
01645         gl_info->formats = NULL;
01646         return FALSE;
01647     }
01648 
01649     return TRUE;
01650 }
01651 
01652 /* Context activation is done by the caller. */
01653 BOOL initPixelFormats(struct wined3d_gl_info *gl_info, enum wined3d_pci_vendor vendor)
01654 {
01655     if (!init_format_base_info(gl_info)) return FALSE;
01656 
01657     if (!init_format_block_info(gl_info)) goto fail;
01658     if (!init_format_texture_info(gl_info)) goto fail;
01659     if (!init_format_vertex_info(gl_info)) goto fail;
01660 
01661     apply_format_fixups(gl_info);
01662     init_format_fbo_compat_info(gl_info);
01663     init_format_filter_info(gl_info, vendor);
01664 
01665     return TRUE;
01666 
01667 fail:
01668     HeapFree(GetProcessHeap(), 0, gl_info->formats);
01669     gl_info->formats = NULL;
01670     return FALSE;
01671 }
01672 
01673 const struct wined3d_format *wined3d_get_format(const struct wined3d_gl_info *gl_info,
01674         enum wined3d_format_id format_id)
01675 {
01676     int idx = getFmtIdx(format_id);
01677 
01678     if (idx == -1)
01679     {
01680         FIXME("Can't find format %s (%#x) in the format lookup table\n",
01681                 debug_d3dformat(format_id), format_id);
01682         /* Get the caller a valid pointer */
01683         idx = getFmtIdx(WINED3DFMT_UNKNOWN);
01684     }
01685 
01686     return &gl_info->formats[idx];
01687 }
01688 
01689 UINT wined3d_format_calculate_size(const struct wined3d_format *format, UINT alignment, UINT width, UINT height)
01690 {
01691     UINT size;
01692 
01693     if (format->id == WINED3DFMT_UNKNOWN)
01694     {
01695         size = 0;
01696     }
01697     else if (format->flags & WINED3DFMT_FLAG_BLOCKS)
01698     {
01699         UINT row_block_count = (width + format->block_width - 1) / format->block_width;
01700         UINT row_count = (height + format->block_height - 1) / format->block_height;
01701         size = row_count * (((row_block_count * format->block_byte_count) + alignment - 1) & ~(alignment - 1));
01702     }
01703     else
01704     {
01705         size = height * (((width * format->byte_count) + alignment - 1) & ~(alignment - 1));
01706     }
01707 
01708     if (format->heightscale != 0.0f)
01709     {
01710         /* The D3D format requirements make sure that the resulting format is an integer again */
01711         size = (UINT) (size * format->heightscale);
01712     }
01713 
01714     return size;
01715 }
01716 
01717 /*****************************************************************************
01718  * Trace formatting of useful values
01719  */
01720 const char *debug_d3dformat(enum wined3d_format_id format_id)
01721 {
01722     switch (format_id)
01723     {
01724 #define FMT_TO_STR(format_id) case format_id: return #format_id
01725         FMT_TO_STR(WINED3DFMT_UNKNOWN);
01726         FMT_TO_STR(WINED3DFMT_B8G8R8_UNORM);
01727         FMT_TO_STR(WINED3DFMT_B5G5R5X1_UNORM);
01728         FMT_TO_STR(WINED3DFMT_B4G4R4A4_UNORM);
01729         FMT_TO_STR(WINED3DFMT_B2G3R3_UNORM);
01730         FMT_TO_STR(WINED3DFMT_B2G3R3A8_UNORM);
01731         FMT_TO_STR(WINED3DFMT_B4G4R4X4_UNORM);
01732         FMT_TO_STR(WINED3DFMT_R8G8B8X8_UNORM);
01733         FMT_TO_STR(WINED3DFMT_B10G10R10A2_UNORM);
01734         FMT_TO_STR(WINED3DFMT_P8_UINT_A8_UNORM);
01735         FMT_TO_STR(WINED3DFMT_P8_UINT);
01736         FMT_TO_STR(WINED3DFMT_L8_UNORM);
01737         FMT_TO_STR(WINED3DFMT_L8A8_UNORM);
01738         FMT_TO_STR(WINED3DFMT_L4A4_UNORM);
01739         FMT_TO_STR(WINED3DFMT_R5G5_SNORM_L6_UNORM);
01740         FMT_TO_STR(WINED3DFMT_R8G8_SNORM_L8X8_UNORM);
01741         FMT_TO_STR(WINED3DFMT_R10G11B11_SNORM);
01742         FMT_TO_STR(WINED3DFMT_R10G10B10_SNORM_A2_UNORM);
01743         FMT_TO_STR(WINED3DFMT_UYVY);
01744         FMT_TO_STR(WINED3DFMT_YUY2);
01745         FMT_TO_STR(WINED3DFMT_YV12);
01746         FMT_TO_STR(WINED3DFMT_DXT1);
01747         FMT_TO_STR(WINED3DFMT_DXT2);
01748         FMT_TO_STR(WINED3DFMT_DXT3);
01749         FMT_TO_STR(WINED3DFMT_DXT4);
01750         FMT_TO_STR(WINED3DFMT_DXT5);
01751         FMT_TO_STR(WINED3DFMT_MULTI2_ARGB8);
01752         FMT_TO_STR(WINED3DFMT_G8R8_G8B8);
01753         FMT_TO_STR(WINED3DFMT_R8G8_B8G8);
01754         FMT_TO_STR(WINED3DFMT_D16_LOCKABLE);
01755         FMT_TO_STR(WINED3DFMT_D32_UNORM);
01756         FMT_TO_STR(WINED3DFMT_S1_UINT_D15_UNORM);
01757         FMT_TO_STR(WINED3DFMT_X8D24_UNORM);
01758         FMT_TO_STR(WINED3DFMT_S4X4_UINT_D24_UNORM);
01759         FMT_TO_STR(WINED3DFMT_L16_UNORM);
01760         FMT_TO_STR(WINED3DFMT_S8_UINT_D24_FLOAT);
01761         FMT_TO_STR(WINED3DFMT_VERTEXDATA);
01762         FMT_TO_STR(WINED3DFMT_R8G8_SNORM_Cx);
01763         FMT_TO_STR(WINED3DFMT_ATI2N);
01764         FMT_TO_STR(WINED3DFMT_NVDB);
01765         FMT_TO_STR(WINED3DFMT_NVHU);
01766         FMT_TO_STR(WINED3DFMT_NVHS);
01767         FMT_TO_STR(WINED3DFMT_R32G32B32A32_TYPELESS);
01768         FMT_TO_STR(WINED3DFMT_R32G32B32A32_FLOAT);
01769         FMT_TO_STR(WINED3DFMT_R32G32B32A32_UINT);
01770         FMT_TO_STR(WINED3DFMT_R32G32B32A32_SINT);
01771         FMT_TO_STR(WINED3DFMT_R32G32B32_TYPELESS);
01772         FMT_TO_STR(WINED3DFMT_R32G32B32_FLOAT);
01773         FMT_TO_STR(WINED3DFMT_R32G32B32_UINT);
01774         FMT_TO_STR(WINED3DFMT_R32G32B32_SINT);
01775         FMT_TO_STR(WINED3DFMT_R16G16B16A16_TYPELESS);
01776         FMT_TO_STR(WINED3DFMT_R16G16B16A16_FLOAT);
01777         FMT_TO_STR(WINED3DFMT_R16G16B16A16_UNORM);
01778         FMT_TO_STR(WINED3DFMT_R16G16B16A16_UINT);
01779         FMT_TO_STR(WINED3DFMT_R16G16B16A16_SNORM);
01780         FMT_TO_STR(WINED3DFMT_R16G16B16A16_SINT);
01781         FMT_TO_STR(WINED3DFMT_R32G32_TYPELESS);
01782         FMT_TO_STR(WINED3DFMT_R32G32_FLOAT);
01783         FMT_TO_STR(WINED3DFMT_R32G32_UINT);
01784         FMT_TO_STR(WINED3DFMT_R32G32_SINT);
01785         FMT_TO_STR(WINED3DFMT_R32G8X24_TYPELESS);
01786         FMT_TO_STR(WINED3DFMT_D32_FLOAT_S8X24_UINT);
01787         FMT_TO_STR(WINED3DFMT_R32_FLOAT_X8X24_TYPELESS);
01788         FMT_TO_STR(WINED3DFMT_X32_TYPELESS_G8X24_UINT);
01789         FMT_TO_STR(WINED3DFMT_R10G10B10A2_TYPELESS);
01790         FMT_TO_STR(WINED3DFMT_R10G10B10A2_UNORM);
01791         FMT_TO_STR(WINED3DFMT_R10G10B10A2_UINT);
01792         FMT_TO_STR(WINED3DFMT_R10G10B10A2_SNORM);
01793         FMT_TO_STR(WINED3DFMT_R11G11B10_FLOAT);
01794         FMT_TO_STR(WINED3DFMT_R8G8B8A8_TYPELESS);
01795         FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM);
01796         FMT_TO_STR(WINED3DFMT_R8G8B8A8_UNORM_SRGB);
01797         FMT_TO_STR(WINED3DFMT_R8G8B8A8_UINT);
01798         FMT_TO_STR(WINED3DFMT_R8G8B8A8_SNORM);
01799         FMT_TO_STR(WINED3DFMT_R8G8B8A8_SINT);
01800         FMT_TO_STR(WINED3DFMT_R16G16_TYPELESS);
01801         FMT_TO_STR(WINED3DFMT_R16G16_FLOAT);
01802         FMT_TO_STR(WINED3DFMT_R16G16_UNORM);
01803         FMT_TO_STR(WINED3DFMT_R16G16_UINT);
01804         FMT_TO_STR(WINED3DFMT_R16G16_SNORM);
01805         FMT_TO_STR(WINED3DFMT_R16G16_SINT);
01806         FMT_TO_STR(WINED3DFMT_R32_TYPELESS);
01807         FMT_TO_STR(WINED3DFMT_D32_FLOAT);
01808         FMT_TO_STR(WINED3DFMT_R32_FLOAT);
01809         FMT_TO_STR(WINED3DFMT_R32_UINT);
01810         FMT_TO_STR(WINED3DFMT_R32_SINT);
01811         FMT_TO_STR(WINED3DFMT_R24G8_TYPELESS);
01812         FMT_TO_STR(WINED3DFMT_D24_UNORM_S8_UINT);
01813         FMT_TO_STR(WINED3DFMT_R24_UNORM_X8_TYPELESS);
01814         FMT_TO_STR(WINED3DFMT_X24_TYPELESS_G8_UINT);
01815         FMT_TO_STR(WINED3DFMT_R8G8_TYPELESS);
01816         FMT_TO_STR(WINED3DFMT_R8G8_UNORM);
01817         FMT_TO_STR(WINED3DFMT_R8G8_UINT);
01818         FMT_TO_STR(WINED3DFMT_R8G8_SNORM);
01819         FMT_TO_STR(WINED3DFMT_R8G8_SINT);
01820         FMT_TO_STR(WINED3DFMT_R16_TYPELESS);
01821         FMT_TO_STR(WINED3DFMT_R16_FLOAT);
01822         FMT_TO_STR(WINED3DFMT_D16_UNORM);
01823         FMT_TO_STR(WINED3DFMT_R16_UNORM);
01824         FMT_TO_STR(WINED3DFMT_R16_UINT);
01825         FMT_TO_STR(WINED3DFMT_R16_SNORM);
01826         FMT_TO_STR(WINED3DFMT_R16_SINT);
01827         FMT_TO_STR(WINED3DFMT_R8_TYPELESS);
01828         FMT_TO_STR(WINED3DFMT_R8_UNORM);
01829         FMT_TO_STR(WINED3DFMT_R8_UINT);
01830         FMT_TO_STR(WINED3DFMT_R8_SNORM);
01831         FMT_TO_STR(WINED3DFMT_R8_SINT);
01832         FMT_TO_STR(WINED3DFMT_A8_UNORM);
01833         FMT_TO_STR(WINED3DFMT_R1_UNORM);
01834         FMT_TO_STR(WINED3DFMT_R9G9B9E5_SHAREDEXP);
01835         FMT_TO_STR(WINED3DFMT_R8G8_B8G8_UNORM);
01836         FMT_TO_STR(WINED3DFMT_G8R8_G8B8_UNORM);
01837         FMT_TO_STR(WINED3DFMT_BC1_TYPELESS);
01838         FMT_TO_STR(WINED3DFMT_BC1_UNORM);
01839         FMT_TO_STR(WINED3DFMT_BC1_UNORM_SRGB);
01840         FMT_TO_STR(WINED3DFMT_BC2_TYPELESS);
01841         FMT_TO_STR(WINED3DFMT_BC2_UNORM);
01842         FMT_TO_STR(WINED3DFMT_BC2_UNORM_SRGB);
01843         FMT_TO_STR(WINED3DFMT_BC3_TYPELESS);
01844         FMT_TO_STR(WINED3DFMT_BC3_UNORM);
01845         FMT_TO_STR(WINED3DFMT_BC3_UNORM_SRGB);
01846         FMT_TO_STR(WINED3DFMT_BC4_TYPELESS);
01847         FMT_TO_STR(WINED3DFMT_BC4_UNORM);
01848         FMT_TO_STR(WINED3DFMT_BC4_SNORM);
01849         FMT_TO_STR(WINED3DFMT_BC5_TYPELESS);
01850         FMT_TO_STR(WINED3DFMT_BC5_UNORM);
01851         FMT_TO_STR(WINED3DFMT_BC5_SNORM);
01852         FMT_TO_STR(WINED3DFMT_B5G6R5_UNORM);
01853         FMT_TO_STR(WINED3DFMT_B5G5R5A1_UNORM);
01854         FMT_TO_STR(WINED3DFMT_B8G8R8A8_UNORM);
01855         FMT_TO_STR(WINED3DFMT_B8G8R8X8_UNORM);
01856         FMT_TO_STR(WINED3DFMT_INTZ);
01857         FMT_TO_STR(WINED3DFMT_NULL);
01858         FMT_TO_STR(WINED3DFMT_R16);
01859         FMT_TO_STR(WINED3DFMT_AL16);
01860 #undef FMT_TO_STR
01861         default:
01862         {
01863             char fourcc[5];
01864             fourcc[0] = (char)(format_id);
01865             fourcc[1] = (char)(format_id >> 8);
01866             fourcc[2] = (char)(format_id >> 16);
01867             fourcc[3] = (char)(format_id >> 24);
01868             fourcc[4] = 0;
01869             if (isprint(fourcc[0]) && isprint(fourcc[1]) && isprint(fourcc[2]) && isprint(fourcc[3]))
01870                 FIXME("Unrecognized %#x (as fourcc: %s) WINED3DFORMAT!\n", format_id, fourcc);
01871             else
01872                 FIXME("Unrecognized %#x WINED3DFORMAT!\n", format_id);
01873         }
01874         return "unrecognized";
01875     }
01876 }
01877 
01878 const char *debug_d3ddevicetype(enum wined3d_device_type device_type)
01879 {
01880     switch (device_type)
01881     {
01882 #define DEVTYPE_TO_STR(dev) case dev: return #dev
01883         DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_HAL);
01884         DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_REF);
01885         DEVTYPE_TO_STR(WINED3D_DEVICE_TYPE_SW);
01886 #undef DEVTYPE_TO_STR
01887         default:
01888             FIXME("Unrecognized device type %#x.\n", device_type);
01889             return "unrecognized";
01890     }
01891 }
01892 
01893 const char *debug_d3dusage(DWORD usage)
01894 {
01895     char buf[333];
01896 
01897     buf[0] = '\0';
01898 #define WINED3DUSAGE_TO_STR(u) if (usage & u) { strcat(buf, " | "#u); usage &= ~u; }
01899     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RENDERTARGET);
01900     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DEPTHSTENCIL);
01901     WINED3DUSAGE_TO_STR(WINED3DUSAGE_WRITEONLY);
01902     WINED3DUSAGE_TO_STR(WINED3DUSAGE_SOFTWAREPROCESSING);
01903     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DONOTCLIP);
01904     WINED3DUSAGE_TO_STR(WINED3DUSAGE_POINTS);
01905     WINED3DUSAGE_TO_STR(WINED3DUSAGE_RTPATCHES);
01906     WINED3DUSAGE_TO_STR(WINED3DUSAGE_NPATCHES);
01907     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DYNAMIC);
01908     WINED3DUSAGE_TO_STR(WINED3DUSAGE_AUTOGENMIPMAP);
01909     WINED3DUSAGE_TO_STR(WINED3DUSAGE_DMAP);
01910     WINED3DUSAGE_TO_STR(WINED3DUSAGE_STATICDECL);
01911     WINED3DUSAGE_TO_STR(WINED3DUSAGE_OVERLAY);
01912 #undef WINED3DUSAGE_TO_STR
01913     if (usage) FIXME("Unrecognized usage flag(s) %#x\n", usage);
01914 
01915     return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
01916 }
01917 
01918 const char *debug_d3dusagequery(DWORD usagequery)
01919 {
01920     char buf[238];
01921 
01922     buf[0] = '\0';
01923 #define WINED3DUSAGEQUERY_TO_STR(u) if (usagequery & u) { strcat(buf, " | "#u); usagequery &= ~u; }
01924     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_FILTER);
01925     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
01926     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING);
01927     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBREAD);
01928     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_SRGBWRITE);
01929     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_VERTEXTEXTURE);
01930     WINED3DUSAGEQUERY_TO_STR(WINED3DUSAGE_QUERY_WRAPANDMIP);
01931 #undef WINED3DUSAGEQUERY_TO_STR
01932     if (usagequery) FIXME("Unrecognized usage query flag(s) %#x\n", usagequery);
01933 
01934     return buf[0] ? wine_dbg_sprintf("%s", &buf[3]) : "0";
01935 }
01936 
01937 const char* debug_d3ddeclmethod(WINED3DDECLMETHOD method) {
01938     switch (method) {
01939 #define WINED3DDECLMETHOD_TO_STR(u) case u: return #u
01940         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_DEFAULT);
01941         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALU);
01942         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_PARTIALV);
01943         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_CROSSUV);
01944         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_UV);
01945         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUP);
01946         WINED3DDECLMETHOD_TO_STR(WINED3DDECLMETHOD_LOOKUPPRESAMPLED);
01947 #undef WINED3DDECLMETHOD_TO_STR
01948         default:
01949             FIXME("Unrecognized %u declaration method!\n", method);
01950             return "unrecognized";
01951     }
01952 }
01953 
01954 const char* debug_d3ddeclusage(BYTE usage) {
01955     switch (usage) {
01956 #define WINED3DDECLUSAGE_TO_STR(u) case u: return #u
01957         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITION);
01958         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDWEIGHT);
01959         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BLENDINDICES);
01960         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_NORMAL);
01961         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_PSIZE);
01962         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TEXCOORD);
01963         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TANGENT);
01964         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_BINORMAL);
01965         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_TESSFACTOR);
01966         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_POSITIONT);
01967         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_COLOR);
01968         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_FOG);
01969         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_DEPTH);
01970         WINED3DDECLUSAGE_TO_STR(WINED3DDECLUSAGE_SAMPLE);
01971 #undef WINED3DDECLUSAGE_TO_STR
01972         default:
01973             FIXME("Unrecognized %u declaration usage!\n", usage);
01974             return "unrecognized";
01975     }
01976 }
01977 
01978 const char *debug_d3dresourcetype(enum wined3d_resource_type resource_type)
01979 {
01980     switch (resource_type)
01981     {
01982 #define RES_TO_STR(res) case res: return #res
01983         RES_TO_STR(WINED3D_RTYPE_SURFACE);
01984         RES_TO_STR(WINED3D_RTYPE_VOLUME);
01985         RES_TO_STR(WINED3D_RTYPE_TEXTURE);
01986         RES_TO_STR(WINED3D_RTYPE_VOLUME_TEXTURE);
01987         RES_TO_STR(WINED3D_RTYPE_CUBE_TEXTURE);
01988         RES_TO_STR(WINED3D_RTYPE_BUFFER);
01989 #undef  RES_TO_STR
01990         default:
01991             FIXME("Unrecognized resource type %#x.\n", resource_type);
01992             return "unrecognized";
01993     }
01994 }
01995 
01996 const char *debug_d3dprimitivetype(enum wined3d_primitive_type primitive_type)
01997 {
01998     switch (primitive_type)
01999     {
02000 #define PRIM_TO_STR(prim) case prim: return #prim
02001         PRIM_TO_STR(WINED3D_PT_UNDEFINED);
02002         PRIM_TO_STR(WINED3D_PT_POINTLIST);
02003         PRIM_TO_STR(WINED3D_PT_LINELIST);
02004         PRIM_TO_STR(WINED3D_PT_LINESTRIP);
02005         PRIM_TO_STR(WINED3D_PT_TRIANGLELIST);
02006         PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP);
02007         PRIM_TO_STR(WINED3D_PT_TRIANGLEFAN);
02008         PRIM_TO_STR(WINED3D_PT_LINELIST_ADJ);
02009         PRIM_TO_STR(WINED3D_PT_LINESTRIP_ADJ);
02010         PRIM_TO_STR(WINED3D_PT_TRIANGLELIST_ADJ);
02011         PRIM_TO_STR(WINED3D_PT_TRIANGLESTRIP_ADJ);
02012 #undef  PRIM_TO_STR
02013         default:
02014             FIXME("Unrecognized %u primitive type!\n", primitive_type);
02015             return "unrecognized";
02016     }
02017 }
02018 
02019 const char *debug_d3drenderstate(enum wined3d_render_state state)
02020 {
02021     switch (state)
02022     {
02023 #define D3DSTATE_TO_STR(u) case u: return #u
02024         D3DSTATE_TO_STR(WINED3D_RS_ANTIALIAS);
02025         D3DSTATE_TO_STR(WINED3D_RS_TEXTUREPERSPECTIVE);
02026         D3DSTATE_TO_STR(WINED3D_RS_WRAPU);
02027         D3DSTATE_TO_STR(WINED3D_RS_WRAPV);
02028         D3DSTATE_TO_STR(WINED3D_RS_ZENABLE);
02029         D3DSTATE_TO_STR(WINED3D_RS_FILLMODE);
02030         D3DSTATE_TO_STR(WINED3D_RS_SHADEMODE);
02031         D3DSTATE_TO_STR(WINED3D_RS_LINEPATTERN);
02032         D3DSTATE_TO_STR(WINED3D_RS_MONOENABLE);
02033         D3DSTATE_TO_STR(WINED3D_RS_ROP2);
02034         D3DSTATE_TO_STR(WINED3D_RS_PLANEMASK);
02035         D3DSTATE_TO_STR(WINED3D_RS_ZWRITEENABLE);
02036         D3DSTATE_TO_STR(WINED3D_RS_ALPHATESTENABLE);
02037         D3DSTATE_TO_STR(WINED3D_RS_LASTPIXEL);
02038         D3DSTATE_TO_STR(WINED3D_RS_SRCBLEND);
02039         D3DSTATE_TO_STR(WINED3D_RS_DESTBLEND);
02040         D3DSTATE_TO_STR(WINED3D_RS_CULLMODE);
02041         D3DSTATE_TO_STR(WINED3D_RS_ZFUNC);
02042         D3DSTATE_TO_STR(WINED3D_RS_ALPHAREF);
02043         D3DSTATE_TO_STR(WINED3D_RS_ALPHAFUNC);
02044         D3DSTATE_TO_STR(WINED3D_RS_DITHERENABLE);
02045         D3DSTATE_TO_STR(WINED3D_RS_ALPHABLENDENABLE);
02046         D3DSTATE_TO_STR(WINED3D_RS_FOGENABLE);
02047         D3DSTATE_TO_STR(WINED3D_RS_SPECULARENABLE);
02048         D3DSTATE_TO_STR(WINED3D_RS_ZVISIBLE);
02049         D3DSTATE_TO_STR(WINED3D_RS_SUBPIXEL);
02050         D3DSTATE_TO_STR(WINED3D_RS_SUBPIXELX);
02051         D3DSTATE_TO_STR(WINED3D_RS_STIPPLEDALPHA);
02052         D3DSTATE_TO_STR(WINED3D_RS_FOGCOLOR);
02053         D3DSTATE_TO_STR(WINED3D_RS_FOGTABLEMODE);
02054         D3DSTATE_TO_STR(WINED3D_RS_FOGSTART);
02055         D3DSTATE_TO_STR(WINED3D_RS_FOGEND);
02056         D3DSTATE_TO_STR(WINED3D_RS_FOGDENSITY);
02057         D3DSTATE_TO_STR(WINED3D_RS_STIPPLEENABLE);
02058         D3DSTATE_TO_STR(WINED3D_RS_EDGEANTIALIAS);
02059         D3DSTATE_TO_STR(WINED3D_RS_COLORKEYENABLE);
02060         D3DSTATE_TO_STR(WINED3D_RS_MIPMAPLODBIAS);
02061         D3DSTATE_TO_STR(WINED3D_RS_RANGEFOGENABLE);
02062         D3DSTATE_TO_STR(WINED3D_RS_ANISOTROPY);
02063         D3DSTATE_TO_STR(WINED3D_RS_FLUSHBATCH);
02064         D3DSTATE_TO_STR(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT);
02065         D3DSTATE_TO_STR(WINED3D_RS_STENCILENABLE);
02066         D3DSTATE_TO_STR(WINED3D_RS_STENCILFAIL);
02067         D3DSTATE_TO_STR(WINED3D_RS_STENCILZFAIL);
02068         D3DSTATE_TO_STR(WINED3D_RS_STENCILPASS);
02069         D3DSTATE_TO_STR(WINED3D_RS_STENCILFUNC);
02070         D3DSTATE_TO_STR(WINED3D_RS_STENCILREF);
02071         D3DSTATE_TO_STR(WINED3D_RS_STENCILMASK);
02072         D3DSTATE_TO_STR(WINED3D_RS_STENCILWRITEMASK);
02073         D3DSTATE_TO_STR(WINED3D_RS_TEXTUREFACTOR);
02074         D3DSTATE_TO_STR(WINED3D_RS_WRAP0);
02075         D3DSTATE_TO_STR(WINED3D_RS_WRAP1);
02076         D3DSTATE_TO_STR(WINED3D_RS_WRAP2);
02077         D3DSTATE_TO_STR(WINED3D_RS_WRAP3);
02078         D3DSTATE_TO_STR(WINED3D_RS_WRAP4);
02079         D3DSTATE_TO_STR(WINED3D_RS_WRAP5);
02080         D3DSTATE_TO_STR(WINED3D_RS_WRAP6);
02081         D3DSTATE_TO_STR(WINED3D_RS_WRAP7);
02082         D3DSTATE_TO_STR(WINED3D_RS_CLIPPING);
02083         D3DSTATE_TO_STR(WINED3D_RS_LIGHTING);
02084         D3DSTATE_TO_STR(WINED3D_RS_EXTENTS);
02085         D3DSTATE_TO_STR(WINED3D_RS_AMBIENT);
02086         D3DSTATE_TO_STR(WINED3D_RS_FOGVERTEXMODE);
02087         D3DSTATE_TO_STR(WINED3D_RS_COLORVERTEX);
02088         D3DSTATE_TO_STR(WINED3D_RS_LOCALVIEWER);
02089         D3DSTATE_TO_STR(WINED3D_RS_NORMALIZENORMALS);
02090         D3DSTATE_TO_STR(WINED3D_RS_COLORKEYBLENDENABLE);
02091         D3DSTATE_TO_STR(WINED3D_RS_DIFFUSEMATERIALSOURCE);
02092         D3DSTATE_TO_STR(WINED3D_RS_SPECULARMATERIALSOURCE);
02093         D3DSTATE_TO_STR(WINED3D_RS_AMBIENTMATERIALSOURCE);
02094         D3DSTATE_TO_STR(WINED3D_RS_EMISSIVEMATERIALSOURCE);
02095         D3DSTATE_TO_STR(WINED3D_RS_VERTEXBLEND);
02096         D3DSTATE_TO_STR(WINED3D_RS_CLIPPLANEENABLE);
02097         D3DSTATE_TO_STR(WINED3D_RS_SOFTWAREVERTEXPROCESSING);
02098         D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE);
02099         D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MIN);
02100         D3DSTATE_TO_STR(WINED3D_RS_POINTSPRITEENABLE);
02101         D3DSTATE_TO_STR(WINED3D_RS_POINTSCALEENABLE);
02102         D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_A);
02103         D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_B);
02104         D3DSTATE_TO_STR(WINED3D_RS_POINTSCALE_C);
02105         D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEANTIALIAS);
02106         D3DSTATE_TO_STR(WINED3D_RS_MULTISAMPLEMASK);
02107         D3DSTATE_TO_STR(WINED3D_RS_PATCHEDGESTYLE);
02108         D3DSTATE_TO_STR(WINED3D_RS_PATCHSEGMENTS);
02109         D3DSTATE_TO_STR(WINED3D_RS_DEBUGMONITORTOKEN);
02110         D3DSTATE_TO_STR(WINED3D_RS_POINTSIZE_MAX);
02111         D3DSTATE_TO_STR(WINED3D_RS_INDEXEDVERTEXBLENDENABLE);
02112         D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE);
02113         D3DSTATE_TO_STR(WINED3D_RS_TWEENFACTOR);
02114         D3DSTATE_TO_STR(WINED3D_RS_BLENDOP);
02115         D3DSTATE_TO_STR(WINED3D_RS_POSITIONDEGREE);
02116         D3DSTATE_TO_STR(WINED3D_RS_NORMALDEGREE);
02117         D3DSTATE_TO_STR(WINED3D_RS_SCISSORTESTENABLE);
02118         D3DSTATE_TO_STR(WINED3D_RS_SLOPESCALEDEPTHBIAS);
02119         D3DSTATE_TO_STR(WINED3D_RS_ANTIALIASEDLINEENABLE);
02120         D3DSTATE_TO_STR(WINED3D_RS_MINTESSELLATIONLEVEL);
02121         D3DSTATE_TO_STR(WINED3D_RS_MAXTESSELLATIONLEVEL);
02122         D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_X);
02123         D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Y);
02124         D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_Z);
02125         D3DSTATE_TO_STR(WINED3D_RS_ADAPTIVETESS_W);
02126         D3DSTATE_TO_STR(WINED3D_RS_ENABLEADAPTIVETESSELLATION);
02127         D3DSTATE_TO_STR(WINED3D_RS_TWOSIDEDSTENCILMODE);
02128         D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFAIL);
02129         D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILZFAIL);
02130         D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILPASS);
02131         D3DSTATE_TO_STR(WINED3D_RS_CCW_STENCILFUNC);
02132         D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE1);
02133         D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE2);
02134         D3DSTATE_TO_STR(WINED3D_RS_COLORWRITEENABLE3);
02135         D3DSTATE_TO_STR(WINED3D_RS_BLENDFACTOR);
02136         D3DSTATE_TO_STR(WINED3D_RS_SRGBWRITEENABLE);
02137         D3DSTATE_TO_STR(WINED3D_RS_DEPTHBIAS);
02138         D3DSTATE_TO_STR(WINED3D_RS_WRAP8);
02139         D3DSTATE_TO_STR(WINED3D_RS_WRAP9);
02140         D3DSTATE_TO_STR(WINED3D_RS_WRAP10);
02141         D3DSTATE_TO_STR(WINED3D_RS_WRAP11);
02142         D3DSTATE_TO_STR(WINED3D_RS_WRAP12);
02143         D3DSTATE_TO_STR(WINED3D_RS_WRAP13);
02144         D3DSTATE_TO_STR(WINED3D_RS_WRAP14);
02145         D3DSTATE_TO_STR(WINED3D_RS_WRAP15);
02146         D3DSTATE_TO_STR(WINED3D_RS_SEPARATEALPHABLENDENABLE);
02147         D3DSTATE_TO_STR(WINED3D_RS_SRCBLENDALPHA);
02148         D3DSTATE_TO_STR(WINED3D_RS_DESTBLENDALPHA);
02149         D3DSTATE_TO_STR(WINED3D_RS_BLENDOPALPHA);
02150 #undef D3DSTATE_TO_STR
02151         default:
02152             FIXME("Unrecognized %u render state!\n", state);
02153             return "unrecognized";
02154     }
02155 }
02156 
02157 const char *debug_d3dsamplerstate(enum wined3d_sampler_state state)
02158 {
02159     switch (state)
02160     {
02161 #define D3DSTATE_TO_STR(u) case u: return #u
02162         D3DSTATE_TO_STR(WINED3D_SAMP_BORDER_COLOR);
02163         D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_U);
02164         D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_V);
02165         D3DSTATE_TO_STR(WINED3D_SAMP_ADDRESS_W);
02166         D3DSTATE_TO_STR(WINED3D_SAMP_MAG_FILTER);
02167         D3DSTATE_TO_STR(WINED3D_SAMP_MIN_FILTER);
02168         D3DSTATE_TO_STR(WINED3D_SAMP_MIP_FILTER);
02169         D3DSTATE_TO_STR(WINED3D_SAMP_MIPMAP_LOD_BIAS);
02170         D3DSTATE_TO_STR(WINED3D_SAMP_MAX_MIP_LEVEL);
02171         D3DSTATE_TO_STR(WINED3D_SAMP_MAX_ANISOTROPY);
02172         D3DSTATE_TO_STR(WINED3D_SAMP_SRGB_TEXTURE);
02173         D3DSTATE_TO_STR(WINED3D_SAMP_ELEMENT_INDEX);
02174         D3DSTATE_TO_STR(WINED3D_SAMP_DMAP_OFFSET);
02175 #undef D3DSTATE_TO_STR
02176         default:
02177             FIXME("Unrecognized %u sampler state!\n", state);
02178             return "unrecognized";
02179     }
02180 }
02181 
02182 const char *debug_d3dtexturefiltertype(enum wined3d_texture_filter_type filter_type)
02183 {
02184     switch (filter_type)
02185     {
02186 #define D3DTEXTUREFILTERTYPE_TO_STR(u) case u: return #u
02187         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_NONE);
02188         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_POINT);
02189         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_LINEAR);
02190         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_ANISOTROPIC);
02191         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_FLAT_CUBIC);
02192         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_CUBIC);
02193         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_PYRAMIDAL_QUAD);
02194         D3DTEXTUREFILTERTYPE_TO_STR(WINED3D_TEXF_GAUSSIAN_QUAD);
02195 #undef D3DTEXTUREFILTERTYPE_TO_STR
02196         default:
02197             FIXME("Unrecognied texture filter type 0x%08x.\n", filter_type);
02198             return "unrecognized";
02199     }
02200 }
02201 
02202 const char *debug_d3dtexturestate(enum wined3d_texture_stage_state state)
02203 {
02204     switch (state)
02205     {
02206 #define D3DSTATE_TO_STR(u) case u: return #u
02207         D3DSTATE_TO_STR(WINED3D_TSS_COLOR_OP);
02208         D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG1);
02209         D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG2);
02210         D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_OP);
02211         D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG1);
02212         D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG2);
02213         D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT00);
02214         D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT01);
02215         D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT10);
02216         D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_MAT11);
02217         D3DSTATE_TO_STR(WINED3D_TSS_TEXCOORD_INDEX);
02218         D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LSCALE);
02219         D3DSTATE_TO_STR(WINED3D_TSS_BUMPENV_LOFFSET);
02220         D3DSTATE_TO_STR(WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS);
02221         D3DSTATE_TO_STR(WINED3D_TSS_COLOR_ARG0);
02222         D3DSTATE_TO_STR(WINED3D_TSS_ALPHA_ARG0);
02223         D3DSTATE_TO_STR(WINED3D_TSS_RESULT_ARG);
02224         D3DSTATE_TO_STR(WINED3D_TSS_CONSTANT);
02225 #undef D3DSTATE_TO_STR
02226         default:
02227             FIXME("Unrecognized %u texture state!\n", state);
02228             return "unrecognized";
02229     }
02230 }
02231 
02232 const char *debug_d3dtop(enum wined3d_texture_op d3dtop)
02233 {
02234     switch (d3dtop)
02235     {
02236 #define D3DTOP_TO_STR(u) case u: return #u
02237         D3DTOP_TO_STR(WINED3D_TOP_DISABLE);
02238         D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG1);
02239         D3DTOP_TO_STR(WINED3D_TOP_SELECT_ARG2);
02240         D3DTOP_TO_STR(WINED3D_TOP_MODULATE);
02241         D3DTOP_TO_STR(WINED3D_TOP_MODULATE_2X);
02242         D3DTOP_TO_STR(WINED3D_TOP_MODULATE_4X);
02243         D3DTOP_TO_STR(WINED3D_TOP_ADD);
02244         D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED);
02245         D3DTOP_TO_STR(WINED3D_TOP_ADD_SIGNED_2X);
02246         D3DTOP_TO_STR(WINED3D_TOP_SUBTRACT);
02247         D3DTOP_TO_STR(WINED3D_TOP_ADD_SMOOTH);
02248         D3DTOP_TO_STR(WINED3D_TOP_BLEND_DIFFUSE_ALPHA);
02249         D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA);
02250         D3DTOP_TO_STR(WINED3D_TOP_BLEND_FACTOR_ALPHA);
02251         D3DTOP_TO_STR(WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM);
02252         D3DTOP_TO_STR(WINED3D_TOP_BLEND_CURRENT_ALPHA);
02253         D3DTOP_TO_STR(WINED3D_TOP_PREMODULATE);
02254         D3DTOP_TO_STR(WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR);
02255         D3DTOP_TO_STR(WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA);
02256         D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR);
02257         D3DTOP_TO_STR(WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA);
02258         D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP);
02259         D3DTOP_TO_STR(WINED3D_TOP_BUMPENVMAP_LUMINANCE);
02260         D3DTOP_TO_STR(WINED3D_TOP_DOTPRODUCT3);
02261         D3DTOP_TO_STR(WINED3D_TOP_MULTIPLY_ADD);
02262         D3DTOP_TO_STR(WINED3D_TOP_LERP);
02263 #undef D3DTOP_TO_STR
02264         default:
02265             FIXME("Unrecognized texture op %#x.\n", d3dtop);
02266             return "unrecognized";
02267     }
02268 }
02269 
02270 const char *debug_d3dtstype(enum wined3d_transform_state tstype)
02271 {
02272     switch (tstype)
02273     {
02274 #define TSTYPE_TO_STR(tstype) case tstype: return #tstype
02275     TSTYPE_TO_STR(WINED3D_TS_VIEW);
02276     TSTYPE_TO_STR(WINED3D_TS_PROJECTION);
02277     TSTYPE_TO_STR(WINED3D_TS_TEXTURE0);
02278     TSTYPE_TO_STR(WINED3D_TS_TEXTURE1);
02279     TSTYPE_TO_STR(WINED3D_TS_TEXTURE2);
02280     TSTYPE_TO_STR(WINED3D_TS_TEXTURE3);
02281     TSTYPE_TO_STR(WINED3D_TS_TEXTURE4);
02282     TSTYPE_TO_STR(WINED3D_TS_TEXTURE5);
02283     TSTYPE_TO_STR(WINED3D_TS_TEXTURE6);
02284     TSTYPE_TO_STR(WINED3D_TS_TEXTURE7);
02285     TSTYPE_TO_STR(WINED3D_TS_WORLD_MATRIX(0));
02286 #undef TSTYPE_TO_STR
02287     default:
02288         if (tstype > 256 && tstype < 512)
02289         {
02290             FIXME("WINED3D_TS_WORLD_MATRIX(%u). 1..255 not currently supported.\n", tstype);
02291             return ("WINED3D_TS_WORLD_MATRIX > 0");
02292         }
02293         FIXME("Unrecognized transform state %#x.\n", tstype);
02294         return "unrecognized";
02295     }
02296 }
02297 
02298 const char *debug_d3dstate(DWORD state)
02299 {
02300     if (STATE_IS_RENDER(state))
02301         return wine_dbg_sprintf("STATE_RENDER(%s)", debug_d3drenderstate(state - STATE_RENDER(0)));
02302     if (STATE_IS_TEXTURESTAGE(state))
02303     {
02304         DWORD texture_stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
02305         DWORD texture_state = state - STATE_TEXTURESTAGE(texture_stage, 0);
02306         return wine_dbg_sprintf("STATE_TEXTURESTAGE(%#x, %s)",
02307                 texture_stage, debug_d3dtexturestate(texture_state));
02308     }
02309     if (STATE_IS_SAMPLER(state))
02310         return wine_dbg_sprintf("STATE_SAMPLER(%#x)", state - STATE_SAMPLER(0));
02311     if (STATE_IS_PIXELSHADER(state))
02312         return "STATE_PIXELSHADER";
02313     if (STATE_IS_TRANSFORM(state))
02314         return wine_dbg_sprintf("STATE_TRANSFORM(%s)", debug_d3dtstype(state - STATE_TRANSFORM(0)));
02315     if (STATE_IS_STREAMSRC(state))
02316         return "STATE_STREAMSRC";
02317     if (STATE_IS_INDEXBUFFER(state))
02318         return "STATE_INDEXBUFFER";
02319     if (STATE_IS_VDECL(state))
02320         return "STATE_VDECL";
02321     if (STATE_IS_VSHADER(state))
02322         return "STATE_VSHADER";
02323     if (STATE_IS_VIEWPORT(state))
02324         return "STATE_VIEWPORT";
02325     if (STATE_IS_VERTEXSHADERCONSTANT(state))
02326         return "STATE_VERTEXSHADERCONSTANT";
02327     if (STATE_IS_PIXELSHADERCONSTANT(state))
02328         return "STATE_PIXELSHADERCONSTANT";
02329     if (STATE_IS_ACTIVELIGHT(state))
02330         return wine_dbg_sprintf("STATE_ACTIVELIGHT(%#x)", state - STATE_ACTIVELIGHT(0));
02331     if (STATE_IS_SCISSORRECT(state))
02332         return "STATE_SCISSORRECT";
02333     if (STATE_IS_CLIPPLANE(state))
02334         return wine_dbg_sprintf("STATE_CLIPPLANE(%#x)", state - STATE_CLIPPLANE(0));
02335     if (STATE_IS_MATERIAL(state))
02336         return "STATE_MATERIAL";
02337     if (STATE_IS_FRONTFACE(state))
02338         return "STATE_FRONTFACE";
02339     if (STATE_IS_POINTSPRITECOORDORIGIN(state))
02340         return "STATE_POINTSPRITECOORDORIGIN";
02341     if (STATE_IS_BASEVERTEXINDEX(state))
02342         return "STATE_BASEVERTEXINDEX";
02343     if (STATE_IS_FRAMEBUFFER(state))
02344         return "STATE_FRAMEBUFFER";
02345 
02346     return wine_dbg_sprintf("UNKNOWN_STATE(%#x)", state);
02347 }
02348 
02349 const char *debug_d3dpool(enum wined3d_pool pool)
02350 {
02351     switch (pool)
02352     {
02353 #define POOL_TO_STR(p) case p: return #p
02354         POOL_TO_STR(WINED3D_POOL_DEFAULT);
02355         POOL_TO_STR(WINED3D_POOL_MANAGED);
02356         POOL_TO_STR(WINED3D_POOL_SYSTEM_MEM);
02357         POOL_TO_STR(WINED3D_POOL_SCRATCH);
02358 #undef  POOL_TO_STR
02359         default:
02360             FIXME("Unrecognized pool %#x.\n", pool);
02361             return "unrecognized";
02362     }
02363 }
02364 
02365 const char *debug_fbostatus(GLenum status) {
02366     switch(status) {
02367 #define FBOSTATUS_TO_STR(u) case u: return #u
02368         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_COMPLETE);
02369         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
02370         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
02371         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT);
02372         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT);
02373         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
02374         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
02375         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
02376         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNSUPPORTED);
02377         FBOSTATUS_TO_STR(GL_FRAMEBUFFER_UNDEFINED);
02378 #undef FBOSTATUS_TO_STR
02379         default:
02380             FIXME("Unrecognied FBO status 0x%08x\n", status);
02381             return "unrecognized";
02382     }
02383 }
02384 
02385 const char *debug_glerror(GLenum error) {
02386     switch(error) {
02387 #define GLERROR_TO_STR(u) case u: return #u
02388         GLERROR_TO_STR(GL_NO_ERROR);
02389         GLERROR_TO_STR(GL_INVALID_ENUM);
02390         GLERROR_TO_STR(GL_INVALID_VALUE);
02391         GLERROR_TO_STR(GL_INVALID_OPERATION);
02392         GLERROR_TO_STR(GL_STACK_OVERFLOW);
02393         GLERROR_TO_STR(GL_STACK_UNDERFLOW);
02394         GLERROR_TO_STR(GL_OUT_OF_MEMORY);
02395         GLERROR_TO_STR(GL_INVALID_FRAMEBUFFER_OPERATION);
02396 #undef GLERROR_TO_STR
02397         default:
02398             FIXME("Unrecognied GL error 0x%08x\n", error);
02399             return "unrecognized";
02400     }
02401 }
02402 
02403 const char *debug_d3dbasis(enum wined3d_basis_type basis)
02404 {
02405     switch (basis)
02406     {
02407         case WINED3D_BASIS_BEZIER:      return "WINED3D_BASIS_BEZIER";
02408         case WINED3D_BASIS_BSPLINE:     return "WINED3D_BASIS_BSPLINE";
02409         case WINED3D_BASIS_INTERPOLATE: return "WINED3D_BASIS_INTERPOLATE";
02410         default:                        return "unrecognized";
02411     }
02412 }
02413 
02414 const char *debug_d3ddegree(enum wined3d_degree_type degree)
02415 {
02416     switch (degree)
02417     {
02418         case WINED3D_DEGREE_LINEAR:     return "WINED3D_DEGREE_LINEAR";
02419         case WINED3D_DEGREE_QUADRATIC:  return "WINED3D_DEGREE_QUADRATIC";
02420         case WINED3D_DEGREE_CUBIC:      return "WINED3D_DEGREE_CUBIC";
02421         case WINED3D_DEGREE_QUINTIC:    return "WINED3D_DEGREE_QUINTIC";
02422         default:                        return "unrecognized";
02423     }
02424 }
02425 
02426 static const char *debug_fixup_channel_source(enum fixup_channel_source source)
02427 {
02428     switch(source)
02429     {
02430 #define WINED3D_TO_STR(x) case x: return #x
02431         WINED3D_TO_STR(CHANNEL_SOURCE_ZERO);
02432         WINED3D_TO_STR(CHANNEL_SOURCE_ONE);
02433         WINED3D_TO_STR(CHANNEL_SOURCE_X);
02434         WINED3D_TO_STR(CHANNEL_SOURCE_Y);
02435         WINED3D_TO_STR(CHANNEL_SOURCE_Z);
02436         WINED3D_TO_STR(CHANNEL_SOURCE_W);
02437         WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX0);
02438         WINED3D_TO_STR(CHANNEL_SOURCE_COMPLEX1);
02439 #undef WINED3D_TO_STR
02440         default:
02441             FIXME("Unrecognized fixup_channel_source %#x\n", source);
02442             return "unrecognized";
02443     }
02444 }
02445 
02446 static const char *debug_complex_fixup(enum complex_fixup fixup)
02447 {
02448     switch(fixup)
02449     {
02450 #define WINED3D_TO_STR(x) case x: return #x
02451         WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
02452         WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
02453         WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
02454         WINED3D_TO_STR(COMPLEX_FIXUP_P8);
02455 #undef WINED3D_TO_STR
02456         default:
02457             FIXME("Unrecognized complex fixup %#x\n", fixup);
02458             return "unrecognized";
02459     }
02460 }
02461 
02462 void dump_color_fixup_desc(struct color_fixup_desc fixup)
02463 {
02464     if (is_complex_fixup(fixup))
02465     {
02466         TRACE("\tComplex: %s\n", debug_complex_fixup(get_complex_fixup(fixup)));
02467         return;
02468     }
02469 
02470     TRACE("\tX: %s%s\n", debug_fixup_channel_source(fixup.x_source), fixup.x_sign_fixup ? ", SIGN_FIXUP" : "");
02471     TRACE("\tY: %s%s\n", debug_fixup_channel_source(fixup.y_source), fixup.y_sign_fixup ? ", SIGN_FIXUP" : "");
02472     TRACE("\tZ: %s%s\n", debug_fixup_channel_source(fixup.z_source), fixup.z_sign_fixup ? ", SIGN_FIXUP" : "");
02473     TRACE("\tW: %s%s\n", debug_fixup_channel_source(fixup.w_source), fixup.w_sign_fixup ? ", SIGN_FIXUP" : "");
02474 }
02475 
02476 const char *debug_surflocation(DWORD flag) {
02477     char buf[128];
02478 
02479     buf[0] = 0;
02480     if (flag & SFLAG_INSYSMEM) strcat(buf, " | SFLAG_INSYSMEM");                    /* 17 */
02481     if (flag & SFLAG_INDRAWABLE) strcat(buf, " | SFLAG_INDRAWABLE");                /* 19 */
02482     if (flag & SFLAG_INTEXTURE) strcat(buf, " | SFLAG_INTEXTURE");                  /* 18 */
02483     if (flag & SFLAG_INSRGBTEX) strcat(buf, " | SFLAG_INSRGBTEX");                  /* 18 */
02484     if (flag & SFLAG_INRB_MULTISAMPLE) strcat(buf, " | SFLAG_INRB_MULTISAMPLE");    /* 25 */
02485     if (flag & SFLAG_INRB_RESOLVED) strcat(buf, " | SFLAG_INRB_RESOLVED");          /* 22 */
02486     return wine_dbg_sprintf("%s", buf[0] ? buf + 3 : "0");
02487 }
02488 
02489 BOOL is_invalid_op(const struct wined3d_state *state, int stage,
02490         enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
02491 {
02492     if (op == WINED3D_TOP_DISABLE)
02493         return FALSE;
02494     if (state->textures[stage])
02495         return FALSE;
02496 
02497     if ((arg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
02498             && op != WINED3D_TOP_SELECT_ARG2)
02499         return TRUE;
02500     if ((arg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
02501             && op != WINED3D_TOP_SELECT_ARG1)
02502         return TRUE;
02503     if ((arg3 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
02504             && (op == WINED3D_TOP_MULTIPLY_ADD || op == WINED3D_TOP_LERP))
02505         return TRUE;
02506 
02507     return FALSE;
02508 }
02509 
02510 /* Setup this textures matrix according to the texture flags*/
02511 /* GL locking is done by the caller (state handler) */
02512 void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed,
02513         enum wined3d_format_id vtx_fmt, BOOL ffp_proj_control)
02514 {
02515     float mat[16];
02516 
02517     glMatrixMode(GL_TEXTURE);
02518     checkGLcall("glMatrixMode(GL_TEXTURE)");
02519 
02520     if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed)
02521     {
02522         glLoadIdentity();
02523         checkGLcall("glLoadIdentity()");
02524         return;
02525     }
02526 
02527     if (flags == (WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED))
02528     {
02529         ERR("Invalid texture transform flags: WINED3D_TTFF_COUNT1 | WINED3D_TTFF_PROJECTED.\n");
02530         return;
02531     }
02532 
02533     memcpy(mat, smat, 16 * sizeof(float));
02534 
02535     if (flags & WINED3D_TTFF_PROJECTED)
02536     {
02537         if (!ffp_proj_control)
02538         {
02539             switch (flags & ~WINED3D_TTFF_PROJECTED)
02540             {
02541                 case WINED3D_TTFF_COUNT2:
02542                     mat[ 3] = mat[ 1];
02543                     mat[ 7] = mat[ 5];
02544                     mat[11] = mat[ 9];
02545                     mat[15] = mat[13];
02546                     mat[ 1] = mat[ 5] = mat[ 9] = mat[13] = 0.0f;
02547                     break;
02548                 case WINED3D_TTFF_COUNT3:
02549                     mat[ 3] = mat[ 2];
02550                     mat[ 7] = mat[ 6];
02551                     mat[11] = mat[10];
02552                     mat[15] = mat[14];
02553                     mat[ 2] = mat[ 6] = mat[10] = mat[14] = 0.0f;
02554                     break;
02555             }
02556         }
02557     } else { /* under directx the R/Z coord can be used for translation, under opengl we use the Q coord instead */
02558         if(!calculatedCoords) {
02559             switch(vtx_fmt)
02560             {
02561                 case WINED3DFMT_R32_FLOAT:
02562                     /* Direct3D passes the default 1.0 in the 2nd coord, while gl passes it in the 4th.
02563                      * swap 2nd and 4th coord. No need to store the value of mat[12] in mat[4] because
02564                      * the input value to the transformation will be 0, so the matrix value is irrelevant
02565                      */
02566                     mat[12] = mat[4];
02567                     mat[13] = mat[5];
02568                     mat[14] = mat[6];
02569                     mat[15] = mat[7];
02570                     break;
02571                 case WINED3DFMT_R32G32_FLOAT:
02572                     /* See above, just 3rd and 4th coord
02573                     */
02574                     mat[12] = mat[8];
02575                     mat[13] = mat[9];
02576                     mat[14] = mat[10];
02577                     mat[15] = mat[11];
02578                     break;
02579                 case WINED3DFMT_R32G32B32_FLOAT: /* Opengl defaults match dx defaults */
02580                 case WINED3DFMT_R32G32B32A32_FLOAT: /* No defaults apply, all app defined */
02581 
02582                 /* This is to prevent swapping the matrix lines and put the default 4th coord = 1.0
02583                  * into a bad place. The division elimination below will apply to make sure the
02584                  * 1.0 doesn't do anything bad. The caller will set this value if the stride is 0
02585                  */
02586                 case WINED3DFMT_UNKNOWN: /* No texture coords, 0/0/0/1 defaults are passed */
02587                     break;
02588                 default:
02589                     FIXME("Unexpected fixed function texture coord input\n");
02590             }
02591         }
02592         if (!ffp_proj_control)
02593         {
02594             switch (flags & ~WINED3D_TTFF_PROJECTED)
02595             {
02596                 /* case WINED3D_TTFF_COUNT1: Won't ever get here. */
02597                 case WINED3D_TTFF_COUNT2:
02598                     mat[2] = mat[6] = mat[10] = mat[14] = 0;
02599                 /* OpenGL divides the first 3 vertex coord by the 4th by default,
02600                 * which is essentially the same as D3DTTFF_PROJECTED. Make sure that
02601                 * the 4th coord evaluates to 1.0 to eliminate that.
02602                 *
02603                 * If the fixed function pipeline is used, the 4th value remains unused,
02604                 * so there is no danger in doing this. With vertex shaders we have a
02605                 * problem. Should an app hit that problem, the code here would have to
02606                 * check for pixel shaders, and the shader has to undo the default gl divide.
02607                 *
02608                 * A more serious problem occurs if the app passes 4 coordinates in, and the
02609                 * 4th is != 1.0(opengl default). This would have to be fixed in drawStridedSlow
02610                 * or a replacement shader. */
02611                 default:
02612                     mat[3] = mat[7] = mat[11] = 0; mat[15] = 1;
02613             }
02614         }
02615     }
02616 
02617     glLoadMatrixf(mat);
02618     checkGLcall("glLoadMatrixf(mat)");
02619 }
02620 
02621 /* This small helper function is used to convert a bitmask into the number of masked bits */
02622 unsigned int count_bits(unsigned int mask)
02623 {
02624     unsigned int count;
02625     for (count = 0; mask; ++count)
02626     {
02627         mask &= mask - 1;
02628     }
02629     return count;
02630 }
02631 
02632 /* Helper function for retrieving color info for ChoosePixelFormat and wglChoosePixelFormatARB.
02633  * The later function requires individual color components. */
02634 BOOL getColorBits(const struct wined3d_format *format,
02635         BYTE *redSize, BYTE *greenSize, BYTE *blueSize, BYTE *alphaSize, BYTE *totalSize)
02636 {
02637     TRACE("format %s.\n", debug_d3dformat(format->id));
02638 
02639     switch (format->id)
02640     {
02641         case WINED3DFMT_B10G10R10A2_UNORM:
02642         case WINED3DFMT_R10G10B10A2_UNORM:
02643         case WINED3DFMT_B8G8R8X8_UNORM:
02644         case WINED3DFMT_B8G8R8_UNORM:
02645         case WINED3DFMT_B8G8R8A8_UNORM:
02646         case WINED3DFMT_R8G8B8A8_UNORM:
02647         case WINED3DFMT_B5G5R5X1_UNORM:
02648         case WINED3DFMT_B5G5R5A1_UNORM:
02649         case WINED3DFMT_B5G6R5_UNORM:
02650         case WINED3DFMT_B4G4R4X4_UNORM:
02651         case WINED3DFMT_B4G4R4A4_UNORM:
02652         case WINED3DFMT_B2G3R3_UNORM:
02653         case WINED3DFMT_P8_UINT_A8_UNORM:
02654         case WINED3DFMT_P8_UINT:
02655             break;
02656         default:
02657             FIXME("Unsupported format %s.\n", debug_d3dformat(format->id));
02658             return FALSE;
02659     }
02660 
02661     *redSize = count_bits(format->red_mask);
02662     *greenSize = count_bits(format->green_mask);
02663     *blueSize = count_bits(format->blue_mask);
02664     *alphaSize = count_bits(format->alpha_mask);
02665     *totalSize = *redSize + *greenSize + *blueSize + *alphaSize;
02666 
02667     TRACE("Returning red: %d, green: %d, blue: %d, alpha: %d, total: %d for format %s.\n",
02668             *redSize, *greenSize, *blueSize, *alphaSize, *totalSize, debug_d3dformat(format->id));
02669     return TRUE;
02670 }
02671 
02672 /* Helper function for retrieving depth/stencil info for ChoosePixelFormat and wglChoosePixelFormatARB */
02673 BOOL getDepthStencilBits(const struct wined3d_format *format, BYTE *depthSize, BYTE *stencilSize)
02674 {
02675     TRACE("format %s.\n", debug_d3dformat(format->id));
02676 
02677     switch (format->id)
02678     {
02679         case WINED3DFMT_D16_LOCKABLE:
02680         case WINED3DFMT_D16_UNORM:
02681         case WINED3DFMT_S1_UINT_D15_UNORM:
02682         case WINED3DFMT_X8D24_UNORM:
02683         case WINED3DFMT_S4X4_UINT_D24_UNORM:
02684         case WINED3DFMT_D24_UNORM_S8_UINT:
02685         case WINED3DFMT_S8_UINT_D24_FLOAT:
02686         case WINED3DFMT_D32_UNORM:
02687         case WINED3DFMT_D32_FLOAT:
02688         case WINED3DFMT_INTZ:
02689             break;
02690         default:
02691             FIXME("Unsupported depth/stencil format %s.\n", debug_d3dformat(format->id));
02692             return FALSE;
02693     }
02694 
02695     *depthSize = format->depth_size;
02696     *stencilSize = format->stencil_size;
02697 
02698     TRACE("Returning depthSize: %d and stencilSize: %d for format %s.\n",
02699             *depthSize, *stencilSize, debug_d3dformat(format->id));
02700     return TRUE;
02701 }
02702 
02703 /* Note: It's the caller's responsibility to ensure values can be expressed
02704  * in the requested format. UNORM formats for example can only express values
02705  * in the range 0.0f -> 1.0f. */
02706 DWORD wined3d_format_convert_from_float(const struct wined3d_surface *surface, const struct wined3d_color *color)
02707 {
02708     static const struct
02709     {
02710         enum wined3d_format_id format_id;
02711         float r_mul;
02712         float g_mul;
02713         float b_mul;
02714         float a_mul;
02715         BYTE r_shift;
02716         BYTE g_shift;
02717         BYTE b_shift;
02718         BYTE a_shift;
02719     }
02720     conv[] =
02721     {
02722         {WINED3DFMT_B8G8R8A8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
02723         {WINED3DFMT_B8G8R8X8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
02724         {WINED3DFMT_B8G8R8_UNORM,       255.0f,  255.0f,  255.0f,  255.0f, 16,  8,  0, 24},
02725         {WINED3DFMT_B5G6R5_UNORM,        31.0f,   63.0f,   31.0f,    0.0f, 11,  5,  0,  0},
02726         {WINED3DFMT_B5G5R5A1_UNORM,      31.0f,   31.0f,   31.0f,    1.0f, 10,  5,  0, 15},
02727         {WINED3DFMT_B5G5R5X1_UNORM,      31.0f,   31.0f,   31.0f,    1.0f, 10,  5,  0, 15},
02728         {WINED3DFMT_A8_UNORM,             0.0f,    0.0f,    0.0f,  255.0f,  0,  0,  0,  0},
02729         {WINED3DFMT_B4G4R4A4_UNORM,      15.0f,   15.0f,   15.0f,   15.0f,  8,  4,  0, 12},
02730         {WINED3DFMT_B4G4R4X4_UNORM,      15.0f,   15.0f,   15.0f,   15.0f,  8,  4,  0, 12},
02731         {WINED3DFMT_B2G3R3_UNORM,         7.0f,    7.0f,    3.0f,    0.0f,  5,  2,  0,  0},
02732         {WINED3DFMT_R8G8B8A8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f,  0,  8, 16, 24},
02733         {WINED3DFMT_R8G8B8X8_UNORM,     255.0f,  255.0f,  255.0f,  255.0f,  0,  8, 16, 24},
02734         {WINED3DFMT_B10G10R10A2_UNORM, 1023.0f, 1023.0f, 1023.0f,    3.0f, 20, 10,  0, 30},
02735         {WINED3DFMT_R10G10B10A2_UNORM, 1023.0f, 1023.0f, 1023.0f,    3.0f,  0, 10, 20, 30},
02736     };
02737     const struct wined3d_format *format = surface->resource.format;
02738     unsigned int i;
02739 
02740     TRACE("Converting color {%.8e %.8e %.8e %.8e} to format %s.\n",
02741             color->r, color->g, color->b, color->a, debug_d3dformat(format->id));
02742 
02743     for (i = 0; i < sizeof(conv) / sizeof(*conv); ++i)
02744     {
02745         DWORD ret;
02746 
02747         if (format->id != conv[i].format_id) continue;
02748 
02749         ret = ((DWORD)((color->r * conv[i].r_mul) + 0.5f)) << conv[i].r_shift;
02750         ret |= ((DWORD)((color->g * conv[i].g_mul) + 0.5f)) << conv[i].g_shift;
02751         ret |= ((DWORD)((color->b * conv[i].b_mul) + 0.5f)) << conv[i].b_shift;
02752         ret |= ((DWORD)((color->a * conv[i].a_mul) + 0.5f)) << conv[i].a_shift;
02753 
02754         TRACE("Returning 0x%08x.\n", ret);
02755 
02756         return ret;
02757     }
02758 
02759     if (format->id == WINED3DFMT_P8_UINT)
02760     {
02761         PALETTEENTRY *e;
02762         BYTE r, g, b, a;
02763 
02764         if (!surface->palette)
02765         {
02766             WARN("Surface doesn't have a palette, returning 0.\n");
02767             return 0;
02768         }
02769 
02770         r = (BYTE)((color->r * 255.0f) + 0.5f);
02771         g = (BYTE)((color->g * 255.0f) + 0.5f);
02772         b = (BYTE)((color->b * 255.0f) + 0.5f);
02773         a = (BYTE)((color->a * 255.0f) + 0.5f);
02774 
02775         e = &surface->palette->palents[a];
02776         if (e->peRed == r && e->peGreen == g && e->peBlue == b)
02777             return a;
02778 
02779         WARN("Alpha didn't match index, searching full palette.\n");
02780 
02781         for (i = 0; i < 256; ++i)
02782         {
02783             e = &surface->palette->palents[i];
02784             if (e->peRed == r && e->peGreen == g && e->peBlue == b)
02785                 return i;
02786         }
02787 
02788         FIXME("Unable to convert color to palette index.\n");
02789 
02790         return 0;
02791     }
02792 
02793     FIXME("Conversion for format %s not implemented.\n", debug_d3dformat(format->id));
02794 
02795     return 0;
02796 }
02797 
02798 /* DirectDraw stuff */
02799 enum wined3d_format_id pixelformat_for_depth(DWORD depth)
02800 {
02801     switch (depth)
02802     {
02803         case 8:  return WINED3DFMT_P8_UINT;
02804         case 15: return WINED3DFMT_B5G5R5X1_UNORM;
02805         case 16: return WINED3DFMT_B5G6R5_UNORM;
02806         case 24: return WINED3DFMT_B8G8R8X8_UNORM; /* Robots needs 24bit to be WINED3DFMT_B8G8R8X8_UNORM */
02807         case 32: return WINED3DFMT_B8G8R8X8_UNORM; /* EVE online and the Fur demo need 32bit AdapterDisplayMode to return WINED3DFMT_B8G8R8X8_UNORM */
02808         default: return WINED3DFMT_UNKNOWN;
02809     }
02810 }
02811 
02812 void multiply_matrix(struct wined3d_matrix *dest, const struct wined3d_matrix *src1,
02813         const struct wined3d_matrix *src2)
02814 {
02815     struct wined3d_matrix temp;
02816 
02817     /* Now do the multiplication 'by hand'.
02818        I know that all this could be optimised, but this will be done later :-) */
02819     temp.u.s._11 = (src1->u.s._11 * src2->u.s._11) + (src1->u.s._21 * src2->u.s._12) + (src1->u.s._31 * src2->u.s._13) + (src1->u.s._41 * src2->u.s._14);
02820     temp.u.s._21 = (src1->u.s._11 * src2->u.s._21) + (src1->u.s._21 * src2->u.s._22) + (src1->u.s._31 * src2->u.s._23) + (src1->u.s._41 * src2->u.s._24);
02821     temp.u.s._31 = (src1->u.s._11 * src2->u.s._31) + (src1->u.s._21 * src2->u.s._32) + (src1->u.s._31 * src2->u.s._33) + (src1->u.s._41 * src2->u.s._34);
02822     temp.u.s._41 = (src1->u.s._11 * src2->u.s._41) + (src1->u.s._21 * src2->u.s._42) + (src1->u.s._31 * src2->u.s._43) + (src1->u.s._41 * src2->u.s._44);
02823 
02824     temp.u.s._12 = (src1->u.s._12 * src2->u.s._11) + (src1->u.s._22 * src2->u.s._12) + (src1->u.s._32 * src2->u.s._13) + (src1->u.s._42 * src2->u.s._14);
02825     temp.u.s._22 = (src1->u.s._12 * src2->u.s._21) + (src1->u.s._22 * src2->u.s._22) + (src1->u.s._32 * src2->u.s._23) + (src1->u.s._42 * src2->u.s._24);
02826     temp.u.s._32 = (src1->u.s._12 * src2->u.s._31) + (src1->u.s._22 * src2->u.s._32) + (src1->u.s._32 * src2->u.s._33) + (src1->u.s._42 * src2->u.s._34);
02827     temp.u.s._42 = (src1->u.s._12 * src2->u.s._41) + (src1->u.s._22 * src2->u.s._42) + (src1->u.s._32 * src2->u.s._43) + (src1->u.s._42 * src2->u.s._44);
02828 
02829     temp.u.s._13 = (src1->u.s._13 * src2->u.s._11) + (src1->u.s._23 * src2->u.s._12) + (src1->u.s._33 * src2->u.s._13) + (src1->u.s._43 * src2->u.s._14);
02830     temp.u.s._23 = (src1->u.s._13 * src2->u.s._21) + (src1->u.s._23 * src2->u.s._22) + (src1->u.s._33 * src2->u.s._23) + (src1->u.s._43 * src2->u.s._24);
02831     temp.u.s._33 = (src1->u.s._13 * src2->u.s._31) + (src1->u.s._23 * src2->u.s._32) + (src1->u.s._33 * src2->u.s._33) + (src1->u.s._43 * src2->u.s._34);
02832     temp.u.s._43 = (src1->u.s._13 * src2->u.s._41) + (src1->u.s._23 * src2->u.s._42) + (src1->u.s._33 * src2->u.s._43) + (src1->u.s._43 * src2->u.s._44);
02833 
02834     temp.u.s._14 = (src1->u.s._14 * src2->u.s._11) + (src1->u.s._24 * src2->u.s._12) + (src1->u.s._34 * src2->u.s._13) + (src1->u.s._44 * src2->u.s._14);
02835     temp.u.s._24 = (src1->u.s._14 * src2->u.s._21) + (src1->u.s._24 * src2->u.s._22) + (src1->u.s._34 * src2->u.s._23) + (src1->u.s._44 * src2->u.s._24);
02836     temp.u.s._34 = (src1->u.s._14 * src2->u.s._31) + (src1->u.s._24 * src2->u.s._32) + (src1->u.s._34 * src2->u.s._33) + (src1->u.s._44 * src2->u.s._34);
02837     temp.u.s._44 = (src1->u.s._14 * src2->u.s._41) + (src1->u.s._24 * src2->u.s._42) + (src1->u.s._34 * src2->u.s._43) + (src1->u.s._44 * src2->u.s._44);
02838 
02839     /* And copy the new matrix in the good storage.. */
02840     memcpy(dest, &temp, 16 * sizeof(float));
02841 }
02842 
02843 DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) {
02844     DWORD size = 0;
02845     int i;
02846     int numTextures = (d3dvtVertexType & WINED3DFVF_TEXCOUNT_MASK) >> WINED3DFVF_TEXCOUNT_SHIFT;
02847 
02848     if (d3dvtVertexType & WINED3DFVF_NORMAL) size += 3 * sizeof(float);
02849     if (d3dvtVertexType & WINED3DFVF_DIFFUSE) size += sizeof(DWORD);
02850     if (d3dvtVertexType & WINED3DFVF_SPECULAR) size += sizeof(DWORD);
02851     if (d3dvtVertexType & WINED3DFVF_PSIZE) size += sizeof(DWORD);
02852     switch (d3dvtVertexType & WINED3DFVF_POSITION_MASK) {
02853         case WINED3DFVF_XYZ:    size += 3 * sizeof(float); break;
02854         case WINED3DFVF_XYZRHW: size += 4 * sizeof(float); break;
02855         case WINED3DFVF_XYZB1:  size += 4 * sizeof(float); break;
02856         case WINED3DFVF_XYZB2:  size += 5 * sizeof(float); break;
02857         case WINED3DFVF_XYZB3:  size += 6 * sizeof(float); break;
02858         case WINED3DFVF_XYZB4:  size += 7 * sizeof(float); break;
02859         case WINED3DFVF_XYZB5:  size += 8 * sizeof(float); break;
02860         case WINED3DFVF_XYZW:   size += 4 * sizeof(float); break;
02861         default: ERR("Unexpected position mask\n");
02862     }
02863     for (i = 0; i < numTextures; i++) {
02864         size += GET_TEXCOORD_SIZE_FROM_FVF(d3dvtVertexType, i) * sizeof(float);
02865     }
02866 
02867     return size;
02868 }
02869 
02870 void gen_ffp_frag_op(const struct wined3d_device *device, const struct wined3d_state *state,
02871         struct ffp_frag_settings *settings, BOOL ignore_textype)
02872 {
02873 #define ARG1 0x01
02874 #define ARG2 0x02
02875 #define ARG0 0x04
02876     static const unsigned char args[WINED3D_TOP_LERP + 1] =
02877     {
02878         /* undefined                        */  0,
02879         /* D3DTOP_DISABLE                   */  0,
02880         /* D3DTOP_SELECTARG1                */  ARG1,
02881         /* D3DTOP_SELECTARG2                */  ARG2,
02882         /* D3DTOP_MODULATE                  */  ARG1 | ARG2,
02883         /* D3DTOP_MODULATE2X                */  ARG1 | ARG2,
02884         /* D3DTOP_MODULATE4X                */  ARG1 | ARG2,
02885         /* D3DTOP_ADD                       */  ARG1 | ARG2,
02886         /* D3DTOP_ADDSIGNED                 */  ARG1 | ARG2,
02887         /* D3DTOP_ADDSIGNED2X               */  ARG1 | ARG2,
02888         /* D3DTOP_SUBTRACT                  */  ARG1 | ARG2,
02889         /* D3DTOP_ADDSMOOTH                 */  ARG1 | ARG2,
02890         /* D3DTOP_BLENDDIFFUSEALPHA         */  ARG1 | ARG2,
02891         /* D3DTOP_BLENDTEXTUREALPHA         */  ARG1 | ARG2,
02892         /* D3DTOP_BLENDFACTORALPHA          */  ARG1 | ARG2,
02893         /* D3DTOP_BLENDTEXTUREALPHAPM       */  ARG1 | ARG2,
02894         /* D3DTOP_BLENDCURRENTALPHA         */  ARG1 | ARG2,
02895         /* D3DTOP_PREMODULATE               */  ARG1 | ARG2,
02896         /* D3DTOP_MODULATEALPHA_ADDCOLOR    */  ARG1 | ARG2,
02897         /* D3DTOP_MODULATECOLOR_ADDALPHA    */  ARG1 | ARG2,
02898         /* D3DTOP_MODULATEINVALPHA_ADDCOLOR */  ARG1 | ARG2,
02899         /* D3DTOP_MODULATEINVCOLOR_ADDALPHA */  ARG1 | ARG2,
02900         /* D3DTOP_BUMPENVMAP                */  ARG1 | ARG2,
02901         /* D3DTOP_BUMPENVMAPLUMINANCE       */  ARG1 | ARG2,
02902         /* D3DTOP_DOTPRODUCT3               */  ARG1 | ARG2,
02903         /* D3DTOP_MULTIPLYADD               */  ARG1 | ARG2 | ARG0,
02904         /* D3DTOP_LERP                      */  ARG1 | ARG2 | ARG0
02905     };
02906     unsigned int i;
02907     DWORD ttff;
02908     DWORD cop, aop, carg0, carg1, carg2, aarg0, aarg1, aarg2;
02909     const struct wined3d_surface *rt = state->fb->render_targets[0];
02910     const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
02911 
02912     for (i = 0; i < gl_info->limits.texture_stages; ++i)
02913     {
02914         const struct wined3d_texture *texture;
02915 
02916         settings->op[i].padding = 0;
02917         if (state->texture_states[i][WINED3D_TSS_COLOR_OP] == WINED3D_TOP_DISABLE)
02918         {
02919             settings->op[i].cop = WINED3D_TOP_DISABLE;
02920             settings->op[i].aop = WINED3D_TOP_DISABLE;
02921             settings->op[i].carg0 = settings->op[i].carg1 = settings->op[i].carg2 = ARG_UNUSED;
02922             settings->op[i].aarg0 = settings->op[i].aarg1 = settings->op[i].aarg2 = ARG_UNUSED;
02923             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
02924             settings->op[i].dst = resultreg;
02925             settings->op[i].tex_type = tex_1d;
02926             settings->op[i].projected = proj_none;
02927             i++;
02928             break;
02929         }
02930 
02931         if ((texture = state->textures[i]))
02932         {
02933             settings->op[i].color_fixup = texture->resource.format->color_fixup;
02934             if (ignore_textype)
02935             {
02936                 settings->op[i].tex_type = tex_1d;
02937             }
02938             else
02939             {
02940                 switch (texture->target)
02941                 {
02942                     case GL_TEXTURE_1D:
02943                         settings->op[i].tex_type = tex_1d;
02944                         break;
02945                     case GL_TEXTURE_2D:
02946                         settings->op[i].tex_type = tex_2d;
02947                         break;
02948                     case GL_TEXTURE_3D:
02949                         settings->op[i].tex_type = tex_3d;
02950                         break;
02951                     case GL_TEXTURE_CUBE_MAP_ARB:
02952                         settings->op[i].tex_type = tex_cube;
02953                         break;
02954                     case GL_TEXTURE_RECTANGLE_ARB:
02955                         settings->op[i].tex_type = tex_rect;
02956                         break;
02957                 }
02958             }
02959         } else {
02960             settings->op[i].color_fixup = COLOR_FIXUP_IDENTITY;
02961             settings->op[i].tex_type = tex_1d;
02962         }
02963 
02964         cop = state->texture_states[i][WINED3D_TSS_COLOR_OP];
02965         aop = state->texture_states[i][WINED3D_TSS_ALPHA_OP];
02966 
02967         carg1 = (args[cop] & ARG1) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG1] : ARG_UNUSED;
02968         carg2 = (args[cop] & ARG2) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG2] : ARG_UNUSED;
02969         carg0 = (args[cop] & ARG0) ? state->texture_states[i][WINED3D_TSS_COLOR_ARG0] : ARG_UNUSED;
02970 
02971         if (is_invalid_op(state, i, cop, carg1, carg2, carg0))
02972         {
02973             carg0 = ARG_UNUSED;
02974             carg2 = ARG_UNUSED;
02975             carg1 = WINED3DTA_CURRENT;
02976             cop = WINED3D_TOP_SELECT_ARG1;
02977         }
02978 
02979         if (cop == WINED3D_TOP_DOTPRODUCT3)
02980         {
02981             /* A dotproduct3 on the colorop overwrites the alphaop operation and replicates
02982              * the color result to the alpha component of the destination
02983              */
02984             aop = cop;
02985             aarg1 = carg1;
02986             aarg2 = carg2;
02987             aarg0 = carg0;
02988         }
02989         else
02990         {
02991             aarg1 = (args[aop] & ARG1) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG1] : ARG_UNUSED;
02992             aarg2 = (args[aop] & ARG2) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG2] : ARG_UNUSED;
02993             aarg0 = (args[aop] & ARG0) ? state->texture_states[i][WINED3D_TSS_ALPHA_ARG0] : ARG_UNUSED;
02994         }
02995 
02996         if (!i && state->textures[0] && state->render_states[WINED3D_RS_COLORKEYENABLE])
02997         {
02998             GLenum texture_dimensions;
02999 
03000             texture = state->textures[0];
03001             texture_dimensions = texture->target;
03002 
03003             if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
03004             {
03005                 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
03006 
03007                 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
03008                 {
03009                     if (aop == WINED3D_TOP_DISABLE)
03010                     {
03011                        aarg1 = WINED3DTA_TEXTURE;
03012                        aop = WINED3D_TOP_SELECT_ARG1;
03013                     }
03014                     else if (aop == WINED3D_TOP_SELECT_ARG1 && aarg1 != WINED3DTA_TEXTURE)
03015                     {
03016                         if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
03017                         {
03018                             aarg2 = WINED3DTA_TEXTURE;
03019                             aop = WINED3D_TOP_MODULATE;
03020                         }
03021                         else aarg1 = WINED3DTA_TEXTURE;
03022                     }
03023                     else if (aop == WINED3D_TOP_SELECT_ARG2 && aarg2 != WINED3DTA_TEXTURE)
03024                     {
03025                         if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
03026                         {
03027                             aarg1 = WINED3DTA_TEXTURE;
03028                             aop = WINED3D_TOP_MODULATE;
03029                         }
03030                         else aarg2 = WINED3DTA_TEXTURE;
03031                     }
03032                 }
03033             }
03034         }
03035 
03036         if (is_invalid_op(state, i, aop, aarg1, aarg2, aarg0))
03037         {
03038                aarg0 = ARG_UNUSED;
03039                aarg2 = ARG_UNUSED;
03040                aarg1 = WINED3DTA_CURRENT;
03041                aop = WINED3D_TOP_SELECT_ARG1;
03042         }
03043 
03044         if (carg1 == WINED3DTA_TEXTURE || carg2 == WINED3DTA_TEXTURE || carg0 == WINED3DTA_TEXTURE
03045                 || aarg1 == WINED3DTA_TEXTURE || aarg2 == WINED3DTA_TEXTURE || aarg0 == WINED3DTA_TEXTURE)
03046         {
03047             ttff = state->texture_states[i][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS];
03048             if (ttff == (WINED3D_TTFF_PROJECTED | WINED3D_TTFF_COUNT3))
03049                 settings->op[i].projected = proj_count3;
03050             else if (ttff & WINED3D_TTFF_PROJECTED)
03051                 settings->op[i].projected = proj_count4;
03052             else
03053                 settings->op[i].projected = proj_none;
03054         }
03055         else
03056         {
03057             settings->op[i].projected = proj_none;
03058         }
03059 
03060         settings->op[i].cop = cop;
03061         settings->op[i].aop = aop;
03062         settings->op[i].carg0 = carg0;
03063         settings->op[i].carg1 = carg1;
03064         settings->op[i].carg2 = carg2;
03065         settings->op[i].aarg0 = aarg0;
03066         settings->op[i].aarg1 = aarg1;
03067         settings->op[i].aarg2 = aarg2;
03068 
03069         if (state->texture_states[i][WINED3D_TSS_RESULT_ARG] == WINED3DTA_TEMP)
03070             settings->op[i].dst = tempreg;
03071         else
03072             settings->op[i].dst = resultreg;
03073     }
03074 
03075     /* Clear unsupported stages */
03076     for(; i < MAX_TEXTURES; i++) {
03077         memset(&settings->op[i], 0xff, sizeof(settings->op[i]));
03078     }
03079 
03080     if (!state->render_states[WINED3D_RS_FOGENABLE])
03081     {
03082         settings->fog = FOG_OFF;
03083     }
03084     else if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
03085     {
03086         if (use_vs(state) || state->vertex_declaration->position_transformed)
03087         {
03088             settings->fog = FOG_LINEAR;
03089         }
03090         else
03091         {
03092             switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
03093             {
03094                 case WINED3D_FOG_NONE:
03095                 case WINED3D_FOG_LINEAR:
03096                     settings->fog = FOG_LINEAR;
03097                     break;
03098                 case WINED3D_FOG_EXP:
03099                     settings->fog = FOG_EXP;
03100                     break;
03101                 case WINED3D_FOG_EXP2:
03102                     settings->fog = FOG_EXP2;
03103                     break;
03104             }
03105         }
03106     }
03107     else
03108     {
03109         switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
03110         {
03111             case WINED3D_FOG_LINEAR:
03112                 settings->fog = FOG_LINEAR;
03113                 break;
03114             case WINED3D_FOG_EXP:
03115                 settings->fog = FOG_EXP;
03116                 break;
03117             case WINED3D_FOG_EXP2:
03118                 settings->fog = FOG_EXP2;
03119                 break;
03120         }
03121     }
03122     if (state->render_states[WINED3D_RS_SRGBWRITEENABLE]
03123             && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
03124     {
03125         settings->sRGB_write = 1;
03126     } else {
03127         settings->sRGB_write = 0;
03128     }
03129     if (device->vs_clipping || !use_vs(state) || !state->render_states[WINED3D_RS_CLIPPING]
03130             || !state->render_states[WINED3D_RS_CLIPPLANEENABLE])
03131     {
03132         /* No need to emulate clipplanes if GL supports native vertex shader clipping or if
03133          * the fixed function vertex pipeline is used(which always supports clipplanes), or
03134          * if no clipplane is enabled
03135          */
03136         settings->emul_clipplanes = 0;
03137     } else {
03138         settings->emul_clipplanes = 1;
03139     }
03140 }
03141 
03142 const struct ffp_frag_desc *find_ffp_frag_shader(const struct wine_rb_tree *fragment_shaders,
03143         const struct ffp_frag_settings *settings)
03144 {
03145     struct wine_rb_entry *entry = wine_rb_get(fragment_shaders, settings);
03146     return entry ? WINE_RB_ENTRY_VALUE(entry, struct ffp_frag_desc, entry) : NULL;
03147 }
03148 
03149 void add_ffp_frag_shader(struct wine_rb_tree *shaders, struct ffp_frag_desc *desc)
03150 {
03151     /* Note that the key is the implementation independent part of the ffp_frag_desc structure,
03152      * whereas desc points to an extended structure with implementation specific parts. */
03153     if (wine_rb_put(shaders, &desc->settings, &desc->entry) == -1)
03154     {
03155         ERR("Failed to insert ffp frag shader.\n");
03156     }
03157 }
03158 
03159 /* Activates the texture dimension according to the bound D3D texture.
03160  * Does not care for the colorop or correct gl texture unit(when using nvrc)
03161  * Requires the caller to activate the correct unit before
03162  */
03163 /* GL locking is done by the caller (state handler) */
03164 void texture_activate_dimensions(const struct wined3d_texture *texture, const struct wined3d_gl_info *gl_info)
03165 {
03166     if (texture)
03167     {
03168         switch (texture->target)
03169         {
03170             case GL_TEXTURE_2D:
03171                 glDisable(GL_TEXTURE_3D);
03172                 checkGLcall("glDisable(GL_TEXTURE_3D)");
03173                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
03174                 {
03175                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
03176                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
03177                 }
03178                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
03179                 {
03180                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
03181                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
03182                 }
03183                 glEnable(GL_TEXTURE_2D);
03184                 checkGLcall("glEnable(GL_TEXTURE_2D)");
03185                 break;
03186             case GL_TEXTURE_RECTANGLE_ARB:
03187                 glDisable(GL_TEXTURE_2D);
03188                 checkGLcall("glDisable(GL_TEXTURE_2D)");
03189                 glDisable(GL_TEXTURE_3D);
03190                 checkGLcall("glDisable(GL_TEXTURE_3D)");
03191                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
03192                 {
03193                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
03194                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
03195                 }
03196                 glEnable(GL_TEXTURE_RECTANGLE_ARB);
03197                 checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
03198                 break;
03199             case GL_TEXTURE_3D:
03200                 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
03201                 {
03202                     glDisable(GL_TEXTURE_CUBE_MAP_ARB);
03203                     checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
03204                 }
03205                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
03206                 {
03207                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
03208                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
03209                 }
03210                 glDisable(GL_TEXTURE_2D);
03211                 checkGLcall("glDisable(GL_TEXTURE_2D)");
03212                 glEnable(GL_TEXTURE_3D);
03213                 checkGLcall("glEnable(GL_TEXTURE_3D)");
03214                 break;
03215             case GL_TEXTURE_CUBE_MAP_ARB:
03216                 glDisable(GL_TEXTURE_2D);
03217                 checkGLcall("glDisable(GL_TEXTURE_2D)");
03218                 glDisable(GL_TEXTURE_3D);
03219                 checkGLcall("glDisable(GL_TEXTURE_3D)");
03220                 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
03221                 {
03222                     glDisable(GL_TEXTURE_RECTANGLE_ARB);
03223                     checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
03224                 }
03225                 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
03226                 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
03227               break;
03228         }
03229     } else {
03230         glEnable(GL_TEXTURE_2D);
03231         checkGLcall("glEnable(GL_TEXTURE_2D)");
03232         glDisable(GL_TEXTURE_3D);
03233         checkGLcall("glDisable(GL_TEXTURE_3D)");
03234         if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
03235         {
03236             glDisable(GL_TEXTURE_CUBE_MAP_ARB);
03237             checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
03238         }
03239         if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
03240         {
03241             glDisable(GL_TEXTURE_RECTANGLE_ARB);
03242             checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
03243         }
03244         /* Binding textures is done by samplers. A dummy texture will be bound */
03245     }
03246 }
03247 
03248 /* GL locking is done by the caller (state handler) */
03249 void sampler_texdim(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03250 {
03251     DWORD sampler = state_id - STATE_SAMPLER(0);
03252     DWORD mapped_stage = context->swapchain->device->texUnitMap[sampler];
03253 
03254     /* No need to enable / disable anything here for unused samplers. The
03255      * tex_colorop handler takes care. Also no action is needed with pixel
03256      * shaders, or if tex_colorop will take care of this business. */
03257     if (mapped_stage == WINED3D_UNMAPPED_STAGE || mapped_stage >= context->gl_info->limits.textures)
03258         return;
03259     if (sampler >= state->lowest_disabled_stage)
03260         return;
03261     if (isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3D_TSS_COLOR_OP)))
03262         return;
03263 
03264     texture_activate_dimensions(state->textures[sampler], context->gl_info);
03265 }
03266 
03267 void *wined3d_rb_alloc(size_t size)
03268 {
03269     return HeapAlloc(GetProcessHeap(), 0, size);
03270 }
03271 
03272 void *wined3d_rb_realloc(void *ptr, size_t size)
03273 {
03274     return HeapReAlloc(GetProcessHeap(), 0, ptr, size);
03275 }
03276 
03277 void wined3d_rb_free(void *ptr)
03278 {
03279     HeapFree(GetProcessHeap(), 0, ptr);
03280 }
03281 
03282 static int ffp_frag_program_key_compare(const void *key, const struct wine_rb_entry *entry)
03283 {
03284     const struct ffp_frag_settings *ka = key;
03285     const struct ffp_frag_settings *kb = &WINE_RB_ENTRY_VALUE(entry, const struct ffp_frag_desc, entry)->settings;
03286 
03287     return memcmp(ka, kb, sizeof(*ka));
03288 }
03289 
03290 const struct wine_rb_functions wined3d_ffp_frag_program_rb_functions =
03291 {
03292     wined3d_rb_alloc,
03293     wined3d_rb_realloc,
03294     wined3d_rb_free,
03295     ffp_frag_program_key_compare,
03296 };
03297 
03298 UINT wined3d_log2i(UINT32 x)
03299 {
03300     static const UINT l[] =
03301     {
03302         ~0U, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
03303           4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
03304           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
03305           5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
03306           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
03307           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
03308           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
03309           6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
03310           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
03311           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
03312           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
03313           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
03314           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
03315           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
03316           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
03317           7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
03318     };
03319     UINT32 i;
03320 
03321     return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x];
03322 }
03323 
03324 /* Set the shader type for this device, depending on the given capabilities
03325  * and the user preferences in wined3d_settings. */
03326 void select_shader_mode(const struct wined3d_gl_info *gl_info, int *ps_selected, int *vs_selected)
03327 {
03328     BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
03329 
03330     if (wined3d_settings.vs_mode == VS_NONE) *vs_selected = SHADER_NONE;
03331     else if (gl_info->supported[ARB_VERTEX_SHADER] && glsl)
03332     {
03333         /* Geforce4 cards support GLSL but for vertex shaders only. Further its reported GLSL caps are
03334          * wrong. This combined with the fact that glsl won't offer more features or performance, use ARB
03335          * shaders only on this card. */
03336         if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2]) *vs_selected = SHADER_ARB;
03337         else *vs_selected = SHADER_GLSL;
03338     }
03339     else if (gl_info->supported[ARB_VERTEX_PROGRAM]) *vs_selected = SHADER_ARB;
03340     else *vs_selected = SHADER_NONE;
03341 
03342     if (wined3d_settings.ps_mode == PS_NONE) *ps_selected = SHADER_NONE;
03343     else if (gl_info->supported[ARB_FRAGMENT_SHADER] && glsl) *ps_selected = SHADER_GLSL;
03344     else if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) *ps_selected = SHADER_ARB;
03345     else if (gl_info->supported[ATI_FRAGMENT_SHADER]) *ps_selected = SHADER_ATI;
03346     else *ps_selected = SHADER_NONE;
03347 }
03348 
03349 const struct blit_shader *wined3d_select_blitter(const struct wined3d_gl_info *gl_info, enum wined3d_blit_op blit_op,
03350         const RECT *src_rect, DWORD src_usage, enum wined3d_pool src_pool, const struct wined3d_format *src_format,
03351         const RECT *dst_rect, DWORD dst_usage, enum wined3d_pool dst_pool, const struct wined3d_format *dst_format)
03352 {
03353     static const struct blit_shader * const blitters[] =
03354     {
03355         &arbfp_blit,
03356         &ffp_blit,
03357         &cpu_blit,
03358     };
03359     unsigned int i;
03360 
03361     for (i = 0; i < sizeof(blitters) / sizeof(*blitters); ++i)
03362     {
03363         if (blitters[i]->blit_supported(gl_info, blit_op,
03364                 src_rect, src_usage, src_pool, src_format,
03365                 dst_rect, dst_usage, dst_pool, dst_format))
03366             return blitters[i];
03367     }
03368 
03369     return NULL;
03370 }
03371 
03372 void wined3d_get_draw_rect(const struct wined3d_state *state, RECT *rect)
03373 {
03374     const struct wined3d_viewport *vp = &state->viewport;
03375 
03376     SetRect(rect, vp->x, vp->y, vp->x + vp->width, vp->y + vp->height);
03377 
03378     if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
03379         IntersectRect(rect, rect, &state->scissor_rect);
03380 }

Generated on Sat May 26 2012 04:20:45 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.