2012-07-23 00:08:58 -04:00
/*
2015-01-01 18:04:46 -05:00
* Copyright 2011 - 2015 Branimir Karadzic . All rights reserved .
2012-07-23 00:08:58 -04:00
* License : http : //www.opensource.org/licenses/BSD-2-Clause
*/
# include "bgfx_p.h"
# if BGFX_CONFIG_RENDERER_DIRECT3D11
# include "renderer_d3d11.h"
2014-09-28 14:03:47 -04:00
2015-03-22 01:11:59 -04:00
namespace bgfx { namespace d3d11
2012-07-23 00:08:58 -04:00
{
2014-10-25 21:07:51 -04:00
static wchar_t s_viewNameW [ BGFX_CONFIG_MAX_VIEWS ] [ BGFX_CONFIG_MAX_VIEW_NAME ] ;
2013-06-09 18:28:25 -04:00
2014-04-27 02:48:41 -04:00
struct PrimInfo
2012-07-23 00:08:58 -04:00
{
2014-04-27 02:48:41 -04:00
D3D11_PRIMITIVE_TOPOLOGY m_type ;
uint32_t m_min ;
uint32_t m_div ;
uint32_t m_sub ;
} ;
static const PrimInfo s_primInfo [ ] =
{
{ D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST , 3 , 3 , 0 } ,
{ D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP , 3 , 1 , 2 } ,
{ D3D11_PRIMITIVE_TOPOLOGY_LINELIST , 2 , 2 , 0 } ,
2014-10-22 22:19:33 -04:00
{ D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP , 2 , 1 , 1 } ,
2014-04-27 02:48:41 -04:00
{ D3D11_PRIMITIVE_TOPOLOGY_POINTLIST , 1 , 1 , 0 } ,
2014-10-05 03:14:21 -04:00
{ D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED , 0 , 0 , 0 } ,
2014-04-27 02:48:41 -04:00
} ;
static const char * s_primName [ ] =
{
" TriList " ,
" TriStrip " ,
" Line " ,
2014-10-22 22:19:33 -04:00
" LineStrip " ,
2014-04-27 02:48:41 -04:00
" Point " ,
2012-07-23 00:08:58 -04:00
} ;
2014-09-01 14:24:51 -04:00
BX_STATIC_ASSERT ( BX_COUNTOF ( s_primInfo ) = = BX_COUNTOF ( s_primName ) + 1 ) ;
2012-07-23 00:08:58 -04:00
2014-12-20 00:09:58 -05:00
union Zero
{
2015-06-25 19:33:56 -04:00
Zero ( )
{
memset ( this , 0 , sizeof ( Zero ) ) ;
}
2014-12-20 00:09:58 -05:00
ID3D11Buffer * m_buffer [ D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT ] ;
ID3D11UnorderedAccessView * m_uav [ D3D11_PS_CS_UAV_REGISTER_COUNT ] ;
ID3D11ShaderResourceView * m_srv [ D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT ] ;
ID3D11SamplerState * m_sampler [ D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT ] ;
uint32_t m_zero [ D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT ] ;
} ;
2015-06-24 13:20:01 -04:00
BX_PRAGMA_DIAGNOSTIC_PUSH ( ) ;
BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC ( 4268 ) // warning C4268: '' : 'const' static/global data initialized with compiler generated default constructor fills the object with zeros
2015-06-22 23:45:50 -04:00
static const Zero s_zero ;
2015-06-24 13:20:01 -04:00
BX_PRAGMA_DIAGNOSTIC_POP ( ) ;
2014-12-20 00:09:58 -05:00
2013-04-11 00:42:00 -04:00
static const uint32_t s_checkMsaa [ ] =
{
0 ,
2 ,
4 ,
8 ,
16 ,
} ;
static DXGI_SAMPLE_DESC s_msaa [ ] =
{
{ 1 , 0 } ,
{ 2 , 0 } ,
{ 4 , 0 } ,
{ 8 , 0 } ,
{ 16 , 0 } ,
} ;
2012-07-24 01:42:51 -04:00
static const D3D11_BLEND s_blendFactor [ ] [ 2 ] =
2012-07-23 00:08:58 -04:00
{
2013-03-30 01:58:50 -04:00
{ ( D3D11_BLEND ) 0 , ( D3D11_BLEND ) 0 } , // ignored
2014-03-26 02:07:51 -04:00
{ D3D11_BLEND_ZERO , D3D11_BLEND_ZERO } , // ZERO
{ D3D11_BLEND_ONE , D3D11_BLEND_ONE } , // ONE
{ D3D11_BLEND_SRC_COLOR , D3D11_BLEND_SRC_ALPHA } , // SRC_COLOR
{ D3D11_BLEND_INV_SRC_COLOR , D3D11_BLEND_INV_SRC_ALPHA } , // INV_SRC_COLOR
{ D3D11_BLEND_SRC_ALPHA , D3D11_BLEND_SRC_ALPHA } , // SRC_ALPHA
{ D3D11_BLEND_INV_SRC_ALPHA , D3D11_BLEND_INV_SRC_ALPHA } , // INV_SRC_ALPHA
{ D3D11_BLEND_DEST_ALPHA , D3D11_BLEND_DEST_ALPHA } , // DST_ALPHA
{ D3D11_BLEND_INV_DEST_ALPHA , D3D11_BLEND_INV_DEST_ALPHA } , // INV_DST_ALPHA
{ D3D11_BLEND_DEST_COLOR , D3D11_BLEND_DEST_ALPHA } , // DST_COLOR
{ D3D11_BLEND_INV_DEST_COLOR , D3D11_BLEND_INV_DEST_ALPHA } , // INV_DST_COLOR
{ D3D11_BLEND_SRC_ALPHA_SAT , D3D11_BLEND_ONE } , // SRC_ALPHA_SAT
{ D3D11_BLEND_BLEND_FACTOR , D3D11_BLEND_BLEND_FACTOR } , // FACTOR
{ D3D11_BLEND_INV_BLEND_FACTOR , D3D11_BLEND_INV_BLEND_FACTOR } , // INV_FACTOR
2012-07-23 00:08:58 -04:00
} ;
2013-06-18 01:11:45 -04:00
static const D3D11_BLEND_OP s_blendEquation [ ] =
{
D3D11_BLEND_OP_ADD ,
D3D11_BLEND_OP_SUBTRACT ,
D3D11_BLEND_OP_REV_SUBTRACT ,
D3D11_BLEND_OP_MIN ,
D3D11_BLEND_OP_MAX ,
} ;
2014-02-23 14:21:23 -05:00
static const D3D11_COMPARISON_FUNC s_cmpFunc [ ] =
2012-11-10 22:59:23 -05:00
{
2013-10-19 01:34:23 -04:00
D3D11_COMPARISON_FUNC ( 0 ) , // ignored
2012-11-10 22:59:23 -05:00
D3D11_COMPARISON_LESS ,
D3D11_COMPARISON_LESS_EQUAL ,
D3D11_COMPARISON_EQUAL ,
D3D11_COMPARISON_GREATER_EQUAL ,
D3D11_COMPARISON_GREATER ,
D3D11_COMPARISON_NOT_EQUAL ,
D3D11_COMPARISON_NEVER ,
D3D11_COMPARISON_ALWAYS ,
} ;
static const D3D11_STENCIL_OP s_stencilOp [ ] =
{
D3D11_STENCIL_OP_ZERO ,
D3D11_STENCIL_OP_KEEP ,
D3D11_STENCIL_OP_REPLACE ,
D3D11_STENCIL_OP_INCR ,
D3D11_STENCIL_OP_INCR_SAT ,
D3D11_STENCIL_OP_DECR ,
D3D11_STENCIL_OP_DECR_SAT ,
D3D11_STENCIL_OP_INVERT ,
} ;
2012-07-23 00:08:58 -04:00
static const D3D11_CULL_MODE s_cullMode [ ] =
{
D3D11_CULL_NONE ,
D3D11_CULL_FRONT ,
D3D11_CULL_BACK ,
} ;
static const D3D11_TEXTURE_ADDRESS_MODE s_textureAddress [ ] =
{
D3D11_TEXTURE_ADDRESS_WRAP ,
D3D11_TEXTURE_ADDRESS_MIRROR ,
D3D11_TEXTURE_ADDRESS_CLAMP ,
} ;
2012-12-09 21:51:55 -05:00
/*
2013-02-22 00:07:31 -05:00
* D3D11_FILTER_MIN_MAG_MIP_POINT = 0x00 ,
* D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR = 0x01 ,
* D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x04 ,
* D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR = 0x05 ,
* D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT = 0x10 ,
* D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x11 ,
* D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT = 0x14 ,
* D3D11_FILTER_MIN_MAG_MIP_LINEAR = 0x15 ,
2012-12-09 21:51:55 -05:00
* D3D11_FILTER_ANISOTROPIC = 0x55 ,
*
2014-02-23 14:21:23 -05:00
* D3D11_COMPARISON_FILTERING_BIT = 0x80 ,
* D3D11_ANISOTROPIC_FILTERING_BIT = 0x40 ,
*
2012-12-09 21:51:55 -05:00
* According to D3D11_FILTER enum bits for mip , mag and mip are :
* 0x10 // MIN_LINEAR
* 0x04 // MAG_LINEAR
* 0x01 // MIP_LINEAR
*/
2015-04-07 20:58:14 -04:00
static const uint8_t s_textureFilter [ 3 ] [ 3 ] =
2012-12-09 21:51:55 -05:00
{
{
0x10 , // min linear
0x00 , // min point
2015-01-21 01:07:30 -05:00
0x55 , // anisotropic
2012-12-09 21:51:55 -05:00
} ,
{
0x04 , // mag linear
0x00 , // mag point
2015-01-21 01:07:30 -05:00
0x55 , // anisotropic
2012-12-09 21:51:55 -05:00
} ,
{
0x01 , // mip linear
0x00 , // mip point
2015-01-21 01:07:30 -05:00
0x55 , // anisotropic
2012-12-09 21:51:55 -05:00
} ,
} ;
2012-07-29 16:50:23 -04:00
struct TextureFormatInfo
{
DXGI_FORMAT m_fmt ;
2014-02-06 02:07:11 -05:00
DXGI_FORMAT m_fmtSrv ;
DXGI_FORMAT m_fmtDsv ;
2015-05-02 22:57:42 -04:00
DXGI_FORMAT m_fmtSrgb ;
2012-07-29 16:50:23 -04:00
} ;
2014-07-20 23:27:13 -04:00
static const TextureFormatInfo s_textureFormat [ ] =
2012-07-29 16:50:23 -04:00
{
2015-05-04 20:23:11 -04:00
{ DXGI_FORMAT_BC1_UNORM , DXGI_FORMAT_BC1_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_BC1_UNORM_SRGB } , // BC1
{ DXGI_FORMAT_BC2_UNORM , DXGI_FORMAT_BC2_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_BC2_UNORM_SRGB } , // BC2
{ DXGI_FORMAT_BC3_UNORM , DXGI_FORMAT_BC3_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_BC3_UNORM_SRGB } , // BC3
{ DXGI_FORMAT_BC4_UNORM , DXGI_FORMAT_BC4_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // BC4
{ DXGI_FORMAT_BC5_UNORM , DXGI_FORMAT_BC5_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // BC5
{ DXGI_FORMAT_BC6H_SF16 , DXGI_FORMAT_BC6H_SF16 , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // BC6H
{ DXGI_FORMAT_BC7_UNORM , DXGI_FORMAT_BC7_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_BC7_UNORM_SRGB } , // BC7
{ DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // ETC1
{ DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // ETC2
{ DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // ETC2A
{ DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // ETC2A1
{ DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // PTC12
{ DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // PTC14
{ DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // PTC12A
{ DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // PTC14A
{ DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // PTC22
{ DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // PTC24
{ DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // Unknown
{ DXGI_FORMAT_R1_UNORM , DXGI_FORMAT_R1_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // R1
{ DXGI_FORMAT_R8_UNORM , DXGI_FORMAT_R8_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // R8
{ DXGI_FORMAT_R16_UINT , DXGI_FORMAT_R16_UINT , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // R16
{ DXGI_FORMAT_R16_FLOAT , DXGI_FORMAT_R16_FLOAT , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // R16F
{ DXGI_FORMAT_R32_UINT , DXGI_FORMAT_R32_UINT , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // R32
{ DXGI_FORMAT_R32_FLOAT , DXGI_FORMAT_R32_FLOAT , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // R32F
{ DXGI_FORMAT_R8G8_UNORM , DXGI_FORMAT_R8G8_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // RG8
{ DXGI_FORMAT_R16G16_UNORM , DXGI_FORMAT_R16G16_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // RG16
{ DXGI_FORMAT_R16G16_FLOAT , DXGI_FORMAT_R16G16_FLOAT , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // RG16F
{ DXGI_FORMAT_R32G32_UINT , DXGI_FORMAT_R32G32_UINT , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // RG32
{ DXGI_FORMAT_R32G32_FLOAT , DXGI_FORMAT_R32G32_FLOAT , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // RG32F
{ DXGI_FORMAT_B8G8R8A8_UNORM , DXGI_FORMAT_B8G8R8A8_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_B8G8R8A8_UNORM_SRGB } , // BGRA8
{ DXGI_FORMAT_R8G8B8A8_UNORM , DXGI_FORMAT_R8G8B8A8_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_R8G8B8A8_UNORM_SRGB } , // RGBA8
{ DXGI_FORMAT_R16G16B16A16_UNORM , DXGI_FORMAT_R16G16B16A16_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // RGBA16
{ DXGI_FORMAT_R16G16B16A16_FLOAT , DXGI_FORMAT_R16G16B16A16_FLOAT , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // RGBA16F
{ DXGI_FORMAT_R32G32B32A32_UINT , DXGI_FORMAT_R32G32B32A32_UINT , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // RGBA32
{ DXGI_FORMAT_R32G32B32A32_FLOAT , DXGI_FORMAT_R32G32B32A32_FLOAT , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // RGBA32F
{ DXGI_FORMAT_B5G6R5_UNORM , DXGI_FORMAT_B5G6R5_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // R5G6B5
{ DXGI_FORMAT_B4G4R4A4_UNORM , DXGI_FORMAT_B4G4R4A4_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // RGBA4
{ DXGI_FORMAT_B5G5R5A1_UNORM , DXGI_FORMAT_B5G5R5A1_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // RGB5A1
{ DXGI_FORMAT_R10G10B10A2_UNORM , DXGI_FORMAT_R10G10B10A2_UNORM , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // RGB10A2
{ DXGI_FORMAT_R11G11B10_FLOAT , DXGI_FORMAT_R11G11B10_FLOAT , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // R11G11B10F
{ DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , // UnknownDepth
{ DXGI_FORMAT_R16_TYPELESS , DXGI_FORMAT_R16_UNORM , DXGI_FORMAT_D16_UNORM , DXGI_FORMAT_UNKNOWN } , // D16
2015-05-02 22:57:42 -04:00
{ DXGI_FORMAT_R24G8_TYPELESS , DXGI_FORMAT_R24_UNORM_X8_TYPELESS , DXGI_FORMAT_D24_UNORM_S8_UINT , DXGI_FORMAT_UNKNOWN } , // D24
{ DXGI_FORMAT_R24G8_TYPELESS , DXGI_FORMAT_R24_UNORM_X8_TYPELESS , DXGI_FORMAT_D24_UNORM_S8_UINT , DXGI_FORMAT_UNKNOWN } , // D24S8
{ DXGI_FORMAT_R24G8_TYPELESS , DXGI_FORMAT_R24_UNORM_X8_TYPELESS , DXGI_FORMAT_D24_UNORM_S8_UINT , DXGI_FORMAT_UNKNOWN } , // D32
2015-05-04 20:23:11 -04:00
{ DXGI_FORMAT_R32_TYPELESS , DXGI_FORMAT_R32_FLOAT , DXGI_FORMAT_D32_FLOAT , DXGI_FORMAT_UNKNOWN } , // D16F
{ DXGI_FORMAT_R32_TYPELESS , DXGI_FORMAT_R32_FLOAT , DXGI_FORMAT_D32_FLOAT , DXGI_FORMAT_UNKNOWN } , // D24F
{ DXGI_FORMAT_R32_TYPELESS , DXGI_FORMAT_R32_FLOAT , DXGI_FORMAT_D32_FLOAT , DXGI_FORMAT_UNKNOWN } , // D32F
2015-05-02 22:57:42 -04:00
{ DXGI_FORMAT_R24G8_TYPELESS , DXGI_FORMAT_R24_UNORM_X8_TYPELESS , DXGI_FORMAT_D24_UNORM_S8_UINT , DXGI_FORMAT_UNKNOWN } , // D0S8
2012-07-29 16:50:23 -04:00
} ;
2014-07-20 23:27:13 -04:00
BX_STATIC_ASSERT ( TextureFormat : : Count = = BX_COUNTOF ( s_textureFormat ) ) ;
2012-07-29 16:50:23 -04:00
2014-08-05 01:01:20 -04:00
static const D3D11_INPUT_ELEMENT_DESC s_attrib [ ] =
2012-07-23 00:08:58 -04:00
{
{ " POSITION " , 0 , DXGI_FORMAT_R32G32B32_FLOAT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
{ " NORMAL " , 0 , DXGI_FORMAT_R32G32B32_FLOAT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
2012-10-28 00:34:41 -04:00
{ " TANGENT " , 0 , DXGI_FORMAT_R32G32B32_FLOAT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
2014-08-17 20:20:15 -04:00
{ " BITANGENT " , 0 , DXGI_FORMAT_R32G32B32_FLOAT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
2012-07-23 00:08:58 -04:00
{ " COLOR " , 0 , DXGI_FORMAT_R8G8B8A8_UINT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
{ " COLOR " , 1 , DXGI_FORMAT_R8G8B8A8_UINT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
{ " BLENDINDICES " , 0 , DXGI_FORMAT_R8G8B8A8_UINT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
{ " BLENDWEIGHT " , 0 , DXGI_FORMAT_R32G32B32_FLOAT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
{ " TEXCOORD " , 0 , DXGI_FORMAT_R32G32_FLOAT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
{ " TEXCOORD " , 1 , DXGI_FORMAT_R32G32_FLOAT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
{ " TEXCOORD " , 2 , DXGI_FORMAT_R32G32_FLOAT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
{ " TEXCOORD " , 3 , DXGI_FORMAT_R32G32_FLOAT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
{ " TEXCOORD " , 4 , DXGI_FORMAT_R32G32_FLOAT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
{ " TEXCOORD " , 5 , DXGI_FORMAT_R32G32_FLOAT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
{ " TEXCOORD " , 6 , DXGI_FORMAT_R32G32_FLOAT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
{ " TEXCOORD " , 7 , DXGI_FORMAT_R32G32_FLOAT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_VERTEX_DATA , 0 } ,
} ;
2014-08-05 01:01:20 -04:00
BX_STATIC_ASSERT ( Attrib : : Count = = BX_COUNTOF ( s_attrib ) ) ;
2012-07-23 00:08:58 -04:00
2014-10-05 03:14:21 -04:00
static const DXGI_FORMAT s_attribType [ ] [ 4 ] [ 2 ] =
2012-11-03 16:12:26 -04:00
{
2015-08-04 22:03:56 -04:00
{ // Uint8
2012-11-03 16:12:26 -04:00
{ DXGI_FORMAT_R8_UINT , DXGI_FORMAT_R8_UNORM } ,
{ DXGI_FORMAT_R8G8_UINT , DXGI_FORMAT_R8G8_UNORM } ,
{ DXGI_FORMAT_R8G8B8A8_UINT , DXGI_FORMAT_R8G8B8A8_UNORM } ,
{ DXGI_FORMAT_R8G8B8A8_UINT , DXGI_FORMAT_R8G8B8A8_UNORM } ,
} ,
2015-08-04 22:03:56 -04:00
{ // Uint10
{ DXGI_FORMAT_R10G10B10A2_UINT , DXGI_FORMAT_R10G10B10A2_UNORM } ,
{ DXGI_FORMAT_R10G10B10A2_UINT , DXGI_FORMAT_R10G10B10A2_UNORM } ,
{ DXGI_FORMAT_R10G10B10A2_UINT , DXGI_FORMAT_R10G10B10A2_UNORM } ,
{ DXGI_FORMAT_R10G10B10A2_UINT , DXGI_FORMAT_R10G10B10A2_UNORM } ,
} ,
{ // Int16
2013-02-23 22:02:51 -05:00
{ DXGI_FORMAT_R16_SINT , DXGI_FORMAT_R16_SNORM } ,
{ DXGI_FORMAT_R16G16_SINT , DXGI_FORMAT_R16G16_SNORM } ,
{ DXGI_FORMAT_R16G16B16A16_SINT , DXGI_FORMAT_R16G16B16A16_SNORM } ,
{ DXGI_FORMAT_R16G16B16A16_SINT , DXGI_FORMAT_R16G16B16A16_SNORM } ,
2012-11-03 16:12:26 -04:00
} ,
2015-08-04 22:03:56 -04:00
{ // Half
2012-11-03 16:12:26 -04:00
{ DXGI_FORMAT_R16_FLOAT , DXGI_FORMAT_R16_FLOAT } ,
{ DXGI_FORMAT_R16G16_FLOAT , DXGI_FORMAT_R16G16_FLOAT } ,
{ DXGI_FORMAT_R16G16B16A16_FLOAT , DXGI_FORMAT_R16G16B16A16_FLOAT } ,
{ DXGI_FORMAT_R16G16B16A16_FLOAT , DXGI_FORMAT_R16G16B16A16_FLOAT } ,
} ,
2015-08-04 22:03:56 -04:00
{ // Float
2012-11-03 16:12:26 -04:00
{ DXGI_FORMAT_R32_FLOAT , DXGI_FORMAT_R32_FLOAT } ,
{ DXGI_FORMAT_R32G32_FLOAT , DXGI_FORMAT_R32G32_FLOAT } ,
{ DXGI_FORMAT_R32G32B32_FLOAT , DXGI_FORMAT_R32G32B32_FLOAT } ,
{ DXGI_FORMAT_R32G32B32A32_FLOAT , DXGI_FORMAT_R32G32B32A32_FLOAT } ,
} ,
} ;
2014-10-05 03:14:21 -04:00
BX_STATIC_ASSERT ( AttribType : : Count = = BX_COUNTOF ( s_attribType ) ) ;
2012-11-03 16:12:26 -04:00
2013-03-26 00:13:54 -04:00
static D3D11_INPUT_ELEMENT_DESC * fillVertexDecl ( D3D11_INPUT_ELEMENT_DESC * _out , const VertexDecl & _decl )
2012-07-23 00:08:58 -04:00
{
D3D11_INPUT_ELEMENT_DESC * elem = _out ;
for ( uint32_t attr = 0 ; attr < Attrib : : Count ; + + attr )
{
if ( 0xff ! = _decl . m_attributes [ attr ] )
{
memcpy ( elem , & s_attrib [ attr ] , sizeof ( D3D11_INPUT_ELEMENT_DESC ) ) ;
2012-08-29 01:59:48 -04:00
if ( 0 = = _decl . m_attributes [ attr ] )
2012-07-23 00:08:58 -04:00
{
2012-08-29 01:59:48 -04:00
elem - > AlignedByteOffset = 0 ;
}
else
{
uint8_t num ;
AttribType : : Enum type ;
bool normalized ;
2012-12-31 21:48:52 -05:00
bool asInt ;
_decl . decode ( Attrib : : Enum ( attr ) , num , type , normalized , asInt ) ;
2012-11-03 16:12:26 -04:00
elem - > Format = s_attribType [ type ] [ num - 1 ] [ normalized ] ;
2012-08-29 01:59:48 -04:00
elem - > AlignedByteOffset = _decl . m_offset [ attr ] ;
2012-07-23 00:08:58 -04:00
}
+ + elem ;
}
}
return elem ;
}
2012-08-05 17:51:49 -04:00
struct TextureStage
{
TextureStage ( )
2012-11-25 21:24:50 -05:00
{
clear ( ) ;
}
void clear ( )
2012-08-05 17:51:49 -04:00
{
memset ( m_srv , 0 , sizeof ( m_srv ) ) ;
memset ( m_sampler , 0 , sizeof ( m_sampler ) ) ;
}
2014-07-30 23:37:54 -04:00
ID3D11ShaderResourceView * m_srv [ BGFX_CONFIG_MAX_TEXTURE_SAMPLERS ] ;
ID3D11SamplerState * m_sampler [ BGFX_CONFIG_MAX_TEXTURE_SAMPLERS ] ;
2012-08-05 17:51:49 -04:00
} ;
2014-10-18 18:44:45 -04:00
BX_PRAGMA_DIAGNOSTIC_PUSH ( ) ;
BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG ( " -Wunused-const-variable " ) ;
BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG ( " -Wunneeded-internal-declaration " ) ;
2014-10-16 22:54:29 -04:00
2012-11-25 21:24:50 -05:00
static const GUID WKPDID_D3DDebugObjectName = { 0x429b8c22 , 0x9188 , 0x4b0c , { 0x87 , 0x42 , 0xac , 0xb0 , 0xbf , 0x85 , 0xc2 , 0x00 } } ;
2015-01-12 23:46:50 -05:00
static const GUID IID_ID3D11Texture2D = { 0x6f15aaf2 , 0xd208 , 0x4e89 , { 0x9a , 0xb4 , 0x48 , 0x95 , 0x35 , 0xd3 , 0x4f , 0x9c } } ;
static const GUID IID_IDXGIFactory = { 0x7b7166ec , 0x21c7 , 0x44ae , { 0xb2 , 0x1a , 0xc9 , 0xae , 0x32 , 0x1a , 0xe3 , 0x69 } } ;
static const GUID IID_IDXGIDevice0 = { 0x54ec77fa , 0x1377 , 0x44e6 , { 0x8c , 0x32 , 0x88 , 0xfd , 0x5f , 0x44 , 0xc8 , 0x4c } } ;
static const GUID IID_IDXGIDevice1 = { 0x77db970f , 0x6276 , 0x48ba , { 0xba , 0x28 , 0x07 , 0x01 , 0x43 , 0xb4 , 0x39 , 0x2c } } ;
static const GUID IID_IDXGIDevice2 = { 0x05008617 , 0xfbfd , 0x4051 , { 0xa7 , 0x90 , 0x14 , 0x48 , 0x84 , 0xb4 , 0xf6 , 0xa9 } } ;
static const GUID IID_IDXGIDevice3 = { 0x6007896c , 0x3244 , 0x4afd , { 0xbf , 0x18 , 0xa6 , 0xd3 , 0xbe , 0xda , 0x50 , 0x23 } } ;
static const GUID IID_IDXGIAdapter = { 0x2411e7e1 , 0x12ac , 0x4ccf , { 0xbd , 0x14 , 0x97 , 0x98 , 0xe8 , 0x53 , 0x4d , 0xc0 } } ;
2015-02-04 22:33:31 -05:00
static const GUID IID_ID3D11InfoQueue = { 0x6543dbb6 , 0x1b48 , 0x42f5 , { 0xab , 0x82 , 0xe9 , 0x7e , 0xc7 , 0x43 , 0x26 , 0xf6 } } ;
2015-05-08 14:49:18 -04:00
static const GUID IID_IDXGIDeviceRenderDoc = { 0xa7aa6116 , 0x9c8d , 0x4bba , { 0x90 , 0x83 , 0xb4 , 0xd8 , 0x16 , 0xb7 , 0x1b , 0x78 } } ;
2015-01-12 23:46:50 -05:00
2015-04-24 12:33:36 -04:00
enum D3D11_FORMAT_SUPPORT2
{
D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD = 0x40 ,
D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE = 0x80 ,
} ;
2015-01-12 23:46:50 -05:00
static const GUID s_deviceIIDs [ ] =
{
IID_IDXGIDevice3 ,
IID_IDXGIDevice2 ,
IID_IDXGIDevice1 ,
IID_IDXGIDevice0 ,
} ;
2012-11-25 21:24:50 -05:00
template < typename Ty >
static BX_NO_INLINE void setDebugObjectName ( Ty * _interface , const char * _format , . . . )
{
2014-03-05 01:20:37 -05:00
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG_OBJECT_NAME ) )
{
char temp [ 2048 ] ;
va_list argList ;
va_start ( argList , _format ) ;
int size = bx : : uint32_min ( sizeof ( temp ) - 1 , vsnprintf ( temp , sizeof ( temp ) , _format , argList ) ) ;
va_end ( argList ) ;
temp [ size ] = ' \0 ' ;
_interface - > SetPrivateData ( WKPDID_D3DDebugObjectName , size , temp ) ;
}
2012-11-25 21:24:50 -05:00
}
2014-10-18 18:44:45 -04:00
BX_PRAGMA_DIAGNOSTIC_POP ( ) ;
2014-10-16 22:54:29 -04:00
2014-07-30 00:29:38 -04:00
static BX_NO_INLINE bool getIntelExtensions ( ID3D11Device * _device )
{
uint8_t temp [ 28 ] ;
D3D11_BUFFER_DESC desc ;
desc . ByteWidth = sizeof ( temp ) ;
desc . Usage = D3D11_USAGE_STAGING ;
desc . BindFlags = 0 ;
desc . CPUAccessFlags = D3D11_CPU_ACCESS_READ ;
desc . MiscFlags = 0 ;
desc . StructureByteStride = 0 ;
D3D11_SUBRESOURCE_DATA initData ;
initData . pSysMem = & temp ;
initData . SysMemPitch = sizeof ( temp ) ;
initData . SysMemSlicePitch = 0 ;
bx : : StaticMemoryBlockWriter writer ( & temp , sizeof ( temp ) ) ;
bx : : write ( & writer , " INTCEXTNCAPSFUNC " , 16 ) ;
bx : : write ( & writer , UINT32_C ( 0x00010000 ) ) ;
bx : : write ( & writer , UINT32_C ( 0 ) ) ;
bx : : write ( & writer , UINT32_C ( 0 ) ) ;
ID3D11Buffer * buffer ;
HRESULT hr = _device - > CreateBuffer ( & desc , & initData , & buffer ) ;
if ( SUCCEEDED ( hr ) )
{
buffer - > Release ( ) ;
bx : : MemoryReader reader ( & temp , sizeof ( temp ) ) ;
bx : : skip ( & reader , 16 ) ;
uint32_t version ;
bx : : read ( & reader , version ) ;
uint32_t driverVersion ;
bx : : read ( & reader , driverVersion ) ;
return version < = driverVersion ;
}
return false ;
} ;
2014-10-07 01:10:55 -04:00
# if USE_D3D11_DYNAMIC_LIB
2015-07-29 17:49:24 -04:00
static PFN_D3D11_CREATE_DEVICE D3D11CreateDevice ;
static PFN_CREATE_DXGI_FACTORY CreateDXGIFactory ;
static PFN_D3DPERF_SET_MARKER D3DPERF_SetMarker ;
static PFN_D3DPERF_BEGIN_EVENT D3DPERF_BeginEvent ;
static PFN_D3DPERF_END_EVENT D3DPERF_EndEvent ;
static PFN_GET_DEBUG_INTERFACE DXGIGetDebugInterface ;
static PFN_GET_DEBUG_INTERFACE1 DXGIGetDebugInterface1 ;
2014-10-07 01:10:55 -04:00
# endif // USE_D3D11_DYNAMIC_LIB
2014-05-26 17:09:26 -04:00
struct RendererContextD3D11 : public RendererContextI
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
RendererContextD3D11 ( )
2015-04-20 19:22:40 -04:00
: m_d3d9dll ( NULL )
, m_d3d11dll ( NULL )
, m_dxgidll ( NULL )
2015-07-29 17:49:24 -04:00
, m_dxgidebugdll ( NULL )
2015-04-20 19:22:40 -04:00
, m_renderdocdll ( NULL )
, m_driverType ( D3D_DRIVER_TYPE_NULL )
, m_featureLevel ( D3D_FEATURE_LEVEL ( 0 ) )
, m_adapter ( NULL )
, m_factory ( NULL )
, m_swapChain ( NULL )
2014-10-29 01:08:55 -04:00
, m_lost ( 0 )
2015-04-20 19:22:40 -04:00
, m_numWindows ( 0 )
, m_device ( NULL )
, m_deviceCtx ( NULL )
2015-04-29 20:18:51 -04:00
, m_infoQueue ( NULL )
2014-10-29 01:08:55 -04:00
, m_backBufferColor ( NULL )
, m_backBufferDepthStencil ( NULL )
2015-04-20 19:22:40 -04:00
, m_currentColor ( NULL )
, m_currentDepthStencil ( NULL )
2014-10-01 00:16:24 -04:00
, m_captureTexture ( NULL )
2013-01-08 02:10:15 -05:00
, m_captureResolve ( NULL )
, m_wireframe ( false )
2014-02-06 02:07:11 -05:00
, m_flags ( BGFX_RESET_NONE )
2015-01-21 23:39:42 -05:00
, m_maxAnisotropy ( 1 )
2015-04-20 19:22:40 -04:00
, m_currentProgram ( NULL )
2012-08-05 17:51:49 -04:00
, m_vsChanges ( 0 )
2012-07-23 00:08:58 -04:00
, m_fsChanges ( 0 )
2014-02-06 02:07:11 -05:00
, m_rtMsaa ( false )
2014-10-29 01:08:55 -04:00
, m_ovrRtv ( NULL )
, m_ovrDsv ( NULL )
2014-10-14 00:14:51 -04:00
{
2015-04-20 19:22:40 -04:00
m_fbh . idx = invalidHandle ;
memset ( & m_adapterDesc , 0 , sizeof ( m_adapterDesc ) ) ;
memset ( & m_scd , 0 , sizeof ( m_scd ) ) ;
memset ( & m_windows , 0xff , sizeof ( m_windows ) ) ;
2014-10-14 00:14:51 -04:00
}
~ RendererContextD3D11 ( )
{
}
2015-07-30 21:36:12 -04:00
bool init ( )
2012-07-23 00:08:58 -04:00
{
2015-07-30 21:36:12 -04:00
uint32_t errorState = 0 ;
2014-10-29 01:08:55 -04:00
// Must be before device creation, and before RenderDoc.
m_ovr . init ( ) ;
if ( ! m_ovr . isInitialized ( ) )
{
m_renderdocdll = loadRenderDoc ( ) ;
}
2014-09-26 01:41:53 -04:00
2014-02-06 02:07:11 -05:00
m_fbh . idx = invalidHandle ;
2014-04-15 22:10:56 -04:00
memset ( m_uniforms , 0 , sizeof ( m_uniforms ) ) ;
2014-05-26 17:09:26 -04:00
memset ( & m_resolution , 0 , sizeof ( m_resolution ) ) ;
2012-07-23 00:08:58 -04:00
2014-08-05 01:01:20 -04:00
# if USE_D3D11_DYNAMIC_LIB
2013-07-27 01:55:13 -04:00
m_d3d11dll = bx : : dlopen ( " d3d11.dll " ) ;
2015-07-30 21:36:12 -04:00
BX_WARN ( NULL ! = m_d3d11dll , " Failed to load d3d11.dll. " ) ;
if ( NULL = = m_d3d11dll )
{
goto error ;
}
errorState = 1 ;
2012-07-23 00:08:58 -04:00
2014-10-07 01:10:55 -04:00
m_d3d9dll = NULL ;
2014-03-05 01:20:37 -05:00
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG_PIX ) )
{
// D3D11_1.h has ID3DUserDefinedAnnotation
// http://msdn.microsoft.com/en-us/library/windows/desktop/hh446881%28v=vs.85%29.aspx
m_d3d9dll = bx : : dlopen ( " d3d9.dll " ) ;
2015-07-30 21:36:12 -04:00
if ( NULL ! = m_d3d9dll )
{
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. "
) ;
}
2014-03-05 01:20:37 -05:00
}
2013-06-09 18:28:25 -04:00
2014-10-07 01:10:55 -04:00
D3D11CreateDevice = ( PFN_D3D11_CREATE_DEVICE ) bx : : dlsym ( m_d3d11dll , " D3D11CreateDevice " ) ;
2015-07-30 21:36:12 -04:00
BX_WARN ( NULL ! = D3D11CreateDevice , " Function D3D11CreateDevice not found. " ) ;
if ( NULL = = D3D11CreateDevice )
{
goto error ;
}
2012-07-23 00:08:58 -04:00
2013-07-27 01:55:13 -04:00
m_dxgidll = bx : : dlopen ( " dxgi.dll " ) ;
2015-07-30 21:36:12 -04:00
BX_WARN ( NULL ! = m_dxgidll , " Failed to load dxgi.dll. " ) ;
if ( NULL = = m_dxgidll )
{
goto error ;
}
errorState = 2 ;
2013-04-27 21:03:40 -04:00
2014-10-07 01:10:55 -04:00
CreateDXGIFactory = ( PFN_CREATE_DXGI_FACTORY ) bx : : dlsym ( m_dxgidll , " CreateDXGIFactory " ) ;
2015-07-30 21:36:12 -04:00
BX_WARN ( NULL ! = CreateDXGIFactory , " Function CreateDXGIFactory not found. " ) ;
if ( NULL = = CreateDXGIFactory )
{
goto error ;
}
2015-07-29 17:49:24 -04:00
m_dxgidebugdll = bx : : dlopen ( " dxgidebug.dll " ) ;
if ( NULL ! = m_dxgidebugdll )
{
DXGIGetDebugInterface = ( PFN_GET_DEBUG_INTERFACE ) bx : : dlsym ( m_dxgidebugdll , " DXGIGetDebugInterface " ) ;
DXGIGetDebugInterface1 = ( PFN_GET_DEBUG_INTERFACE1 ) bx : : dlsym ( m_dxgidebugdll , " DXGIGetDebugInterface1 " ) ;
if ( NULL = = DXGIGetDebugInterface
& & NULL = = DXGIGetDebugInterface1 )
{
bx : : dlclose ( m_dxgidebugdll ) ;
m_dxgidebugdll = NULL ;
}
else
{
// Figure out how to access IDXGIInfoQueue on pre Win8...
}
}
2014-08-05 01:01:20 -04:00
# endif // USE_D3D11_DYNAMIC_LIB
2013-04-27 21:03:40 -04:00
2012-07-23 00:08:58 -04:00
HRESULT hr ;
2013-04-27 21:03:40 -04:00
IDXGIFactory * factory ;
2014-11-14 08:22:32 -05:00
# if BX_PLATFORM_WINRT
2014-12-04 22:56:19 -05:00
// WinRT requires the IDXGIFactory2 interface, which isn't supported on older platforms
2014-11-14 08:22:32 -05:00
hr = CreateDXGIFactory1 ( __uuidof ( IDXGIFactory2 ) , ( void * * ) & factory ) ;
# else
2014-12-24 05:46:49 -05:00
hr = CreateDXGIFactory ( IID_IDXGIFactory , ( void * * ) & factory ) ;
2014-11-14 08:22:32 -05:00
# endif // BX_PLATFORM_WINRT
2015-07-30 21:36:12 -04:00
BX_WARN ( SUCCEEDED ( hr ) , " Unable to create DXGI factory. " ) ;
if ( FAILED ( hr ) )
{
goto error ;
}
errorState = 3 ;
2013-04-27 21:03:40 -04:00
2015-04-20 19:22:40 -04:00
m_device = ( ID3D11Device * ) g_platformData . context ;
2013-04-27 21:03:40 -04:00
2015-04-20 19:22:40 -04:00
if ( NULL = = m_device )
2013-04-27 21:03:40 -04:00
{
2015-04-20 19:22:40 -04:00
m_adapter = NULL ;
2015-04-24 17:57:00 -04:00
m_driverType = BGFX_PCI_ID_SOFTWARE_RASTERIZER = = g_caps . vendorId
? D3D_DRIVER_TYPE_WARP
: D3D_DRIVER_TYPE_HARDWARE
;
2015-03-26 18:01:47 -04:00
2015-04-20 19:22:40 -04:00
IDXGIAdapter * adapter ;
for ( uint32_t ii = 0
; DXGI_ERROR_NOT_FOUND ! = factory - > EnumAdapters ( ii , & adapter ) & & ii < BX_COUNTOF ( g_caps . gpu )
; + + ii
)
{
DXGI_ADAPTER_DESC desc ;
hr = adapter - > GetDesc ( & desc ) ;
if ( SUCCEEDED ( hr ) )
2015-03-26 18:01:47 -04:00
{
2015-04-20 19:22:40 -04:00
BX_TRACE ( " Adapter #%d " , ii ) ;
char description [ BX_COUNTOF ( desc . Description ) ] ;
wcstombs ( description , desc . Description , BX_COUNTOF ( desc . Description ) ) ;
BX_TRACE ( " \t Description: %s " , description ) ;
BX_TRACE ( " \t VendorId: 0x%08x, DeviceId: 0x%08x, SubSysId: 0x%08x, Revision: 0x%08x "
, desc . VendorId
, desc . DeviceId
, desc . SubSysId
, desc . Revision
) ;
BX_TRACE ( " \t Memory: % " PRIi64 " (video), % " PRIi64 " (system), % " PRIi64 " (shared) "
, desc . DedicatedVideoMemory
, desc . DedicatedSystemMemory
, desc . SharedSystemMemory
) ;
g_caps . gpu [ ii ] . vendorId = ( uint16_t ) desc . VendorId ;
g_caps . gpu [ ii ] . deviceId = ( uint16_t ) desc . DeviceId ;
+ + g_caps . numGPUs ;
if ( NULL = = m_adapter )
2015-04-01 01:01:50 -04:00
{
2015-04-20 19:22:40 -04: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 = adapter ;
m_adapter - > AddRef ( ) ;
m_driverType = D3D_DRIVER_TYPE_UNKNOWN ;
}
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG_PERFHUD )
& & 0 ! = strstr ( description , " PerfHUD " ) )
{
m_adapter = adapter ;
m_driverType = D3D_DRIVER_TYPE_REFERENCE ;
}
2015-04-01 01:01:50 -04:00
}
2013-04-27 21:03:40 -04:00
}
2015-04-20 19:22:40 -04:00
DX_RELEASE ( adapter , adapter = = m_adapter ? 1 : 0 ) ;
}
DX_RELEASE ( factory , NULL ! = m_adapter ? 1 : 0 ) ;
2013-04-27 21:03:40 -04:00
2015-04-20 19:22:40 -04:00
D3D_FEATURE_LEVEL features [ ] =
{
D3D_FEATURE_LEVEL_11_1 ,
D3D_FEATURE_LEVEL_11_0 ,
D3D_FEATURE_LEVEL_10_1 ,
D3D_FEATURE_LEVEL_10_0 ,
D3D_FEATURE_LEVEL_9_3 ,
D3D_FEATURE_LEVEL_9_2 ,
D3D_FEATURE_LEVEL_9_1 ,
} ;
2012-07-23 00:08:58 -04:00
2015-04-24 17:57:00 -04:00
for ( ; ; )
2015-01-12 23:46:50 -05:00
{
2015-04-24 17:57:00 -04:00
uint32_t flags = 0
| D3D11_CREATE_DEVICE_SINGLETHREADED
| D3D11_CREATE_DEVICE_BGRA_SUPPORT
| ( BX_ENABLED ( BGFX_CONFIG_DEBUG ) ? D3D11_CREATE_DEVICE_DEBUG : 0 )
;
hr = E_FAIL ;
for ( uint32_t ii = 0 ; ii < 3 & & FAILED ( hr ) ; )
{
hr = D3D11CreateDevice ( m_adapter
, m_driverType
, NULL
, flags
, & features [ ii ]
, BX_COUNTOF ( features ) - ii
, D3D11_SDK_VERSION
, & m_device
, & m_featureLevel
, & m_deviceCtx
) ;
if ( FAILED ( hr )
& & 0 ! = ( flags & D3D11_CREATE_DEVICE_DEBUG ) )
{
// Try without debug in case D3D11 SDK Layers
// is not present?
flags & = ~ D3D11_CREATE_DEVICE_DEBUG ;
continue ;
}
2015-04-29 20:18:51 -04:00
// Enable debug flags.
flags | = ( BX_ENABLED ( BGFX_CONFIG_DEBUG ) ? D3D11_CREATE_DEVICE_DEBUG : 0 ) ;
2015-04-24 17:57:00 -04:00
+ + ii ;
}
2015-04-20 19:22:40 -04:00
if ( FAILED ( hr )
2015-04-24 17:57:00 -04:00
& & D3D_DRIVER_TYPE_WARP ! = m_driverType )
2015-04-20 19:22:40 -04:00
{
2015-04-24 17:57:00 -04:00
// Try with WARP
m_driverType = D3D_DRIVER_TYPE_WARP ;
2015-04-20 19:22:40 -04:00
continue ;
}
2015-04-24 17:57:00 -04:00
break ;
2015-01-12 23:46:50 -05:00
}
2015-07-30 21:36:12 -04:00
BX_WARN ( SUCCEEDED ( hr ) , " Unable to create Direct3D11 device. " ) ;
if ( FAILED ( hr ) )
{
goto error ;
}
errorState = 4 ;
2015-01-12 23:46:50 -05:00
2015-04-20 19:22:40 -04:00
if ( NULL ! = m_adapter )
{
DX_RELEASE ( m_adapter , 2 ) ;
}
2014-11-18 00:35:53 -05:00
}
2015-04-20 19:22:40 -04:00
else
2015-03-26 18:01:47 -04:00
{
2015-04-20 19:22:40 -04:00
m_device - > GetImmediateContext ( & m_deviceCtx ) ;
2015-07-30 21:36:12 -04:00
BX_WARN ( NULL ! = m_deviceCtx , " Unable to create Direct3D11 device. " ) ;
if ( NULL = = m_deviceCtx )
{
goto error ;
}
errorState = 4 ;
2015-03-26 18:01:47 -04:00
}
2015-01-12 23:46:50 -05:00
{
2015-07-31 20:34:33 -04:00
IDXGIDevice * device = NULL ;
IDXGIAdapter * adapter = NULL ;
hr = E_FAIL ;
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( s_deviceIIDs ) & & FAILED ( hr ) ; + + ii )
2015-04-07 23:41:16 -04:00
{
2015-07-31 20:34:33 -04:00
hr = m_device - > QueryInterface ( s_deviceIIDs [ ii ] , ( void * * ) & device ) ;
BX_TRACE ( " D3D device 11.%d, hr %x " , BX_COUNTOF ( s_deviceIIDs ) - 1 - ii , hr ) ;
if ( SUCCEEDED ( hr ) )
{
2015-04-08 17:16:02 -04:00
# if BX_COMPILER_MSVC
2015-04-07 23:41:16 -04:00
BX_PRAGMA_DIAGNOSTIC_PUSH ( ) ;
BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC ( 4530 ) // warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
2015-07-31 20:34:33 -04:00
try
{
// QueryInterface above can succeed, but getting adapter call might crash on Win7.
hr = device - > GetAdapter ( & adapter ) ;
}
catch ( . . . )
{
BX_TRACE ( " Failed to get adapter foro IID_IDXGIDevice%d. " , BX_COUNTOF ( s_deviceIIDs ) - 1 - ii ) ;
DX_RELEASE ( device , 0 ) ;
hr = E_FAIL ;
}
2015-04-07 23:41:16 -04:00
BX_PRAGMA_DIAGNOSTIC_POP ( ) ;
2015-04-08 17:16:02 -04:00
# else
2015-07-31 20:34:33 -04:00
hr = device - > GetAdapter ( & adapter ) ;
2015-04-08 17:16:02 -04:00
# endif // BX_COMPILER_MSVC
2015-07-31 20:34:33 -04:00
}
2015-04-07 23:41:16 -04:00
}
2013-04-27 21:03:40 -04:00
2015-07-30 21:36:12 -04:00
BX_WARN ( SUCCEEDED ( hr ) , " Unable to create Direct3D11 device. " ) ;
if ( FAILED ( hr ) )
{
goto error ;
}
2015-04-20 19:22:40 -04:00
2015-07-31 20:34:33 -04:00
// GPA increases device ref count.
// RenderDoc makes device ref count 0 here.
//
// This causes assert in debug. When debugger is present refcount
// checks are off.
IDXGIDevice * renderdoc ;
hr = m_device - > QueryInterface ( IID_IDXGIDeviceRenderDoc , ( void * * ) & renderdoc ) ;
if ( SUCCEEDED ( hr ) )
{
setGraphicsDebuggerPresent ( true ) ;
DX_RELEASE ( renderdoc , 2 ) ;
}
else
{
setGraphicsDebuggerPresent ( 3 ! = getRefCount ( device ) ) ;
DX_RELEASE ( device , 2 ) ;
}
hr = adapter - > GetDesc ( & m_adapterDesc ) ;
2015-07-30 21:36:12 -04:00
BX_WARN ( SUCCEEDED ( hr ) , " Unable to create Direct3D11 device. " ) ;
if ( FAILED ( hr ) )
{
2015-07-31 20:34:33 -04:00
DX_RELEASE ( adapter , 2 ) ;
2015-07-30 21:36:12 -04:00
goto error ;
}
2015-04-20 19:22:40 -04:00
2015-07-31 20:34:33 -04:00
g_caps . vendorId = 0 = = m_adapterDesc . VendorId
? BGFX_PCI_ID_SOFTWARE_RASTERIZER
: ( uint16_t ) m_adapterDesc . VendorId
;
g_caps . deviceId = ( uint16_t ) m_adapterDesc . DeviceId ;
if ( NULL = = g_platformData . backBuffer )
{
# if BX_PLATFORM_WINRT
hr = adapter - > GetParent ( __uuidof ( IDXGIFactory2 ) , ( void * * ) & m_factory ) ;
BX_WARN ( SUCCEEDED ( hr ) , " Unable to create Direct3D11 device. " ) ;
DX_RELEASE ( adapter , 2 ) ;
if ( FAILED ( hr ) )
{
goto error ;
}
memset ( & m_scd , 0 , sizeof ( m_scd ) ) ;
m_scd . Width = BGFX_DEFAULT_WIDTH ;
m_scd . Height = BGFX_DEFAULT_HEIGHT ;
m_scd . Format = DXGI_FORMAT_R8G8B8A8_UNORM ;
m_scd . Stereo = false ;
m_scd . SampleDesc . Count = 1 ;
m_scd . SampleDesc . Quality = 0 ;
m_scd . BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT ;
m_scd . BufferCount = 2 ;
m_scd . Scaling = DXGI_SCALING_NONE ;
m_scd . SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL ;
m_scd . AlphaMode = DXGI_ALPHA_MODE_IGNORE ;
hr = m_factory - > CreateSwapChainForCoreWindow ( m_device
, ( : : IUnknown * ) g_platformData . nwh
, & m_scd
, NULL
, & m_swapChain
) ;
# else
hr = adapter - > GetParent ( IID_IDXGIFactory , ( void * * ) & m_factory ) ;
BX_WARN ( SUCCEEDED ( hr ) , " Unable to create Direct3D11 device. " ) ;
DX_RELEASE ( adapter , 2 ) ;
if ( FAILED ( hr ) )
{
goto error ;
}
memset ( & m_scd , 0 , sizeof ( m_scd ) ) ;
m_scd . BufferDesc . Width = BGFX_DEFAULT_WIDTH ;
m_scd . BufferDesc . Height = BGFX_DEFAULT_HEIGHT ;
m_scd . BufferDesc . RefreshRate . Numerator = 60 ;
m_scd . BufferDesc . RefreshRate . Denominator = 1 ;
m_scd . BufferDesc . Format = DXGI_FORMAT_R8G8B8A8_UNORM ;
m_scd . SampleDesc . Count = 1 ;
m_scd . SampleDesc . Quality = 0 ;
m_scd . BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT ;
m_scd . BufferCount = 1 ;
m_scd . OutputWindow = ( HWND ) g_platformData . nwh ;
m_scd . Windowed = true ;
hr = m_factory - > CreateSwapChain ( m_device
, & m_scd
, & m_swapChain
) ;
DX_CHECK ( m_factory - > MakeWindowAssociation ( ( HWND ) g_platformData . nwh , 0
| DXGI_MWA_NO_WINDOW_CHANGES
| DXGI_MWA_NO_ALT_ENTER
) ) ;
2015-04-09 23:03:59 -04:00
# endif // BX_PLATFORM_WINRT
2015-07-31 20:34:33 -04:00
BX_WARN ( SUCCEEDED ( hr ) , " Failed to create swap chain. " ) ;
if ( FAILED ( hr ) )
{
goto error ;
}
errorState = 5 ;
}
else
2015-07-30 21:36:12 -04:00
{
2015-07-31 20:34:33 -04:00
memset ( & m_scd , 0 , sizeof ( m_scd ) ) ;
m_scd . SampleDesc . Count = 1 ;
m_scd . SampleDesc . Quality = 0 ;
setBufferSize ( BGFX_DEFAULT_WIDTH , BGFX_DEFAULT_HEIGHT ) ;
m_backBufferColor = ( ID3D11RenderTargetView * ) g_platformData . backBuffer ;
m_backBufferDepthStencil = ( ID3D11DepthStencilView * ) g_platformData . backBufferDS ;
2015-07-30 21:36:12 -04:00
}
2015-04-20 19:22:40 -04:00
}
2015-02-22 23:30:17 -05:00
2014-09-07 20:17:38 -04:00
m_numWindows = 1 ;
2015-03-31 20:15:17 -04:00
# if !defined(__MINGW32__)
2014-04-27 02:48:41 -04:00
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG ) )
{
2015-04-29 20:18:51 -04:00
hr = m_device - > QueryInterface ( IID_ID3D11InfoQueue , ( void * * ) & m_infoQueue ) ;
2014-04-27 02:48:41 -04:00
2014-07-29 22:26:08 -04:00
if ( SUCCEEDED ( hr ) )
{
2015-04-29 20:18:51 -04:00
m_infoQueue - > SetBreakOnSeverity ( D3D11_MESSAGE_SEVERITY_CORRUPTION , true ) ;
2015-07-29 17:49:24 -04:00
m_infoQueue - > SetBreakOnSeverity ( D3D11_MESSAGE_SEVERITY_ERROR , true ) ;
2015-04-29 20:18:51 -04:00
m_infoQueue - > SetBreakOnSeverity ( D3D11_MESSAGE_SEVERITY_WARNING , false ) ;
2014-04-27 02:48:41 -04:00
2014-07-29 22:26:08 -04:00
D3D11_INFO_QUEUE_FILTER filter ;
memset ( & filter , 0 , sizeof ( filter ) ) ;
2014-04-27 02:48:41 -04:00
2015-01-05 23:59:58 -05:00
D3D11_MESSAGE_CATEGORY catlist [ ] =
2014-07-29 22:26:08 -04:00
{
D3D11_MESSAGE_CATEGORY_STATE_SETTING ,
D3D11_MESSAGE_CATEGORY_EXECUTION ,
} ;
2015-01-05 23:59:58 -05:00
filter . DenyList . NumCategories = BX_COUNTOF ( catlist ) ;
filter . DenyList . pCategoryList = catlist ;
2015-04-29 20:18:51 -04:00
m_infoQueue - > PushStorageFilter ( & filter ) ;
2014-07-29 22:26:08 -04:00
2015-04-29 20:18:51 -04:00
DX_RELEASE ( m_infoQueue , 3 ) ;
2014-07-29 22:26:08 -04:00
}
2014-04-27 02:48:41 -04:00
}
2015-03-31 20:15:17 -04:00
# endif // __MINGW__
2015-04-16 19:24:05 -04:00
{
2015-07-30 21:36:12 -04:00
UniformHandle handle = BGFX_INVALID_HANDLE ;
for ( uint32_t ii = 0 ; ii < PredefinedUniform : : Count ; + + ii )
{
m_uniformReg . add ( handle , getPredefinedUniformName ( PredefinedUniform : : Enum ( ii ) ) , & m_predefinedUniforms [ ii ] ) ;
}
2015-04-16 19:24:05 -04:00
2015-07-30 21:36:12 -04:00
g_caps . supported | = ( 0
| BGFX_CAPS_TEXTURE_3D
| BGFX_CAPS_VERTEX_ATTRIB_HALF
2015-08-04 22:03:56 -04:00
| BGFX_CAPS_VERTEX_ATTRIB_UINT10
2015-07-30 21:36:12 -04:00
| BGFX_CAPS_FRAGMENT_DEPTH
| ( getIntelExtensions ( m_device ) ? BGFX_CAPS_FRAGMENT_ORDERING : 0 )
| BGFX_CAPS_SWAP_CHAIN
| ( m_ovr . isInitialized ( ) ? BGFX_CAPS_HMD : 0 )
| BGFX_CAPS_DRAW_INDIRECT
) ;
2015-04-16 19:24:05 -04:00
2015-07-30 21:36:12 -04:00
if ( m_featureLevel < = D3D_FEATURE_LEVEL_9_2 )
2015-04-16 22:47:13 -04:00
{
2015-07-30 21:36:12 -04:00
g_caps . maxTextureSize = D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION ;
g_caps . maxFBAttachments = uint8_t ( bx : : uint32_min ( D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT , BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS ) ) ;
}
else if ( m_featureLevel = = D3D_FEATURE_LEVEL_9_3 )
2015-04-16 19:24:05 -04:00
{
2015-07-30 21:36:12 -04:00
g_caps . maxTextureSize = D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION ;
g_caps . maxFBAttachments = uint8_t ( bx : : uint32_min ( D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT , BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS ) ) ;
}
else
{
g_caps . supported | = BGFX_CAPS_TEXTURE_COMPARE_ALL ;
g_caps . maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION ;
g_caps . maxFBAttachments = uint8_t ( bx : : uint32_min ( D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT , BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS ) ) ;
2015-04-16 19:24:05 -04:00
}
2015-07-30 21:36:12 -04:00
// 32-bit indices only supported on 9_2+.
if ( m_featureLevel > = D3D_FEATURE_LEVEL_9_2 )
2015-04-16 22:47:13 -04:00
{
2015-07-30 21:36:12 -04:00
g_caps . supported | = BGFX_CAPS_INDEX32 ;
}
2015-04-16 22:47:13 -04:00
2015-07-30 21:36:12 -04:00
// Independent blend only supported on 10_1+.
if ( m_featureLevel > = D3D_FEATURE_LEVEL_10_1 )
2015-04-16 19:24:05 -04:00
{
2015-07-30 21:36:12 -04:00
g_caps . supported | = BGFX_CAPS_BLEND_INDEPENDENT ;
2015-04-16 19:24:05 -04:00
}
2015-07-30 21:36:12 -04:00
// Compute support is optional on 10_0 and 10_1 targets.
if ( m_featureLevel = = D3D_FEATURE_LEVEL_10_0
| | m_featureLevel = = D3D_FEATURE_LEVEL_10_1 )
2015-04-16 22:47:13 -04:00
{
2015-07-30 21:36:12 -04:00
struct D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS
{
BOOL ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x ;
} ;
2015-04-16 22:47:13 -04:00
2015-07-30 21:36:12 -04:00
D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS data ;
hr = m_device - > CheckFeatureSupport ( D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS , & data , sizeof ( data ) ) ;
if ( SUCCEEDED ( hr )
& & data . ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x )
{
g_caps . supported | = BGFX_CAPS_COMPUTE ;
}
}
else if ( m_featureLevel > = D3D_FEATURE_LEVEL_11_0 )
2015-04-16 19:24:05 -04:00
{
2015-07-30 21:36:12 -04:00
g_caps . supported | = BGFX_CAPS_COMPUTE ;
2015-04-16 19:24:05 -04:00
}
2013-10-10 21:29:57 -04:00
2015-07-30 21:36:12 -04:00
// Instancing fully supported on 9_3+, optionally partially supported at lower levels.
if ( m_featureLevel > = D3D_FEATURE_LEVEL_9_3 )
{
g_caps . supported | = BGFX_CAPS_INSTANCING ;
}
else
{
struct D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT
{
BOOL SimpleInstancingSupported ;
} ;
2015-03-12 00:52:10 -04:00
2015-07-30 21:36:12 -04:00
D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT data ;
hr = m_device - > CheckFeatureSupport ( D3D11_FEATURE ( 11 ) /*D3D11_FEATURE_D3D9_SIMPLE_INSTANCING_SUPPORT*/ , & data , sizeof ( data ) ) ;
if ( SUCCEEDED ( hr )
& & data . SimpleInstancingSupported )
{
g_caps . supported | = BGFX_CAPS_INSTANCING ;
}
}
2015-05-04 20:23:11 -04:00
2015-07-30 21:36:12 -04:00
// shadow compare is optional on 9_1 through 9_3 targets
if ( m_featureLevel < = D3D_FEATURE_LEVEL_9_3 )
2015-03-12 00:52:10 -04:00
{
2015-07-30 21:36:12 -04:00
struct D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT
2015-04-16 22:47:13 -04:00
{
2015-07-30 21:36:12 -04:00
BOOL SupportsDepthAsTextureWithLessEqualComparisonFilter ;
2015-04-16 22:47:13 -04:00
} ;
2015-07-30 21:36:12 -04:00
D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT data ;
hr = m_device - > CheckFeatureSupport ( D3D11_FEATURE ( 9 ) /*D3D11_FEATURE_D3D9_SHADOW_SUPPORT*/ , & data , sizeof ( data ) ) ;
if ( SUCCEEDED ( hr )
& & data . SupportsDepthAsTextureWithLessEqualComparisonFilter )
2015-03-13 14:48:27 -04:00
{
2015-07-30 21:36:12 -04:00
g_caps . supported | = BGFX_CAPS_TEXTURE_COMPARE_LEQUAL ;
}
}
2015-03-13 14:48:27 -04:00
2015-07-30 21:36:12 -04:00
for ( uint32_t ii = 0 ; ii < TextureFormat : : Count ; + + ii )
{
uint8_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE ;
2015-04-21 18:44:16 -04:00
2015-07-30 21:36:12 -04:00
const DXGI_FORMAT fmt = isDepth ( TextureFormat : : Enum ( ii ) )
? s_textureFormat [ ii ] . m_fmtDsv
: s_textureFormat [ ii ] . m_fmt
;
const DXGI_FORMAT fmtSrgb = s_textureFormat [ ii ] . m_fmtSrgb ;
2015-05-18 15:39:42 -04:00
2015-07-30 21:36:12 -04:00
if ( DXGI_FORMAT_UNKNOWN ! = fmt )
2015-03-13 14:48:27 -04:00
{
2015-07-30 21:36:12 -04:00
struct D3D11_FEATURE_DATA_FORMAT_SUPPORT
{
DXGI_FORMAT InFormat ;
UINT OutFormatSupport ;
} ;
D3D11_FEATURE_DATA_FORMAT_SUPPORT data ; // D3D11_FEATURE_DATA_FORMAT_SUPPORT2
data . InFormat = fmt ;
hr = m_device - > CheckFeatureSupport ( D3D11_FEATURE_FORMAT_SUPPORT , & data , sizeof ( data ) ) ;
if ( SUCCEEDED ( hr ) )
{
support | = 0 ! = ( data . OutFormatSupport & ( 0
| D3D11_FORMAT_SUPPORT_TEXTURE2D
| D3D11_FORMAT_SUPPORT_TEXTURE3D
| D3D11_FORMAT_SUPPORT_TEXTURECUBE
) )
? BGFX_CAPS_FORMAT_TEXTURE_COLOR
: BGFX_CAPS_FORMAT_TEXTURE_NONE
;
support | = 0 ! = ( data . OutFormatSupport & ( 0
| D3D11_FORMAT_SUPPORT_BUFFER
| D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER
| D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER
) )
? BGFX_CAPS_FORMAT_TEXTURE_VERTEX
: BGFX_CAPS_FORMAT_TEXTURE_NONE
;
support | = 0 ! = ( data . OutFormatSupport & ( 0
| D3D11_FORMAT_SUPPORT_SHADER_LOAD
) )
? BGFX_CAPS_FORMAT_TEXTURE_IMAGE
: BGFX_CAPS_FORMAT_TEXTURE_NONE
;
support | = 0 ! = ( data . OutFormatSupport & ( 0
| D3D11_FORMAT_SUPPORT_RENDER_TARGET
| D3D11_FORMAT_SUPPORT_DEPTH_STENCIL
) )
? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER
: BGFX_CAPS_FORMAT_TEXTURE_NONE
;
}
else
{
BX_TRACE ( " CheckFeatureSupport failed with %x for format %s. " , hr , getName ( TextureFormat : : Enum ( ii ) ) ) ;
}
if ( 0 ! = ( support & BGFX_CAPS_FORMAT_TEXTURE_IMAGE ) )
{
// clear image flag for additional testing
support & = ~ BGFX_CAPS_FORMAT_TEXTURE_IMAGE ;
data . InFormat = s_textureFormat [ ii ] . m_fmt ;
hr = m_device - > CheckFeatureSupport ( D3D11_FEATURE_FORMAT_SUPPORT2 , & data , sizeof ( data ) ) ;
if ( SUCCEEDED ( hr ) )
{
support | = 0 ! = ( data . OutFormatSupport & ( 0
| D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD
| D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE
) )
? BGFX_CAPS_FORMAT_TEXTURE_IMAGE
: BGFX_CAPS_FORMAT_TEXTURE_NONE
;
}
}
2015-03-13 14:48:27 -04:00
}
2015-04-21 18:44:16 -04:00
2015-07-30 21:36:12 -04:00
if ( DXGI_FORMAT_UNKNOWN ! = fmtSrgb )
2015-04-21 18:44:16 -04:00
{
2015-07-30 21:36:12 -04:00
struct D3D11_FEATURE_DATA_FORMAT_SUPPORT
{
DXGI_FORMAT InFormat ;
UINT OutFormatSupport ;
} ;
2015-04-21 18:44:16 -04:00
2015-07-30 21:36:12 -04:00
D3D11_FEATURE_DATA_FORMAT_SUPPORT data ; // D3D11_FEATURE_DATA_FORMAT_SUPPORT2
data . InFormat = fmtSrgb ;
hr = m_device - > CheckFeatureSupport ( D3D11_FEATURE_FORMAT_SUPPORT , & data , sizeof ( data ) ) ;
2015-04-21 18:44:16 -04:00
if ( SUCCEEDED ( hr ) )
{
support | = 0 ! = ( data . OutFormatSupport & ( 0
2015-07-30 21:36:12 -04:00
| D3D11_FORMAT_SUPPORT_TEXTURE2D
| D3D11_FORMAT_SUPPORT_TEXTURE3D
| D3D11_FORMAT_SUPPORT_TEXTURECUBE
2015-04-21 18:44:16 -04:00
) )
2015-07-30 21:36:12 -04:00
? BGFX_CAPS_FORMAT_TEXTURE_COLOR_SRGB
2015-04-21 18:44:16 -04:00
: BGFX_CAPS_FORMAT_TEXTURE_NONE
;
}
2015-07-30 21:36:12 -04:00
else
{
BX_TRACE ( " CheckFeatureSupport failed with %x for sRGB format %s. " , hr , getName ( TextureFormat : : Enum ( ii ) ) ) ;
}
2015-04-21 18:44:16 -04:00
}
2015-07-30 21:36:12 -04:00
g_caps . formats [ ii ] = support ;
2015-03-12 00:52:10 -04:00
}
2015-07-30 21:36:12 -04:00
// Init reserved part of view name.
for ( uint32_t ii = 0 ; ii < BGFX_CONFIG_MAX_VIEWS ; + + ii )
2015-05-04 20:23:11 -04:00
{
2015-07-30 21:36:12 -04:00
char name [ BGFX_CONFIG_MAX_VIEW_NAME_RESERVED + 1 ] ;
bx : : snprintf ( name , sizeof ( name ) , " %3d " , ii ) ;
mbstowcs ( s_viewNameW [ ii ] , name , BGFX_CONFIG_MAX_VIEW_NAME_RESERVED ) ;
}
2015-05-04 20:23:11 -04:00
2015-07-30 21:36:12 -04:00
# if !defined(__MINGW32__)
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG )
& & NULL ! = m_infoQueue )
{
m_infoQueue - > SetBreakOnSeverity ( D3D11_MESSAGE_SEVERITY_ERROR , true ) ;
2015-05-04 20:23:11 -04:00
}
2015-07-30 21:36:12 -04:00
# endif // !defined(__MINGW32__)
2015-05-04 20:23:11 -04:00
2015-07-30 21:36:12 -04:00
updateMsaa ( ) ;
postReset ( ) ;
2014-07-27 23:44:02 -04:00
}
2015-07-30 21:36:12 -04:00
return true ;
2014-10-25 21:07:51 -04:00
2015-07-30 21:36:12 -04:00
error :
switch ( errorState )
2015-04-29 20:18:51 -04:00
{
2015-07-30 21:36:12 -04:00
default :
case 5 :
DX_RELEASE ( m_swapChain , 0 ) ;
case 4 :
DX_RELEASE ( m_deviceCtx , 0 ) ;
DX_RELEASE ( m_device , 0 ) ;
case 3 :
DX_RELEASE ( m_factory , 0 ) ;
case 2 :
# if USE_D3D11_DYNAMIC_LIB
if ( NULL ! = m_dxgidebugdll )
{
bx : : dlclose ( m_dxgidebugdll ) ;
m_dxgidebugdll = NULL ;
}
if ( NULL ! = m_d3d9dll )
{
bx : : dlclose ( m_d3d9dll ) ;
m_d3d9dll = NULL ;
}
bx : : dlclose ( m_dxgidll ) ;
m_dxgidll = NULL ;
# endif // USE_D3D11_DYNAMIC_LIB
case 1 :
# if USE_D3D11_DYNAMIC_LIB
bx : : dlclose ( m_d3d11dll ) ;
m_d3d11dll = NULL ;
# endif // USE_D3D11_DYNAMIC_LIB
case 0 :
unloadRenderDoc ( m_renderdocdll ) ;
m_ovr . shutdown ( ) ;
break ;
2015-04-29 20:18:51 -04:00
}
2015-07-30 21:36:12 -04:00
return false ;
2012-07-23 00:08:58 -04:00
}
2014-10-14 00:14:51 -04:00
void shutdown ( )
2012-07-23 00:08:58 -04:00
{
2012-08-05 17:51:49 -04:00
preReset ( ) ;
2014-10-29 01:08:55 -04:00
m_ovr . shutdown ( ) ;
2012-08-05 17:51:49 -04:00
2012-07-24 01:29:20 -04:00
m_deviceCtx - > ClearState ( ) ;
2012-07-23 00:08:58 -04:00
invalidateCache ( ) ;
2013-08-07 00:04:28 -04:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_indexBuffers ) ; + + ii )
2012-07-23 00:08:58 -04:00
{
m_indexBuffers [ ii ] . destroy ( ) ;
}
2013-08-07 00:04:28 -04:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_vertexBuffers ) ; + + ii )
2012-07-23 00:08:58 -04:00
{
m_vertexBuffers [ ii ] . destroy ( ) ;
}
2014-03-29 22:42:57 -04:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_shaders ) ; + + ii )
2012-07-23 00:08:58 -04:00
{
2014-03-29 22:42:57 -04:00
m_shaders [ ii ] . destroy ( ) ;
2012-07-23 00:08:58 -04:00
}
2013-08-07 00:04:28 -04:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_textures ) ; + + ii )
2012-07-23 00:08:58 -04:00
{
m_textures [ ii ] . destroy ( ) ;
}
DX_RELEASE ( m_swapChain , 0 ) ;
DX_RELEASE ( m_deviceCtx , 0 ) ;
2015-04-17 13:55:47 -04:00
DX_RELEASE ( m_device , 0 ) ;
2015-07-30 21:36:12 -04:00
DX_RELEASE ( m_factory , 0 ) ;
2012-07-23 00:08:58 -04:00
2014-09-26 01:41:53 -04:00
unloadRenderDoc ( m_renderdocdll ) ;
2014-08-05 01:01:20 -04:00
# if USE_D3D11_DYNAMIC_LIB
2015-07-29 17:49:24 -04:00
if ( NULL ! = m_dxgidebugdll )
{
bx : : dlclose ( m_dxgidebugdll ) ;
m_dxgidebugdll = NULL ;
}
2015-07-30 21:36:12 -04:00
if ( NULL ! = m_d3d9dll )
{
bx : : dlclose ( m_d3d9dll ) ;
m_d3d9dll = NULL ;
}
2013-07-27 01:55:13 -04:00
bx : : dlclose ( m_dxgidll ) ;
2015-07-29 17:49:24 -04:00
m_dxgidll = NULL ;
2013-07-27 01:55:13 -04:00
bx : : dlclose ( m_d3d11dll ) ;
2015-07-29 17:49:24 -04:00
m_d3d11dll = NULL ;
2014-08-05 01:01:20 -04:00
# endif // USE_D3D11_DYNAMIC_LIB
2012-07-23 00:08:58 -04:00
}
2014-05-26 17:09:26 -04:00
RendererType : : Enum getRendererType ( ) const BX_OVERRIDE
{
return RendererType : : Direct3D11 ;
}
const char * getRendererName ( ) const BX_OVERRIDE
{
return BGFX_RENDERER_DIRECT3D11_NAME ;
}
2015-05-14 14:37:32 -04:00
void createIndexBuffer ( IndexBufferHandle _handle , Memory * _mem , uint16_t _flags ) BX_OVERRIDE
2014-05-26 17:09:26 -04:00
{
2015-01-10 23:56:38 -05:00
m_indexBuffers [ _handle . idx ] . create ( _mem - > size , _mem - > data , _flags ) ;
2014-05-26 17:09:26 -04:00
}
void destroyIndexBuffer ( IndexBufferHandle _handle ) BX_OVERRIDE
{
m_indexBuffers [ _handle . idx ] . destroy ( ) ;
}
void createVertexDecl ( VertexDeclHandle _handle , const VertexDecl & _decl ) BX_OVERRIDE
{
VertexDecl & decl = m_vertexDecls [ _handle . idx ] ;
memcpy ( & decl , & _decl , sizeof ( VertexDecl ) ) ;
dump ( decl ) ;
}
void destroyVertexDecl ( VertexDeclHandle /*_handle*/ ) BX_OVERRIDE
{
}
2015-05-14 14:37:32 -04:00
void createVertexBuffer ( VertexBufferHandle _handle , Memory * _mem , VertexDeclHandle _declHandle , uint16_t _flags ) BX_OVERRIDE
2014-05-26 17:09:26 -04:00
{
2014-12-10 02:16:27 -05:00
m_vertexBuffers [ _handle . idx ] . create ( _mem - > size , _mem - > data , _declHandle , _flags ) ;
2014-05-26 17:09:26 -04:00
}
void destroyVertexBuffer ( VertexBufferHandle _handle ) BX_OVERRIDE
{
m_vertexBuffers [ _handle . idx ] . destroy ( ) ;
}
2015-05-14 14:37:32 -04:00
void createDynamicIndexBuffer ( IndexBufferHandle _handle , uint32_t _size , uint16_t _flags ) BX_OVERRIDE
2014-05-26 17:09:26 -04:00
{
2015-01-10 23:38:47 -05:00
m_indexBuffers [ _handle . idx ] . create ( _size , NULL , _flags ) ;
2014-05-26 17:09:26 -04:00
}
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 ( ) ;
}
2015-05-14 14:37:32 -04:00
void createDynamicVertexBuffer ( VertexBufferHandle _handle , uint32_t _size , uint16_t _flags ) BX_OVERRIDE
2014-05-26 17:09:26 -04:00
{
VertexDeclHandle decl = BGFX_INVALID_HANDLE ;
2014-12-10 02:16:27 -05:00
m_vertexBuffers [ _handle . idx ] . create ( _size , NULL , decl , _flags ) ;
2014-05-26 17:09:26 -04:00
}
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
{
2014-07-20 23:27:13 -04:00
m_program [ _handle . idx ] . create ( & m_shaders [ _vsh . idx ] , isValid ( _fsh ) ? & m_shaders [ _fsh . idx ] : NULL ) ;
2014-05-26 17:09:26 -04:00
}
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
{
}
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_textures [ _handle . idx ] . update ( _side , _mip , _rect , _z , _depth , _pitch , _mem ) ;
}
void updateTextureEnd ( ) BX_OVERRIDE
{
}
2015-04-13 21:39:38 -04:00
void resizeTexture ( TextureHandle _handle , uint16_t _width , uint16_t _height ) BX_OVERRIDE
{
TextureD3D11 & texture = m_textures [ _handle . idx ] ;
uint32_t size = sizeof ( uint32_t ) + sizeof ( TextureCreate ) ;
const Memory * mem = alloc ( size ) ;
bx : : StaticMemoryBlockWriter writer ( mem - > data , mem - > size ) ;
uint32_t magic = BGFX_CHUNK_MAGIC_TEX ;
bx : : write ( & writer , magic ) ;
TextureCreate tc ;
tc . m_flags = texture . m_flags ;
tc . m_width = _width ;
tc . m_height = _height ;
tc . m_sides = 0 ;
tc . m_depth = 0 ;
tc . m_numMips = 1 ;
tc . m_format = texture . m_requestedFormat ;
tc . m_cubeMap = false ;
tc . m_mem = NULL ;
bx : : write ( & writer , tc ) ;
texture . destroy ( ) ;
texture . create ( mem , tc . m_flags , 0 ) ;
release ( mem ) ;
}
2014-05-26 17:09:26 -04:00
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 20:17:38 -04: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 17:09:26 -04:00
void destroyFrameBuffer ( FrameBufferHandle _handle ) BX_OVERRIDE
{
2014-09-07 20:17:38 -04: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 17:09:26 -04: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
{
2015-04-20 19:22:40 -04:00
BX_WARN ( NULL ! = m_swapChain , " Unable to capture screenshot %s. " , _filePath ) ;
if ( NULL = = m_swapChain )
{
return ;
}
2014-05-26 17:09:26 -04:00
ID3D11Texture2D * backBuffer ;
2015-07-16 23:28:43 -04:00
DX_CHECK ( m_swapChain - > GetBuffer ( 0 , IID_ID3D11Texture2D , ( void * * ) & backBuffer ) ) ;
2014-05-26 17:09:26 -04:00
D3D11_TEXTURE2D_DESC backBufferDesc ;
backBuffer - > GetDesc ( & backBufferDesc ) ;
D3D11_TEXTURE2D_DESC desc ;
memcpy ( & desc , & backBufferDesc , sizeof ( desc ) ) ;
desc . SampleDesc . Count = 1 ;
desc . SampleDesc . Quality = 0 ;
desc . Usage = D3D11_USAGE_STAGING ;
desc . BindFlags = 0 ;
desc . CPUAccessFlags = D3D11_CPU_ACCESS_READ ;
ID3D11Texture2D * texture ;
HRESULT hr = m_device - > CreateTexture2D ( & desc , NULL , & texture ) ;
if ( SUCCEEDED ( hr ) )
{
if ( backBufferDesc . SampleDesc . Count = = 1 )
{
m_deviceCtx - > CopyResource ( texture , backBuffer ) ;
}
else
{
desc . Usage = D3D11_USAGE_DEFAULT ;
desc . CPUAccessFlags = 0 ;
ID3D11Texture2D * resolve ;
2014-11-22 17:34:09 -05:00
hr = m_device - > CreateTexture2D ( & desc , NULL , & resolve ) ;
2014-05-26 17:09:26 -04:00
if ( SUCCEEDED ( hr ) )
{
m_deviceCtx - > ResolveSubresource ( resolve , 0 , backBuffer , 0 , desc . Format ) ;
m_deviceCtx - > CopyResource ( texture , resolve ) ;
DX_RELEASE ( resolve , 0 ) ;
}
}
D3D11_MAPPED_SUBRESOURCE mapped ;
DX_CHECK ( m_deviceCtx - > Map ( texture , 0 , D3D11_MAP_READ , 0 , & mapped ) ) ;
2014-12-02 23:28:14 -05:00
imageSwizzleBgra8 ( backBufferDesc . Width
, backBufferDesc . Height
, mapped . RowPitch
, mapped . pData
, mapped . pData
) ;
2014-05-26 17:09:26 -04:00
g_callback - > screenShot ( _filePath
, backBufferDesc . Width
, backBufferDesc . Height
, mapped . RowPitch
, mapped . pData
, backBufferDesc . Height * mapped . RowPitch
, false
) ;
m_deviceCtx - > Unmap ( texture , 0 ) ;
DX_RELEASE ( texture , 0 ) ;
}
DX_RELEASE ( backBuffer , 0 ) ;
}
void updateViewName ( uint8_t _id , const char * _name ) BX_OVERRIDE
{
2015-04-02 14:57:53 -04: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 17:09:26 -04: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 ( BX_ENABLED ( 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 ) ;
}
}
void submit ( Frame * _render , ClearQuad & _clearQuad , TextVideoMemBlitter & _textVideoMemBlitter ) BX_OVERRIDE ;
void blitSetup ( TextVideoMemBlitter & _blitter ) BX_OVERRIDE
{
ID3D11DeviceContext * deviceCtx = m_deviceCtx ;
2014-11-14 08:22:32 -05:00
uint32_t width = getBufferWidth ( ) ;
uint32_t height = getBufferHeight ( ) ;
2014-10-29 01:08:55 -04:00
if ( m_ovr . isEnabled ( ) )
{
m_ovr . getSize ( width , height ) ;
}
2014-05-26 17:09:26 -04:00
FrameBufferHandle fbh = BGFX_INVALID_HANDLE ;
setFrameBuffer ( fbh , false ) ;
D3D11_VIEWPORT vp ;
vp . TopLeftX = 0 ;
vp . TopLeftY = 0 ;
2014-10-05 21:20:05 -04:00
vp . Width = ( float ) width ;
vp . Height = ( float ) height ;
2014-05-26 17:09:26 -04:00
vp . MinDepth = 0.0f ;
vp . MaxDepth = 1.0f ;
deviceCtx - > RSSetViewports ( 1 , & vp ) ;
uint64_t state = BGFX_STATE_RGB_WRITE
| BGFX_STATE_ALPHA_WRITE
| BGFX_STATE_DEPTH_TEST_ALWAYS
;
setBlendState ( state ) ;
setDepthStencilState ( state ) ;
setRasterizerState ( state ) ;
ProgramD3D11 & program = m_program [ _blitter . m_program . idx ] ;
m_currentProgram = & program ;
2014-07-20 23:27:13 -04:00
deviceCtx - > VSSetShader ( program . m_vsh - > m_vertexShader , NULL , 0 ) ;
2014-05-26 17:09:26 -04:00
deviceCtx - > VSSetConstantBuffers ( 0 , 1 , & program . m_vsh - > m_buffer ) ;
2014-07-20 23:27:13 -04:00
deviceCtx - > PSSetShader ( program . m_fsh - > m_pixelShader , NULL , 0 ) ;
2014-05-26 17:09:26 -04:00
deviceCtx - > PSSetConstantBuffers ( 0 , 1 , & program . m_fsh - > m_buffer ) ;
VertexBufferD3D11 & vb = m_vertexBuffers [ _blitter . m_vb - > handle . idx ] ;
VertexDecl & vertexDecl = m_vertexDecls [ _blitter . m_vb - > decl . idx ] ;
uint32_t stride = vertexDecl . m_stride ;
uint32_t offset = 0 ;
deviceCtx - > IASetVertexBuffers ( 0 , 1 , & vb . m_ptr , & stride , & offset ) ;
setInputLayout ( vertexDecl , program , 0 ) ;
IndexBufferD3D11 & ib = m_indexBuffers [ _blitter . m_ib - > handle . idx ] ;
deviceCtx - > IASetIndexBuffer ( ib . m_ptr , DXGI_FORMAT_R16_UINT , 0 ) ;
float proj [ 16 ] ;
2015-04-10 22:21:31 -04:00
bx : : mtxOrtho ( proj , 0.0f , ( float ) width , ( float ) height , 0.0f , 0.0f , 1000.0f ) ;
2014-05-26 17:09:26 -04:00
PredefinedUniform & predefined = program . m_predefined [ 0 ] ;
uint8_t flags = predefined . m_type ;
2014-12-27 22:00:41 -05:00
setShaderUniform ( flags , predefined . m_loc , proj , 4 ) ;
2014-05-26 17:09:26 -04:00
commitShaderConstants ( ) ;
m_textures [ _blitter . m_texture . idx ] . commit ( 0 ) ;
commitTextureStage ( ) ;
}
void blitRender ( TextVideoMemBlitter & _blitter , uint32_t _numIndices ) BX_OVERRIDE
{
2015-01-26 22:09:51 -05:00
const uint32_t numVertices = _numIndices * 4 / 6 ;
if ( 0 < numVertices )
{
ID3D11DeviceContext * deviceCtx = m_deviceCtx ;
2014-05-26 17:09:26 -04:00
2015-01-26 22:09:51 -05:00
m_indexBuffers [ _blitter . m_ib - > handle . idx ] . update ( 0 , _numIndices * 2 , _blitter . m_ib - > data ) ;
m_vertexBuffers [ _blitter . m_vb - > handle . idx ] . update ( 0 , numVertices * _blitter . m_decl . m_stride , _blitter . m_vb - > data , true ) ;
2014-05-26 17:09:26 -04:00
2015-01-26 22:09:51 -05:00
deviceCtx - > IASetPrimitiveTopology ( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ) ;
deviceCtx - > DrawIndexed ( _numIndices , 0 , 0 ) ;
}
2014-05-26 17:09:26 -04:00
}
2012-08-05 17:51:49 -04:00
void preReset ( )
{
2014-10-29 01:08:55 -04:00
ovrPreReset ( ) ;
2015-05-14 14:37:32 -04:00
m_gpuTimer . preReset ( ) ;
2015-05-12 20:03:25 -04:00
2015-05-04 17:05:04 -04:00
if ( NULL = = g_platformData . backBufferDS )
{
DX_RELEASE ( m_backBufferDepthStencil , 0 ) ;
}
2015-04-20 19:22:40 -04:00
if ( NULL ! = m_swapChain )
{
DX_RELEASE ( m_backBufferColor , 0 ) ;
}
2012-08-05 17:51:49 -04:00
2015-04-14 20:02:41 -04:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_frameBuffers ) ; + + ii )
{
m_frameBuffers [ ii ] . preReset ( ) ;
}
2012-08-05 17:51:49 -04:00
// invalidateCache();
2012-12-30 23:52:47 -05:00
capturePreReset ( ) ;
2012-08-05 17:51:49 -04:00
}
void postReset ( )
{
2015-04-20 19:22:40 -04:00
if ( NULL ! = m_swapChain )
{
ID3D11Texture2D * color ;
2015-07-16 23:28:43 -04:00
DX_CHECK ( m_swapChain - > GetBuffer ( 0 , IID_ID3D11Texture2D , ( void * * ) & color ) ) ;
2012-08-05 17:51:49 -04:00
2015-05-02 22:57:42 -04:00
D3D11_RENDER_TARGET_VIEW_DESC desc ;
2015-05-09 19:14:43 -04:00
desc . ViewDimension = ( m_flags & BGFX_RESET_MSAA_MASK )
? D3D11_RTV_DIMENSION_TEXTURE2DMS
: D3D11_RTV_DIMENSION_TEXTURE2D
;
2015-05-02 22:57:42 -04:00
desc . Texture2D . MipSlice = 0 ;
2015-05-05 19:34:13 -04:00
desc . Format = ( m_flags & BGFX_RESET_SRGB_BACKBUFFER )
? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
: DXGI_FORMAT_R8G8B8A8_UNORM
;
2015-05-02 22:57:42 -04:00
DX_CHECK ( m_device - > CreateRenderTargetView ( color , & desc , & m_backBufferColor ) ) ;
2015-04-20 19:22:40 -04:00
DX_RELEASE ( color , 0 ) ;
}
2012-08-05 17:51:49 -04:00
2015-05-14 14:37:32 -04:00
m_gpuTimer . postReset ( ) ;
2015-05-12 20:03:25 -04:00
2014-10-29 01:08:55 -04:00
ovrPostReset ( ) ;
// If OVR doesn't create separate depth stencil view, create default one.
if ( NULL = = m_backBufferDepthStencil )
{
2014-12-21 21:55:33 -05:00
D3D11_TEXTURE2D_DESC dsd ;
dsd . Width = getBufferWidth ( ) ;
dsd . Height = getBufferHeight ( ) ;
dsd . MipLevels = 1 ;
dsd . ArraySize = 1 ;
dsd . Format = DXGI_FORMAT_D24_UNORM_S8_UINT ;
dsd . SampleDesc = m_scd . SampleDesc ;
dsd . Usage = D3D11_USAGE_DEFAULT ;
dsd . BindFlags = D3D11_BIND_DEPTH_STENCIL ;
dsd . CPUAccessFlags = 0 ;
dsd . MiscFlags = 0 ;
2014-10-29 01:08:55 -04:00
ID3D11Texture2D * depthStencil ;
DX_CHECK ( m_device - > CreateTexture2D ( & dsd , NULL , & depthStencil ) ) ;
DX_CHECK ( m_device - > CreateDepthStencilView ( depthStencil , NULL , & m_backBufferDepthStencil ) ) ;
DX_RELEASE ( depthStencil , 0 ) ;
}
2012-08-05 17:51:49 -04:00
m_deviceCtx - > OMSetRenderTargets ( 1 , & m_backBufferColor , m_backBufferDepthStencil ) ;
2012-11-25 21:24:50 -05:00
m_currentColor = m_backBufferColor ;
m_currentDepthStencil = m_backBufferDepthStencil ;
2012-12-30 23:52:47 -05:00
2015-04-14 20:02:41 -04:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_frameBuffers ) ; + + ii )
{
m_frameBuffers [ ii ] . postReset ( ) ;
}
2012-12-30 23:52:47 -05:00
capturePostReset ( ) ;
2012-08-05 17:51:49 -04:00
}
2014-10-01 00:16:24 -04:00
static bool isLost ( HRESULT _hr )
{
return DXGI_ERROR_DEVICE_REMOVED = = _hr
| | DXGI_ERROR_DEVICE_HUNG = = _hr
| | DXGI_ERROR_DEVICE_RESET = = _hr
| | DXGI_ERROR_DRIVER_INTERNAL_ERROR = = _hr
| | DXGI_ERROR_NOT_CURRENTLY_AVAILABLE = = _hr
;
}
2015-04-15 23:59:00 -04:00
void flip ( HMD & _hmd ) BX_OVERRIDE
2012-07-23 00:08:58 -04:00
{
if ( NULL ! = m_swapChain )
{
2014-10-29 01:08:55 -04:00
HRESULT hr = S_OK ;
2015-07-16 20:39:02 -04:00
uint32_t syncInterval = BX_ENABLED ( BX_PLATFORM_WINRT )
? 1 // sync interval of 0 is not supported on WinRT
: ! ! ( m_flags & BGFX_RESET_VSYNC )
;
2014-11-17 22:18:35 -05:00
2014-10-01 01:20:16 -04:00
for ( uint32_t ii = 1 , num = m_numWindows ; ii < num & & SUCCEEDED ( hr ) ; + + ii )
2014-10-01 00:16:24 -04:00
{
hr = m_frameBuffers [ m_windows [ ii ] . idx ] . m_swapChain - > Present ( syncInterval , 0 ) ;
}
if ( SUCCEEDED ( hr ) )
{
2015-04-15 23:59:00 -04:00
if ( ! m_ovr . swap ( _hmd ) )
2014-10-29 01:08:55 -04:00
{
hr = m_swapChain - > Present ( syncInterval , 0 ) ;
}
2014-10-01 00:16:24 -04:00
}
if ( FAILED ( hr )
& & isLost ( hr ) )
{
+ + m_lost ;
BGFX_FATAL ( 10 > m_lost , bgfx : : Fatal : : DeviceLost , " Device is lost. FAILED 0x%08x " , hr ) ;
}
else
2014-09-07 20:17:38 -04:00
{
2014-10-01 00:16:24 -04:00
m_lost = 0 ;
2014-09-07 20:17:38 -04:00
}
2012-07-23 00:08:58 -04:00
}
}
void invalidateCache ( )
{
m_inputLayoutCache . invalidate ( ) ;
m_blendStateCache . invalidate ( ) ;
m_depthStencilStateCache . invalidate ( ) ;
m_rasterizerStateCache . invalidate ( ) ;
m_samplerStateCache . invalidate ( ) ;
}
2014-12-10 02:16:27 -05:00
void invalidateCompute ( )
{
m_deviceCtx - > CSSetShader ( NULL , NULL , 0 ) ;
2014-12-11 00:09:13 -05:00
ID3D11UnorderedAccessView * uav [ BGFX_MAX_COMPUTE_BINDINGS ] = { } ;
m_deviceCtx - > CSSetUnorderedAccessViews ( 0 , BX_COUNTOF ( uav ) , uav , NULL ) ;
2014-12-10 02:16:27 -05:00
2014-12-11 00:09:13 -05:00
ID3D11ShaderResourceView * srv [ BGFX_MAX_COMPUTE_BINDINGS ] = { } ;
m_deviceCtx - > CSSetShaderResources ( 0 , BX_COUNTOF ( srv ) , srv ) ;
2014-12-10 02:16:27 -05:00
2014-12-11 00:09:13 -05:00
ID3D11SamplerState * samplers [ BGFX_MAX_COMPUTE_BINDINGS ] = { } ;
m_deviceCtx - > CSSetSamplers ( 0 , BX_COUNTOF ( samplers ) , samplers ) ;
2014-12-10 02:16:27 -05:00
}
2013-04-11 00:42:00 -04:00
void updateMsaa ( )
{
2013-08-07 00:04:28 -04:00
for ( uint32_t ii = 1 , last = 0 ; ii < BX_COUNTOF ( s_msaa ) ; + + ii )
2013-04-11 00:42:00 -04:00
{
uint32_t msaa = s_checkMsaa [ ii ] ;
uint32_t quality = 0 ;
2014-11-14 08:22:32 -05:00
HRESULT hr = m_device - > CheckMultisampleQualityLevels ( getBufferFormat ( ) , msaa , & quality ) ;
2013-04-11 00:42:00 -04:00
if ( SUCCEEDED ( hr )
& & 0 < quality )
{
s_msaa [ ii ] . Count = msaa ;
s_msaa [ ii ] . Quality = quality - 1 ;
last = ii ;
}
else
{
s_msaa [ ii ] = s_msaa [ last ] ;
}
}
}
2012-07-23 00:08:58 -04:00
void updateResolution ( const Resolution & _resolution )
{
2015-01-21 23:39:42 -05:00
bool recenter = ! ! ( _resolution . m_flags & BGFX_RESET_HMD_RECENTER ) ;
2015-04-16 19:24:05 -04:00
if ( ! ! ( _resolution . m_flags & BGFX_RESET_MAXANISOTROPY ) )
{
m_maxAnisotropy = ( m_featureLevel = = D3D_FEATURE_LEVEL_9_1 )
2015-06-19 01:33:06 -04:00
? D3D_FL9_1_DEFAULT_MAX_ANISOTROPY
: D3D11_REQ_MAXANISOTROPY
;
2015-04-16 19:24:05 -04:00
}
else
{
m_maxAnisotropy = 1 ;
}
2015-01-21 23:39:42 -05:00
uint32_t flags = _resolution . m_flags & ~ ( BGFX_RESET_HMD_RECENTER | BGFX_RESET_MAXANISOTROPY ) ;
2014-11-02 02:06:18 -05:00
2014-11-14 08:22:32 -05:00
if ( getBufferWidth ( ) ! = _resolution . m_width
| | getBufferHeight ( ) ! = _resolution . m_height
2014-11-02 02:06:18 -05:00
| | m_flags ! = flags )
2012-07-23 00:08:58 -04:00
{
2014-12-11 00:09:13 -05:00
bool resize = true
& & ! BX_ENABLED ( BX_PLATFORM_WINRT ) // can't use ResizeBuffers on Windows Phone
& & ( m_flags & BGFX_RESET_MSAA_MASK ) = = ( flags & BGFX_RESET_MSAA_MASK )
;
2014-11-02 02:06:18 -05:00
m_flags = flags ;
2012-07-23 00:08:58 -04:00
m_textVideoMem . resize ( false , _resolution . m_width , _resolution . m_height ) ;
m_textVideoMem . clear ( ) ;
2014-05-26 17:09:26 -04:00
m_resolution = _resolution ;
2014-11-02 02:06:18 -05:00
m_resolution . m_flags = flags ;
2014-05-26 17:09:26 -04:00
2014-12-04 22:56:19 -05:00
setBufferSize ( _resolution . m_width , _resolution . m_height ) ;
2012-07-23 00:08:58 -04:00
2012-08-05 17:51:49 -04:00
preReset ( ) ;
2012-07-23 00:08:58 -04:00
2015-04-22 18:11:45 -04:00
if ( NULL = = m_swapChain )
{
// Updated backbuffer if it changed in PlatformData.
2015-05-04 17:05:04 -04:00
m_backBufferColor = ( ID3D11RenderTargetView * ) g_platformData . backBuffer ;
m_backBufferDepthStencil = ( ID3D11DepthStencilView * ) g_platformData . backBufferDS ;
2015-04-22 18:11:45 -04:00
}
else
2013-04-11 00:42:00 -04:00
{
2015-04-20 19:22:40 -04:00
if ( resize )
{
DX_CHECK ( m_swapChain - > ResizeBuffers ( 2
, getBufferWidth ( )
, getBufferHeight ( )
, getBufferFormat ( )
, DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH
2015-07-16 23:28:43 -04:00
) ) ;
2015-04-20 19:22:40 -04:00
}
else
{
updateMsaa ( ) ;
m_scd . SampleDesc = s_msaa [ ( m_flags & BGFX_RESET_MSAA_MASK ) > > BGFX_RESET_MSAA_SHIFT ] ;
2013-04-11 00:42:00 -04:00
2015-04-20 19:22:40 -04:00
DX_RELEASE ( m_swapChain , 0 ) ;
2013-04-11 00:42:00 -04:00
2015-06-05 13:43:43 -04:00
SwapChainDesc * scd = & m_scd ;
SwapChainDesc swapChainScd ;
if ( 0 ! = ( m_flags & BGFX_RESET_HMD )
2015-07-16 23:28:43 -04:00
& & m_ovr . isInitialized ( ) )
2015-06-04 22:15:05 -04:00
{
swapChainScd = m_scd ;
swapChainScd . SampleDesc = s_msaa [ 0 ] ;
scd = & swapChainScd ;
}
2014-11-14 08:22:32 -05:00
# if BX_PLATFORM_WINRT
2015-04-20 19:22:40 -04:00
HRESULT hr ;
hr = m_factory - > CreateSwapChainForCoreWindow ( m_device
, ( : : IUnknown * ) g_platformData . nwh
2015-06-04 22:15:05 -04:00
, scd
2015-04-20 19:22:40 -04:00
, NULL
, & m_swapChain
) ;
2014-11-14 08:22:32 -05:00
# else
2015-04-20 19:22:40 -04:00
HRESULT hr ;
hr = m_factory - > CreateSwapChain ( m_device
2015-06-04 22:15:05 -04:00
, scd
2015-04-20 19:22:40 -04:00
, & m_swapChain
) ;
2014-12-11 00:09:13 -05:00
# endif // BX_PLATFORM_WINRT
2015-04-20 19:22:40 -04:00
BGFX_FATAL ( SUCCEEDED ( hr ) , bgfx : : Fatal : : UnableToInitialize , " Failed to create swap chain. " ) ;
}
2013-04-11 00:42:00 -04:00
}
2012-07-23 00:08:58 -04:00
postReset ( ) ;
}
2014-11-02 02:06:18 -05:00
if ( recenter )
{
m_ovr . recenter ( ) ;
}
2012-07-23 00:08:58 -04:00
}
2015-04-07 20:58:14 -04:00
void setShaderUniform ( uint8_t _flags , uint32_t _regIndex , const void * _val , uint32_t _numRegs )
2012-07-23 00:08:58 -04:00
{
if ( _flags & BGFX_UNIFORM_FRAGMENTBIT )
{
memcpy ( & m_fsScratch [ _regIndex ] , _val , _numRegs * 16 ) ;
2013-01-06 01:34:31 -05:00
m_fsChanges + = _numRegs ;
2012-07-23 00:08:58 -04:00
}
else
{
memcpy ( & m_vsScratch [ _regIndex ] , _val , _numRegs * 16 ) ;
2013-01-06 01:34:31 -05:00
m_vsChanges + = _numRegs ;
2012-07-23 00:08:58 -04:00
}
}
2015-04-07 20:58:14 -04:00
void setShaderUniform4f ( uint8_t _flags , uint32_t _regIndex , const void * _val , uint32_t _numRegs )
2014-12-27 22:00:41 -05:00
{
setShaderUniform ( _flags , _regIndex , _val , _numRegs ) ;
}
2015-04-07 20:58:14 -04:00
void setShaderUniform4x4f ( uint8_t _flags , uint32_t _regIndex , const void * _val , uint32_t _numRegs )
2014-12-27 22:00:41 -05:00
{
setShaderUniform ( _flags , _regIndex , _val , _numRegs ) ;
}
2012-07-23 00:08:58 -04:00
void commitShaderConstants ( )
{
if ( 0 < m_vsChanges )
{
2012-09-16 20:36:08 -04:00
if ( NULL ! = m_currentProgram - > m_vsh - > m_buffer )
2012-07-23 00:08:58 -04:00
{
2012-09-16 20:36:08 -04:00
m_deviceCtx - > UpdateSubresource ( m_currentProgram - > m_vsh - > m_buffer , 0 , 0 , m_vsScratch , 0 , 0 ) ;
2012-07-23 00:08:58 -04:00
}
m_vsChanges = 0 ;
}
if ( 0 < m_fsChanges )
{
2012-09-16 20:36:08 -04:00
if ( NULL ! = m_currentProgram - > m_fsh - > m_buffer )
2012-07-23 00:08:58 -04:00
{
2012-09-16 20:36:08 -04:00
m_deviceCtx - > UpdateSubresource ( m_currentProgram - > m_fsh - > m_buffer , 0 , 0 , m_fsScratch , 0 , 0 ) ;
2012-07-23 00:08:58 -04:00
}
m_fsChanges = 0 ;
}
}
2014-02-06 02:07:11 -05:00
void setFrameBuffer ( FrameBufferHandle _fbh , bool _msaa = true )
2012-07-23 00:08:58 -04:00
{
2014-12-29 20:20:55 -05:00
if ( isValid ( m_fbh )
& & m_fbh . idx ! = _fbh . idx
& & m_rtMsaa )
{
FrameBufferD3D11 & frameBuffer = m_frameBuffers [ m_fbh . idx ] ;
frameBuffer . resolve ( ) ;
}
2014-02-06 02:07:11 -05:00
if ( ! isValid ( _fbh ) )
2012-07-23 00:08:58 -04:00
{
m_deviceCtx - > OMSetRenderTargets ( 1 , & m_backBufferColor , m_backBufferDepthStencil ) ;
2014-02-06 02:07:11 -05:00
2012-11-25 21:24:50 -05:00
m_currentColor = m_backBufferColor ;
m_currentDepthStencil = m_backBufferDepthStencil ;
2012-07-23 00:08:58 -04:00
}
else
{
2012-11-25 21:24:50 -05:00
invalidateTextureStage ( ) ;
2014-05-26 17:09:26 -04:00
FrameBufferD3D11 & frameBuffer = m_frameBuffers [ _fbh . idx ] ;
2014-02-06 02:07:11 -05:00
m_deviceCtx - > OMSetRenderTargets ( frameBuffer . m_num , frameBuffer . m_rtv , frameBuffer . m_dsv ) ;
2012-11-25 21:24:50 -05:00
2014-02-06 02:07:11 -05:00
m_currentColor = frameBuffer . m_rtv [ 0 ] ;
m_currentDepthStencil = frameBuffer . m_dsv ;
}
m_fbh = _fbh ;
m_rtMsaa = _msaa ;
2012-07-23 00:08:58 -04:00
}
2014-09-01 14:24:51 -04:00
void clear ( const Clear & _clear , const float _palette [ ] [ 4 ] )
2012-07-23 00:08:58 -04:00
{
2014-03-26 02:07:51 -04:00
if ( isValid ( m_fbh ) )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
FrameBufferD3D11 & frameBuffer = m_frameBuffers [ m_fbh . idx ] ;
2014-09-01 14:24:51 -04:00
frameBuffer . clear ( _clear , _palette ) ;
2012-07-23 00:08:58 -04:00
}
2014-03-26 02:07:51 -04:00
else
2012-07-23 00:08:58 -04:00
{
2014-03-26 02:07:51 -04:00
if ( NULL ! = m_currentColor
2015-01-11 00:39:45 -05:00
& & BGFX_CLEAR_COLOR & _clear . m_flags )
2014-03-26 02:07:51 -04:00
{
2015-01-11 21:02:34 -05:00
if ( BGFX_CLEAR_COLOR_USE_PALETTE & _clear . m_flags )
2014-09-01 14:24:51 -04:00
{
uint8_t index = _clear . m_index [ 0 ] ;
if ( UINT8_MAX ! = index )
{
m_deviceCtx - > ClearRenderTargetView ( m_currentColor , _palette [ index ] ) ;
}
}
else
{
float frgba [ 4 ] =
2014-11-22 17:13:14 -05:00
{
2014-09-01 14:24:51 -04:00
_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 ,
} ;
m_deviceCtx - > ClearRenderTargetView ( m_currentColor , frgba ) ;
}
2014-03-26 02:07:51 -04:00
}
if ( NULL ! = m_currentDepthStencil
2015-01-11 00:39:45 -05:00
& & ( BGFX_CLEAR_DEPTH | BGFX_CLEAR_STENCIL ) & _clear . m_flags )
2014-03-26 02:07:51 -04:00
{
DWORD flags = 0 ;
2015-01-11 00:39:45 -05:00
flags | = ( _clear . m_flags & BGFX_CLEAR_DEPTH ) ? D3D11_CLEAR_DEPTH : 0 ;
flags | = ( _clear . m_flags & BGFX_CLEAR_STENCIL ) ? D3D11_CLEAR_STENCIL : 0 ;
2014-03-26 02:07:51 -04:00
m_deviceCtx - > ClearDepthStencilView ( m_currentDepthStencil , flags , _clear . m_depth , _clear . m_stencil ) ;
}
2012-07-23 00:08:58 -04:00
}
}
2015-04-07 20:58:14 -04:00
void setInputLayout ( const VertexDecl & _vertexDecl , const ProgramD3D11 & _program , uint16_t _numInstanceData )
2012-07-23 00:08:58 -04:00
{
2012-09-16 20:36:08 -04:00
uint64_t layoutHash = ( uint64_t ( _vertexDecl . m_hash ) < < 32 ) | _program . m_vsh - > m_hash ;
2012-10-09 02:24:10 -04:00
layoutHash ^ = _numInstanceData ;
2012-07-23 00:08:58 -04:00
ID3D11InputLayout * layout = m_inputLayoutCache . find ( layoutHash ) ;
if ( NULL = = layout )
{
D3D11_INPUT_ELEMENT_DESC vertexElements [ Attrib : : Count + 1 + BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT ] ;
2012-08-29 01:59:48 -04:00
VertexDecl decl ;
memcpy ( & decl , & _vertexDecl , sizeof ( VertexDecl ) ) ;
2012-09-16 20:36:08 -04:00
const uint8_t * attrMask = _program . m_vsh - > m_attrMask ;
2012-08-29 01:59:48 -04:00
for ( uint32_t ii = 0 ; ii < Attrib : : Count ; + + ii )
{
uint8_t mask = attrMask [ ii ] ;
uint8_t attr = ( decl . m_attributes [ ii ] & mask ) ;
decl . m_attributes [ ii ] = attr = = 0 ? 0xff : attr = = 0xff ? 0 : attr ;
}
2013-03-26 00:13:54 -04:00
D3D11_INPUT_ELEMENT_DESC * elem = fillVertexDecl ( vertexElements , decl ) ;
2013-02-26 21:54:03 -05:00
uint32_t num = uint32_t ( elem - vertexElements ) ;
2012-10-09 02:24:10 -04:00
const D3D11_INPUT_ELEMENT_DESC inst = { " TEXCOORD " , 0 , DXGI_FORMAT_R32G32B32A32_FLOAT , 0 , D3D11_APPEND_ALIGNED_ELEMENT , D3D11_INPUT_PER_INSTANCE_DATA , 1 } ;
for ( uint32_t ii = 0 ; ii < _numInstanceData ; + + ii )
{
2015-04-15 13:37:00 -04:00
uint32_t index = 7 - ii ; // TEXCOORD7 = i_data0, TEXCOORD6 = i_data1, etc.
2012-10-09 02:24:10 -04:00
uint32_t jj ;
2013-04-08 00:06:02 -04:00
D3D11_INPUT_ELEMENT_DESC * curr = vertexElements ;
2013-02-26 21:54:03 -05:00
for ( jj = 0 ; jj < num ; + + jj )
2012-10-09 02:24:10 -04:00
{
curr = & vertexElements [ jj ] ;
if ( 0 = = strcmp ( curr - > SemanticName , " TEXCOORD " )
2014-10-06 22:21:08 -04:00
& & curr - > SemanticIndex = = index )
2012-10-09 02:24:10 -04:00
{
break ;
}
}
if ( jj = = num )
{
curr = elem ;
+ + elem ;
}
memcpy ( curr , & inst , sizeof ( D3D11_INPUT_ELEMENT_DESC ) ) ;
curr - > InputSlot = 1 ;
curr - > SemanticIndex = index ;
curr - > AlignedByteOffset = ii * 16 ;
}
2013-02-26 21:54:03 -05:00
num = uint32_t ( elem - vertexElements ) ;
2012-08-05 23:38:17 -04:00
DX_CHECK ( m_device - > CreateInputLayout ( vertexElements
2013-02-26 21:54:03 -05:00
, num
2012-09-16 20:36:08 -04:00
, _program . m_vsh - > m_code - > data
, _program . m_vsh - > m_code - > size
2012-07-23 00:08:58 -04:00
, & layout
) ) ;
m_inputLayoutCache . add ( layoutHash , layout ) ;
}
m_deviceCtx - > IASetInputLayout ( layout ) ;
}
2014-03-26 02:07:51 -04:00
void setBlendState ( uint64_t _state , uint32_t _rgba = 0 )
2012-07-23 00:08:58 -04:00
{
2015-06-17 13:04:12 -04:00
_state & = BGFX_D3D11_BLEND_STATE_MASK ;
2012-07-23 00:08:58 -04:00
2014-03-26 02:07:51 -04:00
bx : : HashMurmur2A murmur ;
murmur . begin ( ) ;
murmur . add ( _state ) ;
const uint64_t f0 = BGFX_STATE_BLEND_FUNC ( BGFX_STATE_BLEND_FACTOR , BGFX_STATE_BLEND_FACTOR ) ;
const uint64_t f1 = BGFX_STATE_BLEND_FUNC ( BGFX_STATE_BLEND_INV_FACTOR , BGFX_STATE_BLEND_INV_FACTOR ) ;
2014-11-22 17:13:14 -05:00
bool hasFactor = f0 = = ( _state & f0 )
2014-05-26 17:09:26 -04:00
| | f1 = = ( _state & f1 )
;
2014-03-26 02:07:51 -04:00
float blendFactor [ 4 ] = { 1.0f , 1.0f , 1.0f , 1.0f } ;
if ( hasFactor )
{
blendFactor [ 0 ] = ( ( _rgba > > 24 ) ) / 255.0f ;
blendFactor [ 1 ] = ( ( _rgba > > 16 ) & 0xff ) / 255.0f ;
blendFactor [ 2 ] = ( ( _rgba > > 8 ) & 0xff ) / 255.0f ;
blendFactor [ 3 ] = ( ( _rgba ) & 0xff ) / 255.0f ;
}
else
{
murmur . add ( _rgba ) ;
}
uint32_t hash = murmur . end ( ) ;
ID3D11BlendState * bs = m_blendStateCache . find ( hash ) ;
2012-07-23 00:08:58 -04:00
if ( NULL = = bs )
{
D3D11_BLEND_DESC desc ;
memset ( & desc , 0 , sizeof ( desc ) ) ;
2014-03-26 02:07:51 -04:00
desc . IndependentBlendEnable = ! ! ( BGFX_STATE_BLEND_INDEPENDENT & _state ) ;
D3D11_RENDER_TARGET_BLEND_DESC * drt = & desc . RenderTarget [ 0 ] ;
drt - > BlendEnable = ! ! ( BGFX_STATE_BLEND_MASK & _state ) ;
const uint32_t blend = uint32_t ( ( _state & BGFX_STATE_BLEND_MASK ) > > BGFX_STATE_BLEND_SHIFT ) ;
const uint32_t equation = uint32_t ( ( _state & BGFX_STATE_BLEND_EQUATION_MASK ) > > BGFX_STATE_BLEND_EQUATION_SHIFT ) ;
2015-06-21 23:00:00 -04:00
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 ;
2014-03-26 02:07:51 -04:00
2015-06-21 23:00:00 -04:00
const uint32_t equRGB = ( equation ) & 0x7 ;
const uint32_t equA = ( equation > > 3 ) & 0x7 ;
2014-03-26 02:07:51 -04:00
drt - > SrcBlend = s_blendFactor [ srcRGB ] [ 0 ] ;
drt - > DestBlend = s_blendFactor [ dstRGB ] [ 0 ] ;
drt - > BlendOp = s_blendEquation [ equRGB ] ;
drt - > SrcBlendAlpha = s_blendFactor [ srcA ] [ 1 ] ;
drt - > DestBlendAlpha = s_blendFactor [ dstA ] [ 1 ] ;
drt - > BlendOpAlpha = s_blendEquation [ equA ] ;
2012-07-23 00:08:58 -04:00
2015-06-24 13:20:01 -04:00
uint8_t writeMask = ( _state & BGFX_STATE_ALPHA_WRITE )
? D3D11_COLOR_WRITE_ENABLE_ALPHA
2015-06-21 23:00:00 -04:00
: 0
;
writeMask | = ( _state & BGFX_STATE_RGB_WRITE )
? D3D11_COLOR_WRITE_ENABLE_RED
| D3D11_COLOR_WRITE_ENABLE_GREEN
| D3D11_COLOR_WRITE_ENABLE_BLUE
: 0
;
2012-07-23 00:08:58 -04:00
2014-03-26 02:07:51 -04:00
drt - > RenderTargetWriteMask = writeMask ;
2012-07-24 01:42:51 -04:00
2014-03-26 02:07:51 -04:00
if ( desc . IndependentBlendEnable )
{
for ( uint32_t ii = 1 , rgba = _rgba ; ii < BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS ; + + ii , rgba > > = 11 )
{
drt = & desc . RenderTarget [ ii ] ;
2015-06-21 23:00:00 -04:00
drt - > BlendEnable = 0 ! = ( rgba & 0x7ff ) ;
2014-03-26 02:07:51 -04:00
2015-06-21 23:00:00 -04:00
const uint32_t src = ( rgba ) & 0xf ;
const uint32_t dst = ( rgba > > 4 ) & 0xf ;
const uint32_t equation = ( rgba > > 8 ) & 0x7 ;
2012-07-24 01:42:51 -04:00
2014-03-26 02:07:51 -04:00
drt - > SrcBlend = s_blendFactor [ src ] [ 0 ] ;
drt - > DestBlend = s_blendFactor [ dst ] [ 0 ] ;
2015-06-21 23:00:00 -04:00
drt - > BlendOp = s_blendEquation [ equation ] ;
2012-07-23 00:08:58 -04:00
2014-03-26 02:07:51 -04:00
drt - > SrcBlendAlpha = s_blendFactor [ src ] [ 1 ] ;
drt - > DestBlendAlpha = s_blendFactor [ dst ] [ 1 ] ;
2015-06-21 23:00:00 -04:00
drt - > BlendOpAlpha = s_blendEquation [ equation ] ;
2014-03-26 02:07:51 -04:00
drt - > RenderTargetWriteMask = writeMask ;
}
}
else
{
for ( uint32_t ii = 1 ; ii < BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS ; + + ii )
{
memcpy ( & desc . RenderTarget [ ii ] , drt , sizeof ( D3D11_RENDER_TARGET_BLEND_DESC ) ) ;
}
}
2014-05-26 17:09:26 -04:00
2012-07-23 00:08:58 -04:00
DX_CHECK ( m_device - > CreateBlendState ( & desc , & bs ) ) ;
2014-03-26 02:07:51 -04:00
m_blendStateCache . add ( hash , bs ) ;
2012-07-23 00:08:58 -04:00
}
2013-03-30 01:58:50 -04:00
m_deviceCtx - > OMSetBlendState ( bs , blendFactor , 0xffffffff ) ;
2012-07-23 00:08:58 -04:00
}
2012-11-10 22:59:23 -05:00
void setDepthStencilState ( uint64_t _state , uint64_t _stencil = 0 )
2012-07-23 00:08:58 -04:00
{
2015-06-17 13:04:12 -04:00
_state & = BGFX_D3D11_DEPTH_STENCIL_MASK ;
2012-07-23 00:08:58 -04:00
2012-11-10 22:59:23 -05:00
uint32_t fstencil = unpackStencil ( 0 , _stencil ) ;
uint32_t ref = ( fstencil & BGFX_STENCIL_FUNC_REF_MASK ) > > BGFX_STENCIL_FUNC_REF_SHIFT ;
2013-04-14 21:18:11 -04:00
_stencil & = packStencil ( ~ BGFX_STENCIL_FUNC_REF_MASK , BGFX_STENCIL_MASK ) ;
2012-11-10 22:59:23 -05:00
2013-08-04 01:15:13 -04:00
bx : : HashMurmur2A murmur ;
2012-11-10 22:59:23 -05:00
murmur . begin ( ) ;
murmur . add ( _state ) ;
murmur . add ( _stencil ) ;
uint32_t hash = murmur . end ( ) ;
ID3D11DepthStencilState * dss = m_depthStencilStateCache . find ( hash ) ;
2012-07-23 00:08:58 -04:00
if ( NULL = = dss )
{
D3D11_DEPTH_STENCIL_DESC desc ;
memset ( & desc , 0 , sizeof ( desc ) ) ;
uint32_t func = ( _state & BGFX_STATE_DEPTH_TEST_MASK ) > > BGFX_STATE_DEPTH_TEST_SHIFT ;
desc . DepthEnable = 0 ! = func ;
desc . DepthWriteMask = ! ! ( BGFX_STATE_DEPTH_WRITE & _state ) ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO ;
2014-02-23 14:21:23 -05:00
desc . DepthFunc = s_cmpFunc [ func ] ;
2012-07-23 00:08:58 -04:00
2012-11-10 22:59:23 -05:00
uint32_t bstencil = unpackStencil ( 1 , _stencil ) ;
uint32_t frontAndBack = bstencil ! = BGFX_STENCIL_NONE & & bstencil ! = fstencil ;
bstencil = frontAndBack ? bstencil : fstencil ;
desc . StencilEnable = 0 ! = _stencil ;
desc . StencilReadMask = ( fstencil & BGFX_STENCIL_FUNC_RMASK_MASK ) > > BGFX_STENCIL_FUNC_RMASK_SHIFT ;
desc . StencilWriteMask = 0xff ;
desc . FrontFace . StencilFailOp = s_stencilOp [ ( fstencil & BGFX_STENCIL_OP_FAIL_S_MASK ) > > BGFX_STENCIL_OP_FAIL_S_SHIFT ] ;
desc . FrontFace . StencilDepthFailOp = s_stencilOp [ ( fstencil & BGFX_STENCIL_OP_FAIL_Z_MASK ) > > BGFX_STENCIL_OP_FAIL_Z_SHIFT ] ;
desc . FrontFace . StencilPassOp = s_stencilOp [ ( fstencil & BGFX_STENCIL_OP_PASS_Z_MASK ) > > BGFX_STENCIL_OP_PASS_Z_SHIFT ] ;
2014-02-23 14:21:23 -05:00
desc . FrontFace . StencilFunc = s_cmpFunc [ ( fstencil & BGFX_STENCIL_TEST_MASK ) > > BGFX_STENCIL_TEST_SHIFT ] ;
2013-10-15 00:08:55 -04:00
desc . BackFace . StencilFailOp = s_stencilOp [ ( bstencil & BGFX_STENCIL_OP_FAIL_S_MASK ) > > BGFX_STENCIL_OP_FAIL_S_SHIFT ] ;
desc . BackFace . StencilDepthFailOp = s_stencilOp [ ( bstencil & BGFX_STENCIL_OP_FAIL_Z_MASK ) > > BGFX_STENCIL_OP_FAIL_Z_SHIFT ] ;
2012-11-10 22:59:23 -05:00
desc . BackFace . StencilPassOp = s_stencilOp [ ( bstencil & BGFX_STENCIL_OP_PASS_Z_MASK ) > > BGFX_STENCIL_OP_PASS_Z_SHIFT ] ;
2014-02-23 14:21:23 -05:00
desc . BackFace . StencilFunc = s_cmpFunc [ ( bstencil & BGFX_STENCIL_TEST_MASK ) > > BGFX_STENCIL_TEST_SHIFT ] ;
2012-11-10 22:59:23 -05:00
2012-07-23 00:08:58 -04:00
DX_CHECK ( m_device - > CreateDepthStencilState ( & desc , & dss ) ) ;
2012-11-25 21:24:50 -05:00
m_depthStencilStateCache . add ( hash , dss ) ;
2012-07-23 00:08:58 -04:00
}
2012-11-10 22:59:23 -05:00
m_deviceCtx - > OMSetDepthStencilState ( dss , ref ) ;
2012-07-23 00:08:58 -04:00
}
2012-08-05 17:51:49 -04:00
void setDebugWireframe ( bool _wireframe )
{
if ( m_wireframe ! = _wireframe )
{
m_wireframe = _wireframe ;
m_rasterizerStateCache . invalidate ( ) ;
}
}
2013-07-14 17:32:09 -04:00
void setRasterizerState ( uint64_t _state , bool _wireframe = false , bool _scissor = false )
2012-07-23 00:08:58 -04:00
{
2013-04-11 00:42:00 -04:00
_state & = BGFX_STATE_CULL_MASK | BGFX_STATE_MSAA ;
2012-08-05 17:51:49 -04:00
_state | = _wireframe ? BGFX_STATE_PT_LINES : BGFX_STATE_NONE ;
2013-07-14 17:32:09 -04:00
_state | = _scissor ? BGFX_STATE_RESERVED_MASK : 0 ;
2012-07-23 00:08:58 -04:00
ID3D11RasterizerState * rs = m_rasterizerStateCache . find ( _state ) ;
if ( NULL = = rs )
{
2012-11-25 21:24:50 -05:00
uint32_t cull = ( _state & BGFX_STATE_CULL_MASK ) > > BGFX_STATE_CULL_SHIFT ;
2012-07-23 00:08:58 -04:00
D3D11_RASTERIZER_DESC desc ;
desc . FillMode = _wireframe ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID ;
desc . CullMode = s_cullMode [ cull ] ;
2012-11-25 21:24:50 -05:00
desc . FrontCounterClockwise = false ;
desc . DepthBias = 0 ;
desc . DepthBiasClamp = 0.0f ;
desc . SlopeScaledDepthBias = 0.0f ;
2015-04-16 19:24:05 -04:00
desc . DepthClipEnable = m_featureLevel < = D3D_FEATURE_LEVEL_9_3 ; // disabling depth clip is only supported on 10_0+
2013-07-14 17:32:09 -04:00
desc . ScissorEnable = _scissor ;
2013-04-11 00:42:00 -04:00
desc . MultisampleEnable = ! ! ( _state & BGFX_STATE_MSAA ) ;
2012-11-25 21:24:50 -05:00
desc . AntialiasedLineEnable = false ;
2012-07-23 00:08:58 -04:00
DX_CHECK ( m_device - > CreateRasterizerState ( & desc , & rs ) ) ;
m_rasterizerStateCache . add ( _state , rs ) ;
}
m_deviceCtx - > RSSetState ( rs ) ;
}
2013-02-16 16:52:35 -05:00
ID3D11SamplerState * getSamplerState ( uint32_t _flags )
{
2014-04-10 00:23:27 -04:00
_flags & = BGFX_TEXTURE_SAMPLER_BITS_MASK ;
2013-07-25 00:59:59 -04:00
ID3D11SamplerState * sampler = m_samplerStateCache . find ( _flags ) ;
2013-02-16 16:52:35 -05:00
if ( NULL = = sampler )
{
2014-02-23 14:21:23 -05:00
const uint32_t cmpFunc = ( _flags & BGFX_TEXTURE_COMPARE_MASK ) > > BGFX_TEXTURE_COMPARE_SHIFT ;
const uint8_t minFilter = s_textureFilter [ 0 ] [ ( _flags & BGFX_TEXTURE_MIN_MASK ) > > BGFX_TEXTURE_MIN_SHIFT ] ;
const uint8_t magFilter = s_textureFilter [ 1 ] [ ( _flags & BGFX_TEXTURE_MAG_MASK ) > > BGFX_TEXTURE_MAG_SHIFT ] ;
const uint8_t mipFilter = s_textureFilter [ 2 ] [ ( _flags & BGFX_TEXTURE_MIP_MASK ) > > BGFX_TEXTURE_MIP_SHIFT ] ;
const uint8_t filter = 0 = = cmpFunc ? 0 : D3D11_COMPARISON_FILTERING_BIT ;
2013-07-25 00:59:59 -04:00
D3D11_SAMPLER_DESC sd ;
2014-02-23 14:21:23 -05:00
sd . Filter = ( D3D11_FILTER ) ( filter | minFilter | magFilter | mipFilter ) ;
2013-07-25 00:59:59 -04:00
sd . AddressU = s_textureAddress [ ( _flags & BGFX_TEXTURE_U_MASK ) > > BGFX_TEXTURE_U_SHIFT ] ;
sd . AddressV = s_textureAddress [ ( _flags & BGFX_TEXTURE_V_MASK ) > > BGFX_TEXTURE_V_SHIFT ] ;
sd . AddressW = s_textureAddress [ ( _flags & BGFX_TEXTURE_W_MASK ) > > BGFX_TEXTURE_W_SHIFT ] ;
sd . MipLODBias = 0.0f ;
2015-01-21 23:39:42 -05:00
sd . MaxAnisotropy = m_maxAnisotropy ;
2014-02-23 14:21:23 -05:00
sd . ComparisonFunc = 0 = = cmpFunc ? D3D11_COMPARISON_NEVER : s_cmpFunc [ cmpFunc ] ;
2013-07-25 00:59:59 -04:00
sd . BorderColor [ 0 ] = 0.0f ;
sd . BorderColor [ 1 ] = 0.0f ;
sd . BorderColor [ 2 ] = 0.0f ;
sd . BorderColor [ 3 ] = 0.0f ;
sd . MinLOD = 0 ;
sd . MaxLOD = D3D11_FLOAT32_MAX ;
2013-02-16 16:52:35 -05:00
m_device - > CreateSamplerState ( & sd , & sampler ) ;
DX_CHECK_REFCOUNT ( sampler , 1 ) ;
2013-07-25 00:59:59 -04:00
m_samplerStateCache . add ( _flags , sampler ) ;
2013-02-16 16:52:35 -05:00
}
return sampler ;
}
2014-12-04 22:56:19 -05:00
DXGI_FORMAT getBufferFormat ( )
{
2014-11-14 08:22:32 -05:00
# if BX_PLATFORM_WINRT
2014-12-04 22:56:19 -05:00
return m_scd . Format ;
2014-11-14 08:22:32 -05:00
# else
2014-12-04 22:56:19 -05:00
return m_scd . BufferDesc . Format ;
2014-11-14 08:22:32 -05:00
# endif
2014-12-04 22:56:19 -05:00
}
2014-11-14 08:22:32 -05:00
2014-12-04 22:56:19 -05:00
uint32_t getBufferWidth ( )
{
2014-11-14 08:22:32 -05:00
# if BX_PLATFORM_WINRT
2014-12-04 22:56:19 -05:00
return m_scd . Width ;
2014-11-14 08:22:32 -05:00
# else
2014-12-04 22:56:19 -05:00
return m_scd . BufferDesc . Width ;
2014-11-14 08:22:32 -05:00
# endif
2014-12-04 22:56:19 -05:00
}
2014-11-14 08:22:32 -05:00
2014-12-04 22:56:19 -05:00
uint32_t getBufferHeight ( )
{
2014-11-14 08:22:32 -05:00
# if BX_PLATFORM_WINRT
2014-12-04 22:56:19 -05:00
return m_scd . Height ;
2014-11-14 08:22:32 -05:00
# else
2014-12-04 22:56:19 -05:00
return m_scd . BufferDesc . Height ;
2014-11-14 08:22:32 -05:00
# endif
2014-12-04 22:56:19 -05:00
}
2014-11-14 08:22:32 -05:00
2014-12-04 22:56:19 -05:00
void setBufferSize ( uint32_t _width , uint32_t _height )
{
2014-11-14 08:22:32 -05:00
# if BX_PLATFORM_WINRT
2014-12-21 21:55:33 -05:00
m_scd . Width = _width ;
2014-12-04 22:56:19 -05:00
m_scd . Height = _height ;
2014-11-14 08:22:32 -05:00
# else
2014-12-21 21:55:33 -05:00
m_scd . BufferDesc . Width = _width ;
2014-12-04 22:56:19 -05:00
m_scd . BufferDesc . Height = _height ;
2014-11-14 08:22:32 -05:00
# endif
2014-12-04 22:56:19 -05:00
}
2014-11-14 08:22:32 -05:00
2012-08-05 17:51:49 -04:00
void commitTextureStage ( )
{
2015-04-16 19:24:05 -04:00
// vertex texture fetch not supported on 9_1 through 9_3
if ( m_featureLevel > D3D_FEATURE_LEVEL_9_3 )
{
m_deviceCtx - > VSSetShaderResources ( 0 , BGFX_CONFIG_MAX_TEXTURE_SAMPLERS , m_textureStage . m_srv ) ;
m_deviceCtx - > VSSetSamplers ( 0 , BGFX_CONFIG_MAX_TEXTURE_SAMPLERS , m_textureStage . m_sampler ) ;
}
2015-03-02 01:01:30 -05:00
2014-07-30 23:37:54 -04:00
m_deviceCtx - > PSSetShaderResources ( 0 , BGFX_CONFIG_MAX_TEXTURE_SAMPLERS , m_textureStage . m_srv ) ;
m_deviceCtx - > PSSetSamplers ( 0 , BGFX_CONFIG_MAX_TEXTURE_SAMPLERS , m_textureStage . m_sampler ) ;
2012-08-05 17:51:49 -04:00
}
2012-07-29 16:50:23 -04:00
2012-11-25 21:24:50 -05:00
void invalidateTextureStage ( )
{
m_textureStage . clear ( ) ;
commitTextureStage ( ) ;
}
2014-10-29 01:08:55 -04:00
void ovrPostReset ( )
{
# if BGFX_CONFIG_USE_OVR
if ( m_flags & ( BGFX_RESET_HMD | BGFX_RESET_HMD_DEBUG ) )
{
ovrD3D11Config config ;
config . D3D11 . Header . API = ovrRenderAPI_D3D11 ;
2014-12-21 21:55:33 -05:00
# if OVR_VERSION > OVR_VERSION_043
2014-12-05 22:17:59 -05:00
config . D3D11 . Header . BackBufferSize . w = m_scd . BufferDesc . Width ;
config . D3D11 . Header . BackBufferSize . h = m_scd . BufferDesc . Height ;
2014-12-21 21:55:33 -05:00
config . D3D11 . pBackBufferUAV = NULL ;
# else
config . D3D11 . Header . RTSize . w = m_scd . BufferDesc . Width ;
config . D3D11 . Header . RTSize . h = m_scd . BufferDesc . Height ;
# endif // OVR_VERSION > OVR_VERSION_042
2014-10-29 01:08:55 -04:00
config . D3D11 . Header . Multisample = 0 ;
2014-12-21 21:55:33 -05:00
config . D3D11 . pDevice = m_device ;
2014-10-29 01:08:55 -04:00
config . D3D11 . pDeviceContext = m_deviceCtx ;
config . D3D11 . pBackBufferRT = m_backBufferColor ;
config . D3D11 . pSwapChain = m_swapChain ;
2015-04-20 19:22:40 -04:00
if ( m_ovr . postReset ( g_platformData . nwh , & config . Config , ! ! ( m_flags & BGFX_RESET_HMD_DEBUG ) ) )
2014-10-29 01:08:55 -04:00
{
uint32_t size = sizeof ( uint32_t ) + sizeof ( TextureCreate ) ;
const Memory * mem = alloc ( size ) ;
bx : : StaticMemoryBlockWriter writer ( mem - > data , mem - > size ) ;
uint32_t magic = BGFX_CHUNK_MAGIC_TEX ;
bx : : write ( & writer , magic ) ;
TextureCreate tc ;
2015-07-16 23:28:43 -04:00
tc . m_flags = BGFX_TEXTURE_RT | ( ( ( m_flags & BGFX_RESET_MSAA_MASK ) > > BGFX_RESET_MSAA_SHIFT ) < < BGFX_TEXTURE_RT_MSAA_SHIFT ) ;
2014-10-29 01:08:55 -04:00
tc . m_width = m_ovr . m_rtSize . w ;
tc . m_height = m_ovr . m_rtSize . h ;
tc . m_sides = 0 ;
tc . m_depth = 0 ;
tc . m_numMips = 1 ;
tc . m_format = uint8_t ( bgfx : : TextureFormat : : BGRA8 ) ;
tc . m_cubeMap = false ;
tc . m_mem = NULL ;
bx : : write ( & writer , tc ) ;
m_ovrRT . create ( mem , tc . m_flags , 0 ) ;
release ( mem ) ;
DX_CHECK ( m_device - > CreateRenderTargetView ( m_ovrRT . m_ptr , NULL , & m_ovrRtv ) ) ;
D3D11_TEXTURE2D_DESC dsd ;
dsd . Width = m_ovr . m_rtSize . w ;
dsd . Height = m_ovr . m_rtSize . h ;
dsd . MipLevels = 1 ;
dsd . ArraySize = 1 ;
dsd . Format = DXGI_FORMAT_D24_UNORM_S8_UINT ;
dsd . SampleDesc = m_scd . SampleDesc ;
dsd . Usage = D3D11_USAGE_DEFAULT ;
dsd . BindFlags = D3D11_BIND_DEPTH_STENCIL ;
dsd . CPUAccessFlags = 0 ;
dsd . MiscFlags = 0 ;
ID3D11Texture2D * depthStencil ;
DX_CHECK ( m_device - > CreateTexture2D ( & dsd , NULL , & depthStencil ) ) ;
DX_CHECK ( m_device - > CreateDepthStencilView ( depthStencil , NULL , & m_ovrDsv ) ) ;
DX_RELEASE ( depthStencil , 0 ) ;
2014-11-22 17:13:14 -05:00
2014-10-29 01:08:55 -04:00
ovrD3D11Texture texture ;
texture . D3D11 . Header . API = ovrRenderAPI_D3D11 ;
texture . D3D11 . Header . TextureSize = m_ovr . m_rtSize ;
texture . D3D11 . pTexture = m_ovrRT . m_texture2d ;
texture . D3D11 . pSRView = m_ovrRT . m_srv ;
m_ovr . postReset ( texture . Texture ) ;
2015-01-20 03:04:30 -05:00
bx : : xchg ( m_ovrRtv , m_backBufferColor ) ;
2014-10-29 01:08:55 -04:00
BX_CHECK ( NULL = = m_backBufferDepthStencil , " " ) ;
2015-01-20 03:04:30 -05:00
bx : : xchg ( m_ovrDsv , m_backBufferDepthStencil ) ;
2014-10-29 01:08:55 -04:00
}
}
# endif // BGFX_CONFIG_USE_OVR
}
void ovrPreReset ( )
{
# if BGFX_CONFIG_USE_OVR
2014-11-13 00:26:28 -05:00
m_ovr . preReset ( ) ;
2014-10-29 01:08:55 -04:00
if ( NULL ! = m_ovrRtv )
{
2015-01-20 03:04:30 -05:00
bx : : xchg ( m_ovrRtv , m_backBufferColor ) ;
bx : : xchg ( m_ovrDsv , m_backBufferDepthStencil ) ;
2014-10-29 01:08:55 -04:00
BX_CHECK ( NULL = = m_backBufferDepthStencil , " " ) ;
DX_RELEASE ( m_ovrRtv , 0 ) ;
DX_RELEASE ( m_ovrDsv , 0 ) ;
m_ovrRT . destroy ( ) ;
}
# endif // BGFX_CONFIG_USE_OVR
}
2013-01-08 02:10:15 -05:00
void capturePostReset ( )
2012-12-30 23:52:47 -05:00
{
2013-01-22 00:40:54 -05:00
if ( m_flags & BGFX_RESET_CAPTURE )
2013-01-08 02:10:15 -05:00
{
2013-01-22 00:40:54 -05:00
ID3D11Texture2D * backBuffer ;
2015-07-16 23:28:43 -04:00
DX_CHECK ( m_swapChain - > GetBuffer ( 0 , IID_ID3D11Texture2D , ( void * * ) & backBuffer ) ) ;
2013-01-22 00:40:54 -05:00
D3D11_TEXTURE2D_DESC backBufferDesc ;
backBuffer - > GetDesc ( & backBufferDesc ) ;
D3D11_TEXTURE2D_DESC desc ;
memcpy ( & desc , & backBufferDesc , sizeof ( desc ) ) ;
2014-12-21 21:55:33 -05:00
desc . SampleDesc . Count = 1 ;
2013-01-22 00:40:54 -05:00
desc . SampleDesc . Quality = 0 ;
desc . Usage = D3D11_USAGE_STAGING ;
desc . BindFlags = 0 ;
desc . CPUAccessFlags = D3D11_CPU_ACCESS_READ ;
HRESULT hr = m_device - > CreateTexture2D ( & desc , NULL , & m_captureTexture ) ;
if ( SUCCEEDED ( hr ) )
2013-01-08 02:10:15 -05:00
{
2013-01-22 00:40:54 -05:00
if ( backBufferDesc . SampleDesc . Count ! = 1 )
{
desc . Usage = D3D11_USAGE_DEFAULT ;
desc . CPUAccessFlags = 0 ;
m_device - > CreateTexture2D ( & desc , NULL , & m_captureResolve ) ;
}
g_callback - > captureBegin ( backBufferDesc . Width , backBufferDesc . Height , backBufferDesc . Width * 4 , TextureFormat : : BGRA8 , false ) ;
2013-01-08 02:10:15 -05:00
}
2013-01-22 00:40:54 -05:00
DX_RELEASE ( backBuffer , 0 ) ;
2013-01-08 02:10:15 -05:00
}
2012-12-30 23:52:47 -05:00
}
2013-01-08 02:10:15 -05:00
void capturePreReset ( )
2012-12-30 23:52:47 -05:00
{
2013-01-08 02:10:15 -05:00
if ( NULL ! = m_captureTexture )
{
g_callback - > captureEnd ( ) ;
}
DX_RELEASE ( m_captureResolve , 0 ) ;
DX_RELEASE ( m_captureTexture , 0 ) ;
2012-12-30 23:52:47 -05:00
}
void capture ( )
{
2013-01-22 00:40:54 -05:00
if ( NULL ! = m_captureTexture )
{
ID3D11Texture2D * backBuffer ;
2015-07-16 23:28:43 -04:00
DX_CHECK ( m_swapChain - > GetBuffer ( 0 , IID_ID3D11Texture2D , ( void * * ) & backBuffer ) ) ;
2013-01-08 02:10:15 -05:00
2013-01-22 00:40:54 -05:00
if ( NULL = = m_captureResolve )
{
m_deviceCtx - > CopyResource ( m_captureTexture , backBuffer ) ;
}
else
{
2015-07-16 23:28:43 -04:00
m_deviceCtx - > ResolveSubresource ( m_captureResolve , 0 , backBuffer , 0 , getBufferFormat ( ) ) ;
2013-01-22 00:40:54 -05:00
m_deviceCtx - > CopyResource ( m_captureTexture , m_captureResolve ) ;
}
2013-01-08 02:10:15 -05:00
2013-01-22 00:40:54 -05:00
D3D11_MAPPED_SUBRESOURCE mapped ;
DX_CHECK ( m_deviceCtx - > Map ( m_captureTexture , 0 , D3D11_MAP_READ , 0 , & mapped ) ) ;
2013-01-08 02:10:15 -05:00
2014-11-14 08:22:32 -05:00
g_callback - > captureFrame ( mapped . pData , getBufferHeight ( ) * mapped . RowPitch ) ;
2013-01-08 02:10:15 -05:00
2013-01-22 00:40:54 -05:00
m_deviceCtx - > Unmap ( m_captureTexture , 0 ) ;
2013-01-08 02:10:15 -05:00
2013-01-22 00:40:54 -05:00
DX_RELEASE ( backBuffer , 0 ) ;
}
2012-12-30 23:52:47 -05:00
}
2014-05-26 17:09:26 -04:00
void commit ( ConstantBuffer & _constantBuffer )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
_constantBuffer . reset ( ) ;
2012-07-23 00:08:58 -04:00
2014-08-22 00:02:41 -04:00
for ( ; ; )
2014-05-26 17:09:26 -04:00
{
uint32_t opcode = _constantBuffer . read ( ) ;
2012-07-23 00:08:58 -04:00
2014-05-26 17:09:26 -04:00
if ( UniformType : : End = = opcode )
{
break ;
}
2012-07-23 00:08:58 -04:00
2014-05-26 17:09:26 -04:00
UniformType : : Enum type ;
uint16_t loc ;
uint16_t num ;
uint16_t copy ;
ConstantBuffer : : decodeOpcode ( opcode , type , loc , num , copy ) ;
const char * data ;
if ( copy )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
data = _constantBuffer . read ( g_uniformTypeSize [ type ] * num ) ;
2012-08-19 21:50:23 -04:00
}
else
{
2014-05-26 17:09:26 -04:00
UniformHandle handle ;
memcpy ( & handle , _constantBuffer . read ( sizeof ( UniformHandle ) ) , sizeof ( UniformHandle ) ) ;
data = ( const char * ) m_uniforms [ handle . idx ] ;
}
# define CASE_IMPLEMENT_UNIFORM(_uniform, _dxsuffix, _type) \
case UniformType : : _uniform : \
case UniformType : : _uniform | BGFX_UNIFORM_FRAGMENTBIT : \
{ \
2015-04-07 20:58:14 -04:00
setShaderUniform ( uint8_t ( type ) , loc , data , num ) ; \
2014-05-26 17:09:26 -04:00
} \
break ;
2015-04-07 20:58:14 -04:00
switch ( ( uint32_t ) type )
2014-05-26 17:09:26 -04:00
{
2015-05-28 18:27:00 -04:00
case UniformType : : Mat3 :
case UniformType : : Mat3 | BGFX_UNIFORM_FRAGMENTBIT : \
2014-05-26 17:09:26 -04:00
{
float * value = ( float * ) data ;
for ( uint32_t ii = 0 , count = num / 3 ; ii < count ; + + ii , loc + = 3 * 16 , 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 ;
2015-04-07 20:58:14 -04:00
setShaderUniform ( uint8_t ( type ) , loc , & mtx . un . val [ 0 ] , 3 ) ;
2014-05-26 17:09:26 -04:00
}
2012-08-19 21:50:23 -04:00
}
2014-05-26 17:09:26 -04:00
break ;
2015-05-28 18:27:00 -04:00
CASE_IMPLEMENT_UNIFORM ( Int1 , I , int ) ;
CASE_IMPLEMENT_UNIFORM ( Vec4 , F , float ) ;
CASE_IMPLEMENT_UNIFORM ( Mat4 , F , float ) ;
2014-05-26 17:09:26 -04:00
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 ;
2012-07-23 00:08:58 -04:00
}
2014-05-26 17:09:26 -04:00
# undef CASE_IMPLEMENT_UNIFORM
2012-07-23 00:08:58 -04:00
2014-08-22 00:02:41 -04:00
}
2014-05-26 17:09:26 -04:00
}
2014-09-01 14:24:51 -04:00
void clearQuad ( ClearQuad & _clearQuad , const Rect & _rect , const Clear & _clear , const float _palette [ ] [ 4 ] )
2014-05-26 17:09:26 -04:00
{
2014-11-14 08:22:32 -05:00
uint32_t width = getBufferWidth ( ) ;
uint32_t height = getBufferHeight ( ) ;
2014-05-26 17:09:26 -04:00
2014-09-01 14:24:51 -04:00
if ( 0 = = _rect . m_x
& & 0 = = _rect . m_y
& & width = = _rect . m_width
2014-05-26 17:09:26 -04:00
& & height = = _rect . m_height )
{
2014-09-01 14:24:51 -04:00
clear ( _clear , _palette ) ;
2012-07-23 00:08:58 -04:00
}
2014-05-26 17:09:26 -04:00
else
{
ID3D11DeviceContext * deviceCtx = m_deviceCtx ;
uint64_t state = 0 ;
2015-01-11 00:39:45 -05:00
state | = _clear . m_flags & BGFX_CLEAR_COLOR ? BGFX_STATE_RGB_WRITE | BGFX_STATE_ALPHA_WRITE : 0 ;
state | = _clear . m_flags & BGFX_CLEAR_DEPTH ? BGFX_STATE_DEPTH_TEST_ALWAYS | BGFX_STATE_DEPTH_WRITE : 0 ;
2014-05-26 17:09:26 -04:00
uint64_t stencil = 0 ;
2015-01-11 00:39:45 -05:00
stencil | = _clear . m_flags & BGFX_CLEAR_STENCIL ? 0
2014-05-26 17:09:26 -04:00
| BGFX_STENCIL_TEST_ALWAYS
| BGFX_STENCIL_FUNC_REF ( _clear . m_stencil )
| BGFX_STENCIL_FUNC_RMASK ( 0xff )
| BGFX_STENCIL_OP_FAIL_S_REPLACE
| BGFX_STENCIL_OP_FAIL_Z_REPLACE
| BGFX_STENCIL_OP_PASS_Z_REPLACE
: 0
;
setBlendState ( state ) ;
setDepthStencilState ( state , stencil ) ;
setRasterizerState ( state ) ;
2014-09-01 14:24:51 -04:00
uint32_t numMrt = 1 ;
2014-05-26 17:09:26 -04:00
FrameBufferHandle fbh = m_fbh ;
if ( isValid ( fbh ) )
{
const FrameBufferD3D11 & fb = m_frameBuffers [ fbh . idx ] ;
2014-09-01 14:24:51 -04:00
numMrt = bx : : uint32_max ( 1 , fb . m_num ) ;
2014-05-26 17:09:26 -04:00
}
2012-07-23 00:08:58 -04:00
2014-09-01 14:24:51 -04:00
ProgramD3D11 & program = m_program [ _clearQuad . m_program [ numMrt - 1 ] . idx ] ;
2014-05-26 17:09:26 -04:00
m_currentProgram = & program ;
2014-07-20 23:27:13 -04:00
deviceCtx - > VSSetShader ( program . m_vsh - > m_vertexShader , NULL , 0 ) ;
2014-05-26 17:09:26 -04:00
deviceCtx - > VSSetConstantBuffers ( 0 , 0 , NULL ) ;
if ( NULL ! = m_currentColor )
{
2014-09-01 14:24:51 -04:00
const ShaderD3D11 * fsh = program . m_fsh ;
deviceCtx - > PSSetShader ( fsh - > m_pixelShader , NULL , 0 ) ;
deviceCtx - > PSSetConstantBuffers ( 0 , 1 , & fsh - > m_buffer ) ;
2015-01-11 21:02:34 -05:00
if ( BGFX_CLEAR_COLOR_USE_PALETTE & _clear . m_flags )
2014-09-01 14:24:51 -04: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 ) ;
}
deviceCtx - > UpdateSubresource ( fsh - > m_buffer , 0 , 0 , mrtClear , 0 , 0 ) ;
}
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 ,
} ;
2015-01-06 06:23:50 -05:00
2014-09-01 14:24:51 -04:00
deviceCtx - > UpdateSubresource ( fsh - > m_buffer , 0 , 0 , rgba , 0 , 0 ) ;
}
2014-05-26 17:09:26 -04:00
}
else
{
deviceCtx - > PSSetShader ( NULL , NULL , 0 ) ;
}
VertexBufferD3D11 & vb = m_vertexBuffers [ _clearQuad . m_vb - > handle . idx ] ;
2014-09-01 14:24:51 -04:00
const VertexDecl & vertexDecl = m_vertexDecls [ _clearQuad . m_vb - > decl . idx ] ;
const uint32_t stride = vertexDecl . m_stride ;
const uint32_t offset = 0 ;
2014-05-26 17:09:26 -04:00
{
struct Vertex
{
float m_x ;
float m_y ;
float m_z ;
2014-09-01 14:24:51 -04:00
} ;
2014-11-22 17:13:14 -05:00
2014-09-01 14:24:51 -04:00
Vertex * vertex = ( Vertex * ) _clearQuad . m_vb - > data ;
2014-05-26 17:09:26 -04:00
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 + + ;
2014-09-01 14:24:51 -04:00
vertex - > m_x = - 1.0f ;
2014-05-26 17:09:26 -04:00
vertex - > m_y = 1.0f ;
vertex - > m_z = depth ;
vertex + + ;
2014-09-01 14:24:51 -04:00
vertex - > m_x = 1.0f ;
2014-05-26 17:09:26 -04:00
vertex - > m_y = 1.0f ;
vertex - > m_z = depth ;
}
m_vertexBuffers [ _clearQuad . m_vb - > handle . idx ] . update ( 0 , 4 * _clearQuad . m_decl . m_stride , _clearQuad . m_vb - > data ) ;
deviceCtx - > IASetVertexBuffers ( 0 , 1 , & vb . m_ptr , & stride , & offset ) ;
setInputLayout ( vertexDecl , program , 0 ) ;
2014-09-01 14:24:51 -04:00
deviceCtx - > IASetPrimitiveTopology ( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP ) ;
deviceCtx - > Draw ( 4 , 0 ) ;
2014-05-26 17:09:26 -04:00
}
2012-07-23 00:08:58 -04:00
}
2014-10-07 01:10:55 -04:00
void * m_d3d9dll ;
2013-07-27 01:55:13 -04:00
void * m_d3d11dll ;
void * m_dxgidll ;
2015-07-29 17:49:24 -04:00
void * m_dxgidebugdll ;
2014-08-05 01:01:20 -04:00
2014-09-26 01:41:53 -04:00
void * m_renderdocdll ;
2015-04-20 19:22:40 -04:00
D3D_DRIVER_TYPE m_driverType ;
2015-04-16 19:24:05 -04:00
D3D_FEATURE_LEVEL m_featureLevel ;
2015-04-20 19:22:40 -04:00
IDXGIAdapter * m_adapter ;
2013-04-27 21:03:40 -04:00
DXGI_ADAPTER_DESC m_adapterDesc ;
2014-11-14 08:22:32 -05:00
# if BX_PLATFORM_WINRT
2015-04-20 19:22:40 -04:00
IDXGIFactory2 * m_factory ;
IDXGISwapChain1 * m_swapChain ;
2014-11-14 08:22:32 -05:00
# else
2015-04-20 19:22:40 -04:00
IDXGIFactory * m_factory ;
IDXGISwapChain * m_swapChain ;
# endif // BX_PLATFORM_WINRT
2014-09-07 20:17:38 -04:00
2014-10-01 00:16:24 -04:00
uint16_t m_lost ;
2014-09-07 20:17:38 -04:00
uint16_t m_numWindows ;
FrameBufferHandle m_windows [ BGFX_CONFIG_MAX_FRAME_BUFFERS ] ;
2015-05-12 20:03:25 -04:00
ID3D11Device * m_device ;
ID3D11DeviceContext * m_deviceCtx ;
ID3D11InfoQueue * m_infoQueue ;
TimerQueryD3D11 m_gpuTimer ;
2015-04-29 20:18:51 -04:00
2012-07-23 00:08:58 -04:00
ID3D11RenderTargetView * m_backBufferColor ;
ID3D11DepthStencilView * m_backBufferDepthStencil ;
2012-11-25 21:24:50 -05:00
ID3D11RenderTargetView * m_currentColor ;
ID3D11DepthStencilView * m_currentDepthStencil ;
2012-07-23 00:08:58 -04:00
2013-01-08 02:10:15 -05:00
ID3D11Texture2D * m_captureTexture ;
ID3D11Texture2D * m_captureResolve ;
2014-05-26 17:09:26 -04:00
Resolution m_resolution ;
2012-08-05 17:51:49 -04:00
bool m_wireframe ;
2014-11-14 08:22:32 -05:00
# if BX_PLATFORM_WINRT
2015-06-05 13:43:43 -04:00
typedef DXGI_SWAP_CHAIN_DESC1 SwapChainDesc ;
2014-11-14 08:22:32 -05:00
# else
2015-06-05 13:43:43 -04:00
typedef DXGI_SWAP_CHAIN_DESC SwapChainDesc ;
# endif // BX_PLATFORM_WINRT
SwapChainDesc m_scd ;
2012-07-23 00:08:58 -04:00
uint32_t m_flags ;
2015-01-21 23:39:42 -05:00
uint32_t m_maxAnisotropy ;
2012-07-23 00:08:58 -04:00
2014-05-26 17:09:26 -04:00
IndexBufferD3D11 m_indexBuffers [ BGFX_CONFIG_MAX_INDEX_BUFFERS ] ;
VertexBufferD3D11 m_vertexBuffers [ BGFX_CONFIG_MAX_VERTEX_BUFFERS ] ;
ShaderD3D11 m_shaders [ BGFX_CONFIG_MAX_SHADERS ] ;
ProgramD3D11 m_program [ BGFX_CONFIG_MAX_PROGRAMS ] ;
TextureD3D11 m_textures [ BGFX_CONFIG_MAX_TEXTURES ] ;
2012-07-23 00:08:58 -04:00
VertexDecl m_vertexDecls [ BGFX_CONFIG_MAX_VERTEX_DECLS ] ;
2014-05-26 17:09:26 -04:00
FrameBufferD3D11 m_frameBuffers [ BGFX_CONFIG_MAX_FRAME_BUFFERS ] ;
2014-04-15 22:10:56 -04:00
void * m_uniforms [ BGFX_CONFIG_MAX_UNIFORMS ] ;
Matrix4 m_predefinedUniforms [ PredefinedUniform : : Count ] ;
2012-07-23 00:08:58 -04:00
UniformRegistry m_uniformReg ;
2015-04-17 22:06:09 -04:00
ViewState m_viewState ;
2014-11-22 17:13:14 -05:00
2012-07-23 00:08:58 -04:00
StateCacheT < ID3D11BlendState > m_blendStateCache ;
StateCacheT < ID3D11DepthStencilState > m_depthStencilStateCache ;
StateCacheT < ID3D11InputLayout > m_inputLayoutCache ;
StateCacheT < ID3D11RasterizerState > m_rasterizerStateCache ;
StateCacheT < ID3D11SamplerState > m_samplerStateCache ;
TextVideoMem m_textVideoMem ;
2012-08-05 17:51:49 -04:00
TextureStage m_textureStage ;
2014-05-26 17:09:26 -04:00
ProgramD3D11 * m_currentProgram ;
2012-07-23 00:08:58 -04:00
uint8_t m_vsScratch [ 64 < < 10 ] ;
uint8_t m_fsScratch [ 64 < < 10 ] ;
uint32_t m_vsChanges ;
uint32_t m_fsChanges ;
2014-02-06 02:07:11 -05:00
FrameBufferHandle m_fbh ;
bool m_rtMsaa ;
2014-10-29 01:08:55 -04:00
OVR m_ovr ;
TextureD3D11 m_ovrRT ;
ID3D11RenderTargetView * m_ovrRtv ;
ID3D11DepthStencilView * m_ovrDsv ;
2012-07-23 00:08:58 -04:00
} ;
2014-05-26 17:09:26 -04:00
static RendererContextD3D11 * s_renderD3D11 ;
2015-03-22 01:11:59 -04:00
RendererContextI * rendererCreate ( )
2014-05-26 17:09:26 -04:00
{
s_renderD3D11 = BX_NEW ( g_allocator , RendererContextD3D11 ) ;
2015-07-30 21:36:12 -04:00
if ( ! s_renderD3D11 - > init ( ) )
{
BX_DELETE ( g_allocator , s_renderD3D11 ) ;
s_renderD3D11 = NULL ;
}
2014-05-26 17:09:26 -04:00
return s_renderD3D11 ;
}
2015-03-22 01:11:59 -04:00
void rendererDestroy ( )
2014-05-26 17:09:26 -04:00
{
2014-10-14 00:14:51 -04:00
s_renderD3D11 - > shutdown ( ) ;
2014-05-26 17:09:26 -04:00
BX_DELETE ( g_allocator , s_renderD3D11 ) ;
s_renderD3D11 = NULL ;
}
2012-07-23 00:08:58 -04:00
2015-05-14 14:37:32 -04:00
struct UavFormat
{
DXGI_FORMAT format [ 3 ] ;
uint32_t stride ;
} ;
static const UavFormat s_uavFormat [ ] =
{ // BGFX_BUFFER_COMPUTE_TYPE_UINT, BGFX_BUFFER_COMPUTE_TYPE_INT, BGFX_BUFFER_COMPUTE_TYPE_FLOAT
{ { DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN , DXGI_FORMAT_UNKNOWN } , 0 } , // ignored
{ { DXGI_FORMAT_R8_SINT , DXGI_FORMAT_R8_UINT , DXGI_FORMAT_UNKNOWN } , 1 } , // BGFX_BUFFER_COMPUTE_FORMAT_8x1
{ { DXGI_FORMAT_R8G8_SINT , DXGI_FORMAT_R8G8_UINT , DXGI_FORMAT_UNKNOWN } , 2 } , // BGFX_BUFFER_COMPUTE_FORMAT_8x2
{ { DXGI_FORMAT_R8G8B8A8_SINT , DXGI_FORMAT_R8G8B8A8_UINT , DXGI_FORMAT_UNKNOWN } , 4 } , // BGFX_BUFFER_COMPUTE_FORMAT_8x4
{ { DXGI_FORMAT_R16_SINT , DXGI_FORMAT_R16_UINT , DXGI_FORMAT_R16_FLOAT } , 2 } , // BGFX_BUFFER_COMPUTE_FORMAT_16x1
{ { DXGI_FORMAT_R16G16_SINT , DXGI_FORMAT_R16G16_UINT , DXGI_FORMAT_R16G16_FLOAT } , 4 } , // BGFX_BUFFER_COMPUTE_FORMAT_16x2
{ { DXGI_FORMAT_R16G16B16A16_SINT , DXGI_FORMAT_R16G16B16A16_UINT , DXGI_FORMAT_R16G16B16A16_FLOAT } , 8 } , // BGFX_BUFFER_COMPUTE_FORMAT_16x4
{ { DXGI_FORMAT_R32_SINT , DXGI_FORMAT_R32_UINT , DXGI_FORMAT_R32_FLOAT } , 4 } , // BGFX_BUFFER_COMPUTE_FORMAT_32x1
{ { DXGI_FORMAT_R32G32_SINT , DXGI_FORMAT_R32G32_UINT , DXGI_FORMAT_R32G32_FLOAT } , 8 } , // BGFX_BUFFER_COMPUTE_FORMAT_32x2
{ { DXGI_FORMAT_R32G32B32A32_SINT , DXGI_FORMAT_R32G32B32A32_UINT , DXGI_FORMAT_R32G32B32A32_FLOAT } , 16 } , // BGFX_BUFFER_COMPUTE_FORMAT_32x4
} ;
void BufferD3D11 : : create ( uint32_t _size , void * _data , uint16_t _flags , uint16_t _stride , bool _vertex )
2012-07-23 00:08:58 -04:00
{
2015-04-08 22:59:48 -04:00
m_uav = NULL ;
m_size = _size ;
m_flags = _flags ;
2014-12-10 02:16:27 -05:00
2015-04-29 20:18:51 -04:00
const bool needUav = 0 ! = ( _flags & ( BGFX_BUFFER_COMPUTE_WRITE | BGFX_BUFFER_DRAW_INDIRECT ) ) ;
2014-12-10 02:16:27 -05:00
const bool needSrv = 0 ! = ( _flags & BGFX_BUFFER_COMPUTE_READ ) ;
2015-04-29 20:18:51 -04:00
const bool drawIndirect = 0 ! = ( _flags & BGFX_BUFFER_DRAW_INDIRECT ) ;
2014-12-10 02:16:27 -05:00
m_dynamic = NULL = = _data & & ! needUav ;
2012-07-23 00:08:58 -04:00
D3D11_BUFFER_DESC desc ;
desc . ByteWidth = _size ;
2014-12-10 02:16:27 -05:00
desc . BindFlags = 0
2015-01-10 23:38:47 -05:00
| ( _vertex ? D3D11_BIND_VERTEX_BUFFER : D3D11_BIND_INDEX_BUFFER )
2014-12-10 02:16:27 -05:00
| ( needUav ? D3D11_BIND_UNORDERED_ACCESS : 0 )
| ( needSrv ? D3D11_BIND_SHADER_RESOURCE : 0 )
;
2015-04-29 20:18:51 -04:00
desc . MiscFlags = 0
| ( drawIndirect ? D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS : 0 )
;
2014-12-10 02:16:27 -05:00
desc . StructureByteStride = 0 ;
2012-07-23 00:08:58 -04:00
2015-05-14 14:37:32 -04:00
DXGI_FORMAT format ;
uint32_t stride ;
2015-05-14 17:38:53 -04:00
if ( drawIndirect )
2015-05-14 14:37:32 -04:00
{
2015-05-14 17:38:53 -04:00
format = DXGI_FORMAT_R32G32B32A32_UINT ;
stride = 16 ;
}
else
{
uint32_t uavFormat = ( _flags & BGFX_BUFFER_COMPUTE_FORMAT_MASK ) > > BGFX_BUFFER_COMPUTE_FORMAT_SHIFT ;
if ( 0 = = uavFormat )
2015-05-14 14:37:32 -04:00
{
2015-05-14 17:38:53 -04:00
if ( _vertex )
2015-05-14 14:37:32 -04:00
{
2015-05-14 17:38:53 -04:00
format = DXGI_FORMAT_R32G32B32A32_FLOAT ;
stride = 16 ;
2015-05-14 14:37:32 -04:00
}
else
{
2015-05-14 17:38:53 -04:00
if ( 0 = = ( _flags & BGFX_BUFFER_INDEX32 ) )
{
format = DXGI_FORMAT_R16_UINT ;
stride = 2 ;
}
else
{
format = DXGI_FORMAT_R32_UINT ;
stride = 4 ;
}
2015-05-14 14:37:32 -04:00
}
}
2015-05-14 17:38:53 -04:00
else
{
const uint32_t uavType = bx : : uint32_satsub ( ( _flags & BGFX_BUFFER_COMPUTE_TYPE_MASK ) > > BGFX_BUFFER_COMPUTE_TYPE_SHIFT , 1 ) ;
format = s_uavFormat [ uavFormat ] . format [ uavType ] ;
stride = s_uavFormat [ uavFormat ] . stride ;
}
2015-05-14 14:37:32 -04:00
}
2015-01-10 23:38:47 -05:00
2014-12-10 02:16:27 -05:00
ID3D11Device * device = s_renderD3D11 - > m_device ;
if ( needUav )
{
desc . Usage = D3D11_USAGE_DEFAULT ;
desc . CPUAccessFlags = 0 ;
2015-01-10 23:38:47 -05:00
desc . StructureByteStride = _stride ;
2014-12-10 02:16:27 -05:00
DX_CHECK ( device - > CreateBuffer ( & desc
, NULL
, & m_ptr
2015-04-29 20:18:51 -04:00
) ) ;
2014-12-10 02:16:27 -05:00
D3D11_UNORDERED_ACCESS_VIEW_DESC uavd ;
2015-01-10 23:38:47 -05:00
uavd . Format = format ;
2014-12-10 02:16:27 -05:00
uavd . ViewDimension = D3D11_UAV_DIMENSION_BUFFER ;
uavd . Buffer . FirstElement = 0 ;
2015-05-14 14:37:32 -04:00
uavd . Buffer . NumElements = m_size / stride ;
2014-12-10 02:16:27 -05:00
uavd . Buffer . Flags = 0 ;
DX_CHECK ( device - > CreateUnorderedAccessView ( m_ptr
, & uavd
, & m_uav
2015-04-29 20:18:51 -04:00
) ) ;
2014-12-10 02:16:27 -05:00
}
else if ( m_dynamic )
2012-07-23 00:08:58 -04:00
{
desc . Usage = D3D11_USAGE_DYNAMIC ;
desc . CPUAccessFlags = D3D11_CPU_ACCESS_WRITE ;
2014-12-10 02:16:27 -05:00
DX_CHECK ( device - > CreateBuffer ( & desc
2012-07-23 00:08:58 -04:00
, NULL
, & m_ptr
2015-04-29 20:18:51 -04:00
) ) ;
2012-07-23 00:08:58 -04:00
}
else
{
2012-11-03 16:12:26 -04:00
desc . Usage = D3D11_USAGE_IMMUTABLE ;
2012-07-23 00:08:58 -04:00
desc . CPUAccessFlags = 0 ;
D3D11_SUBRESOURCE_DATA srd ;
srd . pSysMem = _data ;
srd . SysMemPitch = 0 ;
srd . SysMemSlicePitch = 0 ;
2014-12-10 02:16:27 -05:00
DX_CHECK ( device - > CreateBuffer ( & desc
2012-07-23 00:08:58 -04:00
, & srd
, & m_ptr
2015-04-29 20:18:51 -04:00
) ) ;
2012-07-23 00:08:58 -04:00
}
2014-12-10 02:16:27 -05:00
if ( needSrv )
{
D3D11_SHADER_RESOURCE_VIEW_DESC srvd ;
2015-01-10 23:38:47 -05:00
srvd . Format = format ;
2014-12-10 02:16:27 -05:00
srvd . ViewDimension = D3D11_SRV_DIMENSION_BUFFER ;
srvd . Buffer . FirstElement = 0 ;
2015-05-14 14:37:32 -04:00
srvd . Buffer . NumElements = m_size / stride ;
2014-12-10 02:16:27 -05:00
DX_CHECK ( device - > CreateShaderResourceView ( m_ptr
, & srvd
, & m_srv
2015-04-29 20:18:51 -04:00
) ) ;
2014-12-10 02:16:27 -05:00
}
2012-07-23 00:08:58 -04:00
}
2015-01-10 23:38:47 -05:00
void BufferD3D11 : : update ( uint32_t _offset , uint32_t _size , void * _data , bool _discard )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
ID3D11DeviceContext * deviceCtx = s_renderD3D11 - > m_deviceCtx ;
2012-07-23 00:08:58 -04:00
BX_CHECK ( m_dynamic , " Must be dynamic! " ) ;
2015-04-13 21:39:38 -04:00
#if 0
2015-03-03 17:37:18 -05:00
BX_UNUSED ( _discard ) ;
ID3D11Device * device = s_renderD3D11 - > m_device ;
D3D11_BUFFER_DESC desc ;
desc . ByteWidth = _size ;
desc . Usage = D3D11_USAGE_STAGING ;
desc . BindFlags = 0 ;
desc . MiscFlags = 0 ;
desc . CPUAccessFlags = D3D11_CPU_ACCESS_WRITE ;
desc . StructureByteStride = 0 ;
D3D11_SUBRESOURCE_DATA srd ;
srd . pSysMem = _data ;
srd . SysMemPitch = 0 ;
srd . SysMemSlicePitch = 0 ;
ID3D11Buffer * ptr ;
DX_CHECK ( device - > CreateBuffer ( & desc , & srd , & ptr ) ) ;
2015-03-03 18:16:17 -05:00
D3D11_BOX box ;
box . left = 0 ;
box . top = 0 ;
box . front = 0 ;
box . right = _size ;
box . bottom = 1 ;
box . back = 1 ;
2015-03-03 17:37:18 -05:00
deviceCtx - > CopySubresourceRegion ( m_ptr
, 0
, _offset
, 0
, 0
, ptr
, 0
2015-03-03 18:16:17 -05:00
, & box
2015-03-03 17:37:18 -05:00
) ;
DX_RELEASE ( ptr , 0 ) ;
# else
2012-07-23 00:08:58 -04:00
D3D11_MAPPED_SUBRESOURCE mapped ;
2015-01-30 13:31:50 -05:00
BX_UNUSED ( _discard ) ;
D3D11_MAP type = D3D11_MAP_WRITE_DISCARD ;
2015-07-16 23:28:43 -04:00
DX_CHECK ( deviceCtx - > Map ( m_ptr , 0 , type , 0 , & mapped ) ) ;
2015-03-03 17:37:18 -05:00
memcpy ( ( uint8_t * ) mapped . pData + _offset , _data , _size ) ;
2012-07-23 00:08:58 -04:00
deviceCtx - > Unmap ( m_ptr , 0 ) ;
2015-03-03 17:37:18 -05:00
# endif // 0
2012-07-23 00:08:58 -04:00
}
2015-05-14 14:37:32 -04:00
void VertexBufferD3D11 : : create ( uint32_t _size , void * _data , VertexDeclHandle _declHandle , uint16_t _flags )
2015-01-10 23:38:47 -05:00
{
m_decl = _declHandle ;
uint16_t stride = isValid ( _declHandle )
? s_renderD3D11 - > m_vertexDecls [ _declHandle . idx ] . m_stride
: 0
;
2015-04-08 22:59:48 -04:00
BufferD3D11 : : create ( _size , _data , _flags , stride , true ) ;
2015-01-10 23:38:47 -05:00
}
2014-05-26 17:09:26 -04:00
void ShaderD3D11 : : create ( const Memory * _mem )
2012-07-23 00:08:58 -04:00
{
2012-11-25 21:24:50 -05:00
bx : : MemoryReader reader ( _mem - > data , _mem - > size ) ;
uint32_t magic ;
bx : : read ( & reader , magic ) ;
2012-07-23 00:08:58 -04:00
2014-03-29 22:42:57 -04:00
switch ( magic )
{
2014-07-20 23:27:13 -04:00
case BGFX_CHUNK_MAGIC_CSH :
2014-03-29 22:42:57 -04:00
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 21:24:50 -05:00
uint32_t iohash ;
bx : : read ( & reader , iohash ) ;
2012-08-05 17:51:49 -04:00
2012-07-23 00:08:58 -04:00
uint16_t count ;
2012-11-25 21:24:50 -05:00
bx : : read ( & reader , count ) ;
2012-07-23 00:08:58 -04:00
m_numPredefined = 0 ;
m_numUniforms = count ;
2014-07-20 23:27:13 -04:00
BX_TRACE ( " %s Shader consts %d "
, BGFX_CHUNK_MAGIC_FSH = = magic ? " Fragment " : BGFX_CHUNK_MAGIC_VSH = = magic ? " Vertex " : " Compute "
, count
) ;
2012-07-23 00:08:58 -04:00
2014-03-29 22:42:57 -04:00
uint8_t fragmentBit = fragment ? BGFX_UNIFORM_FRAGMENTBIT : 0 ;
2012-07-23 00:08:58 -04:00
2012-11-25 21:24:50 -05:00
if ( 0 < count )
2012-07-23 00:08:58 -04:00
{
2012-11-25 21:24:50 -05:00
for ( uint32_t ii = 0 ; ii < count ; + + ii )
{
uint8_t nameSize ;
bx : : read ( & reader , nameSize ) ;
2012-07-23 00:08:58 -04:00
2012-11-25 21:24:50 -05:00
char name [ 256 ] ;
bx : : read ( & reader , & name , nameSize ) ;
name [ nameSize ] = ' \0 ' ;
2012-07-23 00:08:58 -04:00
2012-11-25 21:24:50 -05:00
uint8_t type ;
bx : : read ( & reader , type ) ;
2012-07-23 00:08:58 -04:00
2012-11-25 21:24:50 -05:00
uint8_t num ;
bx : : read ( & reader , num ) ;
2012-07-23 00:08:58 -04:00
2012-11-25 21:24:50 -05:00
uint16_t regIndex ;
bx : : read ( & reader , regIndex ) ;
2012-07-23 00:08:58 -04:00
2012-11-25 21:24:50 -05:00
uint16_t regCount ;
bx : : read ( & reader , regCount ) ;
2012-07-23 00:08:58 -04:00
2012-11-25 21:24:50 -05:00
const char * kind = " invalid " ;
2012-07-23 00:08:58 -04:00
2012-11-25 21:24:50 -05:00
PredefinedUniform : : Enum predefined = nameToPredefinedUniformEnum ( name ) ;
if ( PredefinedUniform : : Count ! = predefined )
2012-07-23 00:08:58 -04:00
{
2012-11-25 21:24:50 -05:00
kind = " predefined " ;
2014-04-15 22:10:56 -04:00
m_predefined [ m_numPredefined ] . m_loc = regIndex ;
2012-11-25 21:24:50 -05:00
m_predefined [ m_numPredefined ] . m_count = regCount ;
2015-04-07 20:58:14 -04:00
m_predefined [ m_numPredefined ] . m_type = uint8_t ( predefined | fragmentBit ) ;
2012-11-25 21:24:50 -05:00
m_numPredefined + + ;
}
else
{
2014-05-26 17:09:26 -04:00
const UniformInfo * info = s_renderD3D11 - > m_uniformReg . find ( name ) ;
2012-11-25 21:24:50 -05:00
2014-04-15 22:10:56 -04:00
if ( NULL ! = info )
2012-11-25 21:24:50 -05:00
{
2014-10-08 22:36:59 -04:00
if ( NULL = = m_constantBuffer )
{
m_constantBuffer = ConstantBuffer : : create ( 1024 ) ;
}
2012-11-25 21:24:50 -05:00
kind = " user " ;
2014-04-15 22:10:56 -04:00
m_constantBuffer - > writeUniformHandle ( ( UniformType : : Enum ) ( type | fragmentBit ) , regIndex , info - > m_handle , regCount ) ;
2012-11-25 21:24:50 -05:00
}
2012-07-23 00:08:58 -04:00
}
2012-11-25 21:24:50 -05:00
2014-07-20 23:27:13 -04:00
BX_TRACE ( " \t %s: %s (%s), num %2d, r.index %3d, r.count %2d "
2012-11-25 21:24:50 -05:00
, kind
, name
2014-07-20 23:27:13 -04:00
, getUniformTypeName ( UniformType : : Enum ( type & ~ BGFX_UNIFORM_FRAGMENTBIT ) )
2012-11-25 21:24:50 -05:00
, num
, regIndex
, regCount
) ;
2014-09-18 09:33:09 -04:00
BX_UNUSED ( kind ) ;
2012-07-23 00:08:58 -04:00
}
2014-10-08 22:36:59 -04:00
if ( NULL ! = m_constantBuffer )
{
m_constantBuffer - > finish ( ) ;
}
2012-07-23 00:08:58 -04:00
}
uint16_t shaderSize ;
2012-11-25 21:24:50 -05:00
bx : : read ( & reader , shaderSize ) ;
2012-07-23 00:08:58 -04:00
2012-11-25 21:24:50 -05:00
const DWORD * code = ( const DWORD * ) reader . getDataPtr ( ) ;
2014-04-15 22:10:56 -04:00
bx : : skip ( & reader , shaderSize + 1 ) ;
2012-07-23 00:08:58 -04:00
2014-07-20 23:27:13 -04:00
if ( BGFX_CHUNK_MAGIC_FSH = = magic )
2012-07-23 00:08:58 -04:00
{
2014-07-20 23:27:13 -04:00
DX_CHECK ( s_renderD3D11 - > m_device - > CreatePixelShader ( code , shaderSize , NULL , & m_pixelShader ) ) ;
2012-11-25 22:40:53 -05:00
BGFX_FATAL ( NULL ! = m_ptr , bgfx : : Fatal : : InvalidShader , " Failed to create fragment shader. " ) ;
2012-07-23 00:08:58 -04:00
}
2014-07-20 23:27:13 -04:00
else if ( BGFX_CHUNK_MAGIC_VSH = = magic )
2012-07-23 00:08:58 -04:00
{
2013-08-04 01:15:13 -04:00
m_hash = bx : : hashMurmur2A ( code , shaderSize ) ;
2014-10-06 22:21:08 -04:00
m_code = copy ( code , shaderSize ) ;
2012-07-23 00:08:58 -04:00
2014-07-20 23:27:13 -04:00
DX_CHECK ( s_renderD3D11 - > m_device - > CreateVertexShader ( code , shaderSize , NULL , & m_vertexShader ) ) ;
2012-11-25 22:40:53 -05:00
BGFX_FATAL ( NULL ! = m_ptr , bgfx : : Fatal : : InvalidShader , " Failed to create vertex shader. " ) ;
2012-07-23 00:08:58 -04:00
}
2014-07-20 23:27:13 -04:00
else
{
DX_CHECK ( s_renderD3D11 - > m_device - > CreateComputeShader ( code , shaderSize , NULL , & m_computeShader ) ) ;
BGFX_FATAL ( NULL ! = m_ptr , bgfx : : Fatal : : InvalidShader , " Failed to create compute shader. " ) ;
}
2014-04-15 22:10:56 -04:00
2014-08-17 20:20:15 -04:00
uint8_t numAttrs ;
bx : : read ( & reader , numAttrs ) ;
2015-07-16 23:28:43 -04:00
memset ( m_attrMask , 0 , sizeof ( m_attrMask ) ) ;
2014-08-17 20:20:15 -04:00
for ( uint32_t ii = 0 ; ii < numAttrs ; + + ii )
{
uint16_t id ;
bx : : read ( & reader , id ) ;
Attrib : : Enum attr = idToAttrib ( id ) ;
if ( Attrib : : Count ! = attr )
{
m_attrMask [ attr ] = 0xff ;
}
}
2014-04-15 22:10:56 -04:00
uint16_t size ;
bx : : read ( & reader , size ) ;
if ( 0 < size )
{
D3D11_BUFFER_DESC desc ;
2015-01-06 06:23:50 -05:00
desc . ByteWidth = ( size + 0xf ) & ~ 0xf ;
2014-04-15 22:10:56 -04:00
desc . Usage = D3D11_USAGE_DEFAULT ;
2015-05-15 23:08:38 -04:00
desc . CPUAccessFlags = 0 ;
2015-01-06 06:23:50 -05:00
desc . BindFlags = D3D11_BIND_CONSTANT_BUFFER ;
2014-04-15 22:10:56 -04:00
desc . MiscFlags = 0 ;
desc . StructureByteStride = 0 ;
2014-05-26 17:09:26 -04:00
DX_CHECK ( s_renderD3D11 - > m_device - > CreateBuffer ( & desc , NULL , & m_buffer ) ) ;
2014-04-15 22:10:56 -04:00
}
2012-07-23 00:08:58 -04:00
}
2014-05-26 17:09:26 -04:00
void TextureD3D11 : : create ( const Memory * _mem , uint32_t _flags , uint8_t _skip )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
m_sampler = s_renderD3D11 - > getSamplerState ( _flags ) ;
2012-07-23 00:08:58 -04:00
2013-09-02 19:22:53 -04:00
ImageContainer imageContainer ;
2012-07-23 00:08:58 -04:00
2013-09-02 19:22:53 -04:00
if ( imageParse ( imageContainer , _mem - > data , _mem - > size ) )
2012-07-23 00:08:58 -04:00
{
2014-02-20 01:34:53 -05:00
uint8_t numMips = imageContainer . m_numMips ;
2015-04-07 20:58:14 -04:00
const uint8_t startLod = uint8_t ( bx : : uint32_min ( _skip , numMips - 1 ) ) ;
2014-02-20 01:34:53 -05:00
numMips - = startLod ;
2014-03-01 22:27:34 -05: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-20 01:34:53 -05:00
2014-02-06 02:07:11 -05:00
m_flags = _flags ;
2013-09-09 00:03:03 -04:00
m_requestedFormat = ( uint8_t ) imageContainer . m_format ;
m_textureFormat = ( uint8_t ) imageContainer . m_format ;
const TextureFormatInfo & tfi = s_textureFormat [ m_requestedFormat ] ;
const bool convert = DXGI_FORMAT_UNKNOWN = = tfi . m_fmt ;
uint8_t bpp = getBitsPerPixel ( TextureFormat : : Enum ( m_textureFormat ) ) ;
if ( convert )
{
m_textureFormat = ( uint8_t ) TextureFormat : : BGRA8 ;
bpp = 32 ;
}
2013-09-02 19:22:53 -04:00
if ( imageContainer . m_cubeMap )
2012-07-23 00:08:58 -04:00
{
2012-07-29 16:50:23 -04:00
m_type = TextureCube ;
2012-07-23 00:08:58 -04:00
}
2013-09-02 19:22:53 -04:00
else if ( imageContainer . m_depth > 1 )
2012-07-23 00:08:58 -04:00
{
2012-07-29 16:50:23 -04:00
m_type = Texture3D ;
2012-07-23 00:08:58 -04:00
}
else
{
2012-07-29 16:50:23 -04:00
m_type = Texture2D ;
2012-07-23 00:08:58 -04:00
}
2012-07-29 16:50:23 -04:00
2014-02-20 01:34:53 -05:00
m_numMips = numMips ;
2013-09-09 00:03:03 -04:00
2014-02-20 01:34:53 -05:00
uint32_t numSrd = numMips * ( imageContainer . m_cubeMap ? 6 : 1 ) ;
2012-07-29 16:50:23 -04:00
D3D11_SUBRESOURCE_DATA * srd = ( D3D11_SUBRESOURCE_DATA * ) alloca ( numSrd * sizeof ( D3D11_SUBRESOURCE_DATA ) ) ;
uint32_t kk = 0 ;
2012-08-19 21:50:23 -04:00
2014-03-01 23:08:50 -05:00
const bool compressed = isCompressed ( TextureFormat : : Enum ( m_textureFormat ) ) ;
2014-07-20 23:27:13 -04:00
const bool swizzle = TextureFormat : : BGRA8 = = m_textureFormat & & 0 ! = ( m_flags & BGFX_TEXTURE_COMPUTE_WRITE ) ;
2014-03-01 23:08:50 -05:00
2014-07-20 23:27:13 -04:00
BX_TRACE ( " Texture %3d: %s (requested: %s), %dx%d%s%s%s. "
2014-05-26 17:09:26 -04:00
, this - s_renderD3D11 - > m_textures
2014-04-19 18:02:43 -04: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-07-20 23:27:13 -04:00
, swizzle ? " (swizzle BGRA8 -> RGBA8) " : " "
2014-04-19 18:02:43 -04:00
) ;
2013-09-09 00:03:03 -04:00
for ( uint8_t side = 0 , numSides = imageContainer . m_cubeMap ? 6 : 1 ; side < numSides ; + + side )
2012-07-29 16:50:23 -04:00
{
2014-02-20 01:34:53 -05:00
uint32_t width = textureWidth ;
uint32_t height = textureHeight ;
2013-09-09 00:03:03 -04:00
uint32_t depth = imageContainer . m_depth ;
2012-08-10 01:06:22 -04:00
2015-04-07 20:58:14 -04:00
for ( uint8_t lod = 0 , num = numMips ; lod < num ; + + lod )
2012-07-29 16:50:23 -04:00
{
2013-09-09 00:03:03 -04:00
width = bx : : uint32_max ( 1 , width ) ;
height = bx : : uint32_max ( 1 , height ) ;
depth = bx : : uint32_max ( 1 , depth ) ;
2012-07-29 16:50:23 -04:00
2013-09-09 00:03:03 -04:00
ImageMip mip ;
2014-02-20 01:34:53 -05:00
if ( imageGetRawData ( imageContainer , side , lod + startLod , _mem - > data , _mem - > size , mip ) )
2012-07-29 16:50:23 -04:00
{
2013-09-09 00:03:03 -04:00
srd [ kk ] . pSysMem = mip . m_data ;
2012-07-29 16:50:23 -04:00
2013-09-09 00:03:03 -04:00
if ( convert )
2012-07-29 16:50:23 -04:00
{
2013-11-16 13:58:15 -05:00
uint32_t srcpitch = mip . m_width * bpp / 8 ;
2013-09-17 00:40:30 -04:00
uint8_t * temp = ( uint8_t * ) BX_ALLOC ( g_allocator , mip . m_width * mip . m_height * bpp / 8 ) ;
2013-11-16 13:58:15 -05:00
imageDecodeToBgra8 ( temp , mip . m_data , mip . m_width , mip . m_height , srcpitch , mip . m_format ) ;
2012-07-29 16:50:23 -04:00
2013-09-09 00:03:03 -04:00
srd [ kk ] . pSysMem = temp ;
2013-11-16 13:58:15 -05:00
srd [ kk ] . SysMemPitch = srcpitch ;
2013-09-09 00:03:03 -04:00
}
2014-03-01 23:08:50 -05:00
else if ( compressed )
2013-09-09 00:03:03 -04:00
{
2014-07-20 23:27:13 -04:00
srd [ kk ] . SysMemPitch = ( mip . m_width / blockInfo . blockWidth ) * mip . m_blockSize ;
2014-03-01 23:08:50 -05:00
srd [ kk ] . SysMemSlicePitch = ( mip . m_height / blockInfo . blockHeight ) * srd [ kk ] . SysMemPitch ;
2013-09-09 00:03:03 -04:00
}
else
2012-07-29 16:50:23 -04:00
{
2013-09-09 00:03:03 -04:00
srd [ kk ] . SysMemPitch = mip . m_width * mip . m_bpp / 8 ;
2012-07-29 16:50:23 -04:00
}
2013-09-09 00:03:03 -04:00
2014-07-20 23:27:13 -04:00
if ( swizzle )
{
// imageSwizzleBgra8(width, height, mip.m_width*4, data, temp);
}
2013-09-09 00:03:03 -04:00
srd [ kk ] . SysMemSlicePitch = mip . m_height * srd [ kk ] . SysMemPitch ;
+ + kk ;
2012-07-29 16:50:23 -04:00
}
2013-09-09 00:03:03 -04:00
width > > = 1 ;
height > > = 1 ;
depth > > = 1 ;
2012-07-29 16:50:23 -04:00
}
}
2014-02-06 02:07:11 -05:00
const bool bufferOnly = 0 ! = ( m_flags & BGFX_TEXTURE_RT_BUFFER_ONLY ) ;
2014-07-20 23:27:13 -04:00
const bool computeWrite = 0 ! = ( m_flags & BGFX_TEXTURE_COMPUTE_WRITE ) ;
2014-02-06 02:07:11 -05:00
const bool renderTarget = 0 ! = ( m_flags & BGFX_TEXTURE_RT_MASK ) ;
2015-05-02 22:57:42 -04:00
const bool srgb = 0 ! = ( m_flags & BGFX_TEXTURE_SRGB ) | | imageContainer . m_srgb ;
2014-02-06 02:07:11 -05:00
const uint32_t msaaQuality = bx : : uint32_satsub ( ( m_flags & BGFX_TEXTURE_RT_MSAA_MASK ) > > BGFX_TEXTURE_RT_MSAA_SHIFT , 1 ) ;
const DXGI_SAMPLE_DESC & msaa = s_msaa [ msaaQuality ] ;
2012-08-19 21:50:23 -04:00
2014-07-20 23:27:13 -04:00
D3D11_SHADER_RESOURCE_VIEW_DESC srvd ;
memset ( & srvd , 0 , sizeof ( srvd ) ) ;
2015-05-02 22:57:42 -04:00
DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN ;
2014-07-20 23:27:13 -04:00
if ( swizzle )
{
2015-05-02 22:57:42 -04:00
format = srgb ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM ;
srvd . Format = format ;
}
else if ( srgb )
{
format = s_textureFormat [ m_textureFormat ] . m_fmtSrgb ;
srvd . Format = format ;
BX_WARN ( format ! = DXGI_FORMAT_UNKNOWN , " sRGB not supported for texture format %d " , m_textureFormat ) ;
}
if ( format = = DXGI_FORMAT_UNKNOWN )
{
// not swizzled and not sRGB, or sRGB unsupported
format = s_textureFormat [ m_textureFormat ] . m_fmt ;
srvd . Format = s_textureFormat [ m_textureFormat ] . m_fmtSrv ;
2014-07-20 23:27:13 -04:00
}
2012-08-19 21:50:23 -04:00
switch ( m_type )
{
case Texture2D :
case TextureCube :
{
D3D11_TEXTURE2D_DESC desc ;
2014-12-21 21:55:33 -05:00
desc . Width = textureWidth ;
2014-02-20 01:34:53 -05:00
desc . Height = textureHeight ;
2014-12-21 21:55:33 -05:00
desc . MipLevels = numMips ;
desc . Format = format ;
2014-02-06 02:07:11 -05:00
desc . SampleDesc = msaa ;
2014-12-21 21:55:33 -05:00
desc . Usage = kk = = 0 ? D3D11_USAGE_DEFAULT : D3D11_USAGE_IMMUTABLE ;
desc . BindFlags = bufferOnly ? 0 : D3D11_BIND_SHADER_RESOURCE ;
2012-08-19 21:50:23 -04:00
desc . CPUAccessFlags = 0 ;
2014-02-06 02:07:11 -05:00
if ( isDepth ( ( TextureFormat : : Enum ) m_textureFormat ) )
{
desc . BindFlags | = D3D11_BIND_DEPTH_STENCIL ;
desc . Usage = D3D11_USAGE_DEFAULT ;
}
else if ( renderTarget )
{
desc . BindFlags | = D3D11_BIND_RENDER_TARGET ;
desc . Usage = D3D11_USAGE_DEFAULT ;
}
2014-07-20 23:27:13 -04:00
if ( computeWrite )
{
desc . BindFlags | = D3D11_BIND_UNORDERED_ACCESS ;
desc . Usage = D3D11_USAGE_DEFAULT ;
}
2013-09-02 19:22:53 -04:00
if ( imageContainer . m_cubeMap )
2012-08-19 21:50:23 -04:00
{
desc . ArraySize = 6 ;
desc . MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE ;
srvd . ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE ;
2014-02-20 01:34:53 -05:00
srvd . TextureCube . MipLevels = numMips ;
2012-08-19 21:50:23 -04:00
}
else
{
desc . ArraySize = 1 ;
desc . MiscFlags = 0 ;
2014-02-06 02:07:11 -05:00
srvd . ViewDimension = 1 < msaa . Count ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D ;
2014-02-20 01:34:53 -05:00
srvd . Texture2D . MipLevels = numMips ;
2012-08-19 21:50:23 -04:00
}
2012-07-29 16:50:23 -04:00
2014-05-26 17:09:26 -04:00
DX_CHECK ( s_renderD3D11 - > m_device - > CreateTexture2D ( & desc , kk = = 0 ? NULL : srd , & m_texture2d ) ) ;
2012-08-19 21:50:23 -04:00
}
break ;
case Texture3D :
{
D3D11_TEXTURE3D_DESC desc ;
2014-12-21 21:55:33 -05:00
desc . Width = textureWidth ;
2014-02-20 01:34:53 -05:00
desc . Height = textureHeight ;
2014-12-21 21:55:33 -05:00
desc . Depth = imageContainer . m_depth ;
2013-09-02 19:22:53 -04:00
desc . MipLevels = imageContainer . m_numMips ;
2014-12-21 21:55:33 -05:00
desc . Format = format ;
desc . Usage = kk = = 0 ? D3D11_USAGE_DEFAULT : D3D11_USAGE_IMMUTABLE ;
2012-08-19 21:50:23 -04:00
desc . BindFlags = D3D11_BIND_SHADER_RESOURCE ;
desc . CPUAccessFlags = 0 ;
2014-12-21 21:55:33 -05:00
desc . MiscFlags = 0 ;
2012-08-19 21:50:23 -04:00
2014-07-20 23:27:13 -04:00
if ( computeWrite )
{
desc . BindFlags | = D3D11_BIND_UNORDERED_ACCESS ;
desc . Usage = D3D11_USAGE_DEFAULT ;
}
2012-08-19 21:50:23 -04:00
srvd . ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D ;
2014-02-20 01:34:53 -05:00
srvd . Texture3D . MipLevels = numMips ;
2012-08-19 21:50:23 -04:00
2014-05-26 17:09:26 -04:00
DX_CHECK ( s_renderD3D11 - > m_device - > CreateTexture3D ( & desc , kk = = 0 ? NULL : srd , & m_texture3d ) ) ;
2012-08-19 21:50:23 -04:00
}
break ;
}
2014-02-06 02:07:11 -05:00
if ( ! bufferOnly )
{
2014-05-26 17:09:26 -04:00
DX_CHECK ( s_renderD3D11 - > m_device - > CreateShaderResourceView ( m_ptr , & srvd , & m_srv ) ) ;
2014-02-06 02:07:11 -05:00
}
2012-08-10 01:06:22 -04:00
2014-07-20 23:27:13 -04:00
if ( computeWrite )
{
DX_CHECK ( s_renderD3D11 - > m_device - > CreateUnorderedAccessView ( m_ptr , NULL , & m_uav ) ) ;
}
2013-09-09 00:03:03 -04:00
if ( convert
& & 0 ! = kk )
2012-08-10 01:06:22 -04:00
{
kk = 0 ;
2013-09-02 19:22:53 -04:00
for ( uint8_t side = 0 , numSides = imageContainer . m_cubeMap ? 6 : 1 ; side < numSides ; + + side )
2012-08-10 01:06:22 -04:00
{
2014-02-20 01:34:53 -05:00
for ( uint32_t lod = 0 , num = numMips ; lod < num ; + + lod )
2012-08-10 01:06:22 -04:00
{
2013-09-17 00:40:30 -04:00
BX_FREE ( g_allocator , const_cast < void * > ( srd [ kk ] . pSysMem ) ) ;
2012-08-10 01:06:22 -04:00
+ + kk ;
}
}
}
2012-07-23 00:08:58 -04:00
}
}
2014-05-26 17:09:26 -04:00
void TextureD3D11 : : destroy ( )
2013-02-10 21:12:52 -05:00
{
DX_RELEASE ( m_srv , 0 ) ;
2014-07-20 23:27:13 -04:00
DX_RELEASE ( m_uav , 0 ) ;
2013-02-10 21:12:52 -05:00
DX_RELEASE ( m_ptr , 0 ) ;
}
2014-05-26 17:09:26 -04:00
void TextureD3D11 : : update ( uint8_t _side , uint8_t _mip , const Rect & _rect , uint16_t _z , uint16_t _depth , uint16_t _pitch , const Memory * _mem )
2012-11-25 21:24:50 -05:00
{
2014-05-26 17:09:26 -04:00
ID3D11DeviceContext * deviceCtx = s_renderD3D11 - > m_deviceCtx ;
2012-08-13 00:02:11 -04:00
2012-11-25 21:24:50 -05:00
D3D11_BOX box ;
2015-04-10 00:57:05 -04:00
box . left = _rect . m_x ;
box . top = _rect . m_y ;
box . right = box . left + _rect . m_width ;
2012-08-13 00:02:11 -04:00
box . bottom = box . top + _rect . m_height ;
2015-04-10 00:57:05 -04:00
box . front = _z ;
box . back = box . front + _depth ;
2012-08-19 21:50:23 -04:00
2013-11-08 01:59:17 -05:00
const uint32_t subres = _mip + ( _side * m_numMips ) ;
2015-04-10 00:57:05 -04:00
const uint32_t bpp = getBitsPerPixel ( TextureFormat : : Enum ( m_textureFormat ) ) ;
2013-11-08 01:59:17 -05:00
const uint32_t rectpitch = _rect . m_width * bpp / 8 ;
const uint32_t srcpitch = UINT16_MAX = = _pitch ? rectpitch : _pitch ;
2013-09-09 00:03:03 -04:00
const bool convert = m_textureFormat ! = m_requestedFormat ;
uint8_t * data = _mem - > data ;
uint8_t * temp = NULL ;
if ( convert )
{
2014-11-22 17:34:09 -05:00
temp = ( uint8_t * ) BX_ALLOC ( g_allocator , rectpitch * _rect . m_height ) ;
2013-11-08 01:59:17 -05:00
imageDecodeToBgra8 ( temp , data , _rect . m_width , _rect . m_height , srcpitch , m_requestedFormat ) ;
2013-09-09 00:03:03 -04:00
data = temp ;
}
deviceCtx - > UpdateSubresource ( m_ptr , subres , & box , data , srcpitch , 0 ) ;
if ( NULL ! = temp )
{
2013-09-17 00:40:30 -04:00
BX_FREE ( g_allocator , temp ) ;
2013-09-09 00:03:03 -04:00
}
2012-11-25 21:24:50 -05:00
}
2012-08-13 00:02:11 -04:00
2014-05-26 17:09:26 -04:00
void TextureD3D11 : : commit ( uint8_t _stage , uint32_t _flags )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
TextureStage & ts = s_renderD3D11 - > m_textureStage ;
2014-02-06 02:07:11 -05:00
ts . m_srv [ _stage ] = m_srv ;
2014-11-22 17:13:14 -05:00
ts . m_sampler [ _stage ] = 0 = = ( BGFX_SAMPLER_DEFAULT_FLAGS & _flags )
2014-05-26 17:09:26 -04:00
? s_renderD3D11 - > getSamplerState ( _flags )
2014-02-06 02:07:11 -05:00
: m_sampler
;
}
2012-08-05 17:51:49 -04:00
2014-05-26 17:09:26 -04:00
void TextureD3D11 : : resolve ( )
2014-02-06 02:07:11 -05:00
{
}
2012-08-05 17:51:49 -04:00
2014-05-26 17:09:26 -04:00
void FrameBufferD3D11 : : create ( uint8_t _num , const TextureHandle * _handles )
2014-02-06 02:07:11 -05:00
{
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_rtv ) ; + + ii )
2012-11-25 21:24:50 -05:00
{
2014-02-06 02:07:11 -05:00
m_rtv [ ii ] = NULL ;
2012-11-25 21:24:50 -05:00
}
2014-09-07 20:17:38 -04:00
m_dsv = NULL ;
m_swapChain = NULL ;
2012-11-25 21:24:50 -05:00
2015-04-14 20:02:41 -04:00
m_numTh = _num ;
memcpy ( m_th , _handles , _num * sizeof ( TextureHandle ) ) ;
2014-02-06 02:07:11 -05:00
2015-04-14 20:02:41 -04:00
postReset ( ) ;
2012-08-05 17:51:49 -04:00
}
2014-09-07 20:17:38 -04:00
void FrameBufferD3D11 : : create ( uint16_t _denseIdx , void * _nwh , uint32_t _width , uint32_t _height , TextureFormat : : Enum _depthFormat )
{
BX_UNUSED ( _depthFormat ) ;
DXGI_SWAP_CHAIN_DESC scd ;
memcpy ( & scd , & s_renderD3D11 - > m_scd , sizeof ( DXGI_SWAP_CHAIN_DESC ) ) ;
scd . BufferDesc . Width = _width ;
scd . BufferDesc . Height = _height ;
scd . OutputWindow = ( HWND ) _nwh ;
HRESULT hr ;
hr = s_renderD3D11 - > m_factory - > CreateSwapChain ( s_renderD3D11 - > m_device
, & scd
, & m_swapChain
) ;
BGFX_FATAL ( SUCCEEDED ( hr ) , Fatal : : UnableToInitialize , " Failed to create swap chain. " ) ;
ID3D11Resource * ptr ;
2015-07-16 23:28:43 -04:00
DX_CHECK ( m_swapChain - > GetBuffer ( 0 , IID_ID3D11Texture2D , ( void * * ) & ptr ) ) ;
2014-09-07 20:17:38 -04:00
DX_CHECK ( s_renderD3D11 - > m_device - > CreateRenderTargetView ( ptr , NULL , & m_rtv [ 0 ] ) ) ;
DX_RELEASE ( ptr , 0 ) ;
m_srv [ 0 ] = NULL ;
m_dsv = NULL ;
m_denseIdx = _denseIdx ;
m_num = 1 ;
}
uint16_t FrameBufferD3D11 : : destroy ( )
2015-04-14 20:02:41 -04:00
{
preReset ( ) ;
DX_RELEASE ( m_swapChain , 0 ) ;
m_num = 0 ;
m_numTh = 0 ;
uint16_t denseIdx = m_denseIdx ;
m_denseIdx = UINT16_MAX ;
return denseIdx ;
}
void FrameBufferD3D11 : : preReset ( )
2012-08-05 17:51:49 -04:00
{
2014-02-06 02:07:11 -05:00
for ( uint32_t ii = 0 , num = m_num ; ii < num ; + + ii )
{
DX_RELEASE ( m_srv [ ii ] , 0 ) ;
DX_RELEASE ( m_rtv [ ii ] , 0 ) ;
}
2012-11-25 21:24:50 -05:00
DX_RELEASE ( m_dsv , 0 ) ;
2015-04-14 20:02:41 -04:00
}
2012-07-23 00:08:58 -04:00
2015-04-14 20:02:41 -04:00
void FrameBufferD3D11 : : postReset ( )
{
if ( 0 < m_numTh )
{
m_num = 0 ;
for ( uint32_t ii = 0 ; ii < m_numTh ; + + ii )
{
TextureHandle handle = m_th [ ii ] ;
if ( isValid ( handle ) )
{
const TextureD3D11 & texture = s_renderD3D11 - > m_textures [ handle . idx ] ;
if ( isDepth ( ( TextureFormat : : Enum ) texture . m_textureFormat ) )
{
BX_CHECK ( NULL = = m_dsv , " Frame buffer already has depth-stencil attached. " ) ;
2014-09-07 20:17:38 -04:00
2015-04-14 20:02:41 -04:00
const uint32_t msaaQuality = bx : : uint32_satsub ( ( texture . m_flags & BGFX_TEXTURE_RT_MSAA_MASK ) > > BGFX_TEXTURE_RT_MSAA_SHIFT , 1 ) ;
const DXGI_SAMPLE_DESC & msaa = s_msaa [ msaaQuality ] ;
2014-11-22 17:13:14 -05:00
2015-04-14 20:02:41 -04:00
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc ;
dsvDesc . Format = s_textureFormat [ texture . m_textureFormat ] . m_fmtDsv ;
dsvDesc . ViewDimension = 1 < msaa . Count ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D ;
dsvDesc . Flags = 0 ;
dsvDesc . Texture2D . MipSlice = 0 ;
DX_CHECK ( s_renderD3D11 - > m_device - > CreateDepthStencilView ( texture . m_ptr , & dsvDesc , & m_dsv ) ) ;
}
else
{
DX_CHECK ( s_renderD3D11 - > m_device - > CreateRenderTargetView ( texture . m_ptr , NULL , & m_rtv [ m_num ] ) ) ;
DX_CHECK ( s_renderD3D11 - > m_device - > CreateShaderResourceView ( texture . m_ptr , NULL , & m_srv [ m_num ] ) ) ;
m_num + + ;
}
}
}
}
2012-07-23 00:08:58 -04:00
}
2014-05-26 17:09:26 -04:00
void FrameBufferD3D11 : : resolve ( )
2012-07-23 00:08:58 -04:00
{
}
2014-09-01 14:24:51 -04:00
void FrameBufferD3D11 : : clear ( const Clear & _clear , const float _palette [ ] [ 4 ] )
2014-03-26 02:07:51 -04:00
{
2014-05-26 17:09:26 -04:00
ID3D11DeviceContext * deviceCtx = s_renderD3D11 - > m_deviceCtx ;
2014-03-26 02:07:51 -04:00
2015-01-11 00:39:45 -05:00
if ( BGFX_CLEAR_COLOR & _clear . m_flags )
2014-03-26 02:07:51 -04:00
{
2015-01-11 21:02:34 -05:00
if ( BGFX_CLEAR_COLOR_USE_PALETTE & _clear . m_flags )
2014-09-01 14:24:51 -04:00
{
for ( uint32_t ii = 0 , num = m_num ; ii < num ; + + ii )
{
uint8_t index = _clear . m_index [ ii ] ;
if ( NULL ! = m_rtv [ ii ]
& & UINT8_MAX ! = index )
{
deviceCtx - > ClearRenderTargetView ( m_rtv [ ii ] , _palette [ index ] ) ;
}
}
}
else
2014-03-26 02:07:51 -04:00
{
2014-09-01 14:24:51 -04:00
float frgba [ 4 ] =
2014-11-22 17:13:14 -05:00
{
2014-09-01 14:24:51 -04:00
_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 ,
} ;
for ( uint32_t ii = 0 , num = m_num ; ii < num ; + + ii )
2014-03-26 02:07:51 -04:00
{
2014-09-01 14:24:51 -04:00
if ( NULL ! = m_rtv [ ii ] )
{
deviceCtx - > ClearRenderTargetView ( m_rtv [ ii ] , frgba ) ;
}
2014-03-26 02:07:51 -04:00
}
}
}
if ( NULL ! = m_dsv
2015-01-11 00:39:45 -05:00
& & ( BGFX_CLEAR_DEPTH | BGFX_CLEAR_STENCIL ) & _clear . m_flags )
2014-03-26 02:07:51 -04:00
{
DWORD flags = 0 ;
2015-01-11 00:39:45 -05:00
flags | = ( _clear . m_flags & BGFX_CLEAR_DEPTH ) ? D3D11_CLEAR_DEPTH : 0 ;
flags | = ( _clear . m_flags & BGFX_CLEAR_STENCIL ) ? D3D11_CLEAR_STENCIL : 0 ;
2014-03-26 02:07:51 -04:00
deviceCtx - > ClearDepthStencilView ( m_dsv , flags , _clear . m_depth , _clear . m_stencil ) ;
}
}
2015-05-14 14:37:32 -04:00
void TimerQueryD3D11 : : postReset ( )
2015-05-12 20:03:25 -04:00
{
ID3D11Device * device = s_renderD3D11 - > m_device ;
D3D11_QUERY_DESC query ;
query . MiscFlags = 0 ;
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_frame ) ; + + ii )
{
Frame & frame = m_frame [ ii ] ;
query . Query = D3D11_QUERY_TIMESTAMP_DISJOINT ;
DX_CHECK ( device - > CreateQuery ( & query , & frame . m_disjoint ) ) ;
query . Query = D3D11_QUERY_TIMESTAMP ;
DX_CHECK ( device - > CreateQuery ( & query , & frame . m_start ) ) ;
DX_CHECK ( device - > CreateQuery ( & query , & frame . m_end ) ) ;
}
m_elapsed = 0 ;
m_frequency = 1 ;
2015-05-14 14:37:32 -04:00
m_control . reset ( ) ;
2015-05-12 20:03:25 -04:00
}
2015-05-14 14:37:32 -04:00
void TimerQueryD3D11 : : preReset ( )
2015-05-12 20:03:25 -04:00
{
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_frame ) ; + + ii )
{
Frame & frame = m_frame [ ii ] ;
DX_RELEASE ( frame . m_disjoint , 0 ) ;
DX_RELEASE ( frame . m_start , 0 ) ;
DX_RELEASE ( frame . m_end , 0 ) ;
}
}
void TimerQueryD3D11 : : begin ( )
{
ID3D11DeviceContext * deviceCtx = s_renderD3D11 - > m_deviceCtx ;
while ( 0 = = m_control . reserve ( 1 ) )
{
get ( ) ;
}
Frame & frame = m_frame [ m_control . m_current ] ;
deviceCtx - > Begin ( frame . m_disjoint ) ;
deviceCtx - > End ( frame . m_start ) ;
}
void TimerQueryD3D11 : : end ( )
{
ID3D11DeviceContext * deviceCtx = s_renderD3D11 - > m_deviceCtx ;
Frame & frame = m_frame [ m_control . m_current ] ;
deviceCtx - > End ( frame . m_end ) ;
deviceCtx - > End ( frame . m_disjoint ) ;
m_control . commit ( 1 ) ;
}
bool TimerQueryD3D11 : : get ( )
{
2015-05-15 19:49:53 -04:00
if ( 0 ! = m_control . available ( ) )
2015-05-12 20:03:25 -04:00
{
2015-05-15 19:49:53 -04:00
ID3D11DeviceContext * deviceCtx = s_renderD3D11 - > m_deviceCtx ;
Frame & frame = m_frame [ m_control . m_read ] ;
2015-05-12 20:03:25 -04:00
2015-05-15 19:49:53 -04:00
uint64_t end ;
HRESULT hr = deviceCtx - > GetData ( frame . m_end , & end , sizeof ( end ) , 0 ) ;
if ( S_OK = = hr )
{
m_control . consume ( 1 ) ;
2015-05-12 20:03:25 -04:00
2015-05-27 06:27:00 -04:00
struct D3D11_QUERY_DATA_TIMESTAMP_DISJOINT
{
UINT64 Frequency ;
BOOL Disjoint ;
} ;
2015-05-15 19:49:53 -04:00
D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint ;
deviceCtx - > GetData ( frame . m_disjoint , & disjoint , sizeof ( disjoint ) , 0 ) ;
2015-05-12 20:03:25 -04:00
2015-05-15 19:49:53 -04:00
uint64_t start ;
deviceCtx - > GetData ( frame . m_start , & start , sizeof ( start ) , 0 ) ;
2015-05-12 20:03:25 -04:00
2015-05-15 19:49:53 -04:00
m_frequency = disjoint . Frequency ;
m_elapsed = end - start ;
return true ;
}
2015-05-12 20:03:25 -04:00
}
return false ;
}
2014-05-26 17:09:26 -04:00
void RendererContextD3D11 : : submit ( Frame * _render , ClearQuad & _clearQuad , TextVideoMemBlitter & _textVideoMemBlitter )
2012-07-23 00:08:58 -04:00
{
2013-06-09 18:28:25 -04:00
PIX_BEGINEVENT ( D3DCOLOR_RGBA ( 0xff , 0x00 , 0x00 , 0xff ) , L " rendererSubmit " ) ;
2014-05-26 17:09:26 -04:00
ID3D11DeviceContext * deviceCtx = m_deviceCtx ;
2012-07-23 00:08:58 -04:00
2014-05-26 17:09:26 -04:00
updateResolution ( _render - > m_resolution ) ;
2012-07-23 00:08:58 -04:00
2013-01-01 16:19:10 -05:00
int64_t elapsed = - bx : : getHPCounter ( ) ;
int64_t captureElapsed = 0 ;
2015-07-22 21:05:11 -04:00
m_gpuTimer . begin ( ) ;
2015-05-12 20:03:25 -04:00
2014-05-26 17:09:26 -04:00
if ( 0 < _render - > m_iboffset )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
TransientIndexBuffer * ib = _render - > m_transientIb ;
m_indexBuffers [ ib - > handle . idx ] . update ( 0 , _render - > m_iboffset , ib - > data ) ;
2012-07-23 00:08:58 -04:00
}
2014-05-26 17:09:26 -04:00
if ( 0 < _render - > m_vboffset )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
TransientVertexBuffer * vb = _render - > m_transientVb ;
m_vertexBuffers [ vb - > handle . idx ] . update ( 0 , _render - > m_vboffset , vb - > data ) ;
2012-07-23 00:08:58 -04:00
}
2014-05-26 17:09:26 -04:00
_render - > sort ( ) ;
2012-07-23 00:08:58 -04:00
2014-07-20 23:27:13 -04:00
RenderDraw currentState ;
currentState . clear ( ) ;
2012-07-23 00:08:58 -04:00
currentState . m_flags = BGFX_STATE_NONE ;
2012-11-10 22:59:23 -05:00
currentState . m_stencil = packStencil ( BGFX_STENCIL_NONE , BGFX_STENCIL_NONE ) ;
2012-07-23 00:08:58 -04:00
2015-06-02 20:00:36 -04:00
_render - > m_hmdInitialized = m_ovr . isInitialized ( ) ;
2014-10-29 01:08:55 -04:00
2015-06-02 20:00:36 -04:00
const bool hmdEnabled = m_ovr . isEnabled ( ) | | m_ovr . isDebug ( ) ;
2015-04-17 22:06:09 -04:00
ViewState & viewState = m_viewState ;
viewState . reset ( _render , hmdEnabled ) ;
2014-05-10 23:51:44 -04:00
2014-05-26 17:09:26 -04:00
bool wireframe = ! ! ( _render - > m_debug & BGFX_DEBUG_WIREFRAME ) ;
2013-07-27 18:27:54 -04:00
bool scissorEnabled = false ;
2014-05-26 17:09:26 -04:00
setDebugWireframe ( wireframe ) ;
2012-08-05 17:51:49 -04:00
2012-09-16 20:36:08 -04:00
uint16_t programIdx = invalidHandle ;
2012-07-23 00:08:58 -04:00
SortKey key ;
uint8_t view = 0xff ;
2014-02-06 02:07:11 -05:00
FrameBufferHandle fbh = BGFX_INVALID_HANDLE ;
2014-04-27 02:48:41 -04:00
2014-11-22 17:34:09 -05:00
const uint64_t primType = _render - > m_debug & BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0 ;
uint8_t primIndex = uint8_t ( primType > > BGFX_STATE_PT_SHIFT ) ;
2014-04-27 02:48:41 -04:00
PrimInfo prim = s_primInfo [ primIndex ] ;
deviceCtx - > IASetPrimitiveTopology ( prim . m_type ) ;
2014-07-20 23:27:13 -04:00
bool wasCompute = false ;
2013-08-02 01:55:26 -04:00
bool viewHasScissor = false ;
Rect viewScissorRect ;
2013-08-04 19:56:07 -04:00
viewScissorRect . clear ( ) ;
2012-07-23 00:08:58 -04:00
2014-04-27 02:48:41 -04:00
uint32_t statsNumPrimsSubmitted [ BX_COUNTOF ( s_primInfo ) ] = { } ;
uint32_t statsNumPrimsRendered [ BX_COUNTOF ( s_primInfo ) ] = { } ;
uint32_t statsNumInstances [ BX_COUNTOF ( s_primInfo ) ] = { } ;
2015-04-29 20:18:51 -04:00
uint32_t statsNumDrawIndirect [ BX_COUNTOF ( s_primInfo ) ] = { } ;
2012-07-23 00:08:58 -04:00
uint32_t statsNumIndices = 0 ;
2015-03-27 01:43:50 -04:00
uint32_t statsKeyType [ 2 ] = { } ;
2012-07-23 00:08:58 -04:00
2014-05-26 17:09:26 -04:00
if ( 0 = = ( _render - > m_debug & BGFX_DEBUG_IFH ) )
2012-07-23 00:08:58 -04:00
{
2015-05-24 13:29:21 -04:00
// reset the framebuffer to be the backbuffer; depending on the swap effect,
// if we don't do this we'll only see one frame of output and then nothing
setFrameBuffer ( fbh ) ;
2014-10-29 01:08:55 -04:00
bool viewRestart = false ;
uint8_t eye = 0 ;
uint8_t restartState = 0 ;
2014-12-27 22:00:41 -05:00
viewState . m_rect = _render - > m_rect [ 0 ] ;
2014-10-29 01:08:55 -04:00
int32_t numItems = _render - > m_num ;
for ( int32_t item = 0 , restartItem = numItems ; item < numItems | | restartItem < numItems ; )
2012-07-23 00:08:58 -04:00
{
2015-02-21 18:40:51 -05:00
const bool isCompute = key . decode ( _render - > m_sortKeys [ item ] , _render - > m_viewRemap ) ;
2015-03-27 01:43:50 -04:00
statsKeyType [ isCompute ] + + ;
2014-10-29 01:08:55 -04:00
const bool viewChanged = 0
| | key . m_view ! = view
| | item = = numItems
;
2012-07-23 00:08:58 -04:00
2014-07-20 23:27:13 -04:00
const RenderItem & renderItem = _render - > m_renderItem [ _render - > m_sortValues [ item ] ] ;
2014-10-29 01:08:55 -04:00
+ + item ;
2012-07-23 00:08:58 -04:00
2014-07-20 23:27:13 -04:00
if ( viewChanged )
2012-07-23 00:08:58 -04:00
{
2014-10-29 01:08:55 -04:00
if ( 1 = = restartState )
{
restartState = 2 ;
item = restartItem ;
restartItem = numItems ;
view = 0xff ;
continue ;
}
2013-06-09 18:28:25 -04:00
2012-07-23 00:08:58 -04:00
view = key . m_view ;
2012-09-16 20:36:08 -04:00
programIdx = invalidHandle ;
2012-07-23 00:08:58 -04:00
2014-05-26 17:09:26 -04:00
if ( _render - > m_fb [ view ] . idx ! = fbh . idx )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
fbh = _render - > m_fb [ view ] ;
setFrameBuffer ( fbh ) ;
2012-07-23 00:08:58 -04:00
}
2014-10-29 01:08:55 -04:00
viewRestart = ( ( BGFX_VIEW_STEREO = = ( _render - > m_viewFlags [ view ] & BGFX_VIEW_STEREO ) ) ) ;
viewRestart & = hmdEnabled ;
if ( viewRestart )
{
if ( 0 = = restartState )
{
restartState = 1 ;
restartItem = item - 1 ;
}
eye = ( restartState - 1 ) & 1 ;
restartState & = 1 ;
}
else
{
eye = 0 ;
}
PIX_ENDEVENT ( ) ;
2014-12-27 22:00:41 -05:00
viewState . m_rect = _render - > m_rect [ view ] ;
2014-10-29 01:08:55 -04:00
if ( viewRestart )
{
2015-04-02 14:57:53 -04:00
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG_PIX ) )
{
wchar_t * viewNameW = s_viewNameW [ view ] ;
viewNameW [ 3 ] = L ' ' ;
viewNameW [ 4 ] = eye ? L ' R ' : L ' L ' ;
PIX_BEGINEVENT ( D3DCOLOR_RGBA ( 0xff , 0x00 , 0x00 , 0xff ) , viewNameW ) ;
}
2014-10-29 01:08:55 -04:00
2015-06-05 13:43:43 -04:00
if ( m_ovr . isEnabled ( ) )
2015-06-05 05:00:26 -04:00
{
m_ovr . getViewport ( eye , & viewState . m_rect ) ;
}
else
{
viewState . m_rect . m_x = eye * ( viewState . m_rect . m_width + 1 ) / 2 ;
viewState . m_rect . m_width / = 2 ;
}
2014-10-29 01:08:55 -04:00
}
else
{
2015-04-02 14:57:53 -04:00
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG_PIX ) )
{
wchar_t * viewNameW = s_viewNameW [ view ] ;
viewNameW [ 3 ] = L ' ' ;
viewNameW [ 4 ] = L ' ' ;
PIX_BEGINEVENT ( D3DCOLOR_RGBA ( 0xff , 0x00 , 0x00 , 0xff ) , viewNameW ) ;
}
2014-10-29 01:08:55 -04:00
}
2014-05-26 17:09:26 -04:00
const Rect & scissorRect = _render - > m_scissor [ view ] ;
2013-08-02 01:55:26 -04:00
viewHasScissor = ! scissorRect . isZero ( ) ;
2014-12-27 22:00:41 -05:00
viewScissorRect = viewHasScissor ? scissorRect : viewState . m_rect ;
2012-07-23 00:08:58 -04:00
D3D11_VIEWPORT vp ;
2014-12-27 22:00:41 -05:00
vp . TopLeftX = viewState . m_rect . m_x ;
vp . TopLeftY = viewState . m_rect . m_y ;
vp . Width = viewState . m_rect . m_width ;
vp . Height = viewState . m_rect . m_height ;
2012-07-23 00:08:58 -04:00
vp . MinDepth = 0.0f ;
vp . MaxDepth = 1.0f ;
deviceCtx - > RSSetViewports ( 1 , & vp ) ;
2015-04-09 01:40:51 -04:00
Clear & clr = _render - > m_clear [ view ] ;
2012-07-23 00:08:58 -04:00
2015-04-09 01:40:51 -04:00
if ( BGFX_CLEAR_NONE ! = ( clr . m_flags & BGFX_CLEAR_MASK ) )
2012-07-23 00:08:58 -04:00
{
2015-04-09 01:40:51 -04:00
clearQuad ( _clearQuad , viewState . m_rect , clr , _render - > m_clearColor ) ;
2014-09-01 14:24:51 -04:00
prim = s_primInfo [ BX_COUNTOF ( s_primName ) ] ; // Force primitive type update after clear quad.
2012-07-23 00:08:58 -04:00
}
2014-07-20 23:27:13 -04:00
}
if ( isCompute )
{
if ( ! wasCompute )
{
wasCompute = true ;
2015-04-02 14:57:53 -04:00
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG_PIX ) )
{
wchar_t * viewNameW = s_viewNameW [ view ] ;
viewNameW [ 3 ] = L ' C ' ;
PIX_ENDEVENT ( ) ;
PIX_BEGINEVENT ( D3DCOLOR_RGBA ( 0xff , 0x00 , 0x00 , 0xff ) , viewNameW ) ;
}
2014-12-20 00:09:58 -05:00
deviceCtx - > IASetVertexBuffers ( 0 , 2 , s_zero . m_buffer , s_zero . m_zero , s_zero . m_zero ) ;
deviceCtx - > IASetIndexBuffer ( NULL , DXGI_FORMAT_R16_UINT , 0 ) ;
deviceCtx - > VSSetShaderResources ( 0 , BGFX_CONFIG_MAX_TEXTURE_SAMPLERS , s_zero . m_srv ) ;
deviceCtx - > PSSetShaderResources ( 0 , BGFX_CONFIG_MAX_TEXTURE_SAMPLERS , s_zero . m_srv ) ;
2014-07-20 23:27:13 -04:00
2014-12-20 00:09:58 -05:00
deviceCtx - > VSSetSamplers ( 0 , BGFX_CONFIG_MAX_TEXTURE_SAMPLERS , s_zero . m_sampler ) ;
deviceCtx - > PSSetSamplers ( 0 , BGFX_CONFIG_MAX_TEXTURE_SAMPLERS , s_zero . m_sampler ) ;
2014-07-20 23:27:13 -04:00
}
const RenderCompute & compute = renderItem . compute ;
2014-12-28 14:36:36 -05:00
if ( 0 ! = eye
& & BGFX_SUBMIT_EYE_LEFT = = ( compute . m_submitFlags & BGFX_SUBMIT_EYE_MASK ) )
{
continue ;
}
2014-07-20 23:27:13 -04:00
bool programChanged = false ;
bool constantsChanged = compute . m_constBegin < compute . m_constEnd ;
rendererUpdateUniforms ( this , _render - > m_constantBuffer , compute . m_constBegin , compute . m_constEnd ) ;
if ( key . m_program ! = programIdx )
{
programIdx = key . m_program ;
ProgramD3D11 & program = m_program [ key . m_program ] ;
m_currentProgram = & program ;
deviceCtx - > CSSetShader ( program . m_vsh - > m_computeShader , NULL , 0 ) ;
deviceCtx - > CSSetConstantBuffers ( 0 , 1 , & program . m_vsh - > m_buffer ) ;
2014-11-22 17:13:14 -05:00
programChanged =
2014-07-20 23:27:13 -04:00
constantsChanged = true ;
}
if ( invalidHandle ! = programIdx )
{
ProgramD3D11 & program = m_program [ programIdx ] ;
if ( constantsChanged )
{
ConstantBuffer * vcb = program . m_vsh - > m_constantBuffer ;
if ( NULL ! = vcb )
{
commit ( * vcb ) ;
}
}
2014-12-27 22:00:41 -05:00
viewState . setPredefined < 4 > ( this , view , eye , program , _render , compute ) ;
2014-07-20 23:27:13 -04:00
if ( constantsChanged
| | program . m_numPredefined > 0 )
{
commitShaderConstants ( ) ;
}
}
2014-09-18 09:33:09 -04:00
BX_UNUSED ( programChanged ) ;
2014-07-20 23:27:13 -04:00
ID3D11UnorderedAccessView * uav [ BGFX_MAX_COMPUTE_BINDINGS ] = { } ;
ID3D11ShaderResourceView * srv [ BGFX_MAX_COMPUTE_BINDINGS ] = { } ;
2014-12-11 00:09:13 -05:00
ID3D11SamplerState * sampler [ BGFX_MAX_COMPUTE_BINDINGS ] = { } ;
2014-07-20 23:27:13 -04:00
for ( uint32_t ii = 0 ; ii < BGFX_MAX_COMPUTE_BINDINGS ; + + ii )
{
2015-01-14 01:34:48 -05:00
const Binding & bind = compute . m_bind [ ii ] ;
2014-07-20 23:27:13 -04:00
if ( invalidHandle ! = bind . m_idx )
{
switch ( bind . m_type )
{
2015-01-14 01:34:48 -05:00
case Binding : : Image :
2014-07-20 23:27:13 -04:00
{
const TextureD3D11 & texture = m_textures [ bind . m_idx ] ;
2015-01-14 01:34:48 -05:00
if ( Access : : Read ! = bind . m_un . m_compute . m_access )
2014-07-20 23:27:13 -04:00
{
uav [ ii ] = texture . m_uav ;
}
else
{
2015-04-09 02:25:17 -04:00
srv [ ii ] = texture . m_srv ;
2014-07-20 23:27:13 -04:00
sampler [ ii ] = texture . m_sampler ;
}
}
break ;
2015-01-14 01:34:48 -05:00
case Binding : : IndexBuffer :
case Binding : : VertexBuffer :
2014-07-20 23:27:13 -04:00
{
2015-01-14 01:34:48 -05:00
const BufferD3D11 & buffer = Binding : : IndexBuffer = = bind . m_type
2015-01-10 23:38:47 -05:00
? m_indexBuffers [ bind . m_idx ]
: m_vertexBuffers [ bind . m_idx ]
;
2015-01-14 01:34:48 -05:00
if ( Access : : Read ! = bind . m_un . m_compute . m_access )
2014-12-10 02:16:27 -05:00
{
2015-01-10 23:38:47 -05:00
uav [ ii ] = buffer . m_uav ;
2014-12-10 02:16:27 -05:00
}
else
{
2015-01-10 23:38:47 -05:00
srv [ ii ] = buffer . m_srv ;
2014-12-10 02:16:27 -05:00
}
2014-07-20 23:27:13 -04:00
}
break ;
}
}
}
2014-12-11 00:09:13 -05:00
deviceCtx - > CSSetUnorderedAccessViews ( 0 , BX_COUNTOF ( uav ) , uav , NULL ) ;
deviceCtx - > CSSetShaderResources ( 0 , BX_COUNTOF ( srv ) , srv ) ;
deviceCtx - > CSSetSamplers ( 0 , BX_COUNTOF ( sampler ) , sampler ) ;
2014-07-20 23:27:13 -04:00
2015-05-01 17:54:23 -04:00
if ( isValid ( compute . m_indirectBuffer ) )
{
const VertexBufferD3D11 & vb = m_vertexBuffers [ compute . m_indirectBuffer . idx ] ;
ID3D11Buffer * ptr = vb . m_ptr ;
uint32_t numDrawIndirect = UINT16_MAX = = compute . m_numIndirect
? vb . m_size / BGFX_CONFIG_DRAW_INDIRECT_STRIDE
: compute . m_numIndirect
;
uint32_t args = compute . m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE ;
for ( uint32_t ii = 0 ; ii < numDrawIndirect ; + + ii )
{
deviceCtx - > DispatchIndirect ( ptr , args ) ;
args + = BGFX_CONFIG_DRAW_INDIRECT_STRIDE ;
}
}
else
{
deviceCtx - > Dispatch ( compute . m_numX , compute . m_numY , compute . m_numZ ) ;
}
2014-07-20 23:27:13 -04:00
continue ;
}
2014-12-28 13:12:24 -05:00
bool resetState = viewChanged | | wasCompute ;
2014-07-20 23:27:13 -04:00
if ( wasCompute )
{
2015-04-02 14:57:53 -04:00
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG_PIX ) )
{
wchar_t * viewNameW = s_viewNameW [ view ] ;
viewNameW [ 3 ] = L ' ' ;
PIX_ENDEVENT ( ) ;
PIX_BEGINEVENT ( D3DCOLOR_RGBA ( 0xff , 0x00 , 0x00 , 0xff ) , viewNameW ) ;
}
2014-07-20 23:27:13 -04:00
wasCompute = false ;
programIdx = invalidHandle ;
m_currentProgram = NULL ;
2014-12-10 02:16:27 -05:00
invalidateCompute ( ) ;
2014-07-20 23:27:13 -04:00
}
const RenderDraw & draw = renderItem . draw ;
const uint64_t newFlags = draw . m_flags ;
uint64_t changedFlags = currentState . m_flags ^ draw . m_flags ;
2015-06-17 13:04:12 -04:00
changedFlags | = currentState . m_rgba ! = draw . m_rgba ? BGFX_D3D11_BLEND_STATE_MASK : 0 ;
2014-07-20 23:27:13 -04:00
currentState . m_flags = newFlags ;
const uint64_t newStencil = draw . m_stencil ;
uint64_t changedStencil = currentState . m_stencil ^ draw . m_stencil ;
2015-06-17 13:04:12 -04:00
changedFlags | = 0 ! = changedStencil ? BGFX_D3D11_DEPTH_STENCIL_MASK : 0 ;
2014-07-20 23:27:13 -04:00
currentState . m_stencil = newStencil ;
2014-12-28 13:12:24 -05:00
if ( resetState )
2014-07-20 23:27:13 -04:00
{
currentState . clear ( ) ;
currentState . m_scissor = ! draw . m_scissor ;
changedFlags = BGFX_STATE_MASK ;
changedStencil = packStencil ( BGFX_STENCIL_MASK , BGFX_STENCIL_MASK ) ;
currentState . m_flags = newFlags ;
currentState . m_stencil = newStencil ;
2012-07-23 00:08:58 -04:00
2014-05-26 17:09:26 -04:00
setBlendState ( newFlags ) ;
setDepthStencilState ( newFlags , packStencil ( BGFX_STENCIL_DEFAULT , BGFX_STENCIL_DEFAULT ) ) ;
2013-07-27 18:27:54 -04:00
2014-04-27 02:48:41 -04:00
const uint64_t pt = newFlags & BGFX_STATE_PT_MASK ;
primIndex = uint8_t ( pt > > BGFX_STATE_PT_SHIFT ) ;
2014-12-21 21:55:33 -05:00
}
if ( prim . m_type ! = s_primInfo [ primIndex ] . m_type )
{
prim = s_primInfo [ primIndex ] ;
deviceCtx - > IASetPrimitiveTopology ( prim . m_type ) ;
2013-07-27 18:27:54 -04:00
}
2014-07-20 23:27:13 -04:00
uint16_t scissor = draw . m_scissor ;
2013-07-27 18:27:54 -04:00
if ( currentState . m_scissor ! = scissor )
{
currentState . m_scissor = scissor ;
if ( UINT16_MAX = = scissor )
{
2013-08-02 01:55:26 -04:00
scissorEnabled = viewHasScissor ;
if ( viewHasScissor )
2013-07-27 18:27:54 -04:00
{
D3D11_RECT rc ;
2014-10-05 21:20:05 -04:00
rc . left = viewScissorRect . m_x ;
rc . top = viewScissorRect . m_y ;
rc . right = viewScissorRect . m_x + viewScissorRect . m_width ;
2013-08-02 01:55:26 -04:00
rc . bottom = viewScissorRect . m_y + viewScissorRect . m_height ;
2013-07-27 18:27:54 -04:00
deviceCtx - > RSSetScissorRects ( 1 , & rc ) ;
}
}
else
{
2013-08-02 01:55:26 -04:00
Rect scissorRect ;
2014-05-26 17:09:26 -04:00
scissorRect . intersect ( viewScissorRect , _render - > m_rectCache . m_cache [ scissor ] ) ;
2013-07-27 18:27:54 -04:00
scissorEnabled = true ;
2013-07-14 17:32:09 -04:00
D3D11_RECT rc ;
2014-10-05 21:20:05 -04:00
rc . left = scissorRect . m_x ;
rc . top = scissorRect . m_y ;
rc . right = scissorRect . m_x + scissorRect . m_width ;
2013-07-14 17:32:09 -04:00
rc . bottom = scissorRect . m_y + scissorRect . m_height ;
deviceCtx - > RSSetScissorRects ( 1 , & rc ) ;
}
2014-05-26 17:09:26 -04:00
setRasterizerState ( newFlags , wireframe , scissorEnabled ) ;
2012-07-23 00:08:58 -04:00
}
2015-06-17 13:04:12 -04:00
if ( BGFX_D3D11_DEPTH_STENCIL_MASK & changedFlags )
2012-11-10 22:59:23 -05:00
{
2014-05-26 17:09:26 -04:00
setDepthStencilState ( newFlags , newStencil ) ;
2012-11-10 22:59:23 -05:00
}
2015-06-17 13:04:12 -04:00
if ( BGFX_D3D11_BLEND_STATE_MASK & changedFlags )
{
setBlendState ( newFlags , draw . m_rgba ) ;
currentState . m_rgba = draw . m_rgba ;
}
2013-06-18 01:11:45 -04:00
if ( ( 0
| BGFX_STATE_CULL_MASK
| BGFX_STATE_ALPHA_REF_MASK
| BGFX_STATE_PT_MASK
| BGFX_STATE_POINT_SIZE_MASK
| BGFX_STATE_MSAA
) & changedFlags )
2012-07-23 00:08:58 -04:00
{
2013-04-11 00:42:00 -04:00
if ( ( BGFX_STATE_CULL_MASK | BGFX_STATE_MSAA ) & changedFlags )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
setRasterizerState ( newFlags , wireframe , scissorEnabled ) ;
2012-07-23 00:08:58 -04:00
}
2012-11-03 16:12:26 -04:00
2013-03-09 00:54:08 -05:00
if ( BGFX_STATE_ALPHA_REF_MASK & changedFlags )
2012-11-25 21:24:50 -05:00
{
uint32_t ref = ( newFlags & BGFX_STATE_ALPHA_REF_MASK ) > > BGFX_STATE_ALPHA_REF_SHIFT ;
2014-12-27 22:00:41 -05:00
viewState . m_alphaRef = ref / 255.0f ;
2012-11-25 21:24:50 -05:00
}
2014-04-27 02:48:41 -04:00
const uint64_t pt = newFlags & BGFX_STATE_PT_MASK ;
primIndex = uint8_t ( pt > > BGFX_STATE_PT_SHIFT ) ;
if ( prim . m_type ! = s_primInfo [ primIndex ] . m_type )
2012-11-03 16:12:26 -04:00
{
2014-04-27 02:48:41 -04:00
prim = s_primInfo [ primIndex ] ;
deviceCtx - > IASetPrimitiveTopology ( prim . m_type ) ;
2012-11-03 16:12:26 -04:00
}
2012-07-23 00:08:58 -04:00
}
2012-09-16 20:36:08 -04:00
bool programChanged = false ;
2014-07-20 23:27:13 -04:00
bool constantsChanged = draw . m_constBegin < draw . m_constEnd ;
rendererUpdateUniforms ( this , _render - > m_constantBuffer , draw . m_constBegin , draw . m_constEnd ) ;
2012-07-23 00:08:58 -04:00
2012-09-16 20:36:08 -04:00
if ( key . m_program ! = programIdx )
2012-07-23 00:08:58 -04:00
{
2012-09-16 20:36:08 -04:00
programIdx = key . m_program ;
2012-07-23 00:08:58 -04:00
2012-09-16 20:36:08 -04:00
if ( invalidHandle = = programIdx )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
m_currentProgram = NULL ;
2012-07-23 00:08:58 -04:00
2014-02-25 00:44:12 -05:00
deviceCtx - > VSSetShader ( NULL , NULL , 0 ) ;
deviceCtx - > PSSetShader ( NULL , NULL , 0 ) ;
2012-07-23 00:08:58 -04:00
}
else
{
2014-05-26 17:09:26 -04:00
ProgramD3D11 & program = m_program [ programIdx ] ;
m_currentProgram = & program ;
2012-07-23 00:08:58 -04:00
2014-07-20 23:27:13 -04:00
const ShaderD3D11 * vsh = program . m_vsh ;
deviceCtx - > VSSetShader ( vsh - > m_vertexShader , NULL , 0 ) ;
deviceCtx - > VSSetConstantBuffers ( 0 , 1 , & vsh - > m_buffer ) ;
2012-07-23 00:08:58 -04:00
2014-05-26 17:09:26 -04:00
if ( NULL ! = m_currentColor )
2014-02-25 00:44:12 -05:00
{
2014-05-26 17:09:26 -04:00
const ShaderD3D11 * fsh = program . m_fsh ;
2014-07-20 23:27:13 -04:00
deviceCtx - > PSSetShader ( fsh - > m_pixelShader , NULL , 0 ) ;
2014-02-25 00:44:12 -05:00
deviceCtx - > PSSetConstantBuffers ( 0 , 1 , & fsh - > m_buffer ) ;
}
else
{
deviceCtx - > PSSetShader ( NULL , NULL , 0 ) ;
}
2012-07-23 00:08:58 -04:00
}
2014-11-22 17:13:14 -05:00
programChanged =
2012-07-23 00:08:58 -04:00
constantsChanged = true ;
}
2012-09-16 20:36:08 -04:00
if ( invalidHandle ! = programIdx )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
ProgramD3D11 & program = m_program [ programIdx ] ;
2012-07-23 00:08:58 -04:00
if ( constantsChanged )
{
2014-05-26 17:09:26 -04: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-07-23 00:08:58 -04:00
}
2014-12-27 22:00:41 -05:00
viewState . setPredefined < 4 > ( this , view , eye , program , _render , draw ) ;
2012-07-23 00:08:58 -04:00
2012-10-07 23:41:18 -04:00
if ( constantsChanged
| | program . m_numPredefined > 0 )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
commitShaderConstants ( ) ;
2012-07-23 00:08:58 -04:00
}
}
{
2012-08-05 17:51:49 -04:00
uint32_t changes = 0 ;
2015-04-07 20:58:14 -04:00
for ( uint8_t stage = 0 ; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS ; + + stage )
2012-07-23 00:08:58 -04:00
{
2015-01-14 01:34:48 -05:00
const Binding & sampler = draw . m_bind [ stage ] ;
Binding & current = currentState . m_bind [ stage ] ;
2015-01-15 00:31:08 -05: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 20:36:08 -04:00
| | programChanged )
2012-07-23 00:08:58 -04:00
{
2012-07-29 16:50:23 -04:00
if ( invalidHandle ! = sampler . m_idx )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
TextureD3D11 & texture = m_textures [ sampler . m_idx ] ;
2015-01-15 00:31:08 -05:00
texture . commit ( stage , sampler . m_un . m_draw . m_flags ) ;
2012-07-23 00:08:58 -04:00
}
else
{
2015-01-15 00:31:08 -05:00
m_textureStage . m_srv [ stage ] = NULL ;
2014-05-26 17:09:26 -04:00
m_textureStage . m_sampler [ stage ] = NULL ;
2012-07-23 00:08:58 -04:00
}
2012-08-05 17:51:49 -04:00
+ + changes ;
2012-07-23 00:08:58 -04:00
}
current = sampler ;
}
2012-08-05 17:51:49 -04:00
if ( 0 < changes )
{
2014-05-26 17:09:26 -04:00
commitTextureStage ( ) ;
2012-08-05 17:51:49 -04:00
}
2012-07-23 00:08:58 -04:00
}
2013-07-26 02:13:48 -04:00
if ( programChanged
2014-12-17 02:25:18 -05:00
| | currentState . m_vertexDecl . idx ! = draw . m_vertexDecl . idx
| | currentState . m_vertexBuffer . idx ! = draw . m_vertexBuffer . idx
2014-07-20 23:27:13 -04:00
| | currentState . m_instanceDataBuffer . idx ! = draw . m_instanceDataBuffer . idx
2014-12-17 02:25:18 -05:00
| | currentState . m_instanceDataOffset ! = draw . m_instanceDataOffset
| | currentState . m_instanceDataStride ! = draw . m_instanceDataStride )
2012-07-23 00:08:58 -04:00
{
2014-12-17 02:25:18 -05:00
currentState . m_vertexDecl = draw . m_vertexDecl ;
currentState . m_vertexBuffer = draw . m_vertexBuffer ;
2014-07-20 23:27:13 -04:00
currentState . m_instanceDataBuffer . idx = draw . m_instanceDataBuffer . idx ;
2014-12-17 02:25:18 -05:00
currentState . m_instanceDataOffset = draw . m_instanceDataOffset ;
currentState . m_instanceDataStride = draw . m_instanceDataStride ;
2012-07-23 00:08:58 -04:00
2014-07-20 23:27:13 -04:00
uint16_t handle = draw . m_vertexBuffer . idx ;
2012-07-29 16:50:23 -04:00
if ( invalidHandle ! = handle )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
const VertexBufferD3D11 & vb = m_vertexBuffers [ handle ] ;
2012-07-23 00:08:58 -04:00
2014-07-20 23:27:13 -04:00
uint16_t decl = ! isValid ( vb . m_decl ) ? draw . m_vertexDecl . idx : vb . m_decl . idx ;
2014-05-26 17:09:26 -04:00
const VertexDecl & vertexDecl = m_vertexDecls [ decl ] ;
2012-07-23 00:08:58 -04:00
uint32_t stride = vertexDecl . m_stride ;
uint32_t offset = 0 ;
deviceCtx - > IASetVertexBuffers ( 0 , 1 , & vb . m_ptr , & stride , & offset ) ;
2014-07-20 23:27:13 -04:00
if ( isValid ( draw . m_instanceDataBuffer ) )
2012-07-23 00:08:58 -04:00
{
2015-06-18 23:39:16 -04:00
const VertexBufferD3D11 & inst = m_vertexBuffers [ draw . m_instanceDataBuffer . idx ] ;
2014-07-20 23:27:13 -04:00
uint32_t instStride = draw . m_instanceDataStride ;
deviceCtx - > IASetVertexBuffers ( 1 , 1 , & inst . m_ptr , & instStride , & draw . m_instanceDataOffset ) ;
setInputLayout ( vertexDecl , m_program [ programIdx ] , draw . m_instanceDataStride / 16 ) ;
2012-07-23 00:08:58 -04:00
}
else
{
2015-05-14 14:37:32 -04:00
deviceCtx - > IASetVertexBuffers ( 1 , 1 , s_zero . m_buffer , s_zero . m_zero , s_zero . m_zero ) ;
2014-05-26 17:09:26 -04:00
setInputLayout ( vertexDecl , m_program [ programIdx ] , 0 ) ;
2012-07-23 00:08:58 -04:00
}
}
else
{
2015-05-14 14:37:32 -04:00
deviceCtx - > IASetVertexBuffers ( 0 , 1 , s_zero . m_buffer , s_zero . m_zero , s_zero . m_zero ) ;
2012-07-23 00:08:58 -04:00
}
}
2014-07-20 23:27:13 -04:00
if ( currentState . m_indexBuffer . idx ! = draw . m_indexBuffer . idx )
2012-07-23 00:08:58 -04:00
{
2014-07-20 23:27:13 -04:00
currentState . m_indexBuffer = draw . m_indexBuffer ;
2012-07-23 00:08:58 -04:00
2014-07-20 23:27:13 -04:00
uint16_t handle = draw . m_indexBuffer . idx ;
2012-07-29 16:50:23 -04:00
if ( invalidHandle ! = handle )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
const IndexBufferD3D11 & ib = m_indexBuffers [ handle ] ;
2015-04-08 22:59:48 -04:00
deviceCtx - > IASetIndexBuffer ( ib . m_ptr
, 0 = = ( ib . m_flags & BGFX_BUFFER_INDEX32 ) ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT
, 0
) ;
2012-07-23 00:08:58 -04:00
}
else
{
deviceCtx - > IASetIndexBuffer ( NULL , DXGI_FORMAT_R16_UINT , 0 ) ;
}
}
2013-09-30 00:33:50 -04:00
if ( isValid ( currentState . m_vertexBuffer ) )
2012-07-23 00:08:58 -04:00
{
2014-07-20 23:27:13 -04:00
uint32_t numVertices = draw . m_numVertices ;
2013-09-29 13:42:41 -04:00
if ( UINT32_MAX = = numVertices )
2012-07-23 00:08:58 -04:00
{
2014-05-26 17:09:26 -04:00
const VertexBufferD3D11 & vb = m_vertexBuffers [ currentState . m_vertexBuffer . idx ] ;
2014-07-20 23:27:13 -04:00
uint16_t decl = ! isValid ( vb . m_decl ) ? draw . m_vertexDecl . idx : vb . m_decl . idx ;
2014-05-26 17:09:26 -04:00
const VertexDecl & vertexDecl = m_vertexDecls [ decl ] ;
2012-07-23 00:08:58 -04:00
numVertices = vb . m_size / vertexDecl . m_stride ;
}
2015-04-29 20:18:51 -04:00
uint32_t numIndices = 0 ;
2012-07-23 00:08:58 -04:00
uint32_t numPrimsSubmitted = 0 ;
2015-04-29 20:18:51 -04:00
uint32_t numInstances = 0 ;
uint32_t numPrimsRendered = 0 ;
uint32_t numDrawIndirect = 0 ;
2012-07-23 00:08:58 -04:00
2015-05-01 17:54:23 -04:00
if ( isValid ( draw . m_indirectBuffer ) )
2012-07-23 00:08:58 -04:00
{
2015-05-01 17:54:23 -04:00
const VertexBufferD3D11 & vb = m_vertexBuffers [ draw . m_indirectBuffer . idx ] ;
2015-04-29 20:53:06 -04:00
ID3D11Buffer * ptr = vb . m_ptr ;
2015-04-29 20:18:51 -04:00
if ( isValid ( draw . m_indexBuffer ) )
2012-07-23 00:08:58 -04:00
{
2015-05-01 17:54:23 -04:00
numDrawIndirect = UINT16_MAX = = draw . m_numIndirect
? vb . m_size / BGFX_CONFIG_DRAW_INDIRECT_STRIDE
: draw . m_numIndirect
;
2015-04-29 20:18:51 -04:00
2015-05-01 17:54:23 -04:00
uint32_t args = draw . m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE ;
2015-04-29 20:18:51 -04:00
for ( uint32_t ii = 0 ; ii < numDrawIndirect ; + + ii )
2015-04-16 19:24:05 -04:00
{
2015-04-29 20:53:06 -04:00
deviceCtx - > DrawIndexedInstancedIndirect ( ptr , args ) ;
2015-05-01 17:54:23 -04:00
args + = BGFX_CONFIG_DRAW_INDIRECT_STRIDE ;
2015-04-16 19:24:05 -04:00
}
2015-04-29 20:18:51 -04:00
}
else
{
2015-05-01 17:54:23 -04:00
numDrawIndirect = UINT16_MAX = = draw . m_numIndirect
? vb . m_size / BGFX_CONFIG_DRAW_INDIRECT_STRIDE
: draw . m_numIndirect
;
2015-04-29 20:18:51 -04:00
2015-05-01 17:54:23 -04:00
uint32_t args = draw . m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE ;
2015-04-29 20:18:51 -04:00
for ( uint32_t ii = 0 ; ii < numDrawIndirect ; + + ii )
2015-04-16 19:24:05 -04:00
{
2015-04-29 20:53:06 -04:00
deviceCtx - > DrawInstancedIndirect ( ptr , args ) ;
2015-05-01 17:54:23 -04:00
args + = BGFX_CONFIG_DRAW_INDIRECT_STRIDE ;
2015-04-29 20:18:51 -04:00
}
}
}
else
{
if ( isValid ( draw . m_indexBuffer ) )
{
if ( UINT32_MAX = = draw . m_numIndices )
{
const IndexBufferD3D11 & ib = m_indexBuffers [ draw . m_indexBuffer . idx ] ;
const uint32_t indexSize = 0 = = ( ib . m_flags & BGFX_BUFFER_INDEX32 ) ? 2 : 4 ;
numIndices = ib . m_size / indexSize ;
numPrimsSubmitted = numIndices / prim . m_div - prim . m_sub ;
numInstances = draw . m_numInstances ;
numPrimsRendered = numPrimsSubmitted * draw . m_numInstances ;
if ( numInstances > 1 )
{
deviceCtx - > DrawIndexedInstanced ( numIndices
, draw . m_numInstances
, 0
, draw . m_startVertex
, 0
) ;
}
else
{
deviceCtx - > DrawIndexed ( numIndices
, 0
, draw . m_startVertex
) ;
}
}
else if ( prim . m_min < = draw . m_numIndices )
{
numIndices = draw . m_numIndices ;
numPrimsSubmitted = numIndices / prim . m_div - prim . m_sub ;
numInstances = draw . m_numInstances ;
numPrimsRendered = numPrimsSubmitted * draw . m_numInstances ;
if ( numInstances > 1 )
{
deviceCtx - > DrawIndexedInstanced ( numIndices
, draw . m_numInstances
, draw . m_startIndex
, draw . m_startVertex
, 0
) ;
}
else
{
deviceCtx - > DrawIndexed ( numIndices
, draw . m_startIndex
, draw . m_startVertex
) ;
}
2015-04-16 19:24:05 -04:00
}
2012-07-23 00:08:58 -04:00
}
2015-04-29 20:18:51 -04:00
else
2012-07-23 00:08:58 -04:00
{
2015-04-29 20:18:51 -04:00
numPrimsSubmitted = numVertices / prim . m_div - prim . m_sub ;
numInstances = draw . m_numInstances ;
numPrimsRendered = numPrimsSubmitted * draw . m_numInstances ;
2012-07-23 00:08:58 -04:00
2015-04-16 19:24:05 -04:00
if ( numInstances > 1 )
{
2015-04-29 20:18:51 -04:00
deviceCtx - > DrawInstanced ( numVertices
2015-04-16 19:24:05 -04:00
, draw . m_numInstances
, draw . m_startVertex
, 0
) ;
}
else
{
2015-04-29 20:18:51 -04:00
deviceCtx - > Draw ( numVertices
2015-04-16 19:24:05 -04:00
, draw . m_startVertex
) ;
}
2012-07-23 00:08:58 -04:00
}
}
2014-04-27 02:48:41 -04:00
statsNumPrimsSubmitted [ primIndex ] + = numPrimsSubmitted ;
statsNumPrimsRendered [ primIndex ] + = numPrimsRendered ;
statsNumInstances [ primIndex ] + = numInstances ;
2015-04-29 20:18:51 -04:00
statsNumDrawIndirect [ primIndex ] + = numDrawIndirect ;
statsNumIndices + = numIndices ;
2012-07-23 00:08:58 -04:00
}
}
2013-01-01 16:19:10 -05:00
2014-12-10 02:16:27 -05:00
if ( wasCompute )
{
2015-04-02 14:57:53 -04:00
if ( BX_ENABLED ( BGFX_CONFIG_DEBUG_PIX ) )
{
wchar_t * viewNameW = s_viewNameW [ view ] ;
viewNameW [ 3 ] = L ' C ' ;
PIX_ENDEVENT ( ) ;
PIX_BEGINEVENT ( D3DCOLOR_RGBA ( 0xff , 0x00 , 0x00 , 0xff ) , viewNameW ) ;
}
2014-12-10 02:16:27 -05:00
invalidateCompute ( ) ;
}
2014-05-26 17:09:26 -04:00
if ( 0 < _render - > m_num )
2013-01-01 16:19:10 -05:00
{
2015-05-15 16:14:35 -04:00
if ( 0 ! = ( m_resolution . m_flags & BGFX_RESET_FLUSH_AFTER_RENDER ) )
{
deviceCtx - > Flush ( ) ;
}
2013-01-01 16:19:10 -05:00
captureElapsed = - bx : : getHPCounter ( ) ;
2014-05-26 17:09:26 -04:00
capture ( ) ;
2013-01-01 16:19:10 -05:00
captureElapsed + = bx : : getHPCounter ( ) ;
}
2012-07-23 00:08:58 -04:00
}
2014-10-25 22:16:24 -04:00
PIX_ENDEVENT ( ) ;
2012-07-23 00:08:58 -04:00
int64_t now = bx : : getHPCounter ( ) ;
elapsed + = now ;
static int64_t last = now ;
int64_t frameTime = now - last ;
last = now ;
2012-08-05 17:51:49 -04:00
static int64_t min = frameTime ;
static int64_t max = frameTime ;
min = min > frameTime ? frameTime : min ;
max = max < frameTime ? frameTime : max ;
2015-07-22 21:05:11 -04:00
static uint32_t maxGpuLatency = 0 ;
static double maxGpuElapsed = 0.0f ;
double elapsedGpuMs = 0.0 ;
m_gpuTimer . end ( ) ;
while ( m_gpuTimer . get ( ) )
2012-07-23 00:08:58 -04:00
{
2015-07-22 21:05:11 -04:00
double toGpuMs = 1000.0 / double ( m_gpuTimer . m_frequency ) ;
elapsedGpuMs = m_gpuTimer . m_elapsed * toGpuMs ;
maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed ;
}
maxGpuLatency = bx : : uint32_imax ( maxGpuLatency , m_gpuTimer . m_control . available ( ) - 1 ) ;
2012-07-23 00:08:58 -04:00
2015-07-22 21:05:11 -04:00
const int64_t timerFreq = bx : : getHPFrequency ( ) ;
2015-05-12 20:03:25 -04:00
2015-07-22 21:05:11 -04:00
Stats & perfStats = _render - > m_perfStats ;
perfStats . cpuTime = frameTime ;
perfStats . cpuTimerFreq = timerFreq ;
perfStats . gpuTime = m_gpuTimer . m_elapsed ;
perfStats . gpuTimerFreq = m_gpuTimer . m_frequency ;
2015-05-12 20:03:25 -04:00
2015-07-22 21:05:11 -04:00
if ( _render - > m_debug & ( BGFX_DEBUG_IFH | BGFX_DEBUG_STATS ) )
{
PIX_BEGINEVENT ( D3DCOLOR_RGBA ( 0x40 , 0x40 , 0x40 , 0xff ) , L " debugstats " ) ;
2015-05-12 20:03:25 -04:00
2014-05-26 17:09:26 -04:00
TextVideoMem & tvm = m_textVideoMem ;
2012-07-23 00:08:58 -04:00
static int64_t next = now ;
if ( now > = next )
{
2015-07-22 21:05:11 -04:00
next = now + timerFreq ;
2012-07-23 00:08:58 -04:00
double freq = double ( bx : : getHPFrequency ( ) ) ;
double toMs = 1000.0 / freq ;
tvm . clear ( ) ;
2013-04-27 21:03:40 -04:00
uint16_t pos = 0 ;
2014-09-26 01:41:53 -04:00
tvm . printf ( 0 , pos + + , BGFX_CONFIG_DEBUG ? 0x89 : 0x8f
, " %s / " BX_COMPILER_NAME " / " BX_CPU_NAME " / " BX_ARCH_NAME " / " BX_PLATFORM_NAME " "
2014-05-26 17:09:26 -04:00
, getRendererName ( )
) ;
2013-04-27 21:03:40 -04:00
2014-05-26 17:09:26 -04:00
const DXGI_ADAPTER_DESC & desc = m_adapterDesc ;
2013-08-07 00:04:28 -04:00
char description [ BX_COUNTOF ( desc . Description ) ] ;
wcstombs ( description , desc . Description , BX_COUNTOF ( desc . Description ) ) ;
2013-04-27 21:03:40 -04:00
tvm . printf ( 0 , pos + + , 0x0f , " Device: %s " , description ) ;
2014-08-25 23:50:36 -04:00
char dedicatedVideo [ 16 ] ;
bx : : prettify ( dedicatedVideo , BX_COUNTOF ( dedicatedVideo ) , desc . DedicatedVideoMemory ) ;
char dedicatedSystem [ 16 ] ;
bx : : prettify ( dedicatedSystem , BX_COUNTOF ( dedicatedSystem ) , desc . DedicatedSystemMemory ) ;
char sharedSystem [ 16 ] ;
bx : : prettify ( sharedSystem , BX_COUNTOF ( sharedSystem ) , desc . SharedSystemMemory ) ;
2014-11-22 17:13:14 -05:00
2014-08-25 23:50:36 -04:00
tvm . printf ( 0 , pos + + , 0x0f , " Memory: %s (video), %s (system), %s (shared) "
, dedicatedVideo
, dedicatedSystem
, sharedSystem
2013-04-27 21:03:40 -04:00
) ;
pos = 10 ;
2014-02-06 02:07:11 -05:00
tvm . printf ( 10 , pos + + , 0x8e , " Frame: %7.3f, % 7.3f \x1f , % 7.3f \x1e [ms] / % 6.2f FPS "
2012-08-05 17:51:49 -04:00
, double ( frameTime ) * toMs
, double ( min ) * toMs
, double ( max ) * toMs
, freq / frameTime
2014-02-06 02:07:11 -05:00
) ;
2014-10-29 01:08:55 -04:00
char hmd [ 16 ] ;
bx : : snprintf ( hmd , BX_COUNTOF ( hmd ) , " , [%c] HMD " , hmdEnabled ? ' \xfe ' : ' ' ) ;
2014-02-06 02:07:11 -05:00
const uint32_t msaa = ( m_resolution . m_flags & BGFX_RESET_MSAA_MASK ) > > BGFX_RESET_MSAA_SHIFT ;
2015-01-21 23:39:42 -05:00
tvm . printf ( 10 , pos + + , 0x8e , " Reset flags: [%c] vsync, [%c] MSAAx%d%s, [%c] MaxAnisotropy "
2014-02-06 02:07:11 -05:00
, ! ! ( m_resolution . m_flags & BGFX_RESET_VSYNC ) ? ' \xfe ' : ' '
, 0 ! = msaa ? ' \xfe ' : ' '
, 1 < < msaa
2014-10-29 01:08:55 -04:00
, m_ovr . isInitialized ( ) ? hmd : " , no-HMD "
2015-01-21 23:39:42 -05:00
, ! ! ( m_resolution . m_flags & BGFX_RESET_MAXANISOTROPY ) ? ' \xfe ' : ' '
2012-08-05 17:51:49 -04:00
) ;
2013-01-01 16:19:10 -05:00
double elapsedCpuMs = double ( elapsed ) * toMs ;
2015-05-12 20:03:25 -04:00
tvm . printf ( 10 , pos + + , 0x8e , " Submitted: %4d (draw %4d, compute %4d) / CPU %3.4f [ms] %c GPU %3.4f [ms] (latency %d) "
2014-05-26 17:09:26 -04:00
, _render - > m_num
2015-03-27 01:43:50 -04:00
, statsKeyType [ 0 ]
, statsKeyType [ 1 ]
2012-07-23 00:08:58 -04:00
, elapsedCpuMs
2015-05-12 20:03:25 -04:00
, elapsedCpuMs > maxGpuElapsed ? ' > ' : ' < '
, maxGpuElapsed
, maxGpuLatency
2012-07-23 00:08:58 -04:00
) ;
2015-05-12 20:03:25 -04:00
maxGpuLatency = 0 ;
maxGpuElapsed = 0.0 ;
2014-09-01 14:24:51 -04:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( s_primName ) ; + + ii )
2014-04-27 02:48:41 -04:00
{
2015-04-29 20:18:51 -04:00
tvm . printf ( 10 , pos + + , 0x8e , " %9s: %7d (#inst: %5d), submitted: %7d, indirect %7d "
2014-04-27 02:48:41 -04:00
, s_primName [ ii ]
, statsNumPrimsRendered [ ii ]
, statsNumInstances [ ii ]
, statsNumPrimsSubmitted [ ii ]
2015-04-29 20:18:51 -04:00
, statsNumDrawIndirect [ ii ]
2014-04-27 02:48:41 -04:00
) ;
}
2013-01-01 16:19:10 -05:00
2014-09-26 01:41:53 -04:00
if ( NULL ! = m_renderdocdll )
{
tvm . printf ( tvm . m_width - 27 , 0 , 0x1f , " [F11 - RenderDoc capture] " ) ;
}
2014-02-06 02:07:11 -05:00
tvm . printf ( 10 , pos + + , 0x8e , " Indices: %7d " , statsNumIndices ) ;
2014-05-26 17:09:26 -04:00
tvm . printf ( 10 , pos + + , 0x8e , " DVB size: %7d " , _render - > m_vboffset ) ;
tvm . printf ( 10 , pos + + , 0x8e , " DIB size: %7d " , _render - > m_iboffset ) ;
2012-07-23 00:08:58 -04:00
2014-10-05 03:14:21 -04:00
pos + + ;
tvm . printf ( 10 , pos + + , 0x8e , " State cache: " ) ;
tvm . printf ( 10 , pos + + , 0x8e , " Blend | DepthS | Input | Raster | Sampler " ) ;
tvm . printf ( 10 , pos + + , 0x8e , " %6d | %6d | %6d | %6d | %6d "
, m_blendStateCache . getCount ( )
, m_depthStencilStateCache . getCount ( )
, m_inputLayoutCache . getCount ( )
, m_rasterizerStateCache . getCount ( )
, m_samplerStateCache . getCount ( )
) ;
pos + + ;
2014-04-27 02:48:41 -04:00
double captureMs = double ( captureElapsed ) * toMs ;
tvm . printf ( 10 , pos + + , 0x8e , " Capture: %3.4f [ms] " , captureMs ) ;
2012-07-23 00:08:58 -04:00
uint8_t attr [ 2 ] = { 0x89 , 0x8a } ;
2014-05-26 17:09:26 -04:00
uint8_t attrIndex = _render - > m_waitSubmit < _render - > m_waitRender ;
2012-07-23 00:08:58 -04:00
2014-05-26 17:09:26 -04: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 17:51:49 -04:00
min = frameTime ;
max = frameTime ;
2012-07-23 00:08:58 -04:00
}
2014-05-26 17:09:26 -04:00
blit ( this , _textVideoMemBlitter , tvm ) ;
2012-07-23 00:08:58 -04:00
2013-06-09 18:28:25 -04:00
PIX_ENDEVENT ( ) ;
2012-07-23 00:08:58 -04:00
}
2014-05-26 17:09:26 -04:00
else if ( _render - > m_debug & BGFX_DEBUG_TEXT )
2012-07-23 00:08:58 -04:00
{
2013-06-09 18:28:25 -04:00
PIX_BEGINEVENT ( D3DCOLOR_RGBA ( 0x40 , 0x40 , 0x40 , 0xff ) , L " debugtext " ) ;
2012-07-23 00:08:58 -04:00
2014-05-26 17:09:26 -04:00
blit ( this , _textVideoMemBlitter , _render - > m_textVideoMem ) ;
2012-07-23 00:08:58 -04:00
2013-06-09 18:28:25 -04:00
PIX_ENDEVENT ( ) ;
2012-07-23 00:08:58 -04:00
}
}
2015-03-22 01:11:59 -04:00
} /* namespace d3d11 */ } // namespace bgfx
2014-05-26 17:09:26 -04:00
# else
2015-03-22 01:11:59 -04:00
namespace bgfx { namespace d3d11
2014-05-26 17:09:26 -04:00
{
2015-03-22 01:11:59 -04:00
RendererContextI * rendererCreate ( )
2014-05-26 17:09:26 -04:00
{
return NULL ;
}
2015-03-22 01:11:59 -04:00
void rendererDestroy ( )
2014-05-26 17:09:26 -04:00
{
}
2015-03-22 01:11:59 -04:00
} /* namespace d3d11 */ } // namespace bgfx
2012-07-23 00:08:58 -04:00
# endif // BGFX_CONFIG_RENDERER_DIRECT3D11