2012-08-05 14:51:49 -07:00
/*
2015-01-01 15:04:46 -08:00
* Copyright 2011 - 2015 Branimir Karadzic . All rights reserved .
2012-08-05 14:51:49 -07:00
* License : http : //www.opensource.org/licenses/BSD-2-Clause
*/
# include "bgfx_p.h"
# if BGFX_CONFIG_RENDERER_DIRECT3D9
# include "renderer_d3d9.h"
2015-03-21 22:11:59 -07:00
namespace bgfx { namespace d3d9
2012-08-05 14:51:49 -07:00
{
2014-10-25 18:07:51 -07:00
static wchar_t s_viewNameW [ BGFX_CONFIG_MAX_VIEWS ] [ BGFX_CONFIG_MAX_VIEW_NAME ] ;
2013-06-09 15:28:25 -07:00
2014-04-26 23:48:41 -07:00
struct PrimInfo
2012-08-05 14:51:49 -07:00
{
2014-04-26 23:48:41 -07:00
D3DPRIMITIVETYPE m_type ;
uint32_t m_min ;
uint32_t m_div ;
uint32_t m_sub ;
} ;
static const PrimInfo s_primInfo [ ] =
{
{ D3DPT_TRIANGLELIST , 3 , 3 , 0 } ,
{ D3DPT_TRIANGLESTRIP , 3 , 1 , 2 } ,
{ D3DPT_LINELIST , 2 , 2 , 0 } ,
2014-10-22 19:19:33 -07:00
{ D3DPT_LINESTRIP , 2 , 1 , 1 } ,
2014-04-26 23:48:41 -07:00
{ D3DPT_POINTLIST , 1 , 1 , 0 } ,
2014-09-01 11:24:51 -07:00
{ D3DPRIMITIVETYPE ( 0 ) , 0 , 0 , 0 } ,
2014-04-26 23:48:41 -07:00
} ;
static const char * s_primName [ ] =
{
" TriList " ,
" TriStrip " ,
" Line " ,
2014-10-22 19:19:33 -07:00
" LineStrip " ,
2014-04-26 23:48:41 -07:00
" Point " ,
2012-08-05 14:51:49 -07:00
} ;
2014-09-01 11:24:51 -07:00
BX_STATIC_ASSERT ( BX_COUNTOF ( s_primInfo ) = = BX_COUNTOF ( s_primName ) + 1 ) ;
2012-08-05 14:51:49 -07:00
static const D3DMULTISAMPLE_TYPE s_checkMsaa [ ] =
{
D3DMULTISAMPLE_NONE ,
D3DMULTISAMPLE_2_SAMPLES ,
D3DMULTISAMPLE_4_SAMPLES ,
D3DMULTISAMPLE_8_SAMPLES ,
D3DMULTISAMPLE_16_SAMPLES ,
} ;
static Msaa s_msaa [ ] =
{
{ D3DMULTISAMPLE_NONE , 0 } ,
{ D3DMULTISAMPLE_2_SAMPLES , 0 } ,
{ D3DMULTISAMPLE_4_SAMPLES , 0 } ,
{ D3DMULTISAMPLE_8_SAMPLES , 0 } ,
{ D3DMULTISAMPLE_16_SAMPLES , 0 } ,
} ;
2013-03-30 09:44:13 -07:00
struct Blend
{
D3DBLEND m_src ;
D3DBLEND m_dst ;
bool m_factor ;
} ;
static const Blend s_blendFactor [ ] =
{
{ ( D3DBLEND ) 0 , ( D3DBLEND ) 0 , false } , // ignored
2014-03-25 23:07:51 -07:00
{ D3DBLEND_ZERO , D3DBLEND_ZERO , false } , // ZERO
{ D3DBLEND_ONE , D3DBLEND_ONE , false } , // ONE
{ D3DBLEND_SRCCOLOR , D3DBLEND_SRCCOLOR , false } , // SRC_COLOR
{ D3DBLEND_INVSRCCOLOR , D3DBLEND_INVSRCCOLOR , false } , // INV_SRC_COLOR
{ D3DBLEND_SRCALPHA , D3DBLEND_SRCALPHA , false } , // SRC_ALPHA
{ D3DBLEND_INVSRCALPHA , D3DBLEND_INVSRCALPHA , false } , // INV_SRC_ALPHA
{ D3DBLEND_DESTALPHA , D3DBLEND_DESTALPHA , false } , // DST_ALPHA
{ D3DBLEND_INVDESTALPHA , D3DBLEND_INVDESTALPHA , false } , // INV_DST_ALPHA
{ D3DBLEND_DESTCOLOR , D3DBLEND_DESTCOLOR , false } , // DST_COLOR
{ D3DBLEND_INVDESTCOLOR , D3DBLEND_INVDESTCOLOR , false } , // INV_DST_COLOR
{ D3DBLEND_SRCALPHASAT , D3DBLEND_ONE , false } , // SRC_ALPHA_SAT
{ D3DBLEND_BLENDFACTOR , D3DBLEND_BLENDFACTOR , true } , // FACTOR
{ D3DBLEND_INVBLENDFACTOR , D3DBLEND_INVBLENDFACTOR , true } , // INV_FACTOR
2012-08-05 14:51:49 -07:00
} ;
2013-06-17 22:11:45 -07:00
static const D3DBLENDOP s_blendEquation [ ] =
{
D3DBLENDOP_ADD ,
D3DBLENDOP_SUBTRACT ,
D3DBLENDOP_REVSUBTRACT ,
D3DBLENDOP_MIN ,
D3DBLENDOP_MAX ,
} ;
2014-02-22 08:48:30 -08:00
static const D3DCMPFUNC s_cmpFunc [ ] =
2012-11-10 19:59:23 -08:00
{
( D3DCMPFUNC ) 0 , // ignored
D3DCMP_LESS ,
D3DCMP_LESSEQUAL ,
D3DCMP_EQUAL ,
D3DCMP_GREATEREQUAL ,
D3DCMP_GREATER ,
D3DCMP_NOTEQUAL ,
D3DCMP_NEVER ,
D3DCMP_ALWAYS ,
} ;
static const D3DSTENCILOP s_stencilOp [ ] =
{
D3DSTENCILOP_ZERO ,
D3DSTENCILOP_KEEP ,
D3DSTENCILOP_REPLACE ,
D3DSTENCILOP_INCR ,
D3DSTENCILOP_INCRSAT ,
D3DSTENCILOP_DECR ,
D3DSTENCILOP_DECRSAT ,
D3DSTENCILOP_INVERT ,
} ;
static const D3DRENDERSTATETYPE s_stencilFuncRs [ ] =
{
D3DRS_STENCILFUNC ,
D3DRS_CCW_STENCILFUNC ,
} ;
static const D3DRENDERSTATETYPE s_stencilFailRs [ ] =
{
D3DRS_STENCILFAIL ,
D3DRS_CCW_STENCILFAIL ,
} ;
static const D3DRENDERSTATETYPE s_stencilZFailRs [ ] =
{
D3DRS_STENCILZFAIL ,
D3DRS_CCW_STENCILZFAIL ,
} ;
static const D3DRENDERSTATETYPE s_stencilZPassRs [ ] =
{
D3DRS_STENCILPASS ,
D3DRS_CCW_STENCILPASS ,
} ;
2012-08-05 14:51:49 -07:00
static const D3DCULL s_cullMode [ ] =
{
D3DCULL_NONE ,
D3DCULL_CW ,
D3DCULL_CCW ,
} ;
static const D3DFORMAT s_checkColorFormats [ ] =
{
D3DFMT_UNKNOWN ,
D3DFMT_A8R8G8B8 , D3DFMT_UNKNOWN ,
D3DFMT_R32F , D3DFMT_R16F , D3DFMT_G16R16 , D3DFMT_A8R8G8B8 , D3DFMT_UNKNOWN ,
D3DFMT_UNKNOWN , // terminator
} ;
static D3DFORMAT s_colorFormat [ ] =
{
D3DFMT_UNKNOWN , // ignored
D3DFMT_A8R8G8B8 ,
2013-03-28 22:34:59 -07:00
D3DFMT_A2B10G10R10 ,
D3DFMT_A16B16G16R16 ,
D3DFMT_A16B16G16R16F ,
D3DFMT_R16F ,
2012-08-05 14:51:49 -07:00
D3DFMT_R32F ,
} ;
static const D3DTEXTUREADDRESS s_textureAddress [ ] =
{
D3DTADDRESS_WRAP ,
D3DTADDRESS_MIRROR ,
D3DTADDRESS_CLAMP ,
} ;
static const D3DTEXTUREFILTERTYPE s_textureFilter [ ] =
{
D3DTEXF_LINEAR ,
D3DTEXF_POINT ,
D3DTEXF_ANISOTROPIC ,
} ;
struct TextureFormatInfo
{
D3DFORMAT m_fmt ;
} ;
2014-07-20 20:27:13 -07:00
static TextureFormatInfo s_textureFormat [ ] =
2012-08-05 14:51:49 -07:00
{
2015-01-10 20:38:47 -08:00
{ D3DFMT_DXT1 } , // BC1
2013-09-08 21:03:03 -07:00
{ D3DFMT_DXT3 } , // BC2
{ D3DFMT_DXT5 } , // BC3
{ D3DFMT_UNKNOWN } , // BC4
{ D3DFMT_UNKNOWN } , // BC5
2014-08-01 19:24:42 -07:00
{ D3DFMT_UNKNOWN } , // BC6H
{ D3DFMT_UNKNOWN } , // BC7
2013-09-08 21:03:03 -07:00
{ D3DFMT_UNKNOWN } , // ETC1
{ D3DFMT_UNKNOWN } , // ETC2
{ D3DFMT_UNKNOWN } , // ETC2A
{ D3DFMT_UNKNOWN } , // ETC2A1
{ D3DFMT_UNKNOWN } , // PTC12
{ D3DFMT_UNKNOWN } , // PTC14
{ D3DFMT_UNKNOWN } , // PTC12A
{ D3DFMT_UNKNOWN } , // PTC14A
{ D3DFMT_UNKNOWN } , // PTC22
{ D3DFMT_UNKNOWN } , // PTC24
{ D3DFMT_UNKNOWN } , // Unknown
2014-08-12 21:47:01 -07:00
{ D3DFMT_A1 } , // R1
2014-03-25 23:07:51 -07:00
{ D3DFMT_L8 } , // R8
{ D3DFMT_G16R16 } , // R16
{ D3DFMT_R16F } , // R16F
2014-07-21 21:13:16 -07:00
{ D3DFMT_UNKNOWN } , // R32
{ D3DFMT_R32F } , // R32F
2014-07-25 23:16:11 -07:00
{ D3DFMT_A8L8 } , // RG8
2014-07-21 21:13:16 -07:00
{ D3DFMT_G16R16 } , // RG16
{ D3DFMT_G16R16F } , // RG16F
{ D3DFMT_UNKNOWN } , // RG32
{ D3DFMT_G32R32F } , // RG32F
2013-09-08 21:03:03 -07:00
{ D3DFMT_A8R8G8B8 } , // BGRA8
2015-03-05 17:44:56 -08:00
{ D3DFMT_A8R8G8B8 } , // RGBA8
2013-09-08 21:03:03 -07:00
{ D3DFMT_A16B16G16R16 } , // RGBA16
{ D3DFMT_A16B16G16R16F } , // RGBA16F
2014-07-21 21:13:16 -07:00
{ D3DFMT_UNKNOWN } , // RGBA32
{ D3DFMT_A32B32G32R32F } , // RGBA32F
2013-09-08 21:03:03 -07:00
{ D3DFMT_R5G6B5 } , // R5G6B5
{ D3DFMT_A4R4G4B4 } , // RGBA4
{ D3DFMT_A1R5G5B5 } , // RGB5A1
{ D3DFMT_A2B10G10R10 } , // RGB10A2
2014-08-26 20:56:53 -07:00
{ D3DFMT_UNKNOWN } , // R11G11B10F
2014-01-12 13:51:26 -08:00
{ D3DFMT_UNKNOWN } , // UnknownDepth
2015-01-10 20:38:47 -08:00
{ D3DFMT_D16 } , // D16
{ D3DFMT_D24X8 } , // D24
2014-01-12 13:51:26 -08:00
{ D3DFMT_D24S8 } , // D24S8
2015-01-10 20:38:47 -08:00
{ D3DFMT_D32 } , // D32
{ D3DFMT_DF16 } , // D16F
2014-01-12 13:51:26 -08:00
{ D3DFMT_DF24 } , // D24F
{ D3DFMT_D32F_LOCKABLE } , // D32F
2014-08-12 21:47:01 -07:00
{ D3DFMT_S8_LOCKABLE } , // D0S8
2012-08-05 14:51:49 -07:00
} ;
2014-07-20 20:27:13 -07:00
BX_STATIC_ASSERT ( TextureFormat : : Count = = BX_COUNTOF ( s_textureFormat ) ) ;
2012-08-05 14:51:49 -07:00
static ExtendedFormat s_extendedFormats [ ExtendedFormat : : Count ] =
{
{ D3DFMT_ATI1 , 0 , D3DRTYPE_TEXTURE , false } ,
{ D3DFMT_ATI2 , 0 , D3DRTYPE_TEXTURE , false } ,
{ D3DFMT_DF16 , D3DUSAGE_DEPTHSTENCIL , D3DRTYPE_SURFACE , false } ,
{ D3DFMT_DF24 , D3DUSAGE_DEPTHSTENCIL , D3DRTYPE_SURFACE , false } ,
{ D3DFMT_INST , 0 , D3DRTYPE_SURFACE , false } ,
{ D3DFMT_INTZ , D3DUSAGE_DEPTHSTENCIL , D3DRTYPE_SURFACE , false } ,
{ D3DFMT_NULL , D3DUSAGE_RENDERTARGET , D3DRTYPE_SURFACE , false } ,
{ D3DFMT_RESZ , D3DUSAGE_RENDERTARGET , D3DRTYPE_SURFACE , false } ,
{ D3DFMT_RAWZ , D3DUSAGE_DEPTHSTENCIL , D3DRTYPE_SURFACE , false } ,
} ;
2014-10-16 19:54:29 -07:00
# if BGFX_CONFIG_RENDERER_DIRECT3D9EX
2013-07-26 22:55:13 -07:00
static const GUID IID_IDirect3D9 = { 0x81bdcbca , 0x64d4 , 0x426d , { 0xae , 0x8d , 0xad , 0x1 , 0x47 , 0xf4 , 0x27 , 0x5c } } ;
static const GUID IID_IDirect3DDevice9Ex = { 0xb18b10ce , 0x2649 , 0x405a , { 0x87 , 0xf , 0x95 , 0xf7 , 0x77 , 0xd4 , 0x31 , 0x3a } } ;
2014-10-22 20:45:08 -07:00
typedef HRESULT ( WINAPI * Direct3DCreate9ExFn ) ( UINT SDKVersion , IDirect3D9Ex * * ) ;
static Direct3DCreate9ExFn Direct3DCreate9Ex ;
# endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
typedef IDirect3D9 * ( WINAPI * Direct3DCreate9Fn ) ( UINT SDKVersion ) ;
static Direct3DCreate9Fn Direct3DCreate9 ;
2014-10-06 22:10:55 -07:00
static PFN_D3DPERF_SET_MARKER D3DPERF_SetMarker ;
static PFN_D3DPERF_BEGIN_EVENT D3DPERF_BeginEvent ;
static PFN_D3DPERF_END_EVENT D3DPERF_EndEvent ;
2014-05-26 14:09:26 -07:00
struct RendererContextD3D9 : public RendererContextI
2012-08-05 14:51:49 -07:00
{
2014-05-26 14:09:26 -07:00
RendererContextD3D9 ( )
2013-09-20 22:13:58 -07:00
: m_d3d9 ( NULL )
, m_device ( NULL )
, m_captureTexture ( NULL )
, m_captureSurface ( NULL )
, m_captureResolve ( NULL )
, m_flags ( BGFX_RESET_NONE )
2015-01-21 20:39:42 -08:00
, m_maxAnisotropy ( 1 )
2012-08-05 14:51:49 -07:00
, m_initialized ( false )
, m_amd ( false )
, m_nvidia ( false )
, m_instancing ( false )
, m_rtMsaa ( false )
2014-10-13 21:14:51 -07:00
{
}
~ RendererContextD3D9 ( )
{
}
void init ( )
2012-08-05 14:51:49 -07:00
{
2014-02-05 23:07:11 -08:00
m_fbh . idx = invalidHandle ;
2014-04-15 19:10:56 -07:00
memset ( m_uniforms , 0 , sizeof ( m_uniforms ) ) ;
2014-05-26 14:09:26 -07:00
memset ( & m_resolution , 0 , sizeof ( m_resolution ) ) ;
2012-08-05 14:51:49 -07:00
D3DFORMAT adapterFormat = D3DFMT_X8R8G8B8 ;
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb172588%28v=vs.85%29.aspx
memset ( & m_params , 0 , sizeof ( m_params ) ) ;
m_params . BackBufferWidth = BGFX_DEFAULT_WIDTH ;
m_params . BackBufferHeight = BGFX_DEFAULT_HEIGHT ;
m_params . BackBufferFormat = adapterFormat ;
m_params . BackBufferCount = 1 ;
m_params . MultiSampleType = D3DMULTISAMPLE_NONE ;
m_params . MultiSampleQuality = 0 ;
m_params . EnableAutoDepthStencil = TRUE ;
m_params . AutoDepthStencilFormat = D3DFMT_D24S8 ;
m_params . Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL ;
# if BX_PLATFORM_WINDOWS
m_params . FullScreen_RefreshRateInHz = 0 ;
m_params . PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE ;
m_params . SwapEffect = D3DSWAPEFFECT_DISCARD ;
2014-09-07 17:17:38 -07:00
m_params . hDeviceWindow = NULL ;
2012-08-05 14:51:49 -07:00
m_params . Windowed = true ;
RECT rect ;
GetWindowRect ( g_bgfxHwnd , & rect ) ;
m_params . BackBufferWidth = rect . right - rect . left ;
m_params . BackBufferHeight = rect . bottom - rect . top ;
2013-07-26 22:55:13 -07:00
m_d3d9dll = bx : : dlopen ( " d3d9.dll " ) ;
2012-12-08 14:30:41 -08:00
BGFX_FATAL ( NULL ! = m_d3d9dll , Fatal : : UnableToInitialize , " Failed to load d3d9.dll. " ) ;
2012-08-05 14:51:49 -07:00
2014-10-06 22:10:55 -07:00
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG_PIX ) )
{
D3DPERF_SetMarker = ( PFN_D3DPERF_SET_MARKER ) bx : : dlsym ( m_d3d9dll , " D3DPERF_SetMarker " ) ;
D3DPERF_BeginEvent = ( PFN_D3DPERF_BEGIN_EVENT ) bx : : dlsym ( m_d3d9dll , " D3DPERF_BeginEvent " ) ;
D3DPERF_EndEvent = ( PFN_D3DPERF_END_EVENT ) bx : : dlsym ( m_d3d9dll , " D3DPERF_EndEvent " ) ;
BX_CHECK ( NULL ! = D3DPERF_SetMarker
& & NULL ! = D3DPERF_BeginEvent
& & NULL ! = D3DPERF_EndEvent
, " Failed to initialize PIX events. "
) ;
}
2012-08-05 14:51:49 -07:00
# if BGFX_CONFIG_RENDERER_DIRECT3D9EX
2013-07-26 22:55:13 -07:00
m_d3d9ex = NULL ;
2014-10-22 20:45:08 -07:00
Direct3DCreate9Ex = ( Direct3DCreate9ExFn ) bx : : dlsym ( m_d3d9dll , " Direct3DCreate9Ex " ) ;
if ( NULL ! = Direct3DCreate9Ex )
2013-07-26 22:55:13 -07:00
{
2014-10-22 20:45:08 -07:00
Direct3DCreate9Ex ( D3D_SDK_VERSION , & m_d3d9ex ) ;
2013-07-26 22:55:13 -07:00
DX_CHECK ( m_d3d9ex - > QueryInterface ( IID_IDirect3D9 , ( void * * ) & m_d3d9 ) ) ;
m_pool = D3DPOOL_DEFAULT ;
}
else
# endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
{
2014-10-22 20:45:08 -07:00
Direct3DCreate9 = ( Direct3DCreate9Fn ) bx : : dlsym ( m_d3d9dll , " Direct3DCreate9 " ) ;
BGFX_FATAL ( NULL ! = Direct3DCreate9 , Fatal : : UnableToInitialize , " Function Direct3DCreate9 not found. " ) ;
m_d3d9 = Direct3DCreate9 ( D3D_SDK_VERSION ) ;
2013-07-26 22:55:13 -07:00
m_pool = D3DPOOL_MANAGED ;
}
2012-08-05 14:51:49 -07:00
2012-12-08 14:30:41 -08:00
BGFX_FATAL ( m_d3d9 , Fatal : : UnableToInitialize , " Unable to create Direct3D. " ) ;
2012-08-05 14:51:49 -07:00
m_adapter = D3DADAPTER_DEFAULT ;
m_deviceType = D3DDEVTYPE_HAL ;
2015-03-26 15:01:47 -07:00
uint8_t numGPUs = bx : : uint32_min ( BX_COUNTOF ( g_caps . gpu ) , m_d3d9 - > GetAdapterCount ( ) ) ;
for ( uint32_t ii = 0 ; ii < numGPUs ; + + ii )
2012-08-05 14:51:49 -07:00
{
2015-03-26 15:01:47 -07:00
D3DADAPTER_IDENTIFIER9 desc ;
HRESULT hr = m_d3d9 - > GetAdapterIdentifier ( ii , 0 , & desc ) ;
2013-04-27 18:03:40 -07:00
if ( SUCCEEDED ( hr ) )
{
BX_TRACE ( " Adapter #%d " , ii ) ;
2015-03-26 15:01:47 -07:00
BX_TRACE ( " \t Driver: %s " , desc . Driver ) ;
BX_TRACE ( " \t Description: %s " , desc . Description ) ;
BX_TRACE ( " \t DeviceName: %s " , desc . DeviceName ) ;
2013-04-27 18:03:40 -07:00
BX_TRACE ( " \t VendorId: 0x%08x, DeviceId: 0x%08x, SubSysId: 0x%08x, Revision: 0x%08x "
2015-03-26 15:01:47 -07:00
, desc . VendorId
, desc . DeviceId
, desc . SubSysId
, desc . Revision
2012-08-05 14:51:49 -07:00
) ;
2015-03-26 15:01:47 -07:00
g_caps . gpu [ ii ] . vendorId = ( uint16_t ) desc . VendorId ;
g_caps . gpu [ ii ] . deviceId = ( uint16_t ) desc . DeviceId ;
2015-03-31 22:01:50 -07:00
if ( D3DADAPTER_DEFAULT = = m_adapter )
2015-03-26 15:01:47 -07:00
{
2015-03-31 22:01:50 -07:00
if ( ( BGFX_PCI_ID_NONE ! = g_caps . vendorId | | 0 ! = g_caps . deviceId )
& & ( BGFX_PCI_ID_NONE = = g_caps . vendorId | | desc . VendorId = = g_caps . vendorId )
& & ( 0 = = g_caps . deviceId | | desc . DeviceId = = g_caps . deviceId ) )
{
m_adapter = ii ;
}
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG_PERFHUD )
2015-04-01 13:02:48 +02:00
& & 0 ! = strstr ( desc . Description , " PerfHUD " ) )
2015-03-31 22:01:50 -07:00
{
m_adapter = ii ;
m_deviceType = D3DDEVTYPE_REF ;
}
2015-03-26 15:01:47 -07:00
}
2013-04-27 18:03:40 -07:00
}
2012-08-05 14:51:49 -07:00
}
2013-04-27 16:55:34 -07:00
DX_CHECK ( m_d3d9 - > GetAdapterIdentifier ( m_adapter , 0 , & m_identifier ) ) ;
2015-03-26 15:01:47 -07:00
m_amd = m_identifier . VendorId = = BGFX_PCI_ID_AMD ;
m_nvidia = m_identifier . VendorId = = BGFX_PCI_ID_NVIDIA ;
g_caps . vendorId = ( uint16_t ) m_identifier . VendorId ;
g_caps . deviceId = ( uint16_t ) m_identifier . DeviceId ;
2012-08-05 14:51:49 -07:00
uint32_t behaviorFlags [ ] =
{
2014-09-07 17:17:38 -07:00
D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE | D3DCREATE_PUREDEVICE ,
D3DCREATE_MIXED_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE ,
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE ,
2012-08-05 14:51:49 -07:00
} ;
2013-08-06 21:04:28 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( behaviorFlags ) & & NULL = = m_device ; + + ii )
2012-08-05 14:51:49 -07:00
{
2013-07-26 22:55:13 -07:00
#if 0 // BGFX_CONFIG_RENDERER_DIRECT3D9EX
2012-08-05 14:51:49 -07:00
DX_CHECK ( m_d3d9 - > CreateDeviceEx ( m_adapter
, m_deviceType
, g_bgfxHwnd
, behaviorFlags [ ii ]
, & m_params
, NULL
, & m_device
) ) ;
# else
DX_CHECK ( m_d3d9 - > CreateDevice ( m_adapter
, m_deviceType
, g_bgfxHwnd
, behaviorFlags [ ii ]
, & m_params
, & m_device
) ) ;
# endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
}
2012-12-08 14:30:41 -08:00
BGFX_FATAL ( m_device , Fatal : : UnableToInitialize , " Unable to create Direct3D9 device. " ) ;
2012-08-05 14:51:49 -07:00
2014-09-07 17:17:38 -07:00
m_numWindows = 1 ;
2013-07-26 22:55:13 -07:00
# if BGFX_CONFIG_RENDERER_DIRECT3D9EX
if ( NULL ! = m_d3d9ex )
{
DX_CHECK ( m_device - > QueryInterface ( IID_IDirect3DDevice9Ex , ( void * * ) & m_deviceEx ) ) ;
}
# endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
2012-08-05 14:51:49 -07:00
DX_CHECK ( m_device - > GetDeviceCaps ( & m_caps ) ) ;
// For shit GPUs that can create DX9 device but can't do simple stuff. GTFO!
BGFX_FATAL ( ( D3DPTEXTURECAPS_SQUAREONLY & m_caps . TextureCaps ) = = 0 , Fatal : : MinimumRequiredSpecs , " D3DPTEXTURECAPS_SQUAREONLY " ) ;
BGFX_FATAL ( ( D3DPTEXTURECAPS_MIPMAP & m_caps . TextureCaps ) = = D3DPTEXTURECAPS_MIPMAP , Fatal : : MinimumRequiredSpecs , " D3DPTEXTURECAPS_MIPMAP " ) ;
BGFX_FATAL ( ( D3DPTEXTURECAPS_ALPHA & m_caps . TextureCaps ) = = D3DPTEXTURECAPS_ALPHA , Fatal : : MinimumRequiredSpecs , " D3DPTEXTURECAPS_ALPHA " ) ;
BGFX_FATAL ( m_caps . VertexShaderVersion > = D3DVS_VERSION ( 2 , 0 ) & & m_caps . PixelShaderVersion > = D3DPS_VERSION ( 2 , 1 )
, Fatal : : MinimumRequiredSpecs
, " Shader Model Version (vs: %x, ps: %x). "
, m_caps . VertexShaderVersion
, m_caps . PixelShaderVersion
) ;
BX_TRACE ( " Max vertex shader 3.0 instr. slots: %d " , m_caps . MaxVertexShader30InstructionSlots ) ;
BX_TRACE ( " Max vertex shader constants: %d " , m_caps . MaxVertexShaderConst ) ;
BX_TRACE ( " Max fragment shader 2.0 instr. slots: %d " , m_caps . PS20Caps . NumInstructionSlots ) ;
BX_TRACE ( " Max fragment shader 3.0 instr. slots: %d " , m_caps . MaxPixelShader30InstructionSlots ) ;
2014-02-05 23:07:11 -08:00
BX_TRACE ( " Num simultaneous render targets: %d " , m_caps . NumSimultaneousRTs ) ;
2012-08-05 14:51:49 -07:00
2014-01-12 13:51:26 -08:00
g_caps . supported | = ( 0
2013-12-02 19:47:12 -08:00
| BGFX_CAPS_TEXTURE_3D
2014-02-23 11:21:23 -08:00
| BGFX_CAPS_TEXTURE_COMPARE_LEQUAL
2013-12-02 19:47:12 -08:00
| BGFX_CAPS_VERTEX_ATTRIB_HALF
2013-12-15 12:30:23 -08:00
| BGFX_CAPS_FRAGMENT_DEPTH
2014-09-23 20:35:39 -07:00
| BGFX_CAPS_SWAP_CHAIN
2013-12-02 19:47:12 -08:00
) ;
2013-10-10 18:29:57 -07:00
g_caps . maxTextureSize = bx : : uint32_min ( m_caps . MaxTextureWidth , m_caps . MaxTextureHeight ) ;
2014-02-05 23:07:11 -08:00
m_caps . NumSimultaneousRTs = bx : : uint32_min ( m_caps . NumSimultaneousRTs , BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS ) ;
g_caps . maxFBAttachments = ( uint8_t ) m_caps . NumSimultaneousRTs ;
2015-01-20 22:07:30 -08:00
m_caps . MaxAnisotropy = bx : : uint32_min ( m_caps . MaxAnisotropy , 1 ) ;
2014-09-23 20:35:39 -07:00
if ( BX_ENABLED ( BGFX_CONFIG_RENDERER_USE_EXTENSIONS ) )
2012-08-05 14:51:49 -07:00
{
2014-09-23 20:35:39 -07:00
BX_TRACE ( " Extended formats: " ) ;
for ( uint32_t ii = 0 ; ii < ExtendedFormat : : Count ; + + ii )
{
ExtendedFormat & fmt = s_extendedFormats [ ii ] ;
fmt . m_supported = SUCCEEDED ( m_d3d9 - > CheckDeviceFormat ( m_adapter , m_deviceType , adapterFormat , fmt . m_usage , fmt . m_type , fmt . m_fmt ) ) ;
const char * fourcc = ( const char * ) & fmt . m_fmt ;
BX_TRACE ( " \t %2d: %c%c%c%c %s " , ii , fourcc [ 0 ] , fourcc [ 1 ] , fourcc [ 2 ] , fourcc [ 3 ] , fmt . m_supported ? " supported " : " " ) ;
BX_UNUSED ( fourcc ) ;
}
2012-08-05 14:51:49 -07:00
2014-09-23 20:35:39 -07:00
m_instancing = false
| | s_extendedFormats [ ExtendedFormat : : Inst ] . m_supported
| | ( m_caps . VertexShaderVersion > = D3DVS_VERSION ( 3 , 0 ) )
;
2012-08-05 14:51:49 -07:00
2014-09-23 20:35:39 -07:00
if ( m_amd
& & s_extendedFormats [ ExtendedFormat : : Inst ] . m_supported )
{ // AMD only
m_device - > SetRenderState ( D3DRS_POINTSIZE , D3DFMT_INST ) ;
}
2012-08-05 14:51:49 -07:00
2014-09-23 20:35:39 -07:00
if ( s_extendedFormats [ ExtendedFormat : : Intz ] . m_supported )
{
s_textureFormat [ TextureFormat : : D24 ] . m_fmt = D3DFMT_INTZ ;
s_textureFormat [ TextureFormat : : D32 ] . m_fmt = D3DFMT_INTZ ;
}
2014-05-21 20:33:12 -07:00
2014-09-23 20:35:39 -07:00
s_textureFormat [ TextureFormat : : BC4 ] . m_fmt = s_extendedFormats [ ExtendedFormat : : Ati1 ] . m_supported ? D3DFMT_ATI1 : D3DFMT_UNKNOWN ;
s_textureFormat [ TextureFormat : : BC5 ] . m_fmt = s_extendedFormats [ ExtendedFormat : : Ati2 ] . m_supported ? D3DFMT_ATI2 : D3DFMT_UNKNOWN ;
2013-10-10 18:29:57 -07:00
2014-09-23 20:35:39 -07:00
g_caps . supported | = m_instancing ? BGFX_CAPS_INSTANCING : 0 ;
2014-07-27 20:44:02 -07:00
2014-09-23 20:35:39 -07:00
for ( uint32_t ii = 0 ; ii < TextureFormat : : Count ; + + ii )
{
2015-03-01 22:01:30 -08:00
uint8_t support = SUCCEEDED ( m_d3d9 - > CheckDeviceFormat ( m_adapter
2014-09-23 20:35:39 -07:00
, m_deviceType
, adapterFormat
, 0
, D3DRTYPE_TEXTURE
, s_textureFormat [ ii ] . m_fmt
2015-03-01 22:01:30 -08:00
) ) ? BGFX_CAPS_FORMAT_TEXTURE_COLOR : BGFX_CAPS_FORMAT_TEXTURE_NONE ;
support | = SUCCEEDED ( m_d3d9 - > CheckDeviceFormat ( m_adapter
, m_deviceType
, adapterFormat
, D3DUSAGE_QUERY_VERTEXTEXTURE
, D3DRTYPE_TEXTURE
, s_textureFormat [ ii ] . m_fmt
) ) ? BGFX_CAPS_FORMAT_TEXTURE_VERTEX : BGFX_CAPS_FORMAT_TEXTURE_NONE ;
g_caps . formats [ ii ] = support ;
2014-09-23 20:35:39 -07:00
}
2014-07-27 20:44:02 -07:00
}
2013-09-08 21:03:03 -07:00
2012-08-05 14:51:49 -07:00
uint32_t index = 1 ;
for ( const D3DFORMAT * fmt = & s_checkColorFormats [ index ] ; * fmt ! = D3DFMT_UNKNOWN ; + + fmt , + + index )
{
for ( ; * fmt ! = D3DFMT_UNKNOWN ; + + fmt )
{
if ( SUCCEEDED ( m_d3d9 - > CheckDeviceFormat ( m_adapter , m_deviceType , adapterFormat , D3DUSAGE_RENDERTARGET , D3DRTYPE_TEXTURE , * fmt ) ) )
{
s_colorFormat [ index ] = * fmt ;
break ;
}
}
for ( ; * fmt ! = D3DFMT_UNKNOWN ; + + fmt ) ;
}
m_fmtDepth = D3DFMT_D24S8 ;
# elif BX_PLATFORM_XBOX360
m_params . PresentationInterval = D3DPRESENT_INTERVAL_ONE ;
m_params . DisableAutoBackBuffer = FALSE ;
m_params . DisableAutoFrontBuffer = FALSE ;
m_params . FrontBufferFormat = D3DFMT_X8R8G8B8 ;
m_params . FrontBufferColorSpace = D3DCOLORSPACE_RGB ;
m_d3d9 = Direct3DCreate9 ( D3D_SDK_VERSION ) ;
BX_TRACE ( " Creating D3D9 %p " , m_d3d9 ) ;
XVIDEO_MODE videoMode ;
XGetVideoMode ( & videoMode ) ;
if ( ! videoMode . fIsWideScreen )
{
m_params . Flags | = D3DPRESENTFLAG_NO_LETTERBOX ;
}
BX_TRACE ( " Creating device " ) ;
DX_CHECK ( m_d3d9 - > CreateDevice ( m_adapter
, m_deviceType
, NULL
, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_BUFFER_2_FRAMES
, & m_params
, & m_device
) ) ;
BX_TRACE ( " Device %p " , m_device ) ;
m_fmtDepth = D3DFMT_D24FS8 ;
# endif // BX_PLATFORM_WINDOWS
2014-09-27 14:15:56 -07:00
{
IDirect3DSwapChain9 * swapChain ;
DX_CHECK ( m_device - > GetSwapChain ( 0 , & swapChain ) ) ;
// GPA increases swapchain ref count.
//
// This causes assert in debug. When debugger is present refcount
// checks are off.
setGraphicsDebuggerPresent ( 1 ! = getRefCount ( swapChain ) ) ;
DX_RELEASE ( swapChain , 0 ) ;
}
2014-10-25 18:07:51 -07:00
// Init reserved part of view name.
2015-02-21 15:40:51 -08:00
for ( uint32_t ii = 0 ; ii < BGFX_CONFIG_MAX_VIEWS ; + + ii )
2014-10-25 18:07:51 -07:00
{
char name [ BGFX_CONFIG_MAX_VIEW_NAME_RESERVED + 1 ] ;
2015-04-02 11:57:53 -07:00
bx : : snprintf ( name , sizeof ( name ) , " %3d " , ii ) ;
2014-10-25 18:07:51 -07:00
mbstowcs ( s_viewNameW [ ii ] , name , BGFX_CONFIG_MAX_VIEW_NAME_RESERVED ) ;
}
2012-08-05 14:51:49 -07:00
postReset ( ) ;
m_initialized = true ;
}
2014-10-13 21:14:51 -07:00
void shutdown ( )
2012-08-05 14:51:49 -07:00
{
preReset ( ) ;
2013-08-06 21:04:28 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_indexBuffers ) ; + + ii )
2012-08-05 14:51:49 -07:00
{
m_indexBuffers [ ii ] . destroy ( ) ;
}
2013-08-06 21:04:28 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_vertexBuffers ) ; + + ii )
2012-08-05 14:51:49 -07:00
{
m_vertexBuffers [ ii ] . destroy ( ) ;
}
2014-03-29 19:42:57 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_shaders ) ; + + ii )
2012-08-05 14:51:49 -07:00
{
2014-03-29 19:42:57 -07:00
m_shaders [ ii ] . destroy ( ) ;
2012-08-05 14:51:49 -07:00
}
2013-08-06 21:04:28 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_textures ) ; + + ii )
2012-08-05 14:51:49 -07:00
{
m_textures [ ii ] . destroy ( ) ;
}
2013-08-06 21:04:28 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_vertexDecls ) ; + + ii )
2012-08-05 14:51:49 -07:00
{
m_vertexDecls [ ii ] . destroy ( ) ;
}
2013-07-26 22:55:13 -07:00
# if BGFX_CONFIG_RENDERER_DIRECT3D9EX
if ( NULL ! = m_d3d9ex )
{
DX_RELEASE ( m_deviceEx , 1 ) ;
DX_RELEASE ( m_device , 0 ) ;
DX_RELEASE ( m_d3d9 , 1 ) ;
DX_RELEASE ( m_d3d9ex , 0 ) ;
}
else
# endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
{
DX_RELEASE ( m_device , 0 ) ;
DX_RELEASE ( m_d3d9 , 0 ) ;
}
2012-08-05 14:51:49 -07:00
# if BX_PLATFORM_WINDOWS
2013-07-26 22:55:13 -07:00
bx : : dlclose ( m_d3d9dll ) ;
2012-08-05 14:51:49 -07:00
# endif // BX_PLATFORM_WINDOWS
m_initialized = false ;
}
2014-05-26 14:09:26 -07:00
RendererType : : Enum getRendererType ( ) const BX_OVERRIDE
{
return RendererType : : Direct3D9 ;
}
const char * getRendererName ( ) const BX_OVERRIDE
{
return BGFX_RENDERER_DIRECT3D9_NAME ;
}
2015-01-10 20:56:38 -08:00
void createIndexBuffer ( IndexBufferHandle _handle , Memory * _mem , uint8_t /*_flags*/ ) BX_OVERRIDE
2014-05-26 14:09:26 -07:00
{
m_indexBuffers [ _handle . idx ] . create ( _mem - > size , _mem - > data ) ;
}
void destroyIndexBuffer ( IndexBufferHandle _handle ) BX_OVERRIDE
{
m_indexBuffers [ _handle . idx ] . destroy ( ) ;
}
void createVertexDecl ( VertexDeclHandle _handle , const VertexDecl & _decl ) BX_OVERRIDE
{
m_vertexDecls [ _handle . idx ] . create ( _decl ) ;
}
void destroyVertexDecl ( VertexDeclHandle _handle ) BX_OVERRIDE
{
m_vertexDecls [ _handle . idx ] . destroy ( ) ;
}
2014-12-09 23:16:27 -08:00
void createVertexBuffer ( VertexBufferHandle _handle , Memory * _mem , VertexDeclHandle _declHandle , uint8_t /*_flags*/ ) BX_OVERRIDE
2014-05-26 14:09:26 -07:00
{
m_vertexBuffers [ _handle . idx ] . create ( _mem - > size , _mem - > data , _declHandle ) ;
}
void destroyVertexBuffer ( VertexBufferHandle _handle ) BX_OVERRIDE
{
m_vertexBuffers [ _handle . idx ] . destroy ( ) ;
}
2015-01-10 20:38:47 -08:00
void createDynamicIndexBuffer ( IndexBufferHandle _handle , uint32_t _size , uint8_t /*_flags*/ ) BX_OVERRIDE
2014-05-26 14:09:26 -07:00
{
m_indexBuffers [ _handle . idx ] . create ( _size , NULL ) ;
}
void updateDynamicIndexBuffer ( IndexBufferHandle _handle , uint32_t _offset , uint32_t _size , Memory * _mem ) BX_OVERRIDE
{
m_indexBuffers [ _handle . idx ] . update ( _offset , bx : : uint32_min ( _size , _mem - > size ) , _mem - > data ) ;
}
void destroyDynamicIndexBuffer ( IndexBufferHandle _handle ) BX_OVERRIDE
{
m_indexBuffers [ _handle . idx ] . destroy ( ) ;
}
2014-12-09 23:16:27 -08:00
void createDynamicVertexBuffer ( VertexBufferHandle _handle , uint32_t _size , uint8_t /*_flags*/ ) BX_OVERRIDE
2014-05-26 14:09:26 -07:00
{
VertexDeclHandle decl = BGFX_INVALID_HANDLE ;
m_vertexBuffers [ _handle . idx ] . create ( _size , NULL , decl ) ;
}
void updateDynamicVertexBuffer ( VertexBufferHandle _handle , uint32_t _offset , uint32_t _size , Memory * _mem ) BX_OVERRIDE
{
m_vertexBuffers [ _handle . idx ] . update ( _offset , bx : : uint32_min ( _size , _mem - > size ) , _mem - > data ) ;
}
void destroyDynamicVertexBuffer ( VertexBufferHandle _handle ) BX_OVERRIDE
{
m_vertexBuffers [ _handle . idx ] . destroy ( ) ;
}
void createShader ( ShaderHandle _handle , Memory * _mem ) BX_OVERRIDE
{
m_shaders [ _handle . idx ] . create ( _mem ) ;
}
void destroyShader ( ShaderHandle _handle ) BX_OVERRIDE
{
m_shaders [ _handle . idx ] . destroy ( ) ;
}
void createProgram ( ProgramHandle _handle , ShaderHandle _vsh , ShaderHandle _fsh ) BX_OVERRIDE
{
m_program [ _handle . idx ] . create ( m_shaders [ _vsh . idx ] , m_shaders [ _fsh . idx ] ) ;
}
void destroyProgram ( ProgramHandle _handle ) BX_OVERRIDE
{
m_program [ _handle . idx ] . destroy ( ) ;
}
void createTexture ( TextureHandle _handle , Memory * _mem , uint32_t _flags , uint8_t _skip ) BX_OVERRIDE
{
m_textures [ _handle . idx ] . create ( _mem , _flags , _skip ) ;
}
void updateTextureBegin ( TextureHandle _handle , uint8_t _side , uint8_t _mip ) BX_OVERRIDE
{
m_updateTexture = & m_textures [ _handle . idx ] ;
m_updateTexture - > updateBegin ( _side , _mip ) ;
}
void updateTexture ( TextureHandle /*_handle*/ , uint8_t _side , uint8_t _mip , const Rect & _rect , uint16_t _z , uint16_t _depth , uint16_t _pitch , const Memory * _mem ) BX_OVERRIDE
{
m_updateTexture - > update ( _side , _mip , _rect , _z , _depth , _pitch , _mem ) ;
}
void updateTextureEnd ( ) BX_OVERRIDE
{
m_updateTexture - > updateEnd ( ) ;
m_updateTexture = NULL ;
}
void destroyTexture ( TextureHandle _handle ) BX_OVERRIDE
{
m_textures [ _handle . idx ] . destroy ( ) ;
}
void createFrameBuffer ( FrameBufferHandle _handle , uint8_t _num , const TextureHandle * _textureHandles ) BX_OVERRIDE
{
m_frameBuffers [ _handle . idx ] . create ( _num , _textureHandles ) ;
}
2014-09-07 17:17:38 -07:00
void createFrameBuffer ( FrameBufferHandle _handle , void * _nwh , uint32_t _width , uint32_t _height , TextureFormat : : Enum _depthFormat ) BX_OVERRIDE
{
uint16_t denseIdx = m_numWindows + + ;
m_windows [ denseIdx ] = _handle ;
m_frameBuffers [ _handle . idx ] . create ( denseIdx , _nwh , _width , _height , _depthFormat ) ;
}
2014-05-26 14:09:26 -07:00
void destroyFrameBuffer ( FrameBufferHandle _handle ) BX_OVERRIDE
{
2014-09-07 17:17:38 -07:00
uint16_t denseIdx = m_frameBuffers [ _handle . idx ] . destroy ( ) ;
if ( UINT16_MAX ! = denseIdx )
{
- - m_numWindows ;
if ( m_numWindows > 1 )
{
FrameBufferHandle handle = m_windows [ m_numWindows ] ;
m_windows [ denseIdx ] = handle ;
m_frameBuffers [ handle . idx ] . m_denseIdx = denseIdx ;
}
}
2014-05-26 14:09:26 -07:00
}
void createUniform ( UniformHandle _handle , UniformType : : Enum _type , uint16_t _num , const char * _name ) BX_OVERRIDE
{
if ( NULL ! = m_uniforms [ _handle . idx ] )
{
BX_FREE ( g_allocator , m_uniforms [ _handle . idx ] ) ;
}
uint32_t size = BX_ALIGN_16 ( g_uniformTypeSize [ _type ] * _num ) ;
void * data = BX_ALLOC ( g_allocator , size ) ;
memset ( data , 0 , size ) ;
m_uniforms [ _handle . idx ] = data ;
m_uniformReg . add ( _handle , _name , data ) ;
}
void destroyUniform ( UniformHandle _handle ) BX_OVERRIDE
{
BX_FREE ( g_allocator , m_uniforms [ _handle . idx ] ) ;
m_uniforms [ _handle . idx ] = NULL ;
}
void saveScreenShot ( const char * _filePath ) BX_OVERRIDE
{
# if BX_PLATFORM_WINDOWS
IDirect3DSurface9 * surface ;
D3DDEVICE_CREATION_PARAMETERS dcp ;
DX_CHECK ( m_device - > GetCreationParameters ( & dcp ) ) ;
D3DDISPLAYMODE dm ;
DX_CHECK ( m_d3d9 - > GetAdapterDisplayMode ( dcp . AdapterOrdinal , & dm ) ) ;
DX_CHECK ( m_device - > CreateOffscreenPlainSurface ( dm . Width
, dm . Height
, D3DFMT_A8R8G8B8
, D3DPOOL_SCRATCH
, & surface
, NULL
) ) ;
DX_CHECK ( m_device - > GetFrontBufferData ( 0 , surface ) ) ;
D3DLOCKED_RECT rect ;
DX_CHECK ( surface - > LockRect ( & rect
, NULL
, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY
) ) ;
RECT rc ;
GetClientRect ( g_bgfxHwnd , & rc ) ;
POINT point ;
point . x = rc . left ;
point . y = rc . top ;
ClientToScreen ( g_bgfxHwnd , & point ) ;
uint8_t * data = ( uint8_t * ) rect . pBits ;
uint32_t bytesPerPixel = rect . Pitch / dm . Width ;
g_callback - > screenShot ( _filePath
, m_params . BackBufferWidth
, m_params . BackBufferHeight
, rect . Pitch
, & data [ point . y * rect . Pitch + point . x * bytesPerPixel ]
2014-09-01 13:22:34 -07:00
, m_params . BackBufferHeight * rect . Pitch
2014-05-26 14:09:26 -07:00
, false
) ;
DX_CHECK ( surface - > UnlockRect ( ) ) ;
DX_RELEASE ( surface , 0 ) ;
# endif // BX_PLATFORM_WINDOWS
}
void updateViewName ( uint8_t _id , const char * _name ) BX_OVERRIDE
{
2015-04-02 11:57:53 -07:00
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG_PIX ) )
{
mbstowcs ( & s_viewNameW [ _id ] [ BGFX_CONFIG_MAX_VIEW_NAME_RESERVED ]
, _name
, BX_COUNTOF ( s_viewNameW [ 0 ] ) - BGFX_CONFIG_MAX_VIEW_NAME_RESERVED
) ;
}
2014-05-26 14:09:26 -07:00
}
void updateUniform ( uint16_t _loc , const void * _data , uint32_t _size ) BX_OVERRIDE
{
memcpy ( m_uniforms [ _loc ] , _data , _size ) ;
}
void setMarker ( const char * _marker , uint32_t _size ) BX_OVERRIDE
{
# if BGFX_CONFIG_DEBUG_PIX
uint32_t size = _size * sizeof ( wchar_t ) ;
wchar_t * name = ( wchar_t * ) alloca ( size ) ;
mbstowcs ( name , _marker , size - 2 ) ;
PIX_SETMARKER ( D3DCOLOR_RGBA ( 0xff , 0xff , 0xff , 0xff ) , name ) ;
# endif // BGFX_CONFIG_DEBUG_PIX
BX_UNUSED ( _marker , _size ) ;
}
void submit ( Frame * _render , ClearQuad & _clearQuad , TextVideoMemBlitter & _textVideoMemBlitter ) BX_OVERRIDE ;
void blitSetup ( TextVideoMemBlitter & _blitter ) BX_OVERRIDE
{
uint32_t width = m_params . BackBufferWidth ;
uint32_t height = m_params . BackBufferHeight ;
FrameBufferHandle fbh = BGFX_INVALID_HANDLE ;
setFrameBuffer ( fbh , false ) ;
D3DVIEWPORT9 vp ;
vp . X = 0 ;
vp . Y = 0 ;
vp . Width = width ;
vp . Height = height ;
vp . MinZ = 0.0f ;
vp . MaxZ = 1.0f ;
IDirect3DDevice9 * device = m_device ;
DX_CHECK ( device - > SetViewport ( & vp ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_STENCILENABLE , FALSE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ZENABLE , FALSE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ZFUNC , D3DCMP_ALWAYS ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_CULLMODE , D3DCULL_NONE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ALPHABLENDENABLE , FALSE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ALPHAFUNC , D3DCMP_GREATER ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_COLORWRITEENABLE , D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_FILLMODE , D3DFILL_SOLID ) ) ;
ProgramD3D9 & program = m_program [ _blitter . m_program . idx ] ;
2014-07-20 20:27:13 -07:00
DX_CHECK ( device - > SetVertexShader ( program . m_vsh - > m_vertexShader ) ) ;
DX_CHECK ( device - > SetPixelShader ( program . m_fsh - > m_pixelShader ) ) ;
2014-05-26 14:09:26 -07:00
VertexBufferD3D9 & vb = m_vertexBuffers [ _blitter . m_vb - > handle . idx ] ;
2014-09-01 11:24:51 -07:00
VertexDeclD3D9 & vertexDecl = m_vertexDecls [ _blitter . m_vb - > decl . idx ] ;
2014-05-26 14:09:26 -07:00
DX_CHECK ( device - > SetStreamSource ( 0 , vb . m_ptr , 0 , vertexDecl . m_decl . m_stride ) ) ;
DX_CHECK ( device - > SetVertexDeclaration ( vertexDecl . m_ptr ) ) ;
IndexBufferD3D9 & ib = m_indexBuffers [ _blitter . m_ib - > handle . idx ] ;
DX_CHECK ( device - > SetIndices ( ib . m_ptr ) ) ;
float proj [ 16 ] ;
mtxOrtho ( proj , 0.0f , ( float ) width , ( float ) height , 0.0f , 0.0f , 1000.0f ) ;
PredefinedUniform & predefined = program . m_predefined [ 0 ] ;
uint8_t flags = predefined . m_type ;
2014-12-27 19:00:41 -08:00
setShaderUniform ( flags , predefined . m_loc , proj , 4 ) ;
2014-05-26 14:09:26 -07:00
m_textures [ _blitter . m_texture . idx ] . commit ( 0 ) ;
}
void blitRender ( TextVideoMemBlitter & _blitter , uint32_t _numIndices ) BX_OVERRIDE
{
2015-01-26 19:09:51 -08:00
const uint32_t numVertices = _numIndices * 4 / 6 ;
if ( 0 < numVertices )
{
m_indexBuffers [ _blitter . m_ib - > handle . idx ] . update ( 0 , _numIndices * 2 , _blitter . m_ib - > data , true ) ;
m_vertexBuffers [ _blitter . m_vb - > handle . idx ] . update ( 0 , numVertices * _blitter . m_decl . m_stride , _blitter . m_vb - > data , true ) ;
DX_CHECK ( m_device - > DrawIndexedPrimitive ( D3DPT_TRIANGLELIST
, 0
, 0
, numVertices
, 0
, _numIndices / 3
) ) ;
}
2014-05-26 14:09:26 -07:00
}
2012-08-05 14:51:49 -07:00
void updateMsaa ( )
{
2013-08-06 21:04:28 -07:00
for ( uint32_t ii = 1 , last = 0 ; ii < BX_COUNTOF ( s_checkMsaa ) ; + + ii )
2012-08-05 14:51:49 -07:00
{
D3DMULTISAMPLE_TYPE msaa = s_checkMsaa [ ii ] ;
DWORD quality ;
HRESULT hr = m_d3d9 - > CheckDeviceMultiSampleType ( m_adapter
, m_deviceType
, m_params . BackBufferFormat
, m_params . Windowed
, msaa
, & quality
) ;
if ( SUCCEEDED ( hr ) )
{
s_msaa [ ii ] . m_type = msaa ;
2013-08-03 22:15:13 -07:00
s_msaa [ ii ] . m_quality = bx : : uint32_imax ( 0 , quality - 1 ) ;
2012-08-05 14:51:49 -07:00
last = ii ;
}
else
{
s_msaa [ ii ] = s_msaa [ last ] ;
}
}
}
void updateResolution ( const Resolution & _resolution )
{
2015-01-21 20:39:42 -08:00
m_maxAnisotropy = ! ! ( _resolution . m_flags & BGFX_RESET_MAXANISOTROPY )
? m_caps . MaxAnisotropy
: 1
;
uint32_t flags = _resolution . m_flags & ~ ( BGFX_RESET_HMD_RECENTER | BGFX_RESET_MAXANISOTROPY ) ;
2014-09-07 17:17:38 -07:00
if ( m_params . BackBufferWidth ! = _resolution . m_width
| | m_params . BackBufferHeight ! = _resolution . m_height
2015-01-21 20:39:42 -08:00
| | m_flags ! = flags )
2012-08-05 14:51:49 -07:00
{
2015-01-21 20:39:42 -08:00
m_flags = flags ;
2012-08-05 14:51:49 -07:00
m_textVideoMem . resize ( false , _resolution . m_width , _resolution . m_height ) ;
m_textVideoMem . clear ( ) ;
# if BX_PLATFORM_WINDOWS
D3DDEVICE_CREATION_PARAMETERS dcp ;
DX_CHECK ( m_device - > GetCreationParameters ( & dcp ) ) ;
D3DDISPLAYMODE dm ;
DX_CHECK ( m_d3d9 - > GetAdapterDisplayMode ( dcp . AdapterOrdinal , & dm ) ) ;
2014-05-26 14:09:26 -07:00
2012-08-05 14:51:49 -07:00
m_params . BackBufferFormat = dm . Format ;
# endif // BX_PLATFORM_WINDOWS
2014-09-07 17:17:38 -07:00
m_params . BackBufferWidth = _resolution . m_width ;
2012-08-05 14:51:49 -07:00
m_params . BackBufferHeight = _resolution . m_height ;
m_params . FullScreen_RefreshRateInHz = BGFX_RESET_FULLSCREEN = = ( m_flags & BGFX_RESET_FULLSCREEN_MASK ) ? 60 : 0 ;
m_params . PresentationInterval = ! ! ( m_flags & BGFX_RESET_VSYNC ) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE ;
updateMsaa ( ) ;
Msaa & msaa = s_msaa [ ( m_flags & BGFX_RESET_MSAA_MASK ) > > BGFX_RESET_MSAA_SHIFT ] ;
2014-09-07 17:17:38 -07:00
m_params . MultiSampleType = msaa . m_type ;
2012-08-05 14:51:49 -07:00
m_params . MultiSampleQuality = msaa . m_quality ;
2014-05-26 14:09:26 -07:00
m_resolution = _resolution ;
2012-08-05 14:51:49 -07:00
preReset ( ) ;
DX_CHECK ( m_device - > Reset ( & m_params ) ) ;
postReset ( ) ;
}
}
2014-02-05 23:07:11 -08:00
void setFrameBuffer ( FrameBufferHandle _fbh , bool _msaa = true )
2012-08-05 14:51:49 -07:00
{
2014-08-20 15:55:30 -07:00
if ( isValid ( m_fbh )
2014-08-20 20:11:50 -07:00
& & m_fbh . idx ! = _fbh . idx
& & m_rtMsaa )
2014-08-20 15:55:30 -07:00
{
FrameBufferD3D9 & frameBuffer = m_frameBuffers [ m_fbh . idx ] ;
frameBuffer . resolve ( ) ;
}
2014-02-05 23:07:11 -08:00
if ( ! isValid ( _fbh ) )
2012-08-05 14:51:49 -07:00
{
DX_CHECK ( m_device - > SetRenderTarget ( 0 , m_backBufferColor ) ) ;
2014-02-05 23:07:11 -08:00
for ( uint32_t ii = 1 , num = g_caps . maxFBAttachments ; ii < num ; + + ii )
{
DX_CHECK ( m_device - > SetRenderTarget ( ii , NULL ) ) ;
}
2012-08-05 14:51:49 -07:00
DX_CHECK ( m_device - > SetDepthStencilSurface ( m_backBufferDepthStencil ) ) ;
}
else
{
2014-05-26 14:09:26 -07:00
const FrameBufferD3D9 & frameBuffer = m_frameBuffers [ _fbh . idx ] ;
2014-08-20 20:11:50 -07:00
// If frame buffer has only depth attachment D3DFMT_NULL
2014-02-22 08:48:30 -08:00
// render target is created.
uint32_t fbnum = bx : : uint32_max ( 1 , frameBuffer . m_num ) ;
for ( uint32_t ii = 0 ; ii < fbnum ; + + ii )
2012-08-05 14:51:49 -07:00
{
2014-02-05 23:07:11 -08:00
DX_CHECK ( m_device - > SetRenderTarget ( ii , frameBuffer . m_color [ ii ] ) ) ;
2012-08-05 14:51:49 -07:00
}
2014-02-05 23:07:11 -08:00
2014-02-22 08:48:30 -08:00
for ( uint32_t ii = fbnum , num = g_caps . maxFBAttachments ; ii < num ; + + ii )
2012-08-05 14:51:49 -07:00
{
2014-02-05 23:07:11 -08:00
DX_CHECK ( m_device - > SetRenderTarget ( ii , NULL ) ) ;
2012-08-05 14:51:49 -07:00
}
2014-02-05 23:07:11 -08:00
IDirect3DSurface9 * depthStencil = frameBuffer . m_depthStencil ;
DX_CHECK ( m_device - > SetDepthStencilSurface ( NULL ! = depthStencil ? depthStencil : m_backBufferDepthStencil ) ) ;
2012-08-05 14:51:49 -07:00
}
2014-02-05 23:07:11 -08:00
m_fbh = _fbh ;
2012-08-05 14:51:49 -07:00
m_rtMsaa = _msaa ;
}
2014-12-27 19:00:41 -08:00
void setShaderUniform ( uint8_t _flags , uint16_t _regIndex , const void * _val , uint16_t _numRegs )
2012-08-05 14:51:49 -07:00
{
if ( _flags & BGFX_UNIFORM_FRAGMENTBIT )
{
2014-12-27 19:00:41 -08:00
DX_CHECK ( m_device - > SetPixelShaderConstantF ( _regIndex , ( const float * ) _val , _numRegs ) ) ;
2012-08-05 14:51:49 -07:00
}
else
{
2014-12-27 19:00:41 -08:00
DX_CHECK ( m_device - > SetVertexShaderConstantF ( _regIndex , ( const float * ) _val , _numRegs ) ) ;
2012-08-05 14:51:49 -07:00
}
}
2014-12-27 19:00:41 -08:00
void setShaderUniform4f ( uint8_t _flags , uint16_t _regIndex , const void * _val , uint16_t _numRegs )
{
setShaderUniform ( _flags , _regIndex , _val , _numRegs ) ;
}
void setShaderUniform4x4f ( uint8_t _flags , uint16_t _regIndex , const void * _val , uint16_t _numRegs )
{
setShaderUniform ( _flags , _regIndex , _val , _numRegs ) ;
}
2012-08-05 14:51:49 -07:00
void reset ( )
{
preReset ( ) ;
HRESULT hr ;
2015-01-10 20:38:47 -08:00
do
2012-08-05 14:51:49 -07:00
{
hr = m_device - > Reset ( & m_params ) ;
} while ( FAILED ( hr ) ) ;
postReset ( ) ;
}
2014-09-30 21:16:24 -07:00
static bool isLost ( HRESULT _hr )
2012-08-05 14:51:49 -07:00
{
return D3DERR_DEVICELOST = = _hr
| | D3DERR_DRIVERINTERNALERROR = = _hr
# if !defined(D3D_DISABLE_9EX)
| | D3DERR_DEVICEHUNG = = _hr
| | D3DERR_DEVICEREMOVED = = _hr
# endif // !defined(D3D_DISABLE_9EX)
;
}
2014-05-26 14:09:26 -07:00
void flip ( ) BX_OVERRIDE
2012-08-05 14:51:49 -07:00
{
if ( NULL ! = m_device )
{
# if BGFX_CONFIG_RENDERER_DIRECT3D9EX
2013-07-26 22:55:13 -07:00
if ( NULL ! = m_deviceEx )
{
DX_CHECK ( m_deviceEx - > WaitForVBlank ( 0 ) ) ;
}
2012-08-05 14:51:49 -07:00
# endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
2014-09-07 17:17:38 -07:00
for ( uint32_t ii = 0 , num = m_numWindows ; ii < num ; + + ii )
{
HRESULT hr ;
if ( 0 = = ii )
{
hr = m_swapChain - > Present ( NULL , NULL , g_bgfxHwnd , NULL , 0 ) ;
}
else
{
hr = m_frameBuffers [ m_windows [ ii ] . idx ] . present ( ) ;
}
2012-08-05 14:51:49 -07:00
# if BX_PLATFORM_WINDOWS
2014-09-07 17:17:38 -07:00
if ( isLost ( hr ) )
2012-08-05 14:51:49 -07:00
{
2014-09-07 17:17:38 -07:00
do
2012-08-05 14:51:49 -07:00
{
2015-01-10 20:38:47 -08:00
do
2014-09-07 17:17:38 -07:00
{
hr = m_device - > TestCooperativeLevel ( ) ;
}
while ( D3DERR_DEVICENOTRESET ! = hr ) ;
reset ( ) ;
2012-08-05 14:51:49 -07:00
hr = m_device - > TestCooperativeLevel ( ) ;
}
2014-09-07 17:17:38 -07:00
while ( FAILED ( hr ) ) ;
2012-08-05 14:51:49 -07:00
2014-09-07 17:17:38 -07:00
break ;
}
else if ( FAILED ( hr ) )
{
BX_TRACE ( " Present failed with err 0x%08x. " , hr ) ;
2012-08-05 14:51:49 -07:00
}
# endif // BX_PLATFORM_
2014-09-07 17:17:38 -07:00
}
2012-08-05 14:51:49 -07:00
}
}
void preReset ( )
{
2013-07-24 21:59:59 -07:00
invalidateSamplerState ( ) ;
2014-07-30 20:37:54 -07:00
for ( uint32_t stage = 0 ; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS ; + + stage )
2012-08-05 14:51:49 -07:00
{
DX_CHECK ( m_device - > SetTexture ( stage , NULL ) ) ;
}
DX_CHECK ( m_device - > SetRenderTarget ( 0 , m_backBufferColor ) ) ;
2014-02-05 23:07:11 -08:00
for ( uint32_t ii = 1 , num = g_caps . maxFBAttachments ; ii < num ; + + ii )
{
DX_CHECK ( m_device - > SetRenderTarget ( ii , NULL ) ) ;
}
2012-08-05 14:51:49 -07:00
DX_CHECK ( m_device - > SetDepthStencilSurface ( m_backBufferDepthStencil ) ) ;
DX_CHECK ( m_device - > SetVertexShader ( NULL ) ) ;
DX_CHECK ( m_device - > SetPixelShader ( NULL ) ) ;
DX_CHECK ( m_device - > SetStreamSource ( 0 , NULL , 0 , 0 ) ) ;
DX_CHECK ( m_device - > SetIndices ( NULL ) ) ;
DX_RELEASE ( m_backBufferColor , 0 ) ;
DX_RELEASE ( m_backBufferDepthStencil , 0 ) ;
2014-09-07 17:17:38 -07:00
DX_RELEASE ( m_swapChain , 0 ) ;
2012-08-05 14:51:49 -07:00
2012-12-30 20:52:47 -08:00
capturePreReset ( ) ;
2013-08-06 21:04:28 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_indexBuffers ) ; + + ii )
2012-08-05 14:51:49 -07:00
{
m_indexBuffers [ ii ] . preReset ( ) ;
}
2013-08-06 21:04:28 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_vertexBuffers ) ; + + ii )
2012-08-05 14:51:49 -07:00
{
m_vertexBuffers [ ii ] . preReset ( ) ;
}
2014-02-05 23:07:11 -08:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_frameBuffers ) ; + + ii )
{
m_frameBuffers [ ii ] . preReset ( ) ;
}
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_textures ) ; + + ii )
2012-08-05 14:51:49 -07:00
{
2014-02-05 23:07:11 -08:00
m_textures [ ii ] . preReset ( ) ;
2012-08-05 14:51:49 -07:00
}
}
void postReset ( )
{
2014-09-07 17:17:38 -07:00
DX_CHECK ( m_device - > GetSwapChain ( 0 , & m_swapChain ) ) ;
DX_CHECK ( m_swapChain - > GetBackBuffer ( 0 , D3DBACKBUFFER_TYPE_MONO , & m_backBufferColor ) ) ;
2012-08-05 14:51:49 -07:00
DX_CHECK ( m_device - > GetDepthStencilSurface ( & m_backBufferDepthStencil ) ) ;
2012-12-30 20:52:47 -08:00
capturePostReset ( ) ;
2013-08-06 21:04:28 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_indexBuffers ) ; + + ii )
2012-08-05 14:51:49 -07:00
{
m_indexBuffers [ ii ] . postReset ( ) ;
}
2013-08-06 21:04:28 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_vertexBuffers ) ; + + ii )
2012-08-05 14:51:49 -07:00
{
m_vertexBuffers [ ii ] . postReset ( ) ;
}
2014-02-05 23:07:11 -08:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_textures ) ; + + ii )
2012-08-05 14:51:49 -07:00
{
2014-02-05 23:07:11 -08:00
m_textures [ ii ] . postReset ( ) ;
}
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_frameBuffers ) ; + + ii )
{
m_frameBuffers [ ii ] . postReset ( ) ;
2012-08-05 14:51:49 -07:00
}
}
2013-07-24 21:59:59 -07:00
void invalidateSamplerState ( )
{
2014-07-30 20:37:54 -07:00
for ( uint32_t stage = 0 ; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS ; + + stage )
2013-07-24 21:59:59 -07:00
{
2015-03-01 22:01:30 -08:00
m_samplerFlags [ stage ] [ 0 ] = UINT32_MAX ;
m_samplerFlags [ stage ] [ 1 ] = UINT32_MAX ;
2013-07-24 21:59:59 -07:00
}
}
2015-03-01 22:01:30 -08:00
void setSamplerState ( uint8_t _stage , uint32_t _flags , bool _vertex = false )
2013-07-24 21:59:59 -07:00
{
2014-04-09 21:23:27 -07:00
const uint32_t flags = _flags & ( ( ~ BGFX_TEXTURE_RESERVED_MASK ) | BGFX_TEXTURE_SAMPLER_BITS_MASK ) ;
2015-03-01 22:01:30 -08:00
BX_CHECK ( _stage < BX_COUNTOF ( m_samplerFlags ) , " " ) ;
if ( m_samplerFlags [ _stage ] [ _vertex ] ! = flags )
2013-07-24 21:59:59 -07:00
{
2015-03-01 22:01:30 -08:00
m_samplerFlags [ _stage ] [ _vertex ] = flags ;
2013-07-24 21:59:59 -07:00
IDirect3DDevice9 * device = m_device ;
D3DTEXTUREADDRESS tau = s_textureAddress [ ( _flags & BGFX_TEXTURE_U_MASK ) > > BGFX_TEXTURE_U_SHIFT ] ;
D3DTEXTUREADDRESS tav = s_textureAddress [ ( _flags & BGFX_TEXTURE_V_MASK ) > > BGFX_TEXTURE_V_SHIFT ] ;
D3DTEXTUREADDRESS taw = s_textureAddress [ ( _flags & BGFX_TEXTURE_W_MASK ) > > BGFX_TEXTURE_W_SHIFT ] ;
D3DTEXTUREFILTERTYPE minFilter = s_textureFilter [ ( _flags & BGFX_TEXTURE_MIN_MASK ) > > BGFX_TEXTURE_MIN_SHIFT ] ;
D3DTEXTUREFILTERTYPE magFilter = s_textureFilter [ ( _flags & BGFX_TEXTURE_MAG_MASK ) > > BGFX_TEXTURE_MAG_SHIFT ] ;
D3DTEXTUREFILTERTYPE mipFilter = s_textureFilter [ ( _flags & BGFX_TEXTURE_MIP_MASK ) > > BGFX_TEXTURE_MIP_SHIFT ] ;
2015-03-01 22:01:30 -08:00
DWORD stage = ( _vertex ? D3DVERTEXTEXTURESAMPLER0 : 0 ) + _stage ;
DX_CHECK ( device - > SetSamplerState ( stage , D3DSAMP_ADDRESSU , tau ) ) ;
DX_CHECK ( device - > SetSamplerState ( stage , D3DSAMP_ADDRESSV , tav ) ) ;
DX_CHECK ( device - > SetSamplerState ( stage , D3DSAMP_ADDRESSW , taw ) ) ;
DX_CHECK ( device - > SetSamplerState ( stage , D3DSAMP_MINFILTER , minFilter ) ) ;
DX_CHECK ( device - > SetSamplerState ( stage , D3DSAMP_MAGFILTER , magFilter ) ) ;
DX_CHECK ( device - > SetSamplerState ( stage , D3DSAMP_MIPFILTER , mipFilter ) ) ;
DX_CHECK ( device - > SetSamplerState ( stage , D3DSAMP_MAXANISOTROPY , m_maxAnisotropy ) ) ;
2013-07-24 21:59:59 -07:00
}
}
2012-12-30 20:52:47 -08:00
void capturePreReset ( )
{
if ( NULL ! = m_captureSurface )
{
g_callback - > captureEnd ( ) ;
}
DX_RELEASE ( m_captureSurface , 1 ) ;
DX_RELEASE ( m_captureTexture , 0 ) ;
DX_RELEASE ( m_captureResolve , 0 ) ;
}
void capturePostReset ( )
{
if ( m_flags & BGFX_RESET_CAPTURE )
{
2014-09-07 17:17:38 -07:00
uint32_t width = m_params . BackBufferWidth ;
2012-12-30 20:52:47 -08:00
uint32_t height = m_params . BackBufferHeight ;
2014-09-07 17:17:38 -07:00
D3DFORMAT fmt = m_params . BackBufferFormat ;
2012-12-30 20:52:47 -08:00
DX_CHECK ( m_device - > CreateTexture ( width
, height
, 1
, 0
, fmt
, D3DPOOL_SYSTEMMEM
, & m_captureTexture
, NULL
) ) ;
DX_CHECK ( m_captureTexture - > GetSurfaceLevel ( 0
, & m_captureSurface
) ) ;
if ( m_params . MultiSampleType ! = D3DMULTISAMPLE_NONE )
{
DX_CHECK ( m_device - > CreateRenderTarget ( width
, height
, fmt
, D3DMULTISAMPLE_NONE
, 0
, false
, & m_captureResolve
, NULL
) ) ;
}
g_callback - > captureBegin ( width , height , width * 4 , TextureFormat : : BGRA8 , false ) ;
}
}
void capture ( )
{
if ( NULL ! = m_captureSurface )
{
IDirect3DSurface9 * resolve = m_backBufferColor ;
if ( NULL ! = m_captureResolve )
{
resolve = m_captureResolve ;
DX_CHECK ( m_device - > StretchRect ( m_backBufferColor
, 0
, m_captureResolve
, NULL
, D3DTEXF_NONE
) ) ;
}
HRESULT hr = m_device - > GetRenderTargetData ( resolve , m_captureSurface ) ;
if ( SUCCEEDED ( hr ) )
{
D3DLOCKED_RECT rect ;
DX_CHECK ( m_captureSurface - > LockRect ( & rect
, NULL
, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY
) ) ;
g_callback - > captureFrame ( rect . pBits , m_params . BackBufferHeight * rect . Pitch ) ;
DX_CHECK ( m_captureSurface - > UnlockRect ( ) ) ;
}
}
}
2014-05-26 14:09:26 -07:00
void commit ( ConstantBuffer & _constantBuffer )
2012-08-05 14:51:49 -07:00
{
2014-05-26 14:09:26 -07:00
_constantBuffer . reset ( ) ;
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
IDirect3DDevice9 * device = m_device ;
2012-08-05 14:51:49 -07:00
2014-06-08 20:57:39 -07:00
for ( ; ; )
2014-05-26 14:09:26 -07:00
{
uint32_t opcode = _constantBuffer . read ( ) ;
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
if ( UniformType : : End = = opcode )
{
break ;
}
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
UniformType : : Enum type ;
uint16_t loc ;
uint16_t num ;
uint16_t copy ;
ConstantBuffer : : decodeOpcode ( opcode , type , loc , num , copy ) ;
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
const char * data ;
if ( copy )
{
data = _constantBuffer . read ( g_uniformTypeSize [ type ] * num ) ;
}
else
{
UniformHandle handle ;
memcpy ( & handle , _constantBuffer . read ( sizeof ( UniformHandle ) ) , sizeof ( UniformHandle ) ) ;
data = ( const char * ) m_uniforms [ handle . idx ] ;
}
2012-12-30 20:52:47 -08:00
2014-05-26 14:09:26 -07:00
# define CASE_IMPLEMENT_UNIFORM(_uniform, _dxsuffix, _type) \
case UniformType : : _uniform : \
{ \
_type * value = ( _type * ) data ; \
DX_CHECK ( device - > SetVertexShaderConstant # # _dxsuffix ( loc , value , num ) ) ; \
} \
break ; \
\
case UniformType : : _uniform | BGFX_UNIFORM_FRAGMENTBIT : \
{ \
_type * value = ( _type * ) data ; \
DX_CHECK ( device - > SetPixelShaderConstant # # _dxsuffix ( loc , value , num ) ) ; \
} \
break
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
switch ( ( int32_t ) type )
{
case UniformType : : Uniform3x3fv :
{
float * value = ( float * ) data ;
for ( uint32_t ii = 0 , count = num / 3 ; ii < count ; + + ii , loc + = 3 , value + = 9 )
{
Matrix4 mtx ;
mtx . un . val [ 0 ] = value [ 0 ] ;
mtx . un . val [ 1 ] = value [ 1 ] ;
mtx . un . val [ 2 ] = value [ 2 ] ;
mtx . un . val [ 3 ] = 0.0f ;
mtx . un . val [ 4 ] = value [ 3 ] ;
mtx . un . val [ 5 ] = value [ 4 ] ;
mtx . un . val [ 6 ] = value [ 5 ] ;
mtx . un . val [ 7 ] = 0.0f ;
mtx . un . val [ 8 ] = value [ 6 ] ;
mtx . un . val [ 9 ] = value [ 7 ] ;
mtx . un . val [ 10 ] = value [ 8 ] ;
mtx . un . val [ 11 ] = 0.0f ;
DX_CHECK ( device - > SetVertexShaderConstantF ( loc , & mtx . un . val [ 0 ] , 3 ) ) ;
}
}
break ;
case UniformType : : Uniform3x3fv | BGFX_UNIFORM_FRAGMENTBIT :
{
float * value = ( float * ) data ;
for ( uint32_t ii = 0 , count = num / 3 ; ii < count ; + + ii , loc + = 3 , value + = 9 )
{
Matrix4 mtx ;
mtx . un . val [ 0 ] = value [ 0 ] ;
mtx . un . val [ 1 ] = value [ 1 ] ;
mtx . un . val [ 2 ] = value [ 2 ] ;
mtx . un . val [ 3 ] = 0.0f ;
mtx . un . val [ 4 ] = value [ 3 ] ;
mtx . un . val [ 5 ] = value [ 4 ] ;
mtx . un . val [ 6 ] = value [ 5 ] ;
mtx . un . val [ 7 ] = 0.0f ;
mtx . un . val [ 8 ] = value [ 6 ] ;
mtx . un . val [ 9 ] = value [ 7 ] ;
mtx . un . val [ 10 ] = value [ 8 ] ;
mtx . un . val [ 11 ] = 0.0f ;
DX_CHECK ( device - > SetPixelShaderConstantF ( loc , & mtx . un . val [ 0 ] , 3 ) ) ;
}
}
break ;
CASE_IMPLEMENT_UNIFORM ( Uniform1i , I , int ) ;
CASE_IMPLEMENT_UNIFORM ( Uniform1f , F , float ) ;
CASE_IMPLEMENT_UNIFORM ( Uniform1iv , I , int ) ;
CASE_IMPLEMENT_UNIFORM ( Uniform1fv , F , float ) ;
CASE_IMPLEMENT_UNIFORM ( Uniform2fv , F , float ) ;
CASE_IMPLEMENT_UNIFORM ( Uniform3fv , F , float ) ;
CASE_IMPLEMENT_UNIFORM ( Uniform4fv , F , float ) ;
CASE_IMPLEMENT_UNIFORM ( Uniform4x4fv , F , float ) ;
case UniformType : : End :
break ;
default :
BX_TRACE ( " %4d: INVALID 0x%08x, t %d, l %d, n %d, c %d " , _constantBuffer . getPos ( ) , opcode , type , loc , num , copy ) ;
break ;
}
# undef CASE_IMPLEMENT_UNIFORM
2014-09-01 11:24:51 -07:00
}
}
void clearQuad ( ClearQuad & _clearQuad , const Rect & _rect , const Clear & _clear , const float _palette [ ] [ 4 ] )
{
IDirect3DDevice9 * device = m_device ;
uint32_t numMrt = 1 ;
FrameBufferHandle fbh = m_fbh ;
if ( isValid ( fbh ) )
{
const FrameBufferD3D9 & fb = m_frameBuffers [ fbh . idx ] ;
numMrt = bx : : uint32_max ( 1 , fb . m_num ) ;
}
if ( 1 = = numMrt )
{
D3DCOLOR color = 0 ;
DWORD flags = 0 ;
2015-01-10 21:39:45 -08:00
if ( BGFX_CLEAR_COLOR & _clear . m_flags )
2014-09-01 11:24:51 -07:00
{
2015-01-11 18:02:34 -08:00
if ( BGFX_CLEAR_COLOR_USE_PALETTE & _clear . m_flags )
2014-09-01 11:24:51 -07:00
{
uint8_t index = ( uint8_t ) bx : : uint32_min ( BGFX_CONFIG_MAX_CLEAR_COLOR_PALETTE - 1 , _clear . m_index [ 0 ] ) ;
const float * rgba = _palette [ index ] ;
const float rr = rgba [ 0 ] ;
const float gg = rgba [ 1 ] ;
const float bb = rgba [ 2 ] ;
const float aa = rgba [ 3 ] ;
color = D3DCOLOR_COLORVALUE ( rr , gg , bb , aa ) ;
}
else
{
color = D3DCOLOR_RGBA ( _clear . m_index [ 0 ] , _clear . m_index [ 1 ] , _clear . m_index [ 2 ] , _clear . m_index [ 3 ] ) ;
}
flags | = D3DCLEAR_TARGET ;
DX_CHECK ( device - > SetRenderState ( D3DRS_COLORWRITEENABLE
, D3DCOLORWRITEENABLE_RED
| D3DCOLORWRITEENABLE_GREEN
| D3DCOLORWRITEENABLE_BLUE
| D3DCOLORWRITEENABLE_ALPHA
) ) ;
}
2015-01-10 21:39:45 -08:00
if ( BGFX_CLEAR_DEPTH & _clear . m_flags )
2014-09-01 11:24:51 -07:00
{
flags | = D3DCLEAR_ZBUFFER ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ZWRITEENABLE , TRUE ) ) ;
}
2015-01-10 21:39:45 -08:00
if ( BGFX_CLEAR_STENCIL & _clear . m_flags )
2014-09-01 11:24:51 -07:00
{
flags | = D3DCLEAR_STENCIL ;
}
2014-05-26 14:09:26 -07:00
2014-09-01 11:24:51 -07:00
if ( 0 ! = flags )
{
RECT rc ;
rc . left = _rect . m_x ;
rc . top = _rect . m_y ;
rc . right = _rect . m_x + _rect . m_width ;
rc . bottom = _rect . m_y + _rect . m_height ;
DX_CHECK ( device - > SetRenderState ( D3DRS_SCISSORTESTENABLE , TRUE ) ) ;
DX_CHECK ( device - > SetScissorRect ( & rc ) ) ;
DX_CHECK ( device - > Clear ( 0 , NULL , flags , color , _clear . m_depth , _clear . m_stencil ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_SCISSORTESTENABLE , FALSE ) ) ;
}
}
else
{
DX_CHECK ( device - > SetRenderState ( D3DRS_SCISSORTESTENABLE , FALSE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_CULLMODE , D3DCULL_NONE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ALPHABLENDENABLE , FALSE ) ) ;
2015-01-10 21:39:45 -08:00
if ( BGFX_CLEAR_DEPTH & _clear . m_flags )
2014-09-01 11:24:51 -07:00
{
DX_CHECK ( device - > SetRenderState ( D3DRS_ZWRITEENABLE , TRUE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_COLORWRITEENABLE
, D3DCOLORWRITEENABLE_RED
| D3DCOLORWRITEENABLE_GREEN
| D3DCOLORWRITEENABLE_BLUE
| D3DCOLORWRITEENABLE_ALPHA
) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ZENABLE , TRUE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ZFUNC , D3DCMP_ALWAYS ) ) ;
}
else
{
DX_CHECK ( device - > SetRenderState ( D3DRS_ZWRITEENABLE , FALSE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_COLORWRITEENABLE , 0 ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ZENABLE , FALSE ) ) ;
}
2015-01-10 21:39:45 -08:00
if ( BGFX_CLEAR_STENCIL & _clear . m_flags )
2014-09-01 11:24:51 -07:00
{
DX_CHECK ( device - > SetRenderState ( D3DRS_STENCILENABLE , TRUE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_TWOSIDEDSTENCILMODE , TRUE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_STENCILREF , _clear . m_stencil ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_STENCILMASK , 0xff ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_STENCILFUNC , D3DCMP_ALWAYS ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_STENCILFAIL , D3DSTENCILOP_REPLACE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_STENCILZFAIL , D3DSTENCILOP_REPLACE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_STENCILPASS , D3DSTENCILOP_REPLACE ) ) ;
}
else
{
DX_CHECK ( device - > SetRenderState ( D3DRS_STENCILENABLE , FALSE ) ) ;
}
VertexBufferD3D9 & vb = m_vertexBuffers [ _clearQuad . m_vb - > handle . idx ] ;
VertexDeclD3D9 & vertexDecl = m_vertexDecls [ _clearQuad . m_vb - > decl . idx ] ;
uint32_t stride = _clearQuad . m_decl . m_stride ;
{
struct Vertex
{
float m_x ;
float m_y ;
float m_z ;
} ;
Vertex * vertex = ( Vertex * ) _clearQuad . m_vb - > data ;
BX_CHECK ( stride = = sizeof ( Vertex ) , " Stride/Vertex mismatch (stride %d, sizeof(Vertex) %d) " , stride , sizeof ( Vertex ) ) ;
const float depth = _clear . m_depth ;
vertex - > m_x = - 1.0f ;
vertex - > m_y = - 1.0f ;
vertex - > m_z = depth ;
vertex + + ;
vertex - > m_x = 1.0f ;
vertex - > m_y = - 1.0f ;
vertex - > m_z = depth ;
vertex + + ;
vertex - > m_x = - 1.0f ;
vertex - > m_y = 1.0f ;
vertex - > m_z = depth ;
vertex + + ;
vertex - > m_x = 1.0f ;
vertex - > m_y = 1.0f ;
vertex - > m_z = depth ;
}
vb . update ( 0 , 4 * stride , _clearQuad . m_vb - > data ) ;
ProgramD3D9 & program = m_program [ _clearQuad . m_program [ numMrt - 1 ] . idx ] ;
device - > SetVertexShader ( program . m_vsh - > m_vertexShader ) ;
device - > SetPixelShader ( program . m_fsh - > m_pixelShader ) ;
2015-01-11 18:02:34 -08:00
if ( BGFX_CLEAR_COLOR_USE_PALETTE & _clear . m_flags )
2014-09-01 11:24:51 -07:00
{
float mrtClear [ BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS ] [ 4 ] ;
for ( uint32_t ii = 0 ; ii < numMrt ; + + ii )
{
uint8_t index = ( uint8_t ) bx : : uint32_min ( BGFX_CONFIG_MAX_CLEAR_COLOR_PALETTE - 1 , _clear . m_index [ ii ] ) ;
memcpy ( mrtClear [ ii ] , _palette [ index ] , 16 ) ;
}
DX_CHECK ( m_device - > SetPixelShaderConstantF ( 0 , mrtClear [ 0 ] , numMrt ) ) ;
}
else
{
float rgba [ 4 ] =
{
_clear . m_index [ 0 ] * 1.0f / 255.0f ,
_clear . m_index [ 1 ] * 1.0f / 255.0f ,
_clear . m_index [ 2 ] * 1.0f / 255.0f ,
_clear . m_index [ 3 ] * 1.0f / 255.0f ,
} ;
DX_CHECK ( m_device - > SetPixelShaderConstantF ( 0 , rgba , 1 ) ) ;
}
DX_CHECK ( device - > SetStreamSource ( 0 , vb . m_ptr , 0 , stride ) ) ;
DX_CHECK ( device - > SetStreamSourceFreq ( 0 , 1 ) ) ;
DX_CHECK ( device - > SetStreamSource ( 1 , NULL , 0 , 0 ) ) ;
DX_CHECK ( device - > SetVertexDeclaration ( vertexDecl . m_ptr ) ) ;
DX_CHECK ( device - > SetIndices ( NULL ) ) ;
DX_CHECK ( device - > DrawPrimitive ( D3DPT_TRIANGLESTRIP
, 0
, 2
) ) ;
2014-06-08 20:57:39 -07:00
}
2012-08-05 14:51:49 -07:00
}
# if BX_PLATFORM_WINDOWS
D3DCAPS9 m_caps ;
# endif // BX_PLATFORM_WINDOWS
# if BGFX_CONFIG_RENDERER_DIRECT3D9EX
2013-07-26 22:55:13 -07:00
IDirect3D9Ex * m_d3d9ex ;
IDirect3DDevice9Ex * m_deviceEx ;
# endif // BGFX_CONFIG_RENDERER_DIRECT3D9EX
2012-08-05 14:51:49 -07:00
IDirect3D9 * m_d3d9 ;
IDirect3DDevice9 * m_device ;
2013-07-26 22:55:13 -07:00
D3DPOOL m_pool ;
2012-08-05 14:51:49 -07:00
2014-09-07 17:17:38 -07:00
IDirect3DSwapChain9 * m_swapChain ;
uint16_t m_numWindows ;
FrameBufferHandle m_windows [ BGFX_CONFIG_MAX_FRAME_BUFFERS ] ;
2012-08-05 14:51:49 -07:00
IDirect3DSurface9 * m_backBufferColor ;
IDirect3DSurface9 * m_backBufferDepthStencil ;
2012-12-30 20:52:47 -08:00
IDirect3DTexture9 * m_captureTexture ;
IDirect3DSurface9 * m_captureSurface ;
IDirect3DSurface9 * m_captureResolve ;
2012-08-05 14:51:49 -07:00
IDirect3DVertexDeclaration9 * m_instanceDataDecls [ BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT ] ;
2013-07-26 22:55:13 -07:00
void * m_d3d9dll ;
2012-08-05 14:51:49 -07:00
uint32_t m_adapter ;
D3DDEVTYPE m_deviceType ;
D3DPRESENT_PARAMETERS m_params ;
uint32_t m_flags ;
2015-01-21 20:39:42 -08:00
uint32_t m_maxAnisotropy ;
2013-04-27 16:55:34 -07:00
D3DADAPTER_IDENTIFIER9 m_identifier ;
2014-05-26 14:09:26 -07:00
Resolution m_resolution ;
2012-08-05 14:51:49 -07:00
bool m_initialized ;
bool m_amd ;
bool m_nvidia ;
bool m_instancing ;
D3DFORMAT m_fmtDepth ;
2014-05-26 14:09:26 -07:00
IndexBufferD3D9 m_indexBuffers [ BGFX_CONFIG_MAX_INDEX_BUFFERS ] ;
VertexBufferD3D9 m_vertexBuffers [ BGFX_CONFIG_MAX_VERTEX_BUFFERS ] ;
ShaderD3D9 m_shaders [ BGFX_CONFIG_MAX_SHADERS ] ;
ProgramD3D9 m_program [ BGFX_CONFIG_MAX_PROGRAMS ] ;
TextureD3D9 m_textures [ BGFX_CONFIG_MAX_TEXTURES ] ;
2014-09-01 11:24:51 -07:00
VertexDeclD3D9 m_vertexDecls [ BGFX_CONFIG_MAX_VERTEX_DECLS ] ;
2014-05-26 14:09:26 -07:00
FrameBufferD3D9 m_frameBuffers [ BGFX_CONFIG_MAX_FRAME_BUFFERS ] ;
2012-08-05 14:51:49 -07:00
UniformRegistry m_uniformReg ;
void * m_uniforms [ BGFX_CONFIG_MAX_UNIFORMS ] ;
2015-04-06 10:37:12 +02:00
uint32_t m_samplerFlags [ BGFX_CONFIG_MAX_TEXTURE_SAMPLERS ] [ 2 ] ;
2013-07-24 21:59:59 -07:00
2014-05-26 14:09:26 -07:00
TextureD3D9 * m_updateTexture ;
2013-03-02 21:35:09 -08:00
uint8_t * m_updateTextureBits ;
uint32_t m_updateTexturePitch ;
uint8_t m_updateTextureSide ;
uint8_t m_updateTextureMip ;
2012-08-05 14:51:49 -07:00
TextVideoMem m_textVideoMem ;
2014-02-05 23:07:11 -08:00
FrameBufferHandle m_fbh ;
2012-08-05 14:51:49 -07:00
bool m_rtMsaa ;
} ;
2014-05-26 14:09:26 -07:00
static RendererContextD3D9 * s_renderD3D9 ;
2015-03-21 22:11:59 -07:00
RendererContextI * rendererCreate ( )
2014-05-26 14:09:26 -07:00
{
s_renderD3D9 = BX_NEW ( g_allocator , RendererContextD3D9 ) ;
2014-10-13 21:14:51 -07:00
s_renderD3D9 - > init ( ) ;
2014-05-26 14:09:26 -07:00
return s_renderD3D9 ;
}
2012-08-05 14:51:49 -07:00
2015-03-21 22:11:59 -07:00
void rendererDestroy ( )
2014-05-26 14:09:26 -07:00
{
2014-10-13 21:14:51 -07:00
s_renderD3D9 - > shutdown ( ) ;
2014-05-26 14:09:26 -07:00
BX_DELETE ( g_allocator , s_renderD3D9 ) ;
s_renderD3D9 = NULL ;
}
void IndexBufferD3D9 : : create ( uint32_t _size , void * _data )
2012-08-05 14:51:49 -07:00
{
m_size = _size ;
m_dynamic = NULL = = _data ;
uint32_t usage = D3DUSAGE_WRITEONLY ;
2014-05-26 14:09:26 -07:00
D3DPOOL pool = s_renderD3D9 - > m_pool ;
2012-08-05 14:51:49 -07:00
if ( m_dynamic )
{
usage | = D3DUSAGE_DYNAMIC ;
pool = D3DPOOL_DEFAULT ;
}
2014-05-26 14:09:26 -07:00
DX_CHECK ( s_renderD3D9 - > m_device - > CreateIndexBuffer ( m_size
2012-08-05 14:51:49 -07:00
, usage
, D3DFMT_INDEX16
, pool
, & m_ptr
, NULL
) ) ;
if ( NULL ! = _data )
{
update ( 0 , _size , _data ) ;
}
}
2014-05-26 14:09:26 -07:00
void IndexBufferD3D9 : : preReset ( )
2012-08-05 14:51:49 -07:00
{
if ( m_dynamic )
{
DX_RELEASE ( m_ptr , 0 ) ;
}
}
2014-05-26 14:09:26 -07:00
void IndexBufferD3D9 : : postReset ( )
2012-08-05 14:51:49 -07:00
{
if ( m_dynamic )
{
2014-05-26 14:09:26 -07:00
DX_CHECK ( s_renderD3D9 - > m_device - > CreateIndexBuffer ( m_size
2012-08-05 14:51:49 -07:00
, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC
, D3DFMT_INDEX16
, D3DPOOL_DEFAULT
, & m_ptr
, NULL
) ) ;
}
}
2014-05-26 14:09:26 -07:00
void VertexBufferD3D9 : : create ( uint32_t _size , void * _data , VertexDeclHandle _declHandle )
2012-08-05 14:51:49 -07:00
{
m_size = _size ;
m_decl = _declHandle ;
m_dynamic = NULL = = _data ;
uint32_t usage = D3DUSAGE_WRITEONLY ;
2014-05-26 14:09:26 -07:00
D3DPOOL pool = s_renderD3D9 - > m_pool ;
2012-08-05 14:51:49 -07:00
if ( m_dynamic )
{
usage | = D3DUSAGE_DYNAMIC ;
pool = D3DPOOL_DEFAULT ;
}
2014-05-26 14:09:26 -07:00
DX_CHECK ( s_renderD3D9 - > m_device - > CreateVertexBuffer ( m_size
2012-08-05 14:51:49 -07:00
, usage
, 0
, pool
, & m_ptr
2015-01-10 20:38:47 -08:00
, NULL
2012-08-05 14:51:49 -07:00
) ) ;
if ( NULL ! = _data )
{
update ( 0 , _size , _data ) ;
}
}
2014-05-26 14:09:26 -07:00
void VertexBufferD3D9 : : preReset ( )
2012-08-05 14:51:49 -07:00
{
if ( m_dynamic )
{
DX_RELEASE ( m_ptr , 0 ) ;
}
}
2014-05-26 14:09:26 -07:00
void VertexBufferD3D9 : : postReset ( )
2012-08-05 14:51:49 -07:00
{
if ( m_dynamic )
{
2014-05-26 14:09:26 -07:00
DX_CHECK ( s_renderD3D9 - > m_device - > CreateVertexBuffer ( m_size
2012-08-05 14:51:49 -07:00
, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC
, 0
, D3DPOOL_DEFAULT
, & m_ptr
2015-01-10 20:38:47 -08:00
, NULL
2012-08-05 14:51:49 -07:00
) ) ;
}
}
2014-08-04 22:01:20 -07:00
static const D3DVERTEXELEMENT9 s_attrib [ ] =
2012-08-05 14:51:49 -07:00
{
{ 0 , 0 , D3DDECLTYPE_FLOAT3 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_POSITION , 0 } ,
{ 0 , 0 , D3DDECLTYPE_FLOAT3 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_NORMAL , 0 } ,
2012-10-27 21:34:41 -07:00
{ 0 , 0 , D3DDECLTYPE_FLOAT3 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_TANGENT , 0 } ,
2014-08-17 17:20:15 -07:00
{ 0 , 0 , D3DDECLTYPE_FLOAT3 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_BINORMAL , 0 } ,
2012-08-05 14:51:49 -07:00
{ 0 , 0 , D3DDECLTYPE_UBYTE4 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_COLOR , 0 } ,
{ 0 , 0 , D3DDECLTYPE_UBYTE4 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_COLOR , 1 } ,
{ 0 , 0 , D3DDECLTYPE_UBYTE4 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_BLENDINDICES , 0 } ,
{ 0 , 0 , D3DDECLTYPE_FLOAT3 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_BLENDWEIGHT , 0 } ,
{ 0 , 0 , D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_TEXCOORD , 0 } ,
{ 0 , 0 , D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_TEXCOORD , 1 } ,
{ 0 , 0 , D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_TEXCOORD , 2 } ,
{ 0 , 0 , D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_TEXCOORD , 3 } ,
{ 0 , 0 , D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_TEXCOORD , 4 } ,
{ 0 , 0 , D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_TEXCOORD , 5 } ,
{ 0 , 0 , D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_TEXCOORD , 6 } ,
{ 0 , 0 , D3DDECLTYPE_FLOAT2 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_TEXCOORD , 7 } ,
D3DDECL_END ( )
} ;
2014-08-04 22:01:20 -07:00
BX_STATIC_ASSERT ( Attrib : : Count = = BX_COUNTOF ( s_attrib ) - 1 ) ;
2012-08-05 14:51:49 -07:00
2014-10-05 00:14:21 -07:00
static const D3DDECLTYPE s_attribType [ ] [ 4 ] [ 2 ] =
2012-11-03 13:12:26 -07:00
{
{
{ D3DDECLTYPE_UBYTE4 , D3DDECLTYPE_UBYTE4N } ,
{ D3DDECLTYPE_UBYTE4 , D3DDECLTYPE_UBYTE4N } ,
{ D3DDECLTYPE_UBYTE4 , D3DDECLTYPE_UBYTE4N } ,
{ D3DDECLTYPE_UBYTE4 , D3DDECLTYPE_UBYTE4N } ,
} ,
{
{ D3DDECLTYPE_SHORT2 , D3DDECLTYPE_SHORT2N } ,
{ D3DDECLTYPE_SHORT2 , D3DDECLTYPE_SHORT2N } ,
{ D3DDECLTYPE_SHORT4 , D3DDECLTYPE_SHORT4N } ,
{ D3DDECLTYPE_SHORT4 , D3DDECLTYPE_SHORT4N } ,
} ,
{
{ D3DDECLTYPE_FLOAT16_2 , D3DDECLTYPE_FLOAT16_2 } ,
{ D3DDECLTYPE_FLOAT16_2 , D3DDECLTYPE_FLOAT16_2 } ,
{ D3DDECLTYPE_FLOAT16_4 , D3DDECLTYPE_FLOAT16_4 } ,
{ D3DDECLTYPE_FLOAT16_4 , D3DDECLTYPE_FLOAT16_4 } ,
} ,
{
{ D3DDECLTYPE_FLOAT1 , D3DDECLTYPE_FLOAT1 } ,
{ D3DDECLTYPE_FLOAT2 , D3DDECLTYPE_FLOAT2 } ,
{ D3DDECLTYPE_FLOAT3 , D3DDECLTYPE_FLOAT3 } ,
{ D3DDECLTYPE_FLOAT4 , D3DDECLTYPE_FLOAT4 } ,
} ,
} ;
2014-10-05 00:14:21 -07:00
BX_STATIC_ASSERT ( AttribType : : Count = = BX_COUNTOF ( s_attribType ) ) ;
2012-11-03 13:12:26 -07:00
2013-03-25 21:13:54 -07:00
static D3DVERTEXELEMENT9 * fillVertexDecl ( D3DVERTEXELEMENT9 * _out , const VertexDecl & _decl )
2012-08-05 14:51:49 -07:00
{
D3DVERTEXELEMENT9 * elem = _out ;
for ( uint32_t attr = 0 ; attr < Attrib : : Count ; + + attr )
{
if ( 0xff ! = _decl . m_attributes [ attr ] )
{
uint8_t num ;
AttribType : : Enum type ;
bool normalized ;
2012-12-31 18:48:52 -08:00
bool asInt ;
_decl . decode ( Attrib : : Enum ( attr ) , num , type , normalized , asInt ) ;
2012-08-05 14:51:49 -07:00
memcpy ( elem , & s_attrib [ attr ] , sizeof ( D3DVERTEXELEMENT9 ) ) ;
2012-11-03 13:12:26 -07:00
elem - > Type = s_attribType [ type ] [ num - 1 ] [ normalized ] ;
2012-08-05 14:51:49 -07:00
elem - > Offset = _decl . m_offset [ attr ] ;
+ + elem ;
}
}
return elem ;
}
2014-05-26 14:09:26 -07:00
static IDirect3DVertexDeclaration9 * createVertexDeclaration ( const VertexDecl & _decl , uint8_t _numInstanceData )
2012-08-05 14:51:49 -07:00
{
D3DVERTEXELEMENT9 vertexElements [ Attrib : : Count + 1 + BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT ] ;
2013-03-25 21:13:54 -07:00
D3DVERTEXELEMENT9 * elem = fillVertexDecl ( vertexElements , _decl ) ;
2012-08-05 14:51:49 -07:00
const D3DVERTEXELEMENT9 inst = { 1 , 0 , D3DDECLTYPE_FLOAT4 , D3DDECLMETHOD_DEFAULT , D3DDECLUSAGE_TEXCOORD , 0 } ;
for ( uint32_t ii = 0 ; ii < _numInstanceData ; + + ii )
{
memcpy ( elem , & inst , sizeof ( D3DVERTEXELEMENT9 ) ) ;
elem - > UsageIndex = 8 - _numInstanceData + ii ;
elem - > Offset = ii * 16 ;
+ + elem ;
}
memcpy ( elem , & s_attrib [ Attrib : : Count ] , sizeof ( D3DVERTEXELEMENT9 ) ) ;
IDirect3DVertexDeclaration9 * ptr ;
2014-05-26 14:09:26 -07:00
DX_CHECK ( s_renderD3D9 - > m_device - > CreateVertexDeclaration ( vertexElements , & ptr ) ) ;
2012-08-05 14:51:49 -07:00
return ptr ;
}
2014-09-01 11:24:51 -07:00
void VertexDeclD3D9 : : create ( const VertexDecl & _decl )
2012-08-05 14:51:49 -07:00
{
memcpy ( & m_decl , & _decl , sizeof ( VertexDecl ) ) ;
dump ( m_decl ) ;
2014-05-26 14:09:26 -07:00
m_ptr = createVertexDeclaration ( _decl , 0 ) ;
2012-08-05 14:51:49 -07:00
}
2014-05-26 14:09:26 -07:00
void ShaderD3D9 : : create ( const Memory * _mem )
2012-08-05 14:51:49 -07:00
{
2012-11-25 18:24:50 -08:00
bx : : MemoryReader reader ( _mem - > data , _mem - > size ) ;
uint32_t magic ;
bx : : read ( & reader , magic ) ;
2014-03-29 19:42:57 -07:00
switch ( magic )
{
case BGFX_CHUNK_MAGIC_FSH :
case BGFX_CHUNK_MAGIC_VSH :
break ;
default :
BGFX_FATAL ( false , Fatal : : InvalidShader , " Unknown shader format %x. " , magic ) ;
break ;
}
bool fragment = BGFX_CHUNK_MAGIC_FSH = = magic ;
2012-11-25 18:24:50 -08:00
uint32_t iohash ;
bx : : read ( & reader , iohash ) ;
2012-08-05 14:51:49 -07:00
uint16_t count ;
2012-11-25 18:24:50 -08:00
bx : : read ( & reader , count ) ;
2012-08-05 14:51:49 -07:00
m_numPredefined = 0 ;
BX_TRACE ( " Shader consts %d " , count ) ;
2014-03-29 19:42:57 -07:00
uint8_t fragmentBit = fragment ? BGFX_UNIFORM_FRAGMENTBIT : 0 ;
2012-08-05 14:51:49 -07:00
2012-11-25 18:24:50 -08:00
if ( 0 < count )
2012-08-05 14:51:49 -07:00
{
2012-11-25 18:24:50 -08:00
for ( uint32_t ii = 0 ; ii < count ; + + ii )
{
uint8_t nameSize ;
bx : : read ( & reader , nameSize ) ;
2012-08-05 14:51:49 -07:00
2012-11-25 18:24:50 -08:00
char name [ 256 ] ;
bx : : read ( & reader , & name , nameSize ) ;
name [ nameSize ] = ' \0 ' ;
2012-08-05 14:51:49 -07:00
2012-11-25 18:24:50 -08:00
uint8_t type ;
bx : : read ( & reader , type ) ;
2012-08-05 14:51:49 -07:00
2012-11-25 18:24:50 -08:00
uint8_t num ;
bx : : read ( & reader , num ) ;
2012-08-05 14:51:49 -07:00
2012-11-25 18:24:50 -08:00
uint16_t regIndex ;
bx : : read ( & reader , regIndex ) ;
2012-08-05 14:51:49 -07:00
2012-11-25 18:24:50 -08:00
uint16_t regCount ;
bx : : read ( & reader , regCount ) ;
2012-08-05 14:51:49 -07:00
2012-11-25 18:24:50 -08:00
const char * kind = " invalid " ;
PredefinedUniform : : Enum predefined = nameToPredefinedUniformEnum ( name ) ;
if ( PredefinedUniform : : Count ! = predefined )
2012-08-05 14:51:49 -07:00
{
2012-11-25 18:24:50 -08:00
kind = " predefined " ;
m_predefined [ m_numPredefined ] . m_loc = regIndex ;
m_predefined [ m_numPredefined ] . m_count = regCount ;
m_predefined [ m_numPredefined ] . m_type = predefined | fragmentBit ;
m_numPredefined + + ;
2012-08-05 14:51:49 -07:00
}
2012-11-25 18:24:50 -08:00
else
{
2014-05-26 14:09:26 -07:00
const UniformInfo * info = s_renderD3D9 - > m_uniformReg . find ( name ) ;
2012-11-25 18:24:50 -08:00
BX_CHECK ( NULL ! = info , " User defined uniform '%s' is not found, it won't be set. " , name ) ;
if ( NULL ! = info )
{
2014-10-08 19:36:59 -07:00
if ( NULL = = m_constantBuffer )
{
m_constantBuffer = ConstantBuffer : : create ( 1024 ) ;
}
2012-11-25 18:24:50 -08:00
kind = " user " ;
2014-04-15 19:10:56 -07:00
m_constantBuffer - > writeUniformHandle ( ( UniformType : : Enum ) ( type | fragmentBit ) , regIndex , info - > m_handle , regCount ) ;
2012-11-25 18:24:50 -08:00
}
}
BX_TRACE ( " \t %s: %s, type %2d, num %2d, r.index %3d, r.count %2d "
, kind
, name
, type
, num
, regIndex
, regCount
) ;
2013-05-17 20:03:45 -07:00
BX_UNUSED ( kind ) ;
2012-08-05 14:51:49 -07:00
}
2014-10-08 19:36:59 -07:00
if ( NULL ! = m_constantBuffer )
{
m_constantBuffer - > finish ( ) ;
}
2012-08-05 14:51:49 -07:00
}
uint16_t shaderSize ;
2012-11-25 18:24:50 -08:00
bx : : read ( & reader , shaderSize ) ;
2012-08-05 14:51:49 -07:00
2012-11-25 18:24:50 -08:00
const DWORD * code = ( const DWORD * ) reader . getDataPtr ( ) ;
2012-08-05 14:51:49 -07:00
2014-03-29 19:42:57 -07:00
if ( fragment )
2012-08-05 14:51:49 -07:00
{
2014-07-20 20:27:13 -07:00
m_type = 1 ;
DX_CHECK ( s_renderD3D9 - > m_device - > CreatePixelShader ( code , & m_pixelShader ) ) ;
BGFX_FATAL ( NULL ! = m_pixelShader , bgfx : : Fatal : : InvalidShader , " Failed to create fragment shader. " ) ;
2012-08-05 14:51:49 -07:00
}
else
{
2014-07-20 20:27:13 -07:00
m_type = 0 ;
DX_CHECK ( s_renderD3D9 - > m_device - > CreateVertexShader ( code , & m_vertexShader ) ) ;
BGFX_FATAL ( NULL ! = m_vertexShader , bgfx : : Fatal : : InvalidShader , " Failed to create vertex shader. " ) ;
2012-08-05 14:51:49 -07:00
}
}
2014-05-26 14:09:26 -07:00
void TextureD3D9 : : createTexture ( uint32_t _width , uint32_t _height , uint8_t _numMips )
2012-08-05 14:51:49 -07:00
{
2014-02-05 23:07:11 -08:00
m_width = ( uint16_t ) _width ;
m_height = ( uint16_t ) _height ;
m_numMips = _numMips ;
2012-08-05 14:51:49 -07:00
m_type = Texture2D ;
2014-02-05 23:07:11 -08:00
const TextureFormat : : Enum fmt = ( TextureFormat : : Enum ) m_textureFormat ;
DWORD usage = 0 ;
2014-05-26 14:09:26 -07:00
D3DPOOL pool = s_renderD3D9 - > m_pool ;
2014-02-05 23:07:11 -08:00
const bool renderTarget = 0 ! = ( m_flags & BGFX_TEXTURE_RT_MASK ) ;
if ( isDepth ( fmt ) )
{
usage = D3DUSAGE_DEPTHSTENCIL ;
2014-09-01 11:24:51 -07:00
pool = D3DPOOL_DEFAULT ;
2014-02-05 23:07:11 -08:00
}
else if ( renderTarget )
{
usage = D3DUSAGE_RENDERTARGET ;
2014-09-01 11:24:51 -07:00
pool = D3DPOOL_DEFAULT ;
2014-02-05 23:07:11 -08:00
}
if ( renderTarget )
{
uint32_t msaaQuality = ( ( m_flags & BGFX_TEXTURE_RT_MSAA_MASK ) > > BGFX_TEXTURE_RT_MSAA_SHIFT ) ;
msaaQuality = bx : : uint32_satsub ( msaaQuality , 1 ) ;
bool bufferOnly = 0 ! = ( m_flags & BGFX_TEXTURE_RT_BUFFER_ONLY ) ;
if ( 0 ! = msaaQuality
| | bufferOnly )
{
const Msaa & msaa = s_msaa [ msaaQuality ] ;
if ( isDepth ( fmt ) )
{
2014-05-26 14:09:26 -07:00
DX_CHECK ( s_renderD3D9 - > m_device - > CreateDepthStencilSurface (
2014-02-05 23:07:11 -08:00
m_width
, m_height
, s_textureFormat [ m_textureFormat ] . m_fmt
, msaa . m_type
, msaa . m_quality
, FALSE
, & m_surface
, NULL
) ) ;
}
else
{
2014-05-26 14:09:26 -07:00
DX_CHECK ( s_renderD3D9 - > m_device - > CreateRenderTarget (
2014-02-05 23:07:11 -08:00
m_width
, m_height
, s_textureFormat [ m_textureFormat ] . m_fmt
, msaa . m_type
, msaa . m_quality
, FALSE
, & m_surface
, NULL
) ) ;
}
if ( bufferOnly )
{
// This is render buffer, there is no sampling, no need
// to create texture.
return ;
}
}
}
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
DX_CHECK ( s_renderD3D9 - > m_device - > CreateTexture ( _width
2012-08-05 14:51:49 -07:00
, _height
, _numMips
2014-02-05 23:07:11 -08:00
, usage
, s_textureFormat [ fmt ] . m_fmt
, pool
2012-08-12 21:02:11 -07:00
, & m_texture2d
2012-08-05 14:51:49 -07:00
, NULL
) ) ;
2014-02-05 23:07:11 -08:00
BGFX_FATAL ( NULL ! = m_texture2d , Fatal : : UnableToCreateTexture , " Failed to create texture (size: %dx%d, mips: %d, fmt: %d). "
2012-08-05 14:51:49 -07:00
, _width
, _height
, _numMips
2014-02-05 23:07:11 -08:00
, getName ( fmt )
2012-08-05 14:51:49 -07:00
) ;
}
2014-05-26 14:09:26 -07:00
void TextureD3D9 : : createVolumeTexture ( uint32_t _width , uint32_t _height , uint32_t _depth , uint32_t _numMips )
2012-08-05 14:51:49 -07:00
{
m_type = Texture3D ;
2014-02-05 23:07:11 -08:00
const TextureFormat : : Enum fmt = ( TextureFormat : : Enum ) m_textureFormat ;
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
DX_CHECK ( s_renderD3D9 - > m_device - > CreateVolumeTexture ( _width
2012-08-05 14:51:49 -07:00
, _height
, _depth
, _numMips
, 0
2014-02-05 23:07:11 -08:00
, s_textureFormat [ fmt ] . m_fmt
2014-05-26 14:09:26 -07:00
, s_renderD3D9 - > m_pool
2012-08-12 21:02:11 -07:00
, & m_texture3d
2012-08-05 14:51:49 -07:00
, NULL
) ) ;
2014-02-05 23:07:11 -08:00
BGFX_FATAL ( NULL ! = m_texture3d , Fatal : : UnableToCreateTexture , " Failed to create volume texture (size: %dx%dx%d, mips: %d, fmt: %s). "
2012-08-05 14:51:49 -07:00
, _width
, _height
, _depth
, _numMips
2014-02-05 23:07:11 -08:00
, getName ( fmt )
2012-08-05 14:51:49 -07:00
) ;
}
2014-05-26 14:09:26 -07:00
void TextureD3D9 : : createCubeTexture ( uint32_t _edge , uint32_t _numMips )
2012-08-05 14:51:49 -07:00
{
m_type = TextureCube ;
2014-02-05 23:07:11 -08:00
const TextureFormat : : Enum fmt = ( TextureFormat : : Enum ) m_textureFormat ;
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
DX_CHECK ( s_renderD3D9 - > m_device - > CreateCubeTexture ( _edge
2012-08-05 14:51:49 -07:00
, _numMips
, 0
2014-02-05 23:07:11 -08:00
, s_textureFormat [ fmt ] . m_fmt
2014-05-26 14:09:26 -07:00
, s_renderD3D9 - > m_pool
2012-08-12 21:02:11 -07:00
, & m_textureCube
2012-08-05 14:51:49 -07:00
, NULL
) ) ;
2014-02-05 23:07:11 -08:00
BGFX_FATAL ( NULL ! = m_textureCube , Fatal : : UnableToCreateTexture , " Failed to create cube texture (edge: %d, mips: %d, fmt: %s). "
2012-08-05 14:51:49 -07:00
, _edge
, _numMips
2014-02-05 23:07:11 -08:00
, getName ( fmt )
2012-08-05 14:51:49 -07:00
) ;
}
2014-05-26 14:09:26 -07:00
uint8_t * TextureD3D9 : : lock ( uint8_t _side , uint8_t _lod , uint32_t & _pitch , uint32_t & _slicePitch , const Rect * _rect )
2012-08-05 14:51:49 -07:00
{
switch ( m_type )
{
case Texture2D :
{
2012-08-12 21:02:11 -07:00
D3DLOCKED_RECT lockedRect ;
if ( NULL ! = _rect )
{
RECT rect ;
2015-03-29 22:40:35 -07:00
rect . left = _rect - > m_x ;
rect . top = _rect - > m_y ;
rect . right = rect . left + _rect - > m_width ;
rect . bottom = rect . top + _rect - > m_height ;
2012-08-12 21:02:11 -07:00
DX_CHECK ( m_texture2d - > LockRect ( _lod , & lockedRect , & rect , 0 ) ) ;
}
else
{
DX_CHECK ( m_texture2d - > LockRect ( _lod , & lockedRect , NULL , 0 ) ) ;
}
_pitch = lockedRect . Pitch ;
2012-08-05 14:51:49 -07:00
_slicePitch = 0 ;
2012-08-12 21:02:11 -07:00
return ( uint8_t * ) lockedRect . pBits ;
2012-08-05 14:51:49 -07:00
}
case Texture3D :
{
D3DLOCKED_BOX box ;
2012-08-12 21:02:11 -07:00
DX_CHECK ( m_texture3d - > LockBox ( _lod , & box , NULL , 0 ) ) ;
2012-08-05 14:51:49 -07:00
_pitch = box . RowPitch ;
_slicePitch = box . SlicePitch ;
return ( uint8_t * ) box . pBits ;
}
case TextureCube :
{
2013-01-06 17:53:45 -08:00
D3DLOCKED_RECT lockedRect ;
if ( NULL ! = _rect )
{
RECT rect ;
2013-02-21 21:07:31 -08:00
rect . left = _rect - > m_x ;
rect . top = _rect - > m_y ;
rect . right = rect . left + _rect - > m_width ;
2013-01-06 17:53:45 -08:00
rect . bottom = rect . top + _rect - > m_height ;
DX_CHECK ( m_textureCube - > LockRect ( D3DCUBEMAP_FACES ( _side ) , _lod , & lockedRect , & rect , 0 ) ) ;
}
else
{
DX_CHECK ( m_textureCube - > LockRect ( D3DCUBEMAP_FACES ( _side ) , _lod , & lockedRect , NULL , 0 ) ) ;
}
_pitch = lockedRect . Pitch ;
2012-08-05 14:51:49 -07:00
_slicePitch = 0 ;
2013-01-06 17:53:45 -08:00
return ( uint8_t * ) lockedRect . pBits ;
2012-08-05 14:51:49 -07:00
}
}
BX_CHECK ( false , " You should not be here. " ) ;
2013-12-23 20:57:58 -08:00
_pitch = 0 ;
_slicePitch = 0 ;
2012-08-05 14:51:49 -07:00
return NULL ;
}
2014-05-26 14:09:26 -07:00
void TextureD3D9 : : unlock ( uint8_t _side , uint8_t _lod )
2012-08-05 14:51:49 -07:00
{
switch ( m_type )
{
case Texture2D :
{
2012-08-12 21:02:11 -07:00
DX_CHECK ( m_texture2d - > UnlockRect ( _lod ) ) ;
2012-08-05 14:51:49 -07:00
}
return ;
case Texture3D :
{
2012-08-12 21:02:11 -07:00
DX_CHECK ( m_texture3d - > UnlockBox ( _lod ) ) ;
2012-08-05 14:51:49 -07:00
}
return ;
case TextureCube :
{
2012-08-12 21:02:11 -07:00
DX_CHECK ( m_textureCube - > UnlockRect ( D3DCUBEMAP_FACES ( _side ) , _lod ) ) ;
2012-08-05 14:51:49 -07:00
}
return ;
}
BX_CHECK ( false , " You should not be here. " ) ;
}
2014-05-26 14:09:26 -07:00
void TextureD3D9 : : dirty ( uint8_t _side , const Rect & _rect , uint16_t _z , uint16_t _depth )
2013-03-02 21:35:09 -08:00
{
switch ( m_type )
{
case Texture2D :
{
RECT rect ;
rect . left = _rect . m_x ;
rect . top = _rect . m_y ;
rect . right = rect . left + _rect . m_width ;
rect . bottom = rect . top + _rect . m_height ;
DX_CHECK ( m_texture2d - > AddDirtyRect ( & rect ) ) ;
}
return ;
case Texture3D :
{
2013-03-02 23:20:28 -08:00
D3DBOX box ;
box . Left = _rect . m_x ;
box . Top = _rect . m_y ;
box . Right = box . Left + _rect . m_width ;
box . Bottom = box . Top + _rect . m_height ;
box . Front = _z ;
box . Back = box . Front + _depth ;
DX_CHECK ( m_texture3d - > AddDirtyBox ( & box ) ) ;
2013-03-02 21:35:09 -08:00
}
return ;
case TextureCube :
{
RECT rect ;
rect . left = _rect . m_x ;
rect . top = _rect . m_y ;
rect . right = rect . left + _rect . m_width ;
rect . bottom = rect . top + _rect . m_height ;
DX_CHECK ( m_textureCube - > AddDirtyRect ( D3DCUBEMAP_FACES ( _side ) , & rect ) ) ;
}
return ;
}
BX_CHECK ( false , " You should not be here. " ) ;
}
2014-05-26 14:09:26 -07:00
void TextureD3D9 : : create ( const Memory * _mem , uint32_t _flags , uint8_t _skip )
2012-08-05 14:51:49 -07:00
{
2013-07-24 21:59:59 -07:00
m_flags = _flags ;
2012-08-05 14:51:49 -07:00
2013-09-02 16:22:53 -07:00
ImageContainer imageContainer ;
2012-08-05 14:51:49 -07:00
2013-09-02 16:22:53 -07:00
if ( imageParse ( imageContainer , _mem - > data , _mem - > size ) )
2012-08-05 14:51:49 -07:00
{
2014-02-19 22:34:53 -08:00
uint8_t numMips = imageContainer . m_numMips ;
const uint32_t startLod = bx : : uint32_min ( _skip , numMips - 1 ) ;
numMips - = startLod ;
2014-03-01 19:27:34 -08:00
const ImageBlockInfo & blockInfo = getBlockInfo ( TextureFormat : : Enum ( imageContainer . m_format ) ) ;
const uint32_t textureWidth = bx : : uint32_max ( blockInfo . blockWidth , imageContainer . m_width > > startLod ) ;
const uint32_t textureHeight = bx : : uint32_max ( blockInfo . blockHeight , imageContainer . m_height > > startLod ) ;
2014-02-19 22:34:53 -08:00
2014-03-01 19:27:34 -08:00
m_requestedFormat = imageContainer . m_format ;
m_textureFormat = imageContainer . m_format ;
2012-08-05 14:51:49 -07:00
2013-09-08 21:03:03 -07:00
const TextureFormatInfo & tfi = s_textureFormat [ m_requestedFormat ] ;
const bool convert = D3DFMT_UNKNOWN = = tfi . m_fmt ;
uint8_t bpp = getBitsPerPixel ( TextureFormat : : Enum ( m_textureFormat ) ) ;
if ( convert )
{
m_textureFormat = ( uint8_t ) TextureFormat : : BGRA8 ;
bpp = 32 ;
}
2013-01-20 12:47:29 -08:00
2013-09-02 16:22:53 -07:00
if ( imageContainer . m_cubeMap )
2012-08-05 14:51:49 -07:00
{
2014-02-19 22:34:53 -08:00
createCubeTexture ( textureWidth , numMips ) ;
2012-08-05 14:51:49 -07:00
}
2013-09-02 16:22:53 -07:00
else if ( imageContainer . m_depth > 1 )
2012-08-05 14:51:49 -07:00
{
2014-02-19 22:34:53 -08:00
createVolumeTexture ( textureWidth , textureHeight , imageContainer . m_depth , numMips ) ;
2012-08-05 14:51:49 -07:00
}
else
{
2014-02-19 22:34:53 -08:00
createTexture ( textureWidth , textureHeight , numMips ) ;
2014-02-05 23:07:11 -08:00
}
2014-04-19 15:02:43 -07:00
BX_TRACE ( " Texture %3d: %s (requested: %s), %dx%d%s%s. "
2014-05-26 14:09:26 -07:00
, this - s_renderD3D9 - > m_textures
2014-04-19 15:02:43 -07:00
, getName ( ( TextureFormat : : Enum ) m_textureFormat )
, getName ( ( TextureFormat : : Enum ) m_requestedFormat )
, textureWidth
, textureHeight
, imageContainer . m_cubeMap ? " x6 " : " "
, 0 ! = ( m_flags & BGFX_TEXTURE_RT_MASK ) ? " (render target) " : " "
) ;
2014-02-05 23:07:11 -08:00
if ( 0 ! = ( _flags & BGFX_TEXTURE_RT_BUFFER_ONLY ) )
{
return ;
2012-08-05 14:51:49 -07:00
}
2013-09-08 21:03:03 -07:00
// For BC4 and B5 in DX9 LockRect returns wrong number of
// bytes. If actual mip size is used it causes memory corruption.
// http://www.aras-p.info/texts/D3D9GPUHacks.html#3dc
const bool useMipSize = true
& & imageContainer . m_format ! = TextureFormat : : BC4
& & imageContainer . m_format ! = TextureFormat : : BC5
;
for ( uint8_t side = 0 , numSides = imageContainer . m_cubeMap ? 6 : 1 ; side < numSides ; + + side )
2012-08-05 14:51:49 -07:00
{
2014-02-19 22:34:53 -08:00
uint32_t width = textureWidth ;
uint32_t height = textureHeight ;
2013-09-08 21:03:03 -07:00
uint32_t depth = imageContainer . m_depth ;
uint32_t mipWidth = imageContainer . m_width ;
uint32_t mipHeight = imageContainer . m_height ;
2012-08-05 14:51:49 -07:00
2014-02-19 22:34:53 -08:00
for ( uint32_t lod = 0 , num = numMips ; lod < num ; + + lod )
2013-09-08 21:03:03 -07:00
{
width = bx : : uint32_max ( 1 , width ) ;
height = bx : : uint32_max ( 1 , height ) ;
depth = bx : : uint32_max ( 1 , depth ) ;
2014-03-01 20:08:50 -08:00
mipWidth = bx : : uint32_max ( blockInfo . blockWidth , mipWidth ) ;
mipHeight = bx : : uint32_max ( blockInfo . blockHeight , mipHeight ) ;
2013-09-08 21:03:03 -07:00
uint32_t mipSize = width * height * depth * bpp / 8 ;
ImageMip mip ;
2014-02-19 22:34:53 -08:00
if ( imageGetRawData ( imageContainer , side , lod + startLod , _mem - > data , _mem - > size , mip ) )
2012-08-05 14:51:49 -07:00
{
2013-09-08 21:03:03 -07:00
uint32_t pitch ;
uint32_t slicePitch ;
uint8_t * bits = lock ( side , lod , pitch , slicePitch ) ;
2012-08-05 14:51:49 -07:00
2013-09-08 21:03:03 -07:00
if ( convert )
2012-08-05 14:51:49 -07:00
{
2013-09-08 21:03:03 -07:00
if ( width ! = mipWidth
| | height ! = mipHeight )
2012-08-05 14:51:49 -07:00
{
2013-09-08 21:03:03 -07:00
uint32_t srcpitch = mipWidth * bpp / 8 ;
2012-08-05 14:51:49 -07:00
2013-09-16 21:40:30 -07:00
uint8_t * temp = ( uint8_t * ) BX_ALLOC ( g_allocator , srcpitch * mipHeight ) ;
2013-11-07 22:59:17 -08:00
imageDecodeToBgra8 ( temp , mip . m_data , mip . m_width , mip . m_height , srcpitch , mip . m_format ) ;
2012-08-05 14:51:49 -07:00
uint32_t dstpitch = pitch ;
for ( uint32_t yy = 0 ; yy < height ; + + yy )
{
uint8_t * src = & temp [ yy * srcpitch ] ;
uint8_t * dst = & bits [ yy * dstpitch ] ;
2013-09-08 21:03:03 -07:00
memcpy ( dst , src , dstpitch ) ;
2012-08-05 14:51:49 -07:00
}
2013-09-16 21:40:30 -07:00
BX_FREE ( g_allocator , temp ) ;
2012-08-05 14:51:49 -07:00
}
else
{
2013-11-07 22:59:17 -08:00
imageDecodeToBgra8 ( bits , mip . m_data , mip . m_width , mip . m_height , pitch , mip . m_format ) ;
2012-08-05 14:51:49 -07:00
}
}
2013-09-08 21:03:03 -07:00
else
2012-08-05 14:51:49 -07:00
{
2013-09-08 21:03:03 -07:00
uint32_t size = useMipSize ? mip . m_size : mipSize ;
memcpy ( bits , mip . m_data , size ) ;
2012-08-05 14:51:49 -07:00
}
2013-02-14 21:42:44 -08:00
2013-09-08 21:03:03 -07:00
unlock ( side , lod ) ;
2012-08-12 21:02:11 -07:00
}
2012-08-05 14:51:49 -07:00
2013-09-08 21:03:03 -07:00
width > > = 1 ;
height > > = 1 ;
depth > > = 1 ;
mipWidth > > = 1 ;
mipHeight > > = 1 ;
2012-08-05 14:51:49 -07:00
}
}
}
}
2014-05-26 14:09:26 -07:00
void TextureD3D9 : : updateBegin ( uint8_t _side , uint8_t _mip )
2012-08-12 21:02:11 -07:00
{
uint32_t slicePitch ;
2014-05-26 14:09:26 -07:00
s_renderD3D9 - > m_updateTextureSide = _side ;
s_renderD3D9 - > m_updateTextureMip = _mip ;
s_renderD3D9 - > m_updateTextureBits = lock ( _side , _mip , s_renderD3D9 - > m_updateTexturePitch , slicePitch ) ;
2013-03-02 21:35:09 -08:00
}
2012-08-12 21:02:11 -07:00
2014-05-26 14:09:26 -07:00
void TextureD3D9 : : update ( uint8_t _side , uint8_t _mip , const Rect & _rect , uint16_t _z , uint16_t _depth , uint16_t _pitch , const Memory * _mem )
2013-03-02 21:35:09 -08:00
{
2013-11-07 22:59:17 -08:00
const uint32_t bpp = getBitsPerPixel ( TextureFormat : : Enum ( m_textureFormat ) ) ;
const uint32_t rectpitch = _rect . m_width * bpp / 8 ;
const uint32_t srcpitch = UINT16_MAX = = _pitch ? rectpitch : _pitch ;
2014-05-26 14:09:26 -07:00
const uint32_t dstpitch = s_renderD3D9 - > m_updateTexturePitch ;
uint8_t * bits = s_renderD3D9 - > m_updateTextureBits + _rect . m_y * dstpitch + _rect . m_x * bpp / 8 ;
2013-03-02 21:35:09 -08:00
2013-09-08 21:03:03 -07:00
const bool convert = m_textureFormat ! = m_requestedFormat ;
2015-01-10 20:38:47 -08:00
2013-09-08 21:03:03 -07:00
uint8_t * data = _mem - > data ;
uint8_t * temp = NULL ;
if ( convert )
{
2015-03-29 22:40:35 -07:00
temp = ( uint8_t * ) BX_ALLOC ( g_allocator , rectpitch * _rect . m_height ) ;
2013-11-07 22:59:17 -08:00
imageDecodeToBgra8 ( temp , data , _rect . m_width , _rect . m_height , srcpitch , m_requestedFormat ) ;
2013-09-08 21:03:03 -07:00
data = temp ;
}
2013-03-02 21:35:09 -08:00
{
2013-12-07 22:01:55 -08:00
uint8_t * src = data ;
uint8_t * dst = bits ;
2013-03-02 21:35:09 -08:00
for ( uint32_t yy = 0 , height = _rect . m_height ; yy < height ; + + yy )
{
2013-12-07 22:01:55 -08:00
memcpy ( dst , src , rectpitch ) ;
src + = srcpitch ;
dst + = dstpitch ;
2013-03-02 21:35:09 -08:00
}
2012-08-12 21:02:11 -07:00
}
2013-09-08 21:03:03 -07:00
if ( NULL ! = temp )
{
2013-09-16 21:40:30 -07:00
BX_FREE ( g_allocator , temp ) ;
2013-09-08 21:03:03 -07:00
}
2013-03-02 23:20:28 -08:00
if ( 0 = = _mip )
{
dirty ( _side , _rect , _z , _depth ) ;
}
2013-03-02 21:35:09 -08:00
}
2014-05-26 14:09:26 -07:00
void TextureD3D9 : : updateEnd ( )
2013-03-02 21:35:09 -08:00
{
2014-05-26 14:09:26 -07:00
unlock ( s_renderD3D9 - > m_updateTextureSide , s_renderD3D9 - > m_updateTextureMip ) ;
2012-08-12 21:02:11 -07:00
}
2014-05-26 14:09:26 -07:00
void TextureD3D9 : : commit ( uint8_t _stage , uint32_t _flags )
2012-08-05 14:51:49 -07:00
{
2014-05-26 14:09:26 -07:00
s_renderD3D9 - > setSamplerState ( _stage , 0 = = ( BGFX_SAMPLER_DEFAULT_FLAGS & _flags ) ? _flags : m_flags ) ;
DX_CHECK ( s_renderD3D9 - > m_device - > SetTexture ( _stage , m_ptr ) ) ;
2015-03-01 22:01:30 -08:00
// s_renderD3D9->setSamplerState(_stage, 0 == (BGFX_SAMPLER_DEFAULT_FLAGS & _flags) ? _flags : m_flags, true);
// DX_CHECK(s_renderD3D9->m_device->SetTexture(D3DVERTEXTEXTURESAMPLER0 + _stage, m_ptr) );
2012-08-05 14:51:49 -07:00
}
2014-05-26 14:09:26 -07:00
void TextureD3D9 : : resolve ( ) const
2012-08-05 14:51:49 -07:00
{
2014-02-05 23:07:11 -08:00
if ( NULL ! = m_surface
& & NULL ! = m_texture2d )
{
IDirect3DSurface9 * surface ;
DX_CHECK ( m_texture2d - > GetSurfaceLevel ( 0 , & surface ) ) ;
2014-05-26 14:09:26 -07:00
DX_CHECK ( s_renderD3D9 - > m_device - > StretchRect ( m_surface
2014-02-05 23:07:11 -08:00
, NULL
, surface
, NULL
, D3DTEXF_LINEAR
) ) ;
DX_RELEASE ( surface , 1 ) ;
}
}
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
void TextureD3D9 : : preReset ( )
2014-02-05 23:07:11 -08:00
{
TextureFormat : : Enum fmt = ( TextureFormat : : Enum ) m_textureFormat ;
if ( TextureFormat : : Unknown ! = fmt
& & ( isDepth ( fmt ) | | ! ! ( m_flags & BGFX_TEXTURE_RT_MASK ) ) )
{
DX_RELEASE ( m_ptr , 0 ) ;
DX_RELEASE ( m_surface , 0 ) ;
}
2012-08-05 14:51:49 -07:00
}
2014-05-26 14:09:26 -07:00
void TextureD3D9 : : postReset ( )
2012-08-05 14:51:49 -07:00
{
2014-02-05 23:07:11 -08:00
TextureFormat : : Enum fmt = ( TextureFormat : : Enum ) m_textureFormat ;
if ( TextureFormat : : Unknown ! = fmt
& & ( isDepth ( fmt ) | | ! ! ( m_flags & BGFX_TEXTURE_RT_MASK ) ) )
2012-08-05 14:51:49 -07:00
{
2014-02-05 23:07:11 -08:00
createTexture ( m_width , m_height , m_numMips ) ;
}
}
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
void FrameBufferD3D9 : : create ( uint8_t _num , const TextureHandle * _handles )
2014-02-05 23:07:11 -08:00
{
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_color ) ; + + ii )
{
m_color [ ii ] = NULL ;
}
m_depthStencil = NULL ;
2012-08-05 14:51:49 -07:00
2014-02-05 23:07:11 -08:00
m_num = 0 ;
m_needResolve = false ;
for ( uint32_t ii = 0 ; ii < _num ; + + ii )
{
TextureHandle handle = _handles [ ii ] ;
if ( isValid ( handle ) )
2012-08-05 14:51:49 -07:00
{
2014-05-26 14:09:26 -07:00
const TextureD3D9 & texture = s_renderD3D9 - > m_textures [ handle . idx ] ;
2012-08-05 14:51:49 -07:00
2014-02-05 23:07:11 -08:00
if ( isDepth ( ( TextureFormat : : Enum ) texture . m_textureFormat ) )
2012-08-05 14:51:49 -07:00
{
2014-02-05 23:07:11 -08:00
m_depthHandle = handle ;
if ( NULL ! = texture . m_surface )
{
m_depthStencil = texture . m_surface ;
m_depthStencil - > AddRef ( ) ;
}
else
{
DX_CHECK ( texture . m_texture2d - > GetSurfaceLevel ( 0 , & m_depthStencil ) ) ;
}
2012-08-05 14:51:49 -07:00
}
2014-02-05 23:07:11 -08:00
else
2012-08-05 14:51:49 -07:00
{
2014-02-05 23:07:11 -08:00
m_colorHandle [ m_num ] = handle ;
if ( NULL ! = texture . m_surface )
{
m_color [ m_num ] = texture . m_surface ;
m_color [ m_num ] - > AddRef ( ) ;
}
else
{
DX_CHECK ( texture . m_texture2d - > GetSurfaceLevel ( 0 , & m_color [ m_num ] ) ) ;
}
m_num + + ;
2012-08-05 14:51:49 -07:00
}
2014-02-05 23:07:11 -08:00
m_needResolve | = ( NULL ! = texture . m_surface ) & & ( NULL ! = texture . m_texture2d ) ;
2012-08-05 14:51:49 -07:00
}
}
2014-02-22 08:48:30 -08:00
if ( 0 = = m_num )
{
createNullColorRT ( ) ;
}
2012-08-05 14:51:49 -07:00
}
2014-09-07 17:17:38 -07:00
void FrameBufferD3D9 : : create ( uint16_t _denseIdx , void * _nwh , uint32_t _width , uint32_t _height , TextureFormat : : Enum _depthFormat )
2012-08-05 14:51:49 -07:00
{
2014-09-22 19:34:10 -07:00
BX_UNUSED ( _depthFormat ) ;
2012-08-05 14:51:49 -07:00
2014-09-07 17:17:38 -07:00
m_hwnd = ( HWND ) _nwh ;
2014-09-22 19:34:10 -07:00
D3DPRESENT_PARAMETERS params ;
memcpy ( & params , & s_renderD3D9 - > m_params , sizeof ( D3DPRESENT_PARAMETERS ) ) ;
2014-09-22 23:00:42 -07:00
params . BackBufferWidth = bx : : uint32_max ( _width , 16 ) ;
params . BackBufferHeight = bx : : uint32_max ( _height , 16 ) ;
2014-09-22 19:34:10 -07:00
DX_CHECK ( s_renderD3D9 - > m_device - > CreateAdditionalSwapChain ( & params , & m_swapChain ) ) ;
2014-09-07 17:17:38 -07:00
DX_CHECK ( m_swapChain - > GetBackBuffer ( 0 , D3DBACKBUFFER_TYPE_MONO , & m_color [ 0 ] ) ) ;
2014-09-22 23:00:42 -07:00
DX_CHECK ( s_renderD3D9 - > m_device - > CreateDepthStencilSurface (
params . BackBufferWidth
, params . BackBufferHeight
, params . AutoDepthStencilFormat
, params . MultiSampleType
, params . MultiSampleQuality
, FALSE
, & m_depthStencil
, NULL
) ) ;
2014-09-07 17:17:38 -07:00
m_colorHandle [ 0 ] . idx = invalidHandle ;
m_denseIdx = _denseIdx ;
m_num = 1 ;
m_needResolve = false ;
}
2012-08-05 14:51:49 -07:00
2014-09-07 17:17:38 -07:00
uint16_t FrameBufferD3D9 : : destroy ( )
{
if ( NULL ! = m_hwnd )
2014-02-05 23:07:11 -08:00
{
2014-09-22 23:00:42 -07:00
DX_RELEASE ( m_depthStencil , 0 ) ;
DX_RELEASE ( m_color [ 0 ] , 0 ) ;
DX_RELEASE ( m_swapChain , 0 ) ;
2014-09-07 17:17:38 -07:00
}
else
{
for ( uint32_t ii = 0 , num = m_num ; ii < num ; + + ii )
2014-02-22 08:48:30 -08:00
{
2014-09-07 17:17:38 -07:00
m_colorHandle [ ii ] . idx = invalidHandle ;
IDirect3DSurface9 * ptr = m_color [ ii ] ;
2014-02-22 08:48:30 -08:00
if ( NULL ! = ptr )
{
ptr - > Release ( ) ;
2014-09-07 17:17:38 -07:00
m_color [ ii ] = NULL ;
2014-02-22 08:48:30 -08:00
}
}
2014-09-07 17:17:38 -07:00
if ( NULL ! = m_depthStencil )
{
if ( 0 = = m_num )
{
IDirect3DSurface9 * ptr = m_color [ 0 ] ;
if ( NULL ! = ptr )
{
ptr - > Release ( ) ;
m_color [ 0 ] = NULL ;
}
}
m_depthStencil - > Release ( ) ;
m_depthStencil = NULL ;
}
2014-02-05 23:07:11 -08:00
}
2012-08-05 14:51:49 -07:00
2014-09-07 17:17:38 -07:00
m_hwnd = NULL ;
2014-02-05 23:07:11 -08:00
m_num = 0 ;
m_depthHandle . idx = invalidHandle ;
2014-09-07 17:17:38 -07:00
uint16_t denseIdx = m_denseIdx ;
m_denseIdx = UINT16_MAX ;
return denseIdx ;
}
HRESULT FrameBufferD3D9 : : present ( )
{
return m_swapChain - > Present ( NULL , NULL , m_hwnd , NULL , 0 ) ;
2014-02-05 23:07:11 -08:00
}
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
void FrameBufferD3D9 : : resolve ( ) const
2014-02-05 23:07:11 -08:00
{
if ( m_needResolve )
{
if ( isValid ( m_depthHandle ) )
{
2014-05-26 14:09:26 -07:00
const TextureD3D9 & texture = s_renderD3D9 - > m_textures [ m_depthHandle . idx ] ;
2014-02-05 23:07:11 -08:00
texture . resolve ( ) ;
}
for ( uint32_t ii = 0 , num = m_num ; ii < num ; + + ii )
{
2014-05-26 14:09:26 -07:00
const TextureD3D9 & texture = s_renderD3D9 - > m_textures [ m_colorHandle [ ii ] . idx ] ;
2014-02-05 23:07:11 -08:00
texture . resolve ( ) ;
2012-08-05 14:51:49 -07:00
}
}
}
2014-05-26 14:09:26 -07:00
void FrameBufferD3D9 : : preReset ( )
2012-08-05 14:51:49 -07:00
{
2014-09-07 17:17:38 -07:00
if ( NULL ! = m_hwnd )
2014-02-05 23:07:11 -08:00
{
2014-09-07 17:17:38 -07:00
DX_RELEASE ( m_color [ 0 ] , 0 ) ;
DX_RELEASE ( m_swapChain , 0 ) ;
2014-02-05 23:07:11 -08:00
}
2014-09-07 17:17:38 -07:00
else
2014-02-05 23:07:11 -08:00
{
2014-09-07 17:17:38 -07:00
for ( uint32_t ii = 0 , num = m_num ; ii < num ; + + ii )
2014-02-22 08:48:30 -08:00
{
2014-09-07 17:17:38 -07:00
m_color [ ii ] - > Release ( ) ;
m_color [ ii ] = NULL ;
2014-02-22 08:48:30 -08:00
}
2014-09-07 17:17:38 -07:00
if ( isValid ( m_depthHandle ) )
{
if ( 0 = = m_num )
{
m_color [ 0 ] - > Release ( ) ;
m_color [ 0 ] = NULL ;
}
m_depthStencil - > Release ( ) ;
m_depthStencil = NULL ;
}
2014-02-05 23:07:11 -08:00
}
2012-08-05 14:51:49 -07:00
}
2014-05-26 14:09:26 -07:00
void FrameBufferD3D9 : : postReset ( )
2012-08-05 14:51:49 -07:00
{
2014-09-07 17:17:38 -07:00
if ( NULL ! = m_hwnd )
2014-02-05 23:07:11 -08:00
{
2014-09-07 17:17:38 -07:00
DX_CHECK ( s_renderD3D9 - > m_device - > CreateAdditionalSwapChain ( & s_renderD3D9 - > m_params , & m_swapChain ) ) ;
DX_CHECK ( m_swapChain - > GetBackBuffer ( 0 , D3DBACKBUFFER_TYPE_MONO , & m_color [ 0 ] ) ) ;
2014-02-05 23:07:11 -08:00
}
2014-09-07 17:17:38 -07:00
else
2014-02-05 23:07:11 -08:00
{
2014-09-07 17:17:38 -07:00
for ( uint32_t ii = 0 , num = m_num ; ii < num ; + + ii )
2014-02-05 23:07:11 -08:00
{
2014-09-07 17:17:38 -07:00
TextureHandle th = m_colorHandle [ ii ] ;
if ( isValid ( th ) )
{
TextureD3D9 & texture = s_renderD3D9 - > m_textures [ th . idx ] ;
if ( NULL ! = texture . m_surface )
{
m_color [ ii ] = texture . m_surface ;
m_color [ ii ] - > AddRef ( ) ;
}
else
{
DX_CHECK ( texture . m_texture2d - > GetSurfaceLevel ( 0 , & m_color [ ii ] ) ) ;
}
}
2014-02-05 23:07:11 -08:00
}
2014-02-22 08:48:30 -08:00
2014-09-07 17:17:38 -07:00
if ( isValid ( m_depthHandle ) )
2014-02-22 08:48:30 -08:00
{
2014-09-07 17:17:38 -07:00
TextureD3D9 & texture = s_renderD3D9 - > m_textures [ m_depthHandle . idx ] ;
if ( NULL ! = texture . m_surface )
{
m_depthStencil = texture . m_surface ;
m_depthStencil - > AddRef ( ) ;
}
else
{
DX_CHECK ( texture . m_texture2d - > GetSurfaceLevel ( 0 , & m_depthStencil ) ) ;
}
if ( 0 = = m_num )
{
createNullColorRT ( ) ;
}
2014-02-22 08:48:30 -08:00
}
2014-02-05 23:07:11 -08:00
}
2012-08-05 14:51:49 -07:00
}
2014-05-26 14:09:26 -07:00
void FrameBufferD3D9 : : createNullColorRT ( )
2014-02-22 08:48:30 -08:00
{
2014-05-26 14:09:26 -07:00
const TextureD3D9 & texture = s_renderD3D9 - > m_textures [ m_depthHandle . idx ] ;
DX_CHECK ( s_renderD3D9 - > m_device - > CreateRenderTarget ( texture . m_width
2014-02-22 08:48:30 -08:00
, texture . m_height
, D3DFMT_NULL
, D3DMULTISAMPLE_NONE
, 0
, false
, & m_color [ 0 ]
, NULL
) ) ;
}
2014-09-01 11:24:51 -07:00
void RendererContextD3D9 : : submit ( Frame * _render , ClearQuad & _clearQuad , TextVideoMemBlitter & _textVideoMemBlitter )
2012-08-05 14:51:49 -07:00
{
2014-05-26 14:09:26 -07:00
IDirect3DDevice9 * device = m_device ;
2012-08-05 14:51:49 -07:00
2013-06-09 15:28:25 -07:00
PIX_BEGINEVENT ( D3DCOLOR_RGBA ( 0xff , 0x00 , 0x00 , 0xff ) , L " rendererSubmit " ) ;
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
updateResolution ( _render - > m_resolution ) ;
2012-08-05 14:51:49 -07:00
2013-01-01 13:19:10 -08:00
int64_t elapsed = - bx : : getHPCounter ( ) ;
int64_t captureElapsed = 0 ;
2012-08-05 14:51:49 -07:00
device - > BeginScene ( ) ;
2014-05-26 14:09:26 -07:00
if ( 0 < _render - > m_iboffset )
2012-08-05 14:51:49 -07:00
{
2014-05-26 14:09:26 -07:00
TransientIndexBuffer * ib = _render - > m_transientIb ;
m_indexBuffers [ ib - > handle . idx ] . update ( 0 , _render - > m_iboffset , ib - > data , true ) ;
2012-08-05 14:51:49 -07:00
}
2014-05-26 14:09:26 -07:00
if ( 0 < _render - > m_vboffset )
2012-08-05 14:51:49 -07:00
{
2014-05-26 14:09:26 -07:00
TransientVertexBuffer * vb = _render - > m_transientVb ;
m_vertexBuffers [ vb - > handle . idx ] . update ( 0 , _render - > m_vboffset , vb - > data , true ) ;
2012-08-05 14:51:49 -07:00
}
2014-05-26 14:09:26 -07:00
_render - > sort ( ) ;
2012-08-05 14:51:49 -07:00
2014-07-20 20:27:13 -07:00
RenderDraw currentState ;
currentState . clear ( ) ;
2012-08-05 14:51:49 -07:00
currentState . m_flags = BGFX_STATE_NONE ;
2012-11-10 19:59:23 -08:00
currentState . m_stencil = packStencil ( BGFX_STENCIL_NONE , BGFX_STENCIL_NONE ) ;
2012-08-05 14:51:49 -07:00
2014-12-27 19:00:41 -08:00
ViewState viewState ( _render , false ) ;
2014-05-10 20:51:44 -07:00
2014-05-26 14:09:26 -07:00
DX_CHECK ( device - > SetRenderState ( D3DRS_FILLMODE , _render - > m_debug & BGFX_DEBUG_WIREFRAME ? D3DFILL_WIREFRAME : D3DFILL_SOLID ) ) ;
2012-09-16 17:36:08 -07:00
uint16_t programIdx = invalidHandle ;
2012-08-05 14:51:49 -07:00
SortKey key ;
uint8_t view = 0xff ;
2014-02-05 23:07:11 -08:00
FrameBufferHandle fbh = BGFX_INVALID_HANDLE ;
2013-03-29 22:58:50 -07:00
uint32_t blendFactor = 0 ;
2014-04-26 23:48:41 -07:00
2015-03-29 22:40:35 -07:00
uint8_t primIndex ;
{
const uint64_t pt = _render - > m_debug & BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0 ;
primIndex = uint8_t ( pt > > BGFX_STATE_PT_SHIFT ) ;
}
2014-04-26 23:48:41 -07:00
PrimInfo prim = s_primInfo [ primIndex ] ;
2013-08-01 22:55:26 -07:00
bool viewHasScissor = false ;
Rect viewScissorRect ;
2013-08-04 16:56:07 -07:00
viewScissorRect . clear ( ) ;
2012-08-05 14:51:49 -07:00
2014-04-26 23:48:41 -07:00
uint32_t statsNumPrimsSubmitted [ BX_COUNTOF ( s_primInfo ) ] = { } ;
uint32_t statsNumPrimsRendered [ BX_COUNTOF ( s_primInfo ) ] = { } ;
uint32_t statsNumInstances [ BX_COUNTOF ( s_primInfo ) ] = { } ;
2012-08-05 14:51:49 -07:00
uint32_t statsNumIndices = 0 ;
2015-03-26 22:43:50 -07:00
uint32_t statsKeyType [ 2 ] = { } ;
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
invalidateSamplerState ( ) ;
2013-07-24 21:59:59 -07:00
2014-05-26 14:09:26 -07:00
if ( 0 = = ( _render - > m_debug & BGFX_DEBUG_IFH ) )
2012-08-05 14:51:49 -07:00
{
2014-05-26 14:09:26 -07:00
for ( uint32_t item = 0 , numItems = _render - > m_num ; item < numItems ; + + item )
2012-08-05 14:51:49 -07:00
{
2015-02-21 15:40:51 -08:00
const bool isCompute = key . decode ( _render - > m_sortKeys [ item ] , _render - > m_viewRemap ) ;
2015-03-26 22:43:50 -07:00
statsKeyType [ isCompute ] + + ;
2012-08-05 14:51:49 -07:00
2014-07-20 20:27:13 -07:00
if ( isCompute )
{
BX_CHECK ( false , " Compute is not supported on DirectX 9. " ) ;
continue ;
}
const RenderDraw & draw = _render - > m_renderItem [ _render - > m_sortValues [ item ] ] . draw ;
const uint64_t newFlags = draw . m_flags ;
uint64_t changedFlags = currentState . m_flags ^ draw . m_flags ;
2012-08-05 14:51:49 -07:00
currentState . m_flags = newFlags ;
2014-07-20 20:27:13 -07:00
const uint64_t newStencil = draw . m_stencil ;
uint64_t changedStencil = currentState . m_stencil ^ draw . m_stencil ;
2012-11-10 19:59:23 -08:00
currentState . m_stencil = newStencil ;
2012-08-05 14:51:49 -07:00
if ( key . m_view ! = view )
{
currentState . clear ( ) ;
2014-07-20 20:27:13 -07:00
currentState . m_scissor = ! draw . m_scissor ;
2012-08-05 14:51:49 -07:00
changedFlags = BGFX_STATE_MASK ;
2012-11-10 19:59:23 -08:00
changedStencil = packStencil ( BGFX_STENCIL_MASK , BGFX_STENCIL_MASK ) ;
2012-08-05 14:51:49 -07:00
currentState . m_flags = newFlags ;
2012-11-10 19:59:23 -08:00
currentState . m_stencil = newStencil ;
2012-08-05 14:51:49 -07:00
PIX_ENDEVENT ( ) ;
2013-06-09 15:28:25 -07:00
PIX_BEGINEVENT ( D3DCOLOR_RGBA ( 0xff , 0x00 , 0x00 , 0xff ) , s_viewNameW [ key . m_view ] ) ;
2012-08-05 14:51:49 -07:00
view = key . m_view ;
2012-09-16 17:36:08 -07:00
programIdx = invalidHandle ;
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
if ( _render - > m_fb [ view ] . idx ! = fbh . idx )
2012-08-05 14:51:49 -07:00
{
2014-05-26 14:09:26 -07:00
fbh = _render - > m_fb [ view ] ;
setFrameBuffer ( fbh ) ;
2012-08-05 14:51:49 -07:00
}
2014-12-27 19:00:41 -08:00
viewState . m_rect = _render - > m_rect [ view ] ;
2014-05-26 14:09:26 -07:00
const Rect & scissorRect = _render - > m_scissor [ view ] ;
2014-12-27 19:00:41 -08:00
viewHasScissor = ! scissorRect . isZero ( ) ;
viewScissorRect = viewHasScissor ? scissorRect : viewState . m_rect ;
2013-08-01 22:55:26 -07:00
2012-08-05 14:51:49 -07:00
D3DVIEWPORT9 vp ;
2014-12-27 19:00:41 -08:00
vp . X = viewState . m_rect . m_x ;
vp . Y = viewState . m_rect . m_y ;
vp . Width = viewState . m_rect . m_width ;
vp . Height = viewState . m_rect . m_height ;
2012-08-05 14:51:49 -07:00
vp . MinZ = 0.0f ;
vp . MaxZ = 1.0f ;
DX_CHECK ( device - > SetViewport ( & vp ) ) ;
2014-05-26 14:09:26 -07:00
Clear & clear = _render - > m_clear [ view ] ;
2012-08-05 14:51:49 -07:00
2015-01-11 18:02:34 -08:00
if ( BGFX_CLEAR_NONE ! = ( clear . m_flags & BGFX_CLEAR_MASK ) )
2012-08-05 14:51:49 -07:00
{
2014-12-27 19:00:41 -08:00
clearQuad ( _clearQuad , viewState . m_rect , clear , _render - > m_clearColor ) ;
2014-09-01 11:24:51 -07:00
prim = s_primInfo [ BX_COUNTOF ( s_primName ) ] ; // Force primitive type update after clear quad.
2012-08-05 14:51:49 -07:00
}
2013-07-27 15:27:54 -07:00
DX_CHECK ( device - > SetRenderState ( D3DRS_STENCILENABLE , FALSE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ZENABLE , TRUE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ZFUNC , D3DCMP_LESS ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_CULLMODE , D3DCULL_NONE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ALPHABLENDENABLE , FALSE ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ALPHAFUNC , D3DCMP_GREATER ) ) ;
}
2014-07-20 20:27:13 -07:00
uint16_t scissor = draw . m_scissor ;
2013-07-27 15:27:54 -07:00
if ( currentState . m_scissor ! = scissor )
{
currentState . m_scissor = scissor ;
if ( UINT16_MAX = = scissor )
2013-07-14 14:32:09 -07:00
{
2013-08-01 22:55:26 -07:00
DX_CHECK ( device - > SetRenderState ( D3DRS_SCISSORTESTENABLE , viewHasScissor ) ) ;
if ( viewHasScissor )
2013-07-27 15:27:54 -07:00
{
RECT rc ;
2014-12-27 19:00:41 -08:00
rc . left = viewScissorRect . m_x ;
rc . top = viewScissorRect . m_y ;
rc . right = viewScissorRect . m_x + viewScissorRect . m_width ;
2013-08-01 22:55:26 -07:00
rc . bottom = viewScissorRect . m_y + viewScissorRect . m_height ;
2013-07-27 15:27:54 -07:00
DX_CHECK ( device - > SetScissorRect ( & rc ) ) ;
}
}
else
{
2013-08-01 22:55:26 -07:00
Rect scissorRect ;
2014-05-26 14:09:26 -07:00
scissorRect . intersect ( viewScissorRect , _render - > m_rectCache . m_cache [ scissor ] ) ;
2013-07-27 15:27:54 -07:00
DX_CHECK ( device - > SetRenderState ( D3DRS_SCISSORTESTENABLE , true ) ) ;
2013-07-14 14:32:09 -07:00
RECT rc ;
2014-12-27 19:00:41 -08:00
rc . left = scissorRect . m_x ;
rc . top = scissorRect . m_y ;
rc . right = scissorRect . m_x + scissorRect . m_width ;
2013-07-14 14:32:09 -07:00
rc . bottom = scissorRect . m_y + scissorRect . m_height ;
DX_CHECK ( device - > SetScissorRect ( & rc ) ) ;
}
2012-08-05 14:51:49 -07:00
}
2012-11-10 19:59:23 -08:00
if ( 0 ! = changedStencil )
{
bool enable = 0 ! = newStencil ;
DX_CHECK ( device - > SetRenderState ( D3DRS_STENCILENABLE , enable ) ) ;
2015-01-10 20:38:47 -08:00
2012-11-10 19:59:23 -08:00
if ( 0 ! = newStencil )
{
uint32_t fstencil = unpackStencil ( 0 , newStencil ) ;
uint32_t bstencil = unpackStencil ( 1 , newStencil ) ;
uint32_t frontAndBack = bstencil ! = BGFX_STENCIL_NONE & & bstencil ! = fstencil ;
DX_CHECK ( device - > SetRenderState ( D3DRS_TWOSIDEDSTENCILMODE , 0 ! = frontAndBack ) ) ;
uint32_t fchanged = unpackStencil ( 0 , changedStencil ) ;
if ( ( BGFX_STENCIL_FUNC_REF_MASK | BGFX_STENCIL_FUNC_RMASK_MASK ) & fchanged )
{
uint32_t ref = ( fstencil & BGFX_STENCIL_FUNC_REF_MASK ) > > BGFX_STENCIL_FUNC_REF_SHIFT ;
DX_CHECK ( device - > SetRenderState ( D3DRS_STENCILREF , ref ) ) ;
uint32_t rmask = ( fstencil & BGFX_STENCIL_FUNC_RMASK_MASK ) > > BGFX_STENCIL_FUNC_RMASK_SHIFT ;
DX_CHECK ( device - > SetRenderState ( D3DRS_STENCILMASK , rmask ) ) ;
}
// uint32_t bchanged = unpackStencil(1, changedStencil);
// if (BGFX_STENCIL_FUNC_RMASK_MASK & bchanged)
// {
// uint32_t wmask = (bstencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;
// DX_CHECK(device->SetRenderState(D3DRS_STENCILWRITEMASK, wmask) );
// }
for ( uint32_t ii = 0 , num = frontAndBack + 1 ; ii < num ; + + ii )
{
uint32_t stencil = unpackStencil ( ii , newStencil ) ;
uint32_t changed = unpackStencil ( ii , changedStencil ) ;
if ( ( BGFX_STENCIL_TEST_MASK | BGFX_STENCIL_FUNC_REF_MASK | BGFX_STENCIL_FUNC_RMASK_MASK ) & changed )
{
uint32_t func = ( stencil & BGFX_STENCIL_TEST_MASK ) > > BGFX_STENCIL_TEST_SHIFT ;
2014-02-22 08:48:30 -08:00
DX_CHECK ( device - > SetRenderState ( s_stencilFuncRs [ ii ] , s_cmpFunc [ func ] ) ) ;
2012-11-10 19:59:23 -08:00
}
if ( ( BGFX_STENCIL_OP_FAIL_S_MASK | BGFX_STENCIL_OP_FAIL_Z_MASK | BGFX_STENCIL_OP_PASS_Z_MASK ) & changed )
{
uint32_t sfail = ( stencil & BGFX_STENCIL_OP_FAIL_S_MASK ) > > BGFX_STENCIL_OP_FAIL_S_SHIFT ;
DX_CHECK ( device - > SetRenderState ( s_stencilFailRs [ ii ] , s_stencilOp [ sfail ] ) ) ;
uint32_t zfail = ( stencil & BGFX_STENCIL_OP_FAIL_Z_MASK ) > > BGFX_STENCIL_OP_FAIL_Z_SHIFT ;
DX_CHECK ( device - > SetRenderState ( s_stencilZFailRs [ ii ] , s_stencilOp [ zfail ] ) ) ;
uint32_t zpass = ( stencil & BGFX_STENCIL_OP_PASS_Z_MASK ) > > BGFX_STENCIL_OP_PASS_Z_SHIFT ;
DX_CHECK ( device - > SetRenderState ( s_stencilZPassRs [ ii ] , s_stencilOp [ zpass ] ) ) ;
}
}
}
}
2013-06-17 22:11:45 -07:00
if ( ( 0
| BGFX_STATE_CULL_MASK
| BGFX_STATE_DEPTH_WRITE
| BGFX_STATE_DEPTH_TEST_MASK
| BGFX_STATE_RGB_WRITE
2014-03-25 23:07:51 -07:00
| BGFX_STATE_ALPHA_WRITE
2013-06-17 22:11:45 -07:00
| BGFX_STATE_BLEND_MASK
| BGFX_STATE_BLEND_EQUATION_MASK
| BGFX_STATE_ALPHA_REF_MASK
| BGFX_STATE_PT_MASK
| BGFX_STATE_POINT_SIZE_MASK
| BGFX_STATE_MSAA
) & changedFlags )
2012-08-05 14:51:49 -07:00
{
if ( BGFX_STATE_CULL_MASK & changedFlags )
{
uint32_t cull = ( newFlags & BGFX_STATE_CULL_MASK ) > > BGFX_STATE_CULL_SHIFT ;
DX_CHECK ( device - > SetRenderState ( D3DRS_CULLMODE , s_cullMode [ cull ] ) ) ;
}
if ( BGFX_STATE_DEPTH_WRITE & changedFlags )
2015-01-10 20:38:47 -08:00
{
2012-08-05 14:51:49 -07:00
DX_CHECK ( device - > SetRenderState ( D3DRS_ZWRITEENABLE , ! ! ( BGFX_STATE_DEPTH_WRITE & newFlags ) ) ) ;
}
if ( BGFX_STATE_DEPTH_TEST_MASK & changedFlags )
{
uint32_t func = ( newFlags & BGFX_STATE_DEPTH_TEST_MASK ) > > BGFX_STATE_DEPTH_TEST_SHIFT ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ZENABLE , 0 ! = func ) ) ;
if ( 0 ! = func )
{
2014-02-22 08:48:30 -08:00
DX_CHECK ( device - > SetRenderState ( D3DRS_ZFUNC , s_cmpFunc [ func ] ) ) ;
2012-08-05 14:51:49 -07:00
}
}
2013-03-08 21:54:08 -08:00
if ( BGFX_STATE_ALPHA_REF_MASK & changedFlags )
2012-08-05 14:51:49 -07:00
{
uint32_t ref = ( newFlags & BGFX_STATE_ALPHA_REF_MASK ) > > BGFX_STATE_ALPHA_REF_SHIFT ;
2014-12-27 19:00:41 -08:00
viewState . m_alphaRef = ref / 255.0f ;
2012-08-05 14:51:49 -07:00
}
if ( ( BGFX_STATE_PT_POINTS | BGFX_STATE_POINT_SIZE_MASK ) & changedFlags )
{
DX_CHECK ( device - > SetRenderState ( D3DRS_POINTSIZE , castfu ( ( float ) ( ( newFlags & BGFX_STATE_POINT_SIZE_MASK ) > > BGFX_STATE_POINT_SIZE_SHIFT ) ) ) ) ;
}
if ( BGFX_STATE_MSAA & changedFlags )
{
DX_CHECK ( device - > SetRenderState ( D3DRS_MULTISAMPLEANTIALIAS , ( newFlags & BGFX_STATE_MSAA ) = = BGFX_STATE_MSAA ) ) ;
}
if ( ( BGFX_STATE_ALPHA_WRITE | BGFX_STATE_RGB_WRITE ) & changedFlags )
{
uint32_t writeEnable = ( newFlags & BGFX_STATE_ALPHA_WRITE ) ? D3DCOLORWRITEENABLE_ALPHA : 0 ;
writeEnable | = ( newFlags & BGFX_STATE_RGB_WRITE ) ? D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE : 0 ;
DX_CHECK ( device - > SetRenderState ( D3DRS_COLORWRITEENABLE , writeEnable ) ) ;
}
2014-03-25 23:07:51 -07:00
if ( ( BGFX_STATE_BLEND_MASK | BGFX_STATE_BLEND_EQUATION_MASK ) & changedFlags
2014-07-20 20:27:13 -07:00
| | blendFactor ! = draw . m_rgba )
2012-08-05 14:51:49 -07:00
{
2014-03-25 23:07:51 -07:00
bool enabled = ! ! ( BGFX_STATE_BLEND_MASK & newFlags ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_ALPHABLENDENABLE , enabled ) ) ;
2012-08-05 14:51:49 -07:00
2014-03-25 23:07:51 -07:00
if ( enabled )
2012-08-05 14:51:49 -07:00
{
2014-03-25 23:07:51 -07:00
const uint32_t blend = uint32_t ( ( newFlags & BGFX_STATE_BLEND_MASK ) > > BGFX_STATE_BLEND_SHIFT ) ;
const uint32_t equation = uint32_t ( ( newFlags & BGFX_STATE_BLEND_EQUATION_MASK ) > > BGFX_STATE_BLEND_EQUATION_SHIFT ) ;
const uint32_t srcRGB = ( blend ) & 0xf ;
const uint32_t dstRGB = ( blend > > 4 ) & 0xf ;
const uint32_t srcA = ( blend > > 8 ) & 0xf ;
const uint32_t dstA = ( blend > > 12 ) & 0xf ;
const uint32_t equRGB = ( equation ) & 0x7 ;
const uint32_t equA = ( equation > > 3 ) & 0x7 ;
DX_CHECK ( device - > SetRenderState ( D3DRS_SRCBLEND , s_blendFactor [ srcRGB ] . m_src ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_DESTBLEND , s_blendFactor [ dstRGB ] . m_dst ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_BLENDOP , s_blendEquation [ equRGB ] ) ) ;
const bool separate = srcRGB ! = srcA | | dstRGB ! = dstA | | equRGB ! = equA ;
DX_CHECK ( device - > SetRenderState ( D3DRS_SEPARATEALPHABLENDENABLE , separate ) ) ;
if ( separate )
{
DX_CHECK ( device - > SetRenderState ( D3DRS_SRCBLENDALPHA , s_blendFactor [ srcA ] . m_src ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_DESTBLENDALPHA , s_blendFactor [ dstA ] . m_dst ) ) ;
DX_CHECK ( device - > SetRenderState ( D3DRS_BLENDOPALPHA , s_blendEquation [ equA ] ) ) ;
}
if ( ( s_blendFactor [ srcRGB ] . m_factor | | s_blendFactor [ dstRGB ] . m_factor )
2014-07-20 20:27:13 -07:00
& & blendFactor ! = draw . m_rgba )
2013-03-29 22:58:50 -07:00
{
2014-07-20 20:27:13 -07:00
const uint32_t rgba = draw . m_rgba ;
2014-03-25 23:07:51 -07:00
D3DCOLOR color = D3DCOLOR_RGBA ( rgba > > 24
, ( rgba > > 16 ) & 0xff
, ( rgba > > 8 ) & 0xff
, ( rgba ) & 0xff
) ;
2013-03-30 09:44:13 -07:00
DX_CHECK ( device - > SetRenderState ( D3DRS_BLENDFACTOR , color ) ) ;
2013-03-29 22:58:50 -07:00
}
2012-08-05 14:51:49 -07:00
}
2014-03-25 23:07:51 -07:00
2014-07-20 20:27:13 -07:00
blendFactor = draw . m_rgba ;
2012-08-05 14:51:49 -07:00
}
2014-05-26 14:09:26 -07:00
const uint64_t pt = _render - > m_debug & BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : newFlags & BGFX_STATE_PT_MASK ;
2014-04-26 23:48:41 -07:00
primIndex = uint8_t ( pt > > BGFX_STATE_PT_SHIFT ) ;
prim = s_primInfo [ primIndex ] ;
2012-08-05 14:51:49 -07:00
}
2012-09-16 17:36:08 -07:00
bool programChanged = false ;
2014-07-20 20:27:13 -07:00
bool constantsChanged = draw . m_constBegin < draw . m_constEnd ;
rendererUpdateUniforms ( this , _render - > m_constantBuffer , draw . m_constBegin , draw . m_constEnd ) ;
2012-08-05 14:51:49 -07:00
2012-09-16 17:36:08 -07:00
if ( key . m_program ! = programIdx )
2012-08-05 14:51:49 -07:00
{
2012-09-16 17:36:08 -07:00
programIdx = key . m_program ;
2012-08-05 14:51:49 -07:00
2012-09-16 17:36:08 -07:00
if ( invalidHandle = = programIdx )
2012-08-05 14:51:49 -07:00
{
device - > SetVertexShader ( NULL ) ;
device - > SetPixelShader ( NULL ) ;
}
else
{
2014-05-26 14:09:26 -07:00
ProgramD3D9 & program = m_program [ programIdx ] ;
2014-07-20 20:27:13 -07:00
device - > SetVertexShader ( program . m_vsh - > m_vertexShader ) ;
device - > SetPixelShader ( program . m_fsh - > m_pixelShader ) ;
2012-08-05 14:51:49 -07:00
}
2015-01-10 20:38:47 -08:00
programChanged =
2012-08-05 14:51:49 -07:00
constantsChanged = true ;
}
2012-09-16 17:36:08 -07:00
if ( invalidHandle ! = programIdx )
2012-08-05 14:51:49 -07:00
{
2014-05-26 14:09:26 -07:00
ProgramD3D9 & program = m_program [ programIdx ] ;
2012-08-05 14:51:49 -07:00
if ( constantsChanged )
{
2014-05-26 14:09:26 -07:00
ConstantBuffer * vcb = program . m_vsh - > m_constantBuffer ;
if ( NULL ! = vcb )
{
commit ( * vcb ) ;
}
ConstantBuffer * fcb = program . m_fsh - > m_constantBuffer ;
if ( NULL ! = fcb )
{
commit ( * fcb ) ;
}
2012-08-05 14:51:49 -07:00
}
2014-12-27 19:00:41 -08:00
viewState . setPredefined < 4 > ( this , view , 0 , program , _render , draw ) ;
2012-08-05 14:51:49 -07:00
}
{
2014-07-30 20:37:54 -07:00
for ( uint32_t stage = 0 ; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS ; + + stage )
2012-08-05 14:51:49 -07:00
{
2015-01-13 22:34:48 -08:00
const Binding & sampler = draw . m_bind [ stage ] ;
Binding & current = currentState . m_bind [ stage ] ;
2015-01-14 21:31:08 -08:00
if ( current . m_idx ! = sampler . m_idx
| | current . m_un . m_draw . m_flags ! = sampler . m_un . m_draw . m_flags
2012-09-16 17:36:08 -07:00
| | programChanged )
2012-08-05 14:51:49 -07:00
{
if ( invalidHandle ! = sampler . m_idx )
{
2015-01-14 21:31:08 -08:00
m_textures [ sampler . m_idx ] . commit ( stage , sampler . m_un . m_draw . m_flags ) ;
2012-08-05 14:51:49 -07:00
}
else
{
DX_CHECK ( device - > SetTexture ( stage , NULL ) ) ;
}
}
current = sampler ;
}
}
2013-07-25 23:13:48 -07:00
if ( programChanged
2014-07-20 20:27:13 -07:00
| | currentState . m_vertexBuffer . idx ! = draw . m_vertexBuffer . idx
| | currentState . m_instanceDataBuffer . idx ! = draw . m_instanceDataBuffer . idx
| | currentState . m_instanceDataOffset ! = draw . m_instanceDataOffset
| | currentState . m_instanceDataStride ! = draw . m_instanceDataStride )
2012-08-05 14:51:49 -07:00
{
2014-07-20 20:27:13 -07:00
currentState . m_vertexBuffer = draw . m_vertexBuffer ;
currentState . m_instanceDataBuffer . idx = draw . m_instanceDataBuffer . idx ;
currentState . m_instanceDataOffset = draw . m_instanceDataOffset ;
currentState . m_instanceDataStride = draw . m_instanceDataStride ;
2012-08-05 14:51:49 -07:00
2014-07-20 20:27:13 -07:00
uint16_t handle = draw . m_vertexBuffer . idx ;
2012-08-05 14:51:49 -07:00
if ( invalidHandle ! = handle )
{
2014-05-26 14:09:26 -07:00
const VertexBufferD3D9 & vb = m_vertexBuffers [ handle ] ;
2012-08-05 14:51:49 -07:00
2014-07-20 20:27:13 -07:00
uint16_t decl = ! isValid ( vb . m_decl ) ? draw . m_vertexDecl . idx : vb . m_decl . idx ;
2014-09-01 11:24:51 -07:00
const VertexDeclD3D9 & vertexDecl = m_vertexDecls [ decl ] ;
2012-08-05 14:51:49 -07:00
DX_CHECK ( device - > SetStreamSource ( 0 , vb . m_ptr , 0 , vertexDecl . m_decl . m_stride ) ) ;
2014-07-20 20:27:13 -07:00
if ( isValid ( draw . m_instanceDataBuffer )
2014-05-26 14:09:26 -07:00
& & m_instancing )
2012-08-05 14:51:49 -07:00
{
2014-07-20 20:27:13 -07:00
const VertexBufferD3D9 & inst = m_vertexBuffers [ draw . m_instanceDataBuffer . idx ] ;
DX_CHECK ( device - > SetStreamSourceFreq ( 0 , D3DSTREAMSOURCE_INDEXEDDATA | draw . m_numInstances ) ) ;
2014-06-14 18:11:54 -07:00
DX_CHECK ( device - > SetStreamSourceFreq ( 1 , UINT ( D3DSTREAMSOURCE_INSTANCEDATA | 1 ) ) ) ;
2014-07-20 20:27:13 -07:00
DX_CHECK ( device - > SetStreamSource ( 1 , inst . m_ptr , draw . m_instanceDataOffset , draw . m_instanceDataStride ) ) ;
2012-08-05 14:51:49 -07:00
2014-07-20 20:27:13 -07:00
IDirect3DVertexDeclaration9 * ptr = createVertexDeclaration ( vertexDecl . m_decl , draw . m_instanceDataStride / 16 ) ;
2012-08-05 14:51:49 -07:00
DX_CHECK ( device - > SetVertexDeclaration ( ptr ) ) ;
DX_RELEASE ( ptr , 0 ) ;
}
else
{
DX_CHECK ( device - > SetStreamSourceFreq ( 0 , 1 ) ) ;
DX_CHECK ( device - > SetStreamSource ( 1 , NULL , 0 , 0 ) ) ;
DX_CHECK ( device - > SetVertexDeclaration ( vertexDecl . m_ptr ) ) ;
}
}
else
{
DX_CHECK ( device - > SetStreamSource ( 0 , NULL , 0 , 0 ) ) ;
DX_CHECK ( device - > SetStreamSource ( 1 , NULL , 0 , 0 ) ) ;
}
}
2014-07-20 20:27:13 -07:00
if ( currentState . m_indexBuffer . idx ! = draw . m_indexBuffer . idx )
2012-08-05 14:51:49 -07:00
{
2014-07-20 20:27:13 -07:00
currentState . m_indexBuffer = draw . m_indexBuffer ;
2012-08-05 14:51:49 -07:00
2014-07-20 20:27:13 -07:00
uint16_t handle = draw . m_indexBuffer . idx ;
2012-08-05 14:51:49 -07:00
if ( invalidHandle ! = handle )
{
2014-05-26 14:09:26 -07:00
const IndexBufferD3D9 & ib = m_indexBuffers [ handle ] ;
2012-08-05 14:51:49 -07:00
DX_CHECK ( device - > SetIndices ( ib . m_ptr ) ) ;
}
else
{
DX_CHECK ( device - > SetIndices ( NULL ) ) ;
}
}
2013-09-29 21:33:50 -07:00
if ( isValid ( currentState . m_vertexBuffer ) )
2012-08-05 14:51:49 -07:00
{
2014-07-20 20:27:13 -07:00
uint32_t numVertices = draw . m_numVertices ;
2013-09-29 10:42:41 -07:00
if ( UINT32_MAX = = numVertices )
2012-08-05 14:51:49 -07:00
{
2014-05-26 14:09:26 -07:00
const VertexBufferD3D9 & vb = m_vertexBuffers [ currentState . m_vertexBuffer . idx ] ;
2014-07-20 20:27:13 -07:00
uint16_t decl = ! isValid ( vb . m_decl ) ? draw . m_vertexDecl . idx : vb . m_decl . idx ;
2014-09-01 11:24:51 -07:00
const VertexDeclD3D9 & vertexDecl = m_vertexDecls [ decl ] ;
2012-08-05 14:51:49 -07:00
numVertices = vb . m_size / vertexDecl . m_decl . m_stride ;
}
uint32_t numIndices = 0 ;
uint32_t numPrimsSubmitted = 0 ;
uint32_t numInstances = 0 ;
uint32_t numPrimsRendered = 0 ;
2014-07-20 20:27:13 -07:00
if ( isValid ( draw . m_indexBuffer ) )
2012-08-05 14:51:49 -07:00
{
2014-07-20 20:27:13 -07:00
if ( UINT32_MAX = = draw . m_numIndices )
2012-08-05 14:51:49 -07:00
{
2014-07-20 20:27:13 -07:00
numIndices = m_indexBuffers [ draw . m_indexBuffer . idx ] . m_size / 2 ;
2014-04-26 23:48:41 -07:00
numPrimsSubmitted = numIndices / prim . m_div - prim . m_sub ;
2014-07-20 20:27:13 -07:00
numInstances = draw . m_numInstances ;
numPrimsRendered = numPrimsSubmitted * draw . m_numInstances ;
2012-08-05 14:51:49 -07:00
2014-04-26 23:48:41 -07:00
DX_CHECK ( device - > DrawIndexedPrimitive ( prim . m_type
2014-07-20 20:27:13 -07:00
, draw . m_startVertex
2012-08-05 14:51:49 -07:00
, 0
, numVertices
, 0
, numPrimsSubmitted
) ) ;
}
2014-07-20 20:27:13 -07:00
else if ( prim . m_min < = draw . m_numIndices )
2012-08-05 14:51:49 -07:00
{
2014-07-20 20:27:13 -07:00
numIndices = draw . m_numIndices ;
2014-04-26 23:48:41 -07:00
numPrimsSubmitted = numIndices / prim . m_div - prim . m_sub ;
2014-07-20 20:27:13 -07:00
numInstances = draw . m_numInstances ;
numPrimsRendered = numPrimsSubmitted * draw . m_numInstances ;
2012-08-05 14:51:49 -07:00
2014-04-26 23:48:41 -07:00
DX_CHECK ( device - > DrawIndexedPrimitive ( prim . m_type
2014-07-20 20:27:13 -07:00
, draw . m_startVertex
2012-08-05 14:51:49 -07:00
, 0
, numVertices
2014-07-20 20:27:13 -07:00
, draw . m_startIndex
2012-08-05 14:51:49 -07:00
, numPrimsSubmitted
) ) ;
}
}
else
{
2014-04-26 23:48:41 -07:00
numPrimsSubmitted = numVertices / prim . m_div - prim . m_sub ;
2014-07-20 20:27:13 -07:00
numInstances = draw . m_numInstances ;
numPrimsRendered = numPrimsSubmitted * draw . m_numInstances ;
2013-01-21 21:49:42 -08:00
2014-04-26 23:48:41 -07:00
DX_CHECK ( device - > DrawPrimitive ( prim . m_type
2014-07-20 20:27:13 -07:00
, draw . m_startVertex
2012-08-05 14:51:49 -07:00
, numPrimsSubmitted
) ) ;
}
2014-04-26 23:48:41 -07:00
statsNumPrimsSubmitted [ primIndex ] + = numPrimsSubmitted ;
statsNumPrimsRendered [ primIndex ] + = numPrimsRendered ;
statsNumInstances [ primIndex ] + = numInstances ;
2012-08-05 14:51:49 -07:00
statsNumIndices + = numIndices ;
}
}
2014-05-26 14:09:26 -07:00
if ( 0 < _render - > m_num )
2013-01-01 13:19:10 -08:00
{
captureElapsed = - bx : : getHPCounter ( ) ;
2014-05-26 14:09:26 -07:00
capture ( ) ;
2013-01-01 13:19:10 -08:00
captureElapsed + = bx : : getHPCounter ( ) ;
}
2012-08-05 14:51:49 -07:00
}
2014-10-25 19:16:24 -07:00
PIX_ENDEVENT ( ) ;
2012-08-05 14:51:49 -07:00
int64_t now = bx : : getHPCounter ( ) ;
elapsed + = now ;
static int64_t last = now ;
int64_t frameTime = now - last ;
last = now ;
static int64_t min = frameTime ;
static int64_t max = frameTime ;
min = min > frameTime ? frameTime : min ;
max = max < frameTime ? frameTime : max ;
2014-05-26 14:09:26 -07:00
if ( _render - > m_debug & ( BGFX_DEBUG_IFH | BGFX_DEBUG_STATS ) )
2012-08-05 14:51:49 -07:00
{
2013-06-09 15:28:25 -07:00
PIX_BEGINEVENT ( D3DCOLOR_RGBA ( 0x40 , 0x40 , 0x40 , 0xff ) , L " debugstats " ) ;
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
TextVideoMem & tvm = m_textVideoMem ;
2012-08-05 14:51:49 -07:00
static int64_t next = now ;
if ( now > = next )
{
next = now + bx : : getHPFrequency ( ) ;
double freq = double ( bx : : getHPFrequency ( ) ) ;
double toMs = 1000.0 / freq ;
tvm . clear ( ) ;
2013-04-27 16:55:34 -07:00
uint16_t pos = 0 ;
2014-05-26 14:09:26 -07:00
tvm . printf ( 0 , pos + + , BGFX_CONFIG_DEBUG ? 0x89 : 0x8f , " %s / " BX_COMPILER_NAME " / " BX_CPU_NAME " / " BX_ARCH_NAME " / " BX_PLATFORM_NAME " "
, getRendererName ( )
) ;
2013-04-27 16:55:34 -07:00
2014-05-26 14:09:26 -07:00
const D3DADAPTER_IDENTIFIER9 & identifier = m_identifier ;
2013-04-27 18:03:40 -07:00
tvm . printf ( 0 , pos + + , 0x0f , " Device: %s (%s) " , identifier . Description , identifier . Driver ) ;
2013-04-27 16:55:34 -07:00
pos = 10 ;
2014-02-05 23:07:11 -08:00
tvm . printf ( 10 , pos + + , 0x8e , " Frame: %7.3f, % 7.3f \x1f , % 7.3f \x1e [ms] / % 6.2f FPS "
2012-08-05 14:51:49 -07:00
, double ( frameTime ) * toMs
, double ( min ) * toMs
, double ( max ) * toMs
, freq / frameTime
2014-02-05 23:07:11 -08:00
) ;
const uint32_t msaa = ( m_resolution . m_flags & BGFX_RESET_MSAA_MASK ) > > BGFX_RESET_MSAA_SHIFT ;
2015-01-21 20:39:42 -08:00
tvm . printf ( 10 , pos + + , 0x8e , " Reset flags: [%c] vsync, [%c] MSAAx%d, [%c] MaxAnisotropy "
2014-02-05 23:07:11 -08:00
, ! ! ( m_resolution . m_flags & BGFX_RESET_VSYNC ) ? ' \xfe ' : ' '
, 0 ! = msaa ? ' \xfe ' : ' '
, 1 < < msaa
2015-01-21 20:39:42 -08:00
, ! ! ( m_resolution . m_flags & BGFX_RESET_MAXANISOTROPY ) ? ' \xfe ' : ' '
2012-08-05 14:51:49 -07:00
) ;
2012-12-30 20:52:47 -08:00
double elapsedCpuMs = double ( elapsed ) * toMs ;
2015-03-26 22:43:50 -07:00
tvm . printf ( 10 , pos + + , 0x8e , " Submitted: %4d (draw %4d, compute %4d) / CPU %3.4f [ms] "
2014-05-26 14:09:26 -07:00
, _render - > m_num
2015-03-26 22:43:50 -07:00
, statsKeyType [ 0 ]
, statsKeyType [ 1 ]
2012-08-05 14:51:49 -07:00
, elapsedCpuMs
) ;
2014-09-01 11:24:51 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( s_primName ) ; + + ii )
2014-04-26 23:48:41 -07:00
{
2014-12-10 21:09:13 -08:00
tvm . printf ( 10 , pos + + , 0x8e , " %9s: %7d (#inst: %5d), submitted: %7d "
2014-04-26 23:48:41 -07:00
, s_primName [ ii ]
, statsNumPrimsRendered [ ii ]
, statsNumInstances [ ii ]
, statsNumPrimsSubmitted [ ii ]
) ;
}
2012-12-30 20:52:47 -08:00
2014-02-05 23:07:11 -08:00
tvm . printf ( 10 , pos + + , 0x8e , " Indices: %7d " , statsNumIndices ) ;
2014-05-26 14:09:26 -07:00
tvm . printf ( 10 , pos + + , 0x8e , " DVB size: %7d " , _render - > m_vboffset ) ;
tvm . printf ( 10 , pos + + , 0x8e , " DIB size: %7d " , _render - > m_iboffset ) ;
2012-08-05 14:51:49 -07:00
2014-04-26 23:48:41 -07:00
double captureMs = double ( captureElapsed ) * toMs ;
tvm . printf ( 10 , pos + + , 0x8e , " Capture: %3.4f [ms] " , captureMs ) ;
2012-08-05 14:51:49 -07:00
uint8_t attr [ 2 ] = { 0x89 , 0x8a } ;
2014-05-26 14:09:26 -07:00
uint8_t attrIndex = _render - > m_waitSubmit < _render - > m_waitRender ;
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
tvm . printf ( 10 , pos + + , attr [ attrIndex & 1 ] , " Submit wait: %3.4f [ms] " , _render - > m_waitSubmit * toMs ) ;
tvm . printf ( 10 , pos + + , attr [ ( attrIndex + 1 ) & 1 ] , " Render wait: %3.4f [ms] " , _render - > m_waitRender * toMs ) ;
2012-08-05 14:51:49 -07:00
min = frameTime ;
max = frameTime ;
}
2014-05-26 14:09:26 -07:00
blit ( this , _textVideoMemBlitter , tvm ) ;
2012-08-05 14:51:49 -07:00
PIX_ENDEVENT ( ) ;
}
2014-05-26 14:09:26 -07:00
else if ( _render - > m_debug & BGFX_DEBUG_TEXT )
2012-08-05 14:51:49 -07:00
{
2013-06-09 15:28:25 -07:00
PIX_BEGINEVENT ( D3DCOLOR_RGBA ( 0x40 , 0x40 , 0x40 , 0xff ) , L " debugtext " ) ;
2012-08-05 14:51:49 -07:00
2014-05-26 14:09:26 -07:00
blit ( this , _textVideoMemBlitter , _render - > m_textVideoMem ) ;
2012-08-05 14:51:49 -07:00
PIX_ENDEVENT ( ) ;
}
device - > EndScene ( ) ;
}
2015-03-21 22:11:59 -07:00
} /* namespace d3d9 */ } // namespace bgfx
2014-05-26 14:09:26 -07:00
# else
2015-03-21 22:11:59 -07:00
namespace bgfx { namespace d3d9
2014-05-26 14:09:26 -07:00
{
2015-03-21 22:11:59 -07:00
RendererContextI * rendererCreate ( )
2014-05-26 14:09:26 -07:00
{
return NULL ;
}
2015-03-21 22:11:59 -07:00
void rendererDestroy ( )
2014-05-26 14:09:26 -07:00
{
}
2015-03-21 22:11:59 -07:00
} /* namespace d3d9 */ } // namespace bgfx
2012-08-05 14:51:49 -07:00
# endif // BGFX_CONFIG_RENDERER_DIRECT3D9