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

format.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS ReactX
00004  * FILE:            dll/directx/d3d9/format.c
00005  * PURPOSE:         d3d9.dll D3DFORMAT helper functions
00006  * PROGRAMERS:      Gregor Brunmar <gregor (dot) brunmar (at) home (dot) se>
00007  */
00008 
00009 #include "format.h"
00010 #include <ddrawi.h>
00011 #include <debug.h>
00012 #include <d3d9types.h>
00013 
00014 BOOL IsBackBufferFormat(D3DFORMAT Format)
00015 {
00016     return ((Format >= D3DFMT_A8R8G8B8) && (Format < D3DFMT_A1R5G5B5)) ||
00017             (IsExtendedFormat(Format));
00018 }
00019 
00020 BOOL IsExtendedFormat(D3DFORMAT Format)
00021 {
00022     return (Format == D3DFMT_A2R10G10B10);
00023 }
00024 
00025 BOOL IsZBufferFormat(D3DFORMAT Format)
00026 {
00027     UNIMPLEMENTED
00028 
00029     return TRUE;
00030 }
00031 
00032 BOOL IsMultiElementFormat(D3DFORMAT Format)
00033 {
00034     return (Format == D3DFMT_MULTI2_ARGB8);
00035 }
00036 
00037 BOOL IsFourCCFormat(D3DFORMAT Format)
00038 {
00039     CHAR* cFormat = (CHAR*)&Format;
00040     if (isalnum(cFormat[0]) &&
00041         isalnum(cFormat[1]) &&
00042         isalnum(cFormat[2]) &&
00043         isalnum(cFormat[3]))
00044     {
00045         return TRUE;
00046     }
00047 
00048     return FALSE;
00049 }
00050 
00051 BOOL IsStencilFormat(D3DFORMAT Format)
00052 {
00053     switch (Format)
00054     {
00055     case D3DFMT_D15S1:
00056     case D3DFMT_D24S8:
00057     case D3DFMT_D24X4S4:
00058     case D3DFMT_D24FS8:
00059         return TRUE;
00060 
00061     default:
00062         return FALSE;
00063     }
00064 }
00065 
00066 DWORD GetBytesPerPixel(D3DFORMAT Format)
00067 {
00068     switch (Format)
00069     {
00070     case D3DFMT_R3G3B2:
00071     case D3DFMT_A8:
00072         return 1;
00073 
00074     case D3DFMT_R5G6B5:
00075     case D3DFMT_X1R5G5B5:
00076     case D3DFMT_A1R5G5B5:
00077     case D3DFMT_A4R4G4B4:
00078     case D3DFMT_A8R3G3B2:
00079     case D3DFMT_X4R4G4B4:
00080         return 2;
00081 
00082     case D3DFMT_R8G8B8:
00083         return 3;
00084 
00085     case D3DFMT_A8R8G8B8:
00086     case D3DFMT_X8R8G8B8:
00087     case D3DFMT_A2B10G10R10:
00088     case D3DFMT_A8B8G8R8:
00089     case D3DFMT_X8B8G8R8:
00090     case D3DFMT_G16R16:
00091     case D3DFMT_A2R10G10B10:
00092         return 4;
00093 
00094     case D3DFMT_A16B16G16R16:
00095         return 8;
00096 
00097 
00098     case D3DFMT_P8:
00099     case D3DFMT_L8:
00100     case D3DFMT_A4L4:
00101         return 1;
00102 
00103     case D3DFMT_A8P8:
00104     case D3DFMT_A8L8:
00105         return 2;
00106 
00107 
00108     case D3DFMT_V8U8:
00109     case D3DFMT_L6V5U5:
00110         return 2;
00111 
00112     case D3DFMT_X8L8V8U8:
00113     case D3DFMT_Q8W8V8U8:
00114     case D3DFMT_V16U16:
00115     case D3DFMT_A2W10V10U10:
00116         return 4;
00117 
00118 
00119     case D3DFMT_S8_LOCKABLE:
00120         return 1;
00121 
00122     case D3DFMT_D16_LOCKABLE:
00123     case D3DFMT_D15S1:
00124     case D3DFMT_D16:
00125         return 2;
00126 
00127     case D3DFMT_D32:
00128     case D3DFMT_D24S8:
00129     case D3DFMT_D24X8:
00130     case D3DFMT_D24X4S4:
00131     case D3DFMT_D32F_LOCKABLE:
00132     case D3DFMT_D24FS8:
00133     case D3DFMT_D32_LOCKABLE:
00134         return 4;
00135 
00136 
00137     case D3DFMT_L16:
00138         return 2;
00139 
00140     /* TODO: Handle D3DFMT_VERTEXDATA? */
00141     case D3DFMT_INDEX16:
00142         return 2;
00143     case D3DFMT_INDEX32:
00144         return 4;
00145 
00146 
00147     case D3DFMT_Q16W16V16U16:
00148         return 8;
00149 
00150 
00151     case D3DFMT_R16F:
00152         return 2;
00153     case D3DFMT_G16R16F:
00154         return 4;
00155     case D3DFMT_A16B16G16R16F:
00156         return 8;
00157 
00158 
00159     case D3DFMT_R32F:
00160         return 4;
00161     case D3DFMT_G32R32F:
00162         return 8;
00163     case D3DFMT_A32B32G32R32F:
00164         return 16;
00165 
00166     case D3DFMT_CxV8U8:
00167         return 2;
00168 
00169 
00170     /* Known FourCC formats */
00171     case D3DFMT_UYVY:
00172     case D3DFMT_R8G8_B8G8:
00173     case D3DFMT_YUY2:
00174     case D3DFMT_G8R8_G8B8:
00175         return 2;
00176 
00177     case D3DFMT_DXT1:
00178         return 0xFFFFFFF8;
00179 
00180     case D3DFMT_DXT2:
00181     case D3DFMT_DXT3:
00182     case D3DFMT_DXT4:
00183     case D3DFMT_DXT5:
00184         return 0xFFFFFFF0;
00185 
00186     case D3DFMT_MULTI2_ARGB8:
00187         return 8;
00188 
00189     default:
00190         return 0;
00191     }
00192 }
00193 
00194 DWORD GetPixelStride(D3DFORMAT Format)
00195 {
00196     DWORD Bpp = GetBytesPerPixel(Format);
00197 
00198     if (0 == Bpp)
00199     {
00200         /* TODO: Handle unknown formats here */
00201     }
00202 
00203     return Bpp;
00204 }
00205 
00206 BOOL IsSupportedFormatOp(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT DisplayFormat, DWORD FormatOp)
00207 {
00208     const DWORD NumFormatOps = pDriverCaps->NumSupportedFormatOps;
00209     DWORD FormatOpIndex;
00210 
00211     for (FormatOpIndex = 0; FormatOpIndex < NumFormatOps; FormatOpIndex++)
00212     {
00213         const LPDDSURFACEDESC pSurfaceDesc = &pDriverCaps->pSupportedFormatOps[FormatOpIndex];
00214         if (pSurfaceDesc->ddpfPixelFormat.dwFourCC == DisplayFormat &&
00215             (pSurfaceDesc->ddpfPixelFormat.dwOperations & FormatOp) == FormatOp)
00216         {
00217             return TRUE;
00218         }
00219     }
00220 
00221     return FALSE;
00222 }
00223 
00224 HRESULT CheckDeviceType(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT DisplayFormat, D3DFORMAT BackBufferFormat, BOOL Windowed)
00225 {
00226     if (FALSE == IsSupportedFormatOp(pDriverCaps, DisplayFormat, D3DFORMAT_OP_DISPLAYMODE | D3DFORMAT_OP_3DACCELERATION))
00227     {
00228         return D3DERR_NOTAVAILABLE;
00229     }
00230 
00231     if (DisplayFormat != BackBufferFormat)
00232     {
00233         D3DFORMAT AdjustedDisplayFormat = DisplayFormat;
00234 
00235         if (DisplayFormat == D3DFMT_X8R8G8B8)
00236         {
00237             DisplayFormat = D3DFMT_A8R8G8B8;
00238         }
00239         else if (DisplayFormat == D3DFMT_X1R5G5B5)
00240         {
00241             DisplayFormat = D3DFMT_A1R5G5B5;
00242         }
00243 
00244         if (AdjustedDisplayFormat == BackBufferFormat)
00245         {
00246             if (FALSE == IsSupportedFormatOp(pDriverCaps, AdjustedDisplayFormat, D3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET))
00247             {
00248                 return D3DERR_NOTAVAILABLE;
00249             }
00250 
00251             return D3D_OK;
00252         }
00253         else if (FALSE == Windowed)
00254         {
00255             return D3DERR_NOTAVAILABLE;
00256         }
00257 
00258         if (FALSE == IsSupportedFormatOp(pDriverCaps, BackBufferFormat, D3DFORMAT_OP_OFFSCREEN_RENDERTARGET) ||
00259             FALSE == IsSupportedFormatOp(pDriverCaps, BackBufferFormat, D3DFORMAT_OP_CONVERT_TO_ARGB) ||
00260             FALSE == IsSupportedFormatOp(pDriverCaps, BackBufferFormat, D3DFORMAT_MEMBEROFGROUP_ARGB))
00261         {
00262             return D3DERR_NOTAVAILABLE;
00263         }
00264     }
00265     else
00266     {
00267         if (FALSE == IsSupportedFormatOp(pDriverCaps, DisplayFormat, D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET))
00268         {
00269             return D3DERR_NOTAVAILABLE;
00270         }
00271     }
00272 
00273     return D3D_OK;
00274 }
00275 
00276 static D3DFORMAT GetStencilFormat(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT CheckFormat)
00277 {
00278     switch (CheckFormat)
00279     {
00280     case D3DFMT_D15S1:
00281     case D3DFMT_D24S8:
00282     case D3DFMT_D24X8:
00283     case D3DFMT_D24X4S4:
00284         if (IsSupportedFormatOp(pDriverCaps, CheckFormat - 1, 0))
00285             return CheckFormat - 1;
00286         break;
00287 
00288     case D3DFMT_D16:
00289         if (IsSupportedFormatOp(pDriverCaps, CheckFormat, 0))
00290             return CheckFormat;
00291         else
00292             return D3DFMT_D16_LOCKABLE;
00293 
00294     default:
00295         /* StencilFormat same as CheckFormat */
00296         break;
00297     }
00298 
00299     return CheckFormat;
00300 }
00301 
00302 static D3DFORMAT RemoveAlphaChannel(D3DFORMAT CheckFormat)
00303 {
00304     switch (CheckFormat)
00305     {
00306     case D3DFMT_A8R8G8B8:
00307         return D3DFMT_X8R8G8B8;
00308 
00309     case D3DFMT_A1R5G5B5:
00310         return D3DFMT_X1R5G5B5;
00311 
00312     case D3DFMT_A4R4G4B4:
00313         return D3DFMT_X4R4G4B4;
00314 
00315     case D3DFMT_A8B8G8R8:
00316         return D3DFMT_X8B8G8R8;
00317 
00318     default:
00319         /* CheckFormat has not relevant alpha channel */
00320         break;
00321     }
00322 
00323     return CheckFormat;
00324 }
00325 
00326 HRESULT CheckDeviceFormat(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType, D3DFORMAT CheckFormat)
00327 {
00328     const DWORD NumFormatOps = pDriverCaps->NumSupportedFormatOps;
00329     DWORD NonCompatibleOperations = 0, MustSupportOperations = 0;
00330     BOOL bSupportedWithAutogen = FALSE;
00331     DWORD FormatOpIndex;
00332 
00333     if (FALSE == IsSupportedFormatOp(pDriverCaps, AdapterFormat, D3DFORMAT_OP_DISPLAYMODE | D3DFORMAT_OP_3DACCELERATION))
00334     {
00335         return D3DERR_NOTAVAILABLE;
00336     }
00337 
00338     /* Check for driver auto generated mip map support if requested */
00339     if ((Usage & (D3DUSAGE_AUTOGENMIPMAP)) != 0)
00340     {
00341         switch (RType)
00342         {
00343         case D3DRTYPE_TEXTURE:
00344             if ((pDriverCaps->DriverCaps9.TextureCaps & D3DPTEXTURECAPS_MIPMAP) == 0)
00345                 return D3DERR_NOTAVAILABLE;
00346 
00347             break;
00348 
00349         case D3DRTYPE_VOLUME:
00350         case D3DRTYPE_VOLUMETEXTURE:
00351             if ((pDriverCaps->DriverCaps9.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP) == 0)
00352                 return D3DERR_NOTAVAILABLE;
00353 
00354             break;
00355 
00356         case D3DRTYPE_CUBETEXTURE:
00357             if ((pDriverCaps->DriverCaps9.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP) == 0)
00358                 return D3DERR_NOTAVAILABLE;
00359 
00360             break;
00361 
00362         default:
00363             /* Do nothing */
00364             break;
00365         }
00366 
00367         MustSupportOperations |= D3DFORMAT_OP_AUTOGENMIPMAP;
00368     }
00369 
00370     /* Translate from RType and Usage parameters to FormatOps */
00371     switch (RType)
00372     {
00373     case D3DRTYPE_TEXTURE:
00374         MustSupportOperations |= D3DFORMAT_OP_TEXTURE;
00375         break;
00376 
00377     case D3DRTYPE_VOLUME:
00378     case D3DRTYPE_VOLUMETEXTURE:
00379         MustSupportOperations |= D3DFORMAT_OP_VOLUMETEXTURE;
00380         break;
00381 
00382     case D3DRTYPE_CUBETEXTURE:
00383         MustSupportOperations |= D3DFORMAT_OP_CUBETEXTURE;
00384         break;
00385 
00386     default:
00387         /* Do nothing */
00388         break;
00389     }
00390 
00391     if (Usage == 0 && RType == D3DRTYPE_SURFACE)
00392     {
00393         MustSupportOperations |= D3DFORMAT_OP_OFFSCREENPLAIN;
00394     }
00395 
00396     if ((Usage & D3DUSAGE_DEPTHSTENCIL) != 0)
00397     {
00398         MustSupportOperations |= D3DFORMAT_OP_ZSTENCIL;
00399     }
00400 
00401     if ((Usage & D3DUSAGE_DMAP) != 0)
00402     {
00403         MustSupportOperations |= D3DFORMAT_OP_DMAP;
00404     }
00405 
00406     if ((Usage & D3DUSAGE_QUERY_LEGACYBUMPMAP) != 0)
00407     {
00408         MustSupportOperations |= D3DFORMAT_OP_BUMPMAP;
00409     }
00410 
00411     if ((Usage & D3DUSAGE_QUERY_SRGBREAD) != 0)
00412     {
00413         MustSupportOperations |= D3DFORMAT_OP_SRGBREAD;
00414     }
00415 
00416     if ((Usage & D3DUSAGE_QUERY_SRGBWRITE) != 0)
00417     {
00418         MustSupportOperations |= D3DFORMAT_OP_SRGBWRITE;
00419     }
00420 
00421     if ((Usage & D3DUSAGE_QUERY_VERTEXTEXTURE) != 0)
00422     {
00423         MustSupportOperations |= D3DFORMAT_OP_VERTEXTEXTURE;
00424     }
00425 
00426     CheckFormat = GetStencilFormat(pDriverCaps, CheckFormat);
00427 
00428     if ((Usage & D3DUSAGE_RENDERTARGET) != 0)
00429     {
00430         if (AdapterFormat == CheckFormat)
00431         {
00432             MustSupportOperations |= D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET;
00433         }
00434         else
00435         {
00436             D3DFORMAT NonAlphaAdapterFormat;
00437             D3DFORMAT NonAlphaCheckFormat;
00438 
00439             NonAlphaAdapterFormat = RemoveAlphaChannel(AdapterFormat);
00440             NonAlphaCheckFormat = RemoveAlphaChannel(CheckFormat);
00441 
00442             if (NonAlphaAdapterFormat == NonAlphaCheckFormat &&
00443                 NonAlphaCheckFormat != D3DFMT_UNKNOWN)
00444             {
00445                 MustSupportOperations |= D3DFORMAT_OP_SAME_FORMAT_UP_TO_ALPHA_RENDERTARGET;
00446             }
00447             else
00448             {
00449                 MustSupportOperations |= D3DFORMAT_OP_OFFSCREEN_RENDERTARGET;
00450             }
00451         }
00452     }
00453 
00454     if ((Usage & D3DUSAGE_QUERY_FILTER) != 0)
00455     {
00456         NonCompatibleOperations |= D3DFORMAT_OP_OFFSCREENPLAIN;
00457     }
00458 
00459     if ((Usage & D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) != 0)
00460     {
00461         NonCompatibleOperations |= D3DFORMAT_OP_NOALPHABLEND;
00462     }
00463 
00464     if ((Usage & D3DUSAGE_QUERY_WRAPANDMIP) != 0)
00465     {
00466         NonCompatibleOperations |= D3DFORMAT_OP_NOTEXCOORDWRAPNORMIP;
00467     }
00468 
00469     for (FormatOpIndex = 0; FormatOpIndex < NumFormatOps; FormatOpIndex++)
00470     {
00471         DWORD dwOperations;
00472         LPDDSURFACEDESC pSurfaceDesc = &pDriverCaps->pSupportedFormatOps[FormatOpIndex];
00473 
00474         if (pSurfaceDesc->ddpfPixelFormat.dwFourCC != CheckFormat)
00475             continue;
00476 
00477         dwOperations = pSurfaceDesc->ddpfPixelFormat.dwOperations;
00478 
00479         if ((dwOperations & NonCompatibleOperations) != 0)
00480             continue;
00481 
00482         if ((dwOperations & MustSupportOperations) == MustSupportOperations)
00483             return D3D_OK;
00484         
00485         if (((dwOperations & MustSupportOperations) | D3DFORMAT_OP_AUTOGENMIPMAP) == MustSupportOperations)
00486             bSupportedWithAutogen = TRUE;
00487     }
00488 
00489     if (TRUE == bSupportedWithAutogen)
00490         return D3DOK_NOAUTOGEN;
00491 
00492     return D3DERR_NOTAVAILABLE;
00493 }
00494 
00495 HRESULT CheckDeviceFormatConversion(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT SourceFormat, D3DFORMAT TargetFormat)
00496 {
00497     D3DFORMAT NonAlphaSourceFormat;
00498     D3DFORMAT NonAlphaTargetFormat;
00499 
00500     NonAlphaSourceFormat = RemoveAlphaChannel(SourceFormat);
00501     NonAlphaTargetFormat = RemoveAlphaChannel(TargetFormat);
00502 
00503     if (NonAlphaSourceFormat == NonAlphaTargetFormat)
00504     {
00505         return D3D_OK;
00506     }
00507 
00508     if (FALSE == IsFourCCFormat(SourceFormat))
00509     {
00510         switch (SourceFormat)
00511         {
00512         case D3DFMT_A8R8G8B8:
00513         case D3DFMT_X8R8G8B8:
00514         case D3DFMT_R5G6B5:
00515         case D3DFMT_X1R5G5B5:
00516         case D3DFMT_A1R5G5B5:
00517         case D3DFMT_A2R10G10B10:
00518             /* Do nothing, valid SourceFormat */
00519             break;
00520 
00521         default:
00522             return D3DERR_NOTAVAILABLE;
00523         }
00524     }
00525     else if (pDriverCaps->DriverCaps9.DevCaps2 == 0)
00526     {
00527         return D3D_OK;
00528     }
00529 
00530     if (FALSE == IsSupportedFormatOp(pDriverCaps, SourceFormat, D3DFORMAT_OP_CONVERT_TO_ARGB) ||
00531         FALSE == IsSupportedFormatOp(pDriverCaps, TargetFormat, D3DFORMAT_MEMBEROFGROUP_ARGB))
00532     {
00533         return D3DERR_NOTAVAILABLE;
00534     }
00535 
00536     return D3D_OK;
00537 }
00538 
00539 HRESULT CheckDepthStencilMatch(LPD3D9_DRIVERCAPS pDriverCaps, D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat, D3DFORMAT DepthStencilFormat)
00540 {
00541     const DWORD NumFormatOps = pDriverCaps->NumSupportedFormatOps;
00542     BOOL bRenderTargetAvailable = FALSE;
00543     BOOL bDepthStencilAvailable = FALSE;
00544     BOOL bForceSameDepthStencilBits = FALSE;
00545     DWORD FormatIndex;
00546 
00547     if (FALSE == IsSupportedFormatOp(pDriverCaps, AdapterFormat, D3DFORMAT_OP_DISPLAYMODE | D3DFORMAT_OP_3DACCELERATION))
00548     {
00549         return D3DERR_NOTAVAILABLE;
00550     }
00551    
00552     if (DepthStencilFormat != D3DFMT_D16_LOCKABLE &&
00553         DepthStencilFormat != D3DFMT_D32F_LOCKABLE)
00554     {
00555         if (TRUE == IsStencilFormat(DepthStencilFormat))
00556         {
00557             bForceSameDepthStencilBits = TRUE;
00558         }
00559     }
00560 
00561     if (FALSE == bForceSameDepthStencilBits &&
00562         (DepthStencilFormat == D3DFMT_D32 || DepthStencilFormat == D3DFMT_D24X8))
00563     {
00564         bForceSameDepthStencilBits = TRUE;
00565     }
00566 
00567     DepthStencilFormat = GetStencilFormat(pDriverCaps, DepthStencilFormat);
00568 
00569     /* Observe the multiple conditions */
00570     for (FormatIndex = 0; FormatIndex < NumFormatOps && (bRenderTargetAvailable == FALSE || bDepthStencilAvailable == FALSE); FormatIndex++)
00571     {
00572         const LPDDSURFACEDESC pSurfaceDesc = &pDriverCaps->pSupportedFormatOps[FormatIndex];
00573         const DWORD FourCC = pSurfaceDesc->ddpfPixelFormat.dwFourCC;
00574         const DWORD FormatOperations = pSurfaceDesc->ddpfPixelFormat.dwOperations;
00575 
00576         if (FALSE == bRenderTargetAvailable &&
00577             FourCC == RenderTargetFormat &&
00578             (FormatOperations & D3DFORMAT_OP_SAME_FORMAT_RENDERTARGET) != 0)
00579         {
00580             bRenderTargetAvailable = TRUE;
00581         }
00582 
00583         if (FALSE == bDepthStencilAvailable &&
00584             FourCC == DepthStencilFormat &&
00585             (FormatOperations & D3DFORMAT_OP_ZSTENCIL) != 0)
00586         {
00587             bDepthStencilAvailable = TRUE;
00588 
00589             if ((FormatOperations & D3DFORMAT_OP_ZSTENCIL_WITH_ARBITRARY_COLOR_DEPTH) != 0)
00590             {
00591                 bForceSameDepthStencilBits = FALSE;
00592             }
00593         }
00594     }
00595 
00596     if (FALSE == bRenderTargetAvailable || FALSE == bDepthStencilAvailable)
00597     {
00598         return D3DERR_INVALIDCALL;
00599     }
00600 
00601     if (TRUE == bForceSameDepthStencilBits)
00602     {
00603         if (GetPixelStride(RenderTargetFormat) != GetPixelStride(DepthStencilFormat))
00604             return D3DERR_NOTAVAILABLE;
00605     }
00606 
00607     return D3D_OK;
00608 }

Generated on Sat May 26 2012 04:16:52 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.