From 15740faf9fe9fe4be08965098bbf2947e096aeeb Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 14 Aug 2019 22:50:43 +0800 Subject: +Unity Runtime code --- Runtime/GfxDevice/d3d/D3D9Enumeration.cpp | 344 ++++++++++++++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 Runtime/GfxDevice/d3d/D3D9Enumeration.cpp (limited to 'Runtime/GfxDevice/d3d/D3D9Enumeration.cpp') diff --git a/Runtime/GfxDevice/d3d/D3D9Enumeration.cpp b/Runtime/GfxDevice/d3d/D3D9Enumeration.cpp new file mode 100644 index 0000000..b78433e --- /dev/null +++ b/Runtime/GfxDevice/d3d/D3D9Enumeration.cpp @@ -0,0 +1,344 @@ +#include "UnityPrefix.h" +#include "D3D9Enumeration.h" +#include "D3D9Utils.h" +#include "Runtime/GfxDevice/VramLimits.h" + +// --------------------------------------------------------------------------- + + +const int kMinDisplayWidth = 512; +const int kMinDisplayHeight = 384; +const int kMinColorBits = 4; +const int kMinAlphaBits = 0; + +extern D3DDEVTYPE g_D3DDevType; +extern DWORD g_D3DAdapter; + +// --------------------------------------------------------------------------- + +static int GetFormatColorBits( D3DFORMAT fmt ) { + switch( fmt ) { + case D3DFMT_A2B10G10R10: + case D3DFMT_A2R10G10B10: return 10; + case D3DFMT_R8G8B8: + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: return 8; + case D3DFMT_R5G6B5: + case D3DFMT_X1R5G5B5: + case D3DFMT_A1R5G5B5: return 5; + case D3DFMT_A4R4G4B4: + case D3DFMT_X4R4G4B4: return 4; + case D3DFMT_R3G3B2: + case D3DFMT_A8R3G3B2: return 2; + default: return 0; + } +} + +static int GetFormatAlphaBits( D3DFORMAT fmt ) { + switch( fmt ) { + case D3DFMT_R8G8B8: + case D3DFMT_X8R8G8B8: + case D3DFMT_R5G6B5: + case D3DFMT_X1R5G5B5: + case D3DFMT_R3G3B2: + case D3DFMT_X4R4G4B4: return 0; + case D3DFMT_A8R8G8B8: + case D3DFMT_A8R3G3B2: return 8; + case D3DFMT_A1R5G5B5: return 1; + case D3DFMT_A4R4G4B4: return 4; + case D3DFMT_A2B10G10R10: + case D3DFMT_A2R10G10B10: return 2; + default: return 0; + } +} + +int GetFormatDepthBits( D3DFORMAT fmt ) { + switch( fmt ) { + case D3DFMT_D16: return 16; + case D3DFMT_D15S1: return 15; + case D3DFMT_D24X8: + case D3DFMT_D24S8: + case D3DFMT_D24X4S4: return 24; + case D3DFMT_D32: return 32; + default: return 0; + } +} + +static D3DFORMAT ConvertToAlphaFormat( D3DFORMAT fmt ) +{ + if( fmt == D3DFMT_X8R8G8B8 ) + fmt = D3DFMT_A8R8G8B8; + else if( fmt == D3DFMT_X4R4G4B4 ) + fmt = D3DFMT_A4R4G4B4; + else if( fmt == D3DFMT_X1R5G5B5 ) + fmt = D3DFMT_A1R5G5B5; + return fmt; +} + +// ----------------------------------------------------------------------------- + + +static UInt32 buildVertexProcessings( const D3DCAPS9& caps ) +{ + UInt32 result = 0; + + // TODO: check vertex shader version + + DWORD devCaps = caps.DevCaps; + if( devCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) { + if( devCaps & D3DDEVCAPS_PUREDEVICE ) { + result |= (1<displayModes.push_back( dm ); + if( std::find(adapterFormatList.begin(),adapterFormatList.end(),dm.Format) == adapterFormatList.end() ) { + adapterFormatList.push_back( dm.Format ); + if( m_AdapterFormatForChecks == D3DFMT_UNKNOWN ) + m_AdapterFormatForChecks = format; + } + } + } + + if( m_AdapterFormatForChecks == D3DFMT_UNKNOWN ) // for some reason no format was selected for checks, use default + m_AdapterFormatForChecks = allowedFormats[0]; + + // get info for device on this adapter + D3DCAPS9 caps; + if( FAILED( d3d.GetDeviceCaps( g_D3DAdapter, g_D3DDevType, &caps ) ) ) + return false; + + // find suitable vertex processing modes (if any) + m_VertexProcessings = buildVertexProcessings( caps ); + AssertIf( !m_VertexProcessings ); + + // get info for each device combo on this device + if( !enumerateDeviceCombos( d3d, caps, adapterFormatList, m_Combos ) ) + return false; + + return true; +} + + +void D3D9FormatCaps::FindBestPresentationParams( int width, int height, D3DFORMAT desktopMode, bool windowed, int vBlankCount, int multiSample, D3DPRESENT_PARAMETERS& outParams ) const +{ + const D3DDeviceCombo* bestCombo = NULL; + int bestScore = -1; + + for( size_t idc = 0; idc < m_Combos.size(); ++idc ) + { + const D3DDeviceCombo& devCombo = m_Combos[idc]; + if( windowed && !devCombo.isWindowed ) + continue; + if( !windowed && devCombo.isWindowed ) + continue; + if( windowed ) + { + if( devCombo.adapterFormat != desktopMode ) + continue; + } + + int score = 0; + + bool matchesBB = (devCombo.backBufferFormat == ConvertToAlphaFormat(devCombo.adapterFormat)); + bool matchesDesktop = (devCombo.adapterFormat == desktopMode); + + if( matchesBB ) + score += 1; + if( matchesDesktop ) + score += 1; + if( GetFormatAlphaBits(devCombo.backBufferFormat) > 0 ) + score += 1; + + if( score > bestScore ) + { + bestScore = score; + bestCombo = &devCombo; + } + } + + if( !bestCombo ) + { + // This can happen if we're debugging force-16BPP modes on a 32BPP desktop, and so on + outParams.BackBufferFormat = desktopMode; + outParams.AutoDepthStencilFormat = D3DFMT_D16; + outParams.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + outParams.MultiSampleType = D3DMULTISAMPLE_NONE; + outParams.MultiSampleQuality = 0; + return; + } + + outParams.BackBufferFormat = bestCombo->backBufferFormat; + outParams.AutoDepthStencilFormat = (D3DFORMAT)bestCombo->depthStencilFormats[0]; + + // No support for intervals above 1 in windowed mode (case 497116) + if (windowed && vBlankCount > 1) + vBlankCount = 1; + + // best possible vsync parameter (if device doesn't support 2 fall back to 1) + DWORD intervals = bestCombo->presentationIntervals; + outParams.PresentationInterval = ( vBlankCount >= 2 ) && ( intervals & D3DPRESENT_INTERVAL_TWO ) ? D3DPRESENT_INTERVAL_TWO : + ( vBlankCount >= 1 ) && ( intervals & D3DPRESENT_INTERVAL_ONE ) ? D3DPRESENT_INTERVAL_ONE : + ( vBlankCount == 0 ) && ( intervals & D3DPRESENT_INTERVAL_IMMEDIATE ) ? D3DPRESENT_INTERVAL_IMMEDIATE : + D3DPRESENT_INTERVAL_DEFAULT; + + // Here we already know backbuffer, depth buffer formats and so on, so we can also clamp used FSAA to sane VRAM limits. + int backbufferBPP = GetBPPFromD3DFormat(outParams.BackBufferFormat)/8; + int frontbufferBPP = GetBPPFromD3DFormat(desktopMode)/8; + int depthBPP = GetBPPFromD3DFormat(outParams.AutoDepthStencilFormat)/8; + multiSample = ChooseSuitableFSAALevel( width, height, backbufferBPP, frontbufferBPP, depthBPP, multiSample ); + + // Find out best matched multi sample type. + int msIdx = 0; + if( multiSample > 1 ) + { + while( msIdx < bestCombo->multiSampleTypes.size() && bestCombo->multiSampleTypes[msIdx] <= multiSample ) + ++msIdx; + --msIdx; + AssertIf( msIdx < 0 ); + } + outParams.MultiSampleType = GetD3DMultiSampleType(bestCombo->multiSampleTypes[msIdx]); + outParams.MultiSampleQuality = 0; +} + -- cgit v1.1-26-g67d0