Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenformat.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
1.7.6.1
|