diff options
Diffstat (limited to '3rdparty/bgfx/src/renderer_d3d11.cpp')
-rw-r--r-- | 3rdparty/bgfx/src/renderer_d3d11.cpp | 2037 |
1 files changed, 1374 insertions, 663 deletions
diff --git a/3rdparty/bgfx/src/renderer_d3d11.cpp b/3rdparty/bgfx/src/renderer_d3d11.cpp index eb8e3aa1137..a7a383d3b7d 100644 --- a/3rdparty/bgfx/src/renderer_d3d11.cpp +++ b/3rdparty/bgfx/src/renderer_d3d11.cpp @@ -8,9 +8,10 @@ #if BGFX_CONFIG_RENDERER_DIRECT3D11 # include "renderer_d3d11.h" -# if !defined(BGFX_D3D11_MAP_CONSTANT_BUFFERS) -# define BGFX_D3D11_MAP_CONSTANT_BUFFERS 0 -# endif +#if BX_PLATFORM_WINRT +# include <inspectable.h> +# include <windows.ui.xaml.media.dxinterop.h> +#endif // BX_PLATFORM_WINRT namespace bgfx { namespace d3d11 { @@ -46,14 +47,23 @@ namespace bgfx { namespace d3d11 union Zero { + Zero() + { + memset(this, 0, sizeof(Zero) ); + } + 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]; + float m_zerof[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; }; - static Zero s_zero; + 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 + static const Zero s_zero; + BX_PRAGMA_DIAGNOSTIC_POP(); static const uint32_t s_checkMsaa[] = { @@ -137,6 +147,7 @@ namespace bgfx { namespace d3d11 D3D11_TEXTURE_ADDRESS_WRAP, D3D11_TEXTURE_ADDRESS_MIRROR, D3D11_TEXTURE_ADDRESS_CLAMP, + D3D11_TEXTURE_ADDRESS_BORDER, }; /* @@ -188,55 +199,78 @@ namespace bgfx { namespace d3d11 static const TextureFormatInfo s_textureFormat[] = { - { 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_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_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // A8 + { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R8 + { DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R8I + { DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R8U + { DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R8S + { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R16 + { DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R16I + { DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R16U + { DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R16F + { DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R16S + { DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R32I + { DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R32U + { 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_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG8I + { DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG8U + { DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG8S + { DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG16 + { DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG16I + { DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG16U + { DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG16F + { DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG16S + { DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG32I + { DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG32U + { DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG32F + { DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGB9E5F + { 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 - { 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 - { 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 - { DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN }, // D0S8 + { DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB }, // RGBA8I + { DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB }, // RGBA8U + { DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGBA8S + { DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGBA16 + { DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGBA16I + { DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGBA16U + { DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGBA16F + { DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGBA16S + { DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGBA32I + { DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGBA32U + { 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 + { 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 + { 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 + { DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN }, // D0S8 }; BX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_textureFormat) ); @@ -263,25 +297,31 @@ namespace bgfx { namespace d3d11 static const DXGI_FORMAT s_attribType[][4][2] = { - { + { // Uint8 { 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 }, }, - { + { // 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 { 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 }, }, - { + { // Half { 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 }, }, - { + { // Float { DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT }, { DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT }, { DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT }, @@ -296,7 +336,7 @@ namespace bgfx { namespace d3d11 for (uint32_t attr = 0; attr < Attrib::Count; ++attr) { - if (0xff != _decl.m_attributes[attr]) + if (UINT16_MAX != _decl.m_attributes[attr]) { memcpy(elem, &s_attrib[attr], sizeof(D3D11_INPUT_ELEMENT_DESC) ); @@ -431,12 +471,75 @@ namespace bgfx { namespace d3d11 return false; }; + enum AGS_RETURN_CODE + { + AGS_SUCCESS, + AGS_INVALID_ARGS, + AGS_OUT_OF_MEMORY, + AGS_ERROR_MISSING_DLL, + AGS_ERROR_LEGACY_DRIVER, + AGS_EXTENSION_NOT_SUPPORTED, + AGS_ADL_FAILURE, + }; + + enum AGS_DRIVER_EXTENSION + { + AGS_EXTENSION_QUADLIST = 1 << 0, + AGS_EXTENSION_UAV_OVERLAP = 1 << 1, + AGS_EXTENSION_DEPTH_BOUNDS_TEST = 1 << 2, + AGS_EXTENSION_MULTIDRAWINDIRECT = 1 << 3, + }; + + struct AGSDriverVersionInfo + { + char strDriverVersion[256]; + char strCatalystVersion[256]; + char strCatalystWebLink[256]; + }; + + struct AGSContext; + + typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_INIT)(AGSContext**); + typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DEINIT)(AGSContext*); + typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_CROSSFIRE_GPU_COUNT)(AGSContext*, int32_t*); + typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_TOTAL_GPU_COUNT)(AGSContext*, int32_t*); + typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_GPU_MEMORY_SIZE)(AGSContext*, int32_t, int64_t*); + typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_DRIVER_VERSION_INFO)(AGSContext*, AGSDriverVersionInfo*); + typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_INIT)(AGSContext*, ID3D11Device*, uint32_t*); + typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_DEINIT)(AGSContext*); + typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INSTANCED_INDIRECT)(AGSContext*, uint32_t, ID3D11Buffer*, uint32_t, uint32_t); + typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INDEXED_INSTANCED_INDIRECT)(AGSContext*, uint32_t, ID3D11Buffer*, uint32_t, uint32_t); + + static PFN_AGS_INIT agsInit; + static PFN_AGS_DEINIT agsDeInit; + static PFN_AGS_GET_CROSSFIRE_GPU_COUNT agsGetCrossfireGPUCount; + static PFN_AGS_GET_TOTAL_GPU_COUNT agsGetTotalGPUCount; + static PFN_AGS_GET_GPU_MEMORY_SIZE agsGetGPUMemorySize; + static PFN_AGS_GET_DRIVER_VERSION_INFO agsGetDriverVersionInfo; + static PFN_AGS_DRIVER_EXTENSIONS_INIT agsDriverExtensions_Init; + static PFN_AGS_DRIVER_EXTENSIONS_DEINIT agsDriverExtensions_DeInit; + static PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INSTANCED_INDIRECT agsDriverExtensions_MultiDrawInstancedIndirect; + static PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INDEXED_INSTANCED_INDIRECT agsDriverExtensions_MultiDrawIndexedInstancedIndirect; + + typedef void (* MultiDrawIndirectFn)(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); + + void stubMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); + void stubMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); + + void amdAgsMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); + void amdAgsMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); + + static MultiDrawIndirectFn multiDrawInstancedIndirect; + static MultiDrawIndirectFn multiDrawIndexedInstancedIndirect; + #if USE_D3D11_DYNAMIC_LIB - 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_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; #endif // USE_D3D11_DYNAMIC_LIB struct RendererContextD3D11 : public RendererContextI @@ -445,7 +548,10 @@ namespace bgfx { namespace d3d11 : m_d3d9dll(NULL) , m_d3d11dll(NULL) , m_dxgidll(NULL) + , m_dxgidebugdll(NULL) , m_renderdocdll(NULL) + , m_agsdll(NULL) + , m_ags(NULL) , m_driverType(D3D_DRIVER_TYPE_NULL) , m_featureLevel(D3D_FEATURE_LEVEL(0) ) , m_adapter(NULL) @@ -466,13 +572,8 @@ namespace bgfx { namespace d3d11 , m_flags(BGFX_RESET_NONE) , m_maxAnisotropy(1) , m_currentProgram(NULL) -#if BGFX_D3D11_MAP_CONSTANT_BUFFERS - , m_vsScratch(NULL) - , m_fsScratch(NULL) -#else , m_vsChanges(0) , m_fsChanges(0) -#endif // BGFX_D3D11_MAP_CONSTANT_BUFFERS , m_rtMsaa(false) , m_ovrRtv(NULL) , m_ovrDsv(NULL) @@ -487,8 +588,21 @@ namespace bgfx { namespace d3d11 { } - void init() + bool init() { + struct ErrorState + { + enum Enum + { + Default, + LoadedD3D11, + LoadedDXGI, + CreatedDXGIFactory, + }; + }; + + ErrorState::Enum errorState = ErrorState::Default; + // Must be before device creation, and before RenderDoc. m_ovr.init(); @@ -501,9 +615,96 @@ namespace bgfx { namespace d3d11 memset(m_uniforms, 0, sizeof(m_uniforms) ); memset(&m_resolution, 0, sizeof(m_resolution) ); + m_ags = NULL; + m_agsdll = bx::dlopen( +#if BX_ARCH_32BIT + "amd_ags_x86.dll" +#else + "amd_ags_x64.dll" +#endif // BX_ARCH_32BIT + ); + if (NULL != m_agsdll) + { + agsInit = (PFN_AGS_INIT )bx::dlsym(m_agsdll, "agsInit"); + agsDeInit = (PFN_AGS_DEINIT)bx::dlsym(m_agsdll, "agsDeInit"); + agsGetCrossfireGPUCount = (PFN_AGS_GET_CROSSFIRE_GPU_COUNT )bx::dlsym(m_agsdll, "agsGetCrossfireGPUCount"); + agsGetTotalGPUCount = (PFN_AGS_GET_TOTAL_GPU_COUNT )bx::dlsym(m_agsdll, "agsGetTotalGPUCount"); + agsGetGPUMemorySize = (PFN_AGS_GET_GPU_MEMORY_SIZE )bx::dlsym(m_agsdll, "agsGetGPUMemorySize"); + agsGetDriverVersionInfo = (PFN_AGS_GET_DRIVER_VERSION_INFO )bx::dlsym(m_agsdll, "agsGetDriverVersionInfo"); + agsDriverExtensions_Init = (PFN_AGS_DRIVER_EXTENSIONS_INIT )bx::dlsym(m_agsdll, "agsDriverExtensions_Init"); + agsDriverExtensions_DeInit = (PFN_AGS_DRIVER_EXTENSIONS_DEINIT)bx::dlsym(m_agsdll, "agsDriverExtensions_DeInit"); + agsDriverExtensions_MultiDrawInstancedIndirect = (PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INSTANCED_INDIRECT )bx::dlsym(m_agsdll, "agsDriverExtensions_MultiDrawInstancedIndirect"); + agsDriverExtensions_MultiDrawIndexedInstancedIndirect = (PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INDEXED_INSTANCED_INDIRECT)bx::dlsym(m_agsdll, "agsDriverExtensions_MultiDrawIndexedInstancedIndirect"); + + bool agsSupported = true + && NULL != agsInit + && NULL != agsDeInit + && NULL != agsGetCrossfireGPUCount + && NULL != agsGetTotalGPUCount + && NULL != agsGetGPUMemorySize + && NULL != agsGetDriverVersionInfo + && NULL != agsDriverExtensions_Init + && NULL != agsDriverExtensions_DeInit + && NULL != agsDriverExtensions_MultiDrawInstancedIndirect + && NULL != agsDriverExtensions_MultiDrawIndexedInstancedIndirect + ; + if (agsSupported) + { + AGS_RETURN_CODE result = agsInit(&m_ags); + agsSupported = AGS_SUCCESS == result; + if (agsSupported) + { + AGSDriverVersionInfo vi; + result = agsGetDriverVersionInfo(m_ags, &vi); + BX_TRACE(" Driver version: %s", vi.strDriverVersion); + BX_TRACE(" Catalyst version: %s", vi.strCatalystVersion); + + int32_t numCrossfireGPUs = 0; + result = agsGetCrossfireGPUCount(m_ags, &numCrossfireGPUs); + BX_TRACE(" Num crossfire GPUs: %d", numCrossfireGPUs); + + int32_t numGPUs = 0; + result = agsGetTotalGPUCount(m_ags, &numGPUs); + BX_TRACE(" Num GPUs: %d", numGPUs); + + for (int32_t ii = 0; ii < numGPUs; ++ii) + { + long long memSize; + result = agsGetGPUMemorySize(m_ags, ii, &memSize); + if (AGS_SUCCESS == result) + { + char memSizeStr[16]; + bx::prettify(memSizeStr, BX_COUNTOF(memSizeStr), memSize); + BX_TRACE(" GPU #%d mem size: %s", ii, memSizeStr); + } + } + } + } + + BX_WARN(!agsSupported, "AMD/AGS supported."); + if (!agsSupported) + { + if (NULL != m_ags) + { + agsDeInit(m_ags); + m_ags = NULL; + } + + bx::dlclose(m_agsdll); + m_agsdll = NULL; + } + } + #if USE_D3D11_DYNAMIC_LIB m_d3d11dll = bx::dlopen("d3d11.dll"); - BGFX_FATAL(NULL != m_d3d11dll, Fatal::UnableToInitialize, "Failed to load d3d11.dll."); + BX_WARN(NULL != m_d3d11dll, "Failed to load d3d11.dll."); + + if (NULL == m_d3d11dll) + { + goto error; + } + + errorState = ErrorState::LoadedD3D11; m_d3d9dll = NULL; @@ -512,26 +713,58 @@ namespace bgfx { namespace d3d11 // 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"); - BGFX_FATAL(NULL != m_d3d9dll, Fatal::UnableToInitialize, "Failed to load d3d9.dll."); - - 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." - ); + 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." + ); + } } D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)bx::dlsym(m_d3d11dll, "D3D11CreateDevice"); - BGFX_FATAL(NULL != D3D11CreateDevice, Fatal::UnableToInitialize, "Function D3D11CreateDevice not found."); + BX_WARN(NULL != D3D11CreateDevice, "Function D3D11CreateDevice not found."); + if (NULL == D3D11CreateDevice) + { + goto error; + } m_dxgidll = bx::dlopen("dxgi.dll"); - BGFX_FATAL(NULL != m_dxgidll, Fatal::UnableToInitialize, "Failed to load dxgi.dll."); + BX_WARN(NULL != m_dxgidll, "Failed to load dxgi.dll."); + if (NULL == m_dxgidll) + { + goto error; + } + + errorState = ErrorState::LoadedDXGI; CreateDXGIFactory = (PFN_CREATE_DXGI_FACTORY)bx::dlsym(m_dxgidll, "CreateDXGIFactory"); - BGFX_FATAL(NULL != CreateDXGIFactory, Fatal::UnableToInitialize, "Function CreateDXGIFactory not found."); + BX_WARN(NULL != CreateDXGIFactory, "Function CreateDXGIFactory not found."); + if (NULL == CreateDXGIFactory) + { + goto error; + } + + 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... + } + } #endif // USE_D3D11_DYNAMIC_LIB HRESULT hr; @@ -539,11 +772,16 @@ namespace bgfx { namespace d3d11 #if BX_PLATFORM_WINRT // WinRT requires the IDXGIFactory2 interface, which isn't supported on older platforms hr = CreateDXGIFactory1(__uuidof(IDXGIFactory2), (void**)&factory); - BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create DXGI factory."); #else hr = CreateDXGIFactory(IID_IDXGIFactory, (void**)&factory); - BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create DXGI factory."); #endif // BX_PLATFORM_WINRT + BX_WARN(SUCCEEDED(hr), "Unable to create DXGI factory."); + if (FAILED(hr) ) + { + goto error; + } + + errorState = ErrorState::CreatedDXGIFactory; m_device = (ID3D11Device*)g_platformData.context; @@ -610,7 +848,7 @@ namespace bgfx { namespace d3d11 } DX_RELEASE(factory, NULL != m_adapter ? 1 : 0); - D3D_FEATURE_LEVEL features[] = + D3D_FEATURE_LEVEL featureLevel[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, @@ -626,6 +864,7 @@ namespace bgfx { namespace d3d11 uint32_t flags = 0 | D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT +// | D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS | (BX_ENABLED(BGFX_CONFIG_DEBUG) ? D3D11_CREATE_DEVICE_DEBUG : 0) ; @@ -636,13 +875,17 @@ namespace bgfx { namespace d3d11 , m_driverType , NULL , flags - , &features[ii] - , BX_COUNTOF(features)-ii + , &featureLevel[ii] + , BX_COUNTOF(featureLevel)-ii , D3D11_SDK_VERSION , &m_device , &m_featureLevel , &m_deviceCtx ); + BX_WARN(FAILED(hr), "Direct3D11 device feature level %d.%d." + , (m_featureLevel >> 12) & 0xf + , (m_featureLevel >> 8) & 0xf + ); if (FAILED(hr) && 0 != (flags & D3D11_CREATE_DEVICE_DEBUG) ) { @@ -667,7 +910,12 @@ namespace bgfx { namespace d3d11 break; } - BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device."); + BX_WARN(SUCCEEDED(hr), "Unable to create Direct3D11 device."); + + if (FAILED(hr) ) + { + goto error; + } if (NULL != m_adapter) { @@ -677,137 +925,195 @@ namespace bgfx { namespace d3d11 else { m_device->GetImmediateContext(&m_deviceCtx); - BGFX_FATAL(NULL != m_deviceCtx, Fatal::UnableToInitialize, "Unable to create Direct3D11 device."); + BX_WARN(NULL != m_deviceCtx, "Unable to create Direct3D11 device."); + + if (NULL == m_deviceCtx) + { + goto error; + } } - IDXGIDevice* device = NULL; - IDXGIAdapter* adapter = NULL; - hr = E_FAIL; - for (uint32_t ii = 0; ii < BX_COUNTOF(s_deviceIIDs) && FAILED(hr); ++ii) { - 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) ) + IDXGIDevice* device = NULL; + IDXGIAdapter* adapter = NULL; + hr = E_FAIL; + for (uint32_t ii = 0; ii < BX_COUNTOF(s_deviceIIDs) && FAILED(hr); ++ii) { + 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) ) + { #if BX_COMPILER_MSVC BX_PRAGMA_DIAGNOSTIC_PUSH(); BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4530) // warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc - 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; - } + 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; + } BX_PRAGMA_DIAGNOSTIC_POP(); #else - hr = device->GetAdapter(&adapter); + hr = device->GetAdapter(&adapter); #endif // BX_COMPILER_MSVC + } } - } - BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device."); - - // 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, 0); - } - else - { - setGraphicsDebuggerPresent(2 != getRefCount(device) ); - DX_RELEASE(device, 2); - } - hr = adapter->GetDesc(&m_adapterDesc); - BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device."); - 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; + BX_WARN(SUCCEEDED(hr), "Unable to create Direct3D11 device."); + if (FAILED(hr) ) + { + goto error; + } - if (NULL == g_platformData.backBuffer) - { + // 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); + BX_WARN(SUCCEEDED(hr), "Unable to create Direct3D11 device."); + if (FAILED(hr) ) + { + DX_RELEASE(adapter, 2); + goto error; + } + + 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); - BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device."); - DX_RELEASE(adapter, 2); - - 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 - ); - BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Failed to create swap chain."); + 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 = 0 == g_platformData.ndt + ? DXGI_SCALING_NONE + : DXGI_SCALING_STRETCH; + m_scd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + m_scd.AlphaMode = DXGI_ALPHA_MODE_IGNORE; + + if (NULL == g_platformData.ndt) + { + hr = m_factory->CreateSwapChainForCoreWindow(m_device + , (::IUnknown*)g_platformData.nwh + , &m_scd + , NULL + , &m_swapChain + ); + BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 swap chain."); + } + else + { + BGFX_FATAL(g_platformData.ndt == reinterpret_cast<void*>(1), Fatal::UnableToInitialize, "Unable to set swap chain on panel."); + + hr = m_factory->CreateSwapChainForComposition(m_device + , &m_scd + , NULL + , &m_swapChain + ); + BX_WARN(SUCCEEDED(hr), "Unable to create Direct3D11 swap chain."); + + IInspectable* nativeWindow = reinterpret_cast<IInspectable *>(g_platformData.nwh); + ISwapChainBackgroundPanelNative* panel = NULL; + hr = nativeWindow->QueryInterface(__uuidof(ISwapChainBackgroundPanelNative), (void**)&panel); + BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to set swap chain on panel."); + + if (NULL != panel) + { + hr = panel->SetSwapChain(m_swapChain); + BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to set swap chain on panel."); + + panel->Release(); + } + } #else - hr = adapter->GetParent(IID_IDXGIFactory, (void**)&m_factory); - BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device."); - DX_RELEASE(adapter, 2); - - 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 - ); - BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Failed to create swap chain."); + 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 - )); + DX_CHECK(m_factory->MakeWindowAssociation( (HWND)g_platformData.nwh, 0 + | DXGI_MWA_NO_WINDOW_CHANGES + | DXGI_MWA_NO_ALT_ENTER + ) ); #endif // BX_PLATFORM_WINRT - } - else - { - 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; + BX_WARN(SUCCEEDED(hr), "Failed to create swap chain."); + if (FAILED(hr) ) + { + goto error; + } + } + else + { + 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; + } } m_numWindows = 1; -#if !defined(__MINGW32__) if (BX_ENABLED(BGFX_CONFIG_DEBUG) ) { hr = m_device->QueryInterface(IID_ID3D11InfoQueue, (void**)&m_infoQueue); @@ -823,8 +1129,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); D3D11_MESSAGE_CATEGORY catlist[] = { - D3D11_MESSAGE_CATEGORY_STATE_SETTING, - D3D11_MESSAGE_CATEGORY_EXECUTION, + D3D11_MESSAGE_CATEGORY_STATE_CREATION, }; filter.DenyList.NumCategories = BX_COUNTOF(catlist); filter.DenyList.pCategoryList = catlist; @@ -832,249 +1137,337 @@ BX_PRAGMA_DIAGNOSTIC_POP(); DX_RELEASE(m_infoQueue, 3); } - else - { - // InfoQueue QueryInterface will fail when AMD GPU Perfstudio 2 is present. - setGraphicsDebuggerPresent(true); - } } -#endif // __MINGW__ - - 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]); - } - - g_caps.supported |= (0 - | BGFX_CAPS_TEXTURE_3D - | BGFX_CAPS_VERTEX_ATTRIB_HALF - | 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 - ); - if (m_featureLevel <= D3D_FEATURE_LEVEL_9_2) - { - 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) - { - 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) ); - } - // 32-bit indices only supported on 9_2+. - if (m_featureLevel >= D3D_FEATURE_LEVEL_9_2) - { - g_caps.supported |= BGFX_CAPS_INDEX32; - } + 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]); + } - // Independent blend only supported on 10_1+. - if (m_featureLevel >= D3D_FEATURE_LEVEL_10_1) - { - g_caps.supported |= BGFX_CAPS_BLEND_INDEPENDENT; - } + g_caps.supported |= (0 + | BGFX_CAPS_TEXTURE_3D + | BGFX_CAPS_VERTEX_ATTRIB_HALF + | BGFX_CAPS_VERTEX_ATTRIB_UINT10 + | 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 + ); - // 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) - { - struct D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS + if (m_featureLevel <= D3D_FEATURE_LEVEL_9_2) { - BOOL ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x; - }; - - 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.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) { - g_caps.supported |= BGFX_CAPS_COMPUTE; + 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) ); } - } - else if (m_featureLevel >= D3D_FEATURE_LEVEL_11_0) - { - g_caps.supported |= BGFX_CAPS_COMPUTE; - } - // 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 + // 32-bit indices only supported on 9_2+. + if (m_featureLevel >= D3D_FEATURE_LEVEL_9_2) { - BOOL SimpleInstancingSupported; - }; + g_caps.supported |= BGFX_CAPS_INDEX32; + } - 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) + // Independent blend only supported on 10_1+. + if (m_featureLevel >= D3D_FEATURE_LEVEL_10_1) { - g_caps.supported |= BGFX_CAPS_INSTANCING; + g_caps.supported |= BGFX_CAPS_BLEND_INDEPENDENT; } - } - // shadow compare is optional on 9_1 through 9_3 targets - if (m_featureLevel <= D3D_FEATURE_LEVEL_9_3) - { - struct D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT + // 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) { - BOOL SupportsDepthAsTextureWithLessEqualComparisonFilter; - }; + struct D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS + { + BOOL ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x; + }; - 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) + 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) { - g_caps.supported |= BGFX_CAPS_TEXTURE_COMPARE_LEQUAL; + g_caps.supported |= BGFX_CAPS_COMPUTE; } - } - for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) - { - uint8_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE; + // 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; + }; - 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; + 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; + } + } - if (DXGI_FORMAT_UNKNOWN != fmt) + // shadow compare is optional on 9_1 through 9_3 targets + if (m_featureLevel <= D3D_FEATURE_LEVEL_9_3) { - struct D3D11_FEATURE_DATA_FORMAT_SUPPORT + struct D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT { - DXGI_FORMAT InFormat; - UINT OutFormatSupport; + BOOL SupportsDepthAsTextureWithLessEqualComparisonFilter; }; - 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) ) + 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) { - 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 - ; + g_caps.supported |= BGFX_CAPS_TEXTURE_COMPARE_LEQUAL; + } + } - 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 - ; + for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) + { + uint8_t support = 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 - ; + 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; - 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 + if (DXGI_FORMAT_UNKNOWN != fmt) { - BX_TRACE("CheckFeatureSupport failed with %x for format %s.", hr, getName(TextureFormat::Enum(ii) ) ); + 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 + ; + + support |= 0 != (data.OutFormatSupport & (0 + | D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; + + support |= 0 != (data.OutFormatSupport & (0 + | D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_MSAA + : 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 + ; + } + } } - if (0 != (support & BGFX_CAPS_FORMAT_TEXTURE_IMAGE) ) + if (DXGI_FORMAT_UNKNOWN != fmtSrgb) { - // clear image flag for additional testing - support &= ~BGFX_CAPS_FORMAT_TEXTURE_IMAGE; + struct D3D11_FEATURE_DATA_FORMAT_SUPPORT + { + DXGI_FORMAT InFormat; + UINT OutFormatSupport; + }; - data.InFormat = s_textureFormat[ii].m_fmt; - hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT2, &data, sizeof(data) ); + 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) ); if (SUCCEEDED(hr) ) { support |= 0 != (data.OutFormatSupport & (0 - | D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD - | D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE + | D3D11_FORMAT_SUPPORT_TEXTURE2D + | D3D11_FORMAT_SUPPORT_TEXTURE3D + | D3D11_FORMAT_SUPPORT_TEXTURECUBE ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE + ? BGFX_CAPS_FORMAT_TEXTURE_COLOR_SRGB : BGFX_CAPS_FORMAT_TEXTURE_NONE ; } + else + { + BX_TRACE("CheckFeatureSupport failed with %x for sRGB format %s.", hr, getName(TextureFormat::Enum(ii) ) ); + } } + + g_caps.formats[ii] = support; } - if (DXGI_FORMAT_UNKNOWN != fmtSrgb) + // Init reserved part of view name. + for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii) { - struct D3D11_FEATURE_DATA_FORMAT_SUPPORT - { - DXGI_FORMAT InFormat; - UINT OutFormatSupport; - }; + 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); + } - 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) ); - 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_SRGB - : BGFX_CAPS_FORMAT_TEXTURE_NONE - ; - } - else + if (BX_ENABLED(BGFX_CONFIG_DEBUG) + && NULL != m_infoQueue) + { + m_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true); + } + + { // + multiDrawInstancedIndirect = stubMultiDrawInstancedIndirect; + multiDrawIndexedInstancedIndirect = stubMultiDrawIndexedInstancedIndirect; + if (NULL != m_ags) { - BX_TRACE("CheckFeatureSupport failed with %x for sRGB format %s.", hr, getName(TextureFormat::Enum(ii) ) ); + uint32_t flags; + AGS_RETURN_CODE result = agsDriverExtensions_Init(m_ags, m_device, &flags); + bool hasExtensions = AGS_SUCCESS == result; + + if (hasExtensions + && 0 != (flags & AGS_EXTENSION_MULTIDRAWINDIRECT) ) + { + multiDrawInstancedIndirect = amdAgsMultiDrawInstancedIndirect; + multiDrawIndexedInstancedIndirect = amdAgsMultiDrawIndexedInstancedIndirect; + } + else + { + if (hasExtensions) + { + agsDriverExtensions_DeInit(m_ags); + } + + agsDeInit(m_ags); + m_ags = NULL; + } } } - g_caps.formats[ii] = support; + // + updateMsaa(); + postReset(); } - // Init reserved part of view name. - for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii) - { - 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); - } + return true; -#if !defined(__MINGW32__) - if (BX_ENABLED(BGFX_CONFIG_DEBUG) - && NULL != m_infoQueue) + error: + switch (errorState) { - m_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true); + case ErrorState::CreatedDXGIFactory: + DX_RELEASE(m_swapChain, 0); + DX_RELEASE(m_deviceCtx, 0); + DX_RELEASE(m_device, 0); + DX_RELEASE(m_factory, 0); + + case ErrorState::LoadedDXGI: +#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 ErrorState::LoadedD3D11: +#if USE_D3D11_DYNAMIC_LIB + bx::dlclose(m_d3d11dll); + m_d3d11dll = NULL; +#endif // USE_D3D11_DYNAMIC_LIB + + case ErrorState::Default: + if (NULL != m_ags) + { + agsDeInit(m_ags); + } + bx::dlclose(m_agsdll); + m_agsdll = NULL; + unloadRenderDoc(m_renderdocdll); + m_ovr.shutdown(); + break; } -#endif // !defined(__MINGW32__) - updateMsaa(); - postReset(); + return false; } void shutdown() @@ -1082,10 +1475,24 @@ BX_PRAGMA_DIAGNOSTIC_POP(); preReset(); m_ovr.shutdown(); + if (NULL != m_ags) + { + agsDeInit(m_ags); + m_ags = NULL; + } + + bx::dlclose(m_agsdll); + m_agsdll = NULL; + m_deviceCtx->ClearState(); invalidateCache(); + for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) + { + m_frameBuffers[ii].destroy(); + } + for (uint32_t ii = 0; ii < BX_COUNTOF(m_indexBuffers); ++ii) { m_indexBuffers[ii].destroy(); @@ -1108,15 +1515,29 @@ BX_PRAGMA_DIAGNOSTIC_POP(); DX_RELEASE(m_swapChain, 0); DX_RELEASE(m_deviceCtx, 0); - DX_RELEASE(m_factory, 0); DX_RELEASE(m_device, 0); + DX_RELEASE(m_factory, 0); unloadRenderDoc(m_renderdocdll); #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); - bx::dlclose(m_d3d9dll); + m_dxgidll = NULL; + bx::dlclose(m_d3d11dll); + m_d3d11dll = NULL; #endif // USE_D3D11_DYNAMIC_LIB } @@ -1320,7 +1741,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } ID3D11Texture2D* backBuffer; - DX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer)); + DX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer) ); D3D11_TEXTURE2D_DESC backBufferDesc; backBuffer->GetDesc(&backBufferDesc); @@ -1460,14 +1881,12 @@ BX_PRAGMA_DIAGNOSTIC_POP(); float proj[16]; bx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f); - prepareShaderConstants(); - PredefinedUniform& predefined = program.m_predefined[0]; uint8_t flags = predefined.m_type; setShaderUniform(flags, predefined.m_loc, proj, 4); commitShaderConstants(); - m_textures[_blitter.m_texture.idx].commit(0); + m_textures[_blitter.m_texture.idx].commit(0, BGFX_SAMPLER_DEFAULT_FLAGS, NULL); commitTextureStage(); } @@ -1517,7 +1936,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (NULL != m_swapChain) { ID3D11Texture2D* color; - DX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&color)); + DX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&color) ); D3D11_RENDER_TARGET_VIEW_DESC desc; desc.ViewDimension = (m_flags & BGFX_RESET_MSAA_MASK) @@ -1587,10 +2006,10 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (NULL != m_swapChain) { HRESULT hr = S_OK; - uint32_t syncInterval = !!(m_flags & BGFX_RESET_VSYNC); -#if BX_PLATFORM_WINRT - syncInterval = 1; // sync interval of 0 is not supported on WinRT -#endif + uint32_t syncInterval = BX_ENABLED(BX_PLATFORM_WINRT) + ? 1 // sync interval of 0 is not supported on WinRT + : !!(m_flags & BGFX_RESET_VSYNC) + ; for (uint32_t ii = 1, num = m_numWindows; ii < num && SUCCEEDED(hr); ++ii) { @@ -1625,6 +2044,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_depthStencilStateCache.invalidate(); m_rasterizerStateCache.invalidate(); m_samplerStateCache.invalidate(); + m_srvUavLru.invalidate(); } void invalidateCompute() @@ -1670,9 +2090,9 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (!!(_resolution.m_flags & BGFX_RESET_MAXANISOTROPY) ) { m_maxAnisotropy = (m_featureLevel == D3D_FEATURE_LEVEL_9_1) - ? D3D_FL9_1_DEFAULT_MAX_ANISOTROPY - : D3D11_REQ_MAXANISOTROPY - ; + ? D3D_FL9_1_DEFAULT_MAX_ANISOTROPY + : D3D11_REQ_MAXANISOTROPY + ; } else { @@ -1716,7 +2136,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); , getBufferHeight() , getBufferFormat() , DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH - )); + ) ); } else { @@ -1725,20 +2145,58 @@ BX_PRAGMA_DIAGNOSTIC_POP(); DX_RELEASE(m_swapChain, 0); + SwapChainDesc* scd = &m_scd; + SwapChainDesc swapChainScd; + if (0 != (m_flags & BGFX_RESET_HMD) + && m_ovr.isInitialized() ) + { + swapChainScd = m_scd; + swapChainScd.SampleDesc = s_msaa[0]; + scd = &swapChainScd; + } + #if BX_PLATFORM_WINRT HRESULT hr; - hr = m_factory->CreateSwapChainForCoreWindow(m_device - , (::IUnknown*)g_platformData.nwh - , &m_scd - , NULL - , &m_swapChain - ); + if (g_platformData.ndt == 0) + { + hr = m_factory->CreateSwapChainForCoreWindow(m_device + , (::IUnknown*)g_platformData.nwh + , scd + , NULL + , &m_swapChain + ); + BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 swap chain."); + } + else + { + BGFX_FATAL(g_platformData.ndt == reinterpret_cast<void*>(1), Fatal::UnableToInitialize, "Invalid native display type."); + + hr = m_factory->CreateSwapChainForComposition(m_device + , &m_scd + , NULL + , &m_swapChain + ); + BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 swap chain."); + + IInspectable *nativeWindow = reinterpret_cast<IInspectable *>(g_platformData.nwh); + ISwapChainBackgroundPanelNative* panel = NULL; + hr = nativeWindow->QueryInterface(__uuidof(ISwapChainBackgroundPanelNative), (void **)&panel); + BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to set swap chain on panel."); + + if (NULL != panel) + { + hr = panel->SetSwapChain(m_swapChain); + BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to set swap chain on panel."); + + panel->Release(); + } + } #else HRESULT hr; hr = m_factory->CreateSwapChain(m_device - , &m_scd - , &m_swapChain - ); + , scd + , &m_swapChain + ); #endif // BX_PLATFORM_WINRT BGFX_FATAL(SUCCEEDED(hr), bgfx::Fatal::UnableToInitialize, "Failed to create swap chain."); } @@ -1758,16 +2216,12 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (_flags&BGFX_UNIFORM_FRAGMENTBIT) { memcpy(&m_fsScratch[_regIndex], _val, _numRegs*16); -#if !BGFX_D3D11_MAP_CONSTANT_BUFFERS m_fsChanges += _numRegs; -#endif } else { memcpy(&m_vsScratch[_regIndex], _val, _numRegs*16); -#if !BGFX_D3D11_MAP_CONSTANT_BUFFERS m_vsChanges += _numRegs; -#endif } } @@ -1781,37 +2235,8 @@ BX_PRAGMA_DIAGNOSTIC_POP(); setShaderUniform(_flags, _regIndex, _val, _numRegs); } - void prepareShaderConstants() - { -#if BGFX_D3D11_MAP_CONSTANT_BUFFERS - if (NULL != m_currentProgram->m_vsh->m_buffer) - { - D3D11_MAPPED_SUBRESOURCE mapped; - DX_CHECK(m_deviceCtx->Map(m_currentProgram->m_vsh->m_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); - m_vsScratch = (uint8_t*)mapped.pData; - } - if (NULL != m_currentProgram->m_fsh->m_buffer) - { - D3D11_MAPPED_SUBRESOURCE mapped; - DX_CHECK(m_deviceCtx->Map(m_currentProgram->m_fsh->m_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); - m_fsScratch = (uint8_t*)mapped.pData; - } -#endif // BGFX_D3D11_MAP_CONSTANT_BUFFERS - } - void commitShaderConstants() { -#if BGFX_D3D11_MAP_CONSTANT_BUFFERS - if (NULL != m_vsScratch) - { - m_deviceCtx->Unmap(m_currentProgram->m_vsh->m_buffer, 0); - } - if (NULL != m_fsScratch) - { - m_deviceCtx->Unmap(m_currentProgram->m_fsh->m_buffer, 0); - } - m_vsScratch = m_fsScratch = 0; -#else if (0 < m_vsChanges) { if (NULL != m_currentProgram->m_vsh->m_buffer) @@ -1831,7 +2256,6 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_fsChanges = 0; } -#endif // BGFX_D3D11_MAP_CONSTANT_BUFFERS } void setFrameBuffer(FrameBufferHandle _fbh, bool _msaa = true) @@ -1921,13 +2345,13 @@ BX_PRAGMA_DIAGNOSTIC_POP(); VertexDecl decl; memcpy(&decl, &_vertexDecl, sizeof(VertexDecl) ); - const uint8_t* attrMask = _program.m_vsh->m_attrMask; + const uint16_t* attrMask = _program.m_vsh->m_attrMask; 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; + uint16_t mask = attrMask[ii]; + uint16_t attr = (decl.m_attributes[ii] & mask); + decl.m_attributes[ii] = attr == 0 ? UINT16_MAX : attr == UINT16_MAX ? 0 : attr; } D3D11_INPUT_ELEMENT_DESC* elem = fillVertexDecl(vertexElements, decl); @@ -1978,13 +2402,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void setBlendState(uint64_t _state, uint32_t _rgba = 0) { - _state &= 0 - | BGFX_STATE_BLEND_MASK - | BGFX_STATE_BLEND_EQUATION_MASK - | BGFX_STATE_BLEND_INDEPENDENT - | BGFX_STATE_ALPHA_WRITE - | BGFX_STATE_RGB_WRITE - ; + _state &= BGFX_D3D11_BLEND_STATE_MASK; bx::HashMurmur2A murmur; murmur.begin(); @@ -2024,13 +2442,13 @@ BX_PRAGMA_DIAGNOSTIC_POP(); 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); - const uint32_t srcRGB = (blend )&0xf; - const uint32_t dstRGB = (blend>> 4)&0xf; - const uint32_t srcA = (blend>> 8)&0xf; - const uint32_t dstA = (blend>>12)&0xf; + const uint32_t srcRGB = (blend ) & 0xf; + const uint32_t dstRGB = (blend >> 4) & 0xf; + const uint32_t srcA = (blend >> 8) & 0xf; + const uint32_t dstA = (blend >> 12) & 0xf; - const uint32_t equRGB = (equation )&0x7; - const uint32_t equA = (equation>>3)&0x7; + const uint32_t equRGB = (equation ) & 0x7; + const uint32_t equA = (equation >> 3) & 0x7; drt->SrcBlend = s_blendFactor[srcRGB][0]; drt->DestBlend = s_blendFactor[dstRGB][0]; @@ -2040,8 +2458,16 @@ BX_PRAGMA_DIAGNOSTIC_POP(); drt->DestBlendAlpha = s_blendFactor[dstA][1]; drt->BlendOpAlpha = s_blendEquation[equA]; - uint8_t writeMask = (_state&BGFX_STATE_ALPHA_WRITE) ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0; - writeMask |= (_state&BGFX_STATE_RGB_WRITE) ? D3D11_COLOR_WRITE_ENABLE_RED|D3D11_COLOR_WRITE_ENABLE_GREEN|D3D11_COLOR_WRITE_ENABLE_BLUE : 0; + uint8_t writeMask = (_state&BGFX_STATE_ALPHA_WRITE) + ? D3D11_COLOR_WRITE_ENABLE_ALPHA + : 0 + ; + writeMask |= (_state&BGFX_STATE_RGB_WRITE) + ? D3D11_COLOR_WRITE_ENABLE_RED + | D3D11_COLOR_WRITE_ENABLE_GREEN + | D3D11_COLOR_WRITE_ENABLE_BLUE + : 0 + ; drt->RenderTargetWriteMask = writeMask; @@ -2050,19 +2476,19 @@ BX_PRAGMA_DIAGNOSTIC_POP(); for (uint32_t ii = 1, rgba = _rgba; ii < BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS; ++ii, rgba >>= 11) { drt = &desc.RenderTarget[ii]; - drt->BlendEnable = 0 != (rgba&0x7ff); + drt->BlendEnable = 0 != (rgba & 0x7ff); - const uint32_t src = (rgba )&0xf; - const uint32_t dst = (rgba>>4)&0xf; - const uint32_t equationIndex = (rgba>>8)&0x7; + const uint32_t src = (rgba ) & 0xf; + const uint32_t dst = (rgba >> 4) & 0xf; + const uint32_t equ = (rgba >> 8) & 0x7; drt->SrcBlend = s_blendFactor[src][0]; drt->DestBlend = s_blendFactor[dst][0]; - drt->BlendOp = s_blendEquation[equationIndex]; + drt->BlendOp = s_blendEquation[equ]; drt->SrcBlendAlpha = s_blendFactor[src][1]; drt->DestBlendAlpha = s_blendFactor[dst][1]; - drt->BlendOpAlpha = s_blendEquation[equationIndex]; + drt->BlendOpAlpha = s_blendEquation[equ]; drt->RenderTargetWriteMask = writeMask; } @@ -2085,7 +2511,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void setDepthStencilState(uint64_t _state, uint64_t _stencil = 0) { - _state &= BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK; + _state &= BGFX_D3D11_DEPTH_STENCIL_MASK; uint32_t fstencil = unpackStencil(0, _stencil); uint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT; @@ -2144,7 +2570,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { _state &= BGFX_STATE_CULL_MASK|BGFX_STATE_MSAA; _state |= _wireframe ? BGFX_STATE_PT_LINES : BGFX_STATE_NONE; - _state |= _scissor ? BGFX_STATE_RESERVED_MASK : 0; + _state |= _scissor ? BGFX_STATE_RESERVED_MASK : 0; ID3D11RasterizerState* rs = m_rasterizerStateCache.find(_state); if (NULL == rs) @@ -2171,37 +2597,74 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_deviceCtx->RSSetState(rs); } - ID3D11SamplerState* getSamplerState(uint32_t _flags) + ID3D11SamplerState* getSamplerState(uint32_t _flags, const float _rgba[4]) { + const uint32_t index = (_flags & BGFX_TEXTURE_BORDER_COLOR_MASK) >> BGFX_TEXTURE_BORDER_COLOR_SHIFT; _flags &= BGFX_TEXTURE_SAMPLER_BITS_MASK; - ID3D11SamplerState* sampler = m_samplerStateCache.find(_flags); + + uint32_t hash; + ID3D11SamplerState* sampler; + if (!needBorderColor(_flags) ) + { + bx::HashMurmur2A murmur; + murmur.begin(); + murmur.add(_flags); + murmur.add(-1); + hash = murmur.end(); + _rgba = s_zero.m_zerof; + + sampler = m_samplerStateCache.find(hash); + } + else + { + bx::HashMurmur2A murmur; + murmur.begin(); + murmur.add(_flags); + murmur.add(index); + hash = murmur.end(); + _rgba = NULL == _rgba ? s_zero.m_zerof : _rgba; + + sampler = m_samplerStateCache.find(hash); + if (NULL != sampler) + { + D3D11_SAMPLER_DESC sd; + sampler->GetDesc(&sd); + if (0 != memcmp(_rgba, sd.BorderColor, 16) ) + { + // Sampler will be released when updated sampler + // is added to cache. + sampler = NULL; + } + } + } + if (NULL == sampler) { - 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; + 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; D3D11_SAMPLER_DESC sd; - sd.Filter = (D3D11_FILTER)(filter|minFilter|magFilter|mipFilter); - 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; + sd.Filter = (D3D11_FILTER)(filter|minFilter|magFilter|mipFilter); + 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; sd.MaxAnisotropy = m_maxAnisotropy; sd.ComparisonFunc = 0 == cmpFunc ? D3D11_COMPARISON_NEVER : s_cmpFunc[cmpFunc]; - sd.BorderColor[0] = 0.0f; - sd.BorderColor[1] = 0.0f; - sd.BorderColor[2] = 0.0f; - sd.BorderColor[3] = 0.0f; + sd.BorderColor[0] = _rgba[0]; + sd.BorderColor[1] = _rgba[1]; + sd.BorderColor[2] = _rgba[2]; + sd.BorderColor[3] = _rgba[3]; sd.MinLOD = 0; sd.MaxLOD = D3D11_FLOAT32_MAX; m_device->CreateSamplerState(&sd, &sampler); DX_CHECK_REFCOUNT(sampler, 1); - m_samplerStateCache.add(_flags, sampler); + m_samplerStateCache.add(hash, sampler); } return sampler; @@ -2264,6 +2727,101 @@ BX_PRAGMA_DIAGNOSTIC_POP(); commitTextureStage(); } + ID3D11UnorderedAccessView* getCachedUav(TextureHandle _handle, uint8_t _mip) + { + bx::HashMurmur2A murmur; + murmur.begin(); + murmur.add(_handle); + murmur.add(_mip); + murmur.add(0); + uint32_t hash = murmur.end(); + + IUnknown** ptr = m_srvUavLru.find(hash); + ID3D11UnorderedAccessView* uav; + if (NULL == ptr) + { + TextureD3D11& texture = m_textures[_handle.idx]; + + D3D11_UNORDERED_ACCESS_VIEW_DESC desc; + desc.Format = s_textureFormat[texture.m_textureFormat].m_fmtSrv; + switch (texture.m_type) + { + case TextureD3D11::Texture2D: + case TextureD3D11::TextureCube: + desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D; + desc.Texture2D.MipSlice = _mip; + break; + + case TextureD3D11::Texture3D: + desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D; + desc.Texture3D.MipSlice = _mip; + desc.Texture3D.FirstWSlice = 0; + desc.Texture3D.WSize = UINT32_MAX; + break; + } + + DX_CHECK(m_device->CreateUnorderedAccessView(texture.m_ptr, &desc, &uav) ); + + m_srvUavLru.add(hash, uav, _handle.idx); + } + else + { + uav = static_cast<ID3D11UnorderedAccessView*>(*ptr); + } + + return uav; + } + + ID3D11ShaderResourceView* getCachedSrv(TextureHandle _handle, uint8_t _mip) + { + bx::HashMurmur2A murmur; + murmur.begin(); + murmur.add(_handle); + murmur.add(_mip); + murmur.add(0); + uint32_t hash = murmur.end(); + + IUnknown** ptr = m_srvUavLru.find(hash); + ID3D11ShaderResourceView* srv; + if (NULL == ptr) + { + TextureD3D11& texture = m_textures[_handle.idx]; + + D3D11_SHADER_RESOURCE_VIEW_DESC desc; + desc.Format = s_textureFormat[texture.m_textureFormat].m_fmtSrv; + switch (texture.m_type) + { + case TextureD3D11::Texture2D: + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + desc.Texture2D.MostDetailedMip = _mip; + desc.Texture2D.MipLevels = 1; + break; + + case TextureD3D11::TextureCube: + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + desc.TextureCube.MostDetailedMip = _mip; + desc.TextureCube.MipLevels = 1; + break; + + case TextureD3D11::Texture3D: + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D; + desc.Texture3D.MostDetailedMip = _mip; + desc.Texture3D.MipLevels = 1; + break; + } + + DX_CHECK(m_device->CreateShaderResourceView(texture.m_ptr, &desc, &srv) ); + + m_srvUavLru.add(hash, srv, _handle.idx); + } + else + { + srv = static_cast<ID3D11ShaderResourceView*>(*ptr); + } + + return srv; + } + void ovrPostReset() { #if BGFX_CONFIG_USE_OVR @@ -2294,7 +2852,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); bx::write(&writer, magic); TextureCreate tc; - tc.m_flags = BGFX_TEXTURE_RT; + tc.m_flags = BGFX_TEXTURE_RT|( ((m_flags & BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT) << BGFX_TEXTURE_RT_MSAA_SHIFT); tc.m_width = m_ovr.m_rtSize.w; tc.m_height = m_ovr.m_rtSize.h; tc.m_sides = 0; @@ -2365,7 +2923,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (m_flags&BGFX_RESET_CAPTURE) { ID3D11Texture2D* backBuffer; - DX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer)); + DX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer) ); D3D11_TEXTURE2D_DESC backBufferDesc; backBuffer->GetDesc(&backBufferDesc); @@ -2411,7 +2969,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (NULL != m_captureTexture) { ID3D11Texture2D* backBuffer; - DX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer)); + DX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer) ); if (NULL == m_captureResolve) { @@ -2419,7 +2977,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } else { - m_deviceCtx->ResolveSubresource(m_captureResolve, 0, backBuffer, 0, getBufferFormat()); + m_deviceCtx->ResolveSubresource(m_captureResolve, 0, backBuffer, 0, getBufferFormat() ); m_deviceCtx->CopyResource(m_captureTexture, m_captureResolve); } @@ -2434,13 +2992,13 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } - void commit(ConstantBuffer& _constantBuffer) + void commit(UniformBuffer& _uniformBuffer) { - _constantBuffer.reset(); + _uniformBuffer.reset(); for (;;) { - uint32_t opcode = _constantBuffer.read(); + uint32_t opcode = _uniformBuffer.read(); if (UniformType::End == opcode) { @@ -2451,17 +3009,17 @@ BX_PRAGMA_DIAGNOSTIC_POP(); uint16_t loc; uint16_t num; uint16_t copy; - ConstantBuffer::decodeOpcode(opcode, type, loc, num, copy); + UniformBuffer::decodeOpcode(opcode, type, loc, num, copy); const char* data; if (copy) { - data = _constantBuffer.read(g_uniformTypeSize[type]*num); + data = _uniformBuffer.read(g_uniformTypeSize[type]*num); } else { UniformHandle handle; - memcpy(&handle, _constantBuffer.read(sizeof(UniformHandle) ), sizeof(UniformHandle) ); + memcpy(&handle, _uniformBuffer.read(sizeof(UniformHandle) ), sizeof(UniformHandle) ); data = (const char*)m_uniforms[handle.idx]; } @@ -2475,8 +3033,8 @@ BX_PRAGMA_DIAGNOSTIC_POP(); switch ( (uint32_t)type) { - case UniformType::Uniform3x3fv: - case UniformType::Uniform3x3fv|BGFX_UNIFORM_FRAGMENTBIT: \ + case UniformType::Mat3: + case UniformType::Mat3|BGFX_UNIFORM_FRAGMENTBIT: \ { float* value = (float*)data; for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3*16, value += 9) @@ -2499,32 +3057,37 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } break; - CASE_IMPLEMENT_UNIFORM(Uniform1i, I, int); - CASE_IMPLEMENT_UNIFORM(Uniform1f, F, float); - CASE_IMPLEMENT_UNIFORM(Uniform1iv, I, int); - CASE_IMPLEMENT_UNIFORM(Uniform1fv, F, float); - CASE_IMPLEMENT_UNIFORM(Uniform2fv, F, float); - CASE_IMPLEMENT_UNIFORM(Uniform3fv, F, float); - CASE_IMPLEMENT_UNIFORM(Uniform4fv, F, float); - CASE_IMPLEMENT_UNIFORM(Uniform4x4fv, F, float); + CASE_IMPLEMENT_UNIFORM(Int1, I, int); + CASE_IMPLEMENT_UNIFORM(Vec4, F, float); + CASE_IMPLEMENT_UNIFORM(Mat4, F, float); case UniformType::End: break; default: - BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _constantBuffer.getPos(), opcode, type, loc, num, copy); + BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _uniformBuffer.getPos(), opcode, type, loc, num, copy); break; } - #undef CASE_IMPLEMENT_UNIFORM - } } void clearQuad(ClearQuad& _clearQuad, const Rect& _rect, const Clear& _clear, const float _palette[][4]) { - uint32_t width = getBufferWidth(); - uint32_t height = getBufferHeight(); + uint32_t width; + uint32_t height; + + if (isValid(m_fbh) ) + { + const FrameBufferD3D11& fb = m_frameBuffers[m_fbh.idx]; + width = fb.m_width; + height = fb.m_height; + } + else + { + width = getBufferWidth(); + height = getBufferHeight(); + } if (0 == _rect.m_x && 0 == _rect.m_y @@ -2567,33 +3130,23 @@ BX_PRAGMA_DIAGNOSTIC_POP(); ProgramD3D11& program = m_program[_clearQuad.m_program[numMrt-1].idx]; m_currentProgram = &program; deviceCtx->VSSetShader(program.m_vsh->m_vertexShader, NULL, 0); - deviceCtx->VSSetConstantBuffers(0, 0, NULL); + deviceCtx->VSSetConstantBuffers(0, 1, s_zero.m_buffer); if (NULL != m_currentColor) { const ShaderD3D11* fsh = program.m_fsh; deviceCtx->PSSetShader(fsh->m_pixelShader, NULL, 0); deviceCtx->PSSetConstantBuffers(0, 1, &fsh->m_buffer); -#if BGFX_D3D11_MAP_CONSTANT_BUFFERS - D3D11_MAPPED_SUBRESOURCE mapped; - DX_CHECK(deviceCtx->Map(fsh->m_buffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); - void* fsScratch = mapped.pData; -#endif // BGFX_D3D11_MAP_CONSTANT_BUFFERS - if (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags) { 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]); + uint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_COLOR_PALETTE-1, _clear.m_index[ii]); memcpy(mrtClear[ii], _palette[index], 16); } -#if BGFX_D3D11_MAP_CONSTANT_BUFFERS - memcpy(fsScratch, mrtClear, sizeof(mrtClear)); -#else deviceCtx->UpdateSubresource(fsh->m_buffer, 0, 0, mrtClear, 0, 0); -#endif // BGFX_D3D11_MAP_CONSTANT_BUFFERS } else { @@ -2605,19 +3158,8 @@ BX_PRAGMA_DIAGNOSTIC_POP(); _clear.m_index[3]*1.0f/255.0f, }; -#if BGFX_D3D11_MAP_CONSTANT_BUFFERS - memcpy(fsScratch, rgba, sizeof(rgba)); -#else deviceCtx->UpdateSubresource(fsh->m_buffer, 0, 0, rgba, 0, 0); -#endif // BGFX_D3D11_MAP_CONSTANT_BUFFERS } - -#if BGFX_D3D11_MAP_CONSTANT_BUFFERS - if (NULL != fsScratch) - { - deviceCtx->Unmap(fsh->m_buffer, 0); - } -#endif // BGFX_D3D11_MAP_CONSTANT_BUFFERS } else { @@ -2671,8 +3213,12 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void* m_d3d9dll; void* m_d3d11dll; void* m_dxgidll; + void* m_dxgidebugdll; void* m_renderdocdll; + void* m_agsdll; + AGSContext* m_ags; + D3D_DRIVER_TYPE m_driverType; D3D_FEATURE_LEVEL m_featureLevel; @@ -2707,10 +3253,12 @@ BX_PRAGMA_DIAGNOSTIC_POP(); bool m_wireframe; #if BX_PLATFORM_WINRT - DXGI_SWAP_CHAIN_DESC1 m_scd; + typedef DXGI_SWAP_CHAIN_DESC1 SwapChainDesc; #else - DXGI_SWAP_CHAIN_DESC m_scd; -#endif + typedef DXGI_SWAP_CHAIN_DESC SwapChainDesc; +#endif // BX_PLATFORM_WINRT + + SwapChainDesc m_scd; uint32_t m_flags; uint32_t m_maxAnisotropy; @@ -2731,6 +3279,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); StateCacheT<ID3D11InputLayout> m_inputLayoutCache; StateCacheT<ID3D11RasterizerState> m_rasterizerStateCache; StateCacheT<ID3D11SamplerState> m_samplerStateCache; + StateCacheLru<IUnknown*, 1024> m_srvUavLru; TextVideoMem m_textVideoMem; @@ -2738,15 +3287,10 @@ BX_PRAGMA_DIAGNOSTIC_POP(); ProgramD3D11* m_currentProgram; -#if BGFX_D3D11_MAP_CONSTANT_BUFFERS - uint8_t* m_vsScratch; - uint8_t* m_fsScratch; -#else uint8_t m_vsScratch[64<<10]; uint8_t m_fsScratch[64<<10]; uint32_t m_vsChanges; uint32_t m_fsChanges; -#endif // BGFX_D3D11_MAP_CONSTANT_BUFFERS FrameBufferHandle m_fbh; bool m_rtMsaa; @@ -2762,7 +3306,11 @@ BX_PRAGMA_DIAGNOSTIC_POP(); RendererContextI* rendererCreate() { s_renderD3D11 = BX_NEW(g_allocator, RendererContextD3D11); - s_renderD3D11->init(); + if (!s_renderD3D11->init() ) + { + BX_DELETE(g_allocator, s_renderD3D11); + s_renderD3D11 = NULL; + } return s_renderD3D11; } @@ -2773,6 +3321,55 @@ BX_PRAGMA_DIAGNOSTIC_POP(); s_renderD3D11 = NULL; } + void trim() + { +#if BX_PLATFORM_WINRT + if (NULL != s_renderD3D11) + { + if (s_renderD3D11->m_device) + { + IDXGIDevice3* pDXGIDevice; + HRESULT hr = s_renderD3D11->m_device->QueryInterface(__uuidof(IDXGIDevice3),(void **)&pDXGIDevice); + if (SUCCEEDED(hr) ) + { + pDXGIDevice->Trim(); + pDXGIDevice->Release(); + } + } + } +#endif // BX_PLATFORM_WINRT + } + + void stubMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride) + { + ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx; + for (uint32_t ii = 0; ii < _numDrawIndirect; ++ii) + { + deviceCtx->DrawInstancedIndirect(_ptr, _offset); + _offset += _stride; + } + } + + void stubMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride) + { + ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx; + for (uint32_t ii = 0; ii < _numDrawIndirect; ++ii) + { + deviceCtx->DrawIndexedInstancedIndirect(_ptr, _offset); + _offset += _stride; + } + } + + void amdAgsMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride) + { + agsDriverExtensions_MultiDrawInstancedIndirect(s_renderD3D11->m_ags, _numDrawIndirect, _ptr, _offset, _stride); + } + + void amdAgsMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride) + { + agsDriverExtensions_MultiDrawIndexedInstancedIndirect(s_renderD3D11->m_ags, _numDrawIndirect, _ptr, _offset, _stride); + } + struct UavFormat { DXGI_FORMAT format[3]; @@ -2968,7 +3565,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); D3D11_MAPPED_SUBRESOURCE mapped; BX_UNUSED(_discard); D3D11_MAP type = D3D11_MAP_WRITE_DISCARD; - DX_CHECK(deviceCtx->Map(m_ptr, 0, type, 0, &mapped)); + DX_CHECK(deviceCtx->Map(m_ptr, 0, type, 0, &mapped) ); memcpy( (uint8_t*)mapped.pData + _offset, _data, _size); deviceCtx->Unmap(m_ptr, 0); #endif // 0 @@ -2985,6 +3582,42 @@ BX_PRAGMA_DIAGNOSTIC_POP(); BufferD3D11::create(_size, _data, _flags, stride, true); } + static bool hasDepthOp(const void* _code, uint32_t _size) + { + bx::MemoryReader rd(_code, _size); + + DxbcContext dxbc; + read(&rd, dxbc); + + struct FindDepthOp + { + FindDepthOp() + : m_found(false) + { + } + + static bool find(uint32_t /*_offset*/, const DxbcInstruction& _instruction, void* _userData) + { + FindDepthOp& out = *reinterpret_cast<FindDepthOp*>(_userData); + if (_instruction.opcode == DxbcOpcode::DISCARD + || (0 != _instruction.numOperands && DxbcOperandType::OutputDepth == _instruction.operand[0].type) ) + { + out.m_found = true; + return false; + } + + return true; + } + + bool m_found; + + } find; + + parse(dxbc.shader, FindDepthOp::find, &find); + + return find.m_found; + } + void ShaderD3D11::create(const Memory* _mem) { bx::MemoryReader reader(_mem->data, _mem->size); @@ -3056,26 +3689,31 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_predefined[m_numPredefined].m_type = uint8_t(predefined|fragmentBit); m_numPredefined++; } - else + else if (0 == (BGFX_UNIFORM_SAMPLERBIT & type) ) { const UniformInfo* info = s_renderD3D11->m_uniformReg.find(name); + BX_CHECK(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name); if (NULL != info) { if (NULL == m_constantBuffer) { - m_constantBuffer = ConstantBuffer::create(1024); + m_constantBuffer = UniformBuffer::create(1024); } kind = "user"; m_constantBuffer->writeUniformHandle( (UniformType::Enum)(type|fragmentBit), regIndex, info->m_handle, regCount); } } + else + { + kind = "sampler"; + } BX_TRACE("\t%s: %s (%s), num %2d, r.index %3d, r.count %2d" , kind , name - , getUniformTypeName(UniformType::Enum(type&~BGFX_UNIFORM_FRAGMENTBIT) ) + , getUniformTypeName(UniformType::Enum(type&~BGFX_UNIFORM_MASK) ) , num , regIndex , regCount @@ -3097,6 +3735,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (BGFX_CHUNK_MAGIC_FSH == magic) { + m_hasDepthOp = hasDepthOp(code, shaderSize); DX_CHECK(s_renderD3D11->m_device->CreatePixelShader(code, shaderSize, NULL, &m_pixelShader) ); BGFX_FATAL(NULL != m_ptr, bgfx::Fatal::InvalidShader, "Failed to create fragment shader."); } @@ -3117,7 +3756,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); uint8_t numAttrs; bx::read(&reader, numAttrs); - memset(m_attrMask, 0, sizeof(m_attrMask)); + memset(m_attrMask, 0, sizeof(m_attrMask) ); for (uint32_t ii = 0; ii < numAttrs; ++ii) { @@ -3128,7 +3767,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (Attrib::Count != attr) { - m_attrMask[attr] = 0xff; + m_attrMask[attr] = UINT16_MAX; } } @@ -3139,13 +3778,8 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { D3D11_BUFFER_DESC desc; desc.ByteWidth = (size + 0xf) & ~0xf; -#if BGFX_D3D11_MAP_CONSTANT_BUFFERS - desc.Usage = D3D11_USAGE_DYNAMIC; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; -#else desc.Usage = D3D11_USAGE_DEFAULT; desc.CPUAccessFlags = 0; -#endif // BGFX_D3D11_MAP_CONSTANT_BUFFERS desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; desc.MiscFlags = 0; desc.StructureByteStride = 0; @@ -3155,8 +3789,6 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void TextureD3D11::create(const Memory* _mem, uint32_t _flags, uint8_t _skip) { - m_sampler = s_renderD3D11->getSamplerState(_flags); - ImageContainer imageContainer; if (imageParse(imageContainer, _mem->data, _mem->size) ) @@ -3206,7 +3838,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); const bool swizzle = TextureFormat::BGRA8 == m_textureFormat && 0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE); BX_TRACE("Texture %3d: %s (requested: %s), %dx%d%s%s%s." - , this - s_renderD3D11->m_textures + , getHandle() , getName( (TextureFormat::Enum)m_textureFormat) , getName( (TextureFormat::Enum)m_requestedFormat) , textureWidth @@ -3403,6 +4035,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void TextureD3D11::destroy() { + s_renderD3D11->m_srvUavLru.invalidateWithParent(getHandle().idx); DX_RELEASE(m_srv, 0); DX_RELEASE(m_uav, 0); DX_RELEASE(m_ptr, 0); @@ -3445,20 +4078,30 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } - void TextureD3D11::commit(uint8_t _stage, uint32_t _flags) + void TextureD3D11::commit(uint8_t _stage, uint32_t _flags, const float _palette[][4]) { TextureStage& ts = s_renderD3D11->m_textureStage; ts.m_srv[_stage] = m_srv; - ts.m_sampler[_stage] = 0 == (BGFX_SAMPLER_DEFAULT_FLAGS & _flags) - ? s_renderD3D11->getSamplerState(_flags) - : m_sampler + uint32_t flags = 0 == (BGFX_SAMPLER_DEFAULT_FLAGS & _flags) + ? _flags + : m_flags ; + uint32_t index = (flags & BGFX_TEXTURE_BORDER_COLOR_MASK) >> BGFX_TEXTURE_BORDER_COLOR_SHIFT; + ts.m_sampler[_stage] = s_renderD3D11->getSamplerState(flags + , _palette[index]) + ; } void TextureD3D11::resolve() { } + TextureHandle TextureD3D11::getHandle() const + { + TextureHandle handle = { (uint16_t)(this - s_renderD3D11->m_textures) }; + return handle; + } + void FrameBufferD3D11::create(uint8_t _num, const TextureHandle* _handles) { for (uint32_t ii = 0; ii < BX_COUNTOF(m_rtv); ++ii) @@ -3476,38 +4119,59 @@ BX_PRAGMA_DIAGNOSTIC_POP(); 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; + ID3D11Device* device = s_renderD3D11->m_device; + HRESULT hr; - hr = s_renderD3D11->m_factory->CreateSwapChain(s_renderD3D11->m_device + hr = s_renderD3D11->m_factory->CreateSwapChain(device , &scd , &m_swapChain ); BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Failed to create swap chain."); ID3D11Resource* ptr; - DX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&ptr)); - DX_CHECK(s_renderD3D11->m_device->CreateRenderTargetView(ptr, NULL, &m_rtv[0]) ); + DX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&ptr) ); + DX_CHECK(device->CreateRenderTargetView(ptr, NULL, &m_rtv[0]) ); DX_RELEASE(ptr, 0); + + DXGI_FORMAT fmtDsv = isDepth(_depthFormat) + ? s_textureFormat[_depthFormat].m_fmtDsv + : DXGI_FORMAT_D24_UNORM_S8_UINT + ; + D3D11_TEXTURE2D_DESC dsd; + dsd.Width = scd.BufferDesc.Width; + dsd.Height = scd.BufferDesc.Height; + dsd.MipLevels = 1; + dsd.ArraySize = 1; + dsd.Format = fmtDsv; + dsd.SampleDesc = scd.SampleDesc; + dsd.Usage = D3D11_USAGE_DEFAULT; + dsd.BindFlags = D3D11_BIND_DEPTH_STENCIL; + dsd.CPUAccessFlags = 0; + dsd.MiscFlags = 0; + + ID3D11Texture2D* depthStencil; + DX_CHECK(device->CreateTexture2D(&dsd, NULL, &depthStencil) ); + DX_CHECK(device->CreateDepthStencilView(depthStencil, NULL, &m_dsv) ); + DX_RELEASE(depthStencil, 0); + m_srv[0] = NULL; - m_dsv = NULL; m_denseIdx = _denseIdx; m_num = 1; } uint16_t FrameBufferD3D11::destroy() { - preReset(); + preReset(true); DX_RELEASE(m_swapChain, 0); - m_num = 0; + m_num = 0; m_numTh = 0; uint16_t denseIdx = m_denseIdx; @@ -3516,19 +4180,26 @@ BX_PRAGMA_DIAGNOSTIC_POP(); return denseIdx; } - void FrameBufferD3D11::preReset() + void FrameBufferD3D11::preReset(bool _force) { - for (uint32_t ii = 0, num = m_num; ii < num; ++ii) + if (0 < m_numTh + || _force) { - DX_RELEASE(m_srv[ii], 0); - DX_RELEASE(m_rtv[ii], 0); - } + for (uint32_t ii = 0, num = m_num; ii < num; ++ii) + { + DX_RELEASE(m_srv[ii], 0); + DX_RELEASE(m_rtv[ii], 0); + } - DX_RELEASE(m_dsv, 0); + DX_RELEASE(m_dsv, 0); + } } void FrameBufferD3D11::postReset() { + m_width = 0; + m_height = 0; + if (0 < m_numTh) { m_num = 0; @@ -3538,6 +4209,32 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (isValid(handle) ) { const TextureD3D11& texture = s_renderD3D11->m_textures[handle.idx]; + + if (0 == m_width) + { + switch (texture.m_type) + { + case TextureD3D11::Texture2D: + case TextureD3D11::TextureCube: + { + D3D11_TEXTURE2D_DESC desc; + texture.m_texture2d->GetDesc(&desc); + m_width = desc.Width; + m_height = desc.Height; + } + break; + + case TextureD3D11::Texture3D: + { + D3D11_TEXTURE3D_DESC desc; + texture.m_texture3d->GetDesc(&desc); + m_width = desc.Width; + m_height = desc.Height; + } + break; + } + } + if (isDepth( (TextureFormat::Enum)texture.m_textureFormat) ) { BX_CHECK(NULL == m_dsv, "Frame buffer already has depth-stencil attached."); @@ -3678,8 +4375,8 @@ BX_PRAGMA_DIAGNOSTIC_POP(); ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx; Frame& frame = m_frame[m_control.m_read]; - uint64_t end; - HRESULT hr = deviceCtx->GetData(frame.m_end, &end, sizeof(end), 0); + uint64_t finish; + HRESULT hr = deviceCtx->GetData(frame.m_end, &finish, sizeof(finish), 0); if (S_OK == hr) { m_control.consume(1); @@ -3697,7 +4394,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); deviceCtx->GetData(frame.m_start, &start, sizeof(start), 0); m_frequency = disjoint.Frequency; - m_elapsed = end - start; + m_elapsed = finish - start; return true; } @@ -3717,10 +4414,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); int64_t elapsed = -bx::getHPCounter(); int64_t captureElapsed = 0; - if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) - { - m_gpuTimer.begin(); - } + m_gpuTimer.begin(); if (0 < _render->m_iboffset) { @@ -3741,9 +4435,9 @@ BX_PRAGMA_DIAGNOSTIC_POP(); currentState.m_flags = BGFX_STATE_NONE; currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE); - const bool hmdEnabled = m_ovr.isEnabled() || m_ovr.isDebug(); - _render->m_hmdEnabled = hmdEnabled; + _render->m_hmdInitialized = m_ovr.isInitialized(); + const bool hmdEnabled = m_ovr.isEnabled() || m_ovr.isDebug(); ViewState& viewState = m_viewState; viewState.reset(_render, hmdEnabled); @@ -3753,11 +4447,11 @@ BX_PRAGMA_DIAGNOSTIC_POP(); uint16_t programIdx = invalidHandle; SortKey key; - uint8_t view = 0xff; + uint16_t view = UINT16_MAX; FrameBufferHandle fbh = BGFX_INVALID_HANDLE; 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); + uint8_t primIndex = uint8_t(primType >> BGFX_STATE_PT_SHIFT); PrimInfo prim = s_primInfo[primIndex]; deviceCtx->IASetPrimitiveTopology(prim.m_type); @@ -3805,7 +4499,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); restartState = 2; item = restartItem; restartItem = numItems; - view = 0xff; + view = UINT16_MAX; continue; } @@ -3849,8 +4543,15 @@ BX_PRAGMA_DIAGNOSTIC_POP(); PIX_BEGINEVENT(D3DCOLOR_RGBA(0xff, 0x00, 0x00, 0xff), viewNameW); } - viewState.m_rect.m_x = eye * (viewState.m_rect.m_width+1)/2; - viewState.m_rect.m_width /= 2; + if (m_ovr.isEnabled() ) + { + 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; + } } else { @@ -3879,7 +4580,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (BGFX_CLEAR_NONE != (clr.m_flags & BGFX_CLEAR_MASK) ) { - clearQuad(_clearQuad, viewState.m_rect, clr, _render->m_clearColor); + clearQuad(_clearQuad, viewState.m_rect, clr, _render->m_colorPalette); prim = s_primInfo[BX_COUNTOF(s_primName)]; // Force primitive type update after clear quad. } } @@ -3918,7 +4619,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); bool programChanged = false; bool constantsChanged = compute.m_constBegin < compute.m_constEnd; - rendererUpdateUniforms(this, _render->m_constantBuffer, compute.m_constBegin, compute.m_constEnd); + rendererUpdateUniforms(this, _render->m_uniformBuffer, compute.m_constBegin, compute.m_constEnd); if (key.m_program != programIdx) { @@ -3940,7 +4641,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (constantsChanged) { - ConstantBuffer* vcb = program.m_vsh->m_constantBuffer; + UniformBuffer* vcb = program.m_vsh->m_constantBuffer; if (NULL != vcb) { commit(*vcb); @@ -3969,15 +4670,21 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { case Binding::Image: { - const TextureD3D11& texture = m_textures[bind.m_idx]; + TextureD3D11& texture = m_textures[bind.m_idx]; if (Access::Read != bind.m_un.m_compute.m_access) { - uav[ii] = texture.m_uav; + uav[ii] = 0 == bind.m_un.m_compute.m_mip + ? texture.m_uav + : s_renderD3D11->getCachedUav(texture.getHandle(), bind.m_un.m_compute.m_mip) + ; } else { - srv[ii] = texture.m_srv; - sampler[ii] = texture.m_sampler; + srv[ii] = 0 == bind.m_un.m_compute.m_mip + ? texture.m_srv + : s_renderD3D11->getCachedSrv(texture.getHandle(), bind.m_un.m_compute.m_mip) + ; + sampler[ii] = s_renderD3D11->getSamplerState(texture.m_flags, NULL); } } break; @@ -4056,10 +4763,12 @@ BX_PRAGMA_DIAGNOSTIC_POP(); const uint64_t newFlags = draw.m_flags; uint64_t changedFlags = currentState.m_flags ^ draw.m_flags; + changedFlags |= currentState.m_rgba != draw.m_rgba ? BGFX_D3D11_BLEND_STATE_MASK : 0; currentState.m_flags = newFlags; const uint64_t newStencil = draw.m_stencil; uint64_t changedStencil = currentState.m_stencil ^ draw.m_stencil; + changedFlags |= 0 != changedStencil ? BGFX_D3D11_DEPTH_STENCIL_MASK : 0; currentState.m_stencil = newStencil; if (resetState) @@ -4118,29 +4827,25 @@ BX_PRAGMA_DIAGNOSTIC_POP(); setRasterizerState(newFlags, wireframe, scissorEnabled); } - if ( (BGFX_STATE_DEPTH_WRITE|BGFX_STATE_DEPTH_TEST_MASK) & changedFlags - || 0 != changedStencil) + if (BGFX_D3D11_DEPTH_STENCIL_MASK & changedFlags) { setDepthStencilState(newFlags, newStencil); } + if (BGFX_D3D11_BLEND_STATE_MASK & changedFlags) + { + setBlendState(newFlags, draw.m_rgba); + currentState.m_rgba = draw.m_rgba; + } + if ( (0 | BGFX_STATE_CULL_MASK - | BGFX_STATE_RGB_WRITE - | BGFX_STATE_ALPHA_WRITE - | BGFX_STATE_BLEND_MASK - | BGFX_STATE_BLEND_EQUATION_MASK | BGFX_STATE_ALPHA_REF_MASK | BGFX_STATE_PT_MASK | BGFX_STATE_POINT_SIZE_MASK | BGFX_STATE_MSAA ) & changedFlags) { - if ( (BGFX_STATE_BLEND_MASK|BGFX_STATE_BLEND_EQUATION_MASK|BGFX_STATE_ALPHA_WRITE|BGFX_STATE_RGB_WRITE) & changedFlags) - { - setBlendState(newFlags, draw.m_rgba); - } - if ( (BGFX_STATE_CULL_MASK|BGFX_STATE_MSAA) & changedFlags) { setRasterizerState(newFlags, wireframe, scissorEnabled); @@ -4163,7 +4868,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); bool programChanged = false; bool constantsChanged = draw.m_constBegin < draw.m_constEnd; - rendererUpdateUniforms(this, _render->m_constantBuffer, draw.m_constBegin, draw.m_constEnd); + rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_constBegin, draw.m_constEnd); if (key.m_program != programIdx) { @@ -4185,9 +4890,10 @@ BX_PRAGMA_DIAGNOSTIC_POP(); deviceCtx->VSSetShader(vsh->m_vertexShader, NULL, 0); deviceCtx->VSSetConstantBuffers(0, 1, &vsh->m_buffer); - if (NULL != m_currentColor) + const ShaderD3D11* fsh = program.m_fsh; + if (NULL != m_currentColor + || fsh->m_hasDepthOp) { - const ShaderD3D11* fsh = program.m_fsh; deviceCtx->PSSetShader(fsh->m_pixelShader, NULL, 0); deviceCtx->PSSetConstantBuffers(0, 1, &fsh->m_buffer); } @@ -4205,21 +4911,15 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { ProgramD3D11& program = m_program[programIdx]; -#if BGFX_D3D11_MAP_CONSTANT_BUFFERS - if (constantsChanged || 0 != program.m_numPredefined) - { - prepareShaderConstants(); - } -#endif // BGFX_D3D11_MAP_CONSTANT_BUFFERS if (constantsChanged) { - ConstantBuffer* vcb = program.m_vsh->m_constantBuffer; + UniformBuffer* vcb = program.m_vsh->m_constantBuffer; if (NULL != vcb) { commit(*vcb); } - ConstantBuffer* fcb = program.m_fsh->m_constantBuffer; + UniformBuffer* fcb = program.m_fsh->m_constantBuffer; if (NULL != fcb) { commit(*fcb); @@ -4239,16 +4939,16 @@ BX_PRAGMA_DIAGNOSTIC_POP(); uint32_t changes = 0; for (uint8_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage) { - const Binding& sampler = draw.m_bind[stage]; + const Binding& bind = draw.m_bind[stage]; Binding& current = currentState.m_bind[stage]; - if (current.m_idx != sampler.m_idx - || current.m_un.m_draw.m_flags != sampler.m_un.m_draw.m_flags + if (current.m_idx != bind.m_idx + || current.m_un.m_draw.m_flags != bind.m_un.m_draw.m_flags || programChanged) { - if (invalidHandle != sampler.m_idx) + if (invalidHandle != bind.m_idx) { - TextureD3D11& texture = m_textures[sampler.m_idx]; - texture.commit(stage, sampler.m_un.m_draw.m_flags); + TextureD3D11& texture = m_textures[bind.m_idx]; + texture.commit(stage, bind.m_un.m_draw.m_flags, _render->m_colorPalette); } else { @@ -4259,7 +4959,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); ++changes; } - current = sampler; + current = bind; } if (0 < changes) @@ -4294,7 +4994,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (isValid(draw.m_instanceDataBuffer) ) { - const VertexBufferD3D11& inst = m_vertexBuffers[draw.m_instanceDataBuffer.idx]; + const VertexBufferD3D11& inst = m_vertexBuffers[draw.m_instanceDataBuffer.idx]; 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); @@ -4359,12 +5059,11 @@ BX_PRAGMA_DIAGNOSTIC_POP(); : draw.m_numIndirect ; - uint32_t args = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE; - for (uint32_t ii = 0; ii < numDrawIndirect; ++ii) - { - deviceCtx->DrawIndexedInstancedIndirect(ptr, args); - args += BGFX_CONFIG_DRAW_INDIRECT_STRIDE; - } + multiDrawIndexedInstancedIndirect(numDrawIndirect + , ptr + , draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE + , BGFX_CONFIG_DRAW_INDIRECT_STRIDE + ); } else { @@ -4373,12 +5072,11 @@ BX_PRAGMA_DIAGNOSTIC_POP(); : draw.m_numIndirect ; - uint32_t args = draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE; - for (uint32_t ii = 0; ii < numDrawIndirect; ++ii) - { - deviceCtx->DrawInstancedIndirect(ptr, args); - args += BGFX_CONFIG_DRAW_INDIRECT_STRIDE; - } + multiDrawInstancedIndirect(numDrawIndirect + , ptr + , draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE + , BGFX_CONFIG_DRAW_INDIRECT_STRIDE + ); } } else @@ -4507,23 +5205,31 @@ BX_PRAGMA_DIAGNOSTIC_POP(); min = min > frameTime ? frameTime : min; max = max < frameTime ? frameTime : max; - if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) + static uint32_t maxGpuLatency = 0; + static double maxGpuElapsed = 0.0f; + double elapsedGpuMs = 0.0; + + m_gpuTimer.end(); + + while (m_gpuTimer.get() ) { - PIX_BEGINEVENT(D3DCOLOR_RGBA(0x40, 0x40, 0x40, 0xff), L"debugstats"); + 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); - static uint32_t maxGpuLatency = 0; - static double maxGpuElapsed = 0.0f; - double elapsedGpuMs = 0.0; + const int64_t timerFreq = bx::getHPFrequency(); - m_gpuTimer.end(); + Stats& perfStats = _render->m_perfStats; + perfStats.cpuTime = frameTime; + perfStats.cpuTimerFreq = timerFreq; + perfStats.gpuTime = m_gpuTimer.m_elapsed; + perfStats.gpuTimerFreq = m_gpuTimer.m_frequency; - while (m_gpuTimer.get() ) - { - 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); + if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) + { + PIX_BEGINEVENT(D3DCOLOR_RGBA(0x40, 0x40, 0x40, 0xff), L"debugstats"); TextVideoMem& tvm = m_textVideoMem; @@ -4531,7 +5237,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (now >= next) { - next = now + bx::getHPFrequency(); + next = now + timerFreq; double freq = double(bx::getHPFrequency() ); double toMs = 1000.0/freq; @@ -4545,7 +5251,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); const DXGI_ADAPTER_DESC& desc = m_adapterDesc; char description[BX_COUNTOF(desc.Description)]; wcstombs(description, desc.Description, BX_COUNTOF(desc.Description) ); - tvm.printf(0, pos++, 0x0f, " Device: %s", description); + tvm.printf(0, pos++, 0x8f, " Device: %s", description); char dedicatedVideo[16]; bx::prettify(dedicatedVideo, BX_COUNTOF(dedicatedVideo), desc.DedicatedVideoMemory); @@ -4556,10 +5262,14 @@ BX_PRAGMA_DIAGNOSTIC_POP(); char sharedSystem[16]; bx::prettify(sharedSystem, BX_COUNTOF(sharedSystem), desc.SharedSystemMemory); - tvm.printf(0, pos++, 0x0f, " Memory: %s (video), %s (system), %s (shared)" + char processMemoryUsed[16]; + bx::prettify(processMemoryUsed, BX_COUNTOF(processMemoryUsed), bx::getProcessMemoryUsed() ); + + tvm.printf(0, pos++, 0x8f, " Memory: %s (video), %s (system), %s (shared), %s (process) " , dedicatedVideo , dedicatedSystem , sharedSystem + , processMemoryUsed ); pos = 10; @@ -4583,7 +5293,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); ); double elapsedCpuMs = double(elapsed)*toMs; - tvm.printf(10, pos++, 0x8e, " Submitted: %4d (draw %4d, compute %4d) / CPU %3.4f [ms] %c GPU %3.4f [ms] (latency %d)" + tvm.printf(10, pos++, 0x8e, " Submitted: %5d (draw %5d, compute %4d) / CPU %7.4f [ms] %c GPU %7.4f [ms] (latency %d) " , _render->m_num , statsKeyType[0] , statsKeyType[1] @@ -4611,9 +5321,10 @@ BX_PRAGMA_DIAGNOSTIC_POP(); tvm.printf(tvm.m_width-27, 0, 0x1f, " [F11 - RenderDoc capture] "); } - tvm.printf(10, pos++, 0x8e, " Indices: %7d", statsNumIndices); - tvm.printf(10, pos++, 0x8e, " DVB size: %7d", _render->m_vboffset); - tvm.printf(10, pos++, 0x8e, " DIB size: %7d", _render->m_iboffset); + tvm.printf(10, pos++, 0x8e, " Indices: %7d ", statsNumIndices); + tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); + tvm.printf(10, pos++, 0x8e, " DVB size: %7d ", _render->m_vboffset); + tvm.printf(10, pos++, 0x8e, " DIB size: %7d ", _render->m_iboffset); pos++; tvm.printf(10, pos++, 0x8e, " State cache: "); @@ -4628,13 +5339,13 @@ BX_PRAGMA_DIAGNOSTIC_POP(); pos++; double captureMs = double(captureElapsed)*toMs; - tvm.printf(10, pos++, 0x8e, " Capture: %3.4f [ms]", captureMs); + tvm.printf(10, pos++, 0x8e, " Capture: %7.4f [ms] ", captureMs); uint8_t attr[2] = { 0x89, 0x8a }; uint8_t attrIndex = _render->m_waitSubmit < _render->m_waitRender; - 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); + tvm.printf(10, pos++, attr[attrIndex&1], " Submit wait: %7.4f [ms] ", _render->m_waitSubmit*toMs); + tvm.printf(10, pos++, attr[(attrIndex+1)&1], " Render wait: %7.4f [ms] ", _render->m_waitRender*toMs); min = frameTime; max = frameTime; |