diff options
Diffstat (limited to '3rdparty/bgfx/src/renderer_d3d12.cpp')
-rw-r--r-- | 3rdparty/bgfx/src/renderer_d3d12.cpp | 2187 |
1 files changed, 1456 insertions, 731 deletions
diff --git a/3rdparty/bgfx/src/renderer_d3d12.cpp b/3rdparty/bgfx/src/renderer_d3d12.cpp index d577e63b609..36d23cb5a91 100644 --- a/3rdparty/bgfx/src/renderer_d3d12.cpp +++ b/3rdparty/bgfx/src/renderer_d3d12.cpp @@ -1,6 +1,6 @@ /* - * Copyright 2011-2018 Branimir Karadzic. All rights reserved. - * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause + * Copyright 2011-2022 Branimir Karadzic. All rights reserved. + * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE */ #include "bgfx_p.h" @@ -8,22 +8,30 @@ #if BGFX_CONFIG_RENDERER_DIRECT3D12 # include "renderer_d3d12.h" -#if !BX_PLATFORM_WINDOWS +#if !BX_PLATFORM_WINDOWS && !BX_PLATFORM_LINUX # include <inspectable.h> # if BX_PLATFORM_WINRT # include <windows.ui.xaml.media.dxinterop.h> # endif // BX_PLATFORM_WINRT #endif // !BX_PLATFORM_WINDOWS -#if BGFX_CONFIG_DEBUG_PIX && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) +#if BGFX_CONFIG_DEBUG_ANNOTATION && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) PFN_PIX_GET_THREAD_INFO bgfx_PIXGetThreadInfo; PFN_PIX_EVENTS_REPLACE_BLOCK bgfx_PIXEventsReplaceBlock; -#endif // BGFX_CONFIG_DEBUG_PIX && BX_PLATFORM_WINDOWS +#endif // BGFX_CONFIG_DEBUG_ANNOTATION && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) namespace bgfx { namespace d3d12 { static char s_viewName[BGFX_CONFIG_MAX_VIEWS][BGFX_CONFIG_MAX_VIEW_NAME]; + inline void setViewType(ViewId _view, const bx::StringView _str) + { + if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION || BGFX_CONFIG_PROFILER) ) + { + bx::memCopy(&s_viewName[_view][3], _str.getPtr(), _str.getLength() ); + } + } + struct PrimInfo { D3D_PRIMITIVE_TOPOLOGY m_topology; @@ -174,95 +182,119 @@ namespace bgfx { namespace d3d12 DXGI_FORMAT m_fmtSrv; DXGI_FORMAT m_fmtDsv; DXGI_FORMAT m_fmtSrgb; + uint32_t m_mapping; }; 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 }, // ATC - { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // ATCE - { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // ATCI - { DXGI_FORMAT_ASTC_4X4_UNORM, DXGI_FORMAT_ASTC_4X4_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_4X4_UNORM_SRGB }, // ASTC4x4 - { DXGI_FORMAT_ASTC_5X5_UNORM, DXGI_FORMAT_ASTC_5X5_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_5X5_UNORM_SRGB }, // ASTC5x5 - { DXGI_FORMAT_ASTC_6X6_UNORM, DXGI_FORMAT_ASTC_6X6_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_6X6_UNORM_SRGB }, // ASTC6x6 - { DXGI_FORMAT_ASTC_8X5_UNORM, DXGI_FORMAT_ASTC_8X5_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_8X5_UNORM_SRGB }, // ASTC8x5 - { DXGI_FORMAT_ASTC_8X6_UNORM, DXGI_FORMAT_ASTC_8X6_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_8X6_UNORM_SRGB }, // ASTC8x6 - { DXGI_FORMAT_ASTC_10X5_UNORM, DXGI_FORMAT_ASTC_10X5_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_10X5_UNORM_SRGB }, // ASTC10x5 - { 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_UNORM, DXGI_FORMAT_R16_UNORM, 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_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGB8 - { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGB8I - { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGB8U - { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGB8S - { 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_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 }, // RG11B10F - { 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 +#define $0 D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0 +#define $1 D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1 +#define $R D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0 +#define $G D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1 +#define $B D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2 +#define $A D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3 + { DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_BC1_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // BC1 + { DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_BC2_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // BC2 + { DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_BC3_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // BC3 + { DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // BC4 + { DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // BC5 + { DXGI_FORMAT_BC6H_SF16, DXGI_FORMAT_BC6H_SF16, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // BC6H + { DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_BC7_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // BC7 + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ETC1 + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ETC2 + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ETC2A + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ETC2A1 + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // PTC12 + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // PTC14 + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // PTC12A + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // PTC14A + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // PTC22 + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // PTC24 + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ATC + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ATCE + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ATCI + { DXGI_FORMAT_ASTC_4X4_UNORM, DXGI_FORMAT_ASTC_4X4_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_4X4_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ASTC4x4 + { DXGI_FORMAT_ASTC_5X4_UNORM, DXGI_FORMAT_ASTC_5X4_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_5X4_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ASTC5x4 + { DXGI_FORMAT_ASTC_5X5_UNORM, DXGI_FORMAT_ASTC_5X5_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_5X5_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ASTC5x5 + { DXGI_FORMAT_ASTC_6X5_UNORM, DXGI_FORMAT_ASTC_6X5_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_6X5_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ASTC6x5 + { DXGI_FORMAT_ASTC_6X6_UNORM, DXGI_FORMAT_ASTC_6X6_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_6X6_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ASTC6x6 + { DXGI_FORMAT_ASTC_8X5_UNORM, DXGI_FORMAT_ASTC_8X5_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_8X5_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ASTC8x5 + { DXGI_FORMAT_ASTC_8X6_UNORM, DXGI_FORMAT_ASTC_8X6_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_8X6_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ASTC8x6 + { DXGI_FORMAT_ASTC_8X8_UNORM, DXGI_FORMAT_ASTC_8X8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_8X8_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ASTC8x8 + { DXGI_FORMAT_ASTC_10X5_UNORM, DXGI_FORMAT_ASTC_10X5_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_10X5_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ASTC10x5 + { DXGI_FORMAT_ASTC_10X6_UNORM, DXGI_FORMAT_ASTC_10X6_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_10X6_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ASTC10x6 + { DXGI_FORMAT_ASTC_10X8_UNORM, DXGI_FORMAT_ASTC_10X8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_10X8_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ASTC10x8 + { DXGI_FORMAT_ASTC_10X10_UNORM, DXGI_FORMAT_ASTC_10X10_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_10X10_UNORM_SRGB,D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ASTC10x10 + { DXGI_FORMAT_ASTC_12X10_UNORM, DXGI_FORMAT_ASTC_12X10_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_12X10_UNORM_SRGB,D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ASTC12x10 + { DXGI_FORMAT_ASTC_12X12_UNORM, DXGI_FORMAT_ASTC_12X12_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_12X12_UNORM_SRGB,D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // ASTC12x12 + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // Unknown + { DXGI_FORMAT_R1_UNORM, DXGI_FORMAT_R1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // R1 + { DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // A8 + { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // R8 + { DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // R8I + { DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // R8U + { DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // R8S + { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // R16 + { DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // R16I + { DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // R16U + { DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // R16F + { DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // R16S + { DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // R32I + { DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // R32U + { DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // R32F + { DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RG8 + { DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RG8I + { DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RG8U + { DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RG8S + { DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RG16 + { DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RG16I + { DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RG16U + { DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RG16F + { DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RG16S + { DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RG32I + { DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RG32U + { DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RG32F + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGB8 + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGB8I + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGB8U + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGB8S + { DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGB9E5F + { DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // BGRA8 + { DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGBA8 + { DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGBA8I + { DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGBA8U + { DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGBA8S + { DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGBA16 + { DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGBA16I + { DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGBA16U + { DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGBA16F + { DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGBA16S + { DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGBA32I + { DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGBA32U + { DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGBA32F + { DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // B5G6R5 + { DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING($B, $G, $R, $1) }, // R5G6B5 + { DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // BGRA4 + { DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING($B, $G, $R, $A) }, // RGBA4 + { DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // BGR5A1 + { DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING($B, $G, $R, $A) }, // RGB5A1 + { DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RGB10A2 + { DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // RG11B10F + { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // UnknownDepth + { DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_D16_UNORM, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // D16 + { DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // D24 + { DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // D24S8 + { DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // D32 + { DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_D32_FLOAT, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // D16F + { DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_D32_FLOAT, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // D24F + { DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_D32_FLOAT, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // D32F + { DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING }, // D0S8 +#undef $0 +#undef $1 +#undef $R +#undef $G +#undef $B +#undef $A }; BX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_textureFormat) ); @@ -324,19 +356,19 @@ namespace bgfx { namespace d3d12 }; BX_STATIC_ASSERT(AttribType::Count == BX_COUNTOF(s_attribType) ); - static D3D12_INPUT_ELEMENT_DESC* fillVertexDecl(uint8_t _stream, D3D12_INPUT_ELEMENT_DESC* _out, const VertexDecl& _decl) + static D3D12_INPUT_ELEMENT_DESC* fillVertexLayout(uint8_t _stream, D3D12_INPUT_ELEMENT_DESC* _out, const VertexLayout& _layout) { D3D12_INPUT_ELEMENT_DESC* elem = _out; for (uint32_t attr = 0; attr < Attrib::Count; ++attr) { - if (UINT16_MAX != _decl.m_attributes[attr]) + if (UINT16_MAX != _layout.m_attributes[attr]) { bx::memCopy(elem, &s_attrib[attr], sizeof(D3D12_INPUT_ELEMENT_DESC) ); elem->InputSlot = _stream; - if (0 == _decl.m_attributes[attr]) + if (0 == _layout.m_attributes[attr]) { elem->AlignedByteOffset = 0; } @@ -346,9 +378,9 @@ namespace bgfx { namespace d3d12 AttribType::Enum type; bool normalized; bool asInt; - _decl.decode(Attrib::Enum(attr), num, type, normalized, asInt); + _layout.decode(Attrib::Enum(attr), num, type, normalized, asInt); elem->Format = s_attribType[type][num-1][normalized]; - elem->AlignedByteOffset = _decl.m_offset[attr]; + elem->AlignedByteOffset = _layout.m_offset[attr]; } ++elem; @@ -386,11 +418,14 @@ namespace bgfx { namespace d3d12 static const GUID IID_ID3D12Device3 = { 0x81dadc15, 0x2bad, 0x4392, { 0x93, 0xc5, 0x10, 0x13, 0x45, 0xc4, 0xaa, 0x98 } }; static const GUID IID_ID3D12Device4 = { 0xe865df17, 0xa9ee, 0x46f9, { 0xa4, 0x63, 0x30, 0x98, 0x31, 0x5a, 0xa2, 0xe5 } }; static const GUID IID_ID3D12Device5 = { 0x8b4f173b, 0x2fea, 0x4b80, { 0x8f, 0x58, 0x43, 0x07, 0x19, 0x1a, 0xb9, 0x5d } }; + static const GUID IID_ID3D12Device6 = { 0xc70b221b, 0x40e4, 0x4a17, { 0x89, 0xaf, 0x02, 0x5a, 0x07, 0x27, 0xa6, 0xdc } }; + static const GUID IID_ID3D12Device7 = { 0x5c014b53, 0x68a1, 0x4b9b, { 0x8b, 0xd1, 0xdd, 0x60, 0x46, 0xb9, 0x35, 0x8b } }; + static const GUID IID_ID3D12Device8 = { 0x9218e6bb, 0xf944, 0x4f7e, { 0xa7, 0x5c, 0xb1, 0xb2, 0xc7, 0xb7, 0x01, 0xf3 } }; static const GUID IID_ID3D12Fence = { 0x0a753dcf, 0xc4d8, 0x4b91, { 0xad, 0xf6, 0xbe, 0x5a, 0x60, 0xd9, 0x5a, 0x76 } }; static const GUID IID_ID3D12GraphicsCommandList = { 0x5b160d0f, 0xac1b, 0x4185, { 0x8b, 0xa8, 0xb3, 0xae, 0x42, 0xa5, 0xa4, 0x55 } }; static const GUID IID_ID3D12GraphicsCommandList1 = { 0x553103fb, 0x1fe7, 0x4557, { 0xbb, 0x38, 0x94, 0x6d, 0x7d, 0x0e, 0x7c, 0xa7 } }; - static const GUID IID_ID3D12GraphicsCommandList2 = { 0x38C3E585, 0xFF17, 0x412C, { 0x91, 0x50, 0x4F, 0xC6, 0xF9, 0xD7, 0x2A, 0x28 } }; - static const GUID IID_ID3D12GraphicsCommandList3 = { 0x6FDA83A7, 0xB84C, 0x4E38, { 0x9A, 0xC8, 0xC7, 0xBD, 0x22, 0x01, 0x6B, 0x3D } }; + static const GUID IID_ID3D12GraphicsCommandList2 = { 0x38c3e585, 0xff17, 0x412c, { 0x91, 0x50, 0x4f, 0xc6, 0xf9, 0xd7, 0x2a, 0x28 } }; + static const GUID IID_ID3D12GraphicsCommandList3 = { 0x6fda83a7, 0xb84c, 0x4e38, { 0x9a, 0xc8, 0xc7, 0xbd, 0x22, 0x01, 0x6b, 0x3d } }; static const GUID IID_ID3D12GraphicsCommandList4 = { 0x8754318e, 0xd3a9, 0x4541, { 0x98, 0xcf, 0x64, 0x5b, 0x50, 0xdc, 0x48, 0x74 } }; static const GUID IID_ID3D12InfoQueue = { 0x0742a90b, 0xc387, 0x483f, { 0xb9, 0x46, 0x30, 0xa7, 0xe4, 0xe6, 0x14, 0x58 } }; static const GUID IID_ID3D12PipelineState = { 0x765a30f3, 0xf624, 0x4c6f, { 0xa8, 0x28, 0xac, 0xe9, 0x48, 0x62, 0x24, 0x45 } }; @@ -402,6 +437,9 @@ namespace bgfx { namespace d3d12 static const GUID s_d3dDeviceIIDs[] = { + IID_ID3D12Device8, + IID_ID3D12Device7, + IID_ID3D12Device6, IID_ID3D12Device5, IID_ID3D12Device4, IID_ID3D12Device3, @@ -434,16 +472,15 @@ namespace bgfx { namespace d3d12 }; BX_STATIC_ASSERT(BX_COUNTOF(s_heapProperties) == HeapProperty::Count); - static inline D3D12_HEAP_PROPERTIES ID3D12DeviceGetCustomHeapProperties(ID3D12Device *device, UINT nodeMask, D3D12_HEAP_TYPE heapType) + static inline D3D12_HEAP_PROPERTIES ID3D12DeviceGetCustomHeapProperties(ID3D12Device *device, uint32_t nodeMask, D3D12_HEAP_TYPE heapType) { - // NOTICE: gcc trick for return struct - union { - D3D12_HEAP_PROPERTIES (STDMETHODCALLTYPE ID3D12Device::*w)(UINT, D3D12_HEAP_TYPE); - void (STDMETHODCALLTYPE ID3D12Device::*f)(D3D12_HEAP_PROPERTIES *, UINT, D3D12_HEAP_TYPE); - } conversion = { &ID3D12Device::GetCustomHeapProperties }; +#if BX_COMPILER_MSVC + return device->GetCustomHeapProperties(nodeMask, heapType); +#else D3D12_HEAP_PROPERTIES ret; - (device->*conversion.f)(&ret, nodeMask, heapType); + device->GetCustomHeapProperties(&ret, nodeMask, heapType); return ret; +#endif // BX_COMPILER_MSVC } static void initHeapProperties(ID3D12Device* _device, D3D12_HEAP_PROPERTIES& _properties) @@ -456,11 +493,13 @@ namespace bgfx { namespace d3d12 static void initHeapProperties(ID3D12Device* _device) { -#if BX_PLATFORM_WINDOWS +#if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS initHeapProperties(_device, s_heapProperties[HeapProperty::Default ].m_properties); initHeapProperties(_device, s_heapProperties[HeapProperty::Texture ].m_properties); initHeapProperties(_device, s_heapProperties[HeapProperty::Upload ].m_properties); initHeapProperties(_device, s_heapProperties[HeapProperty::ReadBack].m_properties); +#else + BX_UNUSED(_device); #endif // BX_PLATFORM_WINDOWS } @@ -485,7 +524,12 @@ namespace bgfx { namespace d3d12 { void* ptr; DX_CHECK(resource->Map(0, NULL, &ptr) ); - D3D12_RESOURCE_ALLOCATION_INFO rai = _device->GetResourceAllocationInfo(1, 1, _resourceDesc); + D3D12_RESOURCE_ALLOCATION_INFO rai; +#if BX_COMPILER_MSVC + rai = _device->GetResourceAllocationInfo(1, 1, _resourceDesc); +#else + _device->GetResourceAllocationInfo(&rai, 1, 1, _resourceDesc); +#endif // BX_COMPILER_MSVC bx::memSet(ptr, 0, size_t(rai.SizeInBytes) ); resource->Unmap(0, NULL); } @@ -495,7 +539,7 @@ namespace bgfx { namespace d3d12 ID3D12Resource* createCommittedResource(ID3D12Device* _device, HeapProperty::Enum _heapProperty, uint64_t _size, D3D12_RESOURCE_FLAGS _flags = D3D12_RESOURCE_FLAG_NONE) { - D3D12_RESOURCE_DESC resourceDesc; + D3D12_RESOURCE_DESC resourceDesc = {}; resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; resourceDesc.Alignment = 0; resourceDesc.Width = _size; @@ -574,8 +618,10 @@ namespace bgfx { namespace d3d12 static PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterface; static PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignature; +# if !BX_PLATFORM_LINUX typedef HANDLE (WINAPI* PFN_CREATE_EVENT_EX_A)(LPSECURITY_ATTRIBUTES _attrs, LPCSTR _name, DWORD _flags, DWORD _access); static PFN_CREATE_EVENT_EX_A CreateEventExA; +# endif // !BX_PLATFORM_LINUX #endif // USE_D3D12_DYNAMIC_LIB inline D3D12_CPU_DESCRIPTOR_HANDLE getCPUHandleHeapStart(ID3D12DescriptorHeap* _heap) @@ -584,11 +630,7 @@ namespace bgfx { namespace d3d12 return _heap->GetCPUDescriptorHandleForHeapStart(); #else D3D12_CPU_DESCRIPTOR_HANDLE handle; - union { - D3D12_CPU_DESCRIPTOR_HANDLE (WINAPI ID3D12DescriptorHeap::*w)(); - void (WINAPI ID3D12DescriptorHeap::*f)(D3D12_CPU_DESCRIPTOR_HANDLE *); - } conversion = { &ID3D12DescriptorHeap::GetCPUDescriptorHandleForHeapStart }; - (_heap->*conversion.f)(&handle); + _heap->GetCPUDescriptorHandleForHeapStart(&handle); return handle; #endif // BX_COMPILER_MSVC } @@ -599,11 +641,7 @@ namespace bgfx { namespace d3d12 return _heap->GetGPUDescriptorHandleForHeapStart(); #else D3D12_GPU_DESCRIPTOR_HANDLE handle; - union { - D3D12_GPU_DESCRIPTOR_HANDLE (WINAPI ID3D12DescriptorHeap::*w)(); - void (WINAPI ID3D12DescriptorHeap::*f)(D3D12_GPU_DESCRIPTOR_HANDLE *); - } conversion = { &ID3D12DescriptorHeap::GetGPUDescriptorHandleForHeapStart }; - (_heap->*conversion.f)(&handle); + _heap->GetGPUDescriptorHandleForHeapStart(&handle); return handle; #endif // BX_COMPILER_MSVC } @@ -614,16 +652,12 @@ namespace bgfx { namespace d3d12 return _resource->GetDesc(); #else D3D12_RESOURCE_DESC desc; - union { - D3D12_RESOURCE_DESC (STDMETHODCALLTYPE ID3D12Resource::*w)(); - void (STDMETHODCALLTYPE ID3D12Resource::*f)(D3D12_RESOURCE_DESC *); - } conversion = { &ID3D12Resource::GetDesc }; - (_resource->*conversion.f)(&desc); + _resource->GetDesc(&desc); return desc; #endif // BX_COMPILER_MSVC } -#if BGFX_CONFIG_DEBUG_PIX && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) +#if BGFX_CONFIG_DEBUG_ANNOTATION && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) static PIXEventsThreadInfo s_pixEventsThreadInfo; PIXEventsThreadInfo* WINAPI stubPIXGetThreadInfo() @@ -636,7 +670,7 @@ namespace bgfx { namespace d3d12 BX_UNUSED(_getEarliestTime); return 0; } -#endif // BGFX_CONFIG_DEBUG_PIX && BX_PLATFORM_WINDOWS +#endif // BGFX_CONFIG_DEBUG_ANNOTATION && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) struct RendererContextD3D12 : public RendererContextI { @@ -650,8 +684,6 @@ namespace bgfx { namespace d3d12 , m_lost(false) , m_maxAnisotropy(1) , m_depthClamp(false) - , m_fsChanges(0) - , m_vsChanges(0) , m_backBufferColorIdx(0) , m_rtMsaa(false) , m_directAccessSupport(false) @@ -680,7 +712,7 @@ namespace bgfx { namespace d3d12 ErrorState::Enum errorState = ErrorState::Default; // LUID luid; -#if BGFX_CONFIG_DEBUG_PIX && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) +#if BGFX_CONFIG_DEBUG_ANNOTATION && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) m_winPixEvent = bx::dlopen("WinPixEventRuntime.dll"); if (NULL != m_winPixEvent) @@ -695,7 +727,7 @@ namespace bgfx { namespace d3d12 bgfx_PIXGetThreadInfo = stubPIXGetThreadInfo; bgfx_PIXEventsReplaceBlock = stubPIXEventsReplaceBlock; } -#endif // BGFX_CONFIG_DEBUG_PIX && BX_PLATFORM_WINDOWS +#endif // BGFX_CONFIG_DEBUG_ANNOTATION && (BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) if (_init.debug || _init.profile) @@ -710,6 +742,8 @@ namespace bgfx { namespace d3d12 bx::memSet(&m_resolution, 0, sizeof(m_resolution) ); #if USE_D3D12_DYNAMIC_LIB + +# if !BX_PLATFORM_LINUX m_kernel32Dll = bx::dlopen("kernel32.dll"); if (NULL == m_kernel32Dll) { @@ -725,14 +759,26 @@ namespace bgfx { namespace d3d12 } errorState = ErrorState::LoadedKernel32; +# endif // !BX_PLATFORM_LINUX m_nvapi.init(); - m_d3d12Dll = bx::dlopen("d3d12.dll"); - if (NULL == m_d3d12Dll) { - BX_TRACE("Init error: Failed to load d3d12.dll."); - goto error; + const char* d3d12DllName = +#if BX_PLATFORM_LINUX + "libd3d12.so" +#else + "d3d12.dll" +#endif // BX_PLATFORM_LINUX + ; + + m_d3d12Dll = bx::dlopen(d3d12DllName); + + if (NULL == m_d3d12Dll) + { + BX_TRACE("Init error: Failed to load %s.", d3d12DllName); + goto error; + } } errorState = ErrorState::LoadedD3D12; @@ -758,65 +804,59 @@ namespace bgfx { namespace d3d12 } #endif // USE_D3D12_DYNAMIC_LIB +#if !BX_PLATFORM_LINUX if (!m_dxgi.init(g_caps) ) { goto error; } errorState = ErrorState::LoadedDXGI; +#endif // !BX_PLATFORM_LINUX HRESULT hr; - if (_init.debug - || _init.profile) { - ID3D12Debug* debug0; - hr = D3D12GetDebugInterface(IID_ID3D12Debug, (void**)&debug0); - - if (SUCCEEDED(hr) ) +#if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT + if (_init.debug + || _init.profile) { - uint32_t debugFlags = 0; + ID3D12Debug* debug0; + hr = D3D12GetDebugInterface(IID_ID3D12Debug, (void**)&debug0); - if (_init.debug) + if (SUCCEEDED(hr) ) { -#if BX_PLATFORM_WINDOWS - debug0->EnableDebugLayer(); - + if (_init.debug) { - ID3D12Debug1* debug1; - hr = debug0->QueryInterface(IID_ID3D12Debug1, (void**)&debug1); +#if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT + debug0->EnableDebugLayer(); - if (SUCCEEDED(hr) ) { -// debug1->SetEnableGPUBasedValidation(true); -// debug1->SetEnableSynchronizedCommandQueueValidation(true); - } + ID3D12Debug1* debug1; + hr = debug0->QueryInterface(IID_ID3D12Debug1, (void**)&debug1); - DX_RELEASE(debug1, 1); - } -#elif BX_PLATFORM_XBOXONE - debugFlags |= D3D12_PROCESS_DEBUG_FLAG_DEBUG_LAYER_ENABLED; -#endif // BX_PLATFORM_WINDOWS - } + if (SUCCEEDED(hr)) + { +// debug1->SetEnableGPUBasedValidation(true); -#if BX_PLATFORM_XBOXONE - // https://github.com/Microsoft/Xbox-ATG-Samples/blob/76d236e3bd372aceec18b2ad0556a7879dbd9628/XDKSamples/IntroGraphics/SimpleTriangle12/DeviceResources.cpp#L67 - debugFlags |= _init.profile ? D3D12XBOX_PROCESS_DEBUG_FLAG_INSTRUMENTED : 0; + // https://discordapp.com/channels/590611987420020747/593519198995742733/703642988345032804 + // D3D12 Bug Number: 26131261 + // There is a bug in the D3D12 validation that causes example-21 to fail when using UAV + // Setting this function below to false avoids the bug + debug1->SetEnableSynchronizedCommandQueueValidation(false); + } - if (0 != debugFlags) - { - debug0->SetProcessDebugFlags(D3D12XBOX_PROCESS_DEBUG_FLAGS(debugFlags) ); - } -#endif // BX_PLATFORM_XBOXONE - BX_UNUSED(debugFlags); + DX_RELEASE(debug1, 1); + } +#endif // BX_PLATFORM_WINDOWS + } - DX_RELEASE(debug0, 0); + DX_RELEASE(debug0, 0); + } } - } - { D3D_FEATURE_LEVEL featureLevel[] = { + D3D_FEATURE_LEVEL_12_2, D3D_FEATURE_LEVEL_12_1, D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_11_1, @@ -826,7 +866,12 @@ namespace bgfx { namespace d3d12 hr = E_FAIL; for (uint32_t ii = 0; ii < BX_COUNTOF(featureLevel) && FAILED(hr); ++ii) { - hr = D3D12CreateDevice(m_dxgi.m_adapter + hr = D3D12CreateDevice( +#if BX_PLATFORM_LINUX + NULL +#else + m_dxgi.m_adapter +#endif // BX_PLATFORM_LINUX , featureLevel[ii] , IID_ID3D12Device , (void**)&m_device @@ -837,19 +882,46 @@ namespace bgfx { namespace d3d12 ); m_featureLevel = featureLevel[ii]; } +#else + // Reference(s): + // - https://github.com/Microsoft/Xbox-ATG-Samples/blob/1271bfd61b4883c775f395b6f13aeabea70290ca/XDKSamples/Graphics/AdvancedESRAM12/DeviceResources.cpp#L64 + D3D12XBOX_CREATE_DEVICE_PARAMETERS params = {}; + params.Version = D3D12_SDK_VERSION; + params.ProcessDebugFlags = D3D12XBOX_PROCESS_DEBUG_FLAGS(0 + | (_init.debug ? D3D12XBOX_PROCESS_DEBUG_FLAG_DEBUG : 0) + | (_init.profile ? D3D12XBOX_PROCESS_DEBUG_FLAG_INSTRUMENTED : 0) + ); + params.GraphicsCommandQueueRingSizeBytes = UINT32_MAX; + params.GraphicsScratchMemorySizeBytes = UINT32_MAX; + params.ComputeScratchMemorySizeBytes = UINT32_MAX; + params.DisableGeometryShaderAllocations = true; + params.DisableTessellationShaderAllocations = true; + + hr = D3D12XboxCreateDevice( + m_dxgi.m_adapter + , ¶ms + , IID_ID3D12Device + , (void**)&m_device + ); + m_featureLevel = D3D_FEATURE_LEVEL_12_1; + + if (SUCCEEDED(hr) ) + { + m_device->SetDebugErrorFilterX(0x73EC9EAF, D3D12XBOX_DEBUG_FILTER_FLAG_DISABLE_BREAKS); + m_device->SetDebugErrorFilterX(0x8EC9B15C, D3D12XBOX_DEBUG_FILTER_FLAG_DISABLE_OUTPUT); + } +#endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT } if (FAILED(hr) ) { BX_TRACE("Init error: Unable to create Direct3D12 device."); - if (BX_ENABLED(BX_PLATFORM_WINRT) ) - { - BX_TRACE("Hint: Change UWP app to game?"); - } goto error; } +#if !BX_PLATFORM_LINUX m_dxgi.update(m_device); +#endif // !BX_PLATFORM_LINUX { m_deviceInterfaceVersion = 0; @@ -866,15 +938,12 @@ namespace bgfx { namespace d3d12 } } -#if BX_PLATFORM_XBOXONE - m_device->SetDebugErrorFilterX(0x73EC9EAF, D3D12XBOX_DEBUG_FILTER_FLAG_DISABLE_BREAKS); - m_device->SetDebugErrorFilterX(0x8EC9B15C, D3D12XBOX_DEBUG_FILTER_FLAG_DISABLE_OUTPUT); -#endif // BX_PLATFORM_XBOXONE - +#if !BX_PLATFORM_LINUX if (BGFX_PCI_ID_NVIDIA != m_dxgi.m_adapterDesc.VendorId) { m_nvapi.shutdown(); } +#endif // !BX_PLATFORM_LINUX { uint32_t numNodes = m_device->GetNodeCount(); @@ -898,7 +967,7 @@ namespace bgfx { namespace d3d12 } DX_CHECK(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &m_options, sizeof(m_options) ) ); - BX_TRACE("D3D12 options:") + BX_TRACE("D3D12 options:"); BX_TRACE("\tTiledResourcesTier %d", m_options.TiledResourcesTier); BX_TRACE("\tResourceBindingTier %d", m_options.ResourceBindingTier); BX_TRACE("\tROVsSupported %d", m_options.ROVsSupported); @@ -906,9 +975,150 @@ namespace bgfx { namespace d3d12 BX_TRACE("\tCrossNodeSharingTier %d", m_options.CrossNodeSharingTier); BX_TRACE("\tResourceHeapTier %d", m_options.ResourceHeapTier); + for (D3D12_FEATURE_DATA_D3D12_OPTIONS1 options1; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS1, &options1, sizeof(options1)));) + { + BX_TRACE("D3D12 options 1:"); + BX_TRACE("\tWaveOps %d", options1.WaveOps); + BX_TRACE("\tWaveLaneCountMin %d", options1.WaveLaneCountMin); + BX_TRACE("\tWaveLaneCountMax %d", options1.WaveLaneCountMax); + BX_TRACE("\tTotalLaneCount %d", options1.TotalLaneCount); + BX_TRACE("\tExpandedComputeResourceStates %d", options1.ExpandedComputeResourceStates); + BX_TRACE("\tInt64ShaderOps %d", options1.Int64ShaderOps); + break; + } + + for (D3D12_FEATURE_DATA_D3D12_OPTIONS2 options2; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS2, &options2, sizeof(options2)));) + { + BX_TRACE("D3D12 options 2:"); + BX_TRACE("\tCopyQueueTimestampQueriesSupported %d", options2.DepthBoundsTestSupported); + BX_TRACE("\tCastingFullyTypedFormatSupported %d", options2.ProgrammableSamplePositionsTier); + break; + } + + for (D3D12_FEATURE_DATA_D3D12_OPTIONS3 options3; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS3, &options3, sizeof(options3)));) + { + BX_TRACE("D3D12 options 3:"); + BX_TRACE("\tCopyQueueTimestampQueriesSupported %d", options3.CopyQueueTimestampQueriesSupported); + BX_TRACE("\tCastingFullyTypedFormatSupported %d", options3.CastingFullyTypedFormatSupported); + BX_TRACE("\tWriteBufferImmediateSupportFlags %d", options3.WriteBufferImmediateSupportFlags); + BX_TRACE("\tViewInstancingTier %d", options3.ViewInstancingTier); + BX_TRACE("\tBarycentricsSupported %d", options3.BarycentricsSupported); + break; + } + + for (D3D12_FEATURE_DATA_D3D12_OPTIONS4 options4; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS4, &options4, sizeof(options4)));) + { + BX_TRACE("D3D12 options 4:"); + BX_TRACE("\tMSAA64KBAlignedTextureSupported %d", options4.MSAA64KBAlignedTextureSupported); + BX_TRACE("\tSharedResourceCompatibilityTier %d", options4.SharedResourceCompatibilityTier); + BX_TRACE("\tNative16BitShaderOpsSupported %d", options4.Native16BitShaderOpsSupported); + break; + } + + for (D3D12_FEATURE_DATA_D3D12_OPTIONS5 options5; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5, &options5, sizeof(options5) ) );) + { + BX_TRACE("D3D12 options 5:"); + BX_TRACE("\tSRVOnlyTiledResourceTier3 %d", options5.SRVOnlyTiledResourceTier3); + BX_TRACE("\tRenderPassesTier %d", options5.RenderPassesTier); + BX_TRACE("\tRaytracingTier %d", options5.RaytracingTier); + break; + } + + for (D3D12_FEATURE_DATA_D3D12_OPTIONS6 options6; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS6, &options6, sizeof(options6)));) + { + BX_TRACE("D3D12 options 6:"); + BX_TRACE("\tAdditionalShadingRatesSupported %d", options6.AdditionalShadingRatesSupported); + BX_TRACE("\tPerPrimitiveShadingRateSupportedWithViewportIndexing %d", options6.PerPrimitiveShadingRateSupportedWithViewportIndexing); + BX_TRACE("\tVariableShadingRateTier %d", options6.VariableShadingRateTier); + BX_TRACE("\tShadingRateImageTileSize %d", options6.ShadingRateImageTileSize); + BX_TRACE("\tBackgroundProcessingSupported %d", options6.BackgroundProcessingSupported); + break; + } + + for (D3D12_FEATURE_DATA_D3D12_OPTIONS7 options7; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &options7, sizeof(options7)));) + { + BX_TRACE("D3D12 options 7:"); + BX_TRACE("\tMeshShaderTier %d", options7.MeshShaderTier); + BX_TRACE("\tSamplerFeedbackTier %d", options7.SamplerFeedbackTier); + break; + } + + for (D3D12_FEATURE_DATA_D3D12_OPTIONS8 options8; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS8, &options8, sizeof(options8)));) + { + BX_TRACE("D3D12 options 8:"); + BX_TRACE("\tUnalignedBlockTexturesSupported %d", options8.UnalignedBlockTexturesSupported); + break; + } + + for (D3D12_FEATURE_DATA_D3D12_OPTIONS9 options9; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS9, &options9, sizeof(options9)));) + { + BX_TRACE("D3D12 options 9:"); + BX_TRACE("\tMeshShaderPipelineStatsSupported %d", options9.MeshShaderPipelineStatsSupported); + BX_TRACE("\tMeshShaderSupportsFullRangeRenderTargetArrayIndex %d", options9.MeshShaderSupportsFullRangeRenderTargetArrayIndex); + BX_TRACE("\tAtomicInt64OnTypedResourceSupported %d", options9.AtomicInt64OnTypedResourceSupported); + BX_TRACE("\tAtomicInt64OnGroupSharedSupported %d", options9.AtomicInt64OnGroupSharedSupported); + BX_TRACE("\tDerivativesInMeshAndAmplificationShadersSupported %d", options9.DerivativesInMeshAndAmplificationShadersSupported); + BX_TRACE("\tWaveMMATier %d", options9.WaveMMATier); + break; + } + + for (D3D12_FEATURE_DATA_D3D12_OPTIONS10 options10; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS10, &options10, sizeof(options10)));) + { + BX_TRACE("D3D12 options 10:"); + BX_TRACE("\tVariableRateShadingSumCombinerSupported %d", options10.VariableRateShadingSumCombinerSupported); + BX_TRACE("\tMeshShaderPerPrimitiveShadingRateSupported %d", options10.MeshShaderPerPrimitiveShadingRateSupported); + break; + } + + for (D3D12_FEATURE_DATA_D3D12_OPTIONS11 options11; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS11, &options11, sizeof(options11)));) + { + BX_TRACE("D3D12 options 11:"); + BX_TRACE("\tAtomicInt64OnDescriptorHeapResourceSupported %d", options11.AtomicInt64OnDescriptorHeapResourceSupported); + break; + } + + for (D3D12_FEATURE_DATA_D3D12_OPTIONS12 options12; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS12, &options12, sizeof(options12)));) + { + BX_TRACE("D3D12 options 12:"); + BX_TRACE("\tMSPrimitivesPipelineStatisticIncludesCulledPrimitives %d", options12.MSPrimitivesPipelineStatisticIncludesCulledPrimitives); + BX_TRACE("\tEnhancedBarriersSupported %d", options12.EnhancedBarriersSupported); + BX_TRACE("\tRelaxedFormatCastingSupported %d", options12.RelaxedFormatCastingSupported); + break; + } + + for (D3D12_FEATURE_DATA_D3D12_OPTIONS13 options13; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS12, &options13, sizeof(options13)));) + { + BX_TRACE("D3D12 options 13:"); + BX_TRACE("\tUnrestrictedBufferTextureCopyPitchSupported %d", options13.UnrestrictedBufferTextureCopyPitchSupported); + BX_TRACE("\tUnrestrictedVertexElementAlignmentSupported %d", options13.UnrestrictedVertexElementAlignmentSupported); + BX_TRACE("\tInvertedViewportHeightFlipsYSupported %d", options13.InvertedViewportHeightFlipsYSupported); + BX_TRACE("\tInvertedViewportDepthFlipsZSupported %d", options13.InvertedViewportDepthFlipsZSupported); + BX_TRACE("\tTextureCopyBetweenDimensionsSupported %d", options13.TextureCopyBetweenDimensionsSupported); + BX_TRACE("\tAlphaBlendFactorSupported %d", options13.AlphaBlendFactorSupported); + break; + } + + for (D3D12_FEATURE_DATA_D3D12_OPTIONS14 options14; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS12, &options14, sizeof(options14)));) + { + BX_TRACE("D3D12 options 14:"); + BX_TRACE("\tAdvancedTextureOpsSupported %d", options14.AdvancedTextureOpsSupported); + BX_TRACE("\tWriteableMSAATexturesSupported %d", options14.WriteableMSAATexturesSupported); + BX_TRACE("\tIndependentFrontAndBackStencilRefMaskSupported %d", options14.IndependentFrontAndBackStencilRefMaskSupported); + break; + } + + for (D3D12_FEATURE_DATA_D3D12_OPTIONS15 options15; SUCCEEDED(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS12, &options15, sizeof(options15)));) + { + BX_TRACE("D3D12 options 15:"); + BX_TRACE("\tTriangleFanSupported %d", options15.TriangleFanSupported); + BX_TRACE("\tDynamicIndexBufferStripCutSupported %d", options15.DynamicIndexBufferStripCutSupported); + break; + } + initHeapProperties(m_device); m_cmd.init(m_device); + m_device->SetPrivateDataInterface(IID_ID3D12CommandQueue, m_cmd.m_commandQueue); errorState = ErrorState::CreatedCommandQueue; if (NULL == g_platformData.backBuffer) @@ -932,7 +1142,7 @@ namespace bgfx { namespace d3d12 m_scd.alphaMode = DXGI_ALPHA_MODE_IGNORE; m_scd.flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; - m_scd.maxFrameLatency = bx::min<uint8_t>(_init.resolution.maxFrameLatency, 3); + m_scd.maxFrameLatency = bx::min<uint8_t>(_init.resolution.maxFrameLatency, BGFX_CONFIG_MAX_FRAME_LATENCY); m_scd.nwh = g_platformData.nwh; m_scd.ndt = g_platformData.ndt; m_scd.windowed = true; @@ -943,12 +1153,15 @@ namespace bgfx { namespace d3d12 if (NULL != m_scd.nwh) { +#if BX_PLATFORM_LINUX + hr = E_FAIL; +#else hr = m_dxgi.createSwapChain( getDeviceForSwapChain() , m_scd , &m_swapChain ); - +#endif // BX_PLATFORM_LINUX if (FAILED(hr) ) { @@ -972,7 +1185,9 @@ namespace bgfx { namespace d3d12 resourceDesc.Width = m_scd.width; resourceDesc.Height = m_scd.height; resourceDesc.MipLevels = 1; - resourceDesc.Format = m_scd.format; + resourceDesc.Format = (m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) + ? s_textureFormat[m_resolution.format].m_fmtSrgb + : s_textureFormat[m_resolution.format].m_fmt; resourceDesc.SampleDesc = m_scd.sampleDesc; resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; @@ -997,6 +1212,7 @@ namespace bgfx { namespace d3d12 m_resolution.width = _init.resolution.width; m_resolution.height = _init.resolution.height; + m_windows[0] = BGFX_INVALID_HANDLE; m_numWindows = 1; #if BX_PLATFORM_WINDOWS @@ -1120,6 +1336,7 @@ namespace bgfx { namespace d3d12 g_caps.supported |= ( 0 | BGFX_CAPS_TEXTURE_3D | BGFX_CAPS_TEXTURE_COMPARE_ALL + | BGFX_CAPS_INDEX32 | BGFX_CAPS_INSTANCING | BGFX_CAPS_DRAW_INDIRECT | BGFX_CAPS_VERTEX_ATTRIB_HALF @@ -1137,6 +1354,9 @@ namespace bgfx { namespace d3d12 | BGFX_CAPS_ALPHA_TO_COVERAGE | BGFX_CAPS_TEXTURE_2D_ARRAY | BGFX_CAPS_TEXTURE_CUBE_ARRAY + | BGFX_CAPS_IMAGE_RW + | BGFX_CAPS_VIEWPORT_LAYER_ARRAY + | BGFX_CAPS_DRAW_INDIRECT_COUNT ); g_caps.limits.maxTextureSize = D3D12_REQ_TEXTURE2D_U_OR_V_DIMENSION; g_caps.limits.maxTextureLayers = D3D12_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; @@ -1194,7 +1414,7 @@ namespace bgfx { namespace d3d12 support |= 0 != (data.Support1 & (0 | D3D12_FORMAT_SUPPORT1_SHADER_LOAD ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE + ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ : BGFX_CAPS_FORMAT_TEXTURE_NONE ; @@ -1225,10 +1445,10 @@ namespace bgfx { namespace d3d12 BX_TRACE("CheckFeatureSupport failed with %x for format %s.", hr, getName(TextureFormat::Enum(ii) ) ); } - if (0 != (support & BGFX_CAPS_FORMAT_TEXTURE_IMAGE) ) + if (0 != (support & BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ) ) { // clear image flag for additional testing - support &= ~BGFX_CAPS_FORMAT_TEXTURE_IMAGE; + support &= ~BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ; data.Format = s_textureFormat[ii].m_fmt; hr = m_device->CheckFeatureSupport(D3D12_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) ); @@ -1236,9 +1456,15 @@ namespace bgfx { namespace d3d12 { support |= 0 != (data.Support2 & (0 | D3D12_FORMAT_SUPPORT2_UAV_TYPED_LOAD + ) ) + ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ + : BGFX_CAPS_FORMAT_TEXTURE_NONE + ; + + support |= 0 != (data.Support2 & (0 | D3D12_FORMAT_SUPPORT2_UAV_TYPED_STORE ) ) - ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE + ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE : BGFX_CAPS_FORMAT_TEXTURE_NONE ; } @@ -1250,7 +1476,7 @@ namespace bgfx { namespace d3d12 struct D3D11_FEATURE_DATA_FORMAT_SUPPORT { DXGI_FORMAT InFormat; - UINT OutFormatSupport; + uint32_t OutFormatSupport; }; D3D12_FEATURE_DATA_FORMAT_SUPPORT data; @@ -1297,7 +1523,9 @@ namespace bgfx { namespace d3d12 postReset(); m_batch.create(4<<10); - m_batch.setIndirectMode(BGFX_PCI_ID_NVIDIA != m_dxgi.m_adapterDesc.VendorId); +#if !BX_PLATFORM_LINUX + m_batch.setIndirectMode(BGFX_PCI_ID_NVIDIA != m_dxgi.m_adapterDesc.VendorId && BGFX_PCI_ID_MICROSOFT != m_dxgi.m_adapterDesc.VendorId); +#endif // !BX_PLATFORM_LINUX m_gpuTimer.init(); m_occlusionQuery.init(); @@ -1342,12 +1570,15 @@ namespace bgfx { namespace d3d12 switch (errorState) { case ErrorState::CreatedCommandQueue: + m_device->SetPrivateDataInterface(IID_ID3D12CommandQueue, NULL); m_cmd.shutdown(); BX_FALLTHROUGH; case ErrorState::CreatedDXGIFactory: DX_RELEASE(m_device, 0); +#if !BX_PLATFORM_LINUX m_dxgi.shutdown(); +#endif // !BX_PLATFORM_LINUX BX_FALLTHROUGH; #if USE_D3D12_DYNAMIC_LIB @@ -1429,12 +1660,15 @@ namespace bgfx { namespace d3d12 DX_RELEASE(m_msaaRt, 0); DX_RELEASE(m_swapChain, 0); + m_device->SetPrivateDataInterface(IID_ID3D12CommandQueue, NULL); m_cmd.shutdown(); DX_RELEASE(m_device, 0); m_nvapi.shutdown(); +#if !BX_PLATFORM_LINUX m_dxgi.shutdown(); +#endif // !BX_PLATFORM_LINUX unloadRenderDoc(m_renderDocDll); @@ -1472,17 +1706,28 @@ namespace bgfx { namespace d3d12 HRESULT hr = S_OK; uint32_t syncInterval = !!(m_resolution.reset & BGFX_RESET_VSYNC); - uint32_t flags = 0 == syncInterval ? DXGI_PRESENT_RESTART : 0; + uint32_t presentFlags = 0; + if (syncInterval) + { + presentFlags |= DXGI_PRESENT_RESTART; + } +#if !BX_PLATFORM_LINUX + else if (m_dxgi.tearingSupported() ) + { + presentFlags |= DXGI_PRESENT_ALLOW_TEARING; + } +#endif // !BX_PLATFORM_LINUX + for (uint32_t ii = 1, num = m_numWindows; ii < num && SUCCEEDED(hr); ++ii) { FrameBufferD3D12& frameBuffer = m_frameBuffers[m_windows[ii].idx]; - hr = frameBuffer.present(syncInterval, flags); + hr = frameBuffer.present(syncInterval, presentFlags); } if (SUCCEEDED(hr) && NULL != m_swapChain) { - hr = m_swapChain->Present(syncInterval, flags); + hr = m_swapChain->Present(syncInterval, presentFlags); } int64_t now = bx::getHPCounter(); @@ -1509,20 +1754,20 @@ namespace bgfx { namespace d3d12 m_indexBuffers[_handle.idx].destroy(); } - void createVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl) override + void createVertexLayout(VertexLayoutHandle _handle, const VertexLayout& _layout) override { - VertexDecl& decl = m_vertexDecls[_handle.idx]; - bx::memCopy(&decl, &_decl, sizeof(VertexDecl) ); - dump(decl); + VertexLayout& layout = m_vertexLayouts[_handle.idx]; + bx::memCopy(&layout, &_layout, sizeof(VertexLayout) ); + dump(layout); } - void destroyVertexDecl(VertexDeclHandle /*_handle*/) override + void destroyVertexLayout(VertexLayoutHandle /*_handle*/) override { } - void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexDeclHandle _declHandle, uint16_t _flags) override + void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexLayoutHandle _layoutHandle, uint16_t _flags) override { - m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _declHandle, _flags); + m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _layoutHandle, _flags); } void destroyVertexBuffer(VertexBufferHandle _handle) override @@ -1547,8 +1792,8 @@ namespace bgfx { namespace d3d12 void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { - VertexDeclHandle decl = BGFX_INVALID_HANDLE; - m_vertexBuffers[_handle.idx].create(_size, NULL, decl, _flags); + VertexLayoutHandle layoutHandle = BGFX_INVALID_HANDLE; + m_vertexBuffers[_handle.idx].create(_size, NULL, layoutHandle, _flags); } void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override @@ -1608,46 +1853,47 @@ namespace bgfx { namespace d3d12 D3D12_PLACED_SUBRESOURCE_FOOTPRINT layout; uint32_t numRows; uint64_t total; - uint64_t srcPitch; m_device->GetCopyableFootprints(&desc , _mip , 1 , 0 , &layout , &numRows - , &srcPitch + , NULL , &total ); + uint32_t srcPitch = layout.Footprint.RowPitch; + ID3D12Resource* readback = createCommittedResource(m_device, HeapProperty::ReadBack, total); + uint32_t srcWidth = bx::uint32_max(1, texture.m_width >>_mip); + uint32_t srcHeight = bx::uint32_max(1, texture.m_height>>_mip); + D3D12_BOX box; box.left = 0; box.top = 0; - box.right = texture.m_width; - box.bottom = texture.m_height; + box.right = srcWidth; + box.bottom = srcHeight; box.front = 0; box.back = 1; D3D12_TEXTURE_COPY_LOCATION dstLocation = { readback, D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, { layout } }; - D3D12_TEXTURE_COPY_LOCATION srcLocation = { texture.m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, {} }; + D3D12_TEXTURE_COPY_LOCATION srcLocation = { texture.m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, { } }; + srcLocation.SubresourceIndex = _mip; m_commandList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, &box); finish(); m_commandList = m_cmd.alloc(); - uint32_t srcWidth = bx::uint32_max(1, texture.m_width >>_mip); - uint32_t srcHeight = bx::uint32_max(1, texture.m_height>>_mip); - uint8_t* src; - const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(texture.m_textureFormat) ); uint8_t* dst = (uint8_t*)_data; uint32_t dstPitch = srcWidth*bpp/8; - uint32_t pitch = bx::uint32_min(uint32_t(srcPitch), dstPitch); + uint32_t pitch = bx::uint32_min(srcPitch, dstPitch); - D3D12_RANGE readRange = { 0, dstPitch*srcHeight }; - readback->Map(0, &readRange, (void**)&src); + uint8_t* src; + readback->Map(0, NULL, (void**)&src); for (uint32_t yy = 0, height = srcHeight; yy < height; ++yy) { @@ -1672,7 +1918,7 @@ namespace bgfx { namespace d3d12 bx::StaticMemoryBlockWriter writer(mem->data, mem->size); uint32_t magic = BGFX_CHUNK_MAGIC_TEX; - bx::write(&writer, magic); + bx::write(&writer, magic, bx::ErrorAssert{}); TextureCreate tc; tc.m_width = _width; @@ -1683,7 +1929,7 @@ namespace bgfx { namespace d3d12 tc.m_format = TextureFormat::Enum(texture.m_requestedFormat); tc.m_cubeMap = false; tc.m_mem = NULL; - bx::write(&writer, tc); + bx::write(&writer, tc, bx::ErrorAssert{}); texture.destroy(); texture.create(mem, texture.m_flags, 0); @@ -1693,13 +1939,16 @@ namespace bgfx { namespace d3d12 void overrideInternal(TextureHandle _handle, uintptr_t _ptr) override { - BX_UNUSED(_handle, _ptr); + // Resource ref. counts might be messed up outside of bgfx. + // Disabling ref. count check once texture is overridden. + setGraphicsDebuggerPresent(true); + m_textures[_handle.idx].overrideInternal(_ptr); } uintptr_t getInternal(TextureHandle _handle) override { - BX_UNUSED(_handle); - return 0; + setGraphicsDebuggerPresent(true); + return uintptr_t(m_textures[_handle.idx].m_ptr); } void destroyTexture(TextureHandle _handle) override @@ -1764,7 +2013,7 @@ namespace bgfx { namespace d3d12 BX_FREE(g_allocator, m_uniforms[_handle.idx]); } - uint32_t size = BX_ALIGN_16(g_uniformTypeSize[_type] * _num); + const uint32_t size = bx::alignUp(g_uniformTypeSize[_type] * _num, 16); void* data = BX_ALLOC(g_allocator, size); bx::memSet(data, 0, size); m_uniforms[_handle.idx] = data; @@ -1841,7 +2090,8 @@ namespace bgfx { namespace d3d12 , (uint32_t)total , false ); - readback->Unmap(0, NULL); + D3D12_RANGE writeRange = { 0, 0 }; + readback->Unmap(0, &writeRange); DX_RELEASE(readback, 0); } @@ -1859,33 +2109,43 @@ namespace bgfx { namespace d3d12 bx::memCopy(m_uniforms[_loc], _data, _size); } - void setMarker(const char* _marker, uint32_t /*_size*/) override + void invalidateOcclusionQuery(OcclusionQueryHandle _handle) override { - if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) - { - PIX3_SETMARKER(m_commandList, D3DCOLOR_MARKER, _marker); - } + m_occlusionQuery.invalidate(_handle); } - void invalidateOcclusionQuery(OcclusionQueryHandle _handle) override + void setMarker(const char* _marker, uint16_t _len) override { - m_occlusionQuery.invalidate(_handle); + BX_UNUSED(_len); + + if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) ) + { + PIX3_SETMARKER(m_commandList, kColorMarker, _marker); + } } - virtual void setName(Handle _handle, const char* _name) override + virtual void setName(Handle _handle, const char* _name, uint16_t _len) override { switch (_handle.type) { + case Handle::IndexBuffer: + setDebugObjectName(m_indexBuffers[_handle.idx].m_ptr, "%.*s", _len, _name); + break; + case Handle::Shader: -// setDebugObjectName(m_shaders[_handle.idx].m_ptr, "%s", _name); +// setDebugObjectName(m_shaders[_handle.idx].m_ptr, "%.*s", _len, _name); break; case Handle::Texture: - setDebugObjectName(m_textures[_handle.idx].m_ptr, "%s", _name); + setDebugObjectName(m_textures[_handle.idx].m_ptr, "%.*s", _len, _name); + break; + + case Handle::VertexBuffer: + setDebugObjectName(m_vertexBuffers[_handle.idx].m_ptr, "%.*s", _len, _name); break; default: - BX_CHECK(false, "Invalid handle type?! %d", _handle.type); + BX_ASSERT(false, "Invalid handle type?! %d", _handle.type); break; } } @@ -1923,12 +2183,12 @@ namespace bgfx { namespace d3d12 | BGFX_STATE_DEPTH_TEST_ALWAYS ; - const VertexDecl* decls[1] = { &m_vertexDecls[_blitter.m_vb->decl.idx] }; + const VertexLayout* layouts[1] = { &m_vertexLayouts[_blitter.m_vb->layoutHandle.idx] }; ID3D12PipelineState* pso = getPipelineState(state , packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT) , 1 - , decls - , _blitter.m_program.idx + , layouts + , _blitter.m_program , 0 ); m_commandList->SetPipelineState(pso); @@ -1942,7 +2202,7 @@ namespace bgfx { namespace d3d12 setShaderUniform(flags, predefined.m_loc, proj, 4); D3D12_GPU_VIRTUAL_ADDRESS gpuAddress; - commitShaderConstants(_blitter.m_program.idx, gpuAddress); + commitShaderConstants(_blitter.m_program, gpuAddress); ScratchBufferD3D12& scratchBuffer = m_scratchBuffer[m_backBufferColorIdx]; ID3D12DescriptorHeap* heaps[] = @@ -1961,11 +2221,11 @@ namespace bgfx { namespace d3d12 scratchBuffer.allocSrv(srvHandle, texture); m_commandList->SetGraphicsRootDescriptorTable(Rdt::SRV, srvHandle); - VertexBufferD3D12& vb = m_vertexBuffers[_blitter.m_vb->handle.idx]; - const VertexDecl& vertexDecl = m_vertexDecls[_blitter.m_vb->decl.idx]; + VertexBufferD3D12& vb = m_vertexBuffers[_blitter.m_vb->handle.idx]; + const VertexLayout& layout = m_vertexLayouts[_blitter.m_vb->layoutHandle.idx]; D3D12_VERTEX_BUFFER_VIEW viewDesc; viewDesc.BufferLocation = vb.m_gpuVA; - viewDesc.StrideInBytes = vertexDecl.m_stride; + viewDesc.StrideInBytes = layout.m_stride; viewDesc.SizeInBytes = vb.m_size; m_commandList->IASetVertexBuffers(0, 1, &viewDesc); @@ -1985,7 +2245,7 @@ namespace bgfx { namespace d3d12 if (0 < numVertices) { m_indexBuffers [_blitter.m_ib->handle.idx].update(m_commandList, 0, _numIndices*2, _blitter.m_ib->data); - m_vertexBuffers[_blitter.m_vb->handle.idx].update(m_commandList, 0, numVertices*_blitter.m_decl.m_stride, _blitter.m_vb->data, true); + m_vertexBuffers[_blitter.m_vb->handle.idx].update(m_commandList, 0, numVertices*_blitter.m_layout.m_stride, _blitter.m_vb->data, true); m_commandList->DrawIndexedInstanced(_numIndices , 1 @@ -2039,11 +2299,34 @@ namespace bgfx { namespace d3d12 , IID_ID3D12Resource , (void**)&m_backBufferColor[ii] ) ); + + D3D12_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = (m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) + ? s_textureFormat[m_resolution.format].m_fmtSrgb + : s_textureFormat[m_resolution.format].m_fmt; + + if (1 < getResourceDesc(m_backBufferColor[ii]).DepthOrArraySize) + { + rtvDesc.ViewDimension = (NULL == m_msaaRt) ? + D3D12_RTV_DIMENSION_TEXTURE2DARRAY : D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY; + rtvDesc.Texture2DArray.FirstArraySlice = 0; + rtvDesc.Texture2DArray.ArraySize = getResourceDesc(m_backBufferColor[ii]).DepthOrArraySize; + rtvDesc.Texture2DArray.MipSlice = 0; + rtvDesc.Texture2DArray.PlaneSlice = 0; + } + else + { + rtvDesc.ViewDimension = (NULL == m_msaaRt) ? + D3D12_RTV_DIMENSION_TEXTURE2D : D3D12_RTV_DIMENSION_TEXTURE2DMS; + rtvDesc.Texture2D.MipSlice = 0; + rtvDesc.Texture2D.PlaneSlice = 0; + } + m_device->CreateRenderTargetView( NULL == m_msaaRt ? m_backBufferColor[ii] : m_msaaRt - , NULL + , &rtvDesc , handle ); @@ -2051,7 +2334,7 @@ namespace bgfx { namespace d3d12 { ID3D12Resource* resource = m_backBufferColor[ii]; - BX_CHECK(DXGI_FORMAT_R8G8B8A8_UNORM == m_scd.format, ""); + BX_ASSERT(DXGI_FORMAT_R8G8B8A8_UNORM == m_scd.format, ""); const uint32_t size = m_scd.width*m_scd.height*4; void* ptr; @@ -2216,7 +2499,7 @@ namespace bgfx { namespace d3d12 BX_STATIC_ASSERT(BX_COUNTOF(m_backBufferColor) == BX_COUNTOF(presentQueue) ); DX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd, nodeMask, presentQueue) ); #elif BX_PLATFORM_WINRT - DX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd); + DX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd)); m_backBufferColorIdx = m_scd.bufferCount-1; #endif // BX_PLATFORM_WINDOWS } @@ -2228,11 +2511,15 @@ namespace bgfx { namespace d3d12 DX_RELEASE(m_swapChain, 0); HRESULT hr; +#if BX_PLATFORM_LINUX + hr = E_FAIL; +#else hr = m_dxgi.createSwapChain( getDeviceForSwapChain() , m_scd , &m_swapChain ); +#endif // BX_PLATFORM_LINUX BGFX_FATAL(SUCCEEDED(hr), bgfx::Fatal::UnableToInitialize, "Failed to create swap chain."); } @@ -2244,7 +2531,9 @@ namespace bgfx { namespace d3d12 resourceDesc.Width = m_scd.width; resourceDesc.Height = m_scd.height; resourceDesc.MipLevels = 1; - resourceDesc.Format = m_scd.format; + resourceDesc.Format = (m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) + ? s_textureFormat[m_resolution.format].m_fmtSrgb + : s_textureFormat[m_resolution.format].m_fmt; resourceDesc.SampleDesc = m_scd.sampleDesc; resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; resourceDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; @@ -2270,15 +2559,13 @@ namespace bgfx { namespace d3d12 void setShaderUniform(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs) { - if (_flags&BGFX_UNIFORM_FRAGMENTBIT) + if (_flags&kUniformFragmentBit) { bx::memCopy(&m_fsScratch[_regIndex], _val, _numRegs*16); - m_fsChanges += _numRegs; } else { bx::memCopy(&m_vsScratch[_regIndex], _val, _numRegs*16); - m_vsChanges += _numRegs; } } @@ -2292,9 +2579,9 @@ namespace bgfx { namespace d3d12 setShaderUniform(_flags, _regIndex, _val, _numRegs); } - void commitShaderConstants(uint16_t _programIdx, D3D12_GPU_VIRTUAL_ADDRESS& _gpuAddress) + void commitShaderConstants(ProgramHandle _program, D3D12_GPU_VIRTUAL_ADDRESS& _gpuAddress) { - const ProgramD3D12& program = m_program[_programIdx]; + const ProgramD3D12& program = m_program[_program.idx]; uint32_t total = bx::strideAlign(0 + program.m_vsh->m_size + (NULL != program.m_fsh ? program.m_fsh->m_size : 0) @@ -2306,15 +2593,11 @@ namespace bgfx { namespace d3d12 uint32_t size = program.m_vsh->m_size; bx::memCopy(data, m_vsScratch, size); data += size; - - m_vsChanges = 0; } if (NULL != program.m_fsh) { bx::memCopy(data, m_fsScratch, program.m_fsh->m_size); - - m_fsChanges = 0; } } @@ -2358,7 +2641,9 @@ namespace bgfx { namespace d3d12 if (isValid(m_fbh) && m_fbh.idx != _fbh.idx) { - const FrameBufferD3D12& frameBuffer = m_frameBuffers[m_fbh.idx]; + FrameBufferD3D12& frameBuffer = m_frameBuffers[m_fbh.idx]; + + if (m_rtMsaa) frameBuffer.resolve(); if (NULL == frameBuffer.m_swapChain) { @@ -2382,14 +2667,17 @@ namespace bgfx { namespace d3d12 if (!isValid(_fbh) ) { - m_rtvHandle = getCPUHandleHeapStart(m_rtvDescriptorHeap); - uint32_t rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); - m_rtvHandle.ptr += m_backBufferColorIdx * rtvDescriptorSize; - m_dsvHandle = getCPUHandleHeapStart(m_dsvDescriptorHeap); + if (NULL != m_swapChain) + { + m_rtvHandle = getCPUHandleHeapStart(m_rtvDescriptorHeap); + uint32_t rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + m_rtvHandle.ptr += m_backBufferColorIdx * rtvDescriptorSize; + m_dsvHandle = getCPUHandleHeapStart(m_dsvDescriptorHeap); - m_currentColor = &m_rtvHandle; - m_currentDepthStencil = &m_dsvHandle; - m_commandList->OMSetRenderTargets(1, m_currentColor, true, m_currentDepthStencil); + m_currentColor = &m_rtvHandle; + m_currentDepthStencil = &m_dsvHandle; + m_commandList->OMSetRenderTargets(1, m_currentColor, true, m_currentDepthStencil); + } } else { @@ -2526,8 +2814,8 @@ namespace bgfx { namespace d3d12 ? D3D12_FILL_MODE_WIREFRAME : D3D12_FILL_MODE_SOLID ; - _desc.CullMode = s_cullMode[cull]; - _desc.FrontCounterClockwise = false; + _desc.CullMode = s_cullMode[cull]; + _desc.FrontCounterClockwise = !!(_state&BGFX_STATE_FRONT_CCW);; _desc.DepthBias = 0; _desc.DepthBiasClamp = 0.0f; _desc.SlopeScaledDepthBias = 0.0f; @@ -2573,7 +2861,7 @@ namespace bgfx { namespace d3d12 _desc.BackFace.StencilFunc = s_cmpFunc[(bstencil&BGFX_STENCIL_TEST_MASK) >> BGFX_STENCIL_TEST_SHIFT]; } - uint32_t setInputLayout(D3D12_INPUT_ELEMENT_DESC* _vertexElements, uint8_t _numStreams, const VertexDecl** _vertexDecls, const ProgramD3D12& _program, uint16_t _numInstanceData) + uint32_t setInputLayout(D3D12_INPUT_ELEMENT_DESC* _vertexElements, uint8_t _numStreams, const VertexLayout** _layouts, const ProgramD3D12& _program, uint16_t _numInstanceData) { uint16_t attrMask[Attrib::Count]; bx::memCopy(attrMask, _program.m_vsh->m_attrMask, sizeof(attrMask)); @@ -2582,19 +2870,19 @@ namespace bgfx { namespace d3d12 for (uint8_t stream = 0; stream < _numStreams; ++stream) { - VertexDecl decl; - bx::memCopy(&decl, _vertexDecls[stream], sizeof(VertexDecl)); + VertexLayout layout; + bx::memCopy(&layout, _layouts[stream], sizeof(VertexLayout)); const bool last = stream == _numStreams-1; for (uint32_t ii = 0; ii < Attrib::Count; ++ii) { uint16_t mask = attrMask[ii]; - uint16_t attr = (decl.m_attributes[ii] & mask); + uint16_t attr = (layout.m_attributes[ii] & mask); if (0 == attr || UINT16_MAX == attr) { - decl.m_attributes[ii] = last ? ~attr : UINT16_MAX; + layout.m_attributes[ii] = last ? ~attr : UINT16_MAX; } else { @@ -2602,7 +2890,7 @@ namespace bgfx { namespace d3d12 } } - elem = fillVertexDecl(stream, elem, decl); + elem = fillVertexLayout(stream, elem, layout); } uint32_t num = uint32_t(elem-_vertexElements); @@ -2632,7 +2920,7 @@ namespace bgfx { namespace d3d12 } bx::memCopy(curr, &inst, sizeof(D3D12_INPUT_ELEMENT_DESC) ); - curr->InputSlot = 1; + curr->InputSlot = _numStreams; curr->SemanticIndex = index; curr->AlignedByteOffset = ii*16; } @@ -2640,10 +2928,10 @@ namespace bgfx { namespace d3d12 return uint32_t(elem-_vertexElements); } - uint32_t setInputLayout(D3D12_INPUT_ELEMENT_DESC* _vertexElements, const VertexDecl& _vertexDecl, const ProgramD3D12& _program, uint16_t _numInstanceData) + uint32_t setInputLayout(D3D12_INPUT_ELEMENT_DESC* _vertexElements, const VertexLayout& _layout, const ProgramD3D12& _program, uint16_t _numInstanceData) { - const VertexDecl* decls[1] = { &_vertexDecl }; - return setInputLayout(_vertexElements, BX_COUNTOF(decls), decls, _program, _numInstanceData); + const VertexLayout* layouts[1] = { &_layout }; + return setInputLayout(_vertexElements, BX_COUNTOF(layouts), layouts, _program, _numInstanceData); } static void patchCb0(DxbcInstruction& _instruction, void* _userData) @@ -2677,9 +2965,9 @@ namespace bgfx { namespace d3d12 } } - ID3D12PipelineState* getPipelineState(uint16_t _programIdx) + ID3D12PipelineState* getPipelineState(ProgramHandle _program) { - ProgramD3D12& program = m_program[_programIdx]; + ProgramD3D12& program = m_program[_program.idx]; const uint32_t hash = program.m_vsh->m_hash; @@ -2693,17 +2981,67 @@ namespace bgfx { namespace d3d12 D3D12_COMPUTE_PIPELINE_STATE_DESC desc; bx::memSet(&desc, 0, sizeof(desc) ); - desc.pRootSignature = m_rootSignature; - + desc.pRootSignature = m_rootSignature; desc.CS.pShaderBytecode = program.m_vsh->m_code->data; desc.CS.BytecodeLength = program.m_vsh->m_code->size; + desc.NodeMask = 1; + desc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; + + uint32_t length = g_callback->cacheReadSize(hash); + const bool cached = length > 0; + + void* cachedData = NULL; + + if (cached) + { + cachedData = BX_ALLOC(g_allocator, length); + if (g_callback->cacheRead(hash, cachedData, length) ) + { + BX_TRACE("Loading cached compute PSO (size %d).", length); + bx::MemoryReader reader(cachedData, length); + + desc.CachedPSO.pCachedBlob = reader.getDataPtr(); + desc.CachedPSO.CachedBlobSizeInBytes = (size_t)reader.remaining(); + + HRESULT hr = m_device->CreateComputePipelineState(&desc + , IID_ID3D12PipelineState + , (void**)&pso + ); + if (FAILED(hr) ) + { + BX_TRACE("Failed to load cached compute PSO (HRESULT 0x%08x).", hr); + bx::memSet(&desc.CachedPSO, 0, sizeof(desc.CachedPSO) ); + } + } + } + + if (NULL == pso) + { + DX_CHECK(m_device->CreateComputePipelineState(&desc + , IID_ID3D12PipelineState + , (void**)&pso + ) ); + } - DX_CHECK(m_device->CreateComputePipelineState(&desc - , IID_ID3D12PipelineState - , (void**)&pso - ) ); m_pipelineStateCache.add(hash, pso); + ID3DBlob* blob; + HRESULT hr = pso->GetCachedBlob(&blob); + if (SUCCEEDED(hr) ) + { + void* data = blob->GetBufferPointer(); + length = (uint32_t)blob->GetBufferSize(); + + g_callback->cacheWrite(hash, data, length); + + DX_RELEASE(blob, 0); + } + + if (NULL != cachedData) + { + BX_FREE(g_allocator, cachedData); + } + return pso; } @@ -2711,12 +3049,12 @@ namespace bgfx { namespace d3d12 uint64_t _state , uint64_t _stencil , uint8_t _numStreams - , const VertexDecl** _vertexDecls - , uint16_t _programIdx + , const VertexLayout** _layouts + , ProgramHandle _program , uint8_t _numInstanceData ) { - ProgramD3D12& program = m_program[_programIdx]; + ProgramD3D12& program = m_program[_program.idx]; _state &= 0 | BGFX_STATE_WRITE_RGB @@ -2728,6 +3066,7 @@ namespace bgfx { namespace d3d12 | BGFX_STATE_BLEND_INDEPENDENT | BGFX_STATE_BLEND_ALPHA_TO_COVERAGE | BGFX_STATE_CULL_MASK + | BGFX_STATE_FRONT_CCW | BGFX_STATE_MSAA | BGFX_STATE_LINEAA | BGFX_STATE_CONSERVATIVE_RASTER @@ -2736,17 +3075,17 @@ namespace bgfx { namespace d3d12 _stencil &= packStencil(~BGFX_STENCIL_FUNC_REF_MASK, ~BGFX_STENCIL_FUNC_REF_MASK); - VertexDecl decl; + VertexLayout layout; if (0 < _numStreams) { - bx::memCopy(&decl, _vertexDecls[0], sizeof(VertexDecl) ); + bx::memCopy(&layout, _layouts[0], sizeof(VertexLayout) ); const uint16_t* attrMask = program.m_vsh->m_attrMask; for (uint32_t ii = 0; ii < Attrib::Count; ++ii) { 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; + uint16_t attr = (layout.m_attributes[ii] & mask); + layout.m_attributes[ii] = attr == 0 ? UINT16_MAX : attr == UINT16_MAX ? 0 : attr; } } @@ -2764,10 +3103,10 @@ namespace bgfx { namespace d3d12 for (uint32_t ii = 0; ii < _numStreams; ++ii) { - murmur.add(_vertexDecls[ii]->m_hash); + murmur.add(_layouts[ii]->m_hash); } - murmur.add(decl.m_attributes, sizeof(decl.m_attributes) ); + murmur.add(layout.m_attributes, sizeof(layout.m_attributes) ); murmur.add(m_fbh.idx); murmur.add(_numInstanceData); const uint32_t hash = murmur.end(); @@ -2804,14 +3143,14 @@ namespace bgfx { namespace d3d12 union { uint32_t offset; void* ptr; } cast = { 0 }; filter(dxbc.shader, dxbc.shader, patchCb0, cast.ptr); - temp = alloc(uint32_t(dxbc.shader.byteCode.size() )+1024); + temp = alloc(uint32_t(dxbc.header.size)); bx::StaticMemoryBlockWriter wr(temp->data, temp->size); int32_t size = write(&wr, dxbc, &err); dxbcHash(temp->data + 20, size - 20, temp->data + 4); patchShader = 0 == bx::memCmp(program.m_fsh->m_code->data, temp->data, 16); - BX_CHECK(patchShader, "DXBC fragment shader patching error (ShaderHandle: %d).", program.m_fsh - m_shaders); + BX_ASSERT(patchShader, "DXBC fragment shader patching error (ShaderHandle: %d).", program.m_fsh - m_shaders); if (!patchShader) { @@ -2841,7 +3180,7 @@ namespace bgfx { namespace d3d12 }; filter(dxbc.shader, dxbc.shader, patchCb0, cast.ptr); - temp = alloc(uint32_t(dxbc.shader.byteCode.size() )+1024); + temp = alloc(uint32_t(dxbc.header.size)); bx::StaticMemoryBlockWriter wr(temp->data, temp->size); int32_t size = write(&wr, dxbc, &err); @@ -2883,7 +3222,7 @@ namespace bgfx { namespace d3d12 setDepthStencilState(desc.DepthStencilState, _state, _stencil); D3D12_INPUT_ELEMENT_DESC vertexElements[Attrib::Count + 1 + BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT]; - desc.InputLayout.NumElements = setInputLayout(vertexElements, _numStreams, _vertexDecls, program, _numInstanceData); + desc.InputLayout.NumElements = setInputLayout(vertexElements, _numStreams, _layouts, program, _numInstanceData); desc.InputLayout.pInputElementDescs = 0 == desc.InputLayout.NumElements ? NULL : vertexElements @@ -2930,7 +3269,7 @@ namespace bgfx { namespace d3d12 desc.SampleDesc = m_scd.sampleDesc; uint32_t length = g_callback->cacheReadSize(hash); - bool cached = length > 0; + const bool cached = length > 0; void* cachedData = NULL; @@ -2939,7 +3278,7 @@ namespace bgfx { namespace d3d12 cachedData = BX_ALLOC(g_allocator, length); if (g_callback->cacheRead(hash, cachedData, length) ) { - BX_TRACE("Loading cached PSO (size %d).", length); + BX_TRACE("Loading cached graphics PSO (size %d).", length); bx::MemoryReader reader(cachedData, length); desc.CachedPSO.pCachedBlob = reader.getDataPtr(); @@ -2951,7 +3290,7 @@ namespace bgfx { namespace d3d12 ); if (FAILED(hr) ) { - BX_TRACE("Failed to load cached PSO (HRESULT 0x%08x).", hr); + BX_TRACE("Failed to load cached graphics PSO (HRESULT 0x%08x).", hr); bx::memSet(&desc.CachedPSO, 0, sizeof(desc.CachedPSO) ); } } @@ -3047,18 +3386,10 @@ namespace bgfx { namespace d3d12 data = (const char*)m_uniforms[handle.idx]; } -#define CASE_IMPLEMENT_UNIFORM(_uniform, _dxsuffix, _type) \ - case UniformType::_uniform: \ - case UniformType::_uniform|BGFX_UNIFORM_FRAGMENTBIT: \ - { \ - setShaderUniform(uint8_t(type), loc, data, num); \ - } \ - break; - switch ( (uint32_t)type) { case UniformType::Mat3: - case UniformType::Mat3|BGFX_UNIFORM_FRAGMENTBIT: + case UniformType::Mat3|kUniformFragmentBit: { float* value = (float*)data; for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3*16, value += 9) @@ -3081,9 +3412,16 @@ namespace bgfx { namespace d3d12 } break; - CASE_IMPLEMENT_UNIFORM(Int1, I, int); - CASE_IMPLEMENT_UNIFORM(Vec4, F, float); - CASE_IMPLEMENT_UNIFORM(Mat4, F, float); + case UniformType::Sampler: + case UniformType::Sampler | kUniformFragmentBit: + case UniformType::Vec4: + case UniformType::Vec4 | kUniformFragmentBit: + case UniformType::Mat4: + case UniformType::Mat4 | kUniformFragmentBit: + { + setShaderUniform(uint8_t(type), loc, data, num); + } + break; case UniformType::End: break; @@ -3092,7 +3430,6 @@ namespace bgfx { namespace d3d12 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 } } @@ -3211,7 +3548,10 @@ namespace bgfx { namespace d3d12 m_commandList = _alloc ? m_cmd.alloc() : NULL; } +#if !BX_PLATFORM_LINUX Dxgi m_dxgi; +#endif // !BX_PLATFORM_LINUX + NvApi m_nvapi; void* m_kernel32Dll; @@ -3275,7 +3615,7 @@ namespace bgfx { namespace d3d12 ShaderD3D12 m_shaders[BGFX_CONFIG_MAX_SHADERS]; ProgramD3D12 m_program[BGFX_CONFIG_MAX_PROGRAMS]; TextureD3D12 m_textures[BGFX_CONFIG_MAX_TEXTURES]; - VertexDecl m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS]; + VertexLayout m_vertexLayouts[BGFX_CONFIG_MAX_VERTEX_LAYOUTS]; FrameBufferD3D12 m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS]; void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS]; Matrix4 m_predefinedUniforms[PredefinedUniform::Count]; @@ -3288,8 +3628,6 @@ namespace bgfx { namespace d3d12 uint8_t m_fsScratch[64<<10]; uint8_t m_vsScratch[64<<10]; - uint32_t m_fsChanges; - uint32_t m_vsChanges; FrameBufferHandle m_fbh; uint32_t m_backBufferColorIdx; @@ -3372,7 +3710,7 @@ namespace bgfx { namespace d3d12 _gpuAddress = m_gpuVA + m_pos; void* data = &m_data[m_pos]; - m_pos += BX_ALIGN_256(_size); + m_pos += bx::alignUp(_size, 256); // D3D12_CONSTANT_BUFFER_VIEW_DESC desc; // desc.BufferLocation = _gpuAddress; @@ -3422,7 +3760,7 @@ namespace bgfx { namespace d3d12 } } - device->CreateShaderResourceView(_texture.m_ptr + device->CreateShaderResourceView(NULL != _texture.m_singleMsaa ? _texture.m_singleMsaa : _texture.m_ptr , srvd , m_cpuHandle ); @@ -3696,7 +4034,11 @@ namespace bgfx { namespace d3d12 ID3D12CommandList* commandLists[] = { commandList.m_commandList }; m_commandQueue->ExecuteCommandLists(BX_COUNTOF(commandLists), commandLists); +#if BX_PLATFORM_LINUX + commandList.m_event = NULL; +#else commandList.m_event = CreateEventExA(NULL, NULL, 0, EVENT_ALL_ACCESS); +#endif // BX_PLATFORM_LINUX const uint64_t fence = m_currentFence++; m_commandQueue->Signal(m_fence, fence); m_fence->SetEventOnCompletion(fence, commandList.m_event); @@ -3719,7 +4061,7 @@ namespace bgfx { namespace d3d12 } } - BX_CHECK(0 == m_control.available(), ""); + BX_ASSERT(0 == m_control.available(), ""); } bool CommandQueueD3D12::tryFinish(uint64_t _waitFence) @@ -3744,6 +4086,9 @@ namespace bgfx { namespace d3d12 bool CommandQueueD3D12::consume(uint32_t _ms) { CommandList& commandList = m_commandList[m_control.m_read]; +#if BX_PLATFORM_LINUX + BX_UNUSED(commandList, _ms); +#else if (WAIT_OBJECT_0 == WaitForSingleObject(commandList.m_event, _ms) ) { CloseHandle(commandList.m_event); @@ -3764,6 +4109,7 @@ namespace bgfx { namespace d3d12 return true; } +#endif // !BX_PLATFORM_LINUX return false; } @@ -3861,7 +4207,7 @@ namespace bgfx { namespace d3d12 Ty& BatchD3D12::getCmd(Enum _type) { uint32_t index = m_num[_type]; - BX_CHECK(index < m_maxDrawPerBatch, "Memory corruption..."); + BX_ASSERT(index < m_maxDrawPerBatch, "Memory corruption..."); m_num[_type]++; Ty* cmd = &reinterpret_cast<Ty*>(m_cmds[_type])[index]; return *cmd; @@ -3874,13 +4220,14 @@ namespace bgfx { namespace d3d12 if (UINT8_MAX != _draw.m_streamMask) { - for (uint32_t idx = 0, streamMask = _draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask) + for (uint32_t idx = 0, streamMask = _draw.m_streamMask ; 0 != streamMask - ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask), ++numStreams + ; streamMask >>= 1, idx += 1, ++numStreams ) { + const uint32_t ntz = bx::uint32_cnttz(streamMask); streamMask >>= ntz; - idx += ntz; + idx += ntz; const Stream& stream = _draw.m_stream[idx]; @@ -3888,13 +4235,13 @@ namespace bgfx { namespace d3d12 VertexBufferD3D12& vb = s_renderD3D12->m_vertexBuffers[handle]; vb.setState(_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); - uint16_t decl = !isValid(vb.m_decl) ? stream.m_decl.idx : vb.m_decl.idx; - const VertexDecl& vertexDecl = s_renderD3D12->m_vertexDecls[decl]; - uint32_t stride = vertexDecl.m_stride; + const uint16_t layoutIdx = !isValid(vb.m_layoutHandle) ? stream.m_layoutHandle.idx : vb.m_layoutHandle.idx; + const VertexLayout& layout = s_renderD3D12->m_vertexLayouts[layoutIdx]; + uint32_t stride = layout.m_stride; D3D12_VERTEX_BUFFER_VIEW& vbv = _vbv[numStreams]; vbv.BufferLocation = vb.m_gpuVA + stream.m_startVertex * stride; - vbv.StrideInBytes = vertexDecl.m_stride; + vbv.StrideInBytes = layout.m_stride; vbv.SizeInBytes = vb.m_size; _outNumVertices = bx::uint32_min(UINT32_MAX == _draw.m_numVertices @@ -3939,6 +4286,13 @@ namespace bgfx { namespace d3d12 ? indirect.m_size/BGFX_CONFIG_DRAW_INDIRECT_STRIDE : _draw.m_numIndirect ; + ID3D12Resource* numIndirect = NULL; + uint32_t numOffsetIndirect = 0; + if (isValid(_draw.m_numIndirectBuffer) ) + { + numIndirect = s_renderD3D12->m_indexBuffers[_draw.m_numIndirectBuffer.idx].m_ptr; + numOffsetIndirect = _draw.m_numIndirectIndex * sizeof(uint32_t); + } uint32_t numIndices = 0; @@ -3947,8 +4301,12 @@ namespace bgfx { namespace d3d12 BufferD3D12& ib = s_renderD3D12->m_indexBuffers[_draw.m_indexBuffer.idx]; ib.setState(_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); - const bool hasIndex16 = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32); - const uint32_t indexSize = hasIndex16 ? 2 : 4; + const bool isIndex16 = _draw.isIndex16(); + const uint32_t indexSize = isIndex16 ? 2 : 4; + const DXGI_FORMAT indexFormat = isIndex16 + ? DXGI_FORMAT_R16_UINT + : DXGI_FORMAT_R32_UINT + ; numIndices = UINT32_MAX == _draw.m_numIndices ? ib.m_size / indexSize @@ -3958,10 +4316,7 @@ namespace bgfx { namespace d3d12 D3D12_INDEX_BUFFER_VIEW ibv; ibv.BufferLocation = ib.m_gpuVA; ibv.SizeInBytes = ib.m_size; - ibv.Format = hasIndex16 - ? DXGI_FORMAT_R16_UINT - : DXGI_FORMAT_R32_UINT - ; + ibv.Format = indexFormat; _commandList->IASetIndexBuffer(&ibv); _commandList->ExecuteIndirect( @@ -3969,8 +4324,8 @@ namespace bgfx { namespace d3d12 , numDrawIndirect , indirect.m_ptr , _draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE - , NULL - , 0 + , numIndirect + , numOffsetIndirect ); } else @@ -3980,8 +4335,8 @@ namespace bgfx { namespace d3d12 , numDrawIndirect , indirect.m_ptr , _draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE - , NULL - , 0 + , numIndirect + , numOffsetIndirect ); } @@ -4026,8 +4381,9 @@ namespace bgfx { namespace d3d12 BufferD3D12& ib = s_renderD3D12->m_indexBuffers[_draw.m_indexBuffer.idx]; ib.setState(_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); - const bool hasIndex16 = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32); - const uint32_t indexSize = hasIndex16 ? 2 : 4; + const bool isIndex16 = _draw.isIndex16(); + const uint32_t indexSize = isIndex16 ? 2 : 4; + const DXGI_FORMAT indexFormat = isIndex16 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT; numIndices = UINT32_MAX == _draw.m_numIndices ? ib.m_size / indexSize @@ -4038,10 +4394,7 @@ namespace bgfx { namespace d3d12 cmd.cbv = _cbv; cmd.ibv.BufferLocation = ib.m_gpuVA; cmd.ibv.SizeInBytes = ib.m_size; - cmd.ibv.Format = hasIndex16 - ? DXGI_FORMAT_R16_UINT - : DXGI_FORMAT_R32_UINT - ; + cmd.ibv.Format = indexFormat; uint32_t numVertices; uint8_t numStreams = fill(_commandList, cmd.vbv, _draw, numVertices); @@ -4214,15 +4567,15 @@ namespace bgfx { namespace d3d12 static const UavFormat s_uavFormat[] = { // BGFX_BUFFER_COMPUTE_TYPE_INT, BGFX_BUFFER_COMPUTE_TYPE_UINT, BGFX_BUFFER_COMPUTE_TYPE_FLOAT { { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, 0 }, // ignored - { { DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN }, 1 }, // BGFX_BUFFER_COMPUTE_FORMAT_8x1 - { { DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN }, 2 }, // BGFX_BUFFER_COMPUTE_FORMAT_8x2 - { { DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN }, 4 }, // BGFX_BUFFER_COMPUTE_FORMAT_8x4 - { { DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_FLOAT }, 2 }, // BGFX_BUFFER_COMPUTE_FORMAT_16x1 - { { DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_FLOAT }, 4 }, // BGFX_BUFFER_COMPUTE_FORMAT_16x2 - { { DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_FLOAT }, 8 }, // BGFX_BUFFER_COMPUTE_FORMAT_16x4 - { { DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_FLOAT }, 4 }, // BGFX_BUFFER_COMPUTE_FORMAT_32x1 - { { DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_FLOAT }, 8 }, // BGFX_BUFFER_COMPUTE_FORMAT_32x2 - { { DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_FLOAT }, 16 }, // BGFX_BUFFER_COMPUTE_FORMAT_32x4 + { { DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN }, 1 }, // BGFX_BUFFER_COMPUTE_FORMAT_8X1 + { { DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN }, 2 }, // BGFX_BUFFER_COMPUTE_FORMAT_8X2 + { { DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_UNKNOWN }, 4 }, // BGFX_BUFFER_COMPUTE_FORMAT_8X4 + { { DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_FLOAT }, 2 }, // BGFX_BUFFER_COMPUTE_FORMAT_16X1 + { { DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_FLOAT }, 4 }, // BGFX_BUFFER_COMPUTE_FORMAT_16X2 + { { DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_FLOAT }, 8 }, // BGFX_BUFFER_COMPUTE_FORMAT_16X4 + { { DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_FLOAT }, 4 }, // BGFX_BUFFER_COMPUTE_FORMAT_32X1 + { { DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_FLOAT }, 8 }, // BGFX_BUFFER_COMPUTE_FORMAT_32X2 + { { DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_FLOAT }, 16 }, // BGFX_BUFFER_COMPUTE_FORMAT_32X4 }; void BufferD3D12::create(uint32_t _size, void* _data, uint16_t _flags, bool _vertex, uint32_t _stride) @@ -4247,8 +4600,8 @@ namespace bgfx { namespace d3d12 #if BX_PLATFORM_XBOXONE flags |= D3D12XBOX_RESOURCE_FLAG_ALLOW_INDIRECT_BUFFER; #endif // BX_PLATFORM_XBOXONE - format = DXGI_FORMAT_R32G32B32A32_UINT; - stride = 16; + format = _vertex ? DXGI_FORMAT_R32G32B32A32_UINT : DXGI_FORMAT_R32_UINT; + stride = _vertex ? 16 : 4; } else { @@ -4360,23 +4713,25 @@ namespace bgfx { namespace d3d12 return _state; } - void VertexBufferD3D12::create(uint32_t _size, void* _data, VertexDeclHandle _declHandle, uint16_t _flags) + void VertexBufferD3D12::create(uint32_t _size, void* _data, VertexLayoutHandle _layoutHandle, uint16_t _flags) { BufferD3D12::create(_size, _data, _flags, true); - m_decl = _declHandle; + m_layoutHandle = _layoutHandle; } void ShaderD3D12::create(const Memory* _mem) { bx::MemoryReader reader(_mem->data, _mem->size); + bx::ErrorAssert err; + uint32_t magic; - bx::read(&reader, magic); + bx::read(&reader, magic, &err); const bool fragment = isShaderType(magic, 'F'); uint32_t hashIn; - bx::read(&reader, hashIn); + bx::read(&reader, hashIn, &err); uint32_t hashOut; @@ -4386,11 +4741,11 @@ namespace bgfx { namespace d3d12 } else { - bx::read(&reader, hashOut); + bx::read(&reader, hashOut, &err); } uint16_t count; - bx::read(&reader, count); + bx::read(&reader, count, &err); m_numPredefined = 0; m_numUniforms = count; @@ -4400,30 +4755,42 @@ namespace bgfx { namespace d3d12 , count ); - uint8_t fragmentBit = fragment ? BGFX_UNIFORM_FRAGMENTBIT : 0; + uint8_t fragmentBit = fragment ? kUniformFragmentBit : 0; if (0 < count) { for (uint32_t ii = 0; ii < count; ++ii) { uint8_t nameSize = 0; - bx::read(&reader, nameSize); + bx::read(&reader, nameSize, &err); char name[256] = {}; - bx::read(&reader, &name, nameSize); + bx::read(&reader, &name, nameSize, &err); name[nameSize] = '\0'; uint8_t type = 0; - bx::read(&reader, type); + bx::read(&reader, type, &err); uint8_t num = 0; - bx::read(&reader, num); + bx::read(&reader, num, &err); uint16_t regIndex = 0; - bx::read(&reader, regIndex); + bx::read(&reader, regIndex, &err); uint16_t regCount = 0; - bx::read(&reader, regCount); + bx::read(&reader, regCount, &err); + + if (!isShaderVerLess(magic, 8) ) + { + uint16_t texInfo = 0; + bx::read(&reader, texInfo, &err); + } + + if (!isShaderVerLess(magic, 10) ) + { + uint16_t texFormat = 0; + bx::read(&reader, texFormat, &err); + } const char* kind = "invalid"; @@ -4436,7 +4803,7 @@ namespace bgfx { namespace d3d12 m_predefined[m_numPredefined].m_type = uint8_t(predefined|fragmentBit); m_numPredefined++; } - else if (0 == (BGFX_UNIFORM_SAMPLERBIT & type) ) + else if (0 == (kUniformSamplerBit & type) ) { const UniformRegInfo* info = s_renderD3D12->m_uniformReg.find(name); BX_WARN(NULL != info, "User defined uniform '%s' is not found, it won't be set.", name); @@ -4460,7 +4827,7 @@ namespace bgfx { namespace d3d12 BX_TRACE("\t%s: %s (%s), num %2d, r.index %3d, r.count %2d" , kind , name - , getUniformTypeName(UniformType::Enum(type&~BGFX_UNIFORM_MASK) ) + , getUniformTypeName(UniformType::Enum(type&~kUniformMask) ) , num , regIndex , regCount @@ -4475,7 +4842,7 @@ namespace bgfx { namespace d3d12 } uint32_t shaderSize; - bx::read(&reader, shaderSize); + bx::read(&reader, shaderSize, &err); const void* code = reader.getDataPtr(); bx::skip(&reader, shaderSize+1); @@ -4483,14 +4850,14 @@ namespace bgfx { namespace d3d12 m_code = copy(code, shaderSize); uint8_t numAttrs = 0; - bx::read(&reader, numAttrs); + bx::read(&reader, numAttrs, &err); bx::memSet(m_attrMask, 0, sizeof(m_attrMask) ); for (uint32_t ii = 0; ii < numAttrs; ++ii) { uint16_t id; - bx::read(&reader, id); + bx::read(&reader, id, &err); Attrib::Enum attr = idToAttrib(id); @@ -4509,7 +4876,145 @@ namespace bgfx { namespace d3d12 murmur.add(m_attrMask, numAttrs); m_hash = murmur.end(); - bx::read(&reader, m_size); + bx::read(&reader, m_size, &err); + } + + static void memcpySubresource( + const D3D12_MEMCPY_DEST* _dst + , const D3D12_SUBRESOURCE_DATA* _src + , uint64_t _rowSizeInBytes + , uint32_t _numRows + , uint32_t _numSlices + ) + { + for (uint32_t zz = 0; zz < _numSlices; ++zz) + { + uint8_t* _dstSlice = ( uint8_t*)(_dst->pData) + _dst->SlicePitch * zz; + const uint8_t* _srcSlice = (const uint8_t*)(_src->pData) + _src->SlicePitch * zz; + for (uint32_t yy = 0; yy < _numRows; ++yy) + { + bx::memCopy( + _dstSlice + _dst->RowPitch * yy + , _srcSlice + _src->RowPitch * yy + , size_t(_rowSizeInBytes) + ); + } + } + } + + static uint64_t updateSubresources( + ID3D12GraphicsCommandList* _commandList + , ID3D12Resource* _dstResource + , ID3D12Resource* _intermediate + , uint32_t _firstSubresource + , uint32_t _numSubresources + , uint64_t _requiredSize + , const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* _layouts + , const uint32_t* _numRows + , const uint64_t* _rowSizesInBytes + , const D3D12_SUBRESOURCE_DATA* _srcData + ) + { + uint8_t* data; + DX_CHECK(_intermediate->Map(0, NULL, (void**)&data) ); + + for (uint32_t ii = 0; ii < _numSubresources; ++ii) + { + D3D12_MEMCPY_DEST dstData = + { + data + _layouts[ii].Offset, + _layouts[ii].Footprint.RowPitch, + _layouts[ii].Footprint.RowPitch * _numRows[ii], + }; + + memcpySubresource( + &dstData + , &_srcData[ii] + , _rowSizesInBytes[ii] + , _numRows[ii] + , _layouts[ii].Footprint.Depth + ); + } + + _intermediate->Unmap(0, NULL); + + D3D12_RESOURCE_DESC dstDesc = getResourceDesc(_dstResource); + if (dstDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + _commandList->CopyBufferRegion( + _dstResource + , 0 + , _intermediate + , _layouts[0].Offset + , _layouts[0].Footprint.Width + ); + } + else + { + for (uint32_t i = 0; i < _numSubresources; ++i) + { + D3D12_TEXTURE_COPY_LOCATION src; + src.pResource = _intermediate; + src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + src.PlacedFootprint = _layouts[i]; + + D3D12_TEXTURE_COPY_LOCATION dst; + dst.pResource = _dstResource; + dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dst.SubresourceIndex = i + _firstSubresource; + + _commandList->CopyTextureRegion(&dst, 0, 0, 0, &src, NULL); + } + } + + return _requiredSize; + } + + static uint64_t updateSubresources( + ID3D12GraphicsCommandList* _commandList + , ID3D12Resource* _dstResource + , ID3D12Resource* _intermediate + , uint64_t _intermediateOffset + , uint32_t _firstSubresource + , uint32_t _numSubresources + , D3D12_SUBRESOURCE_DATA* _srcData + ) + { + uint64_t requiredSize = 0; + + const size_t sizeInBytes = size_t(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(uint32_t) + sizeof(uint64_t) ) * _numSubresources; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT* layouts = (D3D12_PLACED_SUBRESOURCE_FOOTPRINT*)BX_ALLOC(g_allocator, sizeInBytes); + uint64_t* rowSizesInBytes = (uint64_t*)(layouts + _numSubresources); + uint32_t* numRows = (uint32_t*)(rowSizesInBytes + _numSubresources); + + D3D12_RESOURCE_DESC desc = getResourceDesc(_dstResource); + s_renderD3D12->m_device->GetCopyableFootprints( + &desc + , _firstSubresource + , _numSubresources + , _intermediateOffset + , layouts + , numRows + , rowSizesInBytes + , &requiredSize + ); + + const uint64_t result = updateSubresources( + _commandList + , _dstResource + , _intermediate + , _firstSubresource + , _numSubresources + , requiredSize + , layouts + , numRows + , rowSizesInBytes + , _srcData + ); + + BX_FREE(g_allocator, layouts); + + return result; } void* TextureD3D12::create(const Memory* _mem, uint64_t _flags, uint8_t _skip) @@ -4518,18 +5023,27 @@ namespace bgfx { namespace d3d12 if (bimg::imageParse(imageContainer, _mem->data, _mem->size) ) { - uint8_t numMips = imageContainer.m_numMips; - const uint8_t startLod = uint8_t(bx::uint32_min(_skip, numMips-1) ); - numMips -= startLod; const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(imageContainer.m_format); - const uint32_t textureWidth = bx::uint32_max(blockInfo.blockWidth, imageContainer.m_width >>startLod); - const uint32_t textureHeight = bx::uint32_max(blockInfo.blockHeight, imageContainer.m_height>>startLod); - const uint16_t numLayers = imageContainer.m_numLayers; - - m_flags = _flags; - m_width = textureWidth; - m_height = textureHeight; - m_depth = imageContainer.m_depth; + const uint8_t startLod = bx::min<uint8_t>(_skip, imageContainer.m_numMips-1); + + bimg::TextureInfo ti; + bimg::imageGetSize( + &ti + , uint16_t(imageContainer.m_width >>startLod) + , uint16_t(imageContainer.m_height>>startLod) + , uint16_t(imageContainer.m_depth >>startLod) + , imageContainer.m_cubeMap + , 1 < imageContainer.m_numMips + , imageContainer.m_numLayers + , imageContainer.m_format + ); + ti.numMips = bx::min<uint8_t>(imageContainer.m_numMips-startLod, ti.numMips); + + m_flags = _flags; + m_width = ti.width; + m_height = ti.height; + m_depth = ti.depth; + m_numLayers = ti.numLayers; m_requestedFormat = uint8_t(imageContainer.m_format); m_textureFormat = uint8_t(getViableTextureFormat(imageContainer) ); const bool convert = m_textureFormat != m_requestedFormat; @@ -4548,9 +5062,9 @@ namespace bgfx { namespace d3d12 m_type = Texture2D; } - m_numMips = numMips; - const uint16_t numSides = numLayers * (imageContainer.m_cubeMap ? 6 : 1); - const uint32_t numSrd = numSides * numMips; + m_numMips = ti.numMips; + const uint16_t numSides = ti.numLayers * (imageContainer.m_cubeMap ? 6 : 1); + const uint32_t numSrd = numSides * ti.numMips; D3D12_SUBRESOURCE_DATA* srd = (D3D12_SUBRESOURCE_DATA*)alloca(numSrd*sizeof(D3D12_SUBRESOURCE_DATA) ); uint32_t kk = 0; @@ -4563,12 +5077,21 @@ namespace bgfx { namespace d3d12 const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK); const bool blit = 0 != (m_flags&BGFX_TEXTURE_BLIT_DST); + const uint32_t msaaQuality = bx::uint32_satsub((m_flags & BGFX_TEXTURE_RT_MSAA_MASK) >> BGFX_TEXTURE_RT_MSAA_SHIFT, 1); + const DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality]; + + const bool needResolve = true + && 1 < msaa.Count + && 0 == (m_flags & BGFX_TEXTURE_MSAA_SAMPLE) + && !writeOnly + ; + BX_TRACE("Texture %3d: %s (requested: %s), %dx%d%s RT[%c], BO[%c], CW[%c]%s." , this - s_renderD3D12->m_textures , getName( (TextureFormat::Enum)m_textureFormat) , getName( (TextureFormat::Enum)m_requestedFormat) - , textureWidth - , textureHeight + , ti.width + , ti.height , imageContainer.m_cubeMap ? "x6" : "" , renderTarget ? 'x' : ' ' , writeOnly ? 'x' : ' ' @@ -4578,7 +5101,7 @@ namespace bgfx { namespace d3d12 for (uint8_t side = 0; side < numSides; ++side) { - for (uint8_t lod = 0; lod < numMips; ++lod) + for (uint8_t lod = 0; lod < ti.numMips; ++lod) { bimg::ImageMip mip; if (bimg::imageGetRawData(imageContainer, side, lod+startLod, _mem->data, _mem->size, mip) ) @@ -4647,29 +5170,27 @@ namespace bgfx { namespace d3d12 } } - const uint32_t msaaQuality = bx::uint32_satsub( (m_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT, 1); - const DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality]; - + const TextureFormatInfo& tfi = s_textureFormat[m_textureFormat]; bx::memSet(&m_srvd, 0, sizeof(m_srvd) ); - m_srvd.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - m_srvd.Format = s_textureFormat[m_textureFormat].m_fmtSrv; - DXGI_FORMAT format = s_textureFormat[m_textureFormat].m_fmt; + m_srvd.Shader4ComponentMapping = tfi.m_mapping; + m_srvd.Format = (m_flags & BGFX_TEXTURE_SRGB) ? tfi.m_fmtSrgb : tfi.m_fmtSrv; + m_uavd.Format = tfi.m_fmtSrv; + DXGI_FORMAT format = tfi.m_fmt; if (swizzle) { format = DXGI_FORMAT_R8G8B8A8_UNORM; m_srvd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + m_uavd.Format = DXGI_FORMAT_R8G8B8A8_UNORM; } - m_uavd.Format = m_srvd.Format; - ID3D12Device* device = s_renderD3D12->m_device; ID3D12GraphicsCommandList* commandList = s_renderD3D12->m_commandList; D3D12_RESOURCE_DESC resourceDesc; resourceDesc.Alignment = 1 < msaa.Count ? D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT : 0; - resourceDesc.Width = textureWidth; - resourceDesc.Height = textureHeight; - resourceDesc.MipLevels = numMips; + resourceDesc.Width = ti.width; + resourceDesc.Height = ti.height; + resourceDesc.MipLevels = ti.numMips; resourceDesc.Format = format; resourceDesc.SampleDesc = msaa; resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; @@ -4680,13 +5201,13 @@ namespace bgfx { namespace d3d12 D3D12_CLEAR_VALUE* clearValue = NULL; if (bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) ) { - resourceDesc.Format = s_textureFormat[m_textureFormat].m_fmt; + resourceDesc.Format = tfi.m_fmt; resourceDesc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; state |= D3D12_RESOURCE_STATE_DEPTH_WRITE; state &= ~D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; clearValue = (D3D12_CLEAR_VALUE*)alloca(sizeof(D3D12_CLEAR_VALUE) ); - clearValue->Format = s_textureFormat[m_textureFormat].m_fmtDsv; + clearValue->Format = tfi.m_fmtDsv; clearValue->DepthStencil.Depth = 1.0f; clearValue->DepthStencil.Stencil = 0; } @@ -4730,56 +5251,50 @@ namespace bgfx { namespace d3d12 switch (m_type) { case Texture2D: - case TextureCube: resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - if (imageContainer.m_cubeMap) + + if (1 < ti.numLayers) { - if (1 < numLayers) + if (1 < msaa.Count && !needResolve) { - m_srvd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY; - m_srvd.TextureCubeArray.MostDetailedMip = 0; - m_srvd.TextureCubeArray.MipLevels = numMips; - m_srvd.TextureCubeArray.ResourceMinLODClamp = 0.0f; - m_srvd.TextureCubeArray.NumCubes = numLayers; + m_srvd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY; + m_srvd.Texture2DMSArray.FirstArraySlice = 0; + m_srvd.Texture2DMSArray.ArraySize = ti.numLayers; } else { - m_srvd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; - m_srvd.TextureCube.MostDetailedMip = 0; - m_srvd.TextureCube.MipLevels = numMips; - m_srvd.TextureCube.ResourceMinLODClamp = 0.0f; + m_srvd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY; + m_srvd.Texture2DArray.MostDetailedMip = 0; + m_srvd.Texture2DArray.MipLevels = ti.numMips; + m_srvd.Texture2DArray.FirstArraySlice = 0; + m_srvd.Texture2DArray.ArraySize = ti.numLayers; + m_srvd.Texture2DArray.PlaneSlice = 0; + m_srvd.Texture2DArray.ResourceMinLODClamp = 0.0f; } } else { - if (1 < numLayers) + if (1 < msaa.Count && !needResolve) { - m_srvd.ViewDimension = 1 < msaa.Count - ? D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY - : D3D12_SRV_DIMENSION_TEXTURE2DARRAY - ; - m_srvd.Texture2DArray.MostDetailedMip = 0; - m_srvd.Texture2DArray.MipLevels = numMips; - m_srvd.Texture2DArray.ResourceMinLODClamp = 0.0f; - m_srvd.Texture2DArray.ArraySize = numLayers; + m_srvd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMS; } else { - m_srvd.ViewDimension = 1 < msaa.Count - ? D3D12_SRV_DIMENSION_TEXTURE2DMS - : D3D12_SRV_DIMENSION_TEXTURE2D - ; + m_srvd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; m_srvd.Texture2D.MostDetailedMip = 0; - m_srvd.Texture2D.MipLevels = numMips; + m_srvd.Texture2D.MipLevels = ti.numMips; + m_srvd.Texture2D.PlaneSlice = 0; m_srvd.Texture2D.ResourceMinLODClamp = 0.0f; } } - if (1 < numLayers) + if (1 < ti.numLayers) { m_uavd.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY; - m_uavd.Texture2DArray.MipSlice = 0; - m_uavd.Texture2DArray.PlaneSlice = 0; + m_uavd.Texture2DArray.MipSlice = 0; + m_uavd.Texture2DArray.FirstArraySlice = 0; + m_uavd.Texture2DArray.ArraySize = ti.numLayers; + m_uavd.Texture2DArray.PlaneSlice = 0; } else { @@ -4787,14 +5302,6 @@ namespace bgfx { namespace d3d12 m_uavd.Texture2D.MipSlice = 0; m_uavd.Texture2D.PlaneSlice = 0; } - - if (TextureCube == m_type) - { - m_uavd.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY; - m_uavd.Texture2DArray.MipSlice = 0; - m_uavd.Texture2DArray.ArraySize = 6; - } - break; case Texture3D: @@ -4802,13 +5309,39 @@ namespace bgfx { namespace d3d12 resourceDesc.DepthOrArraySize = uint16_t(m_depth); m_srvd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D; m_srvd.Texture3D.MostDetailedMip = 0; - m_srvd.Texture3D.MipLevels = numMips; + m_srvd.Texture3D.MipLevels = ti.numMips; m_srvd.Texture3D.ResourceMinLODClamp = 0.0f; m_uavd.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D; m_uavd.Texture3D.MipSlice = 0; m_uavd.Texture3D.FirstWSlice = 0; - m_uavd.Texture3D.WSize = 0; + m_uavd.Texture3D.WSize = m_depth; + break; + + case TextureCube: + resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + + if (1 < ti.numLayers) + { + m_srvd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY; + m_srvd.TextureCubeArray.MostDetailedMip = 0; + m_srvd.TextureCubeArray.MipLevels = ti.numMips; + m_srvd.TextureCubeArray.ResourceMinLODClamp = 0.0f; + m_srvd.TextureCubeArray.NumCubes = ti.numLayers; + } + else + { + m_srvd.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBE; + m_srvd.TextureCube.MostDetailedMip = 0; + m_srvd.TextureCube.MipLevels = ti.numMips; + m_srvd.TextureCube.ResourceMinLODClamp = 0.0f; + } + + m_uavd.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY; + m_uavd.Texture2DArray.MipSlice = 0; + m_uavd.Texture2DArray.FirstArraySlice = 0; + m_uavd.Texture2DArray.ArraySize = 6; + m_uavd.Texture2DArray.PlaneSlice = 0; break; } @@ -4828,7 +5361,7 @@ namespace bgfx { namespace d3d12 setState(commandList, D3D12_RESOURCE_STATE_COPY_DEST); - uint64_t result = UpdateSubresources(commandList + uint64_t result = updateSubresources(commandList , m_ptr , staging , 0 @@ -4836,7 +5369,7 @@ namespace bgfx { namespace d3d12 , numSrd , srd ); - BX_CHECK(0 != result, "Invalid size"); BX_UNUSED(result); + BX_ASSERT(0 != result, "Invalid size"); BX_UNUSED(result); BX_TRACE("Update subresource %" PRId64, result); setState(commandList, state); @@ -4853,13 +5386,30 @@ namespace bgfx { namespace d3d12 kk = 0; for (uint8_t side = 0; side < numSides; ++side) { - for (uint32_t lod = 0, num = numMips; lod < num; ++lod) + for (uint32_t lod = 0, num = ti.numMips; lod < num; ++lod) { BX_FREE(g_allocator, const_cast<void*>(srd[kk].pData) ); ++kk; } } } + + if (needResolve) + { + D3D12_RESOURCE_DESC rd = resourceDesc; + + rd.Alignment = 0; + rd.SampleDesc = s_msaa[0]; + rd.Flags &= ~(D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET | D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL); + + m_singleMsaa = createCommittedResource(device, HeapProperty::Texture, &rd, NULL); + + setResourceBarrier(commandList + , m_singleMsaa + , D3D12_RESOURCE_STATE_COMMON + , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE + ); + } } return m_directAccessPtr; @@ -4876,30 +5426,86 @@ namespace bgfx { namespace d3d12 m_directAccessPtr = NULL; } - s_renderD3D12->m_cmd.release(m_ptr); - m_ptr = NULL; - m_state = D3D12_RESOURCE_STATE_COMMON; + if (0 == (m_flags & BGFX_SAMPLER_INTERNAL_SHARED)) + { + s_renderD3D12->m_cmd.release(m_ptr); + m_ptr = NULL; + m_state = D3D12_RESOURCE_STATE_COMMON; + + if (NULL != m_singleMsaa) + { + s_renderD3D12->m_cmd.release(m_singleMsaa); + m_singleMsaa = NULL; + } + } } } + void TextureD3D12::overrideInternal(uintptr_t _ptr) + { + destroy(); + m_flags |= BGFX_SAMPLER_INTERNAL_SHARED; + m_ptr = (ID3D12Resource*)_ptr; + } + void TextureD3D12::update(ID3D12GraphicsCommandList* _commandList, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) { D3D12_RESOURCE_STATES state = setState(_commandList, D3D12_RESOURCE_STATE_COPY_DEST); const uint32_t subres = _mip + (_side * m_numMips); const uint32_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) ); - const uint32_t rectpitch = _rect.m_width*bpp/8; - const uint32_t srcpitch = UINT16_MAX == _pitch ? rectpitch : _pitch; + uint32_t rectpitch = _rect.m_width*bpp/8; + if (bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat))) + { + const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_textureFormat)); + rectpitch = (_rect.m_width / blockInfo.blockWidth) * blockInfo.blockSize; + } + + const uint32_t srcpitch = UINT16_MAX == _pitch ? rectpitch : _pitch; + const uint32_t slicepitch = rectpitch*_rect.m_height; + + const bool convert = m_textureFormat != m_requestedFormat; + + D3D12_BOX box; + box.left = 0; + box.top = 0; + box.right = box.left + _rect.m_width; + box.bottom = box.top + _rect.m_height; + + if (TextureD3D12::Texture3D == m_type) + { + box.front = _z; + box.back = box.front + _depth; + } + else + { + box.front = 0; + box.back = 1; + } + + uint8_t* srcData = _mem->data; + uint8_t* temp = NULL; + + if (convert) + { + temp = (uint8_t*)BX_ALLOC(g_allocator, slicepitch); + bimg::imageDecodeToBgra8(g_allocator, temp, srcData, _rect.m_width, _rect.m_height, srcpitch, bimg::TextureFormat::Enum(m_requestedFormat)); + srcData = temp; + + box.right = bx::max(1u, m_width >> _mip); + box.bottom = bx::max(1u, m_height >> _mip); + } D3D12_RESOURCE_DESC desc = getResourceDesc(m_ptr); + desc.Width = _rect.m_width; desc.Height = _rect.m_height; uint32_t numRows; uint64_t totalBytes; D3D12_PLACED_SUBRESOURCE_FOOTPRINT layout; s_renderD3D12->m_device->GetCopyableFootprints(&desc - , subres + , 0 , 1 , 0 , &layout @@ -4911,24 +5517,23 @@ namespace bgfx { namespace d3d12 const uint32_t rowPitch = layout.Footprint.RowPitch; ID3D12Resource* staging = createCommittedResource(s_renderD3D12->m_device, HeapProperty::Upload, totalBytes); - uint8_t* data; + uint8_t* dstData; D3D12_RANGE readRange = { 0, 0 }; - DX_CHECK(staging->Map(0, &readRange, (void**)&data) ); - for (uint32_t ii = 0, height = _rect.m_height; ii < height; ++ii) + DX_CHECK(staging->Map(0, &readRange, (void**)&dstData) ); + + for (uint32_t ii = 0, height = numRows; ii < height; ++ii) { - bx::memCopy(&data[ii*rowPitch], &_mem->data[ii*srcpitch], srcpitch); + bx::memCopy(&dstData[ii*rowPitch], &srcData[ii*srcpitch], srcpitch); } - D3D12_RANGE writeRange = { 0, _rect.m_height*srcpitch }; - staging->Unmap(0, &writeRange); - D3D12_BOX box; - box.left = 0; - box.top = 0; - box.right = box.left + _rect.m_width; - box.bottom = box.top + _rect.m_height; - box.front = _z; - box.back = _z+_depth; + if (NULL != temp) + { + BX_FREE(g_allocator, temp); + } + + D3D12_RANGE writeRange = { 0, numRows*rowPitch }; + staging->Unmap(0, &writeRange); D3D12_TEXTURE_COPY_LOCATION dst = { m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, { } }; dst.SubresourceIndex = subres; @@ -4940,9 +5545,41 @@ namespace bgfx { namespace d3d12 s_renderD3D12->m_cmd.release(staging); } - void TextureD3D12::resolve(uint8_t _resolve) const + void TextureD3D12::resolve(ID3D12GraphicsCommandList* _commandList, uint8_t _resolve, uint32_t _layer, uint32_t _numLayers, uint32_t _mip) { BX_UNUSED(_resolve); + + bool needResolve = NULL != m_singleMsaa; + if (needResolve) + { + D3D12_RESOURCE_STATES state = setState(_commandList, D3D12_RESOURCE_STATE_RESOLVE_SOURCE); + + setResourceBarrier(_commandList + , m_singleMsaa + , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE + , D3D12_RESOURCE_STATE_RESOLVE_DEST + ); + + for (uint32_t ii = _layer; ii < _numLayers; ++ii) + { + const uint32_t resource = _mip + (ii * m_numMips); + + _commandList->ResolveSubresource(m_singleMsaa + , resource + , m_ptr + , resource + , s_textureFormat[m_textureFormat].m_fmt + ); + } + + setResourceBarrier(_commandList + , m_singleMsaa + , D3D12_RESOURCE_STATE_RESOLVE_DEST + , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE + ); + + setState(_commandList, state); + } } D3D12_RESOURCE_STATES TextureD3D12::setState(ID3D12GraphicsCommandList* _commandList, D3D12_RESOURCE_STATES _state) @@ -4972,15 +5609,16 @@ namespace bgfx { namespace d3d12 void FrameBufferD3D12::create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _format, TextureFormat::Enum _depthFormat) { - BX_UNUSED(_nwh, _width, _height, _depthFormat); + BX_UNUSED(_nwh, _width, _height, _format, _depthFormat); #if BX_PLATFORM_WINDOWS SwapChainDesc scd; - bx::memCopy(&scd, &s_renderD3D12->m_scd, sizeof(DXGI_SWAP_CHAIN_DESC) ); - scd.format = TextureFormat::Count == _format ? scd.format : s_textureFormat[_format].m_fmt; - scd.width = _width; - scd.height = _height; - scd.nwh = _nwh; + bx::memCopy(&scd, &s_renderD3D12->m_scd, sizeof(SwapChainDesc) ); + scd.format = TextureFormat::Count == _format ? scd.format : s_textureFormat[_format].m_fmt; + scd.width = _width; + scd.height = _height; + scd.nwh = _nwh; + scd.sampleDesc = s_msaa[0]; HRESULT hr; hr = s_renderD3D12->m_dxgi.createSwapChain( @@ -5083,9 +5721,12 @@ namespace bgfx { namespace d3d12 m_height = uint32_t(desc.Height); } + const uint32_t msaaQuality = bx::uint32_satsub((texture.m_flags & BGFX_TEXTURE_RT_MSAA_MASK) >> BGFX_TEXTURE_RT_MSAA_SHIFT, 1); + const DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality]; + if (bimg::isDepth(bimg::TextureFormat::Enum(texture.m_textureFormat) ) ) { - BX_CHECK(!isValid(m_depth), ""); + BX_ASSERT(!isValid(m_depth), ""); m_depth = at.handle; D3D12_CPU_DESCRIPTOR_HANDLE dsvDescriptor = getCPUHandleHeapStart(s_renderD3D12->m_dsvDescriptorHeap); uint32_t dsvDescriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV); @@ -5097,25 +5738,66 @@ namespace bgfx { namespace d3d12 D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc; bx::memSet(&dsvDesc, 0, sizeof(dsvDesc) ); dsvDesc.Format = s_textureFormat[texture.m_textureFormat].m_fmtDsv; - dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; dsvDesc.Flags = D3D12_DSV_FLAG_NONE // | (blockInfo.depthBits > 0 ? D3D12_DSV_FLAG_READ_ONLY_DEPTH : D3D12_DSV_FLAG_NONE) // | (blockInfo.stencilBits > 0 ? D3D12_DSV_FLAG_READ_ONLY_STENCIL : D3D12_DSV_FLAG_NONE) ; + switch (texture.m_type) + { + default: + case TextureD3D12::Texture2D: + if (1 < msaa.Count) + { + if (1 < texture.m_numLayers) + { + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY; + dsvDesc.Texture2DMSArray.FirstArraySlice = at.layer; + dsvDesc.Texture2DMSArray.ArraySize = at.numLayers; + } + else + { + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DMS; + } + } + else + { + if (1 < texture.m_numLayers) + { + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Texture2DArray.FirstArraySlice = at.layer; + dsvDesc.Texture2DArray.ArraySize = at.numLayers; + dsvDesc.Texture2DArray.MipSlice = at.mip; + } + else + { + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; + dsvDesc.Texture2D.MipSlice = at.mip; + } + } + break; + + case TextureD3D12::TextureCube: + if (1 < msaa.Count) + { + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY; + dsvDesc.Texture2DMSArray.FirstArraySlice = at.layer; + dsvDesc.Texture2DMSArray.ArraySize = at.numLayers; + } + else + { + dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Texture2DArray.FirstArraySlice = at.layer; + dsvDesc.Texture2DArray.ArraySize = at.numLayers; + dsvDesc.Texture2DArray.MipSlice = at.mip; + } + break; + } + device->CreateDepthStencilView(texture.m_ptr , &dsvDesc , dsvDescriptor ); - - s_renderD3D12->m_commandList->ClearDepthStencilView( - dsvDescriptor - , D3D12_CLEAR_FLAG_DEPTH|D3D12_CLEAR_FLAG_STENCIL - , 0.0f - , 0 - , 0 - , NULL - ); } else if (Access::Write == at.access) { @@ -5129,30 +5811,50 @@ namespace bgfx { namespace d3d12 { default: case TextureD3D12::Texture2D: -// if (1 < msaa.Count) -// { -// desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS; -// } -// else + if (1 < msaa.Count) { - desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; - desc.Texture2D.MipSlice = at.mip; - desc.Texture2D.PlaneSlice = 0; + if (1 < texture.m_numLayers) + { + desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY; + desc.Texture2DMSArray.FirstArraySlice = at.layer; + desc.Texture2DMSArray.ArraySize = at.numLayers; + } + else + { + desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS; + } + } + else + { + if (1 < texture.m_numLayers) + { + desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY; + desc.Texture2DArray.FirstArraySlice = at.layer; + desc.Texture2DArray.ArraySize = at.numLayers; + desc.Texture2DArray.MipSlice = at.mip; + desc.Texture2DArray.PlaneSlice = 0; + } + else + { + desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + desc.Texture2D.MipSlice = at.mip; + desc.Texture2D.PlaneSlice = 0; + } } break; case TextureD3D12::TextureCube: -// if (1 < msaa.Count) -// { -// desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY; -// desc.Texture2DMSArray.ArraySize = 1; -// desc.Texture2DMSArray.FirstArraySlice = at.layer; -// } -// else + if (1 < msaa.Count) + { + desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY; + desc.Texture2DMSArray.FirstArraySlice = at.layer; + desc.Texture2DMSArray.ArraySize = at.numLayers; + } + else { desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY; - desc.Texture2DArray.ArraySize = 1; desc.Texture2DArray.FirstArraySlice = at.layer; + desc.Texture2DArray.ArraySize = at.numLayers; desc.Texture2DArray.MipSlice = at.mip; desc.Texture2DArray.PlaneSlice = 0; } @@ -5160,9 +5862,9 @@ namespace bgfx { namespace d3d12 case TextureD3D12::Texture3D: desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D; - desc.Texture3D.MipSlice = at.mip; - desc.Texture3D.WSize = 1; + desc.Texture3D.MipSlice = at.mip; desc.Texture3D.FirstWSlice = at.layer; + desc.Texture3D.WSize = at.numLayers; break; } @@ -5171,19 +5873,11 @@ namespace bgfx { namespace d3d12 , rtv ); - float rgba[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; - s_renderD3D12->m_commandList->ClearRenderTargetView( - rtv - , rgba - , 0 - , NULL - ); - m_num++; } else { - BX_CHECK(false, ""); + BX_ASSERT(false, ""); } } } @@ -5200,8 +5894,8 @@ namespace bgfx { namespace d3d12 if (isValid(at.handle) ) { - const TextureD3D12& texture = s_renderD3D12->m_textures[at.handle.idx]; - texture.resolve(at.resolve); + TextureD3D12& texture = s_renderD3D12->m_textures[at.handle.idx]; + texture.resolve(s_renderD3D12->m_commandList, at.resolve, at.layer, at.numLayers, at.mip); } } } @@ -5339,7 +6033,7 @@ namespace bgfx { namespace d3d12 DX_RELEASE(m_readback, 0); } - uint32_t TimerQueryD3D12::begin(uint32_t _resultIdx) + uint32_t TimerQueryD3D12::begin(uint32_t _resultIdx, uint32_t _frameNum) { while (0 == m_control.reserve(1) ) { @@ -5353,6 +6047,7 @@ namespace bgfx { namespace d3d12 Query& query = m_query[idx]; query.m_resultIdx = _resultIdx; query.m_ready = false; + query.m_frameNum = _frameNum; ID3D12GraphicsCommandList* commandList = s_renderD3D12->m_commandList; @@ -5414,6 +6109,7 @@ namespace bgfx { namespace d3d12 Result& result = m_result[query.m_resultIdx]; --result.m_pending; + result.m_frameNum = query.m_frameNum; uint32_t offset = idx * 2; result.m_begin = m_queryResult[offset+0]; @@ -5520,7 +6216,7 @@ namespace bgfx { namespace d3d12 { const BlitItem& blit = _bs.advance(); - TextureD3D12& src = m_textures[blit.m_src.idx]; + TextureD3D12& src = m_textures[blit.m_src.idx]; const TextureD3D12& dst = m_textures[blit.m_dst.idx]; if (currentSrc.idx != blit.m_src.idx) @@ -5530,33 +6226,40 @@ namespace bgfx { namespace d3d12 m_textures[currentSrc.idx].setState(m_commandList, state); } - currentSrc = blit.m_src; + currentSrc = blit.m_src.to<TextureHandle>(); + + if (NULL != src.m_singleMsaa) + { + setResourceBarrier(m_commandList + , src.m_singleMsaa + , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE + , D3D12_RESOURCE_STATE_COPY_SOURCE + ); + } state = src.setState(m_commandList, D3D12_RESOURCE_STATE_COPY_SOURCE); } - uint32_t srcWidth = bx::uint32_min(src.m_width, blit.m_srcX + blit.m_width) - blit.m_srcX; - uint32_t srcHeight = bx::uint32_min(src.m_height, blit.m_srcY + blit.m_height) - blit.m_srcY; - uint32_t srcDepth = bx::uint32_min(src.m_depth, blit.m_srcZ + blit.m_depth) - blit.m_srcZ; - uint32_t dstWidth = bx::uint32_min(dst.m_width, blit.m_dstX + blit.m_width) - blit.m_dstX; - uint32_t dstHeight = bx::uint32_min(dst.m_height, blit.m_dstY + blit.m_height) - blit.m_dstY; - uint32_t dstDepth = bx::uint32_min(dst.m_depth, blit.m_dstZ + blit.m_depth) - blit.m_dstZ; - uint32_t width = bx::uint32_min(srcWidth, dstWidth); - uint32_t height = bx::uint32_min(srcHeight, dstHeight); - uint32_t depth = bx::uint32_min(srcDepth, dstDepth); - if (TextureD3D12::Texture3D == src.m_type) { D3D12_BOX box; - box.left = blit.m_srcX; - box.top = blit.m_srcY; - box.front = blit.m_srcZ; - box.right = blit.m_srcX + width; - box.bottom = blit.m_srcY + height;; - box.back = blit.m_srcZ + bx::uint32_imax(1, depth); - - D3D12_TEXTURE_COPY_LOCATION dstLocation = { dst.m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, { { 0, { DXGI_FORMAT_UNKNOWN, 0, 0, 0, 0 } } } }; - D3D12_TEXTURE_COPY_LOCATION srcLocation = { src.m_ptr, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, { { 0, { DXGI_FORMAT_UNKNOWN, 0, 0, 0, 0 } } } }; + box.left = blit.m_srcX; + box.top = blit.m_srcY; + box.front = blit.m_srcZ; + box.right = blit.m_srcX + blit.m_width; + box.bottom = blit.m_srcY + blit.m_height; + box.back = blit.m_srcZ + bx::uint32_imax(1, blit.m_depth); + + D3D12_TEXTURE_COPY_LOCATION dstLocation; + dstLocation.pResource = dst.m_ptr; + dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dstLocation.SubresourceIndex = blit.m_dstMip; + + D3D12_TEXTURE_COPY_LOCATION srcLocation; + srcLocation.pResource = src.m_ptr; + srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + srcLocation.SubresourceIndex = blit.m_srcMip; + m_commandList->CopyTextureRegion(&dstLocation , blit.m_dstX , blit.m_dstY @@ -5571,8 +6274,8 @@ namespace bgfx { namespace d3d12 box.left = blit.m_srcX; box.top = blit.m_srcY; box.front = 0; - box.right = blit.m_srcX + width; - box.bottom = blit.m_srcY + height;; + box.right = blit.m_srcX + blit.m_width; + box.bottom = blit.m_srcY + blit.m_height; box.back = 1; const uint32_t srcZ = TextureD3D12::TextureCube == src.m_type @@ -5588,13 +6291,16 @@ namespace bgfx { namespace d3d12 dstLocation.pResource = dst.m_ptr; dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; dstLocation.SubresourceIndex = dstZ*dst.m_numMips+blit.m_dstMip; + D3D12_TEXTURE_COPY_LOCATION srcLocation; - srcLocation.pResource = src.m_ptr; + srcLocation.pResource = NULL != src.m_singleMsaa ? src.m_singleMsaa : src.m_ptr; srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; srcLocation.SubresourceIndex = srcZ*src.m_numMips+blit.m_srcMip; - bool depthStencil = bimg::isDepth(bimg::TextureFormat::Enum(src.m_textureFormat) ); - m_commandList->CopyTextureRegion(&dstLocation + const bool depthStencil = bimg::isDepth(bimg::TextureFormat::Enum(src.m_textureFormat) ); + + m_commandList->CopyTextureRegion( + &dstLocation , blit.m_dstX , blit.m_dstY , 0 @@ -5602,6 +6308,16 @@ namespace bgfx { namespace d3d12 , depthStencil ? NULL : &box ); } + + if (NULL != src.m_singleMsaa) + { + setResourceBarrier( + m_commandList + , src.m_singleMsaa + , D3D12_RESOURCE_STATE_COPY_SOURCE + , D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE + ); + } } if (isValid(currentSrc) @@ -5613,8 +6329,6 @@ namespace bgfx { namespace d3d12 void RendererContextD3D12::submit(Frame* _render, ClearQuad& /*_clearQuad*/, TextVideoMemBlitter& _textVideoMemBlitter) { - PIX3_BEGINEVENT(m_commandList, D3DCOLOR_FRAME, "rendererSubmit"); - if (m_lost || updateResolution(_render->m_resolution) ) { @@ -5626,19 +6340,23 @@ namespace bgfx { namespace d3d12 renderDocTriggerCapture(); } + BGFX_D3D12_PROFILER_BEGIN_LITERAL("rendererSubmit", kColorFrame); + int64_t timeBegin = bx::getHPCounter(); int64_t captureElapsed = 0; - uint32_t frameQueryIdx = m_gpuTimer.begin(BGFX_CONFIG_MAX_VIEWS); + uint32_t frameQueryIdx = m_gpuTimer.begin(BGFX_CONFIG_MAX_VIEWS, _render->m_frameNum); if (0 < _render->m_iboffset) { + BGFX_PROFILER_SCOPE("bgfx/Update transient index buffer", kColorResource); TransientIndexBuffer* ib = _render->m_transientIb; m_indexBuffers[ib->handle.idx].update(m_commandList, 0, _render->m_iboffset, ib->data); } if (0 < _render->m_vboffset) { + BGFX_PROFILER_SCOPE("bgfx/Update transient vertex buffer", kColorResource); TransientVertexBuffer* vb = _render->m_transientVb; m_vertexBuffers[vb->handle.idx].update(m_commandList, 0, _render->m_vboffset, vb->data); } @@ -5653,15 +6371,14 @@ namespace bgfx { namespace d3d12 RenderBind currentBind; currentBind.clear(); - const bool hmdEnabled = false; static ViewState viewState; - viewState.reset(_render, hmdEnabled); + viewState.reset(_render); // bool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME); // setDebugWireframe(wireframe); uint16_t currentSamplerStateIdx = kInvalidHandle; - uint16_t currentProgramIdx = kInvalidHandle; + ProgramHandle currentProgram = BGFX_INVALID_HANDLE; uint32_t currentBindHash = 0; bool hasPredefined = false; bool commandListChanged = false; @@ -5753,12 +6470,10 @@ namespace bgfx { namespace d3d12 m_batch.begin(); -// uint8_t eye = 0; -// uint8_t restartState = 0; viewState.m_rect = _render->m_view[0].m_rect; - int32_t numItems = _render->m_numRenderItems; - for (int32_t item = 0, restartItem = numItems; item < numItems || restartItem < numItems;) + + for (int32_t item = 0; item < numItems;) { const uint64_t encodedKey = _render->m_sortKeys[item]; const bool isCompute = key.decode(encodedKey, _render->m_viewRemap); @@ -5784,19 +6499,23 @@ namespace bgfx { namespace d3d12 view = key.m_view; currentPso = NULL; currentSamplerStateIdx = kInvalidHandle; - currentProgramIdx = kInvalidHandle; + currentProgram = BGFX_INVALID_HANDLE; hasPredefined = false; - fbh = _render->m_view[view].m_fbh; - setFrameBuffer(fbh); - if (item > 1) { profiler.end(); } + BGFX_D3D12_PROFILER_END(); + setViewType(view, " "); + BGFX_D3D12_PROFILER_BEGIN(view, kColorView); + profiler.begin(view); + fbh = _render->m_view[view].m_fbh; + setFrameBuffer(fbh); + viewState.m_rect = _render->m_view[view].m_rect; const Rect& rect = _render->m_view[view].m_rect; const Rect& scissorRect = _render->m_view[view].m_scissor; @@ -5839,13 +6558,9 @@ namespace bgfx { namespace d3d12 { wasCompute = true; - if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) - { - char* viewName = s_viewName[view]; - viewName[3] = L'C'; - PIX3_ENDEVENT(m_commandList); - PIX3_BEGINEVENT(m_commandList, D3DCOLOR_COMPUTE, viewName); - } + setViewType(view, "C"); + BGFX_D3D12_PROFILER_END(); + BGFX_D3D12_PROFILER_BEGIN(view, kColorCompute); commandListChanged = true; } @@ -5880,92 +6595,94 @@ namespace bgfx { namespace d3d12 Bind* bindCached = bindLru.find(bindHash); if (NULL == bindCached) { + uint32_t numSet = 0; D3D12_GPU_DESCRIPTOR_HANDLE srvHandle[BGFX_MAX_COMPUTE_BINDINGS] = {}; uint32_t samplerFlags[BGFX_MAX_COMPUTE_BINDINGS] = {}; - - for (uint8_t stage = 0; stage < maxComputeBindings; ++stage) { - const Binding& bind = renderBind.m_bind[stage]; - if (kInvalidHandle != bind.m_idx) + for (uint8_t stage = 0; stage < maxComputeBindings; ++stage) { - switch (bind.m_type) + const Binding& bind = renderBind.m_bind[stage]; + if (kInvalidHandle != bind.m_idx) { - case Binding::Image: + switch (bind.m_type) { - TextureD3D12& texture = m_textures[bind.m_idx]; - - if (Access::Read != bind.m_access) + case Binding::Image: { - texture.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - scratchBuffer.allocUav(srvHandle[stage], texture, bind.m_mip); + TextureD3D12& texture = m_textures[bind.m_idx]; + + if (Access::Read != bind.m_access) + { + texture.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + scratchBuffer.allocUav(srvHandle[stage], texture, bind.m_mip); + } + else + { + texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); + scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_mip); + samplerFlags[stage] = uint32_t(texture.m_flags); + } + + ++numSet; } - else + break; + + case Binding::Texture: { + TextureD3D12& texture = m_textures[bind.m_idx]; texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); - scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_mip); - samplerFlags[stage] = uint32_t(texture.m_flags); + scratchBuffer.allocSrv(srvHandle[stage], texture); + samplerFlags[stage] = (0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & bind.m_samplerFlags) + ? bind.m_samplerFlags + : texture.m_flags + ) & (BGFX_SAMPLER_BITS_MASK | BGFX_SAMPLER_BORDER_COLOR_MASK | BGFX_SAMPLER_COMPARE_MASK) + ; + + ++numSet; } - } - break; + break; - case Binding::Texture: - { - TextureD3D12& texture = m_textures[bind.m_idx]; - texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); - scratchBuffer.allocSrv(srvHandle[stage], texture); - samplerFlags[stage] = (0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & bind.m_samplerFlags) - ? bind.m_samplerFlags - : texture.m_flags - ) & (BGFX_SAMPLER_BITS_MASK | BGFX_SAMPLER_BORDER_COLOR_MASK | BGFX_SAMPLER_COMPARE_MASK) - ; - } - break; + case Binding::IndexBuffer: + case Binding::VertexBuffer: + { + BufferD3D12& buffer = Binding::IndexBuffer == bind.m_type + ? m_indexBuffers[bind.m_idx] + : m_vertexBuffers[bind.m_idx] + ; - case Binding::IndexBuffer: - case Binding::VertexBuffer: - { - BufferD3D12& buffer = Binding::IndexBuffer == bind.m_type - ? m_indexBuffers[bind.m_idx] - : m_vertexBuffers[bind.m_idx] - ; + if (Access::Read != bind.m_access) + { + buffer.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + scratchBuffer.allocUav(srvHandle[stage], buffer); + } + else + { + buffer.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); + scratchBuffer.allocSrv(srvHandle[stage], buffer); + } - if (Access::Read != bind.m_access) - { - buffer.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - scratchBuffer.allocUav(srvHandle[stage], buffer); - } - else - { - buffer.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); - scratchBuffer.allocSrv(srvHandle[stage], buffer); + ++numSet; } + break; } - break; + } + else + { + samplerFlags[stage] = 0; + scratchBuffer.allocEmpty(srvHandle[stage]); } } - else + + if (0 != numSet) { - samplerFlags[stage] = 0; - scratchBuffer.allocEmpty(srvHandle[stage]); + Bind bind; + bind.m_srvHandle = srvHandle[0]; + bind.m_samplerStateIdx = getSamplerState(samplerFlags, maxComputeBindings, _render->m_colorPalette); + bindCached = bindLru.add(bindHash, bind, 0); } } - - uint16_t samplerStateIdx = getSamplerState(samplerFlags, maxComputeBindings, _render->m_colorPalette); - if (samplerStateIdx != currentSamplerStateIdx) - { - currentSamplerStateIdx = samplerStateIdx; - m_commandList->SetComputeRootDescriptorTable(Rdt::Sampler, m_samplerAllocator.get(samplerStateIdx) ); - } - - m_commandList->SetComputeRootDescriptorTable(Rdt::SRV, srvHandle[0]); - m_commandList->SetComputeRootDescriptorTable(Rdt::UAV, srvHandle[0]); - - Bind bind; - bind.m_srvHandle = srvHandle[0]; - bind.m_samplerStateIdx = samplerStateIdx; - bindLru.add(bindHash, bind, 0); } - else + + if (NULL != bindCached) { uint16_t samplerStateIdx = bindCached->m_samplerStateIdx; if (samplerStateIdx != currentSamplerStateIdx) @@ -5980,12 +6697,12 @@ namespace bgfx { namespace d3d12 bool constantsChanged = false; if (compute.m_uniformBegin < compute.m_uniformEnd - || currentProgramIdx != key.m_program) + || currentProgram.idx != key.m_program.idx) { rendererUpdateUniforms(this, _render->m_uniformBuffer[compute.m_uniformIdx], compute.m_uniformBegin, compute.m_uniformEnd); - currentProgramIdx = key.m_program; - ProgramD3D12& program = m_program[currentProgramIdx]; + currentProgram = key.m_program; + ProgramD3D12& program = m_program[currentProgram.idx]; UniformBuffer* vcb = program.m_vsh->m_constantBuffer; if (NULL != vcb) @@ -6000,8 +6717,8 @@ namespace bgfx { namespace d3d12 if (constantsChanged || hasPredefined) { - ProgramD3D12& program = m_program[currentProgramIdx]; - viewState.setPredefined<4>(this, view, 0, program, _render, compute); + ProgramD3D12& program = m_program[currentProgram.idx]; + viewState.setPredefined<4>(this, view, program, _render, compute); commitShaderConstants(key.m_program, gpuAddress); m_commandList->SetComputeRootConstantBufferView(Rdt::CBV, gpuAddress); } @@ -6038,14 +6755,9 @@ namespace bgfx { namespace d3d12 { wasCompute = false; - if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) - { - BX_UNUSED(s_viewName); - char* viewName = s_viewName[view]; - viewName[3] = ' '; - PIX3_ENDEVENT(m_commandList); - PIX3_BEGINEVENT(m_commandList, D3DCOLOR_DRAW, viewName); - } + setViewType(view, " "); + BGFX_D3D12_PROFILER_END(); + BGFX_D3D12_PROFILER_BEGIN(view, kColorDraw); commandListChanged = true; } @@ -6075,63 +6787,54 @@ namespace bgfx { namespace d3d12 } } - const uint64_t newFlags = draw.m_stateFlags; - uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags; - currentState.m_stateFlags = newFlags; - - const uint64_t newStencil = draw.m_stencil; - uint64_t changedStencil = (currentState.m_stencil ^ draw.m_stencil) & BGFX_STENCIL_FUNC_REF_MASK; - currentState.m_stencil = newStencil; - - if (resetState) + if (0 != draw.m_streamMask) { - wasCompute = false; - - currentState.clear(); - currentState.m_scissor = !draw.m_scissor; - changedFlags = BGFX_STATE_MASK; - changedStencil = packStencil(BGFX_STENCIL_MASK, BGFX_STENCIL_MASK); + const uint64_t newFlags = draw.m_stateFlags; + uint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags; currentState.m_stateFlags = newFlags; - currentState.m_stencil = newStencil; - currentBind.clear(); + if (0 != (BGFX_STATE_PT_MASK & changedFlags) ) + { + primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT); + } - commandListChanged = true; - } + const uint64_t newStencil = draw.m_stencil; + uint64_t changedStencil = (currentState.m_stencil ^ draw.m_stencil) & BGFX_STENCIL_FUNC_REF_MASK; + currentState.m_stencil = newStencil; - if (commandListChanged) - { - commandListChanged = false; + if (resetState + || commandListChanged) + { + wasCompute = false; + commandListChanged = false; - m_commandList->SetGraphicsRootSignature(m_rootSignature); - ID3D12DescriptorHeap* heaps[] = { - m_samplerAllocator.getHeap(), - scratchBuffer.getHeap(), - }; - m_commandList->SetDescriptorHeaps(BX_COUNTOF(heaps), heaps); + m_commandList->SetGraphicsRootSignature(m_rootSignature); + ID3D12DescriptorHeap* heaps[] = { + m_samplerAllocator.getHeap(), + scratchBuffer.getHeap(), + }; + m_commandList->SetDescriptorHeaps(BX_COUNTOF(heaps), heaps); - currentPso = NULL; - currentBindHash = 0; - currentSamplerStateIdx = kInvalidHandle; - currentProgramIdx = kInvalidHandle; - currentState.clear(); - currentState.m_scissor = !draw.m_scissor; - changedFlags = BGFX_STATE_MASK; - changedStencil = packStencil(BGFX_STENCIL_MASK, BGFX_STENCIL_MASK); - currentState.m_stateFlags = newFlags; - currentState.m_stencil = newStencil; + currentPso = NULL; + currentBindHash = 0; + currentSamplerStateIdx = kInvalidHandle; + currentProgram = BGFX_INVALID_HANDLE; + currentState.clear(); + currentState.m_scissor = !draw.m_scissor; + changedFlags = BGFX_STATE_MASK; + changedStencil = packStencil(BGFX_STENCIL_MASK, BGFX_STENCIL_MASK); + currentState.m_stateFlags = newFlags; + currentState.m_stencil = newStencil; - currentBind.clear(); + currentBind.clear(); - const uint64_t pt = newFlags&BGFX_STATE_PT_MASK; - primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT); - } + const uint64_t pt = newFlags&BGFX_STATE_PT_MASK; + primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT); + } - bool constantsChanged = draw.m_uniformBegin < draw.m_uniformEnd; - rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd); + bool constantsChanged = draw.m_uniformBegin < draw.m_uniformEnd; + rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd); - if (0 != draw.m_streamMask) - { currentState.m_streamMask = draw.m_streamMask; currentState.m_instanceDataBuffer.idx = draw.m_instanceDataBuffer.idx; currentState.m_instanceDataOffset = draw.m_instanceDataOffset; @@ -6145,49 +6848,52 @@ namespace bgfx { namespace d3d12 || f3 == (state & f3) ; - const VertexDecl* decls[BGFX_CONFIG_MAX_VERTEX_STREAMS]; + const VertexLayout* layouts[BGFX_CONFIG_MAX_VERTEX_STREAMS]; uint8_t numStreams = 0; if (UINT8_MAX != draw.m_streamMask) { - for (uint32_t idx = 0, streamMask = draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask) + for (uint32_t idx = 0, streamMask = draw.m_streamMask ; 0 != streamMask - ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask), ++numStreams + ; streamMask >>= 1, idx += 1, ++numStreams ) { + const uint32_t ntz = bx::uint32_cnttz(streamMask); streamMask >>= ntz; - idx += ntz; + idx += ntz; - currentState.m_stream[idx].m_decl = draw.m_stream[idx].m_decl; - currentState.m_stream[idx].m_handle = draw.m_stream[idx].m_handle; - currentState.m_stream[idx].m_startVertex = draw.m_stream[idx].m_startVertex; + currentState.m_stream[idx].m_layoutHandle = draw.m_stream[idx].m_layoutHandle; + currentState.m_stream[idx].m_handle = draw.m_stream[idx].m_handle; + currentState.m_stream[idx].m_startVertex = draw.m_stream[idx].m_startVertex; uint16_t handle = draw.m_stream[idx].m_handle.idx; const VertexBufferD3D12& vb = m_vertexBuffers[handle]; - uint16_t decl = !isValid(vb.m_decl) ? draw.m_stream[idx].m_decl.idx : vb.m_decl.idx; - const VertexDecl& vertexDecl = m_vertexDecls[decl]; + const uint16_t layoutIdx = isValid(draw.m_stream[idx].m_layoutHandle) + ? draw.m_stream[idx].m_layoutHandle.idx + : vb.m_layoutHandle.idx; + const VertexLayout& layout = m_vertexLayouts[layoutIdx]; - decls[numStreams] = &vertexDecl; + layouts[numStreams] = &layout; } } - ID3D12PipelineState* pso = - getPipelineState(state - , draw.m_stencil - , numStreams - , decls - , key.m_program - , uint8_t(draw.m_instanceDataStride/16) - ); + ID3D12PipelineState* pso = getPipelineState( + state + , draw.m_stencil + , numStreams + , layouts + , key.m_program + , uint8_t(draw.m_instanceDataStride/16) + ); + + const uint32_t bindHash = bx::hash<bx::HashMurmur2A>(renderBind.m_bind, sizeof(renderBind.m_bind) ); - uint16_t scissor = draw.m_scissor; - uint32_t bindHash = bx::hash<bx::HashMurmur2A>(renderBind.m_bind, sizeof(renderBind.m_bind) ); if (currentBindHash != bindHash || 0 != changedStencil || (hasFactor && blendFactor != draw.m_rgba) || (0 != (BGFX_STATE_PT_MASK & changedFlags) || prim.m_topology != s_primInfo[primIndex].m_topology) - || currentState.m_scissor != scissor + || currentState.m_scissor != draw.m_scissor || pso != currentPso || hasOcclusionQuery) { @@ -6202,8 +6908,8 @@ namespace bgfx { namespace d3d12 if (NULL == bindCached) { uint32_t numSet = 0; - D3D12_GPU_DESCRIPTOR_HANDLE srvHandle[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; - uint32_t samplerFlags[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; + D3D12_GPU_DESCRIPTOR_HANDLE srvHandle[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS] = {}; + uint32_t samplerFlags[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS] = {}; { for (uint32_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage) { @@ -6212,6 +6918,26 @@ namespace bgfx { namespace d3d12 { switch (bind.m_type) { + case Binding::Image: + { + TextureD3D12& texture = m_textures[bind.m_idx]; + + if (Access::Read != bind.m_access) + { + texture.setState(m_commandList, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + scratchBuffer.allocUav(srvHandle[stage], texture, bind.m_mip); + } + else + { + texture.setState(m_commandList, D3D12_RESOURCE_STATE_GENERIC_READ); + scratchBuffer.allocSrv(srvHandle[stage], texture, bind.m_mip); + samplerFlags[stage] = uint32_t(texture.m_flags); + } + + ++numSet; + } + break; + case Binding::Texture: { TextureD3D12& texture = m_textures[bind.m_idx]; @@ -6263,23 +6989,14 @@ namespace bgfx { namespace d3d12 if (0 != numSet) { - uint16_t samplerStateIdx = getSamplerState(samplerFlags, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, _render->m_colorPalette); - if (samplerStateIdx != currentSamplerStateIdx) - { - currentSamplerStateIdx = samplerStateIdx; - m_commandList->SetGraphicsRootDescriptorTable(Rdt::Sampler, m_samplerAllocator.get(samplerStateIdx) ); - } - - m_commandList->SetGraphicsRootDescriptorTable(Rdt::SRV, srvHandle[0]); - m_commandList->SetGraphicsRootDescriptorTable(Rdt::UAV, srvHandle[0]); - Bind bind; - bind.m_srvHandle = srvHandle[0]; - bind.m_samplerStateIdx = samplerStateIdx; - bindLru.add(bindHash, bind, 0); + bind.m_srvHandle = srvHandle[0]; + bind.m_samplerStateIdx = getSamplerState(samplerFlags, BGFX_CONFIG_MAX_TEXTURE_SAMPLERS, _render->m_colorPalette); + bindCached = bindLru.add(bindHash, bind, 0); } } - else + + if (NULL != bindCached) { uint16_t samplerStateIdx = bindCached->m_samplerStateIdx; if (samplerStateIdx != currentSamplerStateIdx) @@ -6322,6 +7039,7 @@ namespace bgfx { namespace d3d12 m_commandList->IASetPrimitiveTopology(prim.m_topology); } + const uint16_t scissor = draw.m_scissor; if (currentState.m_scissor != scissor) { currentState.m_scissor = scissor; @@ -6366,11 +7084,11 @@ namespace bgfx { namespace d3d12 } if (constantsChanged - || currentProgramIdx != key.m_program + || currentProgram.idx != key.m_program.idx || BGFX_STATE_ALPHA_REF_MASK & changedFlags) { - currentProgramIdx = key.m_program; - ProgramD3D12& program = m_program[currentProgramIdx]; + currentProgram = key.m_program; + ProgramD3D12& program = m_program[currentProgram.idx]; UniformBuffer* vcb = program.m_vsh->m_constantBuffer; if (NULL != vcb) @@ -6394,10 +7112,10 @@ namespace bgfx { namespace d3d12 if (constantsChanged || hasPredefined) { - ProgramD3D12& program = m_program[currentProgramIdx]; + ProgramD3D12& program = m_program[currentProgram.idx]; uint32_t ref = (newFlags&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT; viewState.m_alphaRef = ref/255.0f; - viewState.setPredefined<4>(this, view, 0, program, _render, draw); + viewState.setPredefined<4>(this, view, program, _render, draw); commitShaderConstants(key.m_program, gpuAddress); } @@ -6424,13 +7142,9 @@ namespace bgfx { namespace d3d12 if (wasCompute) { - if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) - { - char* viewName = s_viewName[view]; - viewName[3] = L'C'; - PIX3_ENDEVENT(m_commandList); - PIX3_BEGINEVENT(m_commandList, D3DCOLOR_DRAW, viewName); - } + setViewType(view, "C"); + BGFX_D3D12_PROFILER_END(); + BGFX_D3D12_PROFILER_BEGIN(view, kColorCompute); } submitBlit(bs, BGFX_CONFIG_MAX_VIEWS); @@ -6450,7 +7164,7 @@ namespace bgfx { namespace d3d12 } } - PIX3_ENDEVENT(m_commandList); + BGFX_D3D12_PROFILER_END(); int64_t timeEnd = bx::getHPCounter(); int64_t frameTime = timeEnd - timeBegin; @@ -6497,6 +7211,7 @@ namespace bgfx { namespace d3d12 perfStats.numCompute = statsKeyType[1]; perfStats.numBlit = _render->m_numBlitItems; perfStats.maxGpuLatency = maxGpuLatency; + perfStats.gpuFrameNum = result.m_frameNum; bx::memCopy(perfStats.numPrims, statsNumPrimsRendered, sizeof(perfStats.numPrims) ); perfStats.gpuMemoryMax = -INT64_MAX; perfStats.gpuMemoryUsed = -INT64_MAX; @@ -6512,7 +7227,7 @@ namespace bgfx { namespace d3d12 if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) { - PIX3_BEGINEVENT(m_commandList, D3DCOLOR_FRAME, "debugstats"); + BGFX_D3D12_PROFILER_BEGIN_LITERAL("debugstats", kColorFrame); // m_needPresent = true; TextVideoMem& tvm = m_textVideoMem; @@ -6529,14 +7244,24 @@ namespace bgfx { namespace d3d12 tvm.clear(); uint16_t pos = 0; tvm.printf(0, pos++, BGFX_CONFIG_DEBUG ? 0x8c : 0x8f - , " %s.%d (FL %d.%d) / " BX_COMPILER_NAME " / " BX_CPU_NAME " / " BX_ARCH_NAME " / " BX_PLATFORM_NAME " " + , " %s.%d (FL %d.%d) / " BX_COMPILER_NAME + " / " BX_CPU_NAME + " / " BX_ARCH_NAME + " / " BX_PLATFORM_NAME + " / Version 1.%d.%d (commit: " BGFX_REV_SHA1 ")" , getRendererName() , m_deviceInterfaceVersion , (m_featureLevel >> 12) & 0xf , (m_featureLevel >> 8) & 0xf + , BGFX_API_VERSION + , BGFX_REV_NUMBER ); +#if BX_PLATFORM_LINUX + const DXGI_ADAPTER_DESC desc = {}; +#else const DXGI_ADAPTER_DESC& desc = m_dxgi.m_adapterDesc; +#endif // BX_PLATFORM_LINUX char description[BX_COUNTOF(desc.Description)]; wcstombs(description, desc.Description, BX_COUNTOF(desc.Description) ); tvm.printf(0, pos++, 0x8f, " Device: %s", description); @@ -6676,15 +7401,15 @@ namespace bgfx { namespace d3d12 blit(this, _textVideoMemBlitter, tvm); - PIX3_ENDEVENT(m_commandList); + BGFX_D3D12_PROFILER_END(); } else if (_render->m_debug & BGFX_DEBUG_TEXT) { - PIX3_BEGINEVENT(m_commandList, D3DCOLOR_FRAME, "debugtext"); + BGFX_D3D12_PROFILER_BEGIN_LITERAL("debugtext", kColorFrame); blit(this, _textVideoMemBlitter, _render->m_textVideoMem); - PIX3_ENDEVENT(m_commandList); + BGFX_D3D12_PROFILER_END(); } m_commandList->OMSetRenderTargets(0, NULL, false, NULL); |