<NME> renderer_d3d11.cpp <BEF> /* * Copyright 2011-2022 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE */ #include "bgfx_p.h" #if BGFX_CONFIG_RENDERER_DIRECT3D11 # include "renderer_d3d11.h" # include <bx/pixelformat.h> namespace bgfx { namespace d3d11 { static wchar_t s_viewNameW[BGFX_CONFIG_MAX_VIEWS][BGFX_CONFIG_MAX_VIEW_NAME]; 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) ) { const uint32_t len = _str.getLength(); bx::memCopy(&s_viewName[_view][3], _str.getPtr(), len); wchar_t tmpW[16]; mbstowcs(tmpW, _str.getPtr(), len); bx::memCopy(&s_viewNameW[_view][3], tmpW, len*2); } } struct PrimInfo { D3D11_PRIMITIVE_TOPOLOGY m_type; uint32_t m_min; uint32_t m_div; uint32_t m_sub; }; static const PrimInfo s_primInfo[] = { { D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, 3, 3, 0 }, { D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, 3, 1, 2 }, { D3D11_PRIMITIVE_TOPOLOGY_LINELIST, 2, 2, 0 }, { D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP, 2, 1, 1 }, { D3D11_PRIMITIVE_TOPOLOGY_POINTLIST, 1, 1, 0 }, { D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED, 0, 0, 0 }, }; BX_STATIC_ASSERT(Topology::Count == BX_COUNTOF(s_primInfo)-1); union Zero { Zero() { bx::memSet(this, 0, sizeof(Zero) ); } ID3D11Buffer* m_buffer[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; ID3D11UnorderedAccessView* m_uav[D3D11_1_UAV_SLOT_COUNT]; ID3D11ShaderResourceView* m_srv[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; ID3D11SamplerState* m_sampler[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; ID3D11RenderTargetView* m_rtv[BGFX_CONFIG_MAX_FRAME_BUFFERS]; uint32_t m_zero[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; float m_zerof[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; }; BX_PRAGMA_DIAGNOSTIC_PUSH(); BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4268) // warning C4268: '' : 'const' static/global data initialized with compiler generated default constructor fills the object with zeros static const Zero s_zero; BX_PRAGMA_DIAGNOSTIC_POP(); static const uint32_t s_checkMsaa[] = { 0, 2, 4, 8, 16, }; static DXGI_SAMPLE_DESC s_msaa[] = { { 1, 0 }, { 2, 0 }, { 4, 0 }, { 8, 0 }, { 16, 0 }, }; static const D3D11_BLEND s_blendFactor[][2] = { { D3D11_BLEND(0), D3D11_BLEND(0) }, // ignored { D3D11_BLEND_ZERO, D3D11_BLEND_ZERO }, // ZERO { D3D11_BLEND_ONE, D3D11_BLEND_ONE }, // ONE { D3D11_BLEND_SRC_COLOR, D3D11_BLEND_SRC_ALPHA }, // SRC_COLOR { D3D11_BLEND_INV_SRC_COLOR, D3D11_BLEND_INV_SRC_ALPHA }, // INV_SRC_COLOR { D3D11_BLEND_SRC_ALPHA, D3D11_BLEND_SRC_ALPHA }, // SRC_ALPHA { D3D11_BLEND_INV_SRC_ALPHA, D3D11_BLEND_INV_SRC_ALPHA }, // INV_SRC_ALPHA { D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_DEST_ALPHA }, // DST_ALPHA { D3D11_BLEND_INV_DEST_ALPHA, D3D11_BLEND_INV_DEST_ALPHA }, // INV_DST_ALPHA { D3D11_BLEND_DEST_COLOR, D3D11_BLEND_DEST_ALPHA }, // DST_COLOR { D3D11_BLEND_INV_DEST_COLOR, D3D11_BLEND_INV_DEST_ALPHA }, // INV_DST_COLOR { D3D11_BLEND_SRC_ALPHA_SAT, D3D11_BLEND_ONE }, // SRC_ALPHA_SAT { D3D11_BLEND_BLEND_FACTOR, D3D11_BLEND_BLEND_FACTOR }, // FACTOR { D3D11_BLEND_INV_BLEND_FACTOR, D3D11_BLEND_INV_BLEND_FACTOR }, // INV_FACTOR }; static const D3D11_BLEND_OP s_blendEquation[] = { D3D11_BLEND_OP_ADD, D3D11_BLEND_OP_SUBTRACT, D3D11_BLEND_OP_REV_SUBTRACT, D3D11_BLEND_OP_MIN, D3D11_BLEND_OP_MAX, }; static const D3D11_COMPARISON_FUNC s_cmpFunc[] = { D3D11_COMPARISON_FUNC(0), // ignored D3D11_COMPARISON_LESS, D3D11_COMPARISON_LESS_EQUAL, D3D11_COMPARISON_EQUAL, D3D11_COMPARISON_GREATER_EQUAL, D3D11_COMPARISON_GREATER, D3D11_COMPARISON_NOT_EQUAL, D3D11_COMPARISON_NEVER, D3D11_COMPARISON_ALWAYS, }; static const D3D11_STENCIL_OP s_stencilOp[] = { D3D11_STENCIL_OP_ZERO, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_REPLACE, D3D11_STENCIL_OP_INCR, D3D11_STENCIL_OP_INCR_SAT, D3D11_STENCIL_OP_DECR, D3D11_STENCIL_OP_DECR_SAT, D3D11_STENCIL_OP_INVERT, }; static const D3D11_CULL_MODE s_cullMode[] = { D3D11_CULL_NONE, D3D11_CULL_FRONT, D3D11_CULL_BACK, }; static const D3D11_TEXTURE_ADDRESS_MODE s_textureAddress[] = { D3D11_TEXTURE_ADDRESS_WRAP, D3D11_TEXTURE_ADDRESS_MIRROR, D3D11_TEXTURE_ADDRESS_CLAMP, D3D11_TEXTURE_ADDRESS_BORDER, }; /* * D3D11_FILTER_MIN_MAG_MIP_POINT = 0x00, * D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR = 0x01, * D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT = 0x04, * D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR = 0x05, * D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT = 0x10, * D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x11, * D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT = 0x14, * D3D11_FILTER_MIN_MAG_MIP_LINEAR = 0x15, * D3D11_FILTER_ANISOTROPIC = 0x55, * * D3D11_COMPARISON_FILTERING_BIT = 0x80, * D3D11_ANISOTROPIC_FILTERING_BIT = 0x40, * * According to D3D11_FILTER enum bits for mip, mag and mip are: * 0x10 // MIN_LINEAR * 0x04 // MAG_LINEAR * 0x01 // MIP_LINEAR */ static const uint8_t s_textureFilter[3][3] = { { 0x10, // min linear 0x00, // min point 0x55, // anisotropic }, { 0x04, // mag linear 0x00, // mag point 0x55, // anisotropic }, { 0x01, // mip linear 0x00, // mip point 0x55, // anisotropic }, }; struct TextureFormatInfo { DXGI_FORMAT m_fmt; DXGI_FORMAT m_fmtSrv; DXGI_FORMAT m_fmtDsv; DXGI_FORMAT m_fmtSrgb; }; 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_5X4_UNORM, DXGI_FORMAT_ASTC_5X4_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_5X4_UNORM_SRGB }, // ASTC5x4 { DXGI_FORMAT_ASTC_5X5_UNORM, DXGI_FORMAT_ASTC_5X5_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_5X5_UNORM_SRGB }, // ASTC5x5 { DXGI_FORMAT_ASTC_6X5_UNORM, DXGI_FORMAT_ASTC_6X5_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_6X5_UNORM_SRGB }, // ASTC6x5 { 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_8X8_UNORM, DXGI_FORMAT_ASTC_8X8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_8X8_UNORM_SRGB }, // ASTC8x8 { DXGI_FORMAT_ASTC_10X5_UNORM, DXGI_FORMAT_ASTC_10X5_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_10X5_UNORM_SRGB }, // ASTC10x5 { DXGI_FORMAT_ASTC_10X6_UNORM, DXGI_FORMAT_ASTC_10X6_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_10X6_UNORM_SRGB }, // ASTC10x6 { DXGI_FORMAT_ASTC_10X8_UNORM, DXGI_FORMAT_ASTC_10X8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_10X8_UNORM_SRGB }, // ASTC10x8 { DXGI_FORMAT_ASTC_10X10_UNORM, DXGI_FORMAT_ASTC_10X10_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_10X10_UNORM_SRGB}, // ASTC10x10 { DXGI_FORMAT_ASTC_12X10_UNORM, DXGI_FORMAT_ASTC_12X10_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_12X10_UNORM_SRGB}, // ASTC12x10 { DXGI_FORMAT_ASTC_12X12_UNORM, DXGI_FORMAT_ASTC_12X12_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_ASTC_12X12_UNORM_SRGB}, // ASTC12x12 { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // Unknown { DXGI_FORMAT_R1_UNORM, DXGI_FORMAT_R1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R1 { DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // A8 { DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R8 { DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R8I { DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R8U { DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R8S { DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R16 { DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R16I { DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R16U { DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R16F { DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R16S { DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R32I { DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R32U { DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R32F { DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG8 { DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG8I { DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG8U { DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG8S { DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG16 { DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG16I { DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG16U { DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG16F { DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG16S { DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG32I { DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG32U { DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RG32F { DXGI_FORMAT_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 }, // B5G6R5 { 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 }, // BGRA4 { 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 }, // BGR5A1 { 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 }; BX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_textureFormat) ); static const D3D11_INPUT_ELEMENT_DESC s_attrib[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "BITANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 1, DXGI_FORMAT_R8G8B8A8_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 2, DXGI_FORMAT_R8G8B8A8_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 3, DXGI_FORMAT_R8G8B8A8_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "BLENDINDICES", 0, DXGI_FORMAT_R8G8B8A8_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "BLENDWEIGHT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 3, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 4, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 5, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 6, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 7, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; BX_STATIC_ASSERT(Attrib::Count == BX_COUNTOF(s_attrib) ); static const DXGI_FORMAT s_attribType[][4][2] = { { // Uint8 { DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_UNORM }, { DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_UNORM }, { DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UNORM }, { DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_UNORM }, }, { // Uint10 { DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UNORM }, { DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UNORM }, { DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UNORM }, { DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R10G10B10A2_UNORM }, }, { // Int16 { DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16_SNORM }, { DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16_SNORM }, { DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SNORM }, { DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_SNORM }, }, { // Half { DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_R16_FLOAT }, { DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_FLOAT }, { DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT }, { DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT }, }, { // Float { DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_FLOAT }, { DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_FLOAT }, { DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT }, { DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT }, }, }; BX_STATIC_ASSERT(AttribType::Count == BX_COUNTOF(s_attribType) ); static D3D11_INPUT_ELEMENT_DESC* fillVertexLayout(uint8_t _stream, D3D11_INPUT_ELEMENT_DESC* _out, const VertexLayout& _layout) { D3D11_INPUT_ELEMENT_DESC* elem = _out; for (uint32_t attr = 0; attr < Attrib::Count; ++attr) { if (UINT16_MAX != _layout.m_attributes[attr]) { bx::memCopy(elem, &s_attrib[attr], sizeof(D3D11_INPUT_ELEMENT_DESC) ); elem->InputSlot = _stream; if (0 == _layout.m_attributes[attr]) { elem->AlignedByteOffset = 0; } else { uint8_t num; AttribType::Enum type; bool normalized; bool asInt; _layout.decode(Attrib::Enum(attr), num, type, normalized, asInt); elem->Format = s_attribType[type][num-1][normalized]; elem->AlignedByteOffset = _layout.m_offset[attr]; } ++elem; } } return elem; } struct TextureStage { TextureStage() { clear(); } void clear() { bx::memSet(m_uav, 0, sizeof(m_uav) ); bx::memSet(m_srv, 0, sizeof(m_srv) ); bx::memSet(m_sampler, 0, sizeof(m_sampler) ); } ID3D11UnorderedAccessView* m_uav[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; ID3D11ShaderResourceView* m_srv[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; ID3D11SamplerState* m_sampler[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS]; }; BX_PRAGMA_DIAGNOSTIC_PUSH(); BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wunused-const-variable"); BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wunneeded-internal-declaration"); static const GUID WKPDID_D3DDebugObjectName = { 0x429b8c22, 0x9188, 0x4b0c, { 0x87, 0x42, 0xac, 0xb0, 0xbf, 0x85, 0xc2, 0x00 } }; static const GUID IID_ID3D11Texture2D = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c } }; static const GUID IID_ID3D11Device1 = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } }; static const GUID IID_ID3D11Device2 = { 0x9d06dffa, 0xd1e5, 0x4d07, { 0x83, 0xa8, 0x1b, 0xb1, 0x23, 0xf2, 0xf8, 0x41 } }; static const GUID IID_ID3D11Device3 = { 0xa05c8c37, 0xd2c6, 0x4732, { 0xb3, 0xa0, 0x9c, 0xe0, 0xb0, 0xdc, 0x9a, 0xe6 } }; static const GUID IID_ID3D11InfoQueue = { 0x6543dbb6, 0x1b48, 0x42f5, { 0xab, 0x82, 0xe9, 0x7e, 0xc7, 0x43, 0x26, 0xf6 } }; static const GUID IID_IDXGIDeviceRenderDoc = { 0xa7aa6116, 0x9c8d, 0x4bba, { 0x90, 0x83, 0xb4, 0xd8, 0x16, 0xb7, 0x1b, 0x78 } }; static const GUID IID_ID3DUserDefinedAnnotation = { 0xb2daad8b, 0x03d4, 0x4dbf, { 0x95, 0xeb, 0x32, 0xab, 0x4b, 0x63, 0xd0, 0xab } }; enum D3D11_FORMAT_SUPPORT2 { D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD = 0x40, D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE = 0x80, }; static const GUID s_d3dDeviceIIDs[] = { IID_ID3D11Device3, IID_ID3D11Device2, IID_ID3D11Device1, }; inline bool isLost(HRESULT _hr) { return false || _hr == DXGI_ERROR_DEVICE_REMOVED || _hr == DXGI_ERROR_DEVICE_HUNG || _hr == DXGI_ERROR_DEVICE_RESET || _hr == DXGI_ERROR_DRIVER_INTERNAL_ERROR || _hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE ; } static const char* getLostReason(HRESULT _hr) { switch (_hr) { // The GPU device instance has been suspended. Use GetDeviceRemovedReason to determine the appropriate action. case DXGI_ERROR_DEVICE_REMOVED: return "DXGI_ERROR_DEVICE_REMOVED"; // The GPU will not respond to more commands, most likely because of an invalid command passed by the calling application. case DXGI_ERROR_DEVICE_HUNG: return "DXGI_ERROR_DEVICE_HUNG"; // The GPU will not respond to more commands, most likely because some other application submitted invalid commands. // The calling application should re-create the device and continue. case DXGI_ERROR_DEVICE_RESET: return "DXGI_ERROR_DEVICE_RESET"; // An internal issue prevented the driver from carrying out the specified operation. The driver's state is probably // suspect, and the application should not continue. case DXGI_ERROR_DRIVER_INTERNAL_ERROR: return "DXGI_ERROR_DRIVER_INTERNAL_ERROR"; // A resource is not available at the time of the call, but may become available later. case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: return "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE"; case S_OK: return "S_OK"; default: break; } return "Unknown HRESULT?"; } template <typename Ty> static BX_NO_INLINE void setDebugObjectName(Ty* _interface, const char* _format, ...) { if (BX_ENABLED(BGFX_CONFIG_DEBUG_OBJECT_NAME) ) { char temp[2048]; va_list argList; va_start(argList, _format); int size = bx::uint32_min(sizeof(temp)-1, bx::vsnprintf(temp, sizeof(temp), _format, argList) ); va_end(argList); temp[size] = '\0'; _interface->SetPrivateData(WKPDID_D3DDebugObjectName, size, temp); } } BX_PRAGMA_DIAGNOSTIC_POP(); static HRESULT setIntelExtension(ID3D11Device* _device, const void* _data, uint32_t _size) { D3D11_BUFFER_DESC desc; desc.ByteWidth = _size; desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; desc.MiscFlags = 0; desc.StructureByteStride = 0; D3D11_SUBRESOURCE_DATA initData; initData.pSysMem = _data; initData.SysMemPitch = _size; initData.SysMemSlicePitch = 0; ID3D11Buffer* buffer; HRESULT hr = _device->CreateBuffer(&desc, &initData, &buffer); if (SUCCEEDED(hr) ) { buffer->Release(); } return hr; }; static const uint32_t kIntelExtensionInterfaceVersion = UINT32_C(0x10000); struct IntelExtension { char key[16]; uint32_t version; uint32_t type; uint32_t data[16]; }; static const IntelExtension s_intelDirectAccessResource = { { 'I', 'N', 'T', 'C', 'E', 'X', 'T', 'N', 'R', 'E', 'S', 'O', 'U', 'R', 'C', 'E' }, kIntelExtensionInterfaceVersion, 1, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, }; static HRESULT setIntelDirectAccessResource(ID3D11Device* _device) { return setIntelExtension(_device, &s_intelDirectAccessResource, sizeof(s_intelDirectAccessResource) ); } static BX_NO_INLINE bool getIntelExtensions(ID3D11Device* _device) { if (windowsVersionIs(Condition::GreaterEqual, 0x0604) ) { uint8_t temp[28]; bx::ErrorAssert err; bx::StaticMemoryBlockWriter writer(&temp, sizeof(temp) ); bx::write(&writer, "INTCEXTNCAPSFUNC", 16, &err); bx::write(&writer, kIntelExtensionInterfaceVersion, &err); bx::write(&writer, uint32_t(0), &err); bx::write(&writer, uint32_t(0), &err); if (SUCCEEDED(setIntelExtension(_device, temp, sizeof(temp) ) ) ) { bx::MemoryReader reader(&temp, sizeof(temp) ); bx::skip(&reader, 16); uint32_t version; bx::read(&reader, version, &err); uint32_t driverVersion; bx::read(&reader, driverVersion, &err); return version <= driverVersion; } } return false; } void resume(ID3D11Device* _device) { BX_UNUSED(_device); } void suspend(ID3D11Device* _device) { BX_UNUSED(_device); } /* * AMD GPU Services (AGS) library * * Reference(s): * - https://web.archive.org/web/20181126035805/https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK */ enum AGS_RETURN_CODE { AGS_SUCCESS, AGS_INVALID_ARGS, AGS_OUT_OF_MEMORY, AGS_ERROR_MISSING_DLL, AGS_ERROR_LEGACY_DRIVER, AGS_EXTENSION_NOT_SUPPORTED, AGS_ADL_FAILURE, }; enum AGS_DRIVER_EXTENSION { AGS_EXTENSION_QUADLIST = 1 << 0, AGS_EXTENSION_UAV_OVERLAP = 1 << 1, AGS_EXTENSION_DEPTH_BOUNDS_TEST = 1 << 2, AGS_EXTENSION_MULTIDRAWINDIRECT = 1 << 3, }; struct AGSDriverVersionInfo { char strDriverVersion[256]; char strCatalystVersion[256]; char strCatalystWebLink[256]; }; struct AGSContext; typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_INIT)(AGSContext**); typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DEINIT)(AGSContext*); typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_CROSSFIRE_GPU_COUNT)(AGSContext*, int32_t*); typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_TOTAL_GPU_COUNT)(AGSContext*, int32_t*); typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_GPU_MEMORY_SIZE)(AGSContext*, int32_t, int64_t*); typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_DRIVER_VERSION_INFO)(AGSContext*, AGSDriverVersionInfo*); typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_INIT)(AGSContext*, ID3D11Device*, uint32_t*); typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_DEINIT)(AGSContext*); typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INSTANCED_INDIRECT)(AGSContext*, uint32_t, ID3D11Buffer*, uint32_t, uint32_t); typedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INDEXED_INSTANCED_INDIRECT)(AGSContext*, uint32_t, ID3D11Buffer*, uint32_t, uint32_t); static PFN_AGS_INIT agsInit; static PFN_AGS_DEINIT agsDeInit; static PFN_AGS_GET_CROSSFIRE_GPU_COUNT agsGetCrossfireGPUCount; static PFN_AGS_GET_TOTAL_GPU_COUNT agsGetTotalGPUCount; static PFN_AGS_GET_GPU_MEMORY_SIZE agsGetGPUMemorySize; static PFN_AGS_GET_DRIVER_VERSION_INFO agsGetDriverVersionInfo; static PFN_AGS_DRIVER_EXTENSIONS_INIT agsDriverExtensions_Init; static PFN_AGS_DRIVER_EXTENSIONS_DEINIT agsDriverExtensions_DeInit; static PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INSTANCED_INDIRECT agsDriverExtensions_MultiDrawInstancedIndirect; static PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INDEXED_INSTANCED_INDIRECT agsDriverExtensions_MultiDrawIndexedInstancedIndirect; typedef void (* MultiDrawIndirectFn)(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); void stubMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); void stubMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); void amdAgsMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); void amdAgsMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); void nvapiMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); void nvapiMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride); static MultiDrawIndirectFn multiDrawInstancedIndirect; static MultiDrawIndirectFn multiDrawIndexedInstancedIndirect; #if USE_D3D11_DYNAMIC_LIB static PFN_D3D11_CREATE_DEVICE D3D11CreateDevice; static PFN_D3DPERF_SET_MARKER D3DPERF_SetMarker; static PFN_D3DPERF_BEGIN_EVENT D3DPERF_BeginEvent; static PFN_D3DPERF_END_EVENT D3DPERF_EndEvent; #endif // USE_D3D11_DYNAMIC_LIB int WINAPI d3d11Annotation_BeginEvent(DWORD _color, LPCWSTR _name); int WINAPI d3d11Annotation_EndEvent(); void WINAPI d3d11Annotation_SetMarker(DWORD _color, LPCWSTR _name); struct RendererContextD3D11 : public RendererContextI { RendererContextD3D11() : m_d3d9Dll(NULL) , m_d3d11Dll(NULL) , m_renderDocDll(NULL) , m_agsDll(NULL) , m_ags(NULL) , m_featureLevel(D3D_FEATURE_LEVEL(0) ) , m_swapChain(NULL) , m_msaaRt(NULL) , m_needPresent(false) , m_lost(false) , m_numWindows(0) , m_device(NULL) , m_deviceCtx(NULL) , m_annotation(NULL) , m_infoQueue(NULL) , m_backBufferColor(NULL) , m_backBufferDepthStencil(NULL) , m_currentColor(NULL) , m_currentDepthStencil(NULL) , m_captureTexture(NULL) , m_captureResolve(NULL) , m_maxAnisotropy(1) , m_depthClamp(false) , m_wireframe(false) , m_currentProgram(NULL) , m_vsChanges(0) , m_fsChanges(0) , m_rtMsaa(false) , m_timerQuerySupport(false) , m_directAccessSupport(false) { m_fbh.idx = kInvalidHandle; bx::memSet(&m_scd, 0, sizeof(m_scd) ); bx::memSet(&m_windows, 0xff, sizeof(m_windows) ); } ~RendererContextD3D11() { } bool init(const Init& _init) { struct ErrorState { enum Enum { Default, LoadedD3D11, LoadedDXGI, }; }; ErrorState::Enum errorState = ErrorState::Default; if (_init.debug || _init.profile) { m_renderDocDll = loadRenderDoc(); } m_fbh.idx = kInvalidHandle; bx::memSet(m_uniforms, 0, sizeof(m_uniforms) ); bx::memSet(&m_resolution, 0, sizeof(m_resolution) ); m_ags = NULL; m_agsDll = bx::dlopen( #if BX_ARCH_32BIT "amd_ags_x86.dll" #else "amd_ags_x64.dll" #endif // BX_ARCH_32BIT ); if (NULL != m_agsDll) { agsInit = (PFN_AGS_INIT )bx::dlsym(m_agsDll, "agsInit"); agsDeInit = (PFN_AGS_DEINIT)bx::dlsym(m_agsDll, "agsDeInit"); agsGetCrossfireGPUCount = (PFN_AGS_GET_CROSSFIRE_GPU_COUNT )bx::dlsym(m_agsDll, "agsGetCrossfireGPUCount"); agsGetTotalGPUCount = (PFN_AGS_GET_TOTAL_GPU_COUNT )bx::dlsym(m_agsDll, "agsGetTotalGPUCount"); agsGetGPUMemorySize = (PFN_AGS_GET_GPU_MEMORY_SIZE )bx::dlsym(m_agsDll, "agsGetGPUMemorySize"); agsGetDriverVersionInfo = (PFN_AGS_GET_DRIVER_VERSION_INFO )bx::dlsym(m_agsDll, "agsGetDriverVersionInfo"); agsDriverExtensions_Init = (PFN_AGS_DRIVER_EXTENSIONS_INIT )bx::dlsym(m_agsDll, "agsDriverExtensions_Init"); agsDriverExtensions_DeInit = (PFN_AGS_DRIVER_EXTENSIONS_DEINIT)bx::dlsym(m_agsDll, "agsDriverExtensions_DeInit"); agsDriverExtensions_MultiDrawInstancedIndirect = (PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INSTANCED_INDIRECT )bx::dlsym(m_agsDll, "agsDriverExtensions_MultiDrawInstancedIndirect"); agsDriverExtensions_MultiDrawIndexedInstancedIndirect = (PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INDEXED_INSTANCED_INDIRECT)bx::dlsym(m_agsDll, "agsDriverExtensions_MultiDrawIndexedInstancedIndirect"); bool agsSupported = true && NULL != agsInit && NULL != agsDeInit && NULL != agsGetCrossfireGPUCount && NULL != agsGetTotalGPUCount && NULL != agsGetGPUMemorySize && NULL != agsGetDriverVersionInfo && NULL != agsDriverExtensions_Init && NULL != agsDriverExtensions_DeInit && NULL != agsDriverExtensions_MultiDrawInstancedIndirect && NULL != agsDriverExtensions_MultiDrawIndexedInstancedIndirect ; if (agsSupported) { AGS_RETURN_CODE result = agsInit(&m_ags); agsSupported = AGS_SUCCESS == result; if (agsSupported) { AGSDriverVersionInfo vi; result = agsGetDriverVersionInfo(m_ags, &vi); BX_TRACE(" Driver version: %s", vi.strDriverVersion); BX_TRACE(" Catalyst version: %s", vi.strCatalystVersion); int32_t numCrossfireGPUs = 0; result = agsGetCrossfireGPUCount(m_ags, &numCrossfireGPUs); BX_TRACE(" Num crossfire GPUs: %d", numCrossfireGPUs); int32_t numGPUs = 0; result = agsGetTotalGPUCount(m_ags, &numGPUs); BX_TRACE(" Num GPUs: %d", numGPUs); for (int32_t ii = 0; ii < numGPUs; ++ii) { int64_t memSize; result = agsGetGPUMemorySize(m_ags, ii, &memSize); if (AGS_SUCCESS == result) { char memSizeStr[16]; bx::prettify(memSizeStr, BX_COUNTOF(memSizeStr), memSize); BX_TRACE(" GPU #%d mem size: %s", ii, memSizeStr); } } } } BX_WARN(!agsSupported, "AMD/AGS supported."); if (!agsSupported) { if (NULL != m_ags) { agsDeInit(m_ags); m_ags = NULL; } bx::dlclose(m_agsDll); m_agsDll = NULL; } } m_nvapi.init(); #if USE_D3D11_DYNAMIC_LIB const char* d3d11DllName = #if BX_PLATFORM_LINUX "d3d11.so" #else "d3d11.dll" #endif // BX_PLATFORM_LINUX ; m_d3d11Dll = bx::dlopen(d3d11DllName); if (NULL == m_d3d11Dll) { BX_TRACE("Init error: Failed to load %s.", d3d11DllName); goto error; } errorState = ErrorState::LoadedD3D11; m_d3d9Dll = NULL; if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) ) { // D3D11_1.h has ID3DUserDefinedAnnotation // https://web.archive.org/web/20190207230424/https://docs.microsoft.com/en-us/windows/desktop/api/d3d11_1/nn-d3d11_1-id3duserdefinedannotation m_d3d9Dll = bx::dlopen("d3d9.dll"); if (NULL != m_d3d9Dll) { D3DPERF_SetMarker = (PFN_D3DPERF_SET_MARKER )bx::dlsym(m_d3d9Dll, "D3DPERF_SetMarker" ); D3DPERF_BeginEvent = (PFN_D3DPERF_BEGIN_EVENT)bx::dlsym(m_d3d9Dll, "D3DPERF_BeginEvent"); D3DPERF_EndEvent = (PFN_D3DPERF_END_EVENT )bx::dlsym(m_d3d9Dll, "D3DPERF_EndEvent" ); if (NULL == D3DPERF_SetMarker || NULL == D3DPERF_BeginEvent || NULL == D3DPERF_EndEvent) { BX_TRACE("Failed to initialize PIX events."); D3DPERF_SetMarker = NULL; D3DPERF_BeginEvent = NULL; D3DPERF_EndEvent = NULL; bx::dlclose(m_d3d9Dll); m_d3d9Dll = NULL; } } } D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)bx::dlsym(m_d3d11Dll, "D3D11CreateDevice"); if (NULL == D3D11CreateDevice) { BX_TRACE("Init error: Function D3D11CreateDevice not found."); goto error; } #endif // USE_D3D11_DYNAMIC_LIB m_device = (ID3D11Device*)g_platformData.context; if (!m_dxgi.init(g_caps) ) { goto error; } errorState = ErrorState::LoadedDXGI; if (NULL == m_device) { if (NULL != m_renderDocDll) { setGraphicsDebuggerPresent(true); } D3D_FEATURE_LEVEL featureLevel[] = { D3D_FEATURE_LEVEL_12_1, D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0, #if BX_PLATFORM_WINRT D3D_FEATURE_LEVEL_9_3, D3D_FEATURE_LEVEL_9_2, #endif // BX_PLATFORM_WINRT }; HRESULT hr = S_OK; for (;;) { uint32_t flags = 0 | D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT // | D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS | (_init.debug ? D3D11_CREATE_DEVICE_DEBUG : 0) ; hr = E_FAIL; for (uint32_t ii = 0; ii < BX_COUNTOF(featureLevel) && FAILED(hr);) { hr = D3D11CreateDevice(m_dxgi.m_adapter , m_dxgi.m_driverType , NULL , flags , &featureLevel[ii] , BX_COUNTOF(featureLevel)-ii , D3D11_SDK_VERSION , &m_device , &m_featureLevel , &m_deviceCtx ); BX_WARN(FAILED(hr), "Direct3D11 device feature level %d.%d." , (m_featureLevel >> 12) & 0xf , (m_featureLevel >> 8) & 0xf ); if (FAILED(hr) && 0 != (flags & D3D11_CREATE_DEVICE_DEBUG) ) { // Try without debug in case D3D11 SDK Layers // is not present? flags &= ~D3D11_CREATE_DEVICE_DEBUG; DX_RELEASE(m_swapChain, 0); DX_RELEASE(m_deviceCtx, 0); DX_RELEASE(m_device, 0); DX_RELEASE(m_factory, 0); unloadRenderDoc(m_renderdocdll); if (FAILED(hr) && D3D_DRIVER_TYPE_WARP != m_dxgi.m_driverType) { // Try with WARP m_dxgi.m_driverType = D3D_DRIVER_TYPE_WARP; continue; } break; } if (FAILED(hr) ) { BX_TRACE("Init error: Unable to create Direct3D11 device."); goto error; } } else { m_device->GetImmediateContext(&m_deviceCtx); if (NULL == m_deviceCtx) { BX_TRACE("Init error: Unable to retrieve Direct3D11 ImmediateContext."); goto error; } m_featureLevel = m_device->GetFeatureLevel(); } m_dxgi.update(m_device); { m_deviceInterfaceVersion = 0; for (uint32_t ii = 0; ii < BX_COUNTOF(s_d3dDeviceIIDs); ++ii) { ID3D11Device* device; HRESULT hr = m_device->QueryInterface(s_d3dDeviceIIDs[ii], (void**)&device); if (SUCCEEDED(hr) ) { device->Release(); // BK - ignore ref count. m_deviceInterfaceVersion = BX_COUNTOF(s_d3dDeviceIIDs)-ii; break; } } { /// IDXGIDevice* renderdoc; HRESULT hr = m_device->QueryInterface(IID_IDXGIDeviceRenderDoc, (void**)&renderdoc); if (SUCCEEDED(hr) ) { setGraphicsDebuggerPresent(true); DX_RELEASE(renderdoc, 2); } else { IUnknown* device = m_device; setGraphicsDebuggerPresent(2 != getRefCount(device) ); } } if (BGFX_PCI_ID_NVIDIA != m_dxgi.m_adapterDesc.VendorId) { m_nvapi.shutdown(); } m_msaaRt = NULL; if (NULL == g_platformData.backBuffer) { HRESULT hr = S_OK; m_swapEffect = #if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS DXGI_SWAP_EFFECT_FLIP_DISCARD #else DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL #endif // BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS ; m_swapBufferCount = bx::clamp<uint8_t>(_init.resolution.numBackBuffers, 2, BGFX_CONFIG_MAX_BACK_BUFFERS); bx::memSet(&m_scd, 0, sizeof(m_scd) ); m_scd.width = _init.resolution.width; m_scd.height = _init.resolution.height; /* * According to https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/converting-data-color-space , * it is OK to create the backbuffer with m_fmt (a non- _SRGB format), and then create the render target view into it * with m_fmtSrgb (the _SRGB format of same), and it will work identically as if you had created the swapchain with * m_fmtSrgb as the backbuffer format. * * Moreover, it is actually not desirable to create the backbuffer with an _SRGB format, because that * is incompatible with the flip presentation model, which is desirable for various reasons including * player embedding. */ m_scd.format = s_textureFormat[_init.resolution.format].m_fmt; updateMsaa(m_scd.format); m_scd.sampleDesc = s_msaa[(_init.resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT]; m_scd.bufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; m_scd.bufferCount = m_swapBufferCount; m_scd.scaling = 0 == g_platformData.ndt ? DXGI_SCALING_NONE : DXGI_SCALING_STRETCH ; m_scd.swapEffect = m_swapEffect; m_scd.alphaMode = (_init.resolution.reset & BGFX_RESET_TRANSPARENT_BACKBUFFER) ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE ; m_scd.flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; 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; if (NULL != m_scd.nwh) { hr = m_dxgi.createSwapChain(m_device , m_scd , &m_swapChain ); if (FAILED(hr) ) { BX_TRACE( "CreateSwapChain with DXGI_SWAP_EFFECT(%d) failed with HRESULT(%x)" , m_scd.swapEffect , hr ); // DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL is not available on win7 // Try again with DXGI_SWAP_EFFECT_DISCARD m_swapEffect = DXGI_SWAP_EFFECT_DISCARD; m_swapBufferCount = 1; m_scd.bufferCount = m_swapBufferCount; m_scd.swapEffect = m_swapEffect; hr = m_dxgi.createSwapChain(m_device , m_scd , &m_swapChain ); if (FAILED(hr) ) { BX_TRACE("Init error: Failed to create swap chain."); goto error; } } m_resolution = _init.resolution; m_resolution.reset = _init.resolution.reset & (~BGFX_RESET_INTERNAL_FORCE); m_textVideoMem.resize(false, _init.resolution.width, _init.resolution.height); m_textVideoMem.clear(); if (1 < m_scd.sampleDesc.Count) { D3D11_TEXTURE2D_DESC desc; desc.Width = m_scd.width; desc.Height = m_scd.height; desc.MipLevels = 1; desc.ArraySize = 1; /* * According to https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/converting-data-color-space , * ONLY the backbuffer from swapchain can be created without *_SRGB format, custom backbuffer should be created the same * format as well as render target view. */ desc.Format = (m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) ? s_textureFormat[m_resolution.format].m_fmtSrgb : s_textureFormat[m_resolution.format].m_fmt; desc.SampleDesc = m_scd.sampleDesc; desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = D3D11_BIND_RENDER_TARGET; desc.CPUAccessFlags = 0; desc.MiscFlags = 0; DX_CHECK(m_device->CreateTexture2D(&desc, NULL, &m_msaaRt) ); } } #if BX_PLATFORM_WINDOWS DX_CHECK(m_dxgi.m_factory->MakeWindowAssociation( (HWND)g_platformData.nwh, 0 | DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER ) ); #endif // BX_PLATFORM_WINDOWS if (FAILED(hr) ) { BX_TRACE("Init error: Failed to create swap chain."); goto error; } } else { bx::memSet(&m_scd, 0, sizeof(m_scd) ); m_scd.sampleDesc.Count = 1; m_scd.sampleDesc.Quality = 0; m_scd.width = _init.resolution.width; m_scd.height = _init.resolution.height; m_backBufferColor = (ID3D11RenderTargetView*)g_platformData.backBuffer; m_backBufferDepthStencil = (ID3D11DepthStencilView*)g_platformData.backBufferDS; } } m_numWindows = 1; #if USE_D3D11_DYNAMIC_LIB if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) ) { HRESULT hr = m_deviceCtx->QueryInterface(IID_ID3DUserDefinedAnnotation, (void**)&m_annotation); if (SUCCEEDED(hr) ) { D3DPERF_BeginEvent = d3d11Annotation_BeginEvent; D3DPERF_EndEvent = d3d11Annotation_EndEvent; D3DPERF_SetMarker = d3d11Annotation_SetMarker; } } #endif // USE_D3D11_DYNAMIC_LIB if (_init.debug) { HRESULT hr = m_device->QueryInterface(IID_ID3D11InfoQueue, (void**)&m_infoQueue); if (SUCCEEDED(hr) ) { m_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true); m_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, false); m_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, false); m_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_INFO, false); m_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_MESSAGE, false); D3D11_INFO_QUEUE_FILTER filter; bx::memSet(&filter, 0, sizeof(filter) ); D3D11_MESSAGE_CATEGORY catlist[] = { D3D11_MESSAGE_CATEGORY_STATE_CREATION, }; filter.DenyList.NumCategories = BX_COUNTOF(catlist); filter.DenyList.pCategoryList = catlist; D3D11_MESSAGE_ID idlist[] = { D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET, D3D11_MESSAGE_ID_QUERY_BEGIN_ABANDONING_PREVIOUS_RESULTS, }; filter.DenyList.NumIDs = BX_COUNTOF(idlist); filter.DenyList.pIDList = idlist; m_infoQueue->PushStorageFilter(&filter); } } { g_caps.supported |= (0 | BGFX_CAPS_TEXTURE_3D | BGFX_CAPS_VERTEX_ATTRIB_HALF | BGFX_CAPS_VERTEX_ATTRIB_UINT10 | BGFX_CAPS_VERTEX_ID | BGFX_CAPS_FRAGMENT_DEPTH | (getIntelExtensions(m_device) ? BGFX_CAPS_FRAGMENT_ORDERING | BGFX_CAPS_TEXTURE_DIRECT_ACCESS : 0) | BGFX_CAPS_SWAP_CHAIN | BGFX_CAPS_DRAW_INDIRECT | BGFX_CAPS_TEXTURE_BLIT | BGFX_CAPS_TEXTURE_READ_BACK | ( (m_featureLevel >= D3D_FEATURE_LEVEL_9_2) ? BGFX_CAPS_OCCLUSION_QUERY : 0) | BGFX_CAPS_ALPHA_TO_COVERAGE | ( (m_deviceInterfaceVersion >= 3) ? BGFX_CAPS_CONSERVATIVE_RASTER : 0) | BGFX_CAPS_TEXTURE_2D_ARRAY | BGFX_CAPS_TEXTURE_CUBE_ARRAY | ((m_featureLevel >= D3D_FEATURE_LEVEL_11_1) ? BGFX_CAPS_IMAGE_RW : 0) ); m_timerQuerySupport = m_featureLevel >= D3D_FEATURE_LEVEL_10_0; m_directAccessSupport = 0 != (g_caps.supported & BGFX_CAPS_TEXTURE_DIRECT_ACCESS); if (m_featureLevel <= D3D_FEATURE_LEVEL_9_2) { g_caps.limits.maxTextureSize = D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; g_caps.limits.maxFBAttachments = uint8_t(bx::uint32_min( D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT , BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS ) ); g_caps.limits.maxVertexStreams = uint8_t(bx::uint32_min( 16 , BGFX_CONFIG_MAX_VERTEX_STREAMS ) ); } else if (m_featureLevel == D3D_FEATURE_LEVEL_9_3) { g_caps.limits.maxTextureSize = D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; g_caps.limits.maxFBAttachments = uint8_t(bx::uint32_min( D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT , BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS ) ); g_caps.limits.maxVertexStreams = uint8_t(bx::uint32_min( 16 , BGFX_CONFIG_MAX_VERTEX_STREAMS ) ); } else { g_caps.limits.maxComputeBindings = bx::min(BGFX_MAX_COMPUTE_BINDINGS , D3D_FEATURE_LEVEL_11_1 <= m_featureLevel ? D3D11_1_UAV_SLOT_COUNT : D3D11_PS_CS_UAV_REGISTER_COUNT ); g_caps.supported |= BGFX_CAPS_TEXTURE_COMPARE_ALL; g_caps.limits.maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; g_caps.limits.maxTextureLayers = D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION; g_caps.limits.maxFBAttachments = uint8_t(bx::uint32_min( D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT , BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS ) ); g_caps.limits.maxVertexStreams = uint8_t(bx::uint32_min( D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT , BGFX_CONFIG_MAX_VERTEX_STREAMS ) ); } // 32-bit indices only supported on 9_2+. if (m_featureLevel >= D3D_FEATURE_LEVEL_9_2) { g_caps.supported |= BGFX_CAPS_INDEX32; } // Independent blend only supported on 10_1+. if (m_featureLevel >= D3D_FEATURE_LEVEL_10_1) { g_caps.supported |= BGFX_CAPS_BLEND_INDEPENDENT; } // Compute support is optional on 10_0 and 10_1 targets. if (m_featureLevel == D3D_FEATURE_LEVEL_10_0 || m_featureLevel == D3D_FEATURE_LEVEL_10_1) { D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS data; HRESULT hr = m_device->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &data, sizeof(data) ); if (SUCCEEDED(hr) && data.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x) { g_caps.supported |= BGFX_CAPS_COMPUTE; } } else if (m_featureLevel >= D3D_FEATURE_LEVEL_11_0) { g_caps.supported |= BGFX_CAPS_COMPUTE; } // Instancing fully supported on 9_3+, optionally partially supported at lower levels. if (m_featureLevel >= D3D_FEATURE_LEVEL_9_3) { g_caps.supported |= BGFX_CAPS_INSTANCING; } else { D3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT data; HRESULT hr = m_device->CheckFeatureSupport(D3D11_FEATURE_D3D9_SIMPLE_INSTANCING_SUPPORT, &data, sizeof(data) ); if (SUCCEEDED(hr) && data.SimpleInstancingSupported) { g_caps.supported |= BGFX_CAPS_INSTANCING; } } // shadow compare is optional on 9_1 through 9_3 targets if (m_featureLevel <= D3D_FEATURE_LEVEL_9_3) { D3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT data; HRESULT hr = m_device->CheckFeatureSupport(D3D11_FEATURE_D3D9_SHADOW_SUPPORT, &data, sizeof(data) ); if (SUCCEEDED(hr) && data.SupportsDepthAsTextureWithLessEqualComparisonFilter) { g_caps.supported |= BGFX_CAPS_TEXTURE_COMPARE_LEQUAL; } } // support for SV_ViewportArrayIndex and SV_RenderTargetArrayIndex in the vertex shader is optional { D3D11_FEATURE_DATA_D3D11_OPTIONS3 data; HRESULT hr = m_device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &data, sizeof(data) ); if (SUCCEEDED(hr) && data.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer) { g_caps.supported |= BGFX_CAPS_VIEWPORT_LAYER_ARRAY; } } for (uint32_t ii = 0; ii < TextureFormat::Count; ++ii) { uint16_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE; const DXGI_FORMAT fmt = bimg::isDepth(bimg::TextureFormat::Enum(ii) ) ? s_textureFormat[ii].m_fmtDsv : s_textureFormat[ii].m_fmt ; const DXGI_FORMAT fmtSrgb = s_textureFormat[ii].m_fmtSrgb; if (DXGI_FORMAT_UNKNOWN != fmt) { if (BX_ENABLED(BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) ) { D3D11_FEATURE_DATA_FORMAT_SUPPORT data; data.InFormat = fmt; HRESULT hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) ); if (SUCCEEDED(hr) ) { support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURE3D | D3D11_FORMAT_SUPPORT_TEXTURECUBE ) ) ? BGFX_CAPS_FORMAT_TEXTURE_2D : BGFX_CAPS_FORMAT_TEXTURE_NONE ; support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT_TEXTURE3D ) ) ? BGFX_CAPS_FORMAT_TEXTURE_3D : BGFX_CAPS_FORMAT_TEXTURE_NONE ; support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT_TEXTURECUBE ) ) ? BGFX_CAPS_FORMAT_TEXTURE_CUBE : BGFX_CAPS_FORMAT_TEXTURE_NONE ; support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT_BUFFER | D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER | D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER ) ) ? BGFX_CAPS_FORMAT_TEXTURE_VERTEX : BGFX_CAPS_FORMAT_TEXTURE_NONE ; support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT_SHADER_LOAD ) ) ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ : BGFX_CAPS_FORMAT_TEXTURE_NONE ; support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_DEPTH_STENCIL ) ) ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER : BGFX_CAPS_FORMAT_TEXTURE_NONE ; support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET ) ) ? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA : BGFX_CAPS_FORMAT_TEXTURE_NONE ; support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD ) ) ? BGFX_CAPS_FORMAT_TEXTURE_MSAA : BGFX_CAPS_FORMAT_TEXTURE_NONE ; support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT_MIP_AUTOGEN ) ) ? BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN : BGFX_CAPS_FORMAT_TEXTURE_NONE ; } else { BX_TRACE( "CheckFeatureSupport failed with HRESULT(%x) for format %s." , hr , getName(TextureFormat::Enum(ii) ) ); } if (0 != (support & BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ) ) { D3D11_FEATURE_DATA_FORMAT_SUPPORT2 data2; // clear image flag for additional testing support &= ~BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ; data2.InFormat = s_textureFormat[ii].m_fmt; hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT2, &data2, sizeof(data2) ); if (SUCCEEDED(hr) ) { support |= 0 != (data2.OutFormatSupport2 & (0 | D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD ) ) ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ : BGFX_CAPS_FORMAT_TEXTURE_NONE ; support |= 0 != (data2.OutFormatSupport2 & (0 | D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE ) ) ? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE : BGFX_CAPS_FORMAT_TEXTURE_NONE ; } } } else { support |= 0 | BGFX_CAPS_FORMAT_TEXTURE_2D | BGFX_CAPS_FORMAT_TEXTURE_3D | BGFX_CAPS_FORMAT_TEXTURE_CUBE | BGFX_CAPS_FORMAT_TEXTURE_VERTEX | BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER | BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA | BGFX_CAPS_FORMAT_TEXTURE_MSAA | BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ | BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE ; } } if (DXGI_FORMAT_UNKNOWN != fmtSrgb) { if (BX_ENABLED(BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) ) { struct D3D11_FEATURE_DATA_FORMAT_SUPPORT { DXGI_FORMAT InFormat; UINT OutFormatSupport; }; D3D11_FEATURE_DATA_FORMAT_SUPPORT data; data.InFormat = fmtSrgb; HRESULT hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) ); if (SUCCEEDED(hr) ) { support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT_TEXTURE2D ) ) ? BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB : BGFX_CAPS_FORMAT_TEXTURE_NONE ; support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT_TEXTURE3D ) ) ? BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB : BGFX_CAPS_FORMAT_TEXTURE_NONE ; support |= 0 != (data.OutFormatSupport & (0 | D3D11_FORMAT_SUPPORT_TEXTURECUBE ) ) ? BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB : BGFX_CAPS_FORMAT_TEXTURE_NONE ; } else { BX_TRACE( "CheckFeatureSupport failed with HRESULT(%x) for sRGB format %s." , hr , getName(TextureFormat::Enum(ii) ) ); } } else { support |= 0 | BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB | BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB | BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB ; } } g_caps.formats[ii] = support; } // Init reserved part of view name. for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii) { bx::snprintf(s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED + 1, "%3d ", ii); mbstowcs(s_viewNameW[ii], s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED); } if (_init.debug && NULL != m_infoQueue) { m_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true); } { // multiDrawInstancedIndirect = stubMultiDrawInstancedIndirect; multiDrawIndexedInstancedIndirect = stubMultiDrawIndexedInstancedIndirect; if (NULL != m_ags) { uint32_t flags; AGS_RETURN_CODE result = agsDriverExtensions_Init(m_ags, m_device, &flags); bool hasExtensions = AGS_SUCCESS == result; if (hasExtensions && 0 != (flags & AGS_EXTENSION_MULTIDRAWINDIRECT) ) { multiDrawInstancedIndirect = amdAgsMultiDrawInstancedIndirect; multiDrawIndexedInstancedIndirect = amdAgsMultiDrawIndexedInstancedIndirect; } else { if (hasExtensions) { agsDriverExtensions_DeInit(m_ags); } agsDeInit(m_ags); m_ags = NULL; } } else if (m_nvapi.isInitialized() && NULL != m_nvapi.nvApiD3D11MultiDrawInstancedIndirect && NULL != m_nvapi.nvApiD3D11MultiDrawIndexedInstancedIndirect) { multiDrawInstancedIndirect = nvapiMultiDrawInstancedIndirect; multiDrawIndexedInstancedIndirect = nvapiMultiDrawIndexedInstancedIndirect; } } // updateMsaa(m_scd.format); postReset(); } m_nvapi.initAftermath(m_device, m_deviceCtx); g_internalData.context = m_device; return true; error: switch (errorState) { case ErrorState::LoadedDXGI: DX_RELEASE(m_annotation, 1); DX_RELEASE_W(m_infoQueue, 0); DX_RELEASE(m_msaaRt, 0); #if BX_PLATFORM_WINRT // Remove swap chain from SwapChainPanel (nwh) if applicable m_dxgi.removeSwapChain(m_scd, &m_swapChain); #endif DX_RELEASE(m_swapChain, 0); DX_RELEASE(m_deviceCtx, 0); DX_RELEASE(m_device, 0); #if USE_D3D11_DYNAMIC_LIB if (NULL != m_d3d9Dll) { bx::dlclose(m_d3d9Dll); m_d3d9Dll = NULL; } #endif // USE_D3D11_DYNAMIC_LIB m_dxgi.shutdown(); BX_FALLTHROUGH; #if USE_D3D11_DYNAMIC_LIB case ErrorState::LoadedD3D11: bx::dlclose(m_d3d11Dll); m_d3d11Dll = NULL; BX_FALLTHROUGH; #endif // USE_D3D11_DYNAMIC_LIB case ErrorState::Default: default: m_nvapi.shutdown(); if (NULL != m_ags) { agsDeInit(m_ags); m_ags = NULL; } bx::dlclose(m_agsDll); m_agsDll = NULL; unloadRenderDoc(m_renderDocDll); break; } return false; } void shutdown() { preReset(); if (NULL != m_ags) { agsDeInit(m_ags); m_ags = NULL; } bx::dlclose(m_agsDll); m_agsDll = NULL; m_deviceCtx->ClearState(); invalidateCache(); for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) { m_frameBuffers[ii].destroy(); } for (uint32_t ii = 0; ii < BX_COUNTOF(m_indexBuffers); ++ii) { m_indexBuffers[ii].destroy(); } for (uint32_t ii = 0; ii < BX_COUNTOF(m_vertexBuffers); ++ii) { m_vertexBuffers[ii].destroy(); } for (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii) { m_shaders[ii].destroy(); } for (uint32_t ii = 0; ii < BX_COUNTOF(m_textures); ++ii) { m_textures[ii].destroy(); } DX_RELEASE(m_annotation, 1); DX_RELEASE_W(m_infoQueue, 0); DX_RELEASE(m_msaaRt, 0); #if BX_PLATFORM_WINRT // Remove swap chain from SwapChainPanel (nwh) if applicable m_dxgi.removeSwapChain(m_scd, &m_swapChain); #endif DX_RELEASE(m_swapChain, 0); DX_RELEASE(m_deviceCtx, 0); DX_RELEASE(m_device, 0); m_nvapi.shutdown(); m_dxgi.shutdown(); unloadRenderDoc(m_renderDocDll); #if USE_D3D11_DYNAMIC_LIB if (NULL != m_d3d9Dll) { bx::dlclose(m_d3d9Dll); m_d3d9Dll = NULL; } bx::dlclose(m_d3d11Dll); m_d3d11Dll = NULL; #endif // USE_D3D11_DYNAMIC_LIB } RendererType::Enum getRendererType() const override { return RendererType::Direct3D11; } const char* getRendererName() const override { return BGFX_RENDERER_DIRECT3D11_NAME; } void createIndexBuffer(IndexBufferHandle _handle, const Memory* _mem, uint16_t _flags) override { m_indexBuffers[_handle.idx].create(_mem->size, _mem->data, _flags); } void destroyIndexBuffer(IndexBufferHandle _handle) override { m_indexBuffers[_handle.idx].destroy(); } void createVertexLayout(VertexLayoutHandle _handle, const VertexLayout& _layout) override { VertexLayout& layout = m_vertexLayouts[_handle.idx]; bx::memCopy(&layout, &_layout, sizeof(VertexLayout) ); dump(layout); } void destroyVertexLayout(VertexLayoutHandle /*_handle*/) override { } void createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexLayoutHandle _layoutHandle, uint16_t _flags) override { m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _layoutHandle, _flags); } void destroyVertexBuffer(VertexBufferHandle _handle) override { m_vertexBuffers[_handle.idx].destroy(); } void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { m_indexBuffers[_handle.idx].create(_size, NULL, _flags); } void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override { m_indexBuffers[_handle.idx].update(_offset, bx::uint32_min(_size, _mem->size), _mem->data); } void destroyDynamicIndexBuffer(IndexBufferHandle _handle) override { m_indexBuffers[_handle.idx].destroy(); } void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { 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 { m_vertexBuffers[_handle.idx].update(_offset, bx::uint32_min(_size, _mem->size), _mem->data); } void destroyDynamicVertexBuffer(VertexBufferHandle _handle) override { m_vertexBuffers[_handle.idx].destroy(); } void createShader(ShaderHandle _handle, const Memory* _mem) override { m_shaders[_handle.idx].create(_mem); } void destroyShader(ShaderHandle _handle) override { m_shaders[_handle.idx].destroy(); } void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) override { m_program[_handle.idx].create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL); } void destroyProgram(ProgramHandle _handle) override { m_program[_handle.idx].destroy(); } void* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip) override { return m_textures[_handle.idx].create(_mem, _flags, _skip); } void updateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/) override { } void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) override { m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _pitch, _mem); } void updateTextureEnd() override { } void readTexture(TextureHandle _handle, void* _data, uint8_t _mip) override { const TextureD3D11& texture = m_textures[_handle.idx]; D3D11_MAPPED_SUBRESOURCE mapped; DX_CHECK(m_deviceCtx->Map(texture.m_ptr, _mip, D3D11_MAP_READ, 0, &mapped) ); 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 = (uint8_t*)mapped.pData; uint32_t srcPitch = mapped.RowPitch; 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(srcPitch, dstPitch); for (uint32_t yy = 0, height = srcHeight; yy < height; ++yy) { bx::memCopy(dst, src, pitch); src += srcPitch; dst += dstPitch; } m_deviceCtx->Unmap(texture.m_ptr, _mip); } void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips, uint16_t _numLayers) override { TextureD3D11& texture = m_textures[_handle.idx]; uint32_t size = sizeof(uint32_t) + sizeof(TextureCreate); const Memory* mem = alloc(size); bx::StaticMemoryBlockWriter writer(mem->data, mem->size); uint32_t magic = BGFX_CHUNK_MAGIC_TEX; bx::write(&writer, magic, bx::ErrorAssert{}); TextureCreate tc; tc.m_width = _width; tc.m_height = _height; tc.m_depth = 0; tc.m_numLayers = _numLayers; tc.m_numMips = _numMips; tc.m_format = TextureFormat::Enum(texture.m_requestedFormat); tc.m_cubeMap = false; tc.m_mem = NULL; bx::write(&writer, tc, bx::ErrorAssert{}); texture.destroy(); texture.create(mem, texture.m_flags, 0); release(mem); } void overrideInternal(TextureHandle _handle, uintptr_t _ptr) override { // 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 { // Resource ref. counts might be messed up outside of bgfx. // Disabling ref. count check once texture is overridden. setGraphicsDebuggerPresent(true); return uintptr_t(m_textures[_handle.idx].m_ptr); } void destroyTexture(TextureHandle _handle) override { m_textures[_handle.idx].destroy(); } void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const Attachment* _attachment) override { m_frameBuffers[_handle.idx].create(_num, _attachment); } void createFrameBuffer(FrameBufferHandle _handle, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _format, TextureFormat::Enum _depthFormat) override { for (uint32_t ii = 0, num = m_numWindows; ii < num; ++ii) { FrameBufferHandle handle = m_windows[ii]; if (isValid(handle) && m_frameBuffers[handle.idx].m_nwh == _nwh) { destroyFrameBuffer(handle); } } uint16_t denseIdx = m_numWindows++; m_windows[denseIdx] = _handle; m_frameBuffers[_handle.idx].create(denseIdx, _nwh, _width, _height, _format, _depthFormat); } void destroyFrameBuffer(FrameBufferHandle _handle) override { uint16_t denseIdx = m_frameBuffers[_handle.idx].destroy(); if (UINT16_MAX != denseIdx) { --m_numWindows; if (m_numWindows > 1) { FrameBufferHandle handle = m_windows[m_numWindows]; m_windows[m_numWindows] = {kInvalidHandle}; if (m_numWindows != denseIdx) { m_windows[denseIdx] = handle; m_frameBuffers[handle.idx].m_denseIdx = denseIdx; } } } } void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) override { if (NULL != m_uniforms[_handle.idx]) { BX_FREE(g_allocator, m_uniforms[_handle.idx]); } 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; m_uniformReg.add(_handle, _name); } void destroyUniform(UniformHandle _handle) override { BX_FREE(g_allocator, m_uniforms[_handle.idx]); m_uniforms[_handle.idx] = NULL; m_uniformReg.remove(_handle); } void requestScreenShot(FrameBufferHandle _handle, const char* _filePath) override { IDXGISwapChain* swapChain = isValid(_handle) ? m_frameBuffers[_handle.idx].m_swapChain : m_swapChain ; if (NULL == swapChain) { BX_TRACE("Unable to capture screenshot %s.", _filePath); return; } ID3D11Texture2D* backBuffer; DX_CHECK(swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer) ); D3D11_TEXTURE2D_DESC backBufferDesc; backBuffer->GetDesc(&backBufferDesc); D3D11_TEXTURE2D_DESC desc; bx::memCopy(&desc, &backBufferDesc, sizeof(desc) ); desc.SampleDesc.Count = 1; desc.SampleDesc.Quality = 0; desc.Usage = D3D11_USAGE_STAGING; desc.BindFlags = 0; desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; ID3D11Texture2D* texture; HRESULT hr = m_device->CreateTexture2D(&desc, NULL, &texture); if (SUCCEEDED(hr) ) { if (backBufferDesc.SampleDesc.Count == 1) { m_deviceCtx->CopyResource(texture, backBuffer); } else { desc.Usage = D3D11_USAGE_DEFAULT; desc.CPUAccessFlags = 0; ID3D11Texture2D* resolve; hr = m_device->CreateTexture2D(&desc, NULL, &resolve); if (SUCCEEDED(hr) ) { m_deviceCtx->ResolveSubresource(resolve, 0, backBuffer, 0, desc.Format); m_deviceCtx->CopyResource(texture, resolve); DX_RELEASE(resolve, 0); } } D3D11_MAPPED_SUBRESOURCE mapped; DX_CHECK(m_deviceCtx->Map(texture, 0, D3D11_MAP_READ, 0, &mapped) ); bimg::imageSwizzleBgra8( mapped.pData , mapped.RowPitch , backBufferDesc.Width , backBufferDesc.Height , mapped.pData , mapped.RowPitch ); g_callback->screenShot(_filePath , backBufferDesc.Width , backBufferDesc.Height , mapped.RowPitch , mapped.pData , backBufferDesc.Height*mapped.RowPitch , false ); m_deviceCtx->Unmap(texture, 0); DX_RELEASE(texture, 0); } DX_RELEASE(backBuffer, 0); } void updateViewName(ViewId _id, const char* _name) override { if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) ) { mbstowcs(&s_viewNameW[_id][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED] , _name , BX_COUNTOF(s_viewNameW[0])-BGFX_CONFIG_MAX_VIEW_NAME_RESERVED ); } bx::strCopy(&s_viewName[_id][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED] , BX_COUNTOF(s_viewName[0]) - BGFX_CONFIG_MAX_VIEW_NAME_RESERVED , _name ); } void updateUniform(uint16_t _loc, const void* _data, uint32_t _size) override { bx::memCopy(m_uniforms[_loc], _data, _size); } void invalidateOcclusionQuery(OcclusionQueryHandle _handle) override { m_occlusionQuery.invalidate(_handle); } void setMarker(const char* _marker, uint16_t _len) override { if (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) ) { uint32_t size = _len*sizeof(wchar_t); wchar_t* name = (wchar_t*)alloca(size+2); name[_len] = L'\0'; mbstowcs(name, _marker, _len); PIX_SETMARKER(kColorMarker, name); } } 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", _len, _name); break; case Handle::Texture: 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_ASSERT(false, "Invalid handle type?! %d", _handle.type); break; } } void submitBlit(BlitState& _bs, uint16_t _view); void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) override; void blitSetup(TextVideoMemBlitter& _blitter) override { ID3D11DeviceContext* deviceCtx = m_deviceCtx; const uint32_t width = m_scd.width; const uint32_t height = m_scd.height; setFrameBuffer(BGFX_INVALID_HANDLE, false, false); D3D11_VIEWPORT vp; vp.TopLeftX = 0; vp.TopLeftY = 0; vp.Width = (float)width; vp.Height = (float)height; vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; deviceCtx->RSSetViewports(1, &vp); uint64_t state = BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A | BGFX_STATE_DEPTH_TEST_ALWAYS ; setBlendState(state); setDepthStencilState(state); setRasterizerState(state); ProgramD3D11& program = m_program[_blitter.m_program.idx]; m_currentProgram = &program; deviceCtx->VSSetShader(program.m_vsh->m_vertexShader, NULL, 0); deviceCtx->VSSetConstantBuffers(0, 1, &program.m_vsh->m_buffer); deviceCtx->PSSetShader(program.m_fsh->m_pixelShader, NULL, 0); deviceCtx->PSSetConstantBuffers(0, 1, &program.m_fsh->m_buffer); VertexBufferD3D11& vb = m_vertexBuffers[_blitter.m_vb->handle.idx]; VertexLayout& layout = m_vertexLayouts[_blitter.m_vb->layoutHandle.idx]; uint32_t stride = layout.m_stride; uint32_t offset = 0; deviceCtx->IASetVertexBuffers(0, 1, &vb.m_ptr, &stride, &offset); setInputLayout(layout, program, 0); IndexBufferD3D11& ib = m_indexBuffers[_blitter.m_ib->handle.idx]; deviceCtx->IASetIndexBuffer(ib.m_ptr, DXGI_FORMAT_R16_UINT, 0); float proj[16]; bx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f, 0.0f, false); PredefinedUniform& predefined = program.m_predefined[0]; uint8_t flags = predefined.m_type; setShaderUniform(flags, predefined.m_loc, proj, 4); commitShaderConstants(); m_textures[_blitter.m_texture.idx].commit(0, BGFX_SAMPLER_INTERNAL_DEFAULT, NULL); commitTextureStage(); } void blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) override { const uint32_t numVertices = _numIndices*4/6; if (0 < numVertices) { ID3D11DeviceContext* deviceCtx = m_deviceCtx; m_indexBuffers [_blitter.m_ib->handle.idx].update(0, _numIndices*2, _blitter.m_ib->data, true); m_vertexBuffers[_blitter.m_vb->handle.idx].update(0, numVertices*_blitter.m_layout.m_stride, _blitter.m_vb->data, true); deviceCtx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); deviceCtx->DrawIndexed(_numIndices, 0, 0); } } void preReset() { m_needPresent = false; if (m_timerQuerySupport) { m_gpuTimer.preReset(); } m_occlusionQuery.preReset(); if (NULL == g_platformData.backBufferDS) { DX_RELEASE(m_backBufferDepthStencil, 0); } if (NULL != m_swapChain) { DX_RELEASE(m_backBufferColor, 0); } for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) { m_frameBuffers[ii].preReset(); } // invalidateCache(); capturePreReset(); } void postReset() { if (NULL != m_swapChain) { ID3D11Texture2D* backBufferColor = NULL; if (NULL == m_msaaRt) { DX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBufferColor) ); } D3D11_RENDER_TARGET_VIEW_DESC desc; desc.ViewDimension = (m_resolution.reset & BGFX_RESET_MSAA_MASK) ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D ; desc.Texture2D.MipSlice = 0; /* go find the srgb version of this format to make a render target view * with the srgb version. this is OK because of this: * https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/converting-data-color-space */ desc.Format = (m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) ? s_textureFormat[m_resolution.format].m_fmtSrgb : s_textureFormat[m_resolution.format].m_fmt; DX_CHECK(m_device->CreateRenderTargetView(NULL == m_msaaRt ? backBufferColor : m_msaaRt, &desc, &m_backBufferColor) ); DX_RELEASE(backBufferColor, 0); } if (m_timerQuerySupport) { m_gpuTimer.postReset(); } m_occlusionQuery.postReset(); if (NULL == m_backBufferDepthStencil) { D3D11_TEXTURE2D_DESC dsd; dsd.Width = m_scd.width; dsd.Height = m_scd.height; dsd.MipLevels = 1; dsd.ArraySize = 1; dsd.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; dsd.SampleDesc = m_scd.sampleDesc; dsd.Usage = D3D11_USAGE_DEFAULT; dsd.BindFlags = D3D11_BIND_DEPTH_STENCIL; dsd.CPUAccessFlags = 0; dsd.MiscFlags = 0; ID3D11Texture2D* depthStencil; DX_CHECK(m_device->CreateTexture2D(&dsd, NULL, &depthStencil) ); DX_CHECK(m_device->CreateDepthStencilView(depthStencil, NULL, &m_backBufferDepthStencil) ); DX_RELEASE(depthStencil, 0); } m_deviceCtx->OMSetRenderTargets(1, &m_backBufferColor, m_backBufferDepthStencil); m_currentColor = m_backBufferColor; m_currentDepthStencil = m_backBufferDepthStencil; for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) { m_frameBuffers[ii].postReset(); } capturePostReset(); } bool isDeviceRemoved() override { return m_lost; } void flip() override { if (!m_lost) { HRESULT hr = S_OK; uint32_t syncInterval = BX_ENABLED(!BX_PLATFORM_WINDOWS) ? 1 // sync interval of 0 is not supported on WinRT : !!(m_resolution.reset & BGFX_RESET_VSYNC) ; for (uint32_t ii = 1, num = m_numWindows; ii < num && SUCCEEDED(hr); ++ii) { hr = m_frameBuffers[m_windows[ii].idx].present(syncInterval); } if (SUCCEEDED(hr) ) { if (NULL != m_swapChain && m_needPresent) { uint32_t presentFlags = 0; if (!syncInterval && m_dxgi.tearingSupported() ) { presentFlags |= DXGI_PRESENT_ALLOW_TEARING; } hr = m_swapChain->Present(syncInterval, presentFlags); m_needPresent = false; } else { m_deviceCtx->Flush(); } } m_lost = isLost(hr); BGFX_FATAL( !m_lost , bgfx::Fatal::DeviceLost , "Device is lost. FAILED HRESULT(%x) %s (%s)" , hr , getLostReason(hr) , DXGI_ERROR_DEVICE_REMOVED == hr ? getLostReason(m_device->GetDeviceRemovedReason() ) : "no info" ); } } void invalidateCache() { m_inputLayoutCache.invalidate(); m_blendStateCache.invalidate(); m_depthStencilStateCache.invalidate(); m_rasterizerStateCache.invalidate(); m_samplerStateCache.invalidate(); m_srvUavLru.invalidate(); } void invalidateCompute() { const uint32_t maxComputeBindings = g_caps.limits.maxComputeBindings; const uint32_t maxTextureSamplers = g_caps.limits.maxTextureSamplers; m_deviceCtx->CSSetShader(NULL, NULL, 0); m_deviceCtx->CSSetUnorderedAccessViews(0, maxComputeBindings, s_zero.m_uav, NULL); m_deviceCtx->CSSetShaderResources(0, maxTextureSamplers, s_zero.m_srv); m_deviceCtx->CSSetSamplers(0, maxTextureSamplers, s_zero.m_sampler); } void updateMsaa(DXGI_FORMAT _format) const { for (uint32_t ii = 1, last = 0; ii < BX_COUNTOF(s_msaa); ++ii) { uint32_t msaa = s_checkMsaa[ii]; uint32_t quality = 0; HRESULT hr = m_device->CheckMultisampleQualityLevels(_format, msaa, &quality); if (SUCCEEDED(hr) && 0 < quality) { s_msaa[ii].Count = msaa; s_msaa[ii].Quality = quality - 1; last = ii; } else { s_msaa[ii] = s_msaa[last]; } } } void updateNativeWindow() { #if BX_PLATFORM_WINRT // SwapChainPanels can be dynamically updated if (m_scd.ndt == reinterpret_cast<void*>(2) && (m_scd.nwh != g_platformData.nwh || m_scd.ndt != g_platformData.ndt)) { // Remove swap chain from SwapChainPanel (nwh) if applicable m_dxgi.removeSwapChain(m_scd, &m_swapChain); // Update nwh after removing swap chain m_scd.nwh = g_platformData.nwh; m_scd.ndt = g_platformData.ndt; } #endif } bool updateResolution(const Resolution& _resolution) { const bool suspended = !!( _resolution.reset & BGFX_RESET_SUSPEND); const bool wasSuspended = !!(m_resolution.reset & BGFX_RESET_SUSPEND); if (suspended && wasSuspended) { return true; } else if (suspended) { m_deviceCtx->Flush(); m_deviceCtx->ClearState(); m_dxgi.trim(); suspend(m_device); m_resolution.reset |= BGFX_RESET_SUSPEND; return true; } else if (wasSuspended) { resume(m_device); m_resolution.reset &= ~BGFX_RESET_SUSPEND; } uint32_t maxAnisotropy = 1; if (!!(_resolution.reset & BGFX_RESET_MAXANISOTROPY) ) { maxAnisotropy = (m_featureLevel == D3D_FEATURE_LEVEL_9_1) ? D3D_FL9_1_DEFAULT_MAX_ANISOTROPY : D3D11_REQ_MAXANISOTROPY ; } if (m_maxAnisotropy != maxAnisotropy) { m_maxAnisotropy = maxAnisotropy; m_samplerStateCache.invalidate(); } bool depthClamp = true && !!(_resolution.reset & BGFX_RESET_DEPTH_CLAMP) && m_featureLevel > D3D_FEATURE_LEVEL_9_3 // disabling depth clamp is only supported on 10_0+ ; if (m_depthClamp != depthClamp) { m_depthClamp = depthClamp; m_rasterizerStateCache.invalidate(); } const uint32_t maskFlags = ~(0 | BGFX_RESET_MAXANISOTROPY | BGFX_RESET_DEPTH_CLAMP | BGFX_RESET_SUSPEND void* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS]; Matrix4 m_predefinedUniforms[PredefinedUniform::Count]; UniformRegistry m_uniformReg; StateCacheT<ID3D11BlendState> m_blendStateCache; StateCacheT<ID3D11DepthStencilState> m_depthStencilStateCache; uint32_t flags = _resolution.reset & (~BGFX_RESET_INTERNAL_FORCE); bool resize = true && !BX_ENABLED(BX_PLATFORM_XBOXONE) && (m_resolution.reset&BGFX_RESET_MSAA_MASK) == (flags&BGFX_RESET_MSAA_MASK) ; m_resolution = _resolution; m_resolution.reset = flags; m_textVideoMem.resize(false, _resolution.width, _resolution.height); m_textVideoMem.clear(); m_scd.width = _resolution.width; m_scd.height = _resolution.height; // see comment in init() about why we don't worry about BGFX_RESET_SRGB_BACKBUFFER here m_scd.format = s_textureFormat[_resolution.format].m_fmt ; preReset(); m_deviceCtx->Flush(); m_deviceCtx->ClearState(); if (NULL == m_swapChain) { // Updated backbuffer if it changed in PlatformData. m_backBufferColor = (ID3D11RenderTargetView*)g_platformData.backBuffer; m_backBufferDepthStencil = (ID3D11DepthStencilView*)g_platformData.backBufferDS; } else { DX_RELEASE(m_msaaRt, 0); if (resize) { m_deviceCtx->OMSetRenderTargets(1, s_zero.m_rtv, NULL); DX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd) ); } else { updateMsaa(m_scd.format); m_scd.sampleDesc = s_msaa[(m_resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT]; #if BX_PLATFORM_WINRT // Remove swap chain from SwapChainPanel (nwh) if applicable m_dxgi.removeSwapChain(m_scd, &m_swapChain); #endif DX_RELEASE(m_swapChain, 0); HRESULT hr = m_dxgi.createSwapChain(m_device , m_scd , &m_swapChain ); BGFX_FATAL(SUCCEEDED(hr), bgfx::Fatal::UnableToInitialize, "Failed to create swap chain."); } if (1 < m_scd.sampleDesc.Count) { D3D11_TEXTURE2D_DESC desc; desc.Width = m_scd.width; desc.Height = m_scd.height; desc.MipLevels = 1; desc.ArraySize = 1; desc.Format = (m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) ? s_textureFormat[m_resolution.format].m_fmtSrgb : s_textureFormat[m_resolution.format].m_fmt; desc.SampleDesc = m_scd.sampleDesc; desc.Usage = D3D11_USAGE_DEFAULT; desc.BindFlags = D3D11_BIND_RENDER_TARGET; desc.CPUAccessFlags = 0; desc.MiscFlags = 0; DX_CHECK(m_device->CreateTexture2D(&desc, NULL, &m_msaaRt) ); } } postReset(); } return false; } void setShaderUniform(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs) { 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; } } void setShaderUniform4f(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs) { setShaderUniform(_flags, _regIndex, _val, _numRegs); } void setShaderUniform4x4f(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs) { setShaderUniform(_flags, _regIndex, _val, _numRegs); } void commitShaderConstants() { if (0 < m_vsChanges) { if (NULL != m_currentProgram->m_vsh->m_buffer) { m_deviceCtx->UpdateSubresource(m_currentProgram->m_vsh->m_buffer, 0, 0, m_vsScratch, 0, 0); } m_vsChanges = 0; } if (0 < m_fsChanges) { if (NULL != m_currentProgram->m_fsh->m_buffer) { m_deviceCtx->UpdateSubresource(m_currentProgram->m_fsh->m_buffer, 0, 0, m_fsScratch, 0, 0); } m_fsChanges = 0; } } void setFrameBuffer(FrameBufferHandle _fbh, bool _msaa = true, bool _needPresent = true) { if (isValid(m_fbh) && m_fbh.idx != _fbh.idx && m_rtMsaa) { FrameBufferD3D11& frameBuffer = m_frameBuffers[m_fbh.idx]; frameBuffer.resolve(); } if (!isValid(_fbh) ) { m_currentColor = m_backBufferColor; m_currentDepthStencil = m_backBufferDepthStencil; m_deviceCtx->OMSetRenderTargetsAndUnorderedAccessViews( 1 , &m_currentColor , m_currentDepthStencil , 1 , 0 , NULL , NULL ); m_needPresent |= _needPresent; } else { invalidateTextureStage(); FrameBufferD3D11& frameBuffer = m_frameBuffers[_fbh.idx]; frameBuffer.set(); } m_fbh = _fbh; m_rtMsaa = _msaa; } void clear(const Clear& _clear, const float _palette[][4]) { if (isValid(m_fbh) ) { FrameBufferD3D11& frameBuffer = m_frameBuffers[m_fbh.idx]; frameBuffer.clear(_clear, _palette); } else { if (NULL != m_currentColor && BGFX_CLEAR_COLOR & _clear.m_flags) { if (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags) { uint8_t index = _clear.m_index[0]; if (UINT8_MAX != index) { m_deviceCtx->ClearRenderTargetView(m_currentColor, _palette[index]); } } else { float frgba[4] = { _clear.m_index[0]*1.0f/255.0f, _clear.m_index[1]*1.0f/255.0f, _clear.m_index[2]*1.0f/255.0f, _clear.m_index[3]*1.0f/255.0f, }; m_deviceCtx->ClearRenderTargetView(m_currentColor, frgba); } } if (NULL != m_currentDepthStencil && (BGFX_CLEAR_DEPTH|BGFX_CLEAR_STENCIL) & _clear.m_flags) { DWORD flags = 0; flags |= (_clear.m_flags & BGFX_CLEAR_DEPTH) ? D3D11_CLEAR_DEPTH : 0; flags |= (_clear.m_flags & BGFX_CLEAR_STENCIL) ? D3D11_CLEAR_STENCIL : 0; m_deviceCtx->ClearDepthStencilView(m_currentDepthStencil, flags, _clear.m_depth, _clear.m_stencil); } } } void setInputLayout(uint8_t _numStreams, const VertexLayout** _layouts, const ProgramD3D11& _program, uint16_t _numInstanceData) { bx::HashMurmur2A murmur; murmur.begin(); murmur.add(_numInstanceData); for (uint8_t stream = 0; stream < _numStreams; ++stream) { murmur.add(_layouts[stream]->m_hash); } uint64_t layoutHash = (uint64_t(_program.m_vsh->m_hash)<<32) | murmur.end(); ID3D11InputLayout* inputLayout = m_inputLayoutCache.find(layoutHash); if (NULL == inputLayout) { D3D11_INPUT_ELEMENT_DESC vertexElements[Attrib::Count+1+BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT]; D3D11_INPUT_ELEMENT_DESC* elem = vertexElements; uint16_t attrMask[Attrib::Count]; bx::memCopy(attrMask, _program.m_vsh->m_attrMask, sizeof(attrMask) ); for (uint8_t stream = 0; stream < _numStreams; ++stream) { 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 = (layout.m_attributes[ii] & mask); if (0 == attr || UINT16_MAX == attr) { layout.m_attributes[ii] = last ? ~attr : UINT16_MAX; } else { attrMask[ii] = 0; } } elem = fillVertexLayout(stream, elem, layout); } uint32_t num = uint32_t(elem-vertexElements); const D3D11_INPUT_ELEMENT_DESC inst = { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1 }; for (uint32_t ii = 0; ii < _numInstanceData; ++ii) { uint32_t index = 7-ii; // TEXCOORD7 = i_data0, TEXCOORD6 = i_data1, etc. uint32_t jj; D3D11_INPUT_ELEMENT_DESC* curr = vertexElements; for (jj = 0; jj < num; ++jj) { curr = &vertexElements[jj]; if (0 == bx::strCmp(curr->SemanticName, "TEXCOORD") && curr->SemanticIndex == index) { break; } } if (jj == num) { curr = elem; ++elem; } bx::memCopy(curr, &inst, sizeof(D3D11_INPUT_ELEMENT_DESC) ); curr->InputSlot = _numStreams; curr->SemanticIndex = index; curr->AlignedByteOffset = ii*16; } num = uint32_t(elem-vertexElements); DX_CHECK(m_device->CreateInputLayout(vertexElements , num , _program.m_vsh->m_code->data , _program.m_vsh->m_code->size , &inputLayout ) ); m_inputLayoutCache.add(layoutHash, inputLayout); } m_deviceCtx->IASetInputLayout(inputLayout); } void setInputLayout(const VertexLayout& _layout, const ProgramD3D11& _program, uint16_t _numInstanceData) { const VertexLayout* layouts[1] = { &_layout }; setInputLayout(BX_COUNTOF(layouts), layouts, _program, _numInstanceData); } void setBlendState(uint64_t _state, uint32_t _rgba = 0) { _state &= BGFX_D3D11_BLEND_STATE_MASK; bx::HashMurmur2A murmur; murmur.begin(); murmur.add(_state); murmur.add(!!(BGFX_STATE_BLEND_INDEPENDENT & _state) ? _rgba : -1 ); const uint32_t hash = murmur.end(); ID3D11BlendState* bs = m_blendStateCache.find(hash); if (NULL == bs) { D3D11_BLEND_DESC desc; desc.AlphaToCoverageEnable = !!(BGFX_STATE_BLEND_ALPHA_TO_COVERAGE & _state); desc.IndependentBlendEnable = !!(BGFX_STATE_BLEND_INDEPENDENT & _state); D3D11_RENDER_TARGET_BLEND_DESC* drt = &desc.RenderTarget[0]; drt->BlendEnable = !!(BGFX_STATE_BLEND_MASK & _state); const uint32_t blend = uint32_t( (_state&BGFX_STATE_BLEND_MASK )>>BGFX_STATE_BLEND_SHIFT); const uint32_t equation = uint32_t( (_state&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT); const uint32_t srcRGB = (blend ) & 0xf; const uint32_t dstRGB = (blend >> 4) & 0xf; const uint32_t srcA = (blend >> 8) & 0xf; const uint32_t dstA = (blend >> 12) & 0xf; const uint32_t equRGB = (equation ) & 0x7; const uint32_t equA = (equation >> 3) & 0x7; drt->SrcBlend = s_blendFactor[srcRGB][0]; drt->DestBlend = s_blendFactor[dstRGB][0]; drt->BlendOp = s_blendEquation[equRGB]; drt->SrcBlendAlpha = s_blendFactor[srcA][1]; drt->DestBlendAlpha = s_blendFactor[dstA][1]; drt->BlendOpAlpha = s_blendEquation[equA]; uint8_t writeMask = 0; writeMask |= (_state&BGFX_STATE_WRITE_R) ? D3D11_COLOR_WRITE_ENABLE_RED : 0; writeMask |= (_state&BGFX_STATE_WRITE_G) ? D3D11_COLOR_WRITE_ENABLE_GREEN : 0; writeMask |= (_state&BGFX_STATE_WRITE_B) ? D3D11_COLOR_WRITE_ENABLE_BLUE : 0; writeMask |= (_state&BGFX_STATE_WRITE_A) ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0; drt->RenderTargetWriteMask = writeMask; if (desc.IndependentBlendEnable) { for (uint32_t ii = 1, rgba = _rgba; ii < BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS; ++ii, rgba >>= 11) { drt = &desc.RenderTarget[ii]; drt->BlendEnable = 0 != (rgba & 0x7ff); const uint32_t src = (rgba ) & 0xf; const uint32_t dst = (rgba >> 4) & 0xf; const uint32_t equ = (rgba >> 8) & 0x7; drt->SrcBlend = s_blendFactor[src][0]; drt->DestBlend = s_blendFactor[dst][0]; drt->BlendOp = s_blendEquation[equ]; drt->SrcBlendAlpha = s_blendFactor[src][1]; drt->DestBlendAlpha = s_blendFactor[dst][1]; drt->BlendOpAlpha = s_blendEquation[equ]; drt->RenderTargetWriteMask = writeMask; } } else { for (uint32_t ii = 1; ii < BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS; ++ii) { bx::memCopy(&desc.RenderTarget[ii], drt, sizeof(D3D11_RENDER_TARGET_BLEND_DESC) ); } } DX_CHECK(m_device->CreateBlendState(&desc, &bs) ); m_blendStateCache.add(hash, bs); } const uint64_t f0 = BGFX_STATE_BLEND_FACTOR; const uint64_t f1 = BGFX_STATE_BLEND_INV_FACTOR; const uint64_t f2 = BGFX_STATE_BLEND_FACTOR<<4; const uint64_t f3 = BGFX_STATE_BLEND_INV_FACTOR<<4; bool hasFactor = 0 || f0 == (_state & f0) || f1 == (_state & f1) || f2 == (_state & f2) || f3 == (_state & f3) ; float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; if (hasFactor) { blendFactor[0] = ( (_rgba>>24) )/255.0f; blendFactor[1] = ( (_rgba>>16)&0xff)/255.0f; blendFactor[2] = ( (_rgba>> 8)&0xff)/255.0f; blendFactor[3] = ( (_rgba )&0xff)/255.0f; } m_deviceCtx->OMSetBlendState(bs, blendFactor, 0xffffffff); } void setDepthStencilState(uint64_t _state, uint64_t _stencil = 0) { uint32_t func = (_state&BGFX_STATE_DEPTH_TEST_MASK)>>BGFX_STATE_DEPTH_TEST_SHIFT; _state &= 0 == func ? 0 : BGFX_D3D11_DEPTH_STENCIL_MASK; uint32_t fstencil = unpackStencil(0, _stencil); uint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT; _stencil &= packStencil(~BGFX_STENCIL_FUNC_REF_MASK, ~BGFX_STENCIL_FUNC_REF_MASK); bx::HashMurmur2A murmur; murmur.begin(); murmur.add(_state); murmur.add(_stencil); uint32_t hash = murmur.end(); ID3D11DepthStencilState* dss = m_depthStencilStateCache.find(hash); if (NULL == dss) { D3D11_DEPTH_STENCIL_DESC desc; bx::memSet(&desc, 0, sizeof(desc) ); desc.DepthEnable = 0 != func; desc.DepthWriteMask = !!(BGFX_STATE_WRITE_Z & _state) ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; desc.DepthFunc = s_cmpFunc[func]; uint32_t bstencil = unpackStencil(1, _stencil); uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil; bstencil = frontAndBack ? bstencil : fstencil; desc.StencilEnable = 0 != _stencil; desc.StencilReadMask = (fstencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT; desc.StencilWriteMask = 0xff; desc.FrontFace.StencilFailOp = s_stencilOp[(fstencil&BGFX_STENCIL_OP_FAIL_S_MASK)>>BGFX_STENCIL_OP_FAIL_S_SHIFT]; desc.FrontFace.StencilDepthFailOp = s_stencilOp[(fstencil&BGFX_STENCIL_OP_FAIL_Z_MASK)>>BGFX_STENCIL_OP_FAIL_Z_SHIFT]; desc.FrontFace.StencilPassOp = s_stencilOp[(fstencil&BGFX_STENCIL_OP_PASS_Z_MASK)>>BGFX_STENCIL_OP_PASS_Z_SHIFT]; desc.FrontFace.StencilFunc = s_cmpFunc[(fstencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT]; desc.BackFace.StencilFailOp = s_stencilOp[(bstencil&BGFX_STENCIL_OP_FAIL_S_MASK)>>BGFX_STENCIL_OP_FAIL_S_SHIFT]; desc.BackFace.StencilDepthFailOp = s_stencilOp[(bstencil&BGFX_STENCIL_OP_FAIL_Z_MASK)>>BGFX_STENCIL_OP_FAIL_Z_SHIFT]; desc.BackFace.StencilPassOp = s_stencilOp[(bstencil&BGFX_STENCIL_OP_PASS_Z_MASK)>>BGFX_STENCIL_OP_PASS_Z_SHIFT]; desc.BackFace.StencilFunc = s_cmpFunc[(bstencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT]; DX_CHECK(m_device->CreateDepthStencilState(&desc, &dss) ); m_depthStencilStateCache.add(hash, dss); } m_deviceCtx->OMSetDepthStencilState(dss, ref); } void setDebugWireframe(bool _wireframe) { if (m_wireframe != _wireframe) { m_wireframe = _wireframe; m_rasterizerStateCache.invalidate(); } } void setRasterizerState(uint64_t _state, bool _wireframe = false, bool _scissor = false) { _state &= 0 | BGFX_STATE_CULL_MASK | BGFX_STATE_FRONT_CCW | BGFX_STATE_MSAA | BGFX_STATE_LINEAA | BGFX_STATE_CONSERVATIVE_RASTER ; _state |= _wireframe ? BGFX_STATE_PT_LINES : BGFX_STATE_NONE; _state |= _scissor ? BGFX_STATE_RESERVED_MASK : 0; _state &= ~(m_deviceInterfaceVersion >= 3 ? 0 : BGFX_STATE_CONSERVATIVE_RASTER); ID3D11RasterizerState* rs = m_rasterizerStateCache.find(_state); if (NULL == rs) { uint32_t cull = (_state&BGFX_STATE_CULL_MASK)>>BGFX_STATE_CULL_SHIFT; #if BX_PLATFORM_WINDOWS if (m_deviceInterfaceVersion >= 3) { D3D11_RASTERIZER_DESC2 desc; desc.FillMode = _wireframe ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID; desc.CullMode = s_cullMode[cull]; desc.FrontCounterClockwise = !!(_state&BGFX_STATE_FRONT_CCW); desc.DepthBias = 0; desc.DepthBiasClamp = 0.0f; desc.SlopeScaledDepthBias = 0.0f; desc.DepthClipEnable = !m_depthClamp; desc.ScissorEnable = _scissor; desc.MultisampleEnable = !!(_state&BGFX_STATE_MSAA); desc.AntialiasedLineEnable = !!(_state&BGFX_STATE_LINEAA); desc.ForcedSampleCount = 0; desc.ConservativeRaster = !!(_state&BGFX_STATE_CONSERVATIVE_RASTER) ? D3D11_CONSERVATIVE_RASTERIZATION_MODE_ON : D3D11_CONSERVATIVE_RASTERIZATION_MODE_OFF ; ID3D11Device3* device3 = reinterpret_cast<ID3D11Device3*>(m_device); DX_CHECK(device3->CreateRasterizerState2(&desc, reinterpret_cast<ID3D11RasterizerState2**>(&rs) ) ); } else #endif // BX_PLATFORM_WINDOWS { D3D11_RASTERIZER_DESC desc; desc.FillMode = _wireframe ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID; desc.CullMode = s_cullMode[cull]; desc.FrontCounterClockwise = false; desc.DepthBias = 0; desc.DepthBiasClamp = 0.0f; desc.SlopeScaledDepthBias = 0.0f; desc.DepthClipEnable = !m_depthClamp; desc.ScissorEnable = _scissor; desc.MultisampleEnable = !!(_state&BGFX_STATE_MSAA); desc.AntialiasedLineEnable = !!(_state&BGFX_STATE_LINEAA); DX_CHECK(m_device->CreateRasterizerState(&desc, &rs) ); } m_rasterizerStateCache.add(_state, rs); } m_deviceCtx->RSSetState(rs); } ID3D11SamplerState* getSamplerState(uint32_t _flags, const float _rgba[4]) { const uint32_t index = (_flags & BGFX_SAMPLER_BORDER_COLOR_MASK) >> BGFX_SAMPLER_BORDER_COLOR_SHIFT; _flags &= BGFX_SAMPLER_BITS_MASK; // Force min+mag anisotropic (can't be set individually) and remove mip (not supported). if (0 != (_flags & (BGFX_SAMPLER_MIN_ANISOTROPIC|BGFX_SAMPLER_MAG_ANISOTROPIC))) { _flags |= BGFX_SAMPLER_MIN_ANISOTROPIC|BGFX_SAMPLER_MAG_ANISOTROPIC; _flags &= ~BGFX_SAMPLER_MIP_MASK; } uint32_t hash; ID3D11SamplerState* sampler; if (!needBorderColor(_flags) ) { bx::HashMurmur2A murmur; murmur.begin(); murmur.add(_flags); murmur.add(-1); hash = murmur.end(); _rgba = s_zero.m_zerof; sampler = m_samplerStateCache.find(hash); } else { bx::HashMurmur2A murmur; murmur.begin(); murmur.add(_flags); murmur.add(index); hash = murmur.end(); _rgba = NULL == _rgba ? s_zero.m_zerof : _rgba;
{'commit': 'diff --git a/src/ovr.cpp b/src/ovr.cpp\nindex 194ba5edf..beaf20d68 100644\n--- a/src/ovr.cpp\n+++ b/src/ovr.cpp\n@@ -117,6 +117,7 @@ namespace bgfx\n \t\t\t| ovrDistortionCap_TimeWarp\n \t\t\t| ovrDistortionCap_Overdrive\n \t\t\t| ovrDistortionCap_NoRestore\n+\t\t\t| ovrDistortionCap_HqDistortion\n \t\t\t, eyeFov\n \t\t\t, m_erd\n \t\t\t);\n@@ -174,6 +175,13 @@ ovrError:\n \t\t\tm_texture[1].Header.RenderViewport = rect;\n \n \t\t\tm_timing = ovrHmd_BeginFrame(m_hmd, 0);\n+#if OVR_VERSION > OVR_VERSION_042\n+\t\t\tm_pose[0] = ovrHmd_GetHmdPosePerEye(m_hmd, ovrEye_Left);\n+\t\t\tm_pose[1] = ovrHmd_GetHmdPosePerEye(m_hmd, ovrEye_Right);\n+#else\n+\t\t\tm_pose[0] = ovrHmd_GetEyePose(m_hmd, ovrEye_Left);\n+\t\t\tm_pose[1] = ovrHmd_GetEyePose(m_hmd, ovrEye_Right);\n+#endif // OVR_VERSION > OVR_VERSION_042\n \t\t}\n \t}\n \ndiff --git a/src/renderer.h b/src/renderer.h\nindex 738f5988e..2404172c8 100644\n--- a/src/renderer.h\n+++ b/src/renderer.h\n@@ -12,12 +12,19 @@ namespace bgfx\n {\n \tstruct ViewState\n \t{\n+\t\tViewState() { }\n \t\tViewState(Frame* _render, bool _hmdEnabled)\n-\t\t\t: m_alphaRef(0.0f)\n-\t\t\t, m_invViewCached(UINT16_MAX)\n-\t\t\t, m_invProjCached(UINT16_MAX)\n-\t\t\t, m_invViewProjCached(UINT16_MAX)\n \t\t{\n+\t\t\treset(_render, _hmdEnabled);\n+\t\t}\n+\n+\t\tvoid reset(Frame* _render, bool _hmdEnabled)\n+\t\t{\n+\t\t\tm_alphaRef = 0.0f;\n+\t\t\tm_invViewCached = UINT16_MAX;\n+\t\t\tm_invProjCached = UINT16_MAX;\n+\t\t\tm_invViewProjCached = UINT16_MAX;\n+\n \t\t\tm_view[0] = _render->m_view;\n \t\t\tm_view[1] = m_viewTmp[1];\n \ndiff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp\nindex fbdb710d7..87591b03b 100644\n--- a/src/renderer_d3d11.cpp\n+++ b/src/renderer_d3d11.cpp\n@@ -942,8 +942,8 @@ BX_PRAGMA_DIAGNOSTIC_POP();\n \n \t\t\tDX_RELEASE(m_swapChain, 0);\n \t\t\tDX_RELEASE(m_deviceCtx, 0);\n-\t\t\tDX_RELEASE(m_device, 0);\n \t\t\tDX_RELEASE(m_factory, 0);\n+\t\t\tDX_RELEASE(m_device, 0);\n \n \t\t\tunloadRenderDoc(m_renderdocdll);\n \n@@ -2459,6 +2459,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();\n \t\tvoid* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];\n \t\tMatrix4 m_predefinedUniforms[PredefinedUniform::Count];\n \t\tUniformRegistry m_uniformReg;\n+\t\tViewState m_viewState;\n \n \t\tStateCacheT<ID3D11BlendState> m_blendStateCache;\n \t\tStateCacheT<ID3D11DepthStencilState> m_depthStencilStateCache;\n@@ -3305,7 +3306,8 @@ BX_PRAGMA_DIAGNOSTIC_POP();\n \t\tconst bool hmdEnabled = m_ovr.isEnabled() || m_ovr.isDebug();\n \t\t_render->m_hmdEnabled = hmdEnabled;\n \n-\t\tViewState viewState(_render, hmdEnabled);\n+\t\tViewState& viewState = m_viewState;\n+\t\tviewState.reset(_render, hmdEnabled);\n \n \t\tbool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME);\n \t\tbool scissorEnabled = false;\n', 'commit_subject': "Merge branch 'master' of github.com:bkaradzic/bgfx", 'repo_name': 'bkaradzic/bgfx', 'committer': {'name': 'Branimir Karadžić', 'email': 'a51d32610a255449bd8868a3bbd33941625e0ee1@gmail.com', 'time_sec': '1429324058', 'tz_offset': '-420', 'date': {'seconds': '1429324058'}}, 'commit_tree': '3a2acedd660cb47435e88f484e76f5cd5d014d7d', 'commit_message': "Merge branch 'master' of github.com:bkaradzic/bgfx\n", 'language_name': 'Shell', 'license': 'bsd-2-clause', 'hunks': '@@ -942,8 +942,8 @@ BX_PRAGMA_DIAGNOSTIC_POP();\n \n \t\t\tDX_RELEASE(m_swapChain, 0);\n \t\t\tDX_RELEASE(m_deviceCtx, 0);\n-\t\t\tDX_RELEASE(m_device, 0);\n \t\t\tDX_RELEASE(m_factory, 0);\n+\t\t\tDX_RELEASE(m_device, 0);\n \n \t\t\tunloadRenderDoc(m_renderdocdll);\n \n@@ -2459,6 +2459,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();\n \t\tvoid* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];\n \t\tMatrix4 m_predefinedUniforms[PredefinedUniform::Count];\n \t\tUniformRegistry m_uniformReg;\n+\t\tViewState m_viewState;\n \n \t\tStateCacheT<ID3D11BlendState> m_blendStateCache;\n \t\tStateCacheT<ID3D11DepthStencilState> m_depthStencilStateCache;\n@@ -3305,7 +3306,8 @@ BX_PRAGMA_DIAGNOSTIC_POP();\n \t\tconst bool hmdEnabled = m_ovr.isEnabled() || m_ovr.isDebug();\n \t\t_render->m_hmdEnabled = hmdEnabled;\n \n-\t\tViewState viewState(_render, hmdEnabled);\n+\t\tViewState& viewState = m_viewState;\n+\t\tviewState.reset(_render, hmdEnabled);\n \n \t\tbool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME);\n \t\tbool scissorEnabled = false;\n', 'addition_count': 4, 'deletion_count': 2, 'src_file': 'a/src/renderer_d3d11.cpp', 'tgt_file': 'b/src/renderer_d3d11.cpp', 'file_extension': '.cpp', 'before_file': '/*\n * Copyright 2011-2022 Branimir Karadzic. All rights reserved.\n * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE\n */\n\n#include "bgfx_p.h"\n\n#if BGFX_CONFIG_RENDERER_DIRECT3D11\n#\tinclude "renderer_d3d11.h"\n#\tinclude <bx/pixelformat.h>\n\nnamespace bgfx { namespace d3d11\n{\n\tstatic wchar_t s_viewNameW[BGFX_CONFIG_MAX_VIEWS][BGFX_CONFIG_MAX_VIEW_NAME];\n\tstatic char    s_viewName [BGFX_CONFIG_MAX_VIEWS][BGFX_CONFIG_MAX_VIEW_NAME];\n\n\tinline void setViewType(ViewId _view, const bx::StringView _str)\n\t{\n\t\tif (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION | BGFX_CONFIG_PROFILER) )\n\t\t{\n\t\t\tconst uint32_t len = _str.getLength();\n\n\t\t\tbx::memCopy(&s_viewName[_view][3], _str.getPtr(), len);\n\n\t\t\twchar_t tmpW[16];\n\t\t\tmbstowcs(tmpW, _str.getPtr(), len);\n\n\t\t\tbx::memCopy(&s_viewNameW[_view][3], tmpW, len*2);\n\t\t}\n\t}\n\n\tstruct PrimInfo\n\t{\n\t\tD3D11_PRIMITIVE_TOPOLOGY m_type;\n\t\tuint32_t m_min;\n\t\tuint32_t m_div;\n\t\tuint32_t m_sub;\n\t};\n\n\tstatic const PrimInfo s_primInfo[] =\n\t{\n\t\t{ D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,  3, 3, 0 },\n\t\t{ D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, 3, 1, 2 },\n\t\t{ D3D11_PRIMITIVE_TOPOLOGY_LINELIST,      2, 2, 0 },\n\t\t{ D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP,     2, 1, 1 },\n\t\t{ D3D11_PRIMITIVE_TOPOLOGY_POINTLIST,     1, 1, 0 },\n\t\t{ D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED,     0, 0, 0 },\n\t};\n\tBX_STATIC_ASSERT(Topology::Count == BX_COUNTOF(s_primInfo)-1);\n\n\tunion Zero\n\t{\n\t\tZero()\n\t\t{\n\t\t\tbx::memSet(this, 0, sizeof(Zero) );\n\t\t}\n\n\t\tID3D11Buffer*              m_buffer[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];\n\t\tID3D11UnorderedAccessView* m_uav[D3D11_1_UAV_SLOT_COUNT];\n\t\tID3D11ShaderResourceView*  m_srv[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];\n\t\tID3D11SamplerState*        m_sampler[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];\n\t\tID3D11RenderTargetView*    m_rtv[BGFX_CONFIG_MAX_FRAME_BUFFERS];\n\t\tuint32_t                   m_zero[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];\n\t\tfloat                      m_zerof[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];\n\t};\n\n\tBX_PRAGMA_DIAGNOSTIC_PUSH();\n\tBX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4268) // warning C4268: \'\' : \'const\' static/global data initialized with compiler generated default constructor fills the object with zeros\n\tstatic const Zero s_zero;\n\tBX_PRAGMA_DIAGNOSTIC_POP();\n\n\tstatic const uint32_t s_checkMsaa[] =\n\t{\n\t\t0,\n\t\t2,\n\t\t4,\n\t\t8,\n\t\t16,\n\t};\n\n\tstatic DXGI_SAMPLE_DESC s_msaa[] =\n\t{\n\t\t{  1, 0 },\n\t\t{  2, 0 },\n\t\t{  4, 0 },\n\t\t{  8, 0 },\n\t\t{ 16, 0 },\n\t};\n\n\tstatic const D3D11_BLEND s_blendFactor[][2] =\n\t{\n\t\t{ D3D11_BLEND(0),               D3D11_BLEND(0)               }, // ignored\n\t\t{ D3D11_BLEND_ZERO,             D3D11_BLEND_ZERO             }, // ZERO\n\t\t{ D3D11_BLEND_ONE,              D3D11_BLEND_ONE              }, // ONE\n\t\t{ D3D11_BLEND_SRC_COLOR,        D3D11_BLEND_SRC_ALPHA        }, // SRC_COLOR\n\t\t{ D3D11_BLEND_INV_SRC_COLOR,    D3D11_BLEND_INV_SRC_ALPHA    }, // INV_SRC_COLOR\n\t\t{ D3D11_BLEND_SRC_ALPHA,        D3D11_BLEND_SRC_ALPHA        }, // SRC_ALPHA\n\t\t{ D3D11_BLEND_INV_SRC_ALPHA,    D3D11_BLEND_INV_SRC_ALPHA    }, // INV_SRC_ALPHA\n\t\t{ D3D11_BLEND_DEST_ALPHA,       D3D11_BLEND_DEST_ALPHA       }, // DST_ALPHA\n\t\t{ D3D11_BLEND_INV_DEST_ALPHA,   D3D11_BLEND_INV_DEST_ALPHA   }, // INV_DST_ALPHA\n\t\t{ D3D11_BLEND_DEST_COLOR,       D3D11_BLEND_DEST_ALPHA       }, // DST_COLOR\n\t\t{ D3D11_BLEND_INV_DEST_COLOR,   D3D11_BLEND_INV_DEST_ALPHA   }, // INV_DST_COLOR\n\t\t{ D3D11_BLEND_SRC_ALPHA_SAT,    D3D11_BLEND_ONE              }, // SRC_ALPHA_SAT\n\t\t{ D3D11_BLEND_BLEND_FACTOR,     D3D11_BLEND_BLEND_FACTOR     }, // FACTOR\n\t\t{ D3D11_BLEND_INV_BLEND_FACTOR, D3D11_BLEND_INV_BLEND_FACTOR }, // INV_FACTOR\n\t};\n\n\tstatic const D3D11_BLEND_OP s_blendEquation[] =\n\t{\n\t\tD3D11_BLEND_OP_ADD,\n\t\tD3D11_BLEND_OP_SUBTRACT,\n\t\tD3D11_BLEND_OP_REV_SUBTRACT,\n\t\tD3D11_BLEND_OP_MIN,\n\t\tD3D11_BLEND_OP_MAX,\n\t};\n\n\tstatic const D3D11_COMPARISON_FUNC s_cmpFunc[] =\n\t{\n\t\tD3D11_COMPARISON_FUNC(0), // ignored\n\t\tD3D11_COMPARISON_LESS,\n\t\tD3D11_COMPARISON_LESS_EQUAL,\n\t\tD3D11_COMPARISON_EQUAL,\n\t\tD3D11_COMPARISON_GREATER_EQUAL,\n\t\tD3D11_COMPARISON_GREATER,\n\t\tD3D11_COMPARISON_NOT_EQUAL,\n\t\tD3D11_COMPARISON_NEVER,\n\t\tD3D11_COMPARISON_ALWAYS,\n\t};\n\n\tstatic const D3D11_STENCIL_OP s_stencilOp[] =\n\t{\n\t\tD3D11_STENCIL_OP_ZERO,\n\t\tD3D11_STENCIL_OP_KEEP,\n\t\tD3D11_STENCIL_OP_REPLACE,\n\t\tD3D11_STENCIL_OP_INCR,\n\t\tD3D11_STENCIL_OP_INCR_SAT,\n\t\tD3D11_STENCIL_OP_DECR,\n\t\tD3D11_STENCIL_OP_DECR_SAT,\n\t\tD3D11_STENCIL_OP_INVERT,\n\t};\n\n\tstatic const D3D11_CULL_MODE s_cullMode[] =\n\t{\n\t\tD3D11_CULL_NONE,\n\t\tD3D11_CULL_FRONT,\n\t\tD3D11_CULL_BACK,\n\t};\n\n\tstatic const D3D11_TEXTURE_ADDRESS_MODE s_textureAddress[] =\n\t{\n\t\tD3D11_TEXTURE_ADDRESS_WRAP,\n\t\tD3D11_TEXTURE_ADDRESS_MIRROR,\n\t\tD3D11_TEXTURE_ADDRESS_CLAMP,\n\t\tD3D11_TEXTURE_ADDRESS_BORDER,\n\t};\n\n\t/*\n\t * D3D11_FILTER_MIN_MAG_MIP_POINT               = 0x00,\n\t * D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR        = 0x01,\n\t * D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT  = 0x04,\n\t * D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR        = 0x05,\n\t * D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT        = 0x10,\n\t * D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR = 0x11,\n\t * D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT        = 0x14,\n\t * D3D11_FILTER_MIN_MAG_MIP_LINEAR              = 0x15,\n\t * D3D11_FILTER_ANISOTROPIC                     = 0x55,\n\t *\n\t * D3D11_COMPARISON_FILTERING_BIT               = 0x80,\n\t * D3D11_ANISOTROPIC_FILTERING_BIT              = 0x40,\n\t *\n\t * According to D3D11_FILTER enum bits for mip, mag and mip are:\n\t * 0x10 // MIN_LINEAR\n\t * 0x04 // MAG_LINEAR\n\t * 0x01 // MIP_LINEAR\n\t */\n\n\tstatic const uint8_t s_textureFilter[3][3] =\n\t{\n\t\t{\n\t\t\t0x10, // min linear\n\t\t\t0x00, // min point\n\t\t\t0x55, // anisotropic\n\t\t},\n\t\t{\n\t\t\t0x04, // mag linear\n\t\t\t0x00, // mag point\n\t\t\t0x55, // anisotropic\n\t\t},\n\t\t{\n\t\t\t0x01, // mip linear\n\t\t\t0x00, // mip point\n\t\t\t0x55, // anisotropic\n\t\t},\n\t};\n\n\tstruct TextureFormatInfo\n\t{\n\t\tDXGI_FORMAT m_fmt;\n\t\tDXGI_FORMAT m_fmtSrv;\n\t\tDXGI_FORMAT m_fmtDsv;\n\t\tDXGI_FORMAT m_fmtSrgb;\n\t};\n\n\tstatic const TextureFormatInfo s_textureFormat[] =\n\t{\n\t\t{ DXGI_FORMAT_BC1_UNORM,          DXGI_FORMAT_BC1_UNORM,             DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_BC1_UNORM_SRGB       }, // BC1\n\t\t{ DXGI_FORMAT_BC2_UNORM,          DXGI_FORMAT_BC2_UNORM,             DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_BC2_UNORM_SRGB       }, // BC2\n\t\t{ DXGI_FORMAT_BC3_UNORM,          DXGI_FORMAT_BC3_UNORM,             DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_BC3_UNORM_SRGB       }, // BC3\n\t\t{ DXGI_FORMAT_BC4_UNORM,          DXGI_FORMAT_BC4_UNORM,             DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // BC4\n\t\t{ DXGI_FORMAT_BC5_UNORM,          DXGI_FORMAT_BC5_UNORM,             DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // BC5\n\t\t{ DXGI_FORMAT_BC6H_SF16,          DXGI_FORMAT_BC6H_SF16,             DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // BC6H\n\t\t{ DXGI_FORMAT_BC7_UNORM,          DXGI_FORMAT_BC7_UNORM,             DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_BC7_UNORM_SRGB       }, // BC7\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // ETC1\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // ETC2\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // ETC2A\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // ETC2A1\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // PTC12\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // PTC14\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // PTC12A\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // PTC14A\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // PTC22\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // PTC24\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // ATC\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // ATCE\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // ATCI\n\t\t{ DXGI_FORMAT_ASTC_4X4_UNORM,     DXGI_FORMAT_ASTC_4X4_UNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_ASTC_4X4_UNORM_SRGB  }, // ASTC4x4\n\t\t{ DXGI_FORMAT_ASTC_5X4_UNORM,     DXGI_FORMAT_ASTC_5X4_UNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_ASTC_5X4_UNORM_SRGB  }, // ASTC5x4\n\t\t{ DXGI_FORMAT_ASTC_5X5_UNORM,     DXGI_FORMAT_ASTC_5X5_UNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_ASTC_5X5_UNORM_SRGB  }, // ASTC5x5\n\t\t{ DXGI_FORMAT_ASTC_6X5_UNORM,     DXGI_FORMAT_ASTC_6X5_UNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_ASTC_6X5_UNORM_SRGB  }, // ASTC6x5\n\t\t{ DXGI_FORMAT_ASTC_6X6_UNORM,     DXGI_FORMAT_ASTC_6X6_UNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_ASTC_6X6_UNORM_SRGB  }, // ASTC6x6\n\t\t{ DXGI_FORMAT_ASTC_8X5_UNORM,     DXGI_FORMAT_ASTC_8X5_UNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_ASTC_8X5_UNORM_SRGB  }, // ASTC8x5\n\t\t{ DXGI_FORMAT_ASTC_8X6_UNORM,     DXGI_FORMAT_ASTC_8X6_UNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_ASTC_8X6_UNORM_SRGB  }, // ASTC8x6\n\t\t{ DXGI_FORMAT_ASTC_8X8_UNORM,     DXGI_FORMAT_ASTC_8X8_UNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_ASTC_8X8_UNORM_SRGB  }, // ASTC8x8\n\t\t{ DXGI_FORMAT_ASTC_10X5_UNORM,    DXGI_FORMAT_ASTC_10X5_UNORM,       DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_ASTC_10X5_UNORM_SRGB }, // ASTC10x5\n\t\t{ DXGI_FORMAT_ASTC_10X6_UNORM,    DXGI_FORMAT_ASTC_10X6_UNORM,       DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_ASTC_10X6_UNORM_SRGB }, // ASTC10x6\n\t\t{ DXGI_FORMAT_ASTC_10X8_UNORM,    DXGI_FORMAT_ASTC_10X8_UNORM,       DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_ASTC_10X8_UNORM_SRGB }, // ASTC10x8\n\t\t{ DXGI_FORMAT_ASTC_10X10_UNORM,   DXGI_FORMAT_ASTC_10X10_UNORM,      DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_ASTC_10X10_UNORM_SRGB}, // ASTC10x10\n\t\t{ DXGI_FORMAT_ASTC_12X10_UNORM,   DXGI_FORMAT_ASTC_12X10_UNORM,      DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_ASTC_12X10_UNORM_SRGB}, // ASTC12x10\n\t\t{ DXGI_FORMAT_ASTC_12X12_UNORM,   DXGI_FORMAT_ASTC_12X12_UNORM,      DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_ASTC_12X12_UNORM_SRGB}, // ASTC12x12\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // Unknown\n\t\t{ DXGI_FORMAT_R1_UNORM,           DXGI_FORMAT_R1_UNORM,              DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // R1\n\t\t{ DXGI_FORMAT_A8_UNORM,           DXGI_FORMAT_A8_UNORM,              DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // A8\n\t\t{ DXGI_FORMAT_R8_UNORM,           DXGI_FORMAT_R8_UNORM,              DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // R8\n\t\t{ DXGI_FORMAT_R8_SINT,            DXGI_FORMAT_R8_SINT,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // R8I\n\t\t{ DXGI_FORMAT_R8_UINT,            DXGI_FORMAT_R8_UINT,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // R8U\n\t\t{ DXGI_FORMAT_R8_SNORM,           DXGI_FORMAT_R8_SNORM,              DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // R8S\n\t\t{ DXGI_FORMAT_R16_UNORM,          DXGI_FORMAT_R16_UNORM,             DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // R16\n\t\t{ DXGI_FORMAT_R16_SINT,           DXGI_FORMAT_R16_SINT,              DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // R16I\n\t\t{ DXGI_FORMAT_R16_UINT,           DXGI_FORMAT_R16_UINT,              DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // R16U\n\t\t{ DXGI_FORMAT_R16_FLOAT,          DXGI_FORMAT_R16_FLOAT,             DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // R16F\n\t\t{ DXGI_FORMAT_R16_SNORM,          DXGI_FORMAT_R16_SNORM,             DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // R16S\n\t\t{ DXGI_FORMAT_R32_SINT,           DXGI_FORMAT_R32_SINT,              DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // R32I\n\t\t{ DXGI_FORMAT_R32_UINT,           DXGI_FORMAT_R32_UINT,              DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // R32U\n\t\t{ DXGI_FORMAT_R32_FLOAT,          DXGI_FORMAT_R32_FLOAT,             DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // R32F\n\t\t{ DXGI_FORMAT_R8G8_UNORM,         DXGI_FORMAT_R8G8_UNORM,            DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RG8\n\t\t{ DXGI_FORMAT_R8G8_SINT,          DXGI_FORMAT_R8G8_SINT,             DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RG8I\n\t\t{ DXGI_FORMAT_R8G8_UINT,          DXGI_FORMAT_R8G8_UINT,             DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RG8U\n\t\t{ DXGI_FORMAT_R8G8_SNORM,         DXGI_FORMAT_R8G8_SNORM,            DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RG8S\n\t\t{ DXGI_FORMAT_R16G16_UNORM,       DXGI_FORMAT_R16G16_UNORM,          DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RG16\n\t\t{ DXGI_FORMAT_R16G16_SINT,        DXGI_FORMAT_R16G16_SINT,           DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RG16I\n\t\t{ DXGI_FORMAT_R16G16_UINT,        DXGI_FORMAT_R16G16_UINT,           DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RG16U\n\t\t{ DXGI_FORMAT_R16G16_FLOAT,       DXGI_FORMAT_R16G16_FLOAT,          DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RG16F\n\t\t{ DXGI_FORMAT_R16G16_SNORM,       DXGI_FORMAT_R16G16_SNORM,          DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RG16S\n\t\t{ DXGI_FORMAT_R32G32_SINT,        DXGI_FORMAT_R32G32_SINT,           DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RG32I\n\t\t{ DXGI_FORMAT_R32G32_UINT,        DXGI_FORMAT_R32G32_UINT,           DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RG32U\n\t\t{ DXGI_FORMAT_R32G32_FLOAT,       DXGI_FORMAT_R32G32_FLOAT,          DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RG32F\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGB8\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGB8I\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGB8U\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGB8S\n\t\t{ DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_R9G9B9E5_SHAREDEXP,    DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGB9E5F\n\t\t{ DXGI_FORMAT_B8G8R8A8_UNORM,     DXGI_FORMAT_B8G8R8A8_UNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_B8G8R8A8_UNORM_SRGB  }, // BGRA8\n\t\t{ DXGI_FORMAT_R8G8B8A8_UNORM,     DXGI_FORMAT_R8G8B8A8_UNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_R8G8B8A8_UNORM_SRGB  }, // RGBA8\n\t\t{ DXGI_FORMAT_R8G8B8A8_SINT,      DXGI_FORMAT_R8G8B8A8_SINT,         DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_R8G8B8A8_UNORM_SRGB  }, // RGBA8I\n\t\t{ DXGI_FORMAT_R8G8B8A8_UINT,      DXGI_FORMAT_R8G8B8A8_UINT,         DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_R8G8B8A8_UNORM_SRGB  }, // RGBA8U\n\t\t{ DXGI_FORMAT_R8G8B8A8_SNORM,     DXGI_FORMAT_R8G8B8A8_SNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGBA8S\n\t\t{ DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM,    DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGBA16\n\t\t{ DXGI_FORMAT_R16G16B16A16_SINT,  DXGI_FORMAT_R16G16B16A16_SINT,     DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGBA16I\n\t\t{ DXGI_FORMAT_R16G16B16A16_UINT,  DXGI_FORMAT_R16G16B16A16_UINT,     DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGBA16U\n\t\t{ DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT,    DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGBA16F\n\t\t{ DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_R16G16B16A16_SNORM,    DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGBA16S\n\t\t{ DXGI_FORMAT_R32G32B32A32_SINT,  DXGI_FORMAT_R32G32B32A32_SINT,     DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGBA32I\n\t\t{ DXGI_FORMAT_R32G32B32A32_UINT,  DXGI_FORMAT_R32G32B32A32_UINT,     DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGBA32U\n\t\t{ DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT,    DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGBA32F\n\t\t{ DXGI_FORMAT_B5G6R5_UNORM,       DXGI_FORMAT_B5G6R5_UNORM,          DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // B5G6R5\n\t\t{ DXGI_FORMAT_B5G6R5_UNORM,       DXGI_FORMAT_B5G6R5_UNORM,          DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // R5G6B5\n\t\t{ DXGI_FORMAT_B4G4R4A4_UNORM,     DXGI_FORMAT_B4G4R4A4_UNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // BGRA4\n\t\t{ DXGI_FORMAT_B4G4R4A4_UNORM,     DXGI_FORMAT_B4G4R4A4_UNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGBA4\n\t\t{ DXGI_FORMAT_B5G5R5A1_UNORM,     DXGI_FORMAT_B5G5R5A1_UNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // BGR5A1\n\t\t{ DXGI_FORMAT_B5G5R5A1_UNORM,     DXGI_FORMAT_B5G5R5A1_UNORM,        DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGB5A1\n\t\t{ DXGI_FORMAT_R10G10B10A2_UNORM,  DXGI_FORMAT_R10G10B10A2_UNORM,     DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RGB10A2\n\t\t{ DXGI_FORMAT_R11G11B10_FLOAT,    DXGI_FORMAT_R11G11B10_FLOAT,       DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // RG11B10F\n\t\t{ DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN,               DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN              }, // UnknownDepth\n\t\t{ DXGI_FORMAT_R16_TYPELESS,       DXGI_FORMAT_R16_UNORM,             DXGI_FORMAT_D16_UNORM,         DXGI_FORMAT_UNKNOWN              }, // D16\n\t\t{ DXGI_FORMAT_R24G8_TYPELESS,     DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN              }, // D24\n\t\t{ DXGI_FORMAT_R24G8_TYPELESS,     DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN              }, // D24S8\n\t\t{ DXGI_FORMAT_R24G8_TYPELESS,     DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN              }, // D32\n\t\t{ DXGI_FORMAT_R32_TYPELESS,       DXGI_FORMAT_R32_FLOAT,             DXGI_FORMAT_D32_FLOAT,         DXGI_FORMAT_UNKNOWN              }, // D16F\n\t\t{ DXGI_FORMAT_R32_TYPELESS,       DXGI_FORMAT_R32_FLOAT,             DXGI_FORMAT_D32_FLOAT,         DXGI_FORMAT_UNKNOWN              }, // D24F\n\t\t{ DXGI_FORMAT_R32_TYPELESS,       DXGI_FORMAT_R32_FLOAT,             DXGI_FORMAT_D32_FLOAT,         DXGI_FORMAT_UNKNOWN              }, // D32F\n\t\t{ DXGI_FORMAT_R24G8_TYPELESS,     DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_UNKNOWN              }, // D0S8\n\t};\n\tBX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_textureFormat) );\n\n\tstatic const D3D11_INPUT_ELEMENT_DESC s_attrib[] =\n\t{\n\t\t{ "POSITION",     0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "NORMAL",       0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "TANGENT",      0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "BITANGENT",    0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "COLOR",        0, DXGI_FORMAT_R8G8B8A8_UINT,   0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "COLOR",        1, DXGI_FORMAT_R8G8B8A8_UINT,   0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "COLOR",        2, DXGI_FORMAT_R8G8B8A8_UINT,   0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "COLOR",        3, DXGI_FORMAT_R8G8B8A8_UINT,   0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "BLENDINDICES", 0, DXGI_FORMAT_R8G8B8A8_UINT,   0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "BLENDWEIGHT",  0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "TEXCOORD",     0, DXGI_FORMAT_R32G32_FLOAT,    0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "TEXCOORD",     1, DXGI_FORMAT_R32G32_FLOAT,    0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "TEXCOORD",     2, DXGI_FORMAT_R32G32_FLOAT,    0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "TEXCOORD",     3, DXGI_FORMAT_R32G32_FLOAT,    0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "TEXCOORD",     4, DXGI_FORMAT_R32G32_FLOAT,    0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "TEXCOORD",     5, DXGI_FORMAT_R32G32_FLOAT,    0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "TEXCOORD",     6, DXGI_FORMAT_R32G32_FLOAT,    0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t\t{ "TEXCOORD",     7, DXGI_FORMAT_R32G32_FLOAT,    0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },\n\t};\n\tBX_STATIC_ASSERT(Attrib::Count == BX_COUNTOF(s_attrib) );\n\n\tstatic const DXGI_FORMAT s_attribType[][4][2] =\n\t{\n\t\t{ // Uint8\n\t\t\t{ DXGI_FORMAT_R8_UINT,            DXGI_FORMAT_R8_UNORM           },\n\t\t\t{ DXGI_FORMAT_R8G8_UINT,          DXGI_FORMAT_R8G8_UNORM         },\n\t\t\t{ DXGI_FORMAT_R8G8B8A8_UINT,      DXGI_FORMAT_R8G8B8A8_UNORM     },\n\t\t\t{ DXGI_FORMAT_R8G8B8A8_UINT,      DXGI_FORMAT_R8G8B8A8_UNORM     },\n\t\t},\n\t\t{ // Uint10\n\t\t\t{ DXGI_FORMAT_R10G10B10A2_UINT,   DXGI_FORMAT_R10G10B10A2_UNORM  },\n\t\t\t{ DXGI_FORMAT_R10G10B10A2_UINT,   DXGI_FORMAT_R10G10B10A2_UNORM  },\n\t\t\t{ DXGI_FORMAT_R10G10B10A2_UINT,   DXGI_FORMAT_R10G10B10A2_UNORM  },\n\t\t\t{ DXGI_FORMAT_R10G10B10A2_UINT,   DXGI_FORMAT_R10G10B10A2_UNORM  },\n\t\t},\n\t\t{ // Int16\n\t\t\t{ DXGI_FORMAT_R16_SINT,           DXGI_FORMAT_R16_SNORM          },\n\t\t\t{ DXGI_FORMAT_R16G16_SINT,        DXGI_FORMAT_R16G16_SNORM       },\n\t\t\t{ DXGI_FORMAT_R16G16B16A16_SINT,  DXGI_FORMAT_R16G16B16A16_SNORM },\n\t\t\t{ DXGI_FORMAT_R16G16B16A16_SINT,  DXGI_FORMAT_R16G16B16A16_SNORM },\n\t\t},\n\t\t{ // Half\n\t\t\t{ DXGI_FORMAT_R16_FLOAT,          DXGI_FORMAT_R16_FLOAT          },\n\t\t\t{ DXGI_FORMAT_R16G16_FLOAT,       DXGI_FORMAT_R16G16_FLOAT       },\n\t\t\t{ DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT },\n\t\t\t{ DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT },\n\t\t},\n\t\t{ // Float\n\t\t\t{ DXGI_FORMAT_R32_FLOAT,          DXGI_FORMAT_R32_FLOAT          },\n\t\t\t{ DXGI_FORMAT_R32G32_FLOAT,       DXGI_FORMAT_R32G32_FLOAT       },\n\t\t\t{ DXGI_FORMAT_R32G32B32_FLOAT,    DXGI_FORMAT_R32G32B32_FLOAT    },\n\t\t\t{ DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT },\n\t\t},\n\t};\n\tBX_STATIC_ASSERT(AttribType::Count == BX_COUNTOF(s_attribType) );\n\n\tstatic D3D11_INPUT_ELEMENT_DESC* fillVertexLayout(uint8_t _stream, D3D11_INPUT_ELEMENT_DESC* _out, const VertexLayout& _layout)\n\t{\n\t\tD3D11_INPUT_ELEMENT_DESC* elem = _out;\n\n\t\tfor (uint32_t attr = 0; attr < Attrib::Count; ++attr)\n\t\t{\n\t\t\tif (UINT16_MAX != _layout.m_attributes[attr])\n\t\t\t{\n\t\t\t\tbx::memCopy(elem, &s_attrib[attr], sizeof(D3D11_INPUT_ELEMENT_DESC) );\n\n\t\t\t\telem->InputSlot = _stream;\n\n\t\t\t\tif (0 == _layout.m_attributes[attr])\n\t\t\t\t{\n\t\t\t\t\telem->AlignedByteOffset = 0;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tuint8_t num;\n\t\t\t\t\tAttribType::Enum type;\n\t\t\t\t\tbool normalized;\n\t\t\t\t\tbool asInt;\n\t\t\t\t\t_layout.decode(Attrib::Enum(attr), num, type, normalized, asInt);\n\t\t\t\t\telem->Format = s_attribType[type][num-1][normalized];\n\t\t\t\t\telem->AlignedByteOffset = _layout.m_offset[attr];\n\t\t\t\t}\n\n\t\t\t\t++elem;\n\t\t\t}\n\t\t}\n\n\t\treturn elem;\n\t}\n\n\tstruct TextureStage\n\t{\n\t\tTextureStage()\n\t\t{\n\t\t\tclear();\n\t\t}\n\n\t\tvoid clear()\n\t\t{\n\t\t\tbx::memSet(m_uav,     0, sizeof(m_uav) );\n\t\t\tbx::memSet(m_srv,     0, sizeof(m_srv) );\n\t\t\tbx::memSet(m_sampler, 0, sizeof(m_sampler) );\n\t\t}\n\n\t\tID3D11UnorderedAccessView* m_uav[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];\n\t\tID3D11ShaderResourceView*  m_srv[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];\n\t\tID3D11SamplerState*        m_sampler[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];\n\t};\n\n\tBX_PRAGMA_DIAGNOSTIC_PUSH();\n\tBX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wunused-const-variable");\n\tBX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wunneeded-internal-declaration");\n\n\tstatic const GUID WKPDID_D3DDebugObjectName     = { 0x429b8c22, 0x9188, 0x4b0c, { 0x87, 0x42, 0xac, 0xb0, 0xbf, 0x85, 0xc2, 0x00 } };\n\tstatic const GUID IID_ID3D11Texture2D           = { 0x6f15aaf2, 0xd208, 0x4e89, { 0x9a, 0xb4, 0x48, 0x95, 0x35, 0xd3, 0x4f, 0x9c } };\n\tstatic const GUID IID_ID3D11Device1             = { 0xa04bfb29, 0x08ef, 0x43d6, { 0xa4, 0x9c, 0xa9, 0xbd, 0xbd, 0xcb, 0xe6, 0x86 } };\n\tstatic const GUID IID_ID3D11Device2             = { 0x9d06dffa, 0xd1e5, 0x4d07, { 0x83, 0xa8, 0x1b, 0xb1, 0x23, 0xf2, 0xf8, 0x41 } };\n\tstatic const GUID IID_ID3D11Device3             = { 0xa05c8c37, 0xd2c6, 0x4732, { 0xb3, 0xa0, 0x9c, 0xe0, 0xb0, 0xdc, 0x9a, 0xe6 } };\n\tstatic const GUID IID_ID3D11InfoQueue           = { 0x6543dbb6, 0x1b48, 0x42f5, { 0xab, 0x82, 0xe9, 0x7e, 0xc7, 0x43, 0x26, 0xf6 } };\n\tstatic const GUID IID_IDXGIDeviceRenderDoc      = { 0xa7aa6116, 0x9c8d, 0x4bba, { 0x90, 0x83, 0xb4, 0xd8, 0x16, 0xb7, 0x1b, 0x78 } };\n\tstatic const GUID IID_ID3DUserDefinedAnnotation = { 0xb2daad8b, 0x03d4, 0x4dbf, { 0x95, 0xeb, 0x32, 0xab, 0x4b, 0x63, 0xd0, 0xab } };\n\n\tenum D3D11_FORMAT_SUPPORT2\n\t{\n\t\tD3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD  = 0x40,\n\t\tD3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE = 0x80,\n\t};\n\n\tstatic const GUID s_d3dDeviceIIDs[] =\n\t{\n\t\tIID_ID3D11Device3,\n\t\tIID_ID3D11Device2,\n\t\tIID_ID3D11Device1,\n\t};\n\n\tinline bool isLost(HRESULT _hr)\n\t{\n\t\treturn false\n\t\t\t|| _hr == DXGI_ERROR_DEVICE_REMOVED\n\t\t\t|| _hr == DXGI_ERROR_DEVICE_HUNG\n\t\t\t|| _hr == DXGI_ERROR_DEVICE_RESET\n\t\t\t|| _hr == DXGI_ERROR_DRIVER_INTERNAL_ERROR\n\t\t\t|| _hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE\n\t\t\t;\n\t}\n\n\tstatic const char* getLostReason(HRESULT _hr)\n\t{\n\t\tswitch (_hr)\n\t\t{\n\t\t// The GPU device instance has been suspended. Use GetDeviceRemovedReason to determine the appropriate action.\n\t\tcase DXGI_ERROR_DEVICE_REMOVED: return "DXGI_ERROR_DEVICE_REMOVED";\n\n\t\t// The GPU will not respond to more commands, most likely because of an invalid command passed by the calling application.\n\t\tcase DXGI_ERROR_DEVICE_HUNG: return "DXGI_ERROR_DEVICE_HUNG";\n\n\t\t// The GPU will not respond to more commands, most likely because some other application submitted invalid commands.\n\t\t// The calling application should re-create the device and continue.\n\t\tcase DXGI_ERROR_DEVICE_RESET: return "DXGI_ERROR_DEVICE_RESET";\n\n\t\t// An internal issue prevented the driver from carrying out the specified operation. The driver\'s state is probably\n\t\t// suspect, and the application should not continue.\n\t\tcase DXGI_ERROR_DRIVER_INTERNAL_ERROR: return "DXGI_ERROR_DRIVER_INTERNAL_ERROR";\n\n\t\t// A resource is not available at the time of the call, but may become available later.\n\t\tcase DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: return "DXGI_ERROR_NOT_CURRENTLY_AVAILABLE";\n\n\t\tcase S_OK: return "S_OK";\n\n\t\tdefault: break;\n\t\t}\n\n\t\treturn "Unknown HRESULT?";\n\t}\n\n\ttemplate <typename Ty>\n\tstatic BX_NO_INLINE void setDebugObjectName(Ty* _interface, const char* _format, ...)\n\t{\n\t\tif (BX_ENABLED(BGFX_CONFIG_DEBUG_OBJECT_NAME) )\n\t\t{\n\t\t\tchar temp[2048];\n\t\t\tva_list argList;\n\t\t\tva_start(argList, _format);\n\t\t\tint size = bx::uint32_min(sizeof(temp)-1, bx::vsnprintf(temp, sizeof(temp), _format, argList) );\n\t\t\tva_end(argList);\n\t\t\ttemp[size] = \'\\0\';\n\n\t\t\t_interface->SetPrivateData(WKPDID_D3DDebugObjectName, size, temp);\n\t\t}\n\t}\n\n\tBX_PRAGMA_DIAGNOSTIC_POP();\n\n\tstatic HRESULT setIntelExtension(ID3D11Device* _device, const void* _data, uint32_t _size)\n\t{\n\t\tD3D11_BUFFER_DESC desc;\n\t\tdesc.ByteWidth = _size;\n\t\tdesc.Usage = D3D11_USAGE_STAGING;\n\t\tdesc.BindFlags = 0;\n\t\tdesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;\n\t\tdesc.MiscFlags = 0;\n\t\tdesc.StructureByteStride = 0;\n\n\t\tD3D11_SUBRESOURCE_DATA initData;\n\t\tinitData.pSysMem = _data;\n\t\tinitData.SysMemPitch = _size;\n\t\tinitData.SysMemSlicePitch = 0;\n\n\t\tID3D11Buffer* buffer;\n\t\tHRESULT hr = _device->CreateBuffer(&desc, &initData, &buffer);\n\n\t\tif (SUCCEEDED(hr) )\n\t\t{\n\t\t\tbuffer->Release();\n\t\t}\n\n\t\treturn hr;\n\t};\n\n\tstatic const uint32_t kIntelExtensionInterfaceVersion = UINT32_C(0x10000);\n\n\tstruct IntelExtension\n\t{\n\t\tchar     key[16];\n\t\tuint32_t version;\n\t\tuint32_t type;\n\t\tuint32_t data[16];\n\t};\n\n\tstatic const IntelExtension s_intelDirectAccessResource =\n\t{\n\t\t{ \'I\', \'N\', \'T\', \'C\', \'E\', \'X\', \'T\', \'N\', \'R\', \'E\', \'S\', \'O\', \'U\', \'R\', \'C\', \'E\' },\n\t\tkIntelExtensionInterfaceVersion,\n\t\t1,\n\t\t{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },\n\t};\n\n\tstatic HRESULT setIntelDirectAccessResource(ID3D11Device* _device)\n\t{\n\t\treturn setIntelExtension(_device, &s_intelDirectAccessResource, sizeof(s_intelDirectAccessResource) );\n\t}\n\n\tstatic BX_NO_INLINE bool getIntelExtensions(ID3D11Device* _device)\n\t{\n\t\tif (windowsVersionIs(Condition::GreaterEqual, 0x0604) )\n\t\t{\n\t\t\tuint8_t temp[28];\n\n\t\t\tbx::ErrorAssert err;\n\n\t\t\tbx::StaticMemoryBlockWriter writer(&temp, sizeof(temp) );\n\t\t\tbx::write(&writer, "INTCEXTNCAPSFUNC", 16, &err);\n\t\t\tbx::write(&writer, kIntelExtensionInterfaceVersion, &err);\n\t\t\tbx::write(&writer, uint32_t(0), &err);\n\t\t\tbx::write(&writer, uint32_t(0), &err);\n\n\t\t\tif (SUCCEEDED(setIntelExtension(_device, temp, sizeof(temp) ) ) )\n\t\t\t{\n\t\t\t\tbx::MemoryReader reader(&temp, sizeof(temp) );\n\t\t\t\tbx::skip(&reader, 16);\n\n\t\t\t\tuint32_t version;\n\t\t\t\tbx::read(&reader, version, &err);\n\n\t\t\t\tuint32_t driverVersion;\n\t\t\t\tbx::read(&reader, driverVersion, &err);\n\n\t\t\t\treturn version <= driverVersion;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tvoid resume(ID3D11Device* _device)\n\t{\n\t\tBX_UNUSED(_device);\n\t}\n\n\tvoid suspend(ID3D11Device* _device)\n\t{\n\t\tBX_UNUSED(_device);\n\t}\n\n\t/*\n\t * AMD GPU Services (AGS) library\n\t *\n\t * Reference(s):\n\t * - https://web.archive.org/web/20181126035805/https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK\n\t */\n\tenum AGS_RETURN_CODE\n\t{\n\t\tAGS_SUCCESS,\n\t\tAGS_INVALID_ARGS,\n\t\tAGS_OUT_OF_MEMORY,\n\t\tAGS_ERROR_MISSING_DLL,\n\t\tAGS_ERROR_LEGACY_DRIVER,\n\t\tAGS_EXTENSION_NOT_SUPPORTED,\n\t\tAGS_ADL_FAILURE,\n\t};\n\n\tenum AGS_DRIVER_EXTENSION\n\t{\n\t\tAGS_EXTENSION_QUADLIST          = 1 << 0,\n\t\tAGS_EXTENSION_UAV_OVERLAP       = 1 << 1,\n\t\tAGS_EXTENSION_DEPTH_BOUNDS_TEST = 1 << 2,\n\t\tAGS_EXTENSION_MULTIDRAWINDIRECT = 1 << 3,\n\t};\n\n\tstruct AGSDriverVersionInfo\n\t{\n\t\tchar strDriverVersion[256];\n\t\tchar strCatalystVersion[256];\n\t\tchar strCatalystWebLink[256];\n\t};\n\n\tstruct AGSContext;\n\n\ttypedef AGS_RETURN_CODE (__cdecl* PFN_AGS_INIT)(AGSContext**);\n\ttypedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DEINIT)(AGSContext*);\n\ttypedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_CROSSFIRE_GPU_COUNT)(AGSContext*, int32_t*);\n\ttypedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_TOTAL_GPU_COUNT)(AGSContext*, int32_t*);\n\ttypedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_GPU_MEMORY_SIZE)(AGSContext*, int32_t, int64_t*);\n\ttypedef AGS_RETURN_CODE (__cdecl* PFN_AGS_GET_DRIVER_VERSION_INFO)(AGSContext*, AGSDriverVersionInfo*);\n\ttypedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_INIT)(AGSContext*, ID3D11Device*, uint32_t*);\n\ttypedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_DEINIT)(AGSContext*);\n\ttypedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INSTANCED_INDIRECT)(AGSContext*, uint32_t, ID3D11Buffer*, uint32_t, uint32_t);\n\ttypedef AGS_RETURN_CODE (__cdecl* PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INDEXED_INSTANCED_INDIRECT)(AGSContext*, uint32_t, ID3D11Buffer*, uint32_t, uint32_t);\n\n\tstatic PFN_AGS_INIT   agsInit;\n\tstatic PFN_AGS_DEINIT agsDeInit;\n\tstatic PFN_AGS_GET_CROSSFIRE_GPU_COUNT  agsGetCrossfireGPUCount;\n\tstatic PFN_AGS_GET_TOTAL_GPU_COUNT      agsGetTotalGPUCount;\n\tstatic PFN_AGS_GET_GPU_MEMORY_SIZE      agsGetGPUMemorySize;\n\tstatic PFN_AGS_GET_DRIVER_VERSION_INFO  agsGetDriverVersionInfo;\n\tstatic PFN_AGS_DRIVER_EXTENSIONS_INIT   agsDriverExtensions_Init;\n\tstatic PFN_AGS_DRIVER_EXTENSIONS_DEINIT agsDriverExtensions_DeInit;\n\tstatic PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INSTANCED_INDIRECT         agsDriverExtensions_MultiDrawInstancedIndirect;\n\tstatic PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INDEXED_INSTANCED_INDIRECT agsDriverExtensions_MultiDrawIndexedInstancedIndirect;\n\n\ttypedef void (* MultiDrawIndirectFn)(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride);\n\n\tvoid stubMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride);\n\tvoid stubMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride);\n\n\tvoid amdAgsMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride);\n\tvoid amdAgsMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride);\n\n\tvoid nvapiMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride);\n\tvoid nvapiMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride);\n\n\tstatic MultiDrawIndirectFn multiDrawInstancedIndirect;\n\tstatic MultiDrawIndirectFn multiDrawIndexedInstancedIndirect;\n\n#if USE_D3D11_DYNAMIC_LIB\n\tstatic PFN_D3D11_CREATE_DEVICE  D3D11CreateDevice;\n\tstatic PFN_D3DPERF_SET_MARKER   D3DPERF_SetMarker;\n\tstatic PFN_D3DPERF_BEGIN_EVENT  D3DPERF_BeginEvent;\n\tstatic PFN_D3DPERF_END_EVENT    D3DPERF_EndEvent;\n#endif // USE_D3D11_DYNAMIC_LIB\n\n\tint  WINAPI d3d11Annotation_BeginEvent(DWORD _color, LPCWSTR _name);\n\tint  WINAPI d3d11Annotation_EndEvent();\n\tvoid WINAPI d3d11Annotation_SetMarker(DWORD _color, LPCWSTR _name);\n\n\tstruct RendererContextD3D11 : public RendererContextI\n\t{\n\t\tRendererContextD3D11()\n\t\t\t: m_d3d9Dll(NULL)\n\t\t\t, m_d3d11Dll(NULL)\n\t\t\t, m_renderDocDll(NULL)\n\t\t\t, m_agsDll(NULL)\n\t\t\t, m_ags(NULL)\n\t\t\t, m_featureLevel(D3D_FEATURE_LEVEL(0) )\n\t\t\t, m_swapChain(NULL)\n\t\t\t, m_msaaRt(NULL)\n\t\t\t, m_needPresent(false)\n\t\t\t, m_lost(false)\n\t\t\t, m_numWindows(0)\n\t\t\t, m_device(NULL)\n\t\t\t, m_deviceCtx(NULL)\n\t\t\t, m_annotation(NULL)\n\t\t\t, m_infoQueue(NULL)\n\t\t\t, m_backBufferColor(NULL)\n\t\t\t, m_backBufferDepthStencil(NULL)\n\t\t\t, m_currentColor(NULL)\n\t\t\t, m_currentDepthStencil(NULL)\n\t\t\t, m_captureTexture(NULL)\n\t\t\t, m_captureResolve(NULL)\n\t\t\t, m_maxAnisotropy(1)\n\t\t\t, m_depthClamp(false)\n\t\t\t, m_wireframe(false)\n\t\t\t, m_currentProgram(NULL)\n\t\t\t, m_vsChanges(0)\n\t\t\t, m_fsChanges(0)\n\t\t\t, m_rtMsaa(false)\n\t\t\t, m_timerQuerySupport(false)\n\t\t\t, m_directAccessSupport(false)\n\t\t{\n\t\t\tm_fbh.idx = kInvalidHandle;\n\t\t\tbx::memSet(&m_scd, 0, sizeof(m_scd) );\n\t\t\tbx::memSet(&m_windows, 0xff, sizeof(m_windows) );\n\t\t}\n\n\t\t~RendererContextD3D11()\n\t\t{\n\t\t}\n\n\t\tbool init(const Init& _init)\n\t\t{\n\t\t\tstruct ErrorState\n\t\t\t{\n\t\t\t\tenum Enum\n\t\t\t\t{\n\t\t\t\t\tDefault,\n\t\t\t\t\tLoadedD3D11,\n\t\t\t\t\tLoadedDXGI,\n\t\t\t\t};\n\t\t\t};\n\n\t\t\tErrorState::Enum errorState = ErrorState::Default;\n\n\t\t\tif (_init.debug\n\t\t\t||  _init.profile)\n\t\t\t{\n\t\t\t\tm_renderDocDll = loadRenderDoc();\n\t\t\t}\n\n\t\t\tm_fbh.idx = kInvalidHandle;\n\t\t\tbx::memSet(m_uniforms, 0, sizeof(m_uniforms) );\n\t\t\tbx::memSet(&m_resolution, 0, sizeof(m_resolution) );\n\n\t\t\tm_ags = NULL;\n\t\t\tm_agsDll = bx::dlopen(\n#if BX_ARCH_32BIT\n\t\t\t\t"amd_ags_x86.dll"\n#else\n\t\t\t\t"amd_ags_x64.dll"\n#endif // BX_ARCH_32BIT\n\t\t\t\t);\n\t\t\tif (NULL != m_agsDll)\n\t\t\t{\n\t\t\t\tagsInit   = (PFN_AGS_INIT  )bx::dlsym(m_agsDll, "agsInit");\n\t\t\t\tagsDeInit = (PFN_AGS_DEINIT)bx::dlsym(m_agsDll, "agsDeInit");\n\t\t\t\tagsGetCrossfireGPUCount    = (PFN_AGS_GET_CROSSFIRE_GPU_COUNT )bx::dlsym(m_agsDll, "agsGetCrossfireGPUCount");\n\t\t\t\tagsGetTotalGPUCount        = (PFN_AGS_GET_TOTAL_GPU_COUNT     )bx::dlsym(m_agsDll, "agsGetTotalGPUCount");\n\t\t\t\tagsGetGPUMemorySize        = (PFN_AGS_GET_GPU_MEMORY_SIZE     )bx::dlsym(m_agsDll, "agsGetGPUMemorySize");\n\t\t\t\tagsGetDriverVersionInfo    = (PFN_AGS_GET_DRIVER_VERSION_INFO )bx::dlsym(m_agsDll, "agsGetDriverVersionInfo");\n\t\t\t\tagsDriverExtensions_Init   = (PFN_AGS_DRIVER_EXTENSIONS_INIT  )bx::dlsym(m_agsDll, "agsDriverExtensions_Init");\n\t\t\t\tagsDriverExtensions_DeInit = (PFN_AGS_DRIVER_EXTENSIONS_DEINIT)bx::dlsym(m_agsDll, "agsDriverExtensions_DeInit");\n\t\t\t\tagsDriverExtensions_MultiDrawInstancedIndirect        = (PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INSTANCED_INDIRECT        )bx::dlsym(m_agsDll, "agsDriverExtensions_MultiDrawInstancedIndirect");\n\t\t\t\tagsDriverExtensions_MultiDrawIndexedInstancedIndirect = (PFN_AGS_DRIVER_EXTENSIONS_MULTIDRAW_INDEXED_INSTANCED_INDIRECT)bx::dlsym(m_agsDll, "agsDriverExtensions_MultiDrawIndexedInstancedIndirect");\n\n\t\t\t\tbool agsSupported = true\n\t\t\t\t\t&& NULL != agsInit\n\t\t\t\t\t&& NULL != agsDeInit\n\t\t\t\t\t&& NULL != agsGetCrossfireGPUCount\n\t\t\t\t\t&& NULL != agsGetTotalGPUCount\n\t\t\t\t\t&& NULL != agsGetGPUMemorySize\n\t\t\t\t\t&& NULL != agsGetDriverVersionInfo\n\t\t\t\t\t&& NULL != agsDriverExtensions_Init\n\t\t\t\t\t&& NULL != agsDriverExtensions_DeInit\n\t\t\t\t\t&& NULL != agsDriverExtensions_MultiDrawInstancedIndirect\n\t\t\t\t\t&& NULL != agsDriverExtensions_MultiDrawIndexedInstancedIndirect\n\t\t\t\t\t;\n\t\t\t\tif (agsSupported)\n\t\t\t\t{\n\t\t\t\t\tAGS_RETURN_CODE result = agsInit(&m_ags);\n\t\t\t\t\tagsSupported = AGS_SUCCESS == result;\n\t\t\t\t\tif (agsSupported)\n\t\t\t\t\t{\n\t\t\t\t\t\tAGSDriverVersionInfo vi;\n\t\t\t\t\t\tresult = agsGetDriverVersionInfo(m_ags, &vi);\n\t\t\t\t\t\tBX_TRACE("      Driver version: %s", vi.strDriverVersion);\n\t\t\t\t\t\tBX_TRACE("    Catalyst version: %s", vi.strCatalystVersion);\n\n\t\t\t\t\t\tint32_t numCrossfireGPUs = 0;\n\t\t\t\t\t\tresult = agsGetCrossfireGPUCount(m_ags, &numCrossfireGPUs);\n\t\t\t\t\t\tBX_TRACE("  Num crossfire GPUs: %d", numCrossfireGPUs);\n\n\t\t\t\t\t\tint32_t numGPUs = 0;\n\t\t\t\t\t\tresult = agsGetTotalGPUCount(m_ags, &numGPUs);\n\t\t\t\t\t\tBX_TRACE("            Num GPUs: %d", numGPUs);\n\n\t\t\t\t\t\tfor (int32_t ii = 0; ii < numGPUs; ++ii)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tint64_t memSize;\n\t\t\t\t\t\t\tresult = agsGetGPUMemorySize(m_ags, ii, &memSize);\n\t\t\t\t\t\t\tif (AGS_SUCCESS == result)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tchar memSizeStr[16];\n\t\t\t\t\t\t\t\tbx::prettify(memSizeStr, BX_COUNTOF(memSizeStr), memSize);\n\t\t\t\t\t\t\t\tBX_TRACE("     GPU #%d mem size: %s", ii, memSizeStr);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tBX_WARN(!agsSupported, "AMD/AGS supported.");\n\t\t\t\tif (!agsSupported)\n\t\t\t\t{\n\t\t\t\t\tif (NULL != m_ags)\n\t\t\t\t\t{\n\t\t\t\t\t\tagsDeInit(m_ags);\n\t\t\t\t\t\tm_ags = NULL;\n\t\t\t\t\t}\n\n\t\t\t\t\tbx::dlclose(m_agsDll);\n\t\t\t\t\tm_agsDll = NULL;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tm_nvapi.init();\n\n#if USE_D3D11_DYNAMIC_LIB\n\t\t\tconst char* d3d11DllName =\n#if BX_PLATFORM_LINUX\n\t\t\t\t"d3d11.so"\n#else\n\t\t\t\t"d3d11.dll"\n#endif // BX_PLATFORM_LINUX\n\t\t\t\t;\n\n\t\t\tm_d3d11Dll = bx::dlopen(d3d11DllName);\n\n\t\t\tif (NULL == m_d3d11Dll)\n\t\t\t{\n\t\t\t\tBX_TRACE("Init error: Failed to load %s.", d3d11DllName);\n\t\t\t\tgoto error;\n\t\t\t}\n\n\t\t\terrorState = ErrorState::LoadedD3D11;\n\n\t\t\tm_d3d9Dll = NULL;\n\n\t\t\tif (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) )\n\t\t\t{\n\t\t\t\t// D3D11_1.h has ID3DUserDefinedAnnotation\n\t\t\t\t// https://web.archive.org/web/20190207230424/https://docs.microsoft.com/en-us/windows/desktop/api/d3d11_1/nn-d3d11_1-id3duserdefinedannotation\n\t\t\t\tm_d3d9Dll = bx::dlopen("d3d9.dll");\n\t\t\t\tif (NULL != m_d3d9Dll)\n\t\t\t\t{\n\t\t\t\t\tD3DPERF_SetMarker  = (PFN_D3DPERF_SET_MARKER )bx::dlsym(m_d3d9Dll, "D3DPERF_SetMarker" );\n\t\t\t\t\tD3DPERF_BeginEvent = (PFN_D3DPERF_BEGIN_EVENT)bx::dlsym(m_d3d9Dll, "D3DPERF_BeginEvent");\n\t\t\t\t\tD3DPERF_EndEvent   = (PFN_D3DPERF_END_EVENT  )bx::dlsym(m_d3d9Dll, "D3DPERF_EndEvent"  );\n\n\t\t\t\t\tif (NULL == D3DPERF_SetMarker\n\t\t\t\t\t||  NULL == D3DPERF_BeginEvent\n\t\t\t\t\t||  NULL == D3DPERF_EndEvent)\n\t\t\t\t\t{\n\t\t\t\t\t\tBX_TRACE("Failed to initialize PIX events.");\n\n\t\t\t\t\t\tD3DPERF_SetMarker  = NULL;\n\t\t\t\t\t\tD3DPERF_BeginEvent = NULL;\n\t\t\t\t\t\tD3DPERF_EndEvent   = NULL;\n\n\t\t\t\t\t\tbx::dlclose(m_d3d9Dll);\n\t\t\t\t\t\tm_d3d9Dll = NULL;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tD3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)bx::dlsym(m_d3d11Dll, "D3D11CreateDevice");\n\t\t\tif (NULL == D3D11CreateDevice)\n\t\t\t{\n\t\t\t\tBX_TRACE("Init error: Function D3D11CreateDevice not found.");\n\t\t\t\tgoto error;\n\t\t\t}\n#endif // USE_D3D11_DYNAMIC_LIB\n\n\t\t\tm_device = (ID3D11Device*)g_platformData.context;\n\n\t\t\tif (!m_dxgi.init(g_caps) )\n\t\t\t{\n\t\t\t\tgoto error;\n\t\t\t}\n\n\t\t\terrorState = ErrorState::LoadedDXGI;\n\n\t\t\tif (NULL == m_device)\n\t\t\t{\n\t\t\t\tif (NULL != m_renderDocDll)\n\t\t\t\t{\n\t\t\t\t\tsetGraphicsDebuggerPresent(true);\n\t\t\t\t}\n\n\t\t\t\tD3D_FEATURE_LEVEL featureLevel[] =\n\t\t\t\t{\n\t\t\t\t\tD3D_FEATURE_LEVEL_12_1,\n\t\t\t\t\tD3D_FEATURE_LEVEL_12_0,\n\t\t\t\t\tD3D_FEATURE_LEVEL_11_1,\n\t\t\t\t\tD3D_FEATURE_LEVEL_11_0,\n\t\t\t\t\tD3D_FEATURE_LEVEL_10_1,\n\t\t\t\t\tD3D_FEATURE_LEVEL_10_0,\n#if BX_PLATFORM_WINRT\n\t\t\t\t\tD3D_FEATURE_LEVEL_9_3,\n\t\t\t\t\tD3D_FEATURE_LEVEL_9_2,\n#endif // BX_PLATFORM_WINRT\n\t\t\t\t};\n\n\t\t\t\tHRESULT hr = S_OK;\n\n\t\t\t\tfor (;;)\n\t\t\t\t{\n\t\t\t\t\tuint32_t flags = 0\n\t\t\t\t\t\t| D3D11_CREATE_DEVICE_SINGLETHREADED\n\t\t\t\t\t\t| D3D11_CREATE_DEVICE_BGRA_SUPPORT\n//\t\t\t\t\t\t| D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS\n\t\t\t\t\t\t| (_init.debug ? D3D11_CREATE_DEVICE_DEBUG : 0)\n\t\t\t\t\t\t;\n\n\t\t\t\t\thr = E_FAIL;\n\t\t\t\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(featureLevel) && FAILED(hr);)\n\t\t\t\t\t{\n\t\t\t\t\t\thr = D3D11CreateDevice(m_dxgi.m_adapter\n\t\t\t\t\t\t\t, m_dxgi.m_driverType\n\t\t\t\t\t\t\t, NULL\n\t\t\t\t\t\t\t, flags\n\t\t\t\t\t\t\t, &featureLevel[ii]\n\t\t\t\t\t\t\t, BX_COUNTOF(featureLevel)-ii\n\t\t\t\t\t\t\t, D3D11_SDK_VERSION\n\t\t\t\t\t\t\t, &m_device\n\t\t\t\t\t\t\t, &m_featureLevel\n\t\t\t\t\t\t\t, &m_deviceCtx\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\tBX_WARN(FAILED(hr), "Direct3D11 device feature level %d.%d."\n\t\t\t\t\t\t\t, (m_featureLevel >> 12) & 0xf\n\t\t\t\t\t\t\t, (m_featureLevel >>  8) & 0xf\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\tif (FAILED(hr)\n\t\t\t\t\t\t&&  0 != (flags & D3D11_CREATE_DEVICE_DEBUG) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Try without debug in case D3D11 SDK Layers\n\t\t\t\t\t\t\t// is not present?\n\t\t\t\t\t\t\tflags &= ~D3D11_CREATE_DEVICE_DEBUG;\n\n\t\t\tDX_RELEASE(m_swapChain, 0);\n\t\t\tDX_RELEASE(m_deviceCtx, 0);\n\t\t\tDX_RELEASE(m_device, 0);\n\t\t\tDX_RELEASE(m_factory, 0);\n\n\t\t\tunloadRenderDoc(m_renderdocdll);\n\n\t\t\t\t\tif (FAILED(hr)\n\t\t\t\t\t&&  D3D_DRIVER_TYPE_WARP != m_dxgi.m_driverType)\n\t\t\t\t\t{\n\t\t\t\t\t\t// Try with WARP\n\t\t\t\t\t\tm_dxgi.m_driverType = D3D_DRIVER_TYPE_WARP;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (FAILED(hr) )\n\t\t\t\t{\n\t\t\t\t\tBX_TRACE("Init error: Unable to create Direct3D11 device.");\n\t\t\t\t\tgoto error;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tm_device->GetImmediateContext(&m_deviceCtx);\n\n\t\t\t\tif (NULL == m_deviceCtx)\n\t\t\t\t{\n\t\t\t\t\tBX_TRACE("Init error: Unable to retrieve Direct3D11 ImmediateContext.");\n\t\t\t\t\tgoto error;\n\t\t\t\t}\n\n\t\t\t\tm_featureLevel = m_device->GetFeatureLevel();\n\t\t\t}\n\n\t\t\tm_dxgi.update(m_device);\n\n\t\t\t{\n\t\t\t\tm_deviceInterfaceVersion = 0;\n\t\t\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(s_d3dDeviceIIDs); ++ii)\n\t\t\t\t{\n\t\t\t\t\tID3D11Device* device;\n\t\t\t\t\tHRESULT hr = m_device->QueryInterface(s_d3dDeviceIIDs[ii], (void**)&device);\n\t\t\t\t\tif (SUCCEEDED(hr) )\n\t\t\t\t\t{\n\t\t\t\t\t\tdevice->Release(); // BK - ignore ref count.\n\t\t\t\t\t\tm_deviceInterfaceVersion = BX_COUNTOF(s_d3dDeviceIIDs)-ii;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t{ ///\n\t\t\t\t\tIDXGIDevice* renderdoc;\n\t\t\t\t\tHRESULT hr = m_device->QueryInterface(IID_IDXGIDeviceRenderDoc, (void**)&renderdoc);\n\t\t\t\t\tif (SUCCEEDED(hr) )\n\t\t\t\t\t{\n\t\t\t\t\t\tsetGraphicsDebuggerPresent(true);\n\t\t\t\t\t\tDX_RELEASE(renderdoc, 2);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tIUnknown* device = m_device;\n\t\t\t\t\t\tsetGraphicsDebuggerPresent(2 != getRefCount(device) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (BGFX_PCI_ID_NVIDIA != m_dxgi.m_adapterDesc.VendorId)\n\t\t\t\t{\n\t\t\t\t\tm_nvapi.shutdown();\n\t\t\t\t}\n\n\t\t\t\tm_msaaRt = NULL;\n\n\t\t\t\tif (NULL == g_platformData.backBuffer)\n\t\t\t\t{\n\t\t\t\t\tHRESULT hr = S_OK;\n\n\t\t\t\t\tm_swapEffect =\n#if BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS\n\t\t\t\t\t\tDXGI_SWAP_EFFECT_FLIP_DISCARD\n#else\n\t\t\t\t\t\tDXGI_SWAP_EFFECT_FLIP_SEQUENTIAL\n#endif // BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS\n\t\t\t\t\t\t;\n\n\t\t\t\t\tm_swapBufferCount = bx::clamp<uint8_t>(_init.resolution.numBackBuffers, 2, BGFX_CONFIG_MAX_BACK_BUFFERS);\n\n\t\t\t\t\tbx::memSet(&m_scd, 0, sizeof(m_scd) );\n\t\t\t\t\tm_scd.width  = _init.resolution.width;\n\t\t\t\t\tm_scd.height = _init.resolution.height;\n\n\t\t\t\t\t/*\n\t\t\t\t\t * According to https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/converting-data-color-space ,\n\t\t\t\t\t * it is OK to create the backbuffer with m_fmt (a non- _SRGB format), and then create the render target view into it\n\t\t\t\t\t * with m_fmtSrgb (the _SRGB format of same), and it will work identically as if you had created the swapchain with\n\t\t\t\t\t * m_fmtSrgb as the backbuffer format.\n\t\t\t\t\t *\n\t\t\t\t\t * Moreover, it is actually not desirable to create the backbuffer with an _SRGB format, because that\n\t\t\t\t\t * is incompatible with the flip presentation model, which is desirable for various reasons including\n\t\t\t\t\t * player embedding.\n\t\t\t\t\t */\n\t\t\t\t\tm_scd.format = s_textureFormat[_init.resolution.format].m_fmt;\n\n\t\t\t\t\tupdateMsaa(m_scd.format);\n\t\t\t\t\tm_scd.sampleDesc  = s_msaa[(_init.resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT];\n\n\t\t\t\t\tm_scd.bufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;\n\t\t\t\t\tm_scd.bufferCount = m_swapBufferCount;\n\t\t\t\t\tm_scd.scaling = 0 == g_platformData.ndt\n\t\t\t\t\t\t? DXGI_SCALING_NONE\n\t\t\t\t\t\t: DXGI_SCALING_STRETCH\n\t\t\t\t\t\t;\n\t\t\t\t\tm_scd.swapEffect = m_swapEffect;\n\n\t\t\t\t\tm_scd.alphaMode = (_init.resolution.reset & BGFX_RESET_TRANSPARENT_BACKBUFFER)\n\t\t\t\t\t\t? DXGI_ALPHA_MODE_PREMULTIPLIED\n\t\t\t\t\t\t: DXGI_ALPHA_MODE_IGNORE\n\t\t\t\t\t\t;\n\n\t\t\t\t\tm_scd.flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;\n\n\t\t\t\t\tm_scd.maxFrameLatency = bx::min<uint8_t>(_init.resolution.maxFrameLatency, BGFX_CONFIG_MAX_FRAME_LATENCY);\n\t\t\t\t\tm_scd.nwh             = g_platformData.nwh;\n\t\t\t\t\tm_scd.ndt             = g_platformData.ndt;\n\t\t\t\t\tm_scd.windowed        = true;\n\n\t\t\t\t\tif (NULL != m_scd.nwh)\n\t\t\t\t\t{\n\t\t\t\t\t\thr = m_dxgi.createSwapChain(m_device\n\t\t\t\t\t\t\t, m_scd\n\t\t\t\t\t\t\t, &m_swapChain\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (FAILED(hr) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tBX_TRACE(\n\t\t\t\t\t\t\t\t  "CreateSwapChain with DXGI_SWAP_EFFECT(%d) failed with HRESULT(%x)"\n\t\t\t\t\t\t\t\t, m_scd.swapEffect\n\t\t\t\t\t\t\t\t, hr\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t// DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL is not available on win7\n\t\t\t\t\t\t\t// Try again with DXGI_SWAP_EFFECT_DISCARD\n\t\t\t\t\t\t\tm_swapEffect      = DXGI_SWAP_EFFECT_DISCARD;\n\t\t\t\t\t\t\tm_swapBufferCount = 1;\n\n\t\t\t\t\t\t\tm_scd.bufferCount = m_swapBufferCount;\n\t\t\t\t\t\t\tm_scd.swapEffect  = m_swapEffect;\n\t\t\t\t\t\t\thr = m_dxgi.createSwapChain(m_device\n\t\t\t\t\t\t\t\t, m_scd\n\t\t\t\t\t\t\t\t, &m_swapChain\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif (FAILED(hr) )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tBX_TRACE("Init error: Failed to create swap chain.");\n\t\t\t\t\t\t\t\tgoto error;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tm_resolution       = _init.resolution;\n\t\t\t\t\t\tm_resolution.reset = _init.resolution.reset & (~BGFX_RESET_INTERNAL_FORCE);\n\n\t\t\t\t\t\tm_textVideoMem.resize(false, _init.resolution.width, _init.resolution.height);\n\t\t\t\t\t\tm_textVideoMem.clear();\n\n\t\t\t\t\t\tif (1 < m_scd.sampleDesc.Count)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tD3D11_TEXTURE2D_DESC desc;\n\t\t\t\t\t\t\tdesc.Width      = m_scd.width;\n\t\t\t\t\t\t\tdesc.Height     = m_scd.height;\n\t\t\t\t\t\t\tdesc.MipLevels  = 1;\n\t\t\t\t\t\t\tdesc.ArraySize  = 1;\n\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t* According to https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/converting-data-color-space ,\n\t\t\t\t\t\t\t* ONLY the backbuffer from swapchain can be created without *_SRGB format, custom backbuffer should be created the same\n\t\t\t\t\t\t\t* format as well as render target view.\n\t\t\t\t\t\t\t*/\n\t\t\t\t\t\t\tdesc.Format     = (m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) ? s_textureFormat[m_resolution.format].m_fmtSrgb : s_textureFormat[m_resolution.format].m_fmt;\n\t\t\t\t\t\t\tdesc.SampleDesc = m_scd.sampleDesc;\n\t\t\t\t\t\t\tdesc.Usage      = D3D11_USAGE_DEFAULT;\n\t\t\t\t\t\t\tdesc.BindFlags  = D3D11_BIND_RENDER_TARGET;\n\t\t\t\t\t\t\tdesc.CPUAccessFlags = 0;\n\t\t\t\t\t\t\tdesc.MiscFlags      = 0;\n\t\t\t\t\t\t\tDX_CHECK(m_device->CreateTexture2D(&desc, NULL, &m_msaaRt) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n#if BX_PLATFORM_WINDOWS\n\t\t\t\t\tDX_CHECK(m_dxgi.m_factory->MakeWindowAssociation( (HWND)g_platformData.nwh, 0\n\t\t\t\t\t\t| DXGI_MWA_NO_WINDOW_CHANGES\n\t\t\t\t\t\t| DXGI_MWA_NO_ALT_ENTER\n\t\t\t\t\t\t) );\n#endif // BX_PLATFORM_WINDOWS\n\n\t\t\t\t\tif (FAILED(hr) )\n\t\t\t\t\t{\n\t\t\t\t\t\tBX_TRACE("Init error: Failed to create swap chain.");\n\t\t\t\t\t\tgoto error;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tbx::memSet(&m_scd, 0, sizeof(m_scd) );\n\t\t\t\t\tm_scd.sampleDesc.Count   = 1;\n\t\t\t\t\tm_scd.sampleDesc.Quality = 0;\n\t\t\t\t\tm_scd.width  = _init.resolution.width;\n\t\t\t\t\tm_scd.height = _init.resolution.height;\n\t\t\t\t\tm_backBufferColor        = (ID3D11RenderTargetView*)g_platformData.backBuffer;\n\t\t\t\t\tm_backBufferDepthStencil = (ID3D11DepthStencilView*)g_platformData.backBufferDS;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tm_numWindows = 1;\n\n#if USE_D3D11_DYNAMIC_LIB\n\t\t\tif (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) )\n\t\t\t{\n\t\t\t\tHRESULT hr = m_deviceCtx->QueryInterface(IID_ID3DUserDefinedAnnotation, (void**)&m_annotation);\n\n\t\t\t\tif (SUCCEEDED(hr) )\n\t\t\t\t{\n\t\t\t\t\tD3DPERF_BeginEvent = d3d11Annotation_BeginEvent;\n\t\t\t\t\tD3DPERF_EndEvent   = d3d11Annotation_EndEvent;\n\t\t\t\t\tD3DPERF_SetMarker  = d3d11Annotation_SetMarker;\n\t\t\t\t}\n\t\t\t}\n#endif // USE_D3D11_DYNAMIC_LIB\n\n\t\t\tif (_init.debug)\n\t\t\t{\n\t\t\t\tHRESULT hr = m_device->QueryInterface(IID_ID3D11InfoQueue, (void**)&m_infoQueue);\n\n\t\t\t\tif (SUCCEEDED(hr) )\n\t\t\t\t{\n\t\t\t\t\tm_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);\n\t\t\t\t\tm_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR,      false);\n\t\t\t\t\tm_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING,    false);\n\t\t\t\t\tm_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_INFO,       false);\n\t\t\t\t\tm_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_MESSAGE,    false);\n\n\t\t\t\t\tD3D11_INFO_QUEUE_FILTER filter;\n\t\t\t\t\tbx::memSet(&filter, 0, sizeof(filter) );\n\n\t\t\t\t\tD3D11_MESSAGE_CATEGORY catlist[] =\n\t\t\t\t\t{\n\t\t\t\t\t\tD3D11_MESSAGE_CATEGORY_STATE_CREATION,\n\t\t\t\t\t};\n\n\t\t\t\t\tfilter.DenyList.NumCategories = BX_COUNTOF(catlist);\n\t\t\t\t\tfilter.DenyList.pCategoryList = catlist;\n\n\t\t\t\t\tD3D11_MESSAGE_ID idlist[] =\n\t\t\t\t\t{\n\t\t\t\t\t\tD3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET,\n\t\t\t\t\t\tD3D11_MESSAGE_ID_QUERY_BEGIN_ABANDONING_PREVIOUS_RESULTS,\n\t\t\t\t\t};\n\n\t\t\t\t\tfilter.DenyList.NumIDs  = BX_COUNTOF(idlist);\n\t\t\t\t\tfilter.DenyList.pIDList = idlist;\n\n\t\t\t\t\tm_infoQueue->PushStorageFilter(&filter);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t{\n\t\t\t\tg_caps.supported |= (0\n\t\t\t\t\t| BGFX_CAPS_TEXTURE_3D\n\t\t\t\t\t| BGFX_CAPS_VERTEX_ATTRIB_HALF\n\t\t\t\t\t| BGFX_CAPS_VERTEX_ATTRIB_UINT10\n\t\t\t\t\t| BGFX_CAPS_VERTEX_ID\n\t\t\t\t\t| BGFX_CAPS_FRAGMENT_DEPTH\n\t\t\t\t\t| (getIntelExtensions(m_device)\n\t\t\t\t\t\t? BGFX_CAPS_FRAGMENT_ORDERING\n\t\t\t\t\t\t| BGFX_CAPS_TEXTURE_DIRECT_ACCESS\n\t\t\t\t\t\t: 0)\n\t\t\t\t\t| BGFX_CAPS_SWAP_CHAIN\n\t\t\t\t\t| BGFX_CAPS_DRAW_INDIRECT\n\t\t\t\t\t| BGFX_CAPS_TEXTURE_BLIT\n\t\t\t\t\t| BGFX_CAPS_TEXTURE_READ_BACK\n\t\t\t\t\t| ( (m_featureLevel >= D3D_FEATURE_LEVEL_9_2)\n\t\t\t\t\t\t? BGFX_CAPS_OCCLUSION_QUERY\n\t\t\t\t\t\t: 0)\n\t\t\t\t\t| BGFX_CAPS_ALPHA_TO_COVERAGE\n\t\t\t\t\t| ( (m_deviceInterfaceVersion >= 3)\n\t\t\t\t\t\t? BGFX_CAPS_CONSERVATIVE_RASTER\n\t\t\t\t\t\t: 0)\n\t\t\t\t\t| BGFX_CAPS_TEXTURE_2D_ARRAY\n\t\t\t\t\t| BGFX_CAPS_TEXTURE_CUBE_ARRAY\n\t\t\t\t\t| ((m_featureLevel >= D3D_FEATURE_LEVEL_11_1)\n\t\t\t\t\t\t? BGFX_CAPS_IMAGE_RW\n\t\t\t\t\t\t: 0)\n\t\t\t\t\t);\n\n\t\t\t\tm_timerQuerySupport   = m_featureLevel >= D3D_FEATURE_LEVEL_10_0;\n\t\t\t\tm_directAccessSupport = 0 != (g_caps.supported & BGFX_CAPS_TEXTURE_DIRECT_ACCESS);\n\n\t\t\t\tif (m_featureLevel <= D3D_FEATURE_LEVEL_9_2)\n\t\t\t\t{\n\t\t\t\t\tg_caps.limits.maxTextureSize   = D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;\n\t\t\t\t\tg_caps.limits.maxFBAttachments = uint8_t(bx::uint32_min(\n\t\t\t\t\t\t  D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT\n\t\t\t\t\t\t, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS\n\t\t\t\t\t\t) );\n\t\t\t\t\tg_caps.limits.maxVertexStreams = uint8_t(bx::uint32_min(\n\t\t\t\t\t\t  16\n\t\t\t\t\t\t, BGFX_CONFIG_MAX_VERTEX_STREAMS\n\t\t\t\t\t\t) );\n\t\t\t\t}\n\t\t\t\telse if (m_featureLevel == D3D_FEATURE_LEVEL_9_3)\n\t\t\t\t{\n\t\t\t\t\tg_caps.limits.maxTextureSize   = D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;\n\t\t\t\t\tg_caps.limits.maxFBAttachments = uint8_t(bx::uint32_min(\n\t\t\t\t\t\t  D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT\n\t\t\t\t\t\t, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS\n\t\t\t\t\t\t) );\n\t\t\t\t\tg_caps.limits.maxVertexStreams = uint8_t(bx::uint32_min(\n\t\t\t\t\t\t  16\n\t\t\t\t\t\t, BGFX_CONFIG_MAX_VERTEX_STREAMS\n\t\t\t\t\t\t) );\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tg_caps.limits.maxComputeBindings = bx::min(BGFX_MAX_COMPUTE_BINDINGS\n\t\t\t\t\t\t, D3D_FEATURE_LEVEL_11_1 <= m_featureLevel\n\t\t\t\t\t\t? D3D11_1_UAV_SLOT_COUNT\n\t\t\t\t\t\t: D3D11_PS_CS_UAV_REGISTER_COUNT\n\t\t\t\t\t\t);\n\n\t\t\t\t\tg_caps.supported |= BGFX_CAPS_TEXTURE_COMPARE_ALL;\n\t\t\t\t\tg_caps.limits.maxTextureSize   = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;\n\t\t\t\t\tg_caps.limits.maxTextureLayers = D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;\n\t\t\t\t\tg_caps.limits.maxFBAttachments = uint8_t(bx::uint32_min(\n\t\t\t\t\t\t  D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT\n\t\t\t\t\t\t, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS\n\t\t\t\t\t\t) );\n\t\t\t\t\tg_caps.limits.maxVertexStreams = uint8_t(bx::uint32_min(\n\t\t\t\t\t\t  D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT\n\t\t\t\t\t\t, BGFX_CONFIG_MAX_VERTEX_STREAMS\n\t\t\t\t\t\t) );\n\t\t\t\t}\n\n\t\t\t\t// 32-bit indices only supported on 9_2+.\n\t\t\t\tif (m_featureLevel >= D3D_FEATURE_LEVEL_9_2)\n\t\t\t\t{\n\t\t\t\t\tg_caps.supported |= BGFX_CAPS_INDEX32;\n\t\t\t\t}\n\n\t\t\t\t// Independent blend only supported on 10_1+.\n\t\t\t\tif (m_featureLevel >= D3D_FEATURE_LEVEL_10_1)\n\t\t\t\t{\n\t\t\t\t\tg_caps.supported |= BGFX_CAPS_BLEND_INDEPENDENT;\n\t\t\t\t}\n\n\t\t\t\t// Compute support is optional on 10_0 and 10_1 targets.\n\t\t\t\tif (m_featureLevel == D3D_FEATURE_LEVEL_10_0\n\t\t\t\t||  m_featureLevel == D3D_FEATURE_LEVEL_10_1)\n\t\t\t\t{\n\t\t\t\t\tD3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS data;\n\t\t\t\t\tHRESULT hr = m_device->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &data, sizeof(data) );\n\t\t\t\t\tif (SUCCEEDED(hr)\n\t\t\t\t\t&&  data.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x)\n\t\t\t\t\t{\n\t\t\t\t\t\tg_caps.supported |= BGFX_CAPS_COMPUTE;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (m_featureLevel >= D3D_FEATURE_LEVEL_11_0)\n\t\t\t\t{\n\t\t\t\t\tg_caps.supported |= BGFX_CAPS_COMPUTE;\n\t\t\t\t}\n\n\t\t\t\t// Instancing fully supported on 9_3+, optionally partially supported at lower levels.\n\t\t\t\tif (m_featureLevel >= D3D_FEATURE_LEVEL_9_3)\n\t\t\t\t{\n\t\t\t\t\tg_caps.supported |= BGFX_CAPS_INSTANCING;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tD3D11_FEATURE_DATA_D3D9_SIMPLE_INSTANCING_SUPPORT data;\n\t\t\t\t\tHRESULT hr = m_device->CheckFeatureSupport(D3D11_FEATURE_D3D9_SIMPLE_INSTANCING_SUPPORT, &data, sizeof(data) );\n\t\t\t\t\tif (SUCCEEDED(hr)\n\t\t\t\t\t&&  data.SimpleInstancingSupported)\n\t\t\t\t\t{\n\t\t\t\t\t\tg_caps.supported |= BGFX_CAPS_INSTANCING;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// shadow compare is optional on 9_1 through 9_3 targets\n\t\t\t\tif (m_featureLevel <= D3D_FEATURE_LEVEL_9_3)\n\t\t\t\t{\n\t\t\t\t\tD3D11_FEATURE_DATA_D3D9_SHADOW_SUPPORT data;\n\t\t\t\t\tHRESULT hr = m_device->CheckFeatureSupport(D3D11_FEATURE_D3D9_SHADOW_SUPPORT, &data, sizeof(data) );\n\t\t\t\t\tif (SUCCEEDED(hr)\n\t\t\t\t\t&&  data.SupportsDepthAsTextureWithLessEqualComparisonFilter)\n\t\t\t\t\t{\n\t\t\t\t\t\tg_caps.supported |= BGFX_CAPS_TEXTURE_COMPARE_LEQUAL;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// support for SV_ViewportArrayIndex and SV_RenderTargetArrayIndex in the vertex shader is optional\n\t\t\t\t{\n\t\t\t\t\tD3D11_FEATURE_DATA_D3D11_OPTIONS3 data;\n\t\t\t\t\tHRESULT hr = m_device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &data, sizeof(data) );\n\t\t\t\t\tif (SUCCEEDED(hr)\n\t\t\t\t\t&&  data.VPAndRTArrayIndexFromAnyShaderFeedingRasterizer)\n\t\t\t\t\t{\n\t\t\t\t\t\tg_caps.supported |= BGFX_CAPS_VIEWPORT_LAYER_ARRAY;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor (uint32_t ii = 0; ii < TextureFormat::Count; ++ii)\n\t\t\t\t{\n\t\t\t\t\tuint16_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE;\n\n\t\t\t\t\tconst DXGI_FORMAT fmt = bimg::isDepth(bimg::TextureFormat::Enum(ii) )\n\t\t\t\t\t\t? s_textureFormat[ii].m_fmtDsv\n\t\t\t\t\t\t: s_textureFormat[ii].m_fmt\n\t\t\t\t\t\t;\n\t\t\t\t\tconst DXGI_FORMAT fmtSrgb = s_textureFormat[ii].m_fmtSrgb;\n\n\t\t\t\t\tif (DXGI_FORMAT_UNKNOWN != fmt)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (BX_ENABLED(BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tD3D11_FEATURE_DATA_FORMAT_SUPPORT data;\n\t\t\t\t\t\t\tdata.InFormat = fmt;\n\t\t\t\t\t\t\tHRESULT hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) );\n\t\t\t\t\t\t\tif (SUCCEEDED(hr) )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsupport |= 0 != (data.OutFormatSupport & (0\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_TEXTURE2D\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_TEXTURE3D\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_TEXTURECUBE\n\t\t\t\t\t\t\t\t\t\t) )\n\t\t\t\t\t\t\t\t\t\t? BGFX_CAPS_FORMAT_TEXTURE_2D\n\t\t\t\t\t\t\t\t\t\t: BGFX_CAPS_FORMAT_TEXTURE_NONE\n\t\t\t\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\t\tsupport |= 0 != (data.OutFormatSupport & (0\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_TEXTURE3D\n\t\t\t\t\t\t\t\t\t\t) )\n\t\t\t\t\t\t\t\t\t\t? BGFX_CAPS_FORMAT_TEXTURE_3D\n\t\t\t\t\t\t\t\t\t\t: BGFX_CAPS_FORMAT_TEXTURE_NONE\n\t\t\t\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\t\tsupport |= 0 != (data.OutFormatSupport & (0\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_TEXTURECUBE\n\t\t\t\t\t\t\t\t\t\t) )\n\t\t\t\t\t\t\t\t\t\t? BGFX_CAPS_FORMAT_TEXTURE_CUBE\n\t\t\t\t\t\t\t\t\t\t: BGFX_CAPS_FORMAT_TEXTURE_NONE\n\t\t\t\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\t\tsupport |= 0 != (data.OutFormatSupport & (0\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_BUFFER\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_IA_INDEX_BUFFER\n\t\t\t\t\t\t\t\t\t\t) )\n\t\t\t\t\t\t\t\t\t\t? BGFX_CAPS_FORMAT_TEXTURE_VERTEX\n\t\t\t\t\t\t\t\t\t\t: BGFX_CAPS_FORMAT_TEXTURE_NONE\n\t\t\t\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\t\tsupport |= 0 != (data.OutFormatSupport & (0\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_SHADER_LOAD\n\t\t\t\t\t\t\t\t\t\t) )\n\t\t\t\t\t\t\t\t\t\t? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ\n\t\t\t\t\t\t\t\t\t\t: BGFX_CAPS_FORMAT_TEXTURE_NONE\n\t\t\t\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\t\tsupport |= 0 != (data.OutFormatSupport & (0\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_RENDER_TARGET\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_DEPTH_STENCIL\n\t\t\t\t\t\t\t\t\t\t) )\n\t\t\t\t\t\t\t\t\t\t? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER\n\t\t\t\t\t\t\t\t\t\t: BGFX_CAPS_FORMAT_TEXTURE_NONE\n\t\t\t\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\t\tsupport |= 0 != (data.OutFormatSupport & (0\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET\n\t\t\t\t\t\t\t\t\t\t) )\n\t\t\t\t\t\t\t\t\t\t? BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA\n\t\t\t\t\t\t\t\t\t\t: BGFX_CAPS_FORMAT_TEXTURE_NONE\n\t\t\t\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\t\tsupport |= 0 != (data.OutFormatSupport & (0\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_MULTISAMPLE_LOAD\n\t\t\t\t\t\t\t\t\t\t) )\n\t\t\t\t\t\t\t\t\t\t? BGFX_CAPS_FORMAT_TEXTURE_MSAA\n\t\t\t\t\t\t\t\t\t\t: BGFX_CAPS_FORMAT_TEXTURE_NONE\n\t\t\t\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\t\tsupport |= 0 != (data.OutFormatSupport & (0\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_MIP_AUTOGEN\n\t\t\t\t\t\t\t\t\t\t) )\n\t\t\t\t\t\t\t\t\t\t? BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN\n\t\t\t\t\t\t\t\t\t\t: BGFX_CAPS_FORMAT_TEXTURE_NONE\n\t\t\t\t\t\t\t\t\t\t;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tBX_TRACE(\n\t\t\t\t\t\t\t\t\t  "CheckFeatureSupport failed with HRESULT(%x) for format %s."\n\t\t\t\t\t\t\t\t\t, hr\n\t\t\t\t\t\t\t\t\t, getName(TextureFormat::Enum(ii) )\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (0 != (support & BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ) )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tD3D11_FEATURE_DATA_FORMAT_SUPPORT2 data2;\n\n\t\t\t\t\t\t\t\t// clear image flag for additional testing\n\t\t\t\t\t\t\t\tsupport &= ~BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ;\n\n\t\t\t\t\t\t\t\tdata2.InFormat = s_textureFormat[ii].m_fmt;\n\t\t\t\t\t\t\t\thr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT2, &data2, sizeof(data2) );\n\t\t\t\t\t\t\t\tif (SUCCEEDED(hr) )\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tsupport |= 0 != (data2.OutFormatSupport2 & (0\n\t\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT2_UAV_TYPED_LOAD\n\t\t\t\t\t\t\t\t\t\t\t) )\n\t\t\t\t\t\t\t\t\t\t\t? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ\n\t\t\t\t\t\t\t\t\t\t\t: BGFX_CAPS_FORMAT_TEXTURE_NONE\n\t\t\t\t\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\t\t\tsupport |= 0 != (data2.OutFormatSupport2 & (0\n\t\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT2_UAV_TYPED_STORE\n\t\t\t\t\t\t\t\t\t\t\t) )\n\t\t\t\t\t\t\t\t\t\t\t? BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE\n\t\t\t\t\t\t\t\t\t\t\t: BGFX_CAPS_FORMAT_TEXTURE_NONE\n\t\t\t\t\t\t\t\t\t\t\t;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsupport |= 0\n\t\t\t\t\t\t\t\t| BGFX_CAPS_FORMAT_TEXTURE_2D\n\t\t\t\t\t\t\t\t| BGFX_CAPS_FORMAT_TEXTURE_3D\n\t\t\t\t\t\t\t\t| BGFX_CAPS_FORMAT_TEXTURE_CUBE\n\t\t\t\t\t\t\t\t| BGFX_CAPS_FORMAT_TEXTURE_VERTEX\n\t\t\t\t\t\t\t\t| BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER\n\t\t\t\t\t\t\t\t| BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA\n\t\t\t\t\t\t\t\t| BGFX_CAPS_FORMAT_TEXTURE_MSAA\n\t\t\t\t\t\t\t\t| BGFX_CAPS_FORMAT_TEXTURE_IMAGE_READ\n\t\t\t\t\t\t\t\t| BGFX_CAPS_FORMAT_TEXTURE_IMAGE_WRITE\n\t\t\t\t\t\t\t\t;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (DXGI_FORMAT_UNKNOWN != fmtSrgb)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (BX_ENABLED(BX_PLATFORM_LINUX || BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstruct D3D11_FEATURE_DATA_FORMAT_SUPPORT\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tDXGI_FORMAT InFormat;\n\t\t\t\t\t\t\t\tUINT OutFormatSupport;\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\tD3D11_FEATURE_DATA_FORMAT_SUPPORT data;\n\t\t\t\t\t\t\tdata.InFormat = fmtSrgb;\n\t\t\t\t\t\t\tHRESULT hr = m_device->CheckFeatureSupport(D3D11_FEATURE_FORMAT_SUPPORT, &data, sizeof(data) );\n\t\t\t\t\t\t\tif (SUCCEEDED(hr) )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsupport |= 0 != (data.OutFormatSupport & (0\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_TEXTURE2D\n\t\t\t\t\t\t\t\t\t\t) )\n\t\t\t\t\t\t\t\t\t\t? BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB\n\t\t\t\t\t\t\t\t\t\t: BGFX_CAPS_FORMAT_TEXTURE_NONE\n\t\t\t\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\t\tsupport |= 0 != (data.OutFormatSupport & (0\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_TEXTURE3D\n\t\t\t\t\t\t\t\t\t\t) )\n\t\t\t\t\t\t\t\t\t\t? BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB\n\t\t\t\t\t\t\t\t\t\t: BGFX_CAPS_FORMAT_TEXTURE_NONE\n\t\t\t\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\t\tsupport |= 0 != (data.OutFormatSupport & (0\n\t\t\t\t\t\t\t\t\t\t| D3D11_FORMAT_SUPPORT_TEXTURECUBE\n\t\t\t\t\t\t\t\t\t\t) )\n\t\t\t\t\t\t\t\t\t\t? BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB\n\t\t\t\t\t\t\t\t\t\t: BGFX_CAPS_FORMAT_TEXTURE_NONE\n\t\t\t\t\t\t\t\t\t\t;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tBX_TRACE(\n\t\t\t\t\t\t\t\t\t  "CheckFeatureSupport failed with HRESULT(%x) for sRGB format %s."\n\t\t\t\t\t\t\t\t\t, hr\n\t\t\t\t\t\t\t\t\t, getName(TextureFormat::Enum(ii) )\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsupport |= 0\n\t\t\t\t\t\t\t\t| BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB\n\t\t\t\t\t\t\t\t| BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB\n\t\t\t\t\t\t\t\t| BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB\n\t\t\t\t\t\t\t\t;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tg_caps.formats[ii] = support;\n\t\t\t\t}\n\n\t\t\t\t// Init reserved part of view name.\n\t\t\t\tfor (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)\n\t\t\t\t{\n\t\t\t\t\tbx::snprintf(s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED + 1, "%3d   ", ii);\n\t\t\t\t\tmbstowcs(s_viewNameW[ii], s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED);\n\t\t\t\t}\n\n\t\t\t\tif (_init.debug\n\t\t\t\t&&  NULL != m_infoQueue)\n\t\t\t\t{\n\t\t\t\t\tm_infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);\n\t\t\t\t}\n\n\t\t\t\t{ //\n\t\t\t\t\tmultiDrawInstancedIndirect        = stubMultiDrawInstancedIndirect;\n\t\t\t\t\tmultiDrawIndexedInstancedIndirect = stubMultiDrawIndexedInstancedIndirect;\n\t\t\t\t\tif (NULL != m_ags)\n\t\t\t\t\t{\n\t\t\t\t\t\tuint32_t flags;\n\t\t\t\t\t\tAGS_RETURN_CODE result = agsDriverExtensions_Init(m_ags, m_device, &flags);\n\t\t\t\t\t\tbool hasExtensions = AGS_SUCCESS == result;\n\n\t\t\t\t\t\tif (hasExtensions\n\t\t\t\t\t\t&&  0 != (flags & AGS_EXTENSION_MULTIDRAWINDIRECT) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmultiDrawInstancedIndirect        = amdAgsMultiDrawInstancedIndirect;\n\t\t\t\t\t\t\tmultiDrawIndexedInstancedIndirect = amdAgsMultiDrawIndexedInstancedIndirect;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (hasExtensions)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tagsDriverExtensions_DeInit(m_ags);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tagsDeInit(m_ags);\n\t\t\t\t\t\t\tm_ags = NULL;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (m_nvapi.isInitialized()\n\t\t\t\t\t\t &&  NULL != m_nvapi.nvApiD3D11MultiDrawInstancedIndirect\n\t\t\t\t\t\t &&  NULL != m_nvapi.nvApiD3D11MultiDrawIndexedInstancedIndirect)\n\t\t\t\t\t{\n\t\t\t\t\t\tmultiDrawInstancedIndirect        = nvapiMultiDrawInstancedIndirect;\n\t\t\t\t\t\tmultiDrawIndexedInstancedIndirect = nvapiMultiDrawIndexedInstancedIndirect;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t//\n\t\t\t\tupdateMsaa(m_scd.format);\n\t\t\t\tpostReset();\n\t\t\t}\n\n\t\t\tm_nvapi.initAftermath(m_device, m_deviceCtx);\n\n\t\t\tg_internalData.context = m_device;\n\t\t\treturn true;\n\n\t\terror:\n\t\t\tswitch (errorState)\n\t\t\t{\n\t\t\tcase ErrorState::LoadedDXGI:\n\t\t\t\tDX_RELEASE(m_annotation, 1);\n\t\t\t\tDX_RELEASE_W(m_infoQueue, 0);\n\t\t\t\tDX_RELEASE(m_msaaRt, 0);\n#if BX_PLATFORM_WINRT\n\t\t\t\t// Remove swap chain from SwapChainPanel (nwh) if applicable\n\t\t\t\tm_dxgi.removeSwapChain(m_scd, &m_swapChain);\n#endif\n\t\t\t\tDX_RELEASE(m_swapChain, 0);\n\t\t\t\tDX_RELEASE(m_deviceCtx, 0);\n\t\t\t\tDX_RELEASE(m_device, 0);\n\n#if USE_D3D11_DYNAMIC_LIB\n\t\t\t\tif (NULL != m_d3d9Dll)\n\t\t\t\t{\n\t\t\t\t\tbx::dlclose(m_d3d9Dll);\n\t\t\t\t\tm_d3d9Dll = NULL;\n\t\t\t\t}\n#endif // USE_D3D11_DYNAMIC_LIB\n\n\t\t\t\tm_dxgi.shutdown();\n\t\t\t\tBX_FALLTHROUGH;\n\n#if USE_D3D11_DYNAMIC_LIB\n\t\t\tcase ErrorState::LoadedD3D11:\n\t\t\t\tbx::dlclose(m_d3d11Dll);\n\t\t\t\tm_d3d11Dll = NULL;\n\t\t\t\tBX_FALLTHROUGH;\n#endif // USE_D3D11_DYNAMIC_LIB\n\n\t\t\tcase ErrorState::Default:\n\t\t\tdefault:\n\t\t\t\tm_nvapi.shutdown();\n\n\t\t\t\tif (NULL != m_ags)\n\t\t\t\t{\n\t\t\t\t\tagsDeInit(m_ags);\n\t\t\t\t\tm_ags = NULL;\n\t\t\t\t}\n\n\t\t\t\tbx::dlclose(m_agsDll);\n\t\t\t\tm_agsDll = NULL;\n\n\t\t\t\tunloadRenderDoc(m_renderDocDll);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tvoid shutdown()\n\t\t{\n\t\t\tpreReset();\n\n\t\t\tif (NULL != m_ags)\n\t\t\t{\n\t\t\t\tagsDeInit(m_ags);\n\t\t\t\tm_ags = NULL;\n\t\t\t}\n\n\t\t\tbx::dlclose(m_agsDll);\n\t\t\tm_agsDll = NULL;\n\n\t\t\tm_deviceCtx->ClearState();\n\n\t\t\tinvalidateCache();\n\n\t\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)\n\t\t\t{\n\t\t\t\tm_frameBuffers[ii].destroy();\n\t\t\t}\n\n\t\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(m_indexBuffers); ++ii)\n\t\t\t{\n\t\t\t\tm_indexBuffers[ii].destroy();\n\t\t\t}\n\n\t\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(m_vertexBuffers); ++ii)\n\t\t\t{\n\t\t\t\tm_vertexBuffers[ii].destroy();\n\t\t\t}\n\n\t\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(m_shaders); ++ii)\n\t\t\t{\n\t\t\t\tm_shaders[ii].destroy();\n\t\t\t}\n\n\t\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(m_textures); ++ii)\n\t\t\t{\n\t\t\t\tm_textures[ii].destroy();\n\t\t\t}\n\n\t\t\tDX_RELEASE(m_annotation, 1);\n\t\t\tDX_RELEASE_W(m_infoQueue, 0);\n\t\t\tDX_RELEASE(m_msaaRt, 0);\n#if BX_PLATFORM_WINRT\n\t\t\t// Remove swap chain from SwapChainPanel (nwh) if applicable\n\t\t\tm_dxgi.removeSwapChain(m_scd, &m_swapChain);\n#endif\n\t\t\tDX_RELEASE(m_swapChain, 0);\n\t\t\tDX_RELEASE(m_deviceCtx, 0);\n\t\t\tDX_RELEASE(m_device, 0);\n\n\t\t\tm_nvapi.shutdown();\n\t\t\tm_dxgi.shutdown();\n\n\t\t\tunloadRenderDoc(m_renderDocDll);\n\n#if USE_D3D11_DYNAMIC_LIB\n\t\t\tif (NULL != m_d3d9Dll)\n\t\t\t{\n\t\t\t\tbx::dlclose(m_d3d9Dll);\n\t\t\t\tm_d3d9Dll = NULL;\n\t\t\t}\n\n\t\t\tbx::dlclose(m_d3d11Dll);\n\t\t\tm_d3d11Dll = NULL;\n#endif // USE_D3D11_DYNAMIC_LIB\n\t\t}\n\n\t\tRendererType::Enum getRendererType() const override\n\t\t{\n\t\t\treturn RendererType::Direct3D11;\n\t\t}\n\n\t\tconst char* getRendererName() const override\n\t\t{\n\t\t\treturn BGFX_RENDERER_DIRECT3D11_NAME;\n\t\t}\n\n\t\tvoid createIndexBuffer(IndexBufferHandle _handle, const Memory* _mem, uint16_t _flags) override\n\t\t{\n\t\t\tm_indexBuffers[_handle.idx].create(_mem->size, _mem->data, _flags);\n\t\t}\n\n\t\tvoid destroyIndexBuffer(IndexBufferHandle _handle) override\n\t\t{\n\t\t\tm_indexBuffers[_handle.idx].destroy();\n\t\t}\n\n\t\tvoid createVertexLayout(VertexLayoutHandle _handle, const VertexLayout& _layout) override\n\t\t{\n\t\t\tVertexLayout& layout = m_vertexLayouts[_handle.idx];\n\t\t\tbx::memCopy(&layout, &_layout, sizeof(VertexLayout) );\n\t\t\tdump(layout);\n\t\t}\n\n\t\tvoid destroyVertexLayout(VertexLayoutHandle /*_handle*/) override\n\t\t{\n\t\t}\n\n\t\tvoid createVertexBuffer(VertexBufferHandle _handle, const Memory* _mem, VertexLayoutHandle _layoutHandle, uint16_t _flags) override\n\t\t{\n\t\t\tm_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _layoutHandle, _flags);\n\t\t}\n\n\t\tvoid destroyVertexBuffer(VertexBufferHandle _handle) override\n\t\t{\n\t\t\tm_vertexBuffers[_handle.idx].destroy();\n\t\t}\n\n\t\tvoid createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) override\n\t\t{\n\t\t\tm_indexBuffers[_handle.idx].create(_size, NULL, _flags);\n\t\t}\n\n\t\tvoid updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override\n\t\t{\n\t\t\tm_indexBuffers[_handle.idx].update(_offset, bx::uint32_min(_size, _mem->size), _mem->data);\n\t\t}\n\n\t\tvoid destroyDynamicIndexBuffer(IndexBufferHandle _handle) override\n\t\t{\n\t\t\tm_indexBuffers[_handle.idx].destroy();\n\t\t}\n\n\t\tvoid createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override\n\t\t{\n\t\t\tVertexLayoutHandle layoutHandle = BGFX_INVALID_HANDLE;\n\t\t\tm_vertexBuffers[_handle.idx].create(_size, NULL, layoutHandle, _flags);\n\t\t}\n\n\t\tvoid updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, const Memory* _mem) override\n\t\t{\n\t\t\tm_vertexBuffers[_handle.idx].update(_offset, bx::uint32_min(_size, _mem->size), _mem->data);\n\t\t}\n\n\t\tvoid destroyDynamicVertexBuffer(VertexBufferHandle _handle) override\n\t\t{\n\t\t\tm_vertexBuffers[_handle.idx].destroy();\n\t\t}\n\n\t\tvoid createShader(ShaderHandle _handle, const Memory* _mem) override\n\t\t{\n\t\t\tm_shaders[_handle.idx].create(_mem);\n\t\t}\n\n\t\tvoid destroyShader(ShaderHandle _handle) override\n\t\t{\n\t\t\tm_shaders[_handle.idx].destroy();\n\t\t}\n\n\t\tvoid createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) override\n\t\t{\n\t\t\tm_program[_handle.idx].create(&m_shaders[_vsh.idx], isValid(_fsh) ? &m_shaders[_fsh.idx] : NULL);\n\t\t}\n\n\t\tvoid destroyProgram(ProgramHandle _handle) override\n\t\t{\n\t\t\tm_program[_handle.idx].destroy();\n\t\t}\n\n\t\tvoid* createTexture(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip) override\n\t\t{\n\t\t\treturn m_textures[_handle.idx].create(_mem, _flags, _skip);\n\t\t}\n\n\t\tvoid updateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/) override\n\t\t{\n\t\t}\n\n\t\tvoid updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) override\n\t\t{\n\t\t\tm_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _pitch, _mem);\n\t\t}\n\n\t\tvoid updateTextureEnd() override\n\t\t{\n\t\t}\n\n\t\tvoid readTexture(TextureHandle _handle, void* _data, uint8_t _mip) override\n\t\t{\n\t\t\tconst TextureD3D11& texture = m_textures[_handle.idx];\n\t\t\tD3D11_MAPPED_SUBRESOURCE mapped;\n\t\t\tDX_CHECK(m_deviceCtx->Map(texture.m_ptr, _mip, D3D11_MAP_READ, 0, &mapped) );\n\n\t\t\tuint32_t srcWidth  = bx::uint32_max(1, texture.m_width >>_mip);\n\t\t\tuint32_t srcHeight = bx::uint32_max(1, texture.m_height>>_mip);\n\t\t\tuint8_t* src       = (uint8_t*)mapped.pData;\n\t\t\tuint32_t srcPitch  = mapped.RowPitch;\n\n\t\t\tconst uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(texture.m_textureFormat) );\n\t\t\tuint8_t* dst      = (uint8_t*)_data;\n\t\t\tuint32_t dstPitch = srcWidth*bpp/8;\n\n\t\t\tuint32_t pitch = bx::uint32_min(srcPitch, dstPitch);\n\n\t\t\tfor (uint32_t yy = 0, height = srcHeight; yy < height; ++yy)\n\t\t\t{\n\t\t\t\tbx::memCopy(dst, src, pitch);\n\n\t\t\t\tsrc += srcPitch;\n\t\t\t\tdst += dstPitch;\n\t\t\t}\n\n\t\t\tm_deviceCtx->Unmap(texture.m_ptr, _mip);\n\t\t}\n\n\t\tvoid resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips, uint16_t _numLayers) override\n\t\t{\n\t\t\tTextureD3D11& texture = m_textures[_handle.idx];\n\n\t\t\tuint32_t size = sizeof(uint32_t) + sizeof(TextureCreate);\n\t\t\tconst Memory* mem = alloc(size);\n\n\t\t\tbx::StaticMemoryBlockWriter writer(mem->data, mem->size);\n\t\t\tuint32_t magic = BGFX_CHUNK_MAGIC_TEX;\n\t\t\tbx::write(&writer, magic, bx::ErrorAssert{});\n\n\t\t\tTextureCreate tc;\n\t\t\ttc.m_width     = _width;\n\t\t\ttc.m_height    = _height;\n\t\t\ttc.m_depth     = 0;\n\t\t\ttc.m_numLayers = _numLayers;\n\t\t\ttc.m_numMips   = _numMips;\n\t\t\ttc.m_format    = TextureFormat::Enum(texture.m_requestedFormat);\n\t\t\ttc.m_cubeMap   = false;\n\t\t\ttc.m_mem       = NULL;\n\t\t\tbx::write(&writer, tc, bx::ErrorAssert{});\n\n\t\t\ttexture.destroy();\n\t\t\ttexture.create(mem, texture.m_flags, 0);\n\n\t\t\trelease(mem);\n\t\t}\n\n\t\tvoid overrideInternal(TextureHandle _handle, uintptr_t _ptr) override\n\t\t{\n\t\t\t// Resource ref. counts might be messed up outside of bgfx.\n\t\t\t// Disabling ref. count check once texture is overridden.\n\t\t\tsetGraphicsDebuggerPresent(true);\n\t\t\tm_textures[_handle.idx].overrideInternal(_ptr);\n\t\t}\n\n\t\tuintptr_t getInternal(TextureHandle _handle) override\n\t\t{\n\t\t\t// Resource ref. counts might be messed up outside of bgfx.\n\t\t\t// Disabling ref. count check once texture is overridden.\n\t\t\tsetGraphicsDebuggerPresent(true);\n\t\t\treturn uintptr_t(m_textures[_handle.idx].m_ptr);\n\t\t}\n\n\t\tvoid destroyTexture(TextureHandle _handle) override\n\t\t{\n\t\t\tm_textures[_handle.idx].destroy();\n\t\t}\n\n\t\tvoid createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const Attachment* _attachment) override\n\t\t{\n\t\t\tm_frameBuffers[_handle.idx].create(_num, _attachment);\n\t\t}\n\n\t\tvoid createFrameBuffer(FrameBufferHandle _handle, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _format, TextureFormat::Enum _depthFormat) override\n\t\t{\n\t\t\tfor (uint32_t ii = 0, num = m_numWindows; ii < num; ++ii)\n\t\t\t{\n\t\t\t\tFrameBufferHandle handle = m_windows[ii];\n\t\t\t\tif (isValid(handle)\n\t\t\t\t&&  m_frameBuffers[handle.idx].m_nwh == _nwh)\n\t\t\t\t{\n\t\t\t\t\tdestroyFrameBuffer(handle);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tuint16_t denseIdx = m_numWindows++;\n\t\t\tm_windows[denseIdx] = _handle;\n\t\t\tm_frameBuffers[_handle.idx].create(denseIdx, _nwh, _width, _height, _format, _depthFormat);\n\t\t}\n\n\t\tvoid destroyFrameBuffer(FrameBufferHandle _handle) override\n\t\t{\n\t\t\tuint16_t denseIdx = m_frameBuffers[_handle.idx].destroy();\n\t\t\tif (UINT16_MAX != denseIdx)\n\t\t\t{\n\t\t\t\t--m_numWindows;\n\t\t\t\tif (m_numWindows > 1)\n\t\t\t\t{\n\t\t\t\t\tFrameBufferHandle handle = m_windows[m_numWindows];\n\t\t\t\t\tm_windows[m_numWindows]  = {kInvalidHandle};\n\t\t\t\t\tif (m_numWindows != denseIdx)\n\t\t\t\t\t{\n\t\t\t\t\t\tm_windows[denseIdx] = handle;\n\t\t\t\t\t\tm_frameBuffers[handle.idx].m_denseIdx = denseIdx;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) override\n\t\t{\n\t\t\tif (NULL != m_uniforms[_handle.idx])\n\t\t\t{\n\t\t\t\tBX_FREE(g_allocator, m_uniforms[_handle.idx]);\n\t\t\t}\n\n\t\t\tconst uint32_t size = bx::alignUp(g_uniformTypeSize[_type]*_num, 16);\n\t\t\tvoid* data = BX_ALLOC(g_allocator, size);\n\t\t\tbx::memSet(data, 0, size);\n\t\t\tm_uniforms[_handle.idx] = data;\n\t\t\tm_uniformReg.add(_handle, _name);\n\t\t}\n\n\t\tvoid destroyUniform(UniformHandle _handle) override\n\t\t{\n\t\t\tBX_FREE(g_allocator, m_uniforms[_handle.idx]);\n\t\t\tm_uniforms[_handle.idx] = NULL;\n\t\t\tm_uniformReg.remove(_handle);\n\t\t}\n\n\t\tvoid requestScreenShot(FrameBufferHandle _handle, const char* _filePath) override\n\t\t{\n\t\t\tIDXGISwapChain* swapChain = isValid(_handle)\n\t\t\t\t? m_frameBuffers[_handle.idx].m_swapChain\n\t\t\t\t: m_swapChain\n\t\t\t\t;\n\n\t\t\tif (NULL == swapChain)\n\t\t\t{\n\t\t\t\tBX_TRACE("Unable to capture screenshot %s.", _filePath);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tID3D11Texture2D* backBuffer;\n\t\t\tDX_CHECK(swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer) );\n\n\t\t\tD3D11_TEXTURE2D_DESC backBufferDesc;\n\t\t\tbackBuffer->GetDesc(&backBufferDesc);\n\n\t\t\tD3D11_TEXTURE2D_DESC desc;\n\t\t\tbx::memCopy(&desc, &backBufferDesc, sizeof(desc) );\n\t\t\tdesc.SampleDesc.Count = 1;\n\t\t\tdesc.SampleDesc.Quality = 0;\n\t\t\tdesc.Usage = D3D11_USAGE_STAGING;\n\t\t\tdesc.BindFlags = 0;\n\t\t\tdesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;\n\n\t\t\tID3D11Texture2D* texture;\n\t\t\tHRESULT hr = m_device->CreateTexture2D(&desc, NULL, &texture);\n\t\t\tif (SUCCEEDED(hr) )\n\t\t\t{\n\t\t\t\tif (backBufferDesc.SampleDesc.Count == 1)\n\t\t\t\t{\n\t\t\t\t\tm_deviceCtx->CopyResource(texture, backBuffer);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tdesc.Usage = D3D11_USAGE_DEFAULT;\n\t\t\t\t\tdesc.CPUAccessFlags = 0;\n\t\t\t\t\tID3D11Texture2D* resolve;\n\t\t\t\t\thr = m_device->CreateTexture2D(&desc, NULL, &resolve);\n\t\t\t\t\tif (SUCCEEDED(hr) )\n\t\t\t\t\t{\n\t\t\t\t\t\tm_deviceCtx->ResolveSubresource(resolve, 0, backBuffer, 0, desc.Format);\n\t\t\t\t\t\tm_deviceCtx->CopyResource(texture, resolve);\n\t\t\t\t\t\tDX_RELEASE(resolve, 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tD3D11_MAPPED_SUBRESOURCE mapped;\n\t\t\t\tDX_CHECK(m_deviceCtx->Map(texture, 0, D3D11_MAP_READ, 0, &mapped) );\n\t\t\t\tbimg::imageSwizzleBgra8(\n\t\t\t\t\t  mapped.pData\n\t\t\t\t\t, mapped.RowPitch\n\t\t\t\t\t, backBufferDesc.Width\n\t\t\t\t\t, backBufferDesc.Height\n\t\t\t\t\t, mapped.pData\n\t\t\t\t\t, mapped.RowPitch\n\t\t\t\t\t);\n\t\t\t\tg_callback->screenShot(_filePath\n\t\t\t\t\t, backBufferDesc.Width\n\t\t\t\t\t, backBufferDesc.Height\n\t\t\t\t\t, mapped.RowPitch\n\t\t\t\t\t, mapped.pData\n\t\t\t\t\t, backBufferDesc.Height*mapped.RowPitch\n\t\t\t\t\t, false\n\t\t\t\t\t);\n\t\t\t\tm_deviceCtx->Unmap(texture, 0);\n\n\t\t\t\tDX_RELEASE(texture, 0);\n\t\t\t}\n\n\t\t\tDX_RELEASE(backBuffer, 0);\n\t\t}\n\n\t\tvoid updateViewName(ViewId _id, const char* _name) override\n\t\t{\n\t\t\tif (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) )\n\t\t\t{\n\t\t\t\tmbstowcs(&s_viewNameW[_id][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED]\n\t\t\t\t\t, _name\n\t\t\t\t\t, BX_COUNTOF(s_viewNameW[0])-BGFX_CONFIG_MAX_VIEW_NAME_RESERVED\n\t\t\t\t\t);\n\t\t\t}\n\n\t\t\tbx::strCopy(&s_viewName[_id][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED]\n\t\t\t\t, BX_COUNTOF(s_viewName[0]) - BGFX_CONFIG_MAX_VIEW_NAME_RESERVED\n\t\t\t\t, _name\n\t\t\t\t);\n\t\t}\n\n\t\tvoid updateUniform(uint16_t _loc, const void* _data, uint32_t _size) override\n\t\t{\n\t\t\tbx::memCopy(m_uniforms[_loc], _data, _size);\n\t\t}\n\n\t\tvoid invalidateOcclusionQuery(OcclusionQueryHandle _handle) override\n\t\t{\n\t\t\tm_occlusionQuery.invalidate(_handle);\n\t\t}\n\n\t\tvoid setMarker(const char* _marker, uint16_t _len) override\n\t\t{\n\t\t\tif (BX_ENABLED(BGFX_CONFIG_DEBUG_ANNOTATION) )\n\t\t\t{\n\t\t\t\tuint32_t size = _len*sizeof(wchar_t);\n\t\t\t\twchar_t* name = (wchar_t*)alloca(size+2);\n\t\t\t\tname[_len] = L\'\\0\';\n\t\t\t\tmbstowcs(name, _marker, _len);\n\t\t\t\tPIX_SETMARKER(kColorMarker, name);\n\t\t\t}\n\t\t}\n\n\t\tvirtual void setName(Handle _handle, const char* _name, uint16_t _len) override\n\t\t{\n\t\t\tswitch (_handle.type)\n\t\t\t{\n\t\t\tcase Handle::IndexBuffer:\n\t\t\t\tsetDebugObjectName(m_indexBuffers[_handle.idx].m_ptr, "%.*s", _len, _name);\n\t\t\t\tbreak;\n\n\t\t\tcase Handle::Shader:\n\t\t\t\tsetDebugObjectName(m_shaders[_handle.idx].m_ptr, "%.*s", _len, _name);\n\t\t\t\tbreak;\n\n\t\t\tcase Handle::Texture:\n\t\t\t\tsetDebugObjectName(m_textures[_handle.idx].m_ptr, "%.*s", _len, _name);\n\t\t\t\tbreak;\n\n\t\t\tcase Handle::VertexBuffer:\n\t\t\t\tsetDebugObjectName(m_vertexBuffers[_handle.idx].m_ptr, "%.*s", _len, _name);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tBX_ASSERT(false, "Invalid handle type?! %d", _handle.type);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tvoid submitBlit(BlitState& _bs, uint16_t _view);\n\n\t\tvoid submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) override;\n\n\t\tvoid blitSetup(TextVideoMemBlitter& _blitter) override\n\t\t{\n\t\t\tID3D11DeviceContext* deviceCtx = m_deviceCtx;\n\n\t\t\tconst uint32_t width  = m_scd.width;\n\t\t\tconst uint32_t height = m_scd.height;\n\n\t\t\tsetFrameBuffer(BGFX_INVALID_HANDLE, false, false);\n\n\t\t\tD3D11_VIEWPORT vp;\n\t\t\tvp.TopLeftX = 0;\n\t\t\tvp.TopLeftY = 0;\n\t\t\tvp.Width    = (float)width;\n\t\t\tvp.Height   = (float)height;\n\t\t\tvp.MinDepth = 0.0f;\n\t\t\tvp.MaxDepth = 1.0f;\n\t\t\tdeviceCtx->RSSetViewports(1, &vp);\n\n\t\t\tuint64_t state = BGFX_STATE_WRITE_RGB\n\t\t\t\t| BGFX_STATE_WRITE_A\n\t\t\t\t| BGFX_STATE_DEPTH_TEST_ALWAYS\n\t\t\t\t;\n\n\t\t\tsetBlendState(state);\n\t\t\tsetDepthStencilState(state);\n\t\t\tsetRasterizerState(state);\n\n\t\t\tProgramD3D11& program = m_program[_blitter.m_program.idx];\n\t\t\tm_currentProgram = &program;\n\t\t\tdeviceCtx->VSSetShader(program.m_vsh->m_vertexShader, NULL, 0);\n\t\t\tdeviceCtx->VSSetConstantBuffers(0, 1, &program.m_vsh->m_buffer);\n\t\t\tdeviceCtx->PSSetShader(program.m_fsh->m_pixelShader, NULL, 0);\n\t\t\tdeviceCtx->PSSetConstantBuffers(0, 1, &program.m_fsh->m_buffer);\n\n\t\t\tVertexBufferD3D11& vb = m_vertexBuffers[_blitter.m_vb->handle.idx];\n\t\t\tVertexLayout& layout  = m_vertexLayouts[_blitter.m_vb->layoutHandle.idx];\n\t\t\tuint32_t stride = layout.m_stride;\n\t\t\tuint32_t offset = 0;\n\t\t\tdeviceCtx->IASetVertexBuffers(0, 1, &vb.m_ptr, &stride, &offset);\n\t\t\tsetInputLayout(layout, program, 0);\n\n\t\t\tIndexBufferD3D11& ib = m_indexBuffers[_blitter.m_ib->handle.idx];\n\t\t\tdeviceCtx->IASetIndexBuffer(ib.m_ptr, DXGI_FORMAT_R16_UINT, 0);\n\n\t\t\tfloat proj[16];\n\t\t\tbx::mtxOrtho(proj, 0.0f, (float)width, (float)height, 0.0f, 0.0f, 1000.0f, 0.0f, false);\n\n\t\t\tPredefinedUniform& predefined = program.m_predefined[0];\n\t\t\tuint8_t flags = predefined.m_type;\n\t\t\tsetShaderUniform(flags, predefined.m_loc, proj, 4);\n\n\t\t\tcommitShaderConstants();\n\t\t\tm_textures[_blitter.m_texture.idx].commit(0, BGFX_SAMPLER_INTERNAL_DEFAULT, NULL);\n\t\t\tcommitTextureStage();\n\t\t}\n\n\t\tvoid blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) override\n\t\t{\n\t\t\tconst uint32_t numVertices = _numIndices*4/6;\n\t\t\tif (0 < numVertices)\n\t\t\t{\n\t\t\t\tID3D11DeviceContext* deviceCtx = m_deviceCtx;\n\n\t\t\t\tm_indexBuffers [_blitter.m_ib->handle.idx].update(0, _numIndices*2, _blitter.m_ib->data, true);\n\t\t\t\tm_vertexBuffers[_blitter.m_vb->handle.idx].update(0, numVertices*_blitter.m_layout.m_stride, _blitter.m_vb->data, true);\n\n\t\t\t\tdeviceCtx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);\n\t\t\t\tdeviceCtx->DrawIndexed(_numIndices, 0, 0);\n\t\t\t}\n\t\t}\n\n\t\tvoid preReset()\n\t\t{\n\t\t\tm_needPresent = false;\n\n\t\t\tif (m_timerQuerySupport)\n\t\t\t{\n\t\t\t\tm_gpuTimer.preReset();\n\t\t\t}\n\t\t\tm_occlusionQuery.preReset();\n\n\t\t\tif (NULL == g_platformData.backBufferDS)\n\t\t\t{\n\t\t\t\tDX_RELEASE(m_backBufferDepthStencil, 0);\n\t\t\t}\n\n\t\t\tif (NULL != m_swapChain)\n\t\t\t{\n\t\t\t\tDX_RELEASE(m_backBufferColor, 0);\n\t\t\t}\n\n\t\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)\n\t\t\t{\n\t\t\t\tm_frameBuffers[ii].preReset();\n\t\t\t}\n\n//\t\t\tinvalidateCache();\n\n\t\t\tcapturePreReset();\n\t\t}\n\n\t\tvoid postReset()\n\t\t{\n\t\t\tif (NULL != m_swapChain)\n\t\t\t{\n\t\t\t\tID3D11Texture2D* backBufferColor = NULL;\n\t\t\t\tif (NULL == m_msaaRt)\n\t\t\t\t{\n\t\t\t\t\tDX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBufferColor) );\n\t\t\t\t}\n\n\t\t\t\tD3D11_RENDER_TARGET_VIEW_DESC desc;\n\t\t\t\tdesc.ViewDimension = (m_resolution.reset & BGFX_RESET_MSAA_MASK)\n\t\t\t\t\t? D3D11_RTV_DIMENSION_TEXTURE2DMS\n\t\t\t\t\t: D3D11_RTV_DIMENSION_TEXTURE2D\n\t\t\t\t\t;\n\t\t\t\tdesc.Texture2D.MipSlice = 0;\n\n\t\t\t\t/* go find the srgb version of this format to make a render target view\n\t\t\t\t * with the srgb version. this is OK because of this:\n\t\t\t\t * https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/converting-data-color-space\n\t\t\t\t */\n\t\t\t\tdesc.Format = (m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) ? s_textureFormat[m_resolution.format].m_fmtSrgb : s_textureFormat[m_resolution.format].m_fmt;\n\n\t\t\t\tDX_CHECK(m_device->CreateRenderTargetView(NULL == m_msaaRt ? backBufferColor : m_msaaRt, &desc, &m_backBufferColor) );\n\t\t\t\tDX_RELEASE(backBufferColor, 0);\n\t\t\t}\n\n\t\t\tif (m_timerQuerySupport)\n\t\t\t{\n\t\t\t\tm_gpuTimer.postReset();\n\t\t\t}\n\t\t\tm_occlusionQuery.postReset();\n\n\t\t\tif (NULL == m_backBufferDepthStencil)\n\t\t\t{\n\t\t\t\tD3D11_TEXTURE2D_DESC dsd;\n\t\t\t\tdsd.Width  = m_scd.width;\n\t\t\t\tdsd.Height = m_scd.height;\n\t\t\t\tdsd.MipLevels  = 1;\n\t\t\t\tdsd.ArraySize  = 1;\n\t\t\t\tdsd.Format     = DXGI_FORMAT_D24_UNORM_S8_UINT;\n\t\t\t\tdsd.SampleDesc = m_scd.sampleDesc;\n\t\t\t\tdsd.Usage      = D3D11_USAGE_DEFAULT;\n\t\t\t\tdsd.BindFlags  = D3D11_BIND_DEPTH_STENCIL;\n\t\t\t\tdsd.CPUAccessFlags = 0;\n\t\t\t\tdsd.MiscFlags      = 0;\n\n\t\t\t\tID3D11Texture2D* depthStencil;\n\t\t\t\tDX_CHECK(m_device->CreateTexture2D(&dsd, NULL, &depthStencil) );\n\t\t\t\tDX_CHECK(m_device->CreateDepthStencilView(depthStencil, NULL, &m_backBufferDepthStencil) );\n\t\t\t\tDX_RELEASE(depthStencil, 0);\n\t\t\t}\n\n\t\t\tm_deviceCtx->OMSetRenderTargets(1, &m_backBufferColor, m_backBufferDepthStencil);\n\n\t\t\tm_currentColor        = m_backBufferColor;\n\t\t\tm_currentDepthStencil = m_backBufferDepthStencil;\n\n\t\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)\n\t\t\t{\n\t\t\t\tm_frameBuffers[ii].postReset();\n\t\t\t}\n\n\t\t\tcapturePostReset();\n\t\t}\n\n\t\tbool isDeviceRemoved() override\n\t\t{\n\t\t\treturn m_lost;\n\t\t}\n\n\t\tvoid flip() override\n\t\t{\n\t\t\tif (!m_lost)\n\t\t\t{\n\t\t\t\tHRESULT hr = S_OK;\n\t\t\t\tuint32_t syncInterval = BX_ENABLED(!BX_PLATFORM_WINDOWS)\n\t\t\t\t\t? 1 // sync interval of 0 is not supported on WinRT\n\t\t\t\t\t: !!(m_resolution.reset & BGFX_RESET_VSYNC)\n\t\t\t\t\t;\n\n\t\t\t\tfor (uint32_t ii = 1, num = m_numWindows; ii < num && SUCCEEDED(hr); ++ii)\n\t\t\t\t{\n\t\t\t\t\thr = m_frameBuffers[m_windows[ii].idx].present(syncInterval);\n\t\t\t\t}\n\n\t\t\t\tif (SUCCEEDED(hr) )\n\t\t\t\t{\n\t\t\t\t\tif (NULL != m_swapChain\n\t\t\t\t\t&&  m_needPresent)\n\t\t\t\t\t{\n\t\t\t\t\t\tuint32_t presentFlags = 0;\n\n\t\t\t\t\t\tif (!syncInterval\n\t\t\t\t\t\t&&  m_dxgi.tearingSupported() )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpresentFlags |= DXGI_PRESENT_ALLOW_TEARING;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\thr = m_swapChain->Present(syncInterval, presentFlags);\n\n\t\t\t\t\t\tm_needPresent = false;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tm_deviceCtx->Flush();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tm_lost = isLost(hr);\n\t\t\t\tBGFX_FATAL(\n\t\t\t\t\t  !m_lost\n\t\t\t\t\t, bgfx::Fatal::DeviceLost\n\t\t\t\t\t, "Device is lost. FAILED HRESULT(%x) %s (%s)"\n\t\t\t\t\t, hr\n\t\t\t\t\t, getLostReason(hr)\n\t\t\t\t\t, DXGI_ERROR_DEVICE_REMOVED == hr ? getLostReason(m_device->GetDeviceRemovedReason() ) : "no info"\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tvoid invalidateCache()\n\t\t{\n\t\t\tm_inputLayoutCache.invalidate();\n\t\t\tm_blendStateCache.invalidate();\n\t\t\tm_depthStencilStateCache.invalidate();\n\t\t\tm_rasterizerStateCache.invalidate();\n\t\t\tm_samplerStateCache.invalidate();\n\t\t\tm_srvUavLru.invalidate();\n\t\t}\n\n\t\tvoid invalidateCompute()\n\t\t{\n\t\t\tconst uint32_t maxComputeBindings = g_caps.limits.maxComputeBindings;\n\t\t\tconst uint32_t maxTextureSamplers = g_caps.limits.maxTextureSamplers;\n\n\t\t\tm_deviceCtx->CSSetShader(NULL, NULL, 0);\n\t\t\tm_deviceCtx->CSSetUnorderedAccessViews(0, maxComputeBindings, s_zero.m_uav, NULL);\n\t\t\tm_deviceCtx->CSSetShaderResources(0, maxTextureSamplers, s_zero.m_srv);\n\t\t\tm_deviceCtx->CSSetSamplers(0, maxTextureSamplers, s_zero.m_sampler);\n\t\t}\n\n\t\tvoid updateMsaa(DXGI_FORMAT _format) const\n\t\t{\n\t\t\tfor (uint32_t ii = 1, last = 0; ii < BX_COUNTOF(s_msaa); ++ii)\n\t\t\t{\n\t\t\t\tuint32_t msaa = s_checkMsaa[ii];\n\t\t\t\tuint32_t quality = 0;\n\t\t\t\tHRESULT hr = m_device->CheckMultisampleQualityLevels(_format, msaa, &quality);\n\n\t\t\t\tif (SUCCEEDED(hr)\n\t\t\t\t&&  0 < quality)\n\t\t\t\t{\n\t\t\t\t\ts_msaa[ii].Count = msaa;\n\t\t\t\t\ts_msaa[ii].Quality = quality - 1;\n\t\t\t\t\tlast = ii;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ts_msaa[ii] = s_msaa[last];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid updateNativeWindow()\n\t\t{\n#if BX_PLATFORM_WINRT\n\t\t\t// SwapChainPanels can be dynamically updated\n\t\t\tif (m_scd.ndt == reinterpret_cast<void*>(2)\n\t\t\t\t&& (m_scd.nwh != g_platformData.nwh || m_scd.ndt != g_platformData.ndt))\n\t\t\t{\n\t\t\t\t// Remove swap chain from SwapChainPanel (nwh) if applicable\n\t\t\t\tm_dxgi.removeSwapChain(m_scd, &m_swapChain);\n\t\t\t\t// Update nwh after removing swap chain\n\t\t\t\tm_scd.nwh = g_platformData.nwh;\n\t\t\t\tm_scd.ndt = g_platformData.ndt;\n\t\t\t}\n#endif\n\t\t}\n\n\t\tbool updateResolution(const Resolution& _resolution)\n\t\t{\n\t\t\tconst bool suspended    = !!( _resolution.reset & BGFX_RESET_SUSPEND);\n\t\t\tconst bool wasSuspended = !!(m_resolution.reset & BGFX_RESET_SUSPEND);\n\t\t\tif (suspended && wasSuspended)\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (suspended)\n\t\t\t{\n\t\t\t\tm_deviceCtx->Flush();\n\t\t\t\tm_deviceCtx->ClearState();\n\t\t\t\tm_dxgi.trim();\n\t\t\t\tsuspend(m_device);\n\t\t\t\tm_resolution.reset |= BGFX_RESET_SUSPEND;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\telse if (wasSuspended)\n\t\t\t{\n\t\t\t\tresume(m_device);\n\t\t\t\tm_resolution.reset &= ~BGFX_RESET_SUSPEND;\n\t\t\t}\n\n\t\t\tuint32_t maxAnisotropy = 1;\n\t\t\tif (!!(_resolution.reset & BGFX_RESET_MAXANISOTROPY) )\n\t\t\t{\n\t\t\t\tmaxAnisotropy = (m_featureLevel == D3D_FEATURE_LEVEL_9_1)\n\t\t\t\t\t\t\t\t? D3D_FL9_1_DEFAULT_MAX_ANISOTROPY\n\t\t\t\t\t\t\t\t: D3D11_REQ_MAXANISOTROPY\n\t\t\t\t\t\t\t\t;\n\t\t\t}\n\n\t\t\tif (m_maxAnisotropy != maxAnisotropy)\n\t\t\t{\n\t\t\t\tm_maxAnisotropy = maxAnisotropy;\n\t\t\t\tm_samplerStateCache.invalidate();\n\t\t\t}\n\n\t\t\tbool depthClamp = true\n\t\t\t\t&& !!(_resolution.reset & BGFX_RESET_DEPTH_CLAMP)\n\t\t\t\t&& m_featureLevel > D3D_FEATURE_LEVEL_9_3 // disabling depth clamp is only supported on 10_0+\n\t\t\t\t;\n\n\t\t\tif (m_depthClamp != depthClamp)\n\t\t\t{\n\t\t\t\tm_depthClamp = depthClamp;\n\t\t\t\tm_rasterizerStateCache.invalidate();\n\t\t\t}\n\n\t\t\tconst uint32_t maskFlags = ~(0\n\t\t\t\t| BGFX_RESET_MAXANISOTROPY\n\t\t\t\t| BGFX_RESET_DEPTH_CLAMP\n\t\t\t\t| BGFX_RESET_SUSPEND\n\t\tvoid* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];\n\t\tMatrix4 m_predefinedUniforms[PredefinedUniform::Count];\n\t\tUniformRegistry m_uniformReg;\n\n\t\tStateCacheT<ID3D11BlendState> m_blendStateCache;\n\t\tStateCacheT<ID3D11DepthStencilState> m_depthStencilStateCache;\n\t\t\t\tuint32_t flags = _resolution.reset & (~BGFX_RESET_INTERNAL_FORCE);\n\n\t\t\t\tbool resize = true\n\t\t\t\t\t&& !BX_ENABLED(BX_PLATFORM_XBOXONE)\n\t\t\t\t\t&& (m_resolution.reset&BGFX_RESET_MSAA_MASK) == (flags&BGFX_RESET_MSAA_MASK)\n\t\t\t\t\t;\n\n\t\t\t\tm_resolution = _resolution;\n\t\t\t\tm_resolution.reset = flags;\n\n\t\t\t\tm_textVideoMem.resize(false, _resolution.width, _resolution.height);\n\t\t\t\tm_textVideoMem.clear();\n\n\t\t\t\tm_scd.width  = _resolution.width;\n\t\t\t\tm_scd.height = _resolution.height;\n\t\t\t\t// see comment in init() about why we don\'t worry about BGFX_RESET_SRGB_BACKBUFFER here\n\t\t\t\tm_scd.format = s_textureFormat[_resolution.format].m_fmt\n\t\t\t\t\t;\n\n\t\t\t\tpreReset();\n\n\t\t\t\tm_deviceCtx->Flush();\n\t\t\t\tm_deviceCtx->ClearState();\n\n\t\t\t\tif (NULL == m_swapChain)\n\t\t\t\t{\n\t\t\t\t\t// Updated backbuffer if it changed in PlatformData.\n\t\t\t\t\tm_backBufferColor        = (ID3D11RenderTargetView*)g_platformData.backBuffer;\n\t\t\t\t\tm_backBufferDepthStencil = (ID3D11DepthStencilView*)g_platformData.backBufferDS;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tDX_RELEASE(m_msaaRt, 0);\n\n\t\t\t\t\tif (resize)\n\t\t\t\t\t{\n\t\t\t\t\t\tm_deviceCtx->OMSetRenderTargets(1, s_zero.m_rtv, NULL);\n\n\t\t\t\t\t\tDX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd) );\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tupdateMsaa(m_scd.format);\n\t\t\t\t\t\tm_scd.sampleDesc = s_msaa[(m_resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT];\n\n#if BX_PLATFORM_WINRT\n\t\t\t\t\t\t// Remove swap chain from SwapChainPanel (nwh) if applicable\n\t\t\t\t\t\tm_dxgi.removeSwapChain(m_scd, &m_swapChain);\n#endif\n\t\t\t\t\t\tDX_RELEASE(m_swapChain, 0);\n\t\t\t\t\t\tHRESULT hr = m_dxgi.createSwapChain(m_device\n\t\t\t\t\t\t\t, m_scd\n\t\t\t\t\t\t\t, &m_swapChain\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\tBGFX_FATAL(SUCCEEDED(hr), bgfx::Fatal::UnableToInitialize, "Failed to create swap chain.");\n\t\t\t\t\t}\n\n\t\t\t\t\tif (1 < m_scd.sampleDesc.Count)\n\t\t\t\t\t{\n\t\t\t\t\t\tD3D11_TEXTURE2D_DESC desc;\n\t\t\t\t\t\tdesc.Width      = m_scd.width;\n\t\t\t\t\t\tdesc.Height     = m_scd.height;\n\t\t\t\t\t\tdesc.MipLevels  = 1;\n\t\t\t\t\t\tdesc.ArraySize  = 1;\n\t\t\t\t\t\tdesc.Format     = (m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) ? s_textureFormat[m_resolution.format].m_fmtSrgb : s_textureFormat[m_resolution.format].m_fmt;\n\t\t\t\t\t\tdesc.SampleDesc = m_scd.sampleDesc;\n\t\t\t\t\t\tdesc.Usage      = D3D11_USAGE_DEFAULT;\n\t\t\t\t\t\tdesc.BindFlags  = D3D11_BIND_RENDER_TARGET;\n\t\t\t\t\t\tdesc.CPUAccessFlags = 0;\n\t\t\t\t\t\tdesc.MiscFlags      = 0;\n\t\t\t\t\t\tDX_CHECK(m_device->CreateTexture2D(&desc, NULL, &m_msaaRt) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tpostReset();\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tvoid setShaderUniform(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs)\n\t\t{\n\t\t\tif (_flags&kUniformFragmentBit)\n\t\t\t{\n\t\t\t\tbx::memCopy(&m_fsScratch[_regIndex], _val, _numRegs*16);\n\t\t\t\tm_fsChanges += _numRegs;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbx::memCopy(&m_vsScratch[_regIndex], _val, _numRegs*16);\n\t\t\t\tm_vsChanges += _numRegs;\n\t\t\t}\n\t\t}\n\n\t\tvoid setShaderUniform4f(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs)\n\t\t{\n\t\t\tsetShaderUniform(_flags, _regIndex, _val, _numRegs);\n\t\t}\n\n\t\tvoid setShaderUniform4x4f(uint8_t _flags, uint32_t _regIndex, const void* _val, uint32_t _numRegs)\n\t\t{\n\t\t\tsetShaderUniform(_flags, _regIndex, _val, _numRegs);\n\t\t}\n\n\t\tvoid commitShaderConstants()\n\t\t{\n\t\t\tif (0 < m_vsChanges)\n\t\t\t{\n\t\t\t\tif (NULL != m_currentProgram->m_vsh->m_buffer)\n\t\t\t\t{\n\t\t\t\t\tm_deviceCtx->UpdateSubresource(m_currentProgram->m_vsh->m_buffer, 0, 0, m_vsScratch, 0, 0);\n\t\t\t\t}\n\n\t\t\t\tm_vsChanges = 0;\n\t\t\t}\n\n\t\t\tif (0 < m_fsChanges)\n\t\t\t{\n\t\t\t\tif (NULL != m_currentProgram->m_fsh->m_buffer)\n\t\t\t\t{\n\t\t\t\t\tm_deviceCtx->UpdateSubresource(m_currentProgram->m_fsh->m_buffer, 0, 0, m_fsScratch, 0, 0);\n\t\t\t\t}\n\n\t\t\t\tm_fsChanges = 0;\n\t\t\t}\n\t\t}\n\n\t\tvoid setFrameBuffer(FrameBufferHandle _fbh, bool _msaa = true, bool _needPresent = true)\n\t\t{\n\t\t\tif (isValid(m_fbh)\n\t\t\t&&  m_fbh.idx != _fbh.idx\n\t\t\t&&  m_rtMsaa)\n\t\t\t{\n\t\t\t\tFrameBufferD3D11& frameBuffer = m_frameBuffers[m_fbh.idx];\n\t\t\t\tframeBuffer.resolve();\n\t\t\t}\n\n\t\t\tif (!isValid(_fbh) )\n\t\t\t{\n\t\t\t\tm_currentColor        = m_backBufferColor;\n\t\t\t\tm_currentDepthStencil = m_backBufferDepthStencil;\n\n\t\t\t\tm_deviceCtx->OMSetRenderTargetsAndUnorderedAccessViews(\n\t\t\t\t\t  1\n\t\t\t\t\t, &m_currentColor\n\t\t\t\t\t, m_currentDepthStencil\n\t\t\t\t\t, 1\n\t\t\t\t\t, 0\n\t\t\t\t\t, NULL\n\t\t\t\t\t, NULL\n\t\t\t\t\t);\n\t\t\t\tm_needPresent |= _needPresent;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tinvalidateTextureStage();\n\n\t\t\t\tFrameBufferD3D11& frameBuffer = m_frameBuffers[_fbh.idx];\n\t\t\t\tframeBuffer.set();\n\t\t\t}\n\n\t\t\tm_fbh = _fbh;\n\t\t\tm_rtMsaa = _msaa;\n\t\t}\n\n\t\tvoid clear(const Clear& _clear, const float _palette[][4])\n\t\t{\n\t\t\tif (isValid(m_fbh) )\n\t\t\t{\n\t\t\t\tFrameBufferD3D11& frameBuffer = m_frameBuffers[m_fbh.idx];\n\t\t\t\tframeBuffer.clear(_clear, _palette);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (NULL != m_currentColor\n\t\t\t\t&&  BGFX_CLEAR_COLOR & _clear.m_flags)\n\t\t\t\t{\n\t\t\t\t\tif (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags)\n\t\t\t\t\t{\n\t\t\t\t\t\tuint8_t index = _clear.m_index[0];\n\t\t\t\t\t\tif (UINT8_MAX != index)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tm_deviceCtx->ClearRenderTargetView(m_currentColor, _palette[index]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tfloat frgba[4] =\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t_clear.m_index[0]*1.0f/255.0f,\n\t\t\t\t\t\t\t_clear.m_index[1]*1.0f/255.0f,\n\t\t\t\t\t\t\t_clear.m_index[2]*1.0f/255.0f,\n\t\t\t\t\t\t\t_clear.m_index[3]*1.0f/255.0f,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tm_deviceCtx->ClearRenderTargetView(m_currentColor, frgba);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (NULL != m_currentDepthStencil\n\t\t\t\t&& (BGFX_CLEAR_DEPTH|BGFX_CLEAR_STENCIL) & _clear.m_flags)\n\t\t\t\t{\n\t\t\t\t\tDWORD flags = 0;\n\t\t\t\t\tflags |= (_clear.m_flags & BGFX_CLEAR_DEPTH)   ? D3D11_CLEAR_DEPTH   : 0;\n\t\t\t\t\tflags |= (_clear.m_flags & BGFX_CLEAR_STENCIL) ? D3D11_CLEAR_STENCIL : 0;\n\t\t\t\t\tm_deviceCtx->ClearDepthStencilView(m_currentDepthStencil, flags, _clear.m_depth, _clear.m_stencil);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid setInputLayout(uint8_t _numStreams, const VertexLayout** _layouts, const ProgramD3D11& _program, uint16_t _numInstanceData)\n\t\t{\n\t\t\tbx::HashMurmur2A murmur;\n\t\t\tmurmur.begin();\n\t\t\tmurmur.add(_numInstanceData);\n\t\t\tfor (uint8_t stream = 0; stream < _numStreams; ++stream)\n\t\t\t{\n\t\t\t\tmurmur.add(_layouts[stream]->m_hash);\n\t\t\t}\n\t\t\tuint64_t layoutHash = (uint64_t(_program.m_vsh->m_hash)<<32) | murmur.end();\n\n\t\t\tID3D11InputLayout* inputLayout = m_inputLayoutCache.find(layoutHash);\n\t\t\tif (NULL == inputLayout)\n\t\t\t{\n\t\t\t\tD3D11_INPUT_ELEMENT_DESC vertexElements[Attrib::Count+1+BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT];\n\t\t\t\tD3D11_INPUT_ELEMENT_DESC* elem = vertexElements;\n\n\t\t\t\tuint16_t attrMask[Attrib::Count];\n\t\t\t\tbx::memCopy(attrMask, _program.m_vsh->m_attrMask, sizeof(attrMask) );\n\n\t\t\t\tfor (uint8_t stream = 0; stream < _numStreams; ++stream)\n\t\t\t\t{\n\t\t\t\t\tVertexLayout layout;\n\t\t\t\t\tbx::memCopy(&layout, _layouts[stream], sizeof(VertexLayout) );\n\n\t\t\t\t\tconst bool last = stream == _numStreams-1;\n\n\t\t\t\t\tfor (uint32_t ii = 0; ii < Attrib::Count; ++ii)\n\t\t\t\t\t{\n\t\t\t\t\t\tuint16_t mask = attrMask[ii];\n\t\t\t\t\t\tuint16_t attr = (layout.m_attributes[ii] & mask);\n\t\t\t\t\t\tif (0          == attr\n\t\t\t\t\t\t||  UINT16_MAX == attr)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlayout.m_attributes[ii] = last ? ~attr : UINT16_MAX;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tattrMask[ii] = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = fillVertexLayout(stream, elem, layout);\n\t\t\t\t}\n\n\t\t\t\tuint32_t num = uint32_t(elem-vertexElements);\n\n\t\t\t\tconst D3D11_INPUT_ELEMENT_DESC inst = { "TEXCOORD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1 };\n\n\t\t\t\tfor (uint32_t ii = 0; ii < _numInstanceData; ++ii)\n\t\t\t\t{\n\t\t\t\t\tuint32_t index = 7-ii; // TEXCOORD7 = i_data0, TEXCOORD6 = i_data1, etc.\n\n\t\t\t\t\tuint32_t jj;\n\t\t\t\t\tD3D11_INPUT_ELEMENT_DESC* curr = vertexElements;\n\t\t\t\t\tfor (jj = 0; jj < num; ++jj)\n\t\t\t\t\t{\n\t\t\t\t\t\tcurr = &vertexElements[jj];\n\t\t\t\t\t\tif (0 == bx::strCmp(curr->SemanticName, "TEXCOORD")\n\t\t\t\t\t\t&&  curr->SemanticIndex == index)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (jj == num)\n\t\t\t\t\t{\n\t\t\t\t\t\tcurr = elem;\n\t\t\t\t\t\t++elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tbx::memCopy(curr, &inst, sizeof(D3D11_INPUT_ELEMENT_DESC) );\n\t\t\t\t\tcurr->InputSlot = _numStreams;\n\t\t\t\t\tcurr->SemanticIndex = index;\n\t\t\t\t\tcurr->AlignedByteOffset = ii*16;\n\t\t\t\t}\n\n\t\t\t\tnum = uint32_t(elem-vertexElements);\n\t\t\t\tDX_CHECK(m_device->CreateInputLayout(vertexElements\n\t\t\t\t\t, num\n\t\t\t\t\t, _program.m_vsh->m_code->data\n\t\t\t\t\t, _program.m_vsh->m_code->size\n\t\t\t\t\t, &inputLayout\n\t\t\t\t\t) );\n\t\t\t\tm_inputLayoutCache.add(layoutHash, inputLayout);\n\t\t\t}\n\n\t\t\tm_deviceCtx->IASetInputLayout(inputLayout);\n\t\t}\n\n\t\tvoid setInputLayout(const VertexLayout& _layout, const ProgramD3D11& _program, uint16_t _numInstanceData)\n\t\t{\n\t\t\tconst VertexLayout* layouts[1] = { &_layout };\n\t\t\tsetInputLayout(BX_COUNTOF(layouts), layouts, _program, _numInstanceData);\n\t\t}\n\n\t\tvoid setBlendState(uint64_t _state, uint32_t _rgba = 0)\n\t\t{\n\t\t\t_state &= BGFX_D3D11_BLEND_STATE_MASK;\n\n\t\t\tbx::HashMurmur2A murmur;\n\t\t\tmurmur.begin();\n\t\t\tmurmur.add(_state);\n\t\t\tmurmur.add(!!(BGFX_STATE_BLEND_INDEPENDENT & _state)\n\t\t\t\t? _rgba\n\t\t\t\t: -1\n\t\t\t\t);\n\t\t\tconst uint32_t hash = murmur.end();\n\n\t\t\tID3D11BlendState* bs = m_blendStateCache.find(hash);\n\t\t\tif (NULL == bs)\n\t\t\t{\n\t\t\t\tD3D11_BLEND_DESC desc;\n\t\t\t\tdesc.AlphaToCoverageEnable  = !!(BGFX_STATE_BLEND_ALPHA_TO_COVERAGE & _state);\n\t\t\t\tdesc.IndependentBlendEnable = !!(BGFX_STATE_BLEND_INDEPENDENT       & _state);\n\n\t\t\t\tD3D11_RENDER_TARGET_BLEND_DESC* drt = &desc.RenderTarget[0];\n\t\t\t\tdrt->BlendEnable = !!(BGFX_STATE_BLEND_MASK & _state);\n\n\t\t\t\tconst uint32_t blend    = uint32_t( (_state&BGFX_STATE_BLEND_MASK         )>>BGFX_STATE_BLEND_SHIFT);\n\t\t\t\tconst uint32_t equation = uint32_t( (_state&BGFX_STATE_BLEND_EQUATION_MASK)>>BGFX_STATE_BLEND_EQUATION_SHIFT);\n\n\t\t\t\tconst uint32_t srcRGB = (blend      ) & 0xf;\n\t\t\t\tconst uint32_t dstRGB = (blend >>  4) & 0xf;\n\t\t\t\tconst uint32_t srcA   = (blend >>  8) & 0xf;\n\t\t\t\tconst uint32_t dstA   = (blend >> 12) & 0xf;\n\n\t\t\t\tconst uint32_t equRGB = (equation     ) & 0x7;\n\t\t\t\tconst uint32_t equA   = (equation >> 3) & 0x7;\n\n\t\t\t\tdrt->SrcBlend       = s_blendFactor[srcRGB][0];\n\t\t\t\tdrt->DestBlend      = s_blendFactor[dstRGB][0];\n\t\t\t\tdrt->BlendOp        = s_blendEquation[equRGB];\n\n\t\t\t\tdrt->SrcBlendAlpha  = s_blendFactor[srcA][1];\n\t\t\t\tdrt->DestBlendAlpha = s_blendFactor[dstA][1];\n\t\t\t\tdrt->BlendOpAlpha   = s_blendEquation[equA];\n\n\t\t\t\tuint8_t writeMask = 0;\n\t\t\t\twriteMask |= (_state&BGFX_STATE_WRITE_R) ? D3D11_COLOR_WRITE_ENABLE_RED   : 0;\n\t\t\t\twriteMask |= (_state&BGFX_STATE_WRITE_G) ? D3D11_COLOR_WRITE_ENABLE_GREEN : 0;\n\t\t\t\twriteMask |= (_state&BGFX_STATE_WRITE_B) ? D3D11_COLOR_WRITE_ENABLE_BLUE  : 0;\n\t\t\t\twriteMask |= (_state&BGFX_STATE_WRITE_A) ? D3D11_COLOR_WRITE_ENABLE_ALPHA : 0;\n\n\t\t\t\tdrt->RenderTargetWriteMask = writeMask;\n\n\t\t\t\tif (desc.IndependentBlendEnable)\n\t\t\t\t{\n\t\t\t\t\tfor (uint32_t ii = 1, rgba = _rgba; ii < BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS; ++ii, rgba >>= 11)\n\t\t\t\t\t{\n\t\t\t\t\t\tdrt = &desc.RenderTarget[ii];\n\t\t\t\t\t\tdrt->BlendEnable = 0 != (rgba & 0x7ff);\n\n\t\t\t\t\t\tconst uint32_t src = (rgba     ) & 0xf;\n\t\t\t\t\t\tconst uint32_t dst = (rgba >> 4) & 0xf;\n\t\t\t\t\t\tconst uint32_t equ = (rgba >> 8) & 0x7;\n\n\t\t\t\t\t\tdrt->SrcBlend       = s_blendFactor[src][0];\n\t\t\t\t\t\tdrt->DestBlend      = s_blendFactor[dst][0];\n\t\t\t\t\t\tdrt->BlendOp        = s_blendEquation[equ];\n\n\t\t\t\t\t\tdrt->SrcBlendAlpha  = s_blendFactor[src][1];\n\t\t\t\t\t\tdrt->DestBlendAlpha = s_blendFactor[dst][1];\n\t\t\t\t\t\tdrt->BlendOpAlpha   = s_blendEquation[equ];\n\n\t\t\t\t\t\tdrt->RenderTargetWriteMask = writeMask;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfor (uint32_t ii = 1; ii < BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS; ++ii)\n\t\t\t\t\t{\n\t\t\t\t\t\tbx::memCopy(&desc.RenderTarget[ii], drt, sizeof(D3D11_RENDER_TARGET_BLEND_DESC) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tDX_CHECK(m_device->CreateBlendState(&desc, &bs) );\n\n\t\t\t\tm_blendStateCache.add(hash, bs);\n\t\t\t}\n\n\t\t\tconst uint64_t f0 = BGFX_STATE_BLEND_FACTOR;\n\t\t\tconst uint64_t f1 = BGFX_STATE_BLEND_INV_FACTOR;\n\t\t\tconst uint64_t f2 = BGFX_STATE_BLEND_FACTOR<<4;\n\t\t\tconst uint64_t f3 = BGFX_STATE_BLEND_INV_FACTOR<<4;\n\t\t\tbool hasFactor = 0\n\t\t\t\t|| f0 == (_state & f0)\n\t\t\t\t|| f1 == (_state & f1)\n\t\t\t\t|| f2 == (_state & f2)\n\t\t\t\t|| f3 == (_state & f3)\n\t\t\t\t;\n\n\t\t\tfloat blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };\n\t\t\tif (hasFactor)\n\t\t\t{\n\t\t\t\tblendFactor[0] = ( (_rgba>>24)     )/255.0f;\n\t\t\t\tblendFactor[1] = ( (_rgba>>16)&0xff)/255.0f;\n\t\t\t\tblendFactor[2] = ( (_rgba>> 8)&0xff)/255.0f;\n\t\t\t\tblendFactor[3] = ( (_rgba    )&0xff)/255.0f;\n\t\t\t}\n\n\t\t\tm_deviceCtx->OMSetBlendState(bs, blendFactor, 0xffffffff);\n\t\t}\n\n\t\tvoid setDepthStencilState(uint64_t _state, uint64_t _stencil = 0)\n\t\t{\n\t\t\tuint32_t func = (_state&BGFX_STATE_DEPTH_TEST_MASK)>>BGFX_STATE_DEPTH_TEST_SHIFT;\n\t\t\t_state &= 0 == func ? 0 : BGFX_D3D11_DEPTH_STENCIL_MASK;\n\n\t\t\tuint32_t fstencil = unpackStencil(0, _stencil);\n\t\t\tuint32_t ref = (fstencil&BGFX_STENCIL_FUNC_REF_MASK)>>BGFX_STENCIL_FUNC_REF_SHIFT;\n\t\t\t_stencil &= packStencil(~BGFX_STENCIL_FUNC_REF_MASK, ~BGFX_STENCIL_FUNC_REF_MASK);\n\n\t\t\tbx::HashMurmur2A murmur;\n\t\t\tmurmur.begin();\n\t\t\tmurmur.add(_state);\n\t\t\tmurmur.add(_stencil);\n\t\t\tuint32_t hash = murmur.end();\n\n\t\t\tID3D11DepthStencilState* dss = m_depthStencilStateCache.find(hash);\n\t\t\tif (NULL == dss)\n\t\t\t{\n\t\t\t\tD3D11_DEPTH_STENCIL_DESC desc;\n\t\t\t\tbx::memSet(&desc, 0, sizeof(desc) );\n\t\t\t\tdesc.DepthEnable    = 0 != func;\n\t\t\t\tdesc.DepthWriteMask = !!(BGFX_STATE_WRITE_Z & _state) ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;\n\t\t\t\tdesc.DepthFunc      = s_cmpFunc[func];\n\n\t\t\t\tuint32_t bstencil     = unpackStencil(1, _stencil);\n\t\t\t\tuint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil;\n\t\t\t\tbstencil = frontAndBack ? bstencil : fstencil;\n\n\t\t\t\tdesc.StencilEnable    = 0 != _stencil;\n\t\t\t\tdesc.StencilReadMask  = (fstencil&BGFX_STENCIL_FUNC_RMASK_MASK)>>BGFX_STENCIL_FUNC_RMASK_SHIFT;\n\t\t\t\tdesc.StencilWriteMask = 0xff;\n\t\t\t\tdesc.FrontFace.StencilFailOp      = s_stencilOp[(fstencil&BGFX_STENCIL_OP_FAIL_S_MASK)>>BGFX_STENCIL_OP_FAIL_S_SHIFT];\n\t\t\t\tdesc.FrontFace.StencilDepthFailOp = s_stencilOp[(fstencil&BGFX_STENCIL_OP_FAIL_Z_MASK)>>BGFX_STENCIL_OP_FAIL_Z_SHIFT];\n\t\t\t\tdesc.FrontFace.StencilPassOp      = s_stencilOp[(fstencil&BGFX_STENCIL_OP_PASS_Z_MASK)>>BGFX_STENCIL_OP_PASS_Z_SHIFT];\n\t\t\t\tdesc.FrontFace.StencilFunc        = s_cmpFunc[(fstencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT];\n\t\t\t\tdesc.BackFace.StencilFailOp       = s_stencilOp[(bstencil&BGFX_STENCIL_OP_FAIL_S_MASK)>>BGFX_STENCIL_OP_FAIL_S_SHIFT];\n\t\t\t\tdesc.BackFace.StencilDepthFailOp  = s_stencilOp[(bstencil&BGFX_STENCIL_OP_FAIL_Z_MASK)>>BGFX_STENCIL_OP_FAIL_Z_SHIFT];\n\t\t\t\tdesc.BackFace.StencilPassOp       = s_stencilOp[(bstencil&BGFX_STENCIL_OP_PASS_Z_MASK)>>BGFX_STENCIL_OP_PASS_Z_SHIFT];\n\t\t\t\tdesc.BackFace.StencilFunc         = s_cmpFunc[(bstencil&BGFX_STENCIL_TEST_MASK)>>BGFX_STENCIL_TEST_SHIFT];\n\n\t\t\t\tDX_CHECK(m_device->CreateDepthStencilState(&desc, &dss) );\n\n\t\t\t\tm_depthStencilStateCache.add(hash, dss);\n\t\t\t}\n\n\t\t\tm_deviceCtx->OMSetDepthStencilState(dss, ref);\n\t\t}\n\n\t\tvoid setDebugWireframe(bool _wireframe)\n\t\t{\n\t\t\tif (m_wireframe != _wireframe)\n\t\t\t{\n\t\t\t\tm_wireframe = _wireframe;\n\t\t\t\tm_rasterizerStateCache.invalidate();\n\t\t\t}\n\t\t}\n\n\t\tvoid setRasterizerState(uint64_t _state, bool _wireframe = false, bool _scissor = false)\n\t\t{\n\t\t\t_state &= 0\n\t\t\t\t| BGFX_STATE_CULL_MASK\n\t\t\t\t| BGFX_STATE_FRONT_CCW\n\t\t\t\t| BGFX_STATE_MSAA\n\t\t\t\t| BGFX_STATE_LINEAA\n\t\t\t\t| BGFX_STATE_CONSERVATIVE_RASTER\n\t\t\t\t;\n\t\t\t_state |= _wireframe ? BGFX_STATE_PT_LINES : BGFX_STATE_NONE;\n\t\t\t_state |= _scissor   ? BGFX_STATE_RESERVED_MASK : 0;\n\t\t\t_state &= ~(m_deviceInterfaceVersion >= 3 ? 0 : BGFX_STATE_CONSERVATIVE_RASTER);\n\n\t\t\tID3D11RasterizerState* rs = m_rasterizerStateCache.find(_state);\n\t\t\tif (NULL == rs)\n\t\t\t{\n\t\t\t\tuint32_t cull = (_state&BGFX_STATE_CULL_MASK)>>BGFX_STATE_CULL_SHIFT;\n\n#if BX_PLATFORM_WINDOWS\n\t\t\t\tif (m_deviceInterfaceVersion >= 3)\n\t\t\t\t{\n\t\t\t\t\tD3D11_RASTERIZER_DESC2 desc;\n\t\t\t\t\tdesc.FillMode = _wireframe ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID;\n\t\t\t\t\tdesc.CullMode = s_cullMode[cull];\n\t\t\t\t\tdesc.FrontCounterClockwise = !!(_state&BGFX_STATE_FRONT_CCW);\n\t\t\t\t\tdesc.DepthBias             = 0;\n\t\t\t\t\tdesc.DepthBiasClamp        = 0.0f;\n\t\t\t\t\tdesc.SlopeScaledDepthBias  = 0.0f;\n\t\t\t\t\tdesc.DepthClipEnable       = !m_depthClamp;\n\t\t\t\t\tdesc.ScissorEnable         = _scissor;\n\t\t\t\t\tdesc.MultisampleEnable     = !!(_state&BGFX_STATE_MSAA);\n\t\t\t\t\tdesc.AntialiasedLineEnable = !!(_state&BGFX_STATE_LINEAA);\n\t\t\t\t\tdesc.ForcedSampleCount     = 0;\n\t\t\t\t\tdesc.ConservativeRaster    = !!(_state&BGFX_STATE_CONSERVATIVE_RASTER)\n\t\t\t\t\t\t? D3D11_CONSERVATIVE_RASTERIZATION_MODE_ON\n\t\t\t\t\t\t: D3D11_CONSERVATIVE_RASTERIZATION_MODE_OFF\n\t\t\t\t\t\t;\n\n\t\t\t\t\tID3D11Device3* device3 = reinterpret_cast<ID3D11Device3*>(m_device);\n\t\t\t\t\tDX_CHECK(device3->CreateRasterizerState2(&desc, reinterpret_cast<ID3D11RasterizerState2**>(&rs) ) );\n\t\t\t\t}\n\t\t\t\telse\n#endif // BX_PLATFORM_WINDOWS\n\t\t\t\t{\n\t\t\t\t\tD3D11_RASTERIZER_DESC desc;\n\t\t\t\t\tdesc.FillMode = _wireframe ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID;\n\t\t\t\t\tdesc.CullMode = s_cullMode[cull];\n\t\t\t\t\tdesc.FrontCounterClockwise = false;\n\t\t\t\t\tdesc.DepthBias             = 0;\n\t\t\t\t\tdesc.DepthBiasClamp        = 0.0f;\n\t\t\t\t\tdesc.SlopeScaledDepthBias  = 0.0f;\n\t\t\t\t\tdesc.DepthClipEnable       = !m_depthClamp;\n\t\t\t\t\tdesc.ScissorEnable         = _scissor;\n\t\t\t\t\tdesc.MultisampleEnable     = !!(_state&BGFX_STATE_MSAA);\n\t\t\t\t\tdesc.AntialiasedLineEnable = !!(_state&BGFX_STATE_LINEAA);\n\n\t\t\t\t\tDX_CHECK(m_device->CreateRasterizerState(&desc, &rs) );\n\t\t\t\t}\n\n\t\t\t\tm_rasterizerStateCache.add(_state, rs);\n\t\t\t}\n\n\t\t\tm_deviceCtx->RSSetState(rs);\n\t\t}\n\n\t\tID3D11SamplerState* getSamplerState(uint32_t _flags, const float _rgba[4])\n\t\t{\n\t\t\tconst uint32_t index = (_flags & BGFX_SAMPLER_BORDER_COLOR_MASK) >> BGFX_SAMPLER_BORDER_COLOR_SHIFT;\n\t\t\t_flags &= BGFX_SAMPLER_BITS_MASK;\n\n\t\t\t// Force min+mag anisotropic (can\'t be set individually) and remove mip (not supported).\n\t\t\tif (0 != (_flags & (BGFX_SAMPLER_MIN_ANISOTROPIC|BGFX_SAMPLER_MAG_ANISOTROPIC)))\n\t\t\t{\n\t\t\t\t_flags |= BGFX_SAMPLER_MIN_ANISOTROPIC|BGFX_SAMPLER_MAG_ANISOTROPIC;\n\t\t\t\t_flags &= ~BGFX_SAMPLER_MIP_MASK;\n\t\t\t}\n\n\t\t\tuint32_t hash;\n\t\t\tID3D11SamplerState* sampler;\n\t\t\tif (!needBorderColor(_flags) )\n\t\t\t{\n\t\t\t\tbx::HashMurmur2A murmur;\n\t\t\t\tmurmur.begin();\n\t\t\t\tmurmur.add(_flags);\n\t\t\t\tmurmur.add(-1);\n\t\t\t\thash = murmur.end();\n\t\t\t\t_rgba = s_zero.m_zerof;\n\n\t\t\t\tsampler = m_samplerStateCache.find(hash);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbx::HashMurmur2A murmur;\n\t\t\t\tmurmur.begin();\n\t\t\t\tmurmur.add(_flags);\n\t\t\t\tmurmur.add(index);\n\t\t\t\thash = murmur.end();\n\t\t\t\t_rgba = NULL == _rgba ? s_zero.m_zerof : _rgba;\n\n\t\t\t\tsampler = m_samplerStateCache.find(hash);\n\t\t\t\tif (NULL != sampler)\n\t\t\t\t{\n\t\t\t\t\tD3D11_SAMPLER_DESC sd;\n\t\t\t\t\tsampler->GetDesc(&sd);\n\t\t\t\t\tif (0 != bx::memCmp(_rgba, sd.BorderColor, 16) )\n\t\t\t\t\t{\n\t\t\t\t\t\t// Sampler will be released when updated sampler\n\t\t\t\t\t\t// is added to cache.\n\t\t\t\t\t\tsampler = NULL;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (NULL == sampler)\n\t\t\t{\n\t\t\t\tconst uint32_t cmpFunc   = (_flags&BGFX_SAMPLER_COMPARE_MASK)>>BGFX_SAMPLER_COMPARE_SHIFT;\n\t\t\t\tconst uint8_t  minFilter = s_textureFilter[0][(_flags&BGFX_SAMPLER_MIN_MASK)>>BGFX_SAMPLER_MIN_SHIFT];\n\t\t\t\tconst uint8_t  magFilter = s_textureFilter[1][(_flags&BGFX_SAMPLER_MAG_MASK)>>BGFX_SAMPLER_MAG_SHIFT];\n\t\t\t\tconst uint8_t  mipFilter = s_textureFilter[2][(_flags&BGFX_SAMPLER_MIP_MASK)>>BGFX_SAMPLER_MIP_SHIFT];\n\t\t\t\tconst uint8_t  filter    = 0 == cmpFunc ? 0 : D3D11_COMPARISON_FILTERING_BIT;\n\n\t\t\t\tD3D11_SAMPLER_DESC sd;\n\t\t\t\tsd.Filter         = (D3D11_FILTER)(filter|minFilter|magFilter|mipFilter);\n\t\t\t\tsd.AddressU       = s_textureAddress[(_flags&BGFX_SAMPLER_U_MASK)>>BGFX_SAMPLER_U_SHIFT];\n\t\t\t\tsd.AddressV       = s_textureAddress[(_flags&BGFX_SAMPLER_V_MASK)>>BGFX_SAMPLER_V_SHIFT];\n\t\t\t\tsd.AddressW       = s_textureAddress[(_flags&BGFX_SAMPLER_W_MASK)>>BGFX_SAMPLER_W_SHIFT];\n\t\t\t\tsd.MipLODBias     = float(BGFX_CONFIG_MIP_LOD_BIAS);\n\t\t\t\tsd.MaxAnisotropy  = m_maxAnisotropy;\n\t\t\t\tsd.ComparisonFunc = 0 == cmpFunc ? D3D11_COMPARISON_NEVER : s_cmpFunc[cmpFunc];\n\t\t\t\tsd.BorderColor[0] = _rgba[0];\n\t\t\t\tsd.BorderColor[1] = _rgba[1];\n\t\t\t\tsd.BorderColor[2] = _rgba[2];\n\t\t\t\tsd.BorderColor[3] = _rgba[3];\n\t\t\t\tsd.MinLOD = 0;\n\t\t\t\tsd.MaxLOD = D3D11_FLOAT32_MAX;\n\n\t\t\t\tDX_CHECK(m_device->CreateSamplerState(&sd, &sampler));\n\t\t\t\tDX_CHECK_REFCOUNT(sampler, 1);\n\n\t\t\t\tm_samplerStateCache.add(hash, sampler);\n\t\t\t}\n\n\t\t\treturn sampler;\n\t\t}\n\n\t\tbool isVisible(Frame* _render, OcclusionQueryHandle _handle, bool _visible)\n\t\t{\n\t\t\tm_occlusionQuery.resolve(_render);\n\t\t\treturn _visible == (0 != _render->m_occlusion[_handle.idx]);\n\t\t}\n\n\t\tvoid quietValidation()\n\t\t{\n\t\t\tconst uint32_t maxTextureSamplers = g_caps.limits.maxTextureSamplers;\n\n\t\t\tID3D11DeviceContext* deviceCtx = m_deviceCtx;\n\n\t\t\t// vertex texture fetch not supported on 9_1 through 9_3\n\t\t\tif (m_featureLevel > D3D_FEATURE_LEVEL_9_3)\n\t\t\t{\n\t\t\t\tdeviceCtx->VSSetShaderResources(0, maxTextureSamplers, s_zero.m_srv);\n\t\t\t\tdeviceCtx->VSSetSamplers(0, maxTextureSamplers, s_zero.m_sampler);\n\t\t\t}\n\n\t\t\tif (m_featureLevel > D3D_FEATURE_LEVEL_11_0)\n\t\t\t{\n\t\t\t\tdeviceCtx->OMSetRenderTargetsAndUnorderedAccessViews(\n\t\t\t\t\t  D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL\n\t\t\t\t\t, NULL\n\t\t\t\t\t, NULL\n\t\t\t\t\t, 16\n\t\t\t\t\t, maxTextureSamplers\n\t\t\t\t\t, s_zero.m_uav\n\t\t\t\t\t, NULL\n\t\t\t\t\t);\n\t\t\t}\n\n\t\t\tdeviceCtx->PSSetShaderResources(0, maxTextureSamplers, s_zero.m_srv);\n\t\t\tdeviceCtx->PSSetSamplers(0, maxTextureSamplers, s_zero.m_sampler);\n\t\t}\n\n\t\tvoid commitTextureStage()\n\t\t{\n\t\t\tif (BX_ENABLED(BGFX_CONFIG_DEBUG) )\n\t\t\t{\n\t\t\t\tquietValidation();\n\t\t\t}\n\n\t\t\tconst uint32_t maxTextureSamplers = g_caps.limits.maxTextureSamplers;\n\n\t\t\tID3D11DeviceContext* deviceCtx = m_deviceCtx;\n\n\t\t\t// vertex texture fetch not supported on 9_1 through 9_3\n\t\t\tif (m_featureLevel > D3D_FEATURE_LEVEL_9_3)\n\t\t\t{\n\t\t\t\tdeviceCtx->VSSetShaderResources(0, maxTextureSamplers, m_textureStage.m_srv);\n\t\t\t\tdeviceCtx->VSSetSamplers(0, maxTextureSamplers, m_textureStage.m_sampler);\n\t\t\t}\n\n\t\t\tif (m_featureLevel > D3D_FEATURE_LEVEL_11_0)\n\t\t\t{\n\t\t\t\tdeviceCtx->OMSetRenderTargetsAndUnorderedAccessViews(\n\t\t\t\t\t  D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL\n\t\t\t\t\t, NULL\n\t\t\t\t\t, NULL\n\t\t\t\t\t, 16\n\t\t\t\t\t, maxTextureSamplers\n\t\t\t\t\t, m_textureStage.m_uav\n\t\t\t\t\t, NULL\n\t\t\t\t\t);\n\t\t\t}\n\n\t\t\tdeviceCtx->PSSetShaderResources(0, maxTextureSamplers, m_textureStage.m_srv);\n\t\t\tdeviceCtx->PSSetSamplers(0, maxTextureSamplers, m_textureStage.m_sampler);\n\t\t}\n\n\t\tvoid invalidateTextureStage()\n\t\t{\n\t\t\tm_textureStage.clear();\n\t\t\tcommitTextureStage();\n\t\t}\n\n\t\tID3D11UnorderedAccessView* getCachedUav(TextureHandle _handle, uint8_t _mip)\n\t\t{\n\t\t\tbx::HashMurmur2A murmur;\n\t\t\tmurmur.begin();\n\t\t\tmurmur.add(_handle);\n\t\t\tmurmur.add(_mip);\n\t\t\tmurmur.add(1);\n\t\t\tuint32_t hash = murmur.end();\n\n\t\t\tIUnknown** ptr = m_srvUavLru.find(hash);\n\t\t\tID3D11UnorderedAccessView* uav;\n\t\t\tif (NULL == ptr)\n\t\t\t{\n\t\t\t\tTextureD3D11& texture = m_textures[_handle.idx];\n\n\t\t\t\tD3D11_UNORDERED_ACCESS_VIEW_DESC desc;\n\t\t\t\tdesc.Format = texture.getSrvFormat();\n\t\t\t\tswitch (texture.m_type)\n\t\t\t\t{\n\t\t\t\tcase TextureD3D11::Texture2D:\n\t\t\t\t\tdesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;\n\t\t\t\t\tdesc.Texture2D.MipSlice = _mip;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase TextureD3D11::TextureCube:\n\t\t\t\t\tdesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;\n\t\t\t\t\tdesc.Texture2DArray.ArraySize = 6;\n\t\t\t\t\tdesc.Texture2DArray.FirstArraySlice = 0;\n\t\t\t\t\tdesc.Texture2DArray.MipSlice = _mip;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase TextureD3D11::Texture3D:\n\t\t\t\t\tdesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;\n\t\t\t\t\tdesc.Texture3D.MipSlice    = _mip;\n\t\t\t\t\tdesc.Texture3D.FirstWSlice = 0;\n\t\t\t\t\tdesc.Texture3D.WSize       = UINT32_MAX;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tDX_CHECK(m_device->CreateUnorderedAccessView(texture.m_ptr, &desc, &uav) );\n\n\t\t\t\tm_srvUavLru.add(hash, uav, _handle.idx);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tuav = static_cast<ID3D11UnorderedAccessView*>(*ptr);\n\t\t\t}\n\n\t\t\treturn uav;\n\t\t}\n\n\t\tID3D11ShaderResourceView* getCachedSrv(TextureHandle _handle, uint8_t _mip, bool _compute = false, bool _stencil = false)\n\t\t{\n\t\t\tbx::HashMurmur2A murmur;\n\t\t\tmurmur.begin();\n\t\t\tmurmur.add(_handle);\n\t\t\tmurmur.add(_mip);\n\t\t\tmurmur.add(0);\n\t\t\tmurmur.add(_compute);\n\t\t\tmurmur.add(_stencil);\n\t\t\tuint32_t hash = murmur.end();\n\n\t\t\tIUnknown** ptr = m_srvUavLru.find(hash);\n\t\t\tID3D11ShaderResourceView* srv;\n\t\t\tif (NULL == ptr)\n\t\t\t{\n\t\t\t\tconst TextureD3D11& texture = m_textures[_handle.idx];\n\t\t\t\tconst uint32_t msaaQuality = bx::uint32_satsub( (texture.m_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT, 1);\n\t\t\t\tconst DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality];\n\t\t\t\tconst bool msaaSample = 1 < msaa.Count && 0 != (texture.m_flags&BGFX_TEXTURE_MSAA_SAMPLE);\n\n\t\t\t\tD3D11_SHADER_RESOURCE_VIEW_DESC desc;\n\t\t\t\tdesc.Format = _stencil ? DXGI_FORMAT_X24_TYPELESS_G8_UINT : texture.getSrvFormat();\n\t\t\t\tswitch (texture.m_type)\n\t\t\t\t{\n\t\t\t\tcase TextureD3D11::Texture2D:\n\t\t\t\t\tif (1 < texture.m_numLayers)\n\t\t\t\t\t{\n\t\t\t\t\t\tdesc.ViewDimension = msaaSample\n\t\t\t\t\t\t\t? D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY\n\t\t\t\t\t\t\t: D3D11_SRV_DIMENSION_TEXTURE2DARRAY\n\t\t\t\t\t\t\t;\n\t\t\t\t\t\tdesc.Texture2DArray.MostDetailedMip = _mip;\n\t\t\t\t\t\tdesc.Texture2DArray.MipLevels       = 1;\n\t\t\t\t\t\tdesc.Texture2DArray.FirstArraySlice = 0;\n\t\t\t\t\t\tdesc.Texture2DArray.ArraySize       = texture.m_numLayers;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tdesc.ViewDimension = msaaSample\n\t\t\t\t\t\t\t? D3D11_SRV_DIMENSION_TEXTURE2DMS\n\t\t\t\t\t\t\t: D3D11_SRV_DIMENSION_TEXTURE2D\n\t\t\t\t\t\t\t;\n\t\t\t\t\t\tdesc.Texture2D.MostDetailedMip = _mip;\n\t\t\t\t\t\tdesc.Texture2D.MipLevels       = 1;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase TextureD3D11::TextureCube:\n\t\t\t\t\tif (_compute)\n\t\t\t\t\t{\n\t\t\t\t\t\tdesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;\n\t\t\t\t\t\tdesc.Texture2DArray.MostDetailedMip = _mip;\n\t\t\t\t\t\tdesc.Texture2DArray.MipLevels       = 1;\n\t\t\t\t\t\tdesc.Texture2DArray.FirstArraySlice = 0;\n\t\t\t\t\t\tdesc.Texture2DArray.ArraySize       = 6;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tdesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;\n\t\t\t\t\t\tdesc.TextureCube.MostDetailedMip = _mip;\n\t\t\t\t\t\tdesc.TextureCube.MipLevels       = 1;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase TextureD3D11::Texture3D:\n\t\t\t\t\tdesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;\n\t\t\t\t\tdesc.Texture3D.MostDetailedMip = _mip;\n\t\t\t\t\tdesc.Texture3D.MipLevels       = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tDX_CHECK(m_device->CreateShaderResourceView(texture.m_ptr, &desc, &srv) );\n\n\t\t\t\tm_srvUavLru.add(hash, srv, _handle.idx);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tsrv = static_cast<ID3D11ShaderResourceView*>(*ptr);\n\t\t\t}\n\n\t\t\treturn srv;\n\t\t}\n\n\t\tvoid capturePostReset()\n\t\t{\n\t\t\tif (m_resolution.reset&BGFX_RESET_CAPTURE)\n\t\t\t{\n\t\t\t\tID3D11Texture2D* backBuffer;\n\t\t\t\tDX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer) );\n\n\t\t\t\tD3D11_TEXTURE2D_DESC backBufferDesc;\n\t\t\t\tbackBuffer->GetDesc(&backBufferDesc);\n\n\t\t\t\tD3D11_TEXTURE2D_DESC desc;\n\t\t\t\tbx::memCopy(&desc, &backBufferDesc, sizeof(desc) );\n\t\t\t\tdesc.SampleDesc.Count   = 1;\n\t\t\t\tdesc.SampleDesc.Quality = 0;\n\t\tconst bool hmdEnabled = m_ovr.isEnabled() || m_ovr.isDebug();\n\t\t_render->m_hmdEnabled = hmdEnabled;\n\n\t\tViewState viewState(_render, hmdEnabled);\n\n\t\tbool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME);\n\t\tbool scissorEnabled = false;\n\t\t\t\t\t{\n\t\t\t\t\t\tdesc.Usage = D3D11_USAGE_DEFAULT;\n\t\t\t\t\t\tdesc.CPUAccessFlags = 0;\n\t\t\t\t\t\tm_device->CreateTexture2D(&desc, NULL, &m_captureResolve);\n\t\t\t\t\t}\n\n\t\t\t\t\tg_callback->captureBegin(backBufferDesc.Width, backBufferDesc.Height, backBufferDesc.Width*4, TextureFormat::BGRA8, false);\n\t\t\t\t}\n\n\t\t\t\tDX_RELEASE(backBuffer, 0);\n\t\t\t}\n\t\t}\n\n\t\tvoid capturePreReset()\n\t\t{\n\t\t\tif (NULL != m_captureTexture)\n\t\t\t{\n\t\t\t\tg_callback->captureEnd();\n\t\t\t}\n\n\t\t\tDX_RELEASE(m_captureResolve, 0);\n\t\t\tDX_RELEASE(m_captureTexture, 0);\n\t\t}\n\n\t\tvoid capture()\n\t\t{\n\t\t\tif (NULL != m_captureTexture)\n\t\t\t{\n\t\t\t\tID3D11Texture2D* backBuffer;\n\t\t\t\tDX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer) );\n\n\t\t\t\tif (NULL == m_captureResolve)\n\t\t\t\t{\n\t\t\t\t\tm_deviceCtx->CopyResource(m_captureTexture, backBuffer);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tm_deviceCtx->ResolveSubresource(m_captureResolve, 0, backBuffer, 0, m_scd.format);\n\t\t\t\t\tm_deviceCtx->CopyResource(m_captureTexture, m_captureResolve);\n\t\t\t\t}\n\n\t\t\t\tD3D11_MAPPED_SUBRESOURCE mapped;\n\t\t\t\tDX_CHECK(m_deviceCtx->Map(m_captureTexture, 0, D3D11_MAP_READ, 0, &mapped) );\n\n\t\t\t\tbimg::imageSwizzleBgra8(\n\t\t\t\t\t  mapped.pData\n\t\t\t\t\t, mapped.RowPitch\n\t\t\t\t\t, m_scd.width\n\t\t\t\t\t, m_scd.height\n\t\t\t\t\t, mapped.pData\n\t\t\t\t\t, mapped.RowPitch\n\t\t\t\t\t);\n\n\t\t\t\tg_callback->captureFrame(mapped.pData, m_scd.height*mapped.RowPitch);\n\n\t\t\t\tm_deviceCtx->Unmap(m_captureTexture, 0);\n\n\t\t\t\tDX_RELEASE(backBuffer, 0);\n\t\t\t}\n\t\t}\n\n\t\tvoid commit(UniformBuffer& _uniformBuffer)\n\t\t{\n\t\t\t_uniformBuffer.reset();\n\n\t\t\tfor (;;)\n\t\t\t{\n\t\t\t\tuint32_t opcode = _uniformBuffer.read();\n\n\t\t\t\tif (UniformType::End == opcode)\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tUniformType::Enum type;\n\t\t\t\tuint16_t loc;\n\t\t\t\tuint16_t num;\n\t\t\t\tuint16_t copy;\n\t\t\t\tUniformBuffer::decodeOpcode(opcode, type, loc, num, copy);\n\n\t\t\t\tconst char* data;\n\t\t\t\tif (copy)\n\t\t\t\t{\n\t\t\t\t\tdata = _uniformBuffer.read(g_uniformTypeSize[type]*num);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tUniformHandle handle;\n\t\t\t\t\tbx::memCopy(&handle, _uniformBuffer.read(sizeof(UniformHandle) ), sizeof(UniformHandle) );\n\t\t\t\t\tdata = (const char*)m_uniforms[handle.idx];\n\t\t\t\t}\n\n\t\t\t\tswitch ( (uint32_t)type)\n\t\t\t\t{\n\t\t\t\tcase UniformType::Mat3:\n\t\t\t\tcase UniformType::Mat3|kUniformFragmentBit:\n\t\t\t\t\t {\n\t\t\t\t\t\t float* value = (float*)data;\n\t\t\t\t\t\t for (uint32_t ii = 0, count = num/3; ii < count; ++ii,  loc += 3*16, value += 9)\n\t\t\t\t\t\t {\n\t\t\t\t\t\t\t Matrix4 mtx;\n\t\t\t\t\t\t\t mtx.un.val[ 0] = value[0];\n\t\t\t\t\t\t\t mtx.un.val[ 1] = value[1];\n\t\t\t\t\t\t\t mtx.un.val[ 2] = value[2];\n\t\t\t\t\t\t\t mtx.un.val[ 3] = 0.0f;\n\t\t\t\t\t\t\t mtx.un.val[ 4] = value[3];\n\t\t\t\t\t\t\t mtx.un.val[ 5] = value[4];\n\t\t\t\t\t\t\t mtx.un.val[ 6] = value[5];\n\t\t\t\t\t\t\t mtx.un.val[ 7] = 0.0f;\n\t\t\t\t\t\t\t mtx.un.val[ 8] = value[6];\n\t\t\t\t\t\t\t mtx.un.val[ 9] = value[7];\n\t\t\t\t\t\t\t mtx.un.val[10] = value[8];\n\t\t\t\t\t\t\t mtx.un.val[11] = 0.0f;\n\t\t\t\t\t\t\t setShaderUniform(uint8_t(type), loc, &mtx.un.val[0], 3);\n\t\t\t\t\t\t }\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase UniformType::Sampler:\n\t\t\t\tcase UniformType::Sampler | kUniformFragmentBit:\n\t\t\t\tcase UniformType::Vec4:\n\t\t\t\tcase UniformType::Vec4 | kUniformFragmentBit:\n\t\t\t\tcase UniformType::Mat4:\n\t\t\t\tcase UniformType::Mat4 | kUniformFragmentBit:\n\t\t\t\t\t{\n\t\t\t\t\t\tsetShaderUniform(uint8_t(type), loc, data, num);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase UniformType::End:\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tBX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _uniformBuffer.getPos(), opcode, type, loc, num, copy);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvoid clearQuad(ClearQuad& _clearQuad, const Rect& _rect, const Clear& _clear, const float _palette[][4])\n\t\t{\n\t\t\tuint32_t width;\n\t\t\tuint32_t height;\n\n\t\t\tif (isValid(m_fbh) )\n\t\t\t{\n\t\t\t\tconst FrameBufferD3D11& fb = m_frameBuffers[m_fbh.idx];\n\t\t\t\twidth  = fb.m_width;\n\t\t\t\theight = fb.m_height;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\twidth  = m_scd.width;\n\t\t\t\theight = m_scd.height;\n\t\t\t}\n\n\t\t\tif (0      == _rect.m_x\n\t\t\t&&  0      == _rect.m_y\n\t\t\t&&  width  == _rect.m_width\n\t\t\t&&  height == _rect.m_height)\n\t\t\t{\n\t\t\t\tclear(_clear, _palette);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tID3D11DeviceContext* deviceCtx = m_deviceCtx;\n\n\t\t\t\tuint64_t state = 0;\n\t\t\t\tstate |= _clear.m_flags & BGFX_CLEAR_COLOR ? BGFX_STATE_WRITE_RGB|BGFX_STATE_WRITE_A         : 0;\n\t\t\t\tstate |= _clear.m_flags & BGFX_CLEAR_DEPTH ? BGFX_STATE_DEPTH_TEST_ALWAYS|BGFX_STATE_WRITE_Z : 0;\n\n\t\t\t\tuint64_t stencil = 0;\n\t\t\t\tstencil |= _clear.m_flags & BGFX_CLEAR_STENCIL ? 0\n\t\t\t\t\t| BGFX_STENCIL_TEST_ALWAYS\n\t\t\t\t\t| BGFX_STENCIL_FUNC_REF(_clear.m_stencil)\n\t\t\t\t\t| BGFX_STENCIL_FUNC_RMASK(0xff)\n\t\t\t\t\t| BGFX_STENCIL_OP_FAIL_S_REPLACE\n\t\t\t\t\t| BGFX_STENCIL_OP_FAIL_Z_REPLACE\n\t\t\t\t\t| BGFX_STENCIL_OP_PASS_Z_REPLACE\n\t\t\t\t\t: 0\n\t\t\t\t\t;\n\n\t\t\t\tsetBlendState(state);\n\t\t\t\tsetDepthStencilState(state, stencil);\n\t\t\t\tsetRasterizerState(state);\n\n\t\t\t\tuint32_t numMrt = 1;\n\t\t\t\tFrameBufferHandle fbh = m_fbh;\n\t\t\t\tif (isValid(fbh) )\n\t\t\t\t{\n\t\t\t\t\tconst FrameBufferD3D11& fb = m_frameBuffers[fbh.idx];\n\t\t\t\t\tnumMrt = bx::uint32_max(1, fb.m_num);\n\t\t\t\t}\n\n\t\t\t\tProgramD3D11& program = m_program[_clearQuad.m_program[numMrt-1].idx];\n\t\t\t\tm_currentProgram = &program;\n\n\t\t\t\tconst ShaderD3D11* vsh = program.m_vsh;\n\t\t\t\tdeviceCtx->VSSetShader(vsh->m_vertexShader, NULL, 0);\n\t\t\t\tdeviceCtx->VSSetConstantBuffers(0, 1, &vsh->m_buffer);\n\t\t\t\tfloat mrtClearDepth[4] = { _clear.m_depth };\n\t\t\t\tdeviceCtx->UpdateSubresource(vsh->m_buffer, 0, 0, mrtClearDepth, 0, 0);\n\n\t\t\t\tif (NULL != m_currentColor)\n\t\t\t\t{\n\t\t\t\t\tconst ShaderD3D11* fsh = program.m_fsh;\n\t\t\t\t\tdeviceCtx->PSSetShader(fsh->m_pixelShader, NULL, 0);\n\t\t\t\t\tdeviceCtx->PSSetConstantBuffers(0, 1, &fsh->m_buffer);\n\n\t\t\t\t\tfloat mrtClearColor[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS][4];\n\t\t\t\t\tif (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags)\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (uint32_t ii = 0; ii < numMrt; ++ii)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tuint8_t index = (uint8_t)bx::uint32_min(BGFX_CONFIG_MAX_COLOR_PALETTE-1, _clear.m_index[ii]);\n\t\t\t\t\t\t\tbx::memCopy(mrtClearColor[ii], _palette[index], 16);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tfloat rgba[4] =\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t_clear.m_index[0]*1.0f/255.0f,\n\t\t\t\t\t\t\t_clear.m_index[1]*1.0f/255.0f,\n\t\t\t\t\t\t\t_clear.m_index[2]*1.0f/255.0f,\n\t\t\t\t\t\t\t_clear.m_index[3]*1.0f/255.0f,\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tfor (uint32_t ii = 0; ii < numMrt; ++ii)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbx::memCopy(mrtClearColor[ii], rgba, 16);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tdeviceCtx->UpdateSubresource(fsh->m_buffer, 0, 0, mrtClearColor, 0, 0);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tdeviceCtx->PSSetShader(NULL, NULL, 0);\n\t\t\t\t}\n\n\t\t\t\tVertexBufferD3D11& vb = m_vertexBuffers[_clearQuad.m_vb.idx];\n\t\t\t\tconst VertexLayout& layout = _clearQuad.m_layout;\n\n\t\t\t\tconst uint32_t stride = layout.m_stride;\n\t\t\t\tconst uint32_t offset = 0;\n\n\t\t\t\tdeviceCtx->IASetVertexBuffers(0, 1, &vb.m_ptr, &stride, &offset);\n\t\t\t\tsetInputLayout(layout, program, 0);\n\n\t\t\t\tdeviceCtx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);\n\t\t\t\tdeviceCtx->Draw(4, 0);\n\t\t\t}\n\t\t}\n\n\t\tvoid* m_d3d9Dll;\n\t\tvoid* m_d3d11Dll;\n\t\tvoid* m_renderDocDll;\n\t\tvoid* m_agsDll;\n\n\t\tDxgi m_dxgi;\n\t\tAGSContext* m_ags;\n\t\tNvApi m_nvapi;\n\n\t\tD3D_FEATURE_LEVEL m_featureLevel;\n\n\t\tDxgi::SwapChainI* m_swapChain;\n\t\tID3D11Texture2D*  m_msaaRt;\n\n\t\tbool m_needPresent;\n\t\tbool m_lost;\n\t\tuint16_t m_numWindows;\n\t\tFrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS];\n\n\t\tID3D11Device*              m_device;\n\t\tID3D11DeviceContext*       m_deviceCtx;\n\t\tID3DUserDefinedAnnotation* m_annotation;\n\t\tID3D11InfoQueue*           m_infoQueue;\n\n\t\tTimerQueryD3D11     m_gpuTimer;\n\t\tOcclusionQueryD3D11 m_occlusionQuery;\n\n\t\tuint32_t m_deviceInterfaceVersion;\n\n\t\tID3D11RenderTargetView* m_backBufferColor;\n\t\tID3D11DepthStencilView* m_backBufferDepthStencil;\n\t\tID3D11RenderTargetView* m_currentColor;\n\t\tID3D11DepthStencilView* m_currentDepthStencil;\n\n\t\tID3D11Texture2D* m_captureTexture;\n\t\tID3D11Texture2D* m_captureResolve;\n\n\t\tResolution m_resolution;\n\n\t\tSwapChainDesc m_scd;\n\t\tDXGI_SWAP_EFFECT m_swapEffect;\n\t\tuint32_t m_swapBufferCount;\n\t\tuint32_t m_maxAnisotropy;\n\t\tbool m_depthClamp;\n\t\tbool m_wireframe;\n\n\t\tIndexBufferD3D11 m_indexBuffers[BGFX_CONFIG_MAX_INDEX_BUFFERS];\n\t\tVertexBufferD3D11 m_vertexBuffers[BGFX_CONFIG_MAX_VERTEX_BUFFERS];\n\t\tShaderD3D11 m_shaders[BGFX_CONFIG_MAX_SHADERS];\n\t\tProgramD3D11 m_program[BGFX_CONFIG_MAX_PROGRAMS];\n\t\tTextureD3D11 m_textures[BGFX_CONFIG_MAX_TEXTURES];\n\t\tVertexLayout m_vertexLayouts[BGFX_CONFIG_MAX_VERTEX_LAYOUTS];\n\t\tFrameBufferD3D11 m_frameBuffers[BGFX_CONFIG_MAX_FRAME_BUFFERS];\n\t\tvoid* m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];\n\t\tMatrix4 m_predefinedUniforms[PredefinedUniform::Count];\n\t\tUniformRegistry m_uniformReg;\n\n\t\tStateCacheT<ID3D11BlendState> m_blendStateCache;\n\t\tStateCacheT<ID3D11DepthStencilState> m_depthStencilStateCache;\n\t\tStateCacheT<ID3D11InputLayout> m_inputLayoutCache;\n\t\tStateCacheT<ID3D11RasterizerState> m_rasterizerStateCache;\n\t\tStateCacheT<ID3D11SamplerState> m_samplerStateCache;\n\t\tStateCacheLru<IUnknown*, 1024> m_srvUavLru;\n\n\t\tTextVideoMem m_textVideoMem;\n\n\t\tTextureStage m_textureStage;\n\n\t\tProgramD3D11* m_currentProgram;\n\n\t\tuint8_t m_vsScratch[64<<10];\n\t\tuint8_t m_fsScratch[64<<10];\n\t\tuint32_t m_vsChanges;\n\t\tuint32_t m_fsChanges;\n\n\t\tFrameBufferHandle m_fbh;\n\t\tbool m_rtMsaa;\n\t\tbool m_timerQuerySupport;\n\t\tbool m_directAccessSupport;\n\t};\n\n\tstatic RendererContextD3D11* s_renderD3D11;\n\n\tRendererContextI* rendererCreate(const Init& _init)\n\t{\n\t\ts_renderD3D11 = BX_NEW(g_allocator, RendererContextD3D11);\n\t\tif (!s_renderD3D11->init(_init) )\n\t\t{\n\t\t\tBX_DELETE(g_allocator, s_renderD3D11);\n\t\t\ts_renderD3D11 = NULL;\n\t\t}\n\t\treturn s_renderD3D11;\n\t}\n\n\tvoid rendererDestroy()\n\t{\n\t\ts_renderD3D11->shutdown();\n\t\tBX_DELETE(g_allocator, s_renderD3D11);\n\t\ts_renderD3D11 = NULL;\n\t}\n\n\tvoid stubMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride)\n\t{\n\t\tID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;\n\t\tfor (uint32_t ii = 0; ii < _numDrawIndirect; ++ii)\n\t\t{\n\t\t\tdeviceCtx->DrawInstancedIndirect(_ptr, _offset);\n\t\t\t_offset += _stride;\n\t\t}\n\t}\n\n\tvoid stubMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride)\n\t{\n\t\tID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;\n\t\tfor (uint32_t ii = 0; ii < _numDrawIndirect; ++ii)\n\t\t{\n\t\t\tdeviceCtx->DrawIndexedInstancedIndirect(_ptr, _offset);\n\t\t\t_offset += _stride;\n\t\t}\n\t}\n\n\tvoid amdAgsMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride)\n\t{\n\t\tagsDriverExtensions_MultiDrawInstancedIndirect(s_renderD3D11->m_ags, _numDrawIndirect, _ptr, _offset, _stride);\n\t}\n\n\tvoid amdAgsMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride)\n\t{\n\t\tagsDriverExtensions_MultiDrawIndexedInstancedIndirect(s_renderD3D11->m_ags, _numDrawIndirect, _ptr, _offset, _stride);\n\t}\n\n\tvoid nvapiMultiDrawInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride)\n\t{\n\t\ts_renderD3D11->m_nvapi.nvApiD3D11MultiDrawInstancedIndirect(s_renderD3D11->m_deviceCtx, _numDrawIndirect, _ptr, _offset, _stride);\n\t}\n\n\tvoid nvapiMultiDrawIndexedInstancedIndirect(uint32_t _numDrawIndirect, ID3D11Buffer* _ptr, uint32_t _offset, uint32_t _stride)\n\t{\n\t\ts_renderD3D11->m_nvapi.nvApiD3D11MultiDrawIndexedInstancedIndirect(s_renderD3D11->m_deviceCtx, _numDrawIndirect, _ptr, _offset, _stride);\n\t}\n\n\tint  WINAPI d3d11Annotation_BeginEvent(DWORD _color, LPCWSTR _name)\n\t{\n\t\tBX_UNUSED(_color);\n\t\treturn s_renderD3D11->m_annotation->BeginEvent(_name);\n\t}\n\n\tint  WINAPI d3d11Annotation_EndEvent()\n\t{\n\t\treturn s_renderD3D11->m_annotation->EndEvent();\n\t}\n\n\tvoid WINAPI d3d11Annotation_SetMarker(DWORD _color, LPCWSTR _name)\n\t{\n\t\tBX_UNUSED(_color);\n\t\ts_renderD3D11->m_annotation->SetMarker(_name);\n\t}\n\n\tstruct UavFormat\n\t{\n\t\tDXGI_FORMAT format[3];\n\t\tuint32_t    stride;\n\t};\n\n\tstatic const UavFormat s_uavFormat[] =\n\t{\t//  BGFX_BUFFER_COMPUTE_TYPE_INT,  BGFX_BUFFER_COMPUTE_TYPE_UINT,  BGFX_BUFFER_COMPUTE_TYPE_FLOAT\n\t\t{ { DXGI_FORMAT_UNKNOWN,           DXGI_FORMAT_UNKNOWN,            DXGI_FORMAT_UNKNOWN            },  0 }, // ignored\n\t\t{ { DXGI_FORMAT_R8_SINT,           DXGI_FORMAT_R8_UINT,            DXGI_FORMAT_UNKNOWN            },  1 }, // BGFX_BUFFER_COMPUTE_FORMAT_8X1\n\t\t{ { DXGI_FORMAT_R8G8_SINT,         DXGI_FORMAT_R8G8_UINT,          DXGI_FORMAT_UNKNOWN            },  2 }, // BGFX_BUFFER_COMPUTE_FORMAT_8X2\n\t\t{ { DXGI_FORMAT_R8G8B8A8_SINT,     DXGI_FORMAT_R8G8B8A8_UINT,      DXGI_FORMAT_UNKNOWN            },  4 }, // BGFX_BUFFER_COMPUTE_FORMAT_8X4\n\t\t{ { DXGI_FORMAT_R16_SINT,          DXGI_FORMAT_R16_UINT,           DXGI_FORMAT_R16_FLOAT          },  2 }, // BGFX_BUFFER_COMPUTE_FORMAT_16X1\n\t\t{ { DXGI_FORMAT_R16G16_SINT,       DXGI_FORMAT_R16G16_UINT,        DXGI_FORMAT_R16G16_FLOAT       },  4 }, // BGFX_BUFFER_COMPUTE_FORMAT_16X2\n\t\t{ { DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R16G16B16A16_UINT,  DXGI_FORMAT_R16G16B16A16_FLOAT },  8 }, // BGFX_BUFFER_COMPUTE_FORMAT_16X4\n\t\t{ { DXGI_FORMAT_R32_SINT,          DXGI_FORMAT_R32_UINT,           DXGI_FORMAT_R32_FLOAT          },  4 }, // BGFX_BUFFER_COMPUTE_FORMAT_32X1\n\t\t{ { DXGI_FORMAT_R32G32_SINT,       DXGI_FORMAT_R32G32_UINT,        DXGI_FORMAT_R32G32_FLOAT       },  8 }, // BGFX_BUFFER_COMPUTE_FORMAT_32X2\n\t\t{ { DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32A32_UINT,  DXGI_FORMAT_R32G32B32A32_FLOAT }, 16 }, // BGFX_BUFFER_COMPUTE_FORMAT_32X4\n\t};\n\n\tvoid BufferD3D11::create(uint32_t _size, void* _data, uint16_t _flags, uint16_t _stride, bool _vertex)\n\t{\n\t\tm_uav   = NULL;\n\t\tm_size  = _size;\n\t\tm_flags = _flags;\n\n\t\tconst bool needUav = 0 != (_flags & (BGFX_BUFFER_COMPUTE_WRITE|BGFX_BUFFER_DRAW_INDIRECT) );\n\t\tconst bool needSrv = 0 != (_flags & BGFX_BUFFER_COMPUTE_READ);\n\t\tconst bool drawIndirect = 0 != (_flags & BGFX_BUFFER_DRAW_INDIRECT);\n\t\tm_dynamic = NULL == _data && !needUav;\n\n\t\tD3D11_BUFFER_DESC desc;\n\t\tdesc.ByteWidth = _size;\n\t\tdesc.BindFlags = 0\n\t\t\t| (_vertex ? D3D11_BIND_VERTEX_BUFFER    : D3D11_BIND_INDEX_BUFFER)\n\t\t\t| (needUav ? D3D11_BIND_UNORDERED_ACCESS : 0)\n\t\t\t| (needSrv ? D3D11_BIND_SHADER_RESOURCE  : 0)\n\t\t\t;\n\t\tdesc.MiscFlags = 0\n\t\t\t| (drawIndirect ? D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS : 0)\n\t\t\t;\n\t\tdesc.StructureByteStride = 0;\n\n\t\tDXGI_FORMAT format;\n\t\tuint32_t    stride;\n\n\t\tif (drawIndirect)\n\t\t{\n\t\t\tformat = DXGI_FORMAT_R32G32B32A32_UINT;\n\t\t\tstride = 16;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tuint32_t uavFormat = (_flags & BGFX_BUFFER_COMPUTE_FORMAT_MASK) >> BGFX_BUFFER_COMPUTE_FORMAT_SHIFT;\n\t\t\tif (0 == uavFormat)\n\t\t\t{\n\t\t\t\tif (_vertex)\n\t\t\t\t{\n\t\t\t\t\tformat = DXGI_FORMAT_R32G32B32A32_FLOAT;\n\t\t\t\t\tstride = 16;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif (0 == (_flags & BGFX_BUFFER_INDEX32) )\n\t\t\t\t\t{\n\t\t\t\t\t\tformat = DXGI_FORMAT_R16_UINT;\n\t\t\t\t\t\tstride = 2;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tformat = DXGI_FORMAT_R32_UINT;\n\t\t\t\t\t\tstride = 4;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tconst uint32_t uavType = bx::uint32_satsub( (_flags & BGFX_BUFFER_COMPUTE_TYPE_MASK  ) >> BGFX_BUFFER_COMPUTE_TYPE_SHIFT, 1);\n\t\t\t\tformat = s_uavFormat[uavFormat].format[uavType];\n\t\t\t\tstride = s_uavFormat[uavFormat].stride;\n\t\t\t}\n\t\t}\n\n\t\tID3D11Device* device = s_renderD3D11->m_device;\n\n\t\tD3D11_SUBRESOURCE_DATA srd;\n\t\tsrd.pSysMem = _data;\n\t\tsrd.SysMemPitch = 0;\n\t\tsrd.SysMemSlicePitch = 0;\n\n\t\tif (needUav)\n\t\t{\n\t\t\tdesc.Usage = D3D11_USAGE_DEFAULT;\n\t\t\tdesc.CPUAccessFlags = 0;\n\t\t\tdesc.StructureByteStride = _stride;\n\n\t\t\tDX_CHECK(device->CreateBuffer(&desc\n\t\t\t\t, NULL == _data ? NULL : &srd\n\t\t\t\t, &m_ptr\n\t\t\t\t) );\n\n\t\t\tD3D11_UNORDERED_ACCESS_VIEW_DESC uavd;\n\t\t\tuavd.Format = format;\n\t\t\tuavd.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;\n\t\t\tuavd.Buffer.FirstElement = 0;\n\t\t\tuavd.Buffer.NumElements = m_size / stride;\n\t\t\tuavd.Buffer.Flags = 0;\n\t\t\tDX_CHECK(device->CreateUnorderedAccessView(m_ptr\n\t\t\t\t, &uavd\n\t\t\t\t, &m_uav\n\t\t\t\t) );\n\t\t}\n\t\telse if (m_dynamic)\n\t\t{\n#if USE_D3D11_STAGING_BUFFER\n\t\t\tdesc.Usage          = D3D11_USAGE_DEFAULT;\n\t\t\tdesc.CPUAccessFlags = 0;\n\n\t\t\tDX_CHECK(device->CreateBuffer(&desc\n\t\t\t\t, NULL\n\t\t\t\t, &m_ptr\n\t\t\t\t) );\n\n\t\t\tdesc.BindFlags      = 0;\n\t\t\tdesc.Usage          = D3D11_USAGE_STAGING;\n\t\t\tdesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\n\n\t\t\tDX_CHECK(device->CreateBuffer(&desc\n\t\t\t\t, NULL\n\t\t\t\t, &m_staging\n\t\t\t\t) );\n#else\n\t\t\tdesc.Usage          = D3D11_USAGE_DYNAMIC;\n\t\t\tdesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\n\n\t\t\tDX_CHECK(device->CreateBuffer(&desc\n\t\t\t\t, NULL\n\t\t\t\t, &m_ptr\n\t\t\t\t) );\n#endif // USE_D3D11_STAGING_BUFFER\n\t\t}\n\t\telse\n\t\t{\n\t\t\tdesc.Usage = D3D11_USAGE_IMMUTABLE;\n\t\t\tdesc.CPUAccessFlags = 0;\n\n\t\t\tDX_CHECK(device->CreateBuffer(&desc\n\t\t\t\t, &srd\n\t\t\t\t, &m_ptr\n\t\t\t\t) );\n\t\t}\n\n\t\tif (needSrv)\n\t\t{\n\t\t\tD3D11_SHADER_RESOURCE_VIEW_DESC srvd;\n\t\t\tsrvd.Format = format;\n\t\t\tsrvd.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;\n\t\t\tsrvd.Buffer.FirstElement = 0;\n\t\t\tsrvd.Buffer.NumElements = m_size / stride;\n\t\t\tDX_CHECK(device->CreateShaderResourceView(m_ptr\n\t\t\t\t, &srvd\n\t\t\t\t, &m_srv\n\t\t\t\t) );\n\t\t}\n\t}\n\n\tvoid BufferD3D11::update(uint32_t _offset, uint32_t _size, void* _data, bool _discard)\n\t{\n\t\tID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;\n\t\tBX_ASSERT(m_dynamic, "Must be dynamic!");\n\n#if USE_D3D11_STAGING_BUFFER\n\t\tBX_UNUSED(_discard);\n\n\t\tD3D11_MAPPED_SUBRESOURCE mapped;\n\t\tDX_CHECK(deviceCtx->Map(m_staging, 0, D3D11_MAP_WRITE, 0, &mapped) );\n\t\tbx::memCopy( (uint8_t*)mapped.pData + _offset, _data, _size);\n\t\tdeviceCtx->Unmap(m_staging, 0);\n\n\t\tD3D11_BOX box;\n\t\tbox.left   = _offset;\n\t\tbox.top    = 0;\n\t\tbox.front  = 0;\n\t\tbox.right  = _offset + _size;\n\t\tbox.bottom = 1;\n\t\tbox.back   = 1;\n\n\t\tdeviceCtx->CopySubresourceRegion(m_ptr\n\t\t\t, 0\n\t\t\t, _offset\n\t\t\t, 0\n\t\t\t, 0\n\t\t\t, m_staging\n\t\t\t, 0\n\t\t\t, &box\n\t\t\t);\n#else\n\t\tif (_discard)\n\t\t{\n\t\t\tD3D11_MAPPED_SUBRESOURCE mapped;\n\t\t\tDX_CHECK(deviceCtx->Map(m_ptr, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped) );\n\t\t\tbx::memCopy( (uint8_t*)mapped.pData + _offset, _data, _size);\n\t\t\tdeviceCtx->Unmap(m_ptr, 0);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tD3D11_BUFFER_DESC desc;\n\t\t\tdesc.ByteWidth = _size;\n\t\t\tdesc.Usage     = D3D11_USAGE_STAGING;\n\t\t\tdesc.BindFlags = 0;\n\t\t\tdesc.MiscFlags = 0;\n\t\t\tdesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\n\t\t\tdesc.StructureByteStride = 0;\n\n\t\t\tD3D11_SUBRESOURCE_DATA srd;\n\t\t\tsrd.pSysMem     = _data;\n\t\t\tsrd.SysMemPitch = 0;\n\t\t\tsrd.SysMemSlicePitch = 0;\n\n\t\t\tD3D11_BOX srcBox;\n\t\t\tsrcBox.left   = 0;\n\t\t\tsrcBox.top    = 0;\n\t\t\tsrcBox.front  = 0;\n\t\t\tsrcBox.right  = _size;\n\t\t\tsrcBox.bottom = 1;\n\t\t\tsrcBox.back   = 1;\n\n\t\t\tID3D11Device* device = s_renderD3D11->m_device;\n\n\t\t\tID3D11Buffer* ptr;\n\t\t\tDX_CHECK(device->CreateBuffer(&desc, &srd, &ptr) );\n\n\t\t\tdeviceCtx->CopySubresourceRegion(m_ptr\n\t\t\t\t, 0\n\t\t\t\t, _offset\n\t\t\t\t, 0\n\t\t\t\t, 0\n\t\t\t\t, ptr\n\t\t\t\t, 0\n\t\t\t\t, &srcBox\n\t\t\t\t);\n\n\t\t\tDX_RELEASE(ptr, 0);\n\t\t}\n#endif // 0\n\t}\n\n\tvoid VertexBufferD3D11::create(uint32_t _size, void* _data, VertexLayoutHandle _layoutHandle, uint16_t _flags)\n\t{\n\t\tm_layoutHandle = _layoutHandle;\n\t\tuint16_t stride = isValid(_layoutHandle)\n\t\t\t? s_renderD3D11->m_vertexLayouts[_layoutHandle.idx].m_stride\n\t\t\t: 0\n\t\t\t;\n\n\t\tBufferD3D11::create(_size, _data, _flags, stride, true);\n\t}\n\n\tstatic bool hasDepthOp(const void* _code, uint32_t _size)\n\t{\n\t\tbx::MemoryReader rd(_code, _size);\n\n\t\tbx::Error err;\n\t\tDxbcContext dxbc;\n\t\tread(&rd, dxbc, &err);\n\n\t\tstruct FindDepthOp\n\t\t{\n\t\t\tFindDepthOp()\n\t\t\t\t: m_found(false)\n\t\t\t{\n\t\t\t}\n\n\t\t\tstatic bool find(uint32_t /*_offset*/, const DxbcInstruction& _instruction, void* _userData)\n\t\t\t{\n\t\t\t\tFindDepthOp& out = *reinterpret_cast<FindDepthOp*>(_userData);\n\t\t\t\tif (_instruction.opcode == DxbcOpcode::DISCARD\n\t\t\t\t|| (0 != _instruction.numOperands &&  DxbcOperandType::OutputDepth == _instruction.operand[0].type) )\n\t\t\t\t{\n\t\t\t\t\tout.m_found = true;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tbool m_found;\n\n\t\t} find;\n\n\t\tparse(dxbc.shader, FindDepthOp::find, &find);\n\n\t\treturn find.m_found;\n\t}\n\n\tstatic void patchUAVRegisterByteCode(DxbcInstruction& _instruction, void* _userData)\n\t{\n\t\tBX_UNUSED(_userData);\n\n\t\tswitch (_instruction.opcode)\n\t\t{\n\t\tcase DxbcOpcode::DCL_UNORDERED_ACCESS_VIEW_TYPED:\n\t\t\t{\n\t\t\t\tDxbcOperand& operand = _instruction.operand[0];\n\t\t\t\toperand.regIndex[0] += 16;\n\n\t\t\t\tBX_ASSERT(operand.regIndex[1] == 0 && operand.regIndex[2] == 0, "Unexpected values");\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase DxbcOpcode::DCL_UNORDERED_ACCESS_VIEW_RAW:\n\t\t\tBX_ASSERT(false, "Unsupported UAV access");\n\t\t\tbreak;\n\n\t\tcase DxbcOpcode::DCL_UNORDERED_ACCESS_VIEW_STRUCTURED:\n\t\t\tBX_ASSERT(false, "Unsupported UAV access");\n\t\t\tbreak;\n\n\t\tcase DxbcOpcode::LD_UAV_TYPED:\n\t\t\t{\n\t\t\t\tDxbcOperand& operand = _instruction.operand[2];\n\t\t\t\toperand.regIndex[0] += 16;\n\n\t\t\t\tBX_ASSERT(operand.regIndex[1] == 0 && operand.regIndex[2] == 0, "Unexpected values");\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase DxbcOpcode::STORE_UAV_TYPED:\n\t\t\t{\n\t\t\t\tDxbcOperand& operand = _instruction.operand[0];\n\t\t\t\toperand.regIndex[0] += 16;\n\n\t\t\t\tBX_ASSERT(operand.regIndex[1] == 0 && operand.regIndex[2] == 0, "Unexpected values");\n\t\t\t}\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tstatic void patchUAVRegisterDebugInfo(DxbcSPDB& _spdb)\n\t{\n\t\tif (!_spdb.debugCode.empty())\n\t\t{\n\t\t\t// \'register( u[xx] )\'\n\t\t\tchar* ptr = (char*)_spdb.debugCode.data();\n\t\t\twhile (ptr < (char*)_spdb.debugCode.data() + _spdb.debugCode.size() - 3)\n\t\t\t{\n\t\t\t\tif (*(ptr+1) == \' \'\n\t\t\t\t&&\t*(ptr+2) == \'u\'\n\t\t\t\t&&\t*(ptr+3) == \'[\')\n\t\t\t\t{\n\t\t\t\t\tchar* startPtr = ptr+4;\n\t\t\t\t\tchar* endPtr = ptr+4;\n\n\t\t\t\t\twhile (*endPtr != \']\')\n\t\t\t\t\t{\n\t\t\t\t\t\tendPtr++;\n\t\t\t\t\t}\n\n\t\t\t\t\tuint32_t regNum = 0;\n\t\t\t\t\tuint32_t regLen = uint32_t(endPtr - startPtr);\n\t\t\t\t\tbx::fromString(&regNum, bx::StringView(startPtr, regLen));\n\n\t\t\t\t\tregNum += 16;\n\t\t\t\t\tuint32_t len = bx::toString(startPtr, regLen+2, regNum);\n\t\t\t\t\t*(startPtr + len) = \']\';\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t++ptr;\n\t\t\t}\n\t\t}\n\t}\n\n\tvoid ShaderD3D11::create(const Memory* _mem)\n\t{\n\t\tbx::MemoryReader reader(_mem->data, _mem->size);\n\n\t\tbx::ErrorAssert err;\n\n\t\tuint32_t magic;\n\t\tbx::read(&reader, magic, &err);\n\n\t\tconst bool fragment = isShaderType(magic, \'F\');\n\n\t\tuint32_t hashIn;\n\t\tbx::read(&reader, hashIn, &err);\n\n\t\tuint32_t hashOut;\n\n\t\tif (isShaderVerLess(magic, 6) )\n\t\t{\n\t\t\thashOut = hashIn;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tbx::read(&reader, hashOut, &err);\n\t\t}\n\n\t\tuint16_t count;\n\t\tbx::read(&reader, count, &err);\n\n\t\tm_numPredefined = 0;\n\t\tm_numUniforms = count;\n\n\t\tBX_TRACE("%s Shader consts %d"\n\t\t\t, getShaderTypeName(magic)\n\t\t\t, count\n\t\t\t);\n\n\t\tconst uint8_t fragmentBit = fragment ? kUniformFragmentBit : 0;\n\n\t\tif (0 < count)\n\t\t{\n\t\t\tfor (uint32_t ii = 0; ii < count; ++ii)\n\t\t\t{\n\t\t\t\tuint8_t nameSize = 0;\n\t\t\t\tbx::read(&reader, nameSize, &err);\n\n\t\t\t\tchar name[256] = { \'\\0\' };\n\t\t\t\tbx::read(&reader, &name, nameSize, &err);\n\t\t\t\tname[nameSize] = \'\\0\';\n\n\t\t\t\tuint8_t type = 0;\n\t\t\t\tbx::read(&reader, type, &err);\n\n\t\t\t\tuint8_t num = 0;\n\t\t\t\tbx::read(&reader, num, &err);\n\n\t\t\t\tuint16_t regIndex = 0;\n\t\t\t\tbx::read(&reader, regIndex, &err);\n\n\t\t\t\tuint16_t regCount = 0;\n\t\t\t\tbx::read(&reader, regCount, &err);\n\n\t\t\t\tif (!isShaderVerLess(magic, 8) )\n\t\t\t\t{\n\t\t\t\t\tuint16_t texInfo = 0;\n\t\t\t\t\tbx::read(&reader, texInfo, &err);\n\t\t\t\t}\n\n\t\t\t\tif (!isShaderVerLess(magic, 10) )\n\t\t\t\t{\n\t\t\t\t\tuint16_t texFormat = 0;\n\t\t\t\t\tbx::read(&reader, texFormat, &err);\n\t\t\t\t}\n\n\t\t\t\tconst char* kind = "invalid";\n\n\t\t\t\tPredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);\n\t\t\t\tif (PredefinedUniform::Count != predefined)\n\t\t\t\t{\n\t\t\t\t\tkind = "predefined";\n\t\t\t\t\tm_predefined[m_numPredefined].m_loc   = regIndex;\n\t\t\t\t\tm_predefined[m_numPredefined].m_count = regCount;\n\t\t\t\t\tm_predefined[m_numPredefined].m_type  = uint8_t(predefined|fragmentBit);\n\t\t\t\t\tm_numPredefined++;\n\t\t\t\t}\n\t\t\t\telse if (0 == (kUniformSamplerBit & type) )\n\t\t\t\t{\n\t\t\t\t\tconst UniformRegInfo* info = s_renderD3D11->m_uniformReg.find(name);\n\t\t\t\t\tBX_WARN(NULL != info, "User defined uniform \'%s\' is not found, it won\'t be set.", name);\n\n\t\t\t\t\tif (NULL != info)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (NULL == m_constantBuffer)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tm_constantBuffer = UniformBuffer::create(1024);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tkind = "user";\n\t\t\t\t\t\tm_constantBuffer->writeUniformHandle( (UniformType::Enum)(type|fragmentBit), regIndex, info->m_handle, regCount);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tkind = "sampler";\n\t\t\t\t}\n\n\t\t\t\tBX_TRACE("\\t%s: %s (%s), num %2d, r.index %3d, r.count %2d"\n\t\t\t\t\t, kind\n\t\t\t\t\t, name\n\t\t\t\t\t, getUniformTypeName(UniformType::Enum(type&~kUniformMask) )\n\t\t\t\t\t, num\n\t\t\t\t\t, regIndex\n\t\t\t\t\t, regCount\n\t\t\t\t\t);\n\t\t\t\tBX_UNUSED(kind);\n\t\t\t}\n\n\t\t\tif (NULL != m_constantBuffer)\n\t\t\t{\n\t\t\t\tm_constantBuffer->finish();\n\t\t\t}\n\t\t}\n\n\t\tuint32_t shaderSize;\n\t\tbx::read(&reader, shaderSize, &err);\n\n\t\tconst void* code = reader.getDataPtr();\n\t\tbx::skip(&reader, shaderSize+1);\n\n\t\tconst Memory* temp = NULL;\n\n\t\tif (!isShaderType(magic, \'C\'))\n\t\t{\n\t\t\tbx::MemoryReader rd(code, shaderSize);\n\n\t\t\tDxbcContext dxbc;\n\t\t\tread(&rd, dxbc, bx::ErrorAssert{});\n\n\t\t\tbool patchShader = !dxbc.shader.aon9;\n\t\t\tif (patchShader)\n\t\t\t{\n\t\t\t\tunion { uint32_t offset; void* ptr; } cast = { 0 };\n\t\t\t\tfilter(dxbc.shader, dxbc.shader, patchUAVRegisterByteCode, cast.ptr);\n\t\t\t\tpatchUAVRegisterDebugInfo(dxbc.spdb);\n\n\t\t\t\ttemp = alloc(shaderSize);\n\t\t\t\tbx::StaticMemoryBlockWriter wr(temp->data, temp->size);\n\n\t\t\t\tint32_t size = write(&wr, dxbc, &err);\n\t\t\t\tdxbcHash(temp->data + 20, size - 20, temp->data + 4);\n\n\t\t\t\tcode = temp->data;\n\t\t\t}\n\t\t}\n\n\t\tif (isShaderType(magic, \'F\') )\n\t\t{\n\t\t\tm_hasDepthOp = hasDepthOp(code, shaderSize);\n\t\t\tDX_CHECK(s_renderD3D11->m_device->CreatePixelShader(code, shaderSize, NULL, &m_pixelShader) );\n\t\t\tBGFX_FATAL(NULL != m_ptr, bgfx::Fatal::InvalidShader, "Failed to create fragment shader.");\n\t\t}\n\t\telse if (isShaderType(magic, \'V\') )\n\t\t{\n\t\t\tm_hash = bx::hash<bx::HashMurmur2A>(code, shaderSize);\n\t\t\tm_code = copy(code, shaderSize);\n\n\t\t\tDX_CHECK(s_renderD3D11->m_device->CreateVertexShader(code, shaderSize, NULL, &m_vertexShader) );\n\t\t\tBGFX_FATAL(NULL != m_ptr, bgfx::Fatal::InvalidShader, "Failed to create vertex shader.");\n\t\t}\n\t\telse if (isShaderType(magic, \'C\') )\n\t\t{\n\t\t\tDX_CHECK(s_renderD3D11->m_device->CreateComputeShader(code, shaderSize, NULL, &m_computeShader) );\n\t\t\tBGFX_FATAL(NULL != m_ptr, bgfx::Fatal::InvalidShader, "Failed to create compute shader.");\n\t\t}\n\n\t\tuint8_t numAttrs = 0;\n\t\tbx::read(&reader, numAttrs, bx::ErrorAssert{});\n\n\t\tbx::memSet(m_attrMask, 0, sizeof(m_attrMask) );\n\n\t\tfor (uint32_t ii = 0; ii < numAttrs; ++ii)\n\t\t{\n\t\t\tuint16_t id;\n\t\t\tbx::read(&reader, id, bx::ErrorAssert{});\n\n\t\t\tAttrib::Enum attr = idToAttrib(id);\n\n\t\t\tif (Attrib::Count != attr)\n\t\t\t{\n\t\t\t\tm_attrMask[attr] = UINT16_MAX;\n\t\t\t}\n\t\t}\n\n\t\tuint16_t size;\n\t\tbx::read(&reader, size, bx::ErrorAssert{});\n\n\t\tif (0 < size)\n\t\t{\n\t\t\tD3D11_BUFFER_DESC desc;\n\t\t\tdesc.ByteWidth = (size + 0xf) & ~0xf;\n\t\t\tdesc.Usage = D3D11_USAGE_DEFAULT;\n\t\t\tdesc.CPUAccessFlags = 0;\n\t\t\tdesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;\n\t\t\tdesc.MiscFlags = 0;\n\t\t\tdesc.StructureByteStride = 0;\n\t\t\tDX_CHECK(s_renderD3D11->m_device->CreateBuffer(&desc, NULL, &m_buffer) );\n\n\t\t\tBX_TRACE("\\tCB size: %d", desc.ByteWidth);\n\t\t}\n\n\t\tif (NULL != temp)\n\t\t{\n\t\t\trelease(temp);\n\t\t}\n\t}\n\n\tvoid* DirectAccessResourceD3D11::createTexture2D(const D3D11_TEXTURE2D_DESC* _gpuDesc, const D3D11_SUBRESOURCE_DATA* _srd, ID3D11Texture2D** _gpuTexture2d)\n\t{\n\t\tID3D11Device* device = s_renderD3D11->m_device;\n\t\tDX_CHECK(setIntelDirectAccessResource(device) );\n\t\tDX_CHECK(device->CreateTexture2D(_gpuDesc, _srd, _gpuTexture2d) );\n\n\t\tD3D11_TEXTURE2D_DESC cpuDesc;\n\t\tbx::memCopy(&cpuDesc, _gpuDesc, sizeof(cpuDesc) );\n\t\tcpuDesc.BindFlags = 0;\n\t\tcpuDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;\n\t\tcpuDesc.Usage = D3D11_USAGE_STAGING;\n\n\t\tDX_CHECK(setIntelDirectAccessResource(s_renderD3D11->m_device) );\n\t\tDX_CHECK(device->CreateTexture2D(&cpuDesc, NULL, &m_texture2d) );\n\n\t\tID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;\n\t\tdeviceCtx->CopyResource(m_texture2d, *_gpuTexture2d);\n\n\t\tD3D11_MAPPED_SUBRESOURCE mappedResource;\n\t\tdeviceCtx->Map(m_texture2d, 0, D3D11_MAP_WRITE, 0, &mappedResource);\n\t\tm_descriptor = reinterpret_cast<IntelDirectAccessResourceDescriptor*>(mappedResource.pData);\n\n\t\treturn m_descriptor->ptr;\n\t}\n\n\tvoid* DirectAccessResourceD3D11::createTexture3D(const D3D11_TEXTURE3D_DESC* _gpuDesc, const D3D11_SUBRESOURCE_DATA* _srd, ID3D11Texture3D** _gpuTexture3d)\n\t{\n\t\tID3D11Device* device = s_renderD3D11->m_device;\n\t\tDX_CHECK(setIntelDirectAccessResource(device) );\n\t\tDX_CHECK(device->CreateTexture3D(_gpuDesc, _srd, _gpuTexture3d) );\n\n\t\tD3D11_TEXTURE3D_DESC cpuDesc;\n\t\tbx::memCopy(&cpuDesc, _gpuDesc, sizeof(cpuDesc) );\n\t\tcpuDesc.BindFlags = 0;\n\t\tcpuDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;\n\t\tcpuDesc.Usage = D3D11_USAGE_STAGING;\n\n\t\tDX_CHECK(setIntelDirectAccessResource(s_renderD3D11->m_device) );\n\t\tDX_CHECK(device->CreateTexture3D(&cpuDesc, NULL, &m_texture3d) );\n\n\t\tID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;\n\t\tdeviceCtx->CopyResource(m_texture3d, *_gpuTexture3d);\n\n\t\tD3D11_MAPPED_SUBRESOURCE mappedResource;\n\t\tdeviceCtx->Map(m_texture3d, 0, D3D11_MAP_WRITE, 0, &mappedResource);\n\t\tm_descriptor = reinterpret_cast<IntelDirectAccessResourceDescriptor*>(mappedResource.pData);\n\n\t\treturn m_descriptor->ptr;\n\t}\n\n\tvoid DirectAccessResourceD3D11::destroy()\n\t{\n\t\tif (NULL != m_descriptor)\n\t\t{\n\t\t\ts_renderD3D11->m_deviceCtx->Unmap(m_ptr, 0);\n\t\t\tm_descriptor = NULL;\n\t\t\tDX_RELEASE(m_ptr, 0);\n\t\t}\n\t}\n\n\tvoid* TextureD3D11::create(const Memory* _mem, uint64_t _flags, uint8_t _skip)\n\t{\n\t\tvoid* directAccessPtr = NULL;\n\n\t\tbimg::ImageContainer imageContainer;\n\n\t\tif (bimg::imageParse(imageContainer, _mem->data, _mem->size) )\n\t\t{\n\t\t\tconst bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(imageContainer.m_format) );\n\t\t\tconst uint8_t startLod = bx::min<uint8_t>(_skip, imageContainer.m_numMips-1);\n\n\t\t\tbimg::TextureInfo ti;\n\t\t\tbimg::imageGetSize(\n\t\t\t\t  &ti\n\t\t\t\t, uint16_t(imageContainer.m_width >>startLod)\n\t\t\t\t, uint16_t(imageContainer.m_height>>startLod)\n\t\t\t\t, uint16_t(imageContainer.m_depth >>startLod)\n\t\t\t\t, imageContainer.m_cubeMap\n\t\t\t\t, 1 < imageContainer.m_numMips\n\t\t\t\t, imageContainer.m_numLayers\n\t\t\t\t, imageContainer.m_format\n\t\t\t\t);\n\t\t\tti.numMips = bx::min<uint8_t>(imageContainer.m_numMips-startLod, ti.numMips);\n\n\t\t\tm_flags     = _flags;\n\t\t\tm_width     = ti.width;\n\t\t\tm_height    = ti.height;\n\t\t\tm_depth     = ti.depth;\n\t\t\tm_numLayers = ti.numLayers;\n\n\t\t\tm_requestedFormat  = uint8_t(imageContainer.m_format);\n\t\t\tm_textureFormat    = uint8_t(getViableTextureFormat(imageContainer) );\n\t\t\tconst bool convert = m_textureFormat != m_requestedFormat;\n\t\t\tconst uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) );\n\n\t\t\tif (imageContainer.m_cubeMap)\n\t\t\t{\n\t\t\t\tm_type  = TextureCube;\n\t\t\t}\n\t\t\telse if (imageContainer.m_depth > 1)\n\t\t\t{\n\t\t\t\tm_type = Texture3D;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tm_type = Texture2D;\n\t\t\t}\n\n\t\t\tm_numMips = ti.numMips;\n\n\t\t\tconst uint16_t numSides = ti.numLayers * (imageContainer.m_cubeMap ? 6 : 1);\n\t\t\tconst uint32_t numSrd   = numSides * ti.numMips;\n\t\t\tD3D11_SUBRESOURCE_DATA* srd = (D3D11_SUBRESOURCE_DATA*)alloca(numSrd*sizeof(D3D11_SUBRESOURCE_DATA) );\n\n\t\t\tuint32_t kk = 0;\n\n\t\t\tconst bool compressed = bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) );\n\t\t\tconst bool swizzle    = TextureFormat::BGRA8 == m_textureFormat && 0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE);\n\n\t\t\tBX_TRACE("Texture %3d: %s (requested: %s), layers %d, %dx%d%s%s%s."\n\t\t\t\t, getHandle()\n\t\t\t\t, getName( (TextureFormat::Enum)m_textureFormat)\n\t\t\t\t, getName( (TextureFormat::Enum)m_requestedFormat)\n\t\t\t\t, ti.numLayers\n\t\t\t\t, ti.width\n\t\t\t\t, ti.height\n\t\t\t\t, imageContainer.m_cubeMap ? "x6" : ""\n\t\t\t\t, 0 != (m_flags&BGFX_TEXTURE_RT_MASK) ? " (render target)" : ""\n\t\t\t\t, swizzle ? " (swizzle BGRA8 -> RGBA8)" : ""\n\t\t\t\t);\n\n\t\t\tuint8_t* temp = NULL;\n\t\t\tfor (uint16_t side = 0; side < numSides; ++side)\n\t\t\t{\n\t\t\t\tfor (uint8_t lod = 0, num = ti.numMips; lod < num; ++lod)\n\t\t\t\t{\n\t\t\t\t\tbimg::ImageMip mip;\n\t\t\t\t\tif (bimg::imageGetRawData(imageContainer, side, lod+startLod, _mem->data, _mem->size, mip) )\n\t\t\t\t\t{\n\t\t\t\t\t\tsrd[kk].pSysMem = mip.m_data;\n\n\t\t\t\t\t\tif (convert)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tuint32_t srcpitch = mip.m_width*bpp/8;\n\t\t\t\t\t\t\ttemp = (uint8_t*)BX_ALLOC(g_allocator, srcpitch*mip.m_height);\n\t\t\t\t\t\t\tbimg::imageDecodeToBgra8(g_allocator, temp, mip.m_data, mip.m_width, mip.m_height, srcpitch, mip.m_format);\n\n\t\t\t\t\t\t\tsrd[kk].pSysMem = temp;\n\t\t\t\t\t\t\tsrd[kk].SysMemPitch = srcpitch;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (compressed)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsrd[kk].SysMemPitch      = (mip.m_width /blockInfo.blockWidth )*mip.m_blockSize;\n\t\t\t\t\t\t\tsrd[kk].SysMemSlicePitch = (mip.m_height/blockInfo.blockHeight)*srd[kk].SysMemPitch;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsrd[kk].SysMemPitch = mip.m_width*mip.m_bpp/8;\n\n\t\t\t\t\t\t\tswitch (m_textureFormat)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase TextureFormat::R5G6B5:\n\t\t\t\t\t\t\t\ttemp = (uint8_t*)BX_ALLOC(g_allocator, srd[kk].SysMemPitch*mip.m_height);\n\t\t\t\t\t\t\t\tbimg::imageConvert(temp, 16, bx::packB5G6R5, mip.m_data, bx::unpackR5G6B5, srd[kk].SysMemPitch*mip.m_height);\n\t\t\t\t\t\t\t\tsrd[kk].pSysMem = temp;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase TextureFormat::RGBA4:\n\t\t\t\t\t\t\t\ttemp = (uint8_t*)BX_ALLOC(g_allocator, srd[kk].SysMemPitch*mip.m_height);\n\t\t\t\t\t\t\t\tbimg::imageConvert(temp, 16, bx::packBgra4, mip.m_data, bx::unpackRgba4, srd[kk].SysMemPitch*mip.m_height);\n\t\t\t\t\t\t\t\tsrd[kk].pSysMem = temp;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase TextureFormat::RGB5A1:\n\t\t\t\t\t\t\t\ttemp = (uint8_t*)BX_ALLOC(g_allocator, srd[kk].SysMemPitch*mip.m_height);\n\t\t\t\t\t\t\t\tbimg::imageConvert(temp, 16, bx::packBgr5a1, mip.m_data, bx::unpackRgb5a1, srd[kk].SysMemPitch*mip.m_height);\n\t\t\t\t\t\t\t\tsrd[kk].pSysMem = temp;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tsrd[kk].SysMemSlicePitch = mip.m_height*srd[kk].SysMemPitch;\n\t\t\t\t\t\t++kk;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst bool writeOnly    = 0 != (m_flags&(BGFX_TEXTURE_RT_WRITE_ONLY|BGFX_TEXTURE_READ_BACK) );\n\t\t\tconst bool computeWrite = 0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE);\n\t\t\tconst bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK);\n\t\t\tconst bool srgb         = 0 != (m_flags&BGFX_TEXTURE_SRGB);\n\t\t\tconst bool blit         = 0 != (m_flags&BGFX_TEXTURE_BLIT_DST);\n\t\t\tconst bool readBack     = 0 != (m_flags&BGFX_TEXTURE_READ_BACK);\n\t\t\tconst uint32_t msaaQuality = bx::uint32_satsub( (m_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT, 1);\n\t\t\tconst DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality];\n\t\t\tconst bool msaaSample  = true\n\t\t\t\t&& 1 < msaa.Count\n\t\t\t\t&& 0 != (m_flags&BGFX_TEXTURE_MSAA_SAMPLE)\n\t\t\t\t&& !writeOnly\n\t\t\t\t;\n\t\t\tconst bool needResolve = true\n\t\t\t\t&& 1 < msaa.Count\n\t\t\t\t&& 0 == (m_flags&BGFX_TEXTURE_MSAA_SAMPLE)\n\t\t\t\t&& !writeOnly\n\t\t\t\t;\n\n\t\t\tD3D11_SHADER_RESOURCE_VIEW_DESC srvd;\n\t\t\tbx::memSet(&srvd, 0, sizeof(srvd) );\n\n\t\t\tDXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;\n\t\t\tif (swizzle)\n\t\t\t{\n\t\t\t\tformat      = srgb ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM;\n\t\t\t\tsrvd.Format = format;\n\t\t\t}\n\t\t\telse if (srgb)\n\t\t\t{\n\t\t\t\tformat      = s_textureFormat[m_textureFormat].m_fmtSrgb;\n\t\t\t\tsrvd.Format = format;\n\t\t\t\tBX_WARN(format != DXGI_FORMAT_UNKNOWN, "sRGB not supported for texture format %d", m_textureFormat);\n\t\t\t}\n\n\t\t\tif (format == DXGI_FORMAT_UNKNOWN)\n\t\t\t{\n\t\t\t\t// not swizzled and not sRGB, or sRGB unsupported\n\t\t\t\tformat      = s_textureFormat[m_textureFormat].m_fmt;\n\t\t\t\tsrvd.Format = getSrvFormat();\n\t\t\t}\n\n\t\t\tconst bool directAccess = s_renderD3D11->m_directAccessSupport\n\t\t\t\t&& !renderTarget\n\t\t\t\t&& !readBack\n\t\t\t\t&& !blit\n\t\t\t\t&& !writeOnly\n\t\t\t\t;\n\n\t\t\tswitch (m_type)\n\t\t\t{\n\t\t\tcase Texture2D:\n\t\t\tcase TextureCube:\n\t\t\t\t{\n\t\t\t\t\tD3D11_TEXTURE2D_DESC desc = {};\n\t\t\t\t\tdesc.Width      = ti.width;\n\t\t\t\t\tdesc.Height     = ti.height;\n\t\t\t\t\tdesc.MipLevels  = ti.numMips;\n\t\t\t\t\tdesc.ArraySize  = numSides;\n\t\t\t\t\tdesc.Format     = format;\n\t\t\t\t\tdesc.SampleDesc = msaa;\n\t\t\t\t\tdesc.Usage      = kk == 0 || blit ? D3D11_USAGE_DEFAULT : D3D11_USAGE_IMMUTABLE;\n\t\t\t\t\tdesc.BindFlags  = writeOnly ? 0 : D3D11_BIND_SHADER_RESOURCE;\n\t\t\t\t\tdesc.CPUAccessFlags = 0;\n\t\t\t\t\tdesc.MiscFlags      = 0;\n\n\t\t\t\t\tif (bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) )\n\t\t\t\t\t{\n\t\t\t\t\t\tdesc.BindFlags |= D3D11_BIND_DEPTH_STENCIL;\n\t\t\t\t\t\tdesc.Usage = D3D11_USAGE_DEFAULT;\n\t\t\t\t\t}\n\t\t\t\t\telse if (renderTarget)\n\t\t\t\t\t{\n\t\t\t\t\t\tdesc.BindFlags |= D3D11_BIND_RENDER_TARGET;\n\t\t\t\t\t\tdesc.Usage = D3D11_USAGE_DEFAULT;\n\t\t\t\t\t\tdesc.MiscFlags |= 0\n\t\t\t\t\t\t\t| (1 < ti.numMips ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0)\n\t\t\t\t\t\t\t;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (computeWrite)\n\t\t\t\t\t{\n\t\t\t\t\t\tdesc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;\n\t\t\t\t\t\tdesc.Usage = D3D11_USAGE_DEFAULT;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (readBack)\n\t\t\t\t\t{\n\t\t\t\t\t\tdesc.BindFlags      = 0;\n\t\t\t\t\t\tdesc.Usage          = D3D11_USAGE_STAGING;\n\t\t\t\t\t\tdesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (imageContainer.m_cubeMap)\n\t\t\t\t\t{\n\t\t\t\t\t\tdesc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE;\n\t\t\t\t\t\tif (1 < ti.numLayers)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsrvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;\n\t\t\t\t\t\t\tsrvd.TextureCubeArray.MipLevels = ti.numMips;\n\t\t\t\t\t\t\tsrvd.TextureCubeArray.NumCubes  = ti.numLayers;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsrvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;\n\t\t\t\t\t\t\tsrvd.TextureCube.MipLevels = ti.numMips;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (msaaSample)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (1 < ti.numLayers)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsrvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;\n\t\t\t\t\t\t\t\tsrvd.Texture2DMSArray.ArraySize = ti.numLayers;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsrvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (1 < ti.numLayers)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsrvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;\n\t\t\t\t\t\t\t\tsrvd.Texture2DArray.MipLevels = ti.numMips;\n\t\t\t\t\t\t\t\tsrvd.Texture2DArray.ArraySize = ti.numLayers;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsrvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;\n\t\t\t\t\t\t\t\tsrvd.Texture2D.MipLevels = ti.numMips;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (needResolve)\n\t\t\t\t\t{\n\t\t\t\t\t\tDX_CHECK(s_renderD3D11->m_device->CreateTexture2D(&desc, NULL, &m_rt2d) );\n\t\t\t\t\t\tdesc.BindFlags &= ~(D3D11_BIND_RENDER_TARGET|D3D11_BIND_DEPTH_STENCIL);\n\t\t\t\t\t\tdesc.SampleDesc = s_msaa[0];\n\t\t\t\t\t}\n\n\t\t\t\t\tif (directAccess)\n\t\t\t\t\t{\n\t\t\t\t\t\tdirectAccessPtr = m_dar.createTexture2D(&desc, kk == 0 ? NULL : srd, &m_texture2d);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tDX_CHECK(s_renderD3D11->m_device->CreateTexture2D(&desc, kk == 0 ? NULL : srd, &m_texture2d) );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase Texture3D:\n\t\t\t\t{\n\t\t\t\t\tD3D11_TEXTURE3D_DESC desc = {};\n\t\t\t\t\tdesc.Width     = ti.width;\n\t\t\t\t\tdesc.Height    = ti.height;\n\t\t\t\t\tdesc.Depth     = ti.depth;\n\t\t\t\t\tdesc.MipLevels = ti.numMips;\n\t\t\t\t\tdesc.Format    = format;\n\t\t\t\t\tdesc.Usage     = kk == 0 || blit ? D3D11_USAGE_DEFAULT : D3D11_USAGE_IMMUTABLE;\n\t\t\t\t\tdesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;\n\t\t\t\t\tdesc.CPUAccessFlags = 0;\n\t\t\t\t\tdesc.MiscFlags      = 0;\n\n\t\t\t\t\tif (renderTarget)\n\t\t\t\t\t{\n\t\t\t\t\t\tdesc.BindFlags |= D3D11_BIND_RENDER_TARGET;\n\t\t\t\t\t\tdesc.Usage = D3D11_USAGE_DEFAULT;\n\t\t\t\t\t\tdesc.MiscFlags |= 0\n\t\t\t\t\t\t\t| (1 < ti.numMips ? D3D11_RESOURCE_MISC_GENERATE_MIPS : 0)\n\t\t\t\t\t\t\t;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (computeWrite)\n\t\t\t\t\t{\n\t\t\t\t\t\tdesc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;\n\t\t\t\t\t\tdesc.Usage = D3D11_USAGE_DEFAULT;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (readBack)\n\t\t\t\t\t{\n\t\t\t\t\t\tdesc.BindFlags = 0;\n\t\t\t\t\t\tdesc.Usage = D3D11_USAGE_STAGING;\n\t\t\t\t\t\tdesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;\n\t\t\t\t\t}\n\n\t\t\t\t\tsrvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;\n\t\t\t\t\tsrvd.Texture3D.MipLevels = ti.numMips;\n\n\t\t\t\t\tif (directAccess)\n\t\t\t\t\t{\n\t\t\t\t\t\tdirectAccessPtr = m_dar.createTexture3D(&desc, kk == 0 ? NULL : srd, &m_texture3d);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tDX_CHECK(s_renderD3D11->m_device->CreateTexture3D(&desc, kk == 0 ? NULL : srd, &m_texture3d) );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (!writeOnly)\n\t\t\t{\n\t\t\t\tDX_CHECK(s_renderD3D11->m_device->CreateShaderResourceView(m_ptr, &srvd, &m_srv) );\n\t\t\t}\n\n\t\t\tif (computeWrite)\n\t\t\t{\n\t\t\t\tDX_CHECK(s_renderD3D11->m_device->CreateUnorderedAccessView(m_ptr, NULL, &m_uav) );\n\t\t\t}\n\n\t\t\tif (temp != NULL)\n\t\t\t{\n\t\t\t\tkk = 0;\n\t\t\t\tfor (uint16_t side = 0; side < numSides; ++side)\n\t\t\t\t{\n\t\t\t\t\tfor (uint32_t lod = 0, num = ti.numMips; lod < num; ++lod)\n\t\t\t\t\t{\n\t\t\t\t\t\tBX_FREE(g_allocator, const_cast<void*>(srd[kk].pSysMem) );\n\t\t\t\t\t\t++kk;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn directAccessPtr;\n\t}\n\n\tvoid TextureD3D11::destroy()\n\t{\n\t\tm_dar.destroy();\n\n\t\ts_renderD3D11->m_srvUavLru.invalidateWithParent(getHandle().idx);\n\t\tDX_RELEASE(m_rt, 0);\n\t\tDX_RELEASE(m_srv, 0);\n\t\tDX_RELEASE(m_uav, 0);\n\t\tif (0 == (m_flags & BGFX_SAMPLER_INTERNAL_SHARED) )\n\t\t{\n\t\t\tDX_RELEASE(m_ptr, 0);\n\t\t}\n\t}\n\n\tvoid TextureD3D11::overrideInternal(uintptr_t _ptr)\n\t{\n\t\tD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc{};\n\n\t\tconst bool readable = (m_srv != NULL);\n\t\tif (readable)\n\t\t{\n\t\t\tm_srv->GetDesc(&srvDesc);\n\t\t}\n\n\t\tdestroy();\n\t\tm_flags |= BGFX_SAMPLER_INTERNAL_SHARED;\n\t\tm_ptr = (ID3D11Resource*)_ptr;\n\n\t\tif (readable)\n\t\t{\n\t\t\ts_renderD3D11->m_device->CreateShaderResourceView(m_ptr, &srvDesc, &m_srv);\n\t\t}\n\t}\n\n\tvoid TextureD3D11::update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem)\n\t{\n\t\tID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;\n\n\t\tD3D11_BOX box;\n\t\tbox.left   = _rect.m_x;\n\t\tbox.top    = _rect.m_y;\n\t\tbox.right  = box.left + _rect.m_width;\n\t\tbox.bottom = box.top  + _rect.m_height;\n\n\t\tuint32_t layer = 0;\n\n\t\tif (TextureD3D11::Texture3D == m_type)\n\t\t{\n\t\t\tbox.front = _z;\n\t\t\tbox.back  = box.front + _depth;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tlayer = _z * (TextureD3D11::TextureCube == m_type ? 6 : 1);\n\t\t\tbox.front = 0;\n\t\t\tbox.back  = 1;\n\t\t}\n\n\t\tconst bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_textureFormat) );\n\t\tconst uint16_t bpp    = blockInfo.bitsPerPixel;\n\t\tconst uint32_t subres = _mip + ( (layer + _side) * m_numMips);\n\t\tconst bool     depth  = bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) );\n\t\tuint32_t rectpitch  = _rect.m_width*bpp/8;\n\t\tif (bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) ) )\n\t\t{\n\t\t\trectpitch = (_rect.m_width / blockInfo.blockWidth)*blockInfo.blockSize;\n\t\t}\n\n\t\tconst uint32_t srcpitch   = UINT16_MAX == _pitch ? rectpitch : _pitch;\n\t\tconst uint32_t slicepitch = rectpitch*_rect.m_height;\n\n\t\tconst bool convert = m_textureFormat != m_requestedFormat;\n\n\t\tuint8_t* data = _mem->data;\n\t\tuint8_t* temp = NULL;\n\n\t\tif (convert)\n\t\t{\n\t\t\ttemp = (uint8_t*)BX_ALLOC(g_allocator, slicepitch);\n\t\t\tbimg::imageDecodeToBgra8(g_allocator, temp, data, _rect.m_width, _rect.m_height, srcpitch, bimg::TextureFormat::Enum(m_requestedFormat) );\n\t\t\tdata = temp;\n\n\t\t\tbox.right  = bx::max(1u, m_width  >> _mip);\n\t\t\tbox.bottom = bx::max(1u, m_height >> _mip);\n\t\t}\n\n\t\tdeviceCtx->UpdateSubresource(\n\t\t\t  m_ptr\n\t\t\t, subres\n\t\t\t, depth ? NULL : &box\n\t\t\t, data\n\t\t\t, srcpitch\n\t\t\t, TextureD3D11::Texture3D == m_type ? slicepitch : 0\n\t\t\t);\n\n\t\tif (NULL != temp)\n\t\t{\n\t\t\tBX_FREE(g_allocator, temp);\n\t\t}\n\t}\n\n\tvoid TextureD3D11::commit(uint8_t _stage, uint32_t _flags, const float _palette[][4])\n\t{\n\t\tTextureStage& ts = s_renderD3D11->m_textureStage;\n\n\t\tif (0 != (_flags & BGFX_SAMPLER_SAMPLE_STENCIL) )\n\t\t{\n\t\t\tts.m_srv[_stage] = s_renderD3D11->getCachedSrv(\n\t\t\t\t  TextureHandle{ uint16_t(this - s_renderD3D11->m_textures) }\n\t\t\t\t, 0\n\t\t\t\t, false\n\t\t\t\t, true\n\t\t\t\t);\n\t\t}\n\t\telse\n\t\t{\n\t\t\tts.m_srv[_stage] = m_srv;\n\t\t}\n\n\t\tconst uint32_t flags = 0 == (BGFX_SAMPLER_INTERNAL_DEFAULT & _flags)\n\t\t\t? _flags\n\t\t\t: uint32_t(m_flags)\n\t\t\t;\n\t\tuint32_t index = (flags & BGFX_SAMPLER_BORDER_COLOR_MASK) >> BGFX_SAMPLER_BORDER_COLOR_SHIFT;\n\t\tts.m_sampler[_stage] = s_renderD3D11->getSamplerState(flags, _palette[index]);\n\t}\n\n\tvoid TextureD3D11::resolve(uint8_t _resolve, uint32_t _layer, uint32_t _numLayers, uint32_t _mip) const\n\t{\n\t\tID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;\n\n\t\tconst bool needResolve = NULL != m_rt;\n\t\tif (needResolve)\n\t\t{\n\t\t\tfor (uint32_t ii = _layer; ii < _numLayers; ++ii)\n\t\t\t{\n\t\t\t\tconst UINT resource = _mip + (ii * m_numMips);\n\t\t\t\tdeviceCtx->ResolveSubresource(m_texture2d, resource, m_rt, resource, s_textureFormat[m_textureFormat].m_fmt);\n\t\t\t}\n\t\t}\n\n\t\tconst bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK);\n\t\tif (renderTarget\n\t\t&&  1 < m_numMips\n\t\t&&  0 != (_resolve & BGFX_RESOLVE_AUTO_GEN_MIPS) )\n\t\t{\n\t\t\tdeviceCtx->GenerateMips(m_srv);\n\t\t}\n\t}\n\n\tTextureHandle TextureD3D11::getHandle() const\n\t{\n\t\tTextureHandle handle = { (uint16_t)(this - s_renderD3D11->m_textures) };\n\t\treturn handle;\n\t}\n\n\tDXGI_FORMAT TextureD3D11::getSrvFormat() const\n\t{\n\t\tif (bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) )\n\t\t{\n\t\t\treturn s_textureFormat[m_textureFormat].m_fmtSrv;\n\t\t}\n\n\t\treturn 0 != (m_flags&BGFX_TEXTURE_SRGB)\n\t\t\t? s_textureFormat[m_textureFormat].m_fmtSrgb\n\t\t\t: s_textureFormat[m_textureFormat].m_fmt\n\t\t\t;\n\t}\n\n\tvoid FrameBufferD3D11::create(uint8_t _num, const Attachment* _attachment)\n\t{\n\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(m_rtv); ++ii)\n\t\t{\n\t\t\tm_rtv[ii] = NULL;\n\t\t}\n\n\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(m_uav); ++ii)\n\t\t{\n\t\t\tm_uav[ii] = NULL;\n\t\t}\n\n\t\tm_dsv       = NULL;\n\t\tm_swapChain = NULL;\n\n\t\tm_denseIdx = UINT16_MAX;\n\t\tm_numTh    = _num;\n\t\tm_needPresent = false;\n\t\tbx::memCopy(m_attachment, _attachment, _num*sizeof(Attachment) );\n\n\t\tpostReset();\n\t}\n\n\tvoid FrameBufferD3D11::create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _format, TextureFormat::Enum _depthFormat)\n\t{\n\t\tSwapChainDesc scd;\n\t\tbx::memCopy(&scd, &s_renderD3D11->m_scd, sizeof(SwapChainDesc) );\n\t\tscd.format     = TextureFormat::Count == _format ? scd.format : s_textureFormat[_format].m_fmt;\n\t\tscd.width      = _width;\n\t\tscd.height     = _height;\n\t\tscd.nwh        = _nwh;\n\t\tscd.ndt        = NULL;\n\t\tscd.sampleDesc = s_msaa[0];\n\n\t\tID3D11Device* device = s_renderD3D11->m_device;\n\n\t\tHRESULT hr = s_renderD3D11->m_dxgi.createSwapChain(device\n\t\t\t, scd\n\t\t\t, &m_swapChain\n\t\t\t);\n\t\tBGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Failed to create swap chain.");\n\n#if BX_PLATFORM_WINDOWS\n\t\tDX_CHECK(s_renderD3D11->m_dxgi.m_factory->MakeWindowAssociation(\n\t\t\t  (HWND)_nwh\n\t\t\t, 0\n\t\t\t| DXGI_MWA_NO_WINDOW_CHANGES\n\t\t\t| DXGI_MWA_NO_ALT_ENTER\n\t\t\t) );\n#endif // BX_PLATFORM_WINDOWS\n\n\t\tID3D11Resource* ptr;\n\t\tDX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&ptr) );\n\t\tDX_CHECK(device->CreateRenderTargetView(ptr, NULL, &m_rtv[0]) );\n\t\tDX_RELEASE(ptr, 0);\n\n\t\tDXGI_FORMAT fmtDsv = bimg::isDepth(bimg::TextureFormat::Enum(_depthFormat) )\n\t\t\t? s_textureFormat[_depthFormat].m_fmtDsv\n\t\t\t: DXGI_FORMAT_D24_UNORM_S8_UINT\n\t\t\t;\n\t\tD3D11_TEXTURE2D_DESC dsd;\n\t\tdsd.Width  = scd.width;\n\t\tdsd.Height = scd.height;\n\t\tdsd.MipLevels  = 1;\n\t\tdsd.ArraySize  = 1;\n\t\tdsd.Format     = fmtDsv;\n\t\tdsd.SampleDesc = scd.sampleDesc;\n\t\tdsd.Usage      = D3D11_USAGE_DEFAULT;\n\t\tdsd.BindFlags  = D3D11_BIND_DEPTH_STENCIL;\n\t\tdsd.CPUAccessFlags = 0;\n\t\tdsd.MiscFlags      = 0;\n\n\t\tID3D11Texture2D* depthStencil;\n\t\tDX_CHECK(device->CreateTexture2D(&dsd, NULL, &depthStencil) );\n\t\tDX_CHECK(device->CreateDepthStencilView(depthStencil, NULL, &m_dsv) );\n\t\tDX_RELEASE(depthStencil, 0);\n\n\t\tm_srv[0]   = NULL;\n\t\tm_nwh      = _nwh;\n\t\tm_denseIdx = _denseIdx;\n\t\tm_num      = 1;\n\t}\n\n\tuint16_t FrameBufferD3D11::destroy()\n\t{\n\t\tpreReset(true);\n\n\t\tDX_RELEASE(m_swapChain, 0);\n\n\t\tm_num   = 0;\n\t\tm_nwh   = NULL;\n\t\tm_numTh = 0;\n\t\tm_needPresent = false;\n\n\t\tuint16_t denseIdx = m_denseIdx;\n\t\tm_denseIdx = UINT16_MAX;\n\n\t\treturn denseIdx;\n\t}\n\n\tvoid FrameBufferD3D11::preReset(bool _force)\n\t{\n\t\tif (0 < m_numTh\n\t\t||  _force)\n\t\t{\n\t\t\tfor (uint32_t ii = 0, num = m_num; ii < num; ++ii)\n\t\t\t{\n\t\t\t\tDX_RELEASE(m_srv[ii], 0);\n\t\t\t\tDX_RELEASE(m_rtv[ii], 0);\n\t\t\t}\n\n\t\t\tDX_RELEASE(m_dsv, 0);\n\t\t}\n\t}\n\n\tvoid FrameBufferD3D11::postReset()\n\t{\n\t\tm_width  = 0;\n\t\tm_height = 0;\n\n\t\tif (0 < m_numTh)\n\t\t{\n\t\t\tm_num    = 0;\n\t\t\tm_numUav = 0;\n\n\t\t\tfor (uint32_t ii = 0; ii < m_numTh; ++ii)\n\t\t\t{\n\t\t\t\tconst Attachment& at = m_attachment[ii];\n\n\t\t\t\tif (isValid(at.handle) )\n\t\t\t\t{\n\t\t\t\t\tconst TextureD3D11& texture = s_renderD3D11->m_textures[at.handle.idx];\n\n\t\t\t\t\tif (0 == m_width)\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch (texture.m_type)\n\t\t\t\t\t\t{\n\t\t\t\t\t\tcase TextureD3D11::Texture2D:\n\t\t\t\t\t\tcase TextureD3D11::TextureCube:\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tD3D11_TEXTURE2D_DESC desc;\n\t\t\t\t\t\t\t\ttexture.m_texture2d->GetDesc(&desc);\n\t\t\t\t\t\t\t\tm_width  = desc.Width;\n\t\t\t\t\t\t\t\tm_height = desc.Height;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TextureD3D11::Texture3D:\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tD3D11_TEXTURE3D_DESC desc;\n\t\t\t\t\t\t\t\ttexture.m_texture3d->GetDesc(&desc);\n\t\t\t\t\t\t\t\tm_width  = desc.Width;\n\t\t\t\t\t\t\t\tm_height = desc.Height;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst uint32_t msaaQuality = bx::uint32_satsub( (texture.m_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT, 1);\n\t\t\t\t\tconst DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality];\n\n\t\t\t\t\tif (bimg::isDepth(bimg::TextureFormat::Enum(texture.m_textureFormat) ) )\n\t\t\t\t\t{\n\t\t\t\t\t\tBX_ASSERT(NULL == m_dsv, "Frame buffer already has depth-stencil attached.");\n\n\t\t\t\t\t\tD3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;\n\t\t\t\t\t\tdsvDesc.Format = s_textureFormat[texture.m_textureFormat].m_fmtDsv;\n\t\t\t\t\t\tdsvDesc.Flags = 0;\n\n\t\t\t\t\t\tswitch (texture.m_type)\n\t\t\t\t\t\t{\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\tcase TextureD3D11::Texture2D:\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (1 < msaa.Count)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (1 < texture.m_numLayers)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tdsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;\n\t\t\t\t\t\t\t\t\t\tdsvDesc.Texture2DMSArray.FirstArraySlice = at.layer;\n\t\t\t\t\t\t\t\t\t\tdsvDesc.Texture2DMSArray.ArraySize       = at.numLayers;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tdsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif (1 < texture.m_numLayers)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tdsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;\n\t\t\t\t\t\t\t\t\t\tdsvDesc.Texture2DArray.FirstArraySlice = at.layer;\n\t\t\t\t\t\t\t\t\t\tdsvDesc.Texture2DArray.ArraySize       = at.numLayers;\n\t\t\t\t\t\t\t\t\t\tdsvDesc.Texture2DArray.MipSlice        = at.mip;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tdsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;\n\t\t\t\t\t\t\t\t\t\tdsvDesc.Texture2D.MipSlice = at.mip;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tDX_CHECK(s_renderD3D11->m_device->CreateDepthStencilView(\n\t\t\t\t\t\t\t\t\t  NULL == texture.m_rt ? texture.m_ptr : texture.m_rt\n\t\t\t\t\t\t\t\t\t, &dsvDesc\n\t\t\t\t\t\t\t\t\t, &m_dsv\n\t\t\t\t\t\t\t\t\t) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TextureD3D11::TextureCube:\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (1 < msaa.Count)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;\n\t\t\t\t\t\t\t\t\tdsvDesc.Texture2DMSArray.FirstArraySlice = at.layer;\n\t\t\t\t\t\t\t\t\tdsvDesc.Texture2DMSArray.ArraySize       = at.numLayers;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;\n\t\t\t\t\t\t\t\t\tdsvDesc.Texture2DArray.FirstArraySlice = at.layer;\n\t\t\t\t\t\t\t\t\tdsvDesc.Texture2DArray.ArraySize       = at.numLayers;\n\t\t\t\t\t\t\t\t\tdsvDesc.Texture2DArray.MipSlice        = at.mip;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tDX_CHECK(s_renderD3D11->m_device->CreateDepthStencilView(texture.m_ptr, &dsvDesc, &m_dsv) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if (Access::Write == at.access)\n\t\t\t\t\t{\n\t\t\t\t\t\tD3D11_RENDER_TARGET_VIEW_DESC desc;\n\t\t\t\t\t\tdesc.Format = texture.getSrvFormat();\n\t\t\t\t\t\tswitch (texture.m_type)\n\t\t\t\t\t\t{\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\tcase TextureD3D11::Texture2D:\n\t\t\t\t\t\t\tif (1 < msaa.Count)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (1 < texture.m_numLayers)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;\n\t\t\t\t\t\t\t\t\tdesc.Texture2DMSArray.FirstArraySlice = at.layer;\n\t\t\t\t\t\t\t\t\tdesc.Texture2DMSArray.ArraySize       = at.numLayers;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (1 < texture.m_numLayers)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;\n\t\t\t\t\t\t\t\t\tdesc.Texture2DArray.FirstArraySlice = at.layer;\n\t\t\t\t\t\t\t\t\tdesc.Texture2DArray.ArraySize       = at.numLayers;\n\t\t\t\t\t\t\t\t\tdesc.Texture2DArray.MipSlice        = at.mip;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;\n\t\t\t\t\t\t\t\t\tdesc.Texture2D.MipSlice = at.mip;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tDX_CHECK(s_renderD3D11->m_device->CreateRenderTargetView(\n\t\t\t\t\t\t\t\t  NULL == texture.m_rt ? texture.m_ptr : texture.m_rt\n\t\t\t\t\t\t\t\t, &desc\n\t\t\t\t\t\t\t\t, &m_rtv[m_num]\n\t\t\t\t\t\t\t\t) );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TextureD3D11::TextureCube:\n\t\t\t\t\t\t\tif (1 < msaa.Count)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;\n\t\t\t\t\t\t\t\tdesc.Texture2DMSArray.FirstArraySlice = at.layer;\n\t\t\t\t\t\t\t\tdesc.Texture2DMSArray.ArraySize       = at.numLayers;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;\n\t\t\t\t\t\t\t\tdesc.Texture2DArray.FirstArraySlice = at.layer;\n\t\t\t\t\t\t\t\tdesc.Texture2DArray.ArraySize       = at.numLayers;\n\t\t\t\t\t\t\t\tdesc.Texture2DArray.MipSlice        = at.mip;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tDX_CHECK(s_renderD3D11->m_device->CreateRenderTargetView(texture.m_ptr, &desc, &m_rtv[m_num]) );\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\tcase TextureD3D11::Texture3D:\n\t\t\t\t\t\t\tdesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;\n\t\t\t\t\t\t\tdesc.Texture3D.MipSlice    = at.mip;\n\t\t\t\t\t\t\tdesc.Texture3D.FirstWSlice = at.layer;\n\t\t\t\t\t\t\tdesc.Texture3D.WSize       = at.numLayers;\n\n\t\t\t\t\t\t\tDX_CHECK(s_renderD3D11->m_device->CreateRenderTargetView(texture.m_ptr, &desc, &m_rtv[m_num]) );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc{};\n\t\t\t\t\t\ttexture.m_srv->GetDesc(&srvDesc);\n\t\t\t\t\t\tDX_CHECK(s_renderD3D11->m_device->CreateShaderResourceView(texture.m_ptr, &srvDesc, &m_srv[m_num]));\n\t\t\t\t\t\tm_num++;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tm_uav[m_numUav++] = texture.m_uav;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tvoid FrameBufferD3D11::resolve()\n\t{\n\t\tif (0 < m_numTh)\n\t\t{\n\t\t\tfor (uint32_t ii = 0; ii < m_numTh; ++ii)\n\t\t\t{\n\t\t\t\tconst Attachment& at = m_attachment[ii];\n\n\t\t\t\tif (isValid(at.handle) )\n\t\t\t\t{\n\t\t\t\t\tconst TextureD3D11& texture = s_renderD3D11->m_textures[at.handle.idx];\n\t\t\t\t\ttexture.resolve(at.resolve, at.layer, at.numLayers, at.mip);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tvoid FrameBufferD3D11::clear(const Clear& _clear, const float _palette[][4])\n\t{\n\t\tID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;\n\n\t\tif (BGFX_CLEAR_COLOR & _clear.m_flags)\n\t\t{\n\t\t\tif (BGFX_CLEAR_COLOR_USE_PALETTE & _clear.m_flags)\n\t\t\t{\n\t\t\t\tfor (uint32_t ii = 0, num = m_num; ii < num; ++ii)\n\t\t\t\t{\n\t\t\t\t\tuint8_t index = _clear.m_index[ii];\n\t\t\t\t\tif (NULL != m_rtv[ii]\n\t\t\t\t\t&&  UINT8_MAX != index)\n\t\t\t\t\t{\n\t\t\t\t\t\tdeviceCtx->ClearRenderTargetView(m_rtv[ii], _palette[index]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfloat frgba[4] =\n\t\t\t\t{\n\t\t\t\t\t_clear.m_index[0]*1.0f/255.0f,\n\t\t\t\t\t_clear.m_index[1]*1.0f/255.0f,\n\t\t\t\t\t_clear.m_index[2]*1.0f/255.0f,\n\t\t\t\t\t_clear.m_index[3]*1.0f/255.0f,\n\t\t\t\t};\n\t\t\t\tfor (uint32_t ii = 0, num = m_num; ii < num; ++ii)\n\t\t\t\t{\n\t\t\t\t\tif (NULL != m_rtv[ii])\n\t\t\t\t\t{\n\t\t\t\t\t\tdeviceCtx->ClearRenderTargetView(m_rtv[ii], frgba);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (NULL != m_dsv\n\t\t&& (BGFX_CLEAR_DEPTH|BGFX_CLEAR_STENCIL) & _clear.m_flags)\n\t\t{\n\t\t\tDWORD flags = 0;\n\t\t\tflags |= (_clear.m_flags & BGFX_CLEAR_DEPTH) ? D3D11_CLEAR_DEPTH : 0;\n\t\t\tflags |= (_clear.m_flags & BGFX_CLEAR_STENCIL) ? D3D11_CLEAR_STENCIL : 0;\n\t\t\tdeviceCtx->ClearDepthStencilView(m_dsv, flags, _clear.m_depth, _clear.m_stencil);\n\t\t}\n\t}\n\n\tvoid FrameBufferD3D11::set()\n\t{\n\t\ts_renderD3D11->m_deviceCtx->OMSetRenderTargets(m_num, m_rtv, m_dsv);\n\t\tm_needPresent = UINT16_MAX != m_denseIdx;\n\t\ts_renderD3D11->m_currentColor        = m_rtv[0];\n\t\ts_renderD3D11->m_currentDepthStencil = m_dsv;\n\t}\n\n\tHRESULT FrameBufferD3D11::present(uint32_t _syncInterval)\n\t{\n\t\tif (m_needPresent)\n\t\t{\n\t\t\tHRESULT hr = m_swapChain->Present(_syncInterval, 0);\n\t\t\thr = !isLost(hr) ? S_OK : hr;\n\t\t\tm_needPresent = false;\n\t\t\treturn hr;\n\t\t}\n\n\t\treturn S_OK;\n\t}\n\n\tvoid TimerQueryD3D11::postReset()\n\t{\n\t\tID3D11Device* device = s_renderD3D11->m_device;\n\n\t\tD3D11_QUERY_DESC qd;\n\t\tqd.MiscFlags = 0;\n\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(m_query); ++ii)\n\t\t{\n\t\t\tQuery& query = m_query[ii];\n\t\t\tquery.m_ready = false;\n\n\t\t\tqd.Query = D3D11_QUERY_TIMESTAMP_DISJOINT;\n\t\t\tDX_CHECK(device->CreateQuery(&qd, &query.m_disjoint) );\n\n\t\t\tqd.Query = D3D11_QUERY_TIMESTAMP;\n\t\t\tDX_CHECK(device->CreateQuery(&qd, &query.m_begin) );\n\t\t\tDX_CHECK(device->CreateQuery(&qd, &query.m_end) );\n\t\t}\n\n\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(m_result); ++ii)\n\t\t{\n\t\t\tResult& result = m_result[ii];\n\t\t\tresult.reset();\n\t\t}\n\n\t\tm_control.reset();\n\t}\n\n\tvoid TimerQueryD3D11::preReset()\n\t{\n\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(m_query); ++ii)\n\t\t{\n\t\t\tQuery& query = m_query[ii];\n\t\t\tDX_RELEASE(query.m_disjoint, 0);\n\t\t\tDX_RELEASE(query.m_begin, 0);\n\t\t\tDX_RELEASE(query.m_end, 0);\n\t\t}\n\t}\n\n\tuint32_t TimerQueryD3D11::begin(uint32_t _resultIdx, uint32_t _frameNum)\n\t{\n\t\tID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;\n\n\t\twhile (0 == m_control.reserve(1) )\n\t\t{\n\t\t\tupdate();\n\t\t}\n\n\t\tResult& result = m_result[_resultIdx];\n\t\t++result.m_pending;\n\n\t\tconst uint32_t idx = m_control.m_current;\n\t\tQuery& query = m_query[idx];\n\t\tquery.m_resultIdx = _resultIdx;\n\t\tquery.m_ready     = false;\n\t\tquery.m_frameNum  = _frameNum;\n\n\t\tdeviceCtx->Begin(query.m_disjoint);\n\t\tdeviceCtx->End(query.m_begin);\n\n\t\tm_control.commit(1);\n\n\t\treturn idx;\n\t}\n\n\tvoid TimerQueryD3D11::end(uint32_t _idx)\n\t{\n\t\tID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;\n\t\tQuery& query = m_query[_idx];\n\t\tquery.m_ready = true;\n\n\t\tdeviceCtx->End(query.m_end);\n\t\tdeviceCtx->End(query.m_disjoint);\n\n\t\twhile (update() )\n\t\t{\n\t\t}\n\t}\n\n\tbool TimerQueryD3D11::update()\n\t{\n\t\tif (0 != m_control.available() )\n\t\t{\n\t\t\tQuery& query = m_query[m_control.m_read];\n\n\t\t\tif (!query.m_ready)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tuint64_t timeEnd;\n\t\t\tID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;\n\t\t\tHRESULT hr = deviceCtx->GetData(query.m_end, &timeEnd, sizeof(timeEnd), D3D11_ASYNC_GETDATA_DONOTFLUSH);\n\t\t\tif (S_OK == hr\n\t\t\t||  isLost(hr) )\n\t\t\t{\n\t\t\t\tm_control.consume(1);\n\n\t\t\t\tstruct D3D11_QUERY_DATA_TIMESTAMP_DISJOINT\n\t\t\t\t{\n\t\t\t\t\tUINT64 Frequency;\n\t\t\t\t\tBOOL Disjoint;\n\t\t\t\t};\n\n\t\t\t\tD3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint;\n\t\t\t\tDX_CHECK(deviceCtx->GetData(query.m_disjoint, &disjoint, sizeof(disjoint), 0) );\n\n\t\t\t\tuint64_t timeBegin;\n\t\t\t\tDX_CHECK(deviceCtx->GetData(query.m_begin, &timeBegin, sizeof(timeBegin), 0) );\n\n\t\t\t\tResult& result = m_result[query.m_resultIdx];\n\t\t\t\t--result.m_pending;\n\t\t\t\tresult.m_frameNum = query.m_frameNum;\n\n\t\t\t\tresult.m_frequency = disjoint.Frequency;\n\t\t\t\tresult.m_begin     = timeBegin;\n\t\t\t\tresult.m_end       = timeEnd;\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\tvoid OcclusionQueryD3D11::postReset()\n\t{\n\t\tID3D11Device* device = s_renderD3D11->m_device;\n\n\t\tD3D11_QUERY_DESC desc;\n\t\tdesc.Query = D3D11_QUERY_OCCLUSION;\n\t\tdesc.MiscFlags = 0;\n\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(m_query); ++ii)\n\t\t{\n\t\t\tQuery& query = m_query[ii];\n\t\t\tDX_CHECK(device->CreateQuery(&desc, &query.m_ptr) );\n\t\t}\n\t}\n\n\tvoid OcclusionQueryD3D11::preReset()\n\t{\n\t\tfor (uint32_t ii = 0; ii < BX_COUNTOF(m_query); ++ii)\n\t\t{\n\t\t\tQuery& query = m_query[ii];\n\t\t\tDX_RELEASE(query.m_ptr, 0);\n\t\t}\n\t}\n\n\tvoid OcclusionQueryD3D11::begin(Frame* _render, OcclusionQueryHandle _handle)\n\t{\n\t\twhile (0 == m_control.reserve(1) )\n\t\t{\n\t\t\tresolve(_render, true);\n\t\t}\n\n\t\tID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;\n\t\tQuery& query = m_query[m_control.m_current];\n\t\tdeviceCtx->Begin(query.m_ptr);\n\t\tquery.m_handle = _handle;\n\t}\n\n\tvoid OcclusionQueryD3D11::end()\n\t{\n\t\tID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;\n\t\tQuery& query = m_query[m_control.m_current];\n\t\tdeviceCtx->End(query.m_ptr);\n\t\tm_control.commit(1);\n\t}\n\n\tvoid OcclusionQueryD3D11::resolve(Frame* _render, bool _wait)\n\t{\n\t\tID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;\n\n\t\twhile (0 != m_control.available() )\n\t\t{\n\t\t\tQuery& query = m_query[m_control.m_read];\n\n\t\t\tif (isValid(query.m_handle) )\n\t\t\t{\n\t\t\t\tuint64_t result = 0;\n\t\t\t\tHRESULT hr = deviceCtx->GetData(query.m_ptr, &result, sizeof(result), _wait ? 0 : D3D11_ASYNC_GETDATA_DONOTFLUSH);\n\t\t\t\tif (S_FALSE == hr)\n\t\t\t\t{\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t_render->m_occlusion[query.m_handle.idx] = int32_t(result);\n\t\t\t}\n\n\t\t\tm_control.consume(1);\n\t\t}\n\t}\n\n\tvoid OcclusionQueryD3D11::invalidate(OcclusionQueryHandle _handle)\n\t{\n\t\tconst uint32_t size = m_control.m_size;\n\n\t\tfor (uint32_t ii = 0, num = m_control.available(); ii < num; ++ii)\n\t\t{\n\t\t\tQuery& query = m_query[(m_control.m_read + ii) % size];\n\t\t\tif (query.m_handle.idx == _handle.idx)\n\t\t\t{\n\t\t\t\tquery.m_handle.idx = bgfx::kInvalidHandle;\n\t\t\t}\n\t\t}\n\t}\n\n\tvoid RendererContextD3D11::submitBlit(BlitState& _bs, uint16_t _view)\n\t{\n\t\tID3D11DeviceContext* deviceCtx = m_deviceCtx;\n\n\t\twhile (_bs.hasItem(_view) )\n\t\t{\n\t\t\tconst BlitItem& blit = _bs.advance();\n\n\t\t\tconst TextureD3D11& src = m_textures[blit.m_src.idx];\n\t\t\tconst TextureD3D11& dst = m_textures[blit.m_dst.idx];\n\n\t\t\tif (TextureD3D11::Texture3D == src.m_type)\n\t\t\t{\n\t\t\t\tD3D11_BOX box;\n\t\t\t\tbox.left   = blit.m_srcX;\n\t\t\t\tbox.top    = blit.m_srcY;\n\t\t\t\tbox.front  = blit.m_srcZ;\n\t\t\t\tbox.right  = blit.m_srcX + blit.m_width;\n\t\t\t\tbox.bottom = blit.m_srcY + blit.m_height;\n\t\t\t\tbox.back   = blit.m_srcZ + bx::uint32_imax(1, blit.m_depth);\n\n\t\t\t\tdeviceCtx->CopySubresourceRegion(dst.m_ptr\n\t\t\t\t\t, blit.m_dstMip\n\t\t\t\t\t, blit.m_dstX\n\t\t\t\t\t, blit.m_dstY\n\t\t\t\t\t, blit.m_dstZ\n\t\t\t\t\t, src.m_ptr\n\t\t\t\t\t, blit.m_srcMip\n\t\t\t\t\t, &box\n\t\t\t\t\t);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbool depthStencil = bimg::isDepth(bimg::TextureFormat::Enum(src.m_textureFormat) );\n\t\t\t\tBX_ASSERT(!depthStencil\n\t\t\t\t\t||  (blit.m_width == bx::uint32_max(1, src.m_width >> blit.m_srcMip) && blit.m_height == bx::uint32_max(1, src.m_height >> blit.m_srcMip))\n\t\t\t\t\t, "When blitting depthstencil surface, source resolution must match destination."\n\t\t\t\t\t);\n\n\t\t\t\tD3D11_BOX box;\n\t\t\t\tbox.left   = blit.m_srcX;\n\t\t\t\tbox.top    = blit.m_srcY;\n\t\t\t\tbox.front  = 0;\n\t\t\t\tbox.right  = blit.m_srcX + blit.m_width;\n\t\t\t\tbox.bottom = blit.m_srcY + blit.m_height;\n\t\t\t\tbox.back   = 1;\n\n\t\t\t\tconst uint32_t srcZ = blit.m_srcZ;\n\t\t\t\tconst uint32_t dstZ = blit.m_dstZ;\n\n\t\t\t\tdeviceCtx->CopySubresourceRegion(dst.m_ptr\n\t\t\t\t\t, dstZ*dst.m_numMips+blit.m_dstMip\n\t\t\t\t\t, blit.m_dstX\n\t\t\t\t\t, blit.m_dstY\n\t\t\t\t\t, 0\n\t\t\t\t\t, src.m_ptr\n\t\t\t\t\t, srcZ*src.m_numMips+blit.m_srcMip\n\t\t\t\t\t, depthStencil ? NULL : &box\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tvoid RendererContextD3D11::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter)\n\t{\n\t\tif (m_lost)\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\tupdateNativeWindow();\n\t\tif (updateResolution(_render->m_resolution) )\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\tif (_render->m_capture)\n\t\t{\n\t\t\trenderDocTriggerCapture();\n\t\t}\n\n\t\tBGFX_D3D11_PROFILER_BEGIN_LITERAL("rendererSubmit", kColorView);\n\n\t\tID3D11DeviceContext* deviceCtx = m_deviceCtx;\n\n\t\tint64_t timeBegin = bx::getHPCounter();\n\t\tint64_t captureElapsed = 0;\n\n\t\tuint32_t frameQueryIdx = UINT32_MAX;\n\n\t\tif (m_timerQuerySupport)\n\t\t{\n\t\t\tframeQueryIdx = m_gpuTimer.begin(BGFX_CONFIG_MAX_VIEWS, _render->m_frameNum);\n\t\t}\n\n\t\tif (0 < _render->m_iboffset)\n\t\t{\n\t\t\tBGFX_PROFILER_SCOPE("bgfx/Update transient index buffer", kColorResource);\n\t\t\tTransientIndexBuffer* ib = _render->m_transientIb;\n\t\t\tm_indexBuffers[ib->handle.idx].update(0, _render->m_iboffset, ib->data, true);\n\t\t}\n\n\t\tif (0 < _render->m_vboffset)\n\t\t{\n\t\t\tBGFX_PROFILER_SCOPE("bgfx/Update transient vertex buffer", kColorResource);\n\t\t\tTransientVertexBuffer* vb = _render->m_transientVb;\n\t\t\tm_vertexBuffers[vb->handle.idx].update(0, _render->m_vboffset, vb->data, true);\n\t\t}\n\n\t\t_render->sort();\n\n\t\tRenderDraw currentState;\n\t\tcurrentState.clear();\n\t\tcurrentState.m_stateFlags = BGFX_STATE_NONE;\n\t\tcurrentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE);\n\n\t\tuint32_t currentNumVertices = 0;\n\n\t\tRenderBind currentBind;\n\t\tcurrentBind.clear();\n\n\t\tstatic ViewState viewState;\n\t\tviewState.reset(_render);\n\n\t\tbool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME);\n\t\tbool scissorEnabled = false;\n\t\tsetDebugWireframe(wireframe);\n\n\t\tProgramHandle currentProgram = BGFX_INVALID_HANDLE;\n\t\tSortKey key;\n\t\tuint16_t view = UINT16_MAX;\n\t\tFrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS };\n\n\t\tBlitState bs(_render);\n\n\t\tconst uint64_t primType = _render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0;\n\t\tuint8_t primIndex = uint8_t(primType >> BGFX_STATE_PT_SHIFT);\n\t\tPrimInfo prim = s_primInfo[primIndex];\n\t\tdeviceCtx->IASetPrimitiveTopology(prim.m_type);\n\n\t\tbool wasCompute = false;\n\t\tbool viewHasScissor = false;\n\t\tRect viewScissorRect;\n\t\tviewScissorRect.clear();\n\n\t\tconst uint32_t maxComputeBindings = g_caps.limits.maxComputeBindings;\n\t\tconst uint32_t maxTextureSamplers = g_caps.limits.maxTextureSamplers;\n\n\t\tuint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {};\n\t\tuint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {};\n\t\tuint32_t statsNumInstances[BX_COUNTOF(s_primInfo)] = {};\n\t\tuint32_t statsNumDrawIndirect[BX_COUNTOF(s_primInfo)] = {};\n\t\tuint32_t statsNumIndices = 0;\n\t\tuint32_t statsKeyType[2] = {};\n\n\t\tProfiler<TimerQueryD3D11> profiler(\n\t\t\t  _render\n\t\t\t, m_gpuTimer\n\t\t\t, s_viewName\n\t\t\t, m_timerQuerySupport\n\t\t\t);\n\n\t\tm_occlusionQuery.resolve(_render);\n\n\t\tif (0 == (_render->m_debug&BGFX_DEBUG_IFH) )\n\t\t{\n\t\t\t// reset the framebuffer to be the backbuffer; depending on the swap effect,\n\t\t\t// if we don\'t do this we\'ll only see one frame of output and then nothing\n\t\t\tsetFrameBuffer(BGFX_INVALID_HANDLE, true, false);\n\n\t\t\tviewState.m_rect = _render->m_view[0].m_rect;\n\t\t\tint32_t numItems = _render->m_numRenderItems;\n\n\t\t\tfor (int32_t item = 0; item < numItems;)\n\t\t\t{\n\t\t\t\tconst uint64_t encodedKey = _render->m_sortKeys[item];\n\t\t\t\tconst bool isCompute = key.decode(encodedKey, _render->m_viewRemap);\n\t\t\t\tstatsKeyType[isCompute]++;\n\n\t\t\t\tconst bool viewChanged = 0\n\t\t\t\t\t|| key.m_view != view\n\t\t\t\t\t|| item == numItems\n\t\t\t\t\t;\n\n\t\t\t\tconst uint32_t itemIdx       = _render->m_sortValues[item];\n\t\t\t\tconst RenderItem& renderItem = _render->m_renderItem[itemIdx];\n\t\t\t\tconst RenderBind& renderBind = _render->m_renderItemBind[itemIdx];\n\t\t\t\t++item;\n\n\t\t\t\tif (viewChanged)\n\t\t\t\t{\n\t\t\t\t\tview = key.m_view;\n\t\t\t\t\tcurrentProgram = BGFX_INVALID_HANDLE;\n\n\t\t\t\t\tif (item > 1)\n\t\t\t\t\t{\n\t\t\t\t\t\tprofiler.end();\n\t\t\t\t\t}\n\n\t\t\t\t\tBGFX_D3D11_PROFILER_END();\n\t\t\t\t\tsetViewType(view, "  ");\n\t\t\t\t\tBGFX_D3D11_PROFILER_BEGIN(view, kColorView);\n\n\t\t\t\t\tprofiler.begin(view);\n\n\t\t\t\t\tif (_render->m_view[view].m_fbh.idx != fbh.idx)\n\t\t\t\t\t{\n\t\t\t\t\t\tfbh = _render->m_view[view].m_fbh;\n\t\t\t\t\t\tsetFrameBuffer(fbh);\n\t\t\t\t\t}\n\n\t\t\t\t\tviewState.m_rect = _render->m_view[view].m_rect;\n\n\t\t\t\t\tconst Rect& scissorRect = _render->m_view[view].m_scissor;\n\t\t\t\t\tviewHasScissor = !scissorRect.isZero();\n\t\t\t\t\tviewScissorRect = viewHasScissor ? scissorRect : viewState.m_rect;\n\n\t\t\t\t\tD3D11_VIEWPORT vp;\n\t\t\t\t\tvp.TopLeftX = viewState.m_rect.m_x;\n\t\t\t\t\tvp.TopLeftY = viewState.m_rect.m_y;\n\t\t\t\t\tvp.Width    = viewState.m_rect.m_width;\n\t\t\t\t\tvp.Height   = viewState.m_rect.m_height;\n\t\t\t\t\tvp.MinDepth = 0.0f;\n\t\t\t\t\tvp.MaxDepth = 1.0f;\n\t\t\t\t\tdeviceCtx->RSSetViewports(1, &vp);\n\t\t\t\t\tClear& clr = _render->m_view[view].m_clear;\n\n\t\t\t\t\tif (BGFX_CLEAR_NONE != (clr.m_flags & BGFX_CLEAR_MASK) )\n\t\t\t\t\t{\n\t\t\t\t\t\tclearQuad(_clearQuad, viewState.m_rect, clr, _render->m_colorPalette);\n\t\t\t\t\t\tprim = s_primInfo[Topology::Count]; // Force primitive type update after clear quad.\n\t\t\t\t\t}\n\n\t\t\t\t\tsubmitBlit(bs, view);\n\t\t\t\t}\n\n\t\t\t\tif (isCompute)\n\t\t\t\t{\n\t\t\t\t\tif (!wasCompute)\n\t\t\t\t\t{\n\t\t\t\t\t\twasCompute = true;\n\n\t\t\t\t\t\tsetViewType(view, "C");\n\t\t\t\t\t\tBGFX_D3D11_PROFILER_END();\n\t\t\t\t\t\tBGFX_D3D11_PROFILER_BEGIN(view, kColorCompute);\n\n\t\t\t\t\t\tdeviceCtx->IASetVertexBuffers(0, 2, s_zero.m_buffer, s_zero.m_zero, s_zero.m_zero);\n\t\t\t\t\t\tdeviceCtx->IASetIndexBuffer(NULL, DXGI_FORMAT_R16_UINT, 0);\n\n\t\t\t\t\t\tdeviceCtx->VSSetShaderResources(0, maxTextureSamplers, s_zero.m_srv);\n\t\t\t\t\t\tdeviceCtx->PSSetShaderResources(0, maxTextureSamplers, s_zero.m_srv);\n\n\t\t\t\t\t\tdeviceCtx->VSSetSamplers(0, maxTextureSamplers, s_zero.m_sampler);\n\t\t\t\t\t\tdeviceCtx->PSSetSamplers(0, maxTextureSamplers, s_zero.m_sampler);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst RenderCompute& compute = renderItem.compute;\n\n\t\t\t\t\tbool programChanged = false;\n\t\t\t\t\tbool constantsChanged = compute.m_uniformBegin < compute.m_uniformEnd;\n\t\t\t\t\trendererUpdateUniforms(this, _render->m_uniformBuffer[compute.m_uniformIdx], compute.m_uniformBegin, compute.m_uniformEnd);\n\n\t\t\t\t\tif (key.m_program.idx != currentProgram.idx)\n\t\t\t\t\t{\n\t\t\t\t\t\tcurrentProgram = key.m_program;\n\n\t\t\t\t\t\tProgramD3D11& program = m_program[currentProgram.idx];\n\t\t\t\t\t\tm_currentProgram = &program;\n\n\t\t\t\t\t\tdeviceCtx->CSSetShader(program.m_vsh->m_computeShader, NULL, 0);\n\t\t\t\t\t\tdeviceCtx->CSSetConstantBuffers(0, 1, &program.m_vsh->m_buffer);\n\n\t\t\t\t\t\tprogramChanged =\n\t\t\t\t\t\t\tconstantsChanged = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isValid(currentProgram) )\n\t\t\t\t\t{\n\t\t\t\t\t\tProgramD3D11& program = m_program[currentProgram.idx];\n\n\t\t\t\t\t\tif (constantsChanged)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tUniformBuffer* vcb = program.m_vsh->m_constantBuffer;\n\t\t\t\t\t\t\tif (NULL != vcb)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcommit(*vcb);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tviewState.setPredefined<4>(this, view, program, _render, compute);\n\n\t\t\t\t\t\tif (constantsChanged\n\t\t\t\t\t\t||  program.m_numPredefined > 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommitShaderConstants();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tBX_UNUSED(programChanged);\n\t\t\t\t\tID3D11UnorderedAccessView* uav[BGFX_MAX_COMPUTE_BINDINGS] = {};\n\n\t\t\t\t\tfor (uint8_t stage = 0; stage < maxComputeBindings; ++stage)\n\t\t\t\t\t{\n\t\t\t\t\t\tconst Binding& bind = renderBind.m_bind[stage];\n\t\t\t\t\t\tif (kInvalidHandle != bind.m_idx)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tswitch (bind.m_type)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcase Binding::Image:\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tTextureD3D11& texture = m_textures[bind.m_idx];\n\t\t\t\t\t\t\t\t\tif (Access::Read != bind.m_access)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tuav[stage] = 0 == bind.m_mip\n\t\t\t\t\t\t\t\t\t\t\t? texture.m_uav\n\t\t\t\t\t\t\t\t\t\t\t: s_renderD3D11->getCachedUav(texture.getHandle(), bind.m_mip)\n\t\t\t\t\t\t\t\t\t\t\t;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tm_textureStage.m_srv[stage]     = s_renderD3D11->getCachedSrv(texture.getHandle(), bind.m_mip, true);\n\t\t\t\t\t\t\t\t\t\tm_textureStage.m_sampler[stage] = s_renderD3D11->getSamplerState(uint32_t(texture.m_flags), NULL);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase Binding::Texture:\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tTextureD3D11& texture = m_textures[bind.m_idx];\n\t\t\t\t\t\t\t\t\ttexture.commit(stage, bind.m_samplerFlags, _render->m_colorPalette);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase Binding::IndexBuffer:\n\t\t\t\t\t\t\tcase Binding::VertexBuffer:\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tconst BufferD3D11& buffer = Binding::IndexBuffer == bind.m_type\n\t\t\t\t\t\t\t\t\t\t? m_indexBuffers[bind.m_idx]\n\t\t\t\t\t\t\t\t\t\t: m_vertexBuffers[bind.m_idx]\n\t\t\t\t\t\t\t\t\t\t;\n\t\t\t\t\t\t\t\t\tif (Access::Read != bind.m_access)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tuav[stage] = buffer.m_uav;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tm_textureStage.m_srv[stage] = buffer.m_srv;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tm_textureStage.m_srv[stage]     = NULL;\n\t\t\t\t\t\t\tm_textureStage.m_sampler[stage] = NULL;\n\t\t\t\t\t\t\tm_textureStage.m_uav[stage]     = NULL;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (BX_ENABLED(BGFX_CONFIG_DEBUG) )\n\t\t\t\t\t{\n\t\t\t\t\t\t// Quiet validation: Resource being set to CS UnorderedAccessView slot 0 is still bound on input!\n\t\t\t\t\t\tdeviceCtx->CSSetShaderResources(0, maxComputeBindings, s_zero.m_srv);\n\t\t\t\t\t}\n\n\t\t\t\t\tdeviceCtx->CSSetUnorderedAccessViews(0, maxComputeBindings, uav, NULL);\n\t\t\t\t\tdeviceCtx->CSSetShaderResources(0, maxTextureSamplers, m_textureStage.m_srv);\n\t\t\t\t\tdeviceCtx->CSSetSamplers(0, maxTextureSamplers, m_textureStage.m_sampler);\n\n\t\t\t\t\tif (isValid(compute.m_indirectBuffer) )\n\t\t\t\t\t{\n\t\t\t\t\t\tconst VertexBufferD3D11& vb = m_vertexBuffers[compute.m_indirectBuffer.idx];\n\t\t\t\t\t\tID3D11Buffer* ptr = vb.m_ptr;\n\n\t\t\t\t\t\tuint32_t numDrawIndirect = UINT16_MAX == compute.m_numIndirect\n\t\t\t\t\t\t\t? vb.m_size/BGFX_CONFIG_DRAW_INDIRECT_STRIDE\n\t\t\t\t\t\t\t: compute.m_numIndirect\n\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\tuint32_t args = compute.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE;\n\t\t\t\t\t\tfor (uint32_t ii = 0; ii < numDrawIndirect; ++ii)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdeviceCtx->DispatchIndirect(ptr, args);\n\t\t\t\t\t\t\targs += BGFX_CONFIG_DRAW_INDIRECT_STRIDE;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tdeviceCtx->Dispatch(compute.m_numX, compute.m_numY, compute.m_numZ);\n\t\t\t\t\t}\n\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tbool resetState = viewChanged || wasCompute;\n\n\t\t\t\tif (wasCompute)\n\t\t\t\t{\n\t\t\t\t\tsetViewType(view, " ");\n\t\t\t\t\tBGFX_D3D11_PROFILER_END();\n\t\t\t\t\tBGFX_D3D11_PROFILER_BEGIN(view, kColorDraw);\n\n\t\t\t\t\tcurrentProgram   = BGFX_INVALID_HANDLE;\n\t\t\t\t\tm_currentProgram = NULL;\n\n\t\t\t\t\tinvalidateCompute();\n\t\t\t\t}\n\n\t\t\t\tconst RenderDraw& draw = renderItem.draw;\n\n\t\t\t\tconst bool hasOcclusionQuery = 0 != (draw.m_stateFlags & BGFX_STATE_INTERNAL_OCCLUSION_QUERY);\n\t\t\t\t{\n\t\t\t\t\tconst bool occluded = true\n\t\t\t\t\t\t&& isValid(draw.m_occlusionQuery)\n\t\t\t\t\t\t&& !hasOcclusionQuery\n\t\t\t\t\t\t&& !isVisible(_render, draw.m_occlusionQuery, 0 != (draw.m_submitFlags&BGFX_SUBMIT_INTERNAL_OCCLUSION_VISIBLE) )\n\t\t\t\t\t\t;\n\n\t\t\t\t\tif (occluded\n\t\t\t\t\t||  _render->m_frameCache.isZeroArea(viewScissorRect, draw.m_scissor) )\n\t\t\t\t\t{\n\t\t\t\t\t\tif (resetState)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcurrentState.clear();\n\t\t\t\t\t\t\tcurrentState.m_scissor = !draw.m_scissor;\n\t\t\t\t\t\t\tcurrentBind.clear();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst uint64_t newFlags = draw.m_stateFlags;\n\t\t\t\tuint64_t changedFlags = currentState.m_stateFlags ^ draw.m_stateFlags;\n\t\t\t\tchangedFlags |= currentState.m_rgba != draw.m_rgba ? BGFX_D3D11_BLEND_STATE_MASK : 0;\n\t\t\t\tcurrentState.m_stateFlags = newFlags;\n\n\t\t\t\tconst uint64_t newStencil = draw.m_stencil;\n\t\t\t\tuint64_t changedStencil = currentState.m_stencil ^ draw.m_stencil;\n\t\t\t\tchangedFlags |= 0 != changedStencil ? BGFX_D3D11_DEPTH_STENCIL_MASK : 0;\n\t\t\t\tcurrentState.m_stencil = newStencil;\n\n\t\t\t\tif (resetState)\n\t\t\t\t{\n\t\t\t\t\twasCompute = false;\n\n\t\t\t\t\tcurrentState.clear();\n\t\t\t\t\tcurrentState.m_scissor = !draw.m_scissor;\n\t\t\t\t\tchangedFlags = BGFX_STATE_MASK;\n\t\t\t\t\tchangedStencil = packStencil(BGFX_STENCIL_MASK, BGFX_STENCIL_MASK);\n\t\t\t\t\tcurrentState.m_stateFlags = newFlags;\n\t\t\t\t\tcurrentState.m_stencil    = newStencil;\n\n\t\t\t\t\tcurrentBind.clear();\n\n\t\t\t\t\tsetBlendState(newFlags);\n\t\t\t\t\tsetDepthStencilState(newFlags, packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT) );\n\n\t\t\t\t\tconst uint64_t pt = newFlags&BGFX_STATE_PT_MASK;\n\t\t\t\t\tprimIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT);\n\t\t\t\t}\n\n\t\t\t\tif (prim.m_type != s_primInfo[primIndex].m_type)\n\t\t\t\t{\n\t\t\t\t\tprim = s_primInfo[primIndex];\n\t\t\t\t\tdeviceCtx->IASetPrimitiveTopology(prim.m_type);\n\t\t\t\t}\n\n\t\t\t\tuint16_t scissor = draw.m_scissor;\n\t\t\t\tif (currentState.m_scissor != scissor)\n\t\t\t\t{\n\t\t\t\t\tcurrentState.m_scissor = scissor;\n\n\t\t\t\t\tif (UINT16_MAX == scissor)\n\t\t\t\t\t{\n\t\t\t\t\t\tscissorEnabled = viewHasScissor;\n\t\t\t\t\t\tif (viewHasScissor)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tD3D11_RECT rc;\n\t\t\t\t\t\t\trc.left   = viewScissorRect.m_x;\n\t\t\t\t\t\t\trc.top    = viewScissorRect.m_y;\n\t\t\t\t\t\t\trc.right  = viewScissorRect.m_x + viewScissorRect.m_width;\n\t\t\t\t\t\t\trc.bottom = viewScissorRect.m_y + viewScissorRect.m_height;\n\t\t\t\t\t\t\tdeviceCtx->RSSetScissorRects(1, &rc);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tRect scissorRect;\n\t\t\t\t\t\tscissorRect.setIntersect(viewScissorRect, _render->m_frameCache.m_rectCache.m_cache[scissor]);\n\n\t\t\t\t\t\tscissorEnabled = true;\n\t\t\t\t\t\tD3D11_RECT rc;\n\t\t\t\t\t\trc.left   = scissorRect.m_x;\n\t\t\t\t\t\trc.top    = scissorRect.m_y;\n\t\t\t\t\t\trc.right  = scissorRect.m_x + scissorRect.m_width;\n\t\t\t\t\t\trc.bottom = scissorRect.m_y + scissorRect.m_height;\n\t\t\t\t\t\tdeviceCtx->RSSetScissorRects(1, &rc);\n\t\t\t\t\t}\n\n\t\t\t\t\tsetRasterizerState(newFlags, wireframe, scissorEnabled);\n\t\t\t\t}\n\n\t\t\t\tif (BGFX_D3D11_DEPTH_STENCIL_MASK & changedFlags)\n\t\t\t\t{\n\t\t\t\t\tsetDepthStencilState(newFlags, newStencil);\n\t\t\t\t}\n\n\t\t\t\tif (BGFX_D3D11_BLEND_STATE_MASK & changedFlags)\n\t\t\t\t{\n\t\t\t\t\tsetBlendState(newFlags, draw.m_rgba);\n\t\t\t\t\tcurrentState.m_rgba = draw.m_rgba;\n\t\t\t\t}\n\n\t\t\t\tif ( (0\n\t\t\t\t\t | BGFX_STATE_CULL_MASK\n\t\t\t\t\t | BGFX_STATE_FRONT_CCW\n\t\t\t\t\t | BGFX_STATE_ALPHA_REF_MASK\n\t\t\t\t\t | BGFX_STATE_PT_MASK\n\t\t\t\t\t | BGFX_STATE_POINT_SIZE_MASK\n\t\t\t\t\t | BGFX_STATE_MSAA\n\t\t\t\t\t | BGFX_STATE_LINEAA\n\t\t\t\t\t | BGFX_STATE_CONSERVATIVE_RASTER\n\t\t\t\t\t ) & changedFlags)\n\t\t\t\t{\n\t\t\t\t\tif ( (0\n\t\t\t\t\t\t | BGFX_STATE_CULL_MASK\n\t\t\t\t\t\t | BGFX_STATE_FRONT_CCW\n\t\t\t\t\t\t | BGFX_STATE_MSAA\n\t\t\t\t\t\t | BGFX_STATE_LINEAA\n\t\t\t\t\t\t | BGFX_STATE_CONSERVATIVE_RASTER\n\t\t\t\t\t\t ) & changedFlags)\n\t\t\t\t\t{\n\t\t\t\t\t\tsetRasterizerState(newFlags, wireframe, scissorEnabled);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (BGFX_STATE_ALPHA_REF_MASK & changedFlags)\n\t\t\t\t\t{\n\t\t\t\t\t\tuint32_t ref = (newFlags&BGFX_STATE_ALPHA_REF_MASK)>>BGFX_STATE_ALPHA_REF_SHIFT;\n\t\t\t\t\t\tviewState.m_alphaRef = ref/255.0f;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst uint64_t pt = newFlags&BGFX_STATE_PT_MASK;\n\t\t\t\t\tprimIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT);\n\t\t\t\t\tif (prim.m_type != s_primInfo[primIndex].m_type)\n\t\t\t\t\t{\n\t\t\t\t\t\tprim = s_primInfo[primIndex];\n\t\t\t\t\t\tdeviceCtx->IASetPrimitiveTopology(prim.m_type);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbool programChanged = false;\n\t\t\t\tbool constantsChanged = draw.m_uniformBegin < draw.m_uniformEnd;\n\t\t\t\trendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd);\n\n\t\t\t\tif (key.m_program.idx != currentProgram.idx)\n\t\t\t\t{\n\t\t\t\t\tcurrentProgram = key.m_program;\n\n\t\t\t\t\tif (!isValid(currentProgram) )\n\t\t\t\t\t{\n\t\t\t\t\t\tm_currentProgram = NULL;\n\n\t\t\t\t\t\tdeviceCtx->VSSetShader(NULL, NULL, 0);\n\t\t\t\t\t\tdeviceCtx->PSSetShader(NULL, NULL, 0);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tProgramD3D11& program = m_program[currentProgram.idx];\n\t\t\t\t\t\tm_currentProgram = &program;\n\n\t\t\t\t\t\tconst ShaderD3D11* vsh = program.m_vsh;\n\t\t\t\t\t\tdeviceCtx->VSSetShader(vsh->m_vertexShader, NULL, 0);\n\t\t\t\t\t\tdeviceCtx->VSSetConstantBuffers(0, 1, &vsh->m_buffer);\n\n\t\t\t\t\t\tconst ShaderD3D11* fsh = program.m_fsh;\n\t\t\t\t\t\tif (NULL != fsh\n\t\t\t\t\t\t&& (NULL != m_currentColor || fsh->m_hasDepthOp) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdeviceCtx->PSSetShader(fsh->m_pixelShader, NULL, 0);\n\t\t\t\t\t\t\tdeviceCtx->PSSetConstantBuffers(0, 1, &fsh->m_buffer);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdeviceCtx->PSSetShader(NULL, NULL, 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tprogramChanged =\n\t\t\t\t\t\tconstantsChanged = true;\n\t\t\t\t}\n\n\t\t\t\tif (isValid(currentProgram) )\n\t\t\t\t{\n\t\t\t\t\tProgramD3D11& program = m_program[currentProgram.idx];\n\n\t\t\t\t\tif (constantsChanged)\n\t\t\t\t\t{\n\t\t\t\t\t\tUniformBuffer* vcb = program.m_vsh->m_constantBuffer;\n\t\t\t\t\t\tif (NULL != vcb)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcommit(*vcb);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (NULL != program.m_fsh)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tUniformBuffer* fcb = program.m_fsh->m_constantBuffer;\n\t\t\t\t\t\t\tif (NULL != fcb)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcommit(*fcb);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tviewState.setPredefined<4>(this, view, program, _render, draw);\n\n\t\t\t\t\tif (constantsChanged\n\t\t\t\t\t||  program.m_numPredefined > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tcommitShaderConstants();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t{\n\t\t\t\t\tuint32_t changes = 0;\n\t\t\t\t\tfor (uint8_t stage = 0; stage < maxTextureSamplers; ++stage)\n\t\t\t\t\t{\n\t\t\t\t\t\tconst Binding& bind = renderBind.m_bind[stage];\n\t\t\t\t\t\tBinding& current = currentBind.m_bind[stage];\n\t\t\t\t\t\tif (current.m_idx          != bind.m_idx\n\t\t\t\t\t\t||  current.m_type         != bind.m_type\n\t\t\t\t\t\t||  current.m_samplerFlags != bind.m_samplerFlags\n\t\t\t\t\t\t||  programChanged)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (kInvalidHandle != bind.m_idx)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tswitch (bind.m_type)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcase Binding::Image:\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tTextureD3D11& texture = m_textures[bind.m_idx];\n\t\t\t\t\t\t\t\t\t\tif (Access::Read != bind.m_access)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tm_textureStage.m_uav[stage] = 0 == bind.m_mip\n\t\t\t\t\t\t\t\t\t\t\t\t? texture.m_uav\n\t\t\t\t\t\t\t\t\t\t\t\t: s_renderD3D11->getCachedUav(texture.getHandle(), bind.m_mip)\n\t\t\t\t\t\t\t\t\t\t\t\t;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tm_textureStage.m_srv[stage]     = s_renderD3D11->getCachedSrv(texture.getHandle(), bind.m_mip, true);\n\t\t\t\t\t\t\t\t\t\t\tm_textureStage.m_sampler[stage] = s_renderD3D11->getSamplerState(uint32_t(texture.m_flags), NULL);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase Binding::Texture:\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tTextureD3D11& texture = m_textures[bind.m_idx];\n\t\t\t\t\t\t\t\t\t\ttexture.commit(stage, bind.m_samplerFlags, _render->m_colorPalette);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\tcase Binding::IndexBuffer:\n\t\t\t\t\t\t\t\tcase Binding::VertexBuffer:\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tconst BufferD3D11& buffer = Binding::IndexBuffer == bind.m_type\n\t\t\t\t\t\t\t\t\t\t\t? m_indexBuffers[bind.m_idx]\n\t\t\t\t\t\t\t\t\t\t\t: m_vertexBuffers[bind.m_idx]\n\t\t\t\t\t\t\t\t\t\t\t;\n\t\t\t\t\t\t\t\t\t\tm_textureStage.m_srv[stage] = buffer.m_srv;\n\t\t\t\t\t\t\t\t\t\tm_textureStage.m_sampler[stage] = NULL;\n\t\t\t\t\t\t\t\t\t\tm_textureStage.m_uav[stage]     = NULL;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tm_textureStage.m_srv[stage]     = NULL;\n\t\t\t\t\t\t\t\tm_textureStage.m_sampler[stage] = NULL;\n\t\t\t\t\t\t\t\tm_textureStage.m_uav[stage]     = NULL;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t++changes;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcurrent = bind;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (0 < changes)\n\t\t\t\t\t{\n\t\t\t\t\t\tcommitTextureStage();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbool vertexStreamChanged = hasVertexStreamChanged(currentState, draw);\n\n\t\t\t\tif (programChanged\n\t\t\t\t||  vertexStreamChanged)\n\t\t\t\t{\n\t\t\t\t\tcurrentState.m_streamMask             = draw.m_streamMask;\n\t\t\t\t\tcurrentState.m_instanceDataBuffer.idx = draw.m_instanceDataBuffer.idx;\n\t\t\t\t\tcurrentState.m_instanceDataOffset     = draw.m_instanceDataOffset;\n\t\t\t\t\tcurrentState.m_instanceDataStride     = draw.m_instanceDataStride;\n\n\t\t\t\t\tID3D11Buffer* buffers[BGFX_CONFIG_MAX_VERTEX_STREAMS];\n\t\t\t\t\tuint32_t strides[BGFX_CONFIG_MAX_VERTEX_STREAMS];\n\t\t\t\t\tuint32_t offsets[BGFX_CONFIG_MAX_VERTEX_STREAMS];\n\t\t\t\t\tconst VertexLayout* layouts[BGFX_CONFIG_MAX_VERTEX_STREAMS];\n\n\t\t\t\t\tuint32_t numVertices = draw.m_numVertices;\n\t\t\t\t\tuint8_t  numStreams  = 0;\n\n\t\t\t\t\tif (UINT8_MAX != draw.m_streamMask)\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (uint32_t idx = 0, streamMask = draw.m_streamMask\n\t\t\t\t\t\t\t; 0 != streamMask\n\t\t\t\t\t\t\t; streamMask >>= 1, idx += 1, ++numStreams\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconst uint32_t ntz = bx::uint32_cnttz(streamMask);\n\t\t\t\t\t\t\tstreamMask >>= ntz;\n\t\t\t\t\t\t\tidx         += ntz;\n\n\t\t\t\t\t\t\tcurrentState.m_stream[idx].m_layoutHandle = draw.m_stream[idx].m_layoutHandle;\n\t\t\t\t\t\t\tcurrentState.m_stream[idx].m_handle       = draw.m_stream[idx].m_handle;\n\t\t\t\t\t\t\tcurrentState.m_stream[idx].m_startVertex  = draw.m_stream[idx].m_startVertex;\n\n\t\t\t\t\t\t\tconst uint16_t handle = draw.m_stream[idx].m_handle.idx;\n\t\t\t\t\t\t\tconst VertexBufferD3D11& vb = m_vertexBuffers[handle];\n\t\t\t\t\t\t\tconst uint16_t layoutIdx = isValid(draw.m_stream[idx].m_layoutHandle)\n\t\t\t\t\t\t\t\t? draw.m_stream[idx].m_layoutHandle.idx\n\t\t\t\t\t\t\t\t: vb.m_layoutHandle.idx;\n\t\t\t\t\t\t\tconst VertexLayout& layout = m_vertexLayouts[layoutIdx];\n\t\t\t\t\t\t\tconst uint32_t stride = layout.m_stride;\n\n\t\t\t\t\t\t\tbuffers[numStreams] = vb.m_ptr;\n\t\t\t\t\t\t\tstrides[numStreams] = stride;\n\t\t\t\t\t\t\toffsets[numStreams] = draw.m_stream[idx].m_startVertex * stride;\n\t\t\t\t\t\t\tlayouts[numStreams]   = &layout;\n\n\t\t\t\t\t\t\tnumVertices = bx::uint32_min(UINT32_MAX == draw.m_numVertices\n\t\t\t\t\t\t\t\t? vb.m_size/stride\n\t\t\t\t\t\t\t\t: draw.m_numVertices\n\t\t\t\t\t\t\t\t, numVertices\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcurrentNumVertices = numVertices;\n\n\t\t\t\t\tif (0 < numStreams)\n\t\t\t\t\t{\n\t\t\t\t\t\tdeviceCtx->IASetVertexBuffers(0, numStreams, buffers, strides, offsets);\n\n\t\t\t\t\t\tif (isValid(draw.m_instanceDataBuffer) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconst VertexBufferD3D11& inst = m_vertexBuffers[draw.m_instanceDataBuffer.idx];\n\t\t\t\t\t\t\tconst uint32_t instStride = draw.m_instanceDataStride;\n\t\t\t\t\t\t\tdeviceCtx->IASetVertexBuffers(numStreams, 1, &inst.m_ptr, &instStride, &draw.m_instanceDataOffset);\n\t\t\t\t\t\t\tsetInputLayout(numStreams, layouts, m_program[currentProgram.idx], uint16_t(instStride/16) );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdeviceCtx->IASetVertexBuffers(numStreams, 1, s_zero.m_buffer, s_zero.m_zero, s_zero.m_zero);\n\t\t\t\t\t\t\tsetInputLayout(numStreams, layouts, m_program[currentProgram.idx], 0);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tdeviceCtx->IASetVertexBuffers(0, 1, s_zero.m_buffer, s_zero.m_zero, s_zero.m_zero);\n\n\t\t\t\t\t\tif (isValid(draw.m_instanceDataBuffer) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tconst VertexBufferD3D11& inst = m_vertexBuffers[draw.m_instanceDataBuffer.idx];\n\t\t\t\t\t\t\tconst uint32_t instStride = draw.m_instanceDataStride;\n\t\t\t\t\t\t\tdeviceCtx->IASetVertexBuffers(0, 1, &inst.m_ptr, &instStride, &draw.m_instanceDataOffset);\n\t\t\t\t\t\t\tsetInputLayout(0, NULL, m_program[currentProgram.idx], uint16_t(instStride/16) );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdeviceCtx->IASetInputLayout(NULL);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (currentState.m_indexBuffer.idx != draw.m_indexBuffer.idx\n\t\t\t\t||  currentState.isIndex16() != draw.isIndex16() )\n\t\t\t\t{\n\t\t\t\t\tcurrentState.m_indexBuffer = draw.m_indexBuffer;\n\t\t\t\t\tcurrentState.m_submitFlags = draw.m_submitFlags;\n\n\t\t\t\t\tuint16_t handle = draw.m_indexBuffer.idx;\n\t\t\t\t\tif (kInvalidHandle != handle)\n\t\t\t\t\t{\n\t\t\t\t\t\tconst IndexBufferD3D11& ib = m_indexBuffers[handle];\n\t\t\t\t\t\tdeviceCtx->IASetIndexBuffer(ib.m_ptr\n\t\t\t\t\t\t\t, draw.isIndex16() ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT\n\t\t\t\t\t\t\t, 0\n\t\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tdeviceCtx->IASetIndexBuffer(NULL, DXGI_FORMAT_R16_UINT, 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (0 != currentState.m_streamMask)\n\t\t\t\t{\n\t\t\t\t\tuint32_t numVertices       = currentNumVertices;\n\t\t\t\t\tuint32_t numIndices        = 0;\n\t\t\t\t\tuint32_t numPrimsSubmitted = 0;\n\t\t\t\t\tuint32_t numInstances      = 0;\n\t\t\t\t\tuint32_t numPrimsRendered  = 0;\n\t\t\t\t\tuint32_t numDrawIndirect   = 0;\n\n\t\t\t\t\tif (hasOcclusionQuery)\n\t\t\t\t\t{\n\t\t\t\t\t\tm_occlusionQuery.begin(_render, draw.m_occlusionQuery);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isValid(draw.m_indirectBuffer) )\n\t\t\t\t\t{\n\t\t\t\t\t\tconst VertexBufferD3D11& vb = m_vertexBuffers[draw.m_indirectBuffer.idx];\n\t\t\t\t\t\tID3D11Buffer* ptr = vb.m_ptr;\n\n\t\t\t\t\t\tif (isValid(draw.m_indexBuffer) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnumDrawIndirect = UINT16_MAX == draw.m_numIndirect\n\t\t\t\t\t\t\t\t? vb.m_size/BGFX_CONFIG_DRAW_INDIRECT_STRIDE\n\t\t\t\t\t\t\t\t: draw.m_numIndirect\n\t\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\tmultiDrawIndexedInstancedIndirect(\n\t\t\t\t\t\t\t\t  numDrawIndirect\n\t\t\t\t\t\t\t\t, ptr\n\t\t\t\t\t\t\t\t, draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE\n\t\t\t\t\t\t\t\t, BGFX_CONFIG_DRAW_INDIRECT_STRIDE\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnumDrawIndirect = UINT16_MAX == draw.m_numIndirect\n\t\t\t\t\t\t\t\t? vb.m_size/BGFX_CONFIG_DRAW_INDIRECT_STRIDE\n\t\t\t\t\t\t\t\t: draw.m_numIndirect\n\t\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\tmultiDrawInstancedIndirect(\n\t\t\t\t\t\t\t\t  numDrawIndirect\n\t\t\t\t\t\t\t\t, ptr\n\t\t\t\t\t\t\t\t, draw.m_startIndirect * BGFX_CONFIG_DRAW_INDIRECT_STRIDE\n\t\t\t\t\t\t\t\t, BGFX_CONFIG_DRAW_INDIRECT_STRIDE\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (isValid(draw.m_indexBuffer) )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (UINT32_MAX == draw.m_numIndices)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tconst IndexBufferD3D11& ib = m_indexBuffers[draw.m_indexBuffer.idx];\n\t\t\t\t\t\t\t\tconst uint32_t indexSize = 0 == (ib.m_flags & BGFX_BUFFER_INDEX32) ? 2 : 4;\n\t\t\t\t\t\t\t\tnumIndices        = ib.m_size/indexSize;\n\t\t\t\t\t\t\t\tnumPrimsSubmitted = numIndices/prim.m_div - prim.m_sub;\n\t\t\t\t\t\t\t\tnumInstances      = draw.m_numInstances;\n\t\t\t\t\t\t\t\tnumPrimsRendered  = numPrimsSubmitted*draw.m_numInstances;\n\n\t\t\t\t\t\t\t\tif (numInstances > 1)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdeviceCtx->DrawIndexedInstanced(numIndices\n\t\t\t\t\t\t\t\t\t\t, draw.m_numInstances\n\t\t\t\t\t\t\t\t\t\t, 0\n\t\t\t\t\t\t\t\t\t\t, 0\n\t\t\t\t\t\t\t\t\t\t, 0\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdeviceCtx->DrawIndexed(numIndices\n\t\t\t\t\t\t\t\t\t\t, 0\n\t\t\t\t\t\t\t\t\t\t, 0\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (prim.m_min <= draw.m_numIndices)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnumIndices        = draw.m_numIndices;\n\t\t\t\t\t\t\t\tnumPrimsSubmitted = numIndices/prim.m_div - prim.m_sub;\n\t\t\t\t\t\t\t\tnumInstances      = draw.m_numInstances;\n\t\t\t\t\t\t\t\tnumPrimsRendered  = numPrimsSubmitted*draw.m_numInstances;\n\n\t\t\t\t\t\t\t\tif (numInstances > 1)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdeviceCtx->DrawIndexedInstanced(numIndices\n\t\t\t\t\t\t\t\t\t\t, draw.m_numInstances\n\t\t\t\t\t\t\t\t\t\t, draw.m_startIndex\n\t\t\t\t\t\t\t\t\t\t, 0\n\t\t\t\t\t\t\t\t\t\t, 0\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tdeviceCtx->DrawIndexed(numIndices\n\t\t\t\t\t\t\t\t\t\t, draw.m_startIndex\n\t\t\t\t\t\t\t\t\t\t, 0\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnumPrimsSubmitted = numVertices/prim.m_div - prim.m_sub;\n\t\t\t\t\t\t\tnumInstances      = draw.m_numInstances;\n\t\t\t\t\t\t\tnumPrimsRendered  = numPrimsSubmitted*draw.m_numInstances;\n\n\t\t\t\t\t\t\tif (numInstances > 1)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdeviceCtx->DrawInstanced(numVertices\n\t\t\t\t\t\t\t\t\t, draw.m_numInstances\n\t\t\t\t\t\t\t\t\t, 0\n\t\t\t\t\t\t\t\t\t, 0\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdeviceCtx->Draw(numVertices\n\t\t\t\t\t\t\t\t\t, 0\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (hasOcclusionQuery)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tm_occlusionQuery.end();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tstatsNumPrimsSubmitted[primIndex] += numPrimsSubmitted;\n\t\t\t\t\tstatsNumPrimsRendered[primIndex]  += numPrimsRendered;\n\t\t\t\t\tstatsNumInstances[primIndex]      += numInstances;\n\t\t\t\t\tstatsNumDrawIndirect[primIndex]   += numDrawIndirect;\n\t\t\t\t\tstatsNumIndices                   += numIndices;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (wasCompute)\n\t\t\t{\n\t\t\t\tsetViewType(view, "C");\n\t\t\t\tBGFX_D3D11_PROFILER_END();\n\t\t\t\tBGFX_D3D11_PROFILER_BEGIN(view, kColorCompute);\n\n\t\t\t\tinvalidateCompute();\n\t\t\t}\n\n\t\t\tsubmitBlit(bs, BGFX_CONFIG_MAX_VIEWS);\n\n\t\t\tif (0 < _render->m_numRenderItems)\n\t\t\t{\n\t\t\t\tif (0 != (m_resolution.reset & BGFX_RESET_FLUSH_AFTER_RENDER) )\n\t\t\t\t{\n\t\t\t\t\tdeviceCtx->Flush();\n\t\t\t\t}\n\n\t\t\t\tcaptureElapsed = -bx::getHPCounter();\n\t\t\t\tcapture();\n\t\t\t\tcaptureElapsed += bx::getHPCounter();\n\n\t\t\t\tprofiler.end();\n\t\t\t}\n\t\t}\n\n\t\tBGFX_D3D11_PROFILER_END();\n\n\t\tint64_t timeEnd = bx::getHPCounter();\n\t\tint64_t frameTime = timeEnd - timeBegin;\n\n\t\tstatic int64_t min = frameTime;\n\t\tstatic int64_t max = frameTime;\n\t\tmin = min > frameTime ? frameTime : min;\n\t\tmax = max < frameTime ? frameTime : max;\n\n\t\tstatic uint32_t maxGpuLatency = 0;\n\t\tstatic double   maxGpuElapsed = 0.0f;\n\t\tdouble elapsedGpuMs = 0.0;\n\n\t\tif (UINT32_MAX != frameQueryIdx)\n\t\t{\n\t\t\tm_gpuTimer.end(frameQueryIdx);\n\n\t\t\tconst TimerQueryD3D11::Result& result = m_gpuTimer.m_result[BGFX_CONFIG_MAX_VIEWS];\n\t\t\tdouble toGpuMs = 1000.0 / double(result.m_frequency);\n\t\t\telapsedGpuMs   = (result.m_end - result.m_begin) * toGpuMs;\n\t\t\tmaxGpuElapsed  = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed;\n\n\t\t\tmaxGpuLatency = bx::uint32_imax(maxGpuLatency, result.m_pending-1);\n\t\t}\n\n\t\tconst int64_t timerFreq = bx::getHPFrequency();\n\n\t\tStats& perfStats = _render->m_perfStats;\n\t\tperfStats.cpuTimeBegin  = timeBegin;\n\t\tperfStats.cpuTimeEnd    = timeEnd;\n\t\tperfStats.cpuTimerFreq  = timerFreq;\n\t\tconst TimerQueryD3D11::Result& result = m_gpuTimer.m_result[BGFX_CONFIG_MAX_VIEWS];\n\t\tperfStats.gpuTimeBegin  = result.m_begin;\n\t\tperfStats.gpuTimeEnd    = result.m_end;\n\t\tperfStats.gpuTimerFreq  = result.m_frequency;\n\t\tperfStats.numDraw       = statsKeyType[0];\n\t\tperfStats.numCompute    = statsKeyType[1];\n\t\tperfStats.numBlit       = _render->m_numBlitItems;\n\t\tperfStats.maxGpuLatency = maxGpuLatency;\n\t\tperfStats.gpuFrameNum   = result.m_frameNum;\n\t\tbx::memCopy(perfStats.numPrims, statsNumPrimsRendered, sizeof(perfStats.numPrims) );\n\t\tm_nvapi.getMemoryInfo(perfStats.gpuMemoryUsed, perfStats.gpuMemoryMax);\n\n\t\tif (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) )\n\t\t{\n\t\t\tBGFX_D3D11_PROFILER_BEGIN_LITERAL("debugstats", kColorFrame);\n\n\t\t\tm_needPresent = true;\n\t\t\tTextVideoMem& tvm = m_textVideoMem;\n\n\t\t\tstatic int64_t next = timeEnd;\n\n\t\t\tif (timeEnd >= next)\n\t\t\t{\n\t\t\t\tnext = timeEnd + timerFreq;\n\n\t\t\t\tdouble freq = double(timerFreq);\n\t\t\t\tdouble toMs = 1000.0/freq;\n\n\t\t\t\ttvm.clear();\n\t\t\t\tuint16_t pos = 0;\n\t\t\t\ttvm.printf(0, pos++, BGFX_CONFIG_DEBUG ? 0x8c : 0x8f\n\t\t\t\t\t, " %s.%d (FL %d.%d) / " BX_COMPILER_NAME\n\t\t\t\t\t  " / " BX_CPU_NAME\n\t\t\t\t\t  " / " BX_ARCH_NAME\n\t\t\t\t\t  " / " BX_PLATFORM_NAME\n\t\t\t\t\t  " / Version 1.%d.%d (commit: " BGFX_REV_SHA1 ")"\n\t\t\t\t\t, getRendererName()\n\t\t\t\t\t, m_deviceInterfaceVersion\n\t\t\t\t\t, (m_featureLevel >> 12) & 0xf\n\t\t\t\t\t, (m_featureLevel >>  8) & 0xf\n\t\t\t\t\t, BGFX_API_VERSION\n\t\t\t\t\t, BGFX_REV_NUMBER\n\t\t\t\t\t);\n\n\t\t\t\tconst DXGI_ADAPTER_DESC& desc = m_dxgi.m_adapterDesc;\n\t\t\t\tchar description[BX_COUNTOF(desc.Description)];\n\t\t\t\twcstombs(description, desc.Description, BX_COUNTOF(desc.Description) );\n\t\t\t\ttvm.printf(0, pos++, 0x8f, " Device: %s", description);\n\n\t\t\t\tchar dedicatedVideo[16];\n\t\t\t\tbx::prettify(dedicatedVideo, BX_COUNTOF(dedicatedVideo), desc.DedicatedVideoMemory);\n\n\t\t\t\tchar dedicatedSystem[16];\n\t\t\t\tbx::prettify(dedicatedSystem, BX_COUNTOF(dedicatedSystem), desc.DedicatedSystemMemory);\n\n\t\t\t\tchar sharedSystem[16];\n\t\t\t\tbx::prettify(sharedSystem, BX_COUNTOF(sharedSystem), desc.SharedSystemMemory);\n\n\t\t\t\tchar processMemoryUsed[16];\n\t\t\t\tbx::prettify(processMemoryUsed, BX_COUNTOF(processMemoryUsed), bx::getProcessMemoryUsed() );\n\n\t\t\t\ttvm.printf(0, pos++, 0x8f, " Memory: %s (video), %s (system), %s (shared), %s (process) "\n\t\t\t\t\t, dedicatedVideo\n\t\t\t\t\t, dedicatedSystem\n\t\t\t\t\t, sharedSystem\n\t\t\t\t\t, processMemoryUsed\n\t\t\t\t\t);\n\n\t\t\t\tpos = 10;\n\t\t\t\ttvm.printf(10, pos++, 0x8b, "        Frame: %7.3f, % 7.3f \\x1f, % 7.3f \\x1e [ms] / % 6.2f FPS "\n\t\t\t\t\t, double(frameTime)*toMs\n\t\t\t\t\t, double(min)*toMs\n\t\t\t\t\t, double(max)*toMs\n\t\t\t\t\t, freq/frameTime\n\t\t\t\t\t);\n\n\t\t\t\tconst uint32_t msaa = (m_resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT;\n\t\t\t\ttvm.printf(10, pos++, 0x8b, "  Reset flags: [%c] vsync, [%c] MSAAx%d, [%c] MaxAnisotropy "\n\t\t\t\t\t, !!(m_resolution.reset&BGFX_RESET_VSYNC) ? \'\\xfe\' : \' \'\n\t\t\t\t\t, 0 != msaa ? \'\\xfe\' : \' \'\n\t\t\t\t\t, 1<<msaa\n\t\t\t\t\t, !!(m_resolution.reset&BGFX_RESET_MAXANISOTROPY) ? \'\\xfe\' : \' \'\n\t\t\t\t\t);\n\n\t\t\t\tdouble elapsedCpuMs = double(frameTime)*toMs;\n\t\t\t\ttvm.printf(10, pos++, 0x8b, "    Submitted: %5d (draw %5d, compute %4d) / CPU %7.4f [ms] %c GPU %7.4f [ms] (latency %d) "\n\t\t\t\t\t, _render->m_numRenderItems\n\t\t\t\t\t, statsKeyType[0]\n\t\t\t\t\t, statsKeyType[1]\n\t\t\t\t\t, elapsedCpuMs\n\t\t\t\t\t, elapsedCpuMs > maxGpuElapsed ? \'>\' : \'<\'\n\t\t\t\t\t, maxGpuElapsed\n\t\t\t\t\t, maxGpuLatency\n\t\t\t\t\t);\n\t\t\t\tmaxGpuLatency = 0;\n\t\t\t\tmaxGpuElapsed = 0.0;\n\n\t\t\t\tfor (uint32_t ii = 0; ii < Topology::Count; ++ii)\n\t\t\t\t{\n\t\t\t\t\ttvm.printf(10, pos++, 0x8b, "   %10s: %7d (#inst: %5d), submitted: %7d, indirect %7d"\n\t\t\t\t\t\t, getName(Topology::Enum(ii) )\n\t\t\t\t\t\t, statsNumPrimsRendered[ii]\n\t\t\t\t\t\t, statsNumInstances[ii]\n\t\t\t\t\t\t, statsNumPrimsSubmitted[ii]\n\t\t\t\t\t\t, statsNumDrawIndirect[ii]\n\t\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (NULL != m_renderDocDll)\n\t\t\t\t{\n\t\t\t\t\ttvm.printf(tvm.m_width-27, 0, 0x4f, " [F11 - RenderDoc capture] ");\n\t\t\t\t}\n\n\t\t\t\ttvm.printf(10, pos++, 0x8b, "      Indices: %7d ", statsNumIndices);\n//\t\t\t\ttvm.printf(10, pos++, 0x8b, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax);\n\t\t\t\ttvm.printf(10, pos++, 0x8b, "     DVB size: %7d ", _render->m_vboffset);\n\t\t\t\ttvm.printf(10, pos++, 0x8b, "     DIB size: %7d ", _render->m_iboffset);\n\n\t\t\t\tpos++;\n\t\t\t\ttvm.printf(10, pos++, 0x8b, " Occlusion queries: %3d ", m_occlusionQuery.m_control.available() );\n\n\t\t\t\tpos++;\n\t\t\t\ttvm.printf(10, pos++, 0x8b, " State cache:                                ");\n\t\t\t\ttvm.printf(10, pos++, 0x8b, " Blend  | DepthS | Input  | Raster | Sampler ");\n\t\t\t\ttvm.printf(10, pos++, 0x8b, " %6d | %6d | %6d | %6d | %6d  "\n\t\t\t\t\t, m_blendStateCache.getCount()\n\t\t\t\t\t, m_depthStencilStateCache.getCount()\n\t\t\t\t\t, m_inputLayoutCache.getCount()\n\t\t\t\t\t, m_rasterizerStateCache.getCount()\n\t\t\t\t\t, m_samplerStateCache.getCount()\n\t\t\t\t\t);\n\t\t\t\tpos++;\n\n\t\t\t\tdouble captureMs = double(captureElapsed)*toMs;\n\t\t\t\ttvm.printf(10, pos++, 0x8b, "     Capture: %7.4f [ms] ", captureMs);\n\n\t\t\t\tuint8_t attr[2] = { 0x8c, 0x8a };\n\t\t\t\tuint8_t attrIndex = _render->m_waitSubmit < _render->m_waitRender;\n\n\t\t\t\ttvm.printf(10, pos++, attr[attrIndex&1], " Submit wait: %7.4f [ms] ", _render->m_waitSubmit*toMs);\n\t\t\t\ttvm.printf(10, pos++, attr[(attrIndex+1)&1], " Render wait: %7.4f [ms] ", _render->m_waitRender*toMs);\n\n\t\t\t\tmin = frameTime;\n\t\t\t\tmax = frameTime;\n\t\t\t}\n\n\t\t\tblit(this, _textVideoMemBlitter, tvm);\n\n\t\t\tBGFX_D3D11_PROFILER_END();\n\t\t}\n\t\telse if (_render->m_debug & BGFX_DEBUG_TEXT)\n\t\t{\n\t\t\tBGFX_D3D11_PROFILER_BEGIN_LITERAL("debugtext", kColorFrame);\n\n\t\t\tblit(this, _textVideoMemBlitter, _render->m_textVideoMem);\n\n\t\t\tBGFX_D3D11_PROFILER_END();\n\t\t}\n\n\t\tm_deviceCtx->OMSetRenderTargets(1, s_zero.m_rtv, NULL);\n\n\t\tif (NULL != m_msaaRt)\n\t\t{\n\t\t\tID3D11Texture2D* backBufferColor;\n\t\t\tDX_CHECK(m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBufferColor) );\n\t\t\tdeviceCtx->ResolveSubresource(backBufferColor, 0, m_msaaRt, 0, m_scd.format);\n\t\t\tDX_RELEASE(backBufferColor, 0);\n\t\t}\n\t}\n} /* namespace d3d11 */ } // namespace bgfx\n\n#else\n\nnamespace bgfx { namespace d3d11\n{\n\tRendererContextI* rendererCreate(const Init& _init)\n\t{\n\t\tBX_UNUSED(_init);\n\t\treturn NULL;\n\t}\n\n\tvoid rendererDestroy()\n\t{\n\t}\n} /* namespace d3d11 */ } // namespace bgfx\n\n#endif // BGFX_CONFIG_RENDERER_DIRECT3D11\n', 'message': "Merge branch 'master' of github.com:bkaradzic/bgfx\n", 'author_name': 'Branimir Karadžić', 'lang': 'cpp'}