diff options
author | 2017-12-01 13:22:27 +0100 | |
---|---|---|
committer | 2017-12-01 13:22:27 +0100 | |
commit | 39176274946d70ff520f265dee8fbd16d5fe0000 (patch) | |
tree | 318801d93146752050c9a492654ae3738820e3b9 /3rdparty/bgfx/src/renderer_d3d11.cpp | |
parent | 6829ecb3b037d6bfbe0b84e818d17d712f71bce6 (diff) |
Updated GENie, BGFX, BX, added BIMG since it is separated now, updated all shader binaries and MAME part of code to support new interfaces [Miodrag Milanovic]
Diffstat (limited to '3rdparty/bgfx/src/renderer_d3d11.cpp')
-rw-r--r-- | 3rdparty/bgfx/src/renderer_d3d11.cpp | 1256 |
1 files changed, 769 insertions, 487 deletions
diff --git a/3rdparty/bgfx/src/renderer_d3d11.cpp b/3rdparty/bgfx/src/renderer_d3d11.cpp index 2a65c2a2c1d..0a22fa4b443 100644 --- a/3rdparty/bgfx/src/renderer_d3d11.cpp +++ b/3rdparty/bgfx/src/renderer_d3d11.cpp @@ -15,20 +15,6 @@ # endif // BX_PLATFORM_WINRT #endif // !BX_PLATFORM_WINDOWS -#if BGFX_CONFIG_PROFILER_REMOTERY -# define BGFX_GPU_PROFILER_BIND(_device, _context) rmt_BindD3D11(_device, _context) -# define BGFX_GPU_PROFILER_UNBIND() rmt_UnbindD3D11() -# define BGFX_GPU_PROFILER_BEGIN(_group, _name, _color) rmt_BeginD3D11Sample(_group##_##_name) -# define BGFX_GPU_PROFILER_BEGIN_DYNAMIC(_namestr) rmt_BeginD3D11SampleDynamic(_namestr) -# define BGFX_GPU_PROFILER_END() rmt_EndD3D11Sample() -#else -# define BGFX_GPU_PROFILER_BIND(_device, _context) BX_NOOP() -# define BGFX_GPU_PROFILER_UNBIND() BX_NOOP() -# define BGFX_GPU_PROFILER_BEGIN(_group, _name, _color) BX_NOOP() -# define BGFX_GPU_PROFILER_BEGIN_DYNAMIC(_namestr) BX_NOOP() -# define BGFX_GPU_PROFILER_END() BX_NOOP() -#endif - #if BGFX_CONFIG_USE_OVR # include "hmd_ovr.h" #endif // BGFX_CONFIG_USE_OVR @@ -287,7 +273,7 @@ namespace bgfx { namespace d3d11 { DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGBA4 { DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGB5A1 { DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // RGB10A2 - { DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, // R11G11B10F + { DXGI_FORMAT_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 @@ -308,6 +294,8 @@ namespace bgfx { namespace d3d11 { "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 }, @@ -356,7 +344,7 @@ namespace bgfx { namespace d3d11 }; BX_STATIC_ASSERT(AttribType::Count == BX_COUNTOF(s_attribType) ); - static D3D11_INPUT_ELEMENT_DESC* fillVertexDecl(D3D11_INPUT_ELEMENT_DESC* _out, const VertexDecl& _decl) + static D3D11_INPUT_ELEMENT_DESC* fillVertexDecl(uint8_t _stream, D3D11_INPUT_ELEMENT_DESC* _out, const VertexDecl& _decl) { D3D11_INPUT_ELEMENT_DESC* elem = _out; @@ -366,6 +354,8 @@ namespace bgfx { namespace d3d11 { bx::memCopy(elem, &s_attrib[attr], sizeof(D3D11_INPUT_ELEMENT_DESC) ); + elem->InputSlot = _stream; + if (0 == _decl.m_attributes[attr]) { elem->AlignedByteOffset = 0; @@ -409,19 +399,20 @@ namespace bgfx { namespace d3d11 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_IDXGIFactory = { 0x7b7166ec, 0x21c7, 0x44ae, { 0xb2, 0x1a, 0xc9, 0xae, 0x32, 0x1a, 0xe3, 0x69 } }; - static const GUID IID_IDXGIDevice0 = { 0x54ec77fa, 0x1377, 0x44e6, { 0x8c, 0x32, 0x88, 0xfd, 0x5f, 0x44, 0xc8, 0x4c } }; - static const GUID IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } }; - static const GUID IID_IDXGIDevice2 = { 0x05008617, 0xfbfd, 0x4051, { 0xa7, 0x90, 0x14, 0x48, 0x84, 0xb4, 0xf6, 0xa9 } }; - static const GUID IID_IDXGIDevice3 = { 0x6007896c, 0x3244, 0x4afd, { 0xbf, 0x18, 0xa6, 0xd3, 0xbe, 0xda, 0x50, 0x23 } }; - static const GUID IID_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_IDXGIAdapter = { 0x2411e7e1, 0x12ac, 0x4ccf, { 0xbd, 0x14, 0x97, 0x98, 0xe8, 0x53, 0x4d, 0xc0 } }; - 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 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_IDXGIFactory = { 0x7b7166ec, 0x21c7, 0x44ae, { 0xb2, 0x1a, 0xc9, 0xae, 0x32, 0x1a, 0xe3, 0x69 } }; + static const GUID IID_IDXGIDevice0 = { 0x54ec77fa, 0x1377, 0x44e6, { 0x8c, 0x32, 0x88, 0xfd, 0x5f, 0x44, 0xc8, 0x4c } }; + static const GUID IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } }; + static const GUID IID_IDXGIDevice2 = { 0x05008617, 0xfbfd, 0x4051, { 0xa7, 0x90, 0x14, 0x48, 0x84, 0xb4, 0xf6, 0xa9 } }; + static const GUID IID_IDXGIDevice3 = { 0x6007896c, 0x3244, 0x4afd, { 0xbf, 0x18, 0xa6, 0xd3, 0xbe, 0xda, 0x50, 0x23 } }; + static const GUID IID_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_IDXGIAdapter = { 0x2411e7e1, 0x12ac, 0x4ccf, { 0xbd, 0x14, 0x97, 0x98, 0xe8, 0x53, 0x4d, 0xc0 } }; + 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 { @@ -455,6 +446,35 @@ namespace bgfx { namespace d3d11 ; } + 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, ...) { @@ -543,8 +563,12 @@ namespace bgfx { namespace d3d11 #endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT } - // Reference: - // https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK + /* + * AMD GPU Services (AGS) library + * + * Reference: + * https://github.com/GPUOpen-LibrariesAndSDKs/AGS_SDK + */ enum AGS_RETURN_CODE { AGS_SUCCESS, @@ -616,17 +640,21 @@ namespace bgfx { namespace d3d11 static PFN_GET_DEBUG_INTERFACE1 DXGIGetDebugInterface1; #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); + #if BGFX_CONFIG_USE_OVR class VRImplOVRD3D11 : public VRImplOVR { public: VRImplOVRD3D11(); - virtual bool createSwapChain(const VRDesc& _desc, int _msaaSamples, int _mirrorWidth, int _mirrorHeight) BX_OVERRIDE; - virtual void destroySwapChain() BX_OVERRIDE; - virtual void destroyMirror() BX_OVERRIDE; - virtual void makeRenderTargetActive(const VRDesc& _desc) BX_OVERRIDE; - virtual bool submitSwapChain(const VRDesc& _desc) BX_OVERRIDE; + virtual bool createSwapChain(const VRDesc& _desc, int _msaaSamples, int _mirrorWidth, int _mirrorHeight) override; + virtual void destroySwapChain() override; + virtual void destroyMirror() override; + virtual void makeRenderTargetActive(const VRDesc& _desc) override; + virtual bool submitSwapChain(const VRDesc& _desc) override; private: ID3D11DepthStencilView* m_depthBuffer; @@ -654,10 +682,11 @@ namespace bgfx { namespace d3d11 , m_adapter(NULL) , m_factory(NULL) , m_swapChain(NULL) - , m_lost(0) + , m_lost(false) , m_numWindows(0) , m_device(NULL) , m_deviceCtx(NULL) + , m_annotation(NULL) , m_infoQueue(NULL) , m_backBufferColor(NULL) , m_backBufferDepthStencil(NULL) @@ -674,7 +703,7 @@ namespace bgfx { namespace d3d11 , m_rtMsaa(false) , m_timerQuerySupport(false) { - m_fbh.idx = invalidHandle; + m_fbh.idx = kInvalidHandle; bx::memSet(&m_adapterDesc, 0, sizeof(m_adapterDesc) ); bx::memSet(&m_scd, 0, sizeof(m_scd) ); bx::memSet(&m_windows, 0xff, sizeof(m_windows) ); @@ -711,18 +740,18 @@ namespace bgfx { namespace d3d11 m_renderdocdll = loadRenderDoc(); } - m_fbh.idx = invalidHandle; + 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" + "amd_ags_x86.dll" #else - "amd_ags_x64.dll" + "amd_ags_x64.dll" #endif // BX_ARCH_32BIT - ); + ); if (NULL != m_agsdll) { agsInit = (PFN_AGS_INIT )bx::dlsym(m_agsdll, "agsInit"); @@ -795,12 +824,14 @@ namespace bgfx { namespace d3d11 } } + m_nvapi.init(); + #if USE_D3D11_DYNAMIC_LIB m_d3d11dll = bx::dlopen("d3d11.dll"); if (NULL == m_d3d11dll) { - BX_TRACE("Failed to load d3d11.dll."); + BX_TRACE("Init error: Failed to load d3d11.dll."); goto error; } @@ -829,14 +860,14 @@ namespace bgfx { namespace d3d11 D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)bx::dlsym(m_d3d11dll, "D3D11CreateDevice"); if (NULL == D3D11CreateDevice) { - BX_TRACE("Function D3D11CreateDevice not found."); + BX_TRACE("Init error: Function D3D11CreateDevice not found."); goto error; } m_dxgidll = bx::dlopen("dxgi.dll"); if (NULL == m_dxgidll) { - BX_TRACE("Failed to load dxgi.dll."); + BX_TRACE("Init error: Failed to load dxgi.dll."); goto error; } @@ -849,7 +880,7 @@ namespace bgfx { namespace d3d11 } if (NULL == CreateDXGIFactory) { - BX_TRACE("Function CreateDXGIFactory not found."); + BX_TRACE("Init error: Function CreateDXGIFactory not found."); goto error; } @@ -884,7 +915,7 @@ namespace bgfx { namespace d3d11 #endif // BX_PLATFORM_* if (FAILED(hr) ) { - BX_TRACE("Unable to create DXGI factory."); + BX_TRACE("Init error: Unable to create DXGI factory."); goto error; } @@ -945,7 +976,7 @@ namespace bgfx { namespace d3d11 } if (BX_ENABLED(BGFX_CONFIG_DEBUG_PERFHUD) - && 0 != strstr(description, "PerfHUD") ) + && 0 != bx::strFind(description, "PerfHUD") ) { m_adapter = adapter; m_driverType = D3D_DRIVER_TYPE_REFERENCE; @@ -1026,7 +1057,7 @@ namespace bgfx { namespace d3d11 if (FAILED(hr) ) { - BX_TRACE("Unable to create Direct3D11 device."); + BX_TRACE("Init error: Unable to create Direct3D11 device."); goto error; } @@ -1041,7 +1072,7 @@ namespace bgfx { namespace d3d11 if (NULL == m_deviceCtx) { - BX_TRACE("Unable to retrieve Direct3D11 ImmediateContext."); + BX_TRACE("Init error: Unable to retrieve Direct3D11 ImmediateContext."); goto error; } @@ -1102,7 +1133,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (FAILED(hr) ) { - BX_TRACE("Unable to create Direct3D11 device."); + BX_TRACE("Init error: Unable to create Direct3D11 device."); goto error; } @@ -1141,7 +1172,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); DX_RELEASE(adapter, 2); if (FAILED(hr) ) { - BX_TRACE("Unable to create Direct3D11 device."); + BX_TRACE("Init error: Unable to create Direct3D11 device."); goto error; } @@ -1201,7 +1232,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); DX_RELEASE(adapter, 2); if (FAILED(hr) ) { - BX_TRACE("Unable to create Direct3D11 device."); + BX_TRACE("Init error: Unable to create Direct3D11 device."); goto error; } @@ -1230,7 +1261,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); #endif // BX_PLATFORM_* if (FAILED(hr) ) { - BX_TRACE("Failed to create swap chain."); + BX_TRACE("Init error: Failed to create swap chain."); goto error; } } @@ -1247,6 +1278,20 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_numWindows = 1; +#if USE_D3D11_DYNAMIC_LIB + if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) + { + 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 (BX_ENABLED(BGFX_CONFIG_DEBUG) ) { hr = m_device->QueryInterface(IID_ID3D11InfoQueue, (void**)&m_infoQueue); @@ -1264,8 +1309,19 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { 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); DX_RELEASE(m_infoQueue, 3); @@ -1296,18 +1352,39 @@ BX_PRAGMA_DIAGNOSTIC_POP(); 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.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.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.supported |= BGFX_CAPS_TEXTURE_COMPARE_ALL; g_caps.limits.maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; - g_caps.limits.maxFBAttachments = uint8_t(bx::uint32_min(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS) ); + 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+. @@ -1386,7 +1463,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { uint16_t support = BGFX_CAPS_FORMAT_TEXTURE_NONE; - const DXGI_FORMAT fmt = isDepth(TextureFormat::Enum(ii) ) + const DXGI_FORMAT fmt = bimg::isDepth(bimg::TextureFormat::Enum(ii) ) ? s_textureFormat[ii].m_fmtDsv : s_textureFormat[ii].m_fmt ; @@ -1615,8 +1692,6 @@ BX_PRAGMA_DIAGNOSTIC_POP(); postReset(); } - BGFX_GPU_PROFILER_BIND(m_device, m_deviceCtx); - g_internalData.context = m_device; return true; @@ -1653,12 +1728,17 @@ BX_PRAGMA_DIAGNOSTIC_POP(); 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); m_ovr.shutdown(); break; @@ -1669,11 +1749,11 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void shutdown() { - BGFX_GPU_PROFILER_UNBIND(); - preReset(); m_ovr.shutdown(); + m_nvapi.shutdown(); + if (NULL != m_ags) { agsDeInit(m_ags); @@ -1712,6 +1792,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_textures[ii].destroy(); } + DX_RELEASE(m_annotation, 1); DX_RELEASE(m_swapChain, 0); DX_RELEASE(m_deviceCtx, 0); DX_RELEASE(m_device, 0); @@ -1740,117 +1821,117 @@ BX_PRAGMA_DIAGNOSTIC_POP(); #endif // USE_D3D11_DYNAMIC_LIB } - RendererType::Enum getRendererType() const BX_OVERRIDE + RendererType::Enum getRendererType() const override { return RendererType::Direct3D11; } - const char* getRendererName() const BX_OVERRIDE + const char* getRendererName() const override { return BGFX_RENDERER_DIRECT3D11_NAME; } - void createIndexBuffer(IndexBufferHandle _handle, Memory* _mem, uint16_t _flags) BX_OVERRIDE + void createIndexBuffer(IndexBufferHandle _handle, Memory* _mem, uint16_t _flags) override { m_indexBuffers[_handle.idx].create(_mem->size, _mem->data, _flags); } - void destroyIndexBuffer(IndexBufferHandle _handle) BX_OVERRIDE + void destroyIndexBuffer(IndexBufferHandle _handle) override { m_indexBuffers[_handle.idx].destroy(); } - void createVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl) BX_OVERRIDE + void createVertexDecl(VertexDeclHandle _handle, const VertexDecl& _decl) override { VertexDecl& decl = m_vertexDecls[_handle.idx]; bx::memCopy(&decl, &_decl, sizeof(VertexDecl) ); dump(decl); } - void destroyVertexDecl(VertexDeclHandle /*_handle*/) BX_OVERRIDE + void destroyVertexDecl(VertexDeclHandle /*_handle*/) override { } - void createVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle, uint16_t _flags) BX_OVERRIDE + void createVertexBuffer(VertexBufferHandle _handle, Memory* _mem, VertexDeclHandle _declHandle, uint16_t _flags) override { m_vertexBuffers[_handle.idx].create(_mem->size, _mem->data, _declHandle, _flags); } - void destroyVertexBuffer(VertexBufferHandle _handle) BX_OVERRIDE + void destroyVertexBuffer(VertexBufferHandle _handle) override { m_vertexBuffers[_handle.idx].destroy(); } - void createDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _size, uint16_t _flags) BX_OVERRIDE + 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, Memory* _mem) BX_OVERRIDE + void updateDynamicIndexBuffer(IndexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) override { m_indexBuffers[_handle.idx].update(_offset, bx::uint32_min(_size, _mem->size), _mem->data); } - void destroyDynamicIndexBuffer(IndexBufferHandle _handle) BX_OVERRIDE + void destroyDynamicIndexBuffer(IndexBufferHandle _handle) override { m_indexBuffers[_handle.idx].destroy(); } - void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) BX_OVERRIDE + void createDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _size, uint16_t _flags) override { VertexDeclHandle decl = BGFX_INVALID_HANDLE; m_vertexBuffers[_handle.idx].create(_size, NULL, decl, _flags); } - void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) BX_OVERRIDE + void updateDynamicVertexBuffer(VertexBufferHandle _handle, uint32_t _offset, uint32_t _size, Memory* _mem) override { m_vertexBuffers[_handle.idx].update(_offset, bx::uint32_min(_size, _mem->size), _mem->data); } - void destroyDynamicVertexBuffer(VertexBufferHandle _handle) BX_OVERRIDE + void destroyDynamicVertexBuffer(VertexBufferHandle _handle) override { m_vertexBuffers[_handle.idx].destroy(); } - void createShader(ShaderHandle _handle, Memory* _mem) BX_OVERRIDE + void createShader(ShaderHandle _handle, Memory* _mem) override { m_shaders[_handle.idx].create(_mem); } - void destroyShader(ShaderHandle _handle) BX_OVERRIDE + void destroyShader(ShaderHandle _handle) override { m_shaders[_handle.idx].destroy(); } - void createProgram(ProgramHandle _handle, ShaderHandle _vsh, ShaderHandle _fsh) BX_OVERRIDE + 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) BX_OVERRIDE + void destroyProgram(ProgramHandle _handle) override { m_program[_handle.idx].destroy(); } - void createTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags, uint8_t _skip) BX_OVERRIDE + void createTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags, uint8_t _skip) override { m_textures[_handle.idx].create(_mem, _flags, _skip); } - void updateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/) BX_OVERRIDE + 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) BX_OVERRIDE + void updateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) override { m_textures[_handle.idx].update(_side, _mip, _rect, _z, _depth, _pitch, _mem); } - void updateTextureEnd() BX_OVERRIDE + void updateTextureEnd() override { } - void readTexture(TextureHandle _handle, void* _data, uint8_t _mip) BX_OVERRIDE + void readTexture(TextureHandle _handle, void* _data, uint8_t _mip) override { const TextureD3D11& texture = m_textures[_handle.idx]; D3D11_MAPPED_SUBRESOURCE mapped; @@ -1861,7 +1942,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); uint8_t* src = (uint8_t*)mapped.pData; uint32_t srcPitch = mapped.RowPitch; - const uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(texture.m_textureFormat) ); + const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(texture.m_textureFormat) ); uint8_t* dst = (uint8_t*)_data; uint32_t dstPitch = srcWidth*bpp/8; @@ -1878,7 +1959,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_deviceCtx->Unmap(texture.m_ptr, _mip); } - void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips) BX_OVERRIDE + void resizeTexture(TextureHandle _handle, uint16_t _width, uint16_t _height, uint8_t _numMips) override { TextureD3D11& texture = m_textures[_handle.idx]; @@ -1906,7 +1987,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); release(mem); } - void overrideInternal(TextureHandle _handle, uintptr_t _ptr) BX_OVERRIDE + 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. @@ -1914,7 +1995,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_textures[_handle.idx].overrideInternal(_ptr); } - uintptr_t getInternal(TextureHandle _handle) BX_OVERRIDE + uintptr_t getInternal(TextureHandle _handle) override { // Resource ref. counts might be messed up outside of bgfx. // Disabling ref. count check once texture is overridden. @@ -1922,24 +2003,24 @@ BX_PRAGMA_DIAGNOSTIC_POP(); return uintptr_t(m_textures[_handle.idx].m_ptr); } - void destroyTexture(TextureHandle _handle) BX_OVERRIDE + void destroyTexture(TextureHandle _handle) override { m_textures[_handle.idx].destroy(); } - void createFrameBuffer(FrameBufferHandle _handle, uint8_t _num, const Attachment* _attachment) BX_OVERRIDE + 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 _depthFormat) BX_OVERRIDE + void createFrameBuffer(FrameBufferHandle _handle, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat) override { uint16_t denseIdx = m_numWindows++; m_windows[denseIdx] = _handle; m_frameBuffers[_handle.idx].create(denseIdx, _nwh, _width, _height, _depthFormat); } - void destroyFrameBuffer(FrameBufferHandle _handle) BX_OVERRIDE + void destroyFrameBuffer(FrameBufferHandle _handle) override { uint16_t denseIdx = m_frameBuffers[_handle.idx].destroy(); if (UINT16_MAX != denseIdx) @@ -1954,7 +2035,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } - void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) BX_OVERRIDE + void createUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) override { if (NULL != m_uniforms[_handle.idx]) { @@ -1968,14 +2049,14 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_uniformReg.add(_handle, _name, data); } - void destroyUniform(UniformHandle _handle) BX_OVERRIDE + 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) BX_OVERRIDE + void requestScreenShot(FrameBufferHandle _handle, const char* _filePath) override { IDXGISwapChain* swapChain = isValid(_handle) ? m_frameBuffers[_handle.idx].m_swapChain @@ -2026,12 +2107,13 @@ BX_PRAGMA_DIAGNOSTIC_POP(); D3D11_MAPPED_SUBRESOURCE mapped; DX_CHECK(m_deviceCtx->Map(texture, 0, D3D11_MAP_READ, 0, &mapped) ); - imageSwizzleBgra8( + bimg::imageSwizzleBgra8( mapped.pData + , mapped.RowPitch , backBufferDesc.Width , backBufferDesc.Height - , mapped.RowPitch , mapped.pData + , mapped.RowPitch ); g_callback->screenShot(_filePath , backBufferDesc.Width @@ -2049,7 +2131,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); DX_RELEASE(backBuffer, 0); } - void updateViewName(uint8_t _id, const char* _name) BX_OVERRIDE + void updateViewName(ViewId _id, const char* _name) override { if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) { @@ -2059,18 +2141,18 @@ BX_PRAGMA_DIAGNOSTIC_POP(); ); } - bx::strlcpy(&s_viewName[_id][BGFX_CONFIG_MAX_VIEW_NAME_RESERVED] - , _name + 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) BX_OVERRIDE + void updateUniform(uint16_t _loc, const void* _data, uint32_t _size) override { bx::memCopy(m_uniforms[_loc], _data, _size); } - void setMarker(const char* _marker, uint32_t _size) BX_OVERRIDE + void setMarker(const char* _marker, uint32_t _size) override { if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) { @@ -2081,14 +2163,34 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } - void invalidateOcclusionQuery(OcclusionQueryHandle _handle) BX_OVERRIDE + void invalidateOcclusionQuery(OcclusionQueryHandle _handle) override { m_occlusionQuery.invalidate(_handle); } - void submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) BX_OVERRIDE; + virtual void setName(Handle _handle, const char* _name) override + { + switch (_handle.type) + { + case Handle::Shader: + setDebugObjectName(m_shaders[_handle.idx].m_ptr, _name); + break; + + case Handle::Texture: + setDebugObjectName(m_textures[_handle.idx].m_ptr, _name); + break; + + default: + BX_CHECK(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) BX_OVERRIDE + void blitSetup(TextVideoMemBlitter& _blitter) override { ID3D11DeviceContext* deviceCtx = m_deviceCtx; @@ -2134,7 +2236,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); 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); + 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; @@ -2145,7 +2247,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); commitTextureStage(); } - void blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) BX_OVERRIDE + void blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) override { const uint32_t numVertices = _numIndices*4/6; if (0 < numVertices) @@ -2263,9 +2365,15 @@ BX_PRAGMA_DIAGNOSTIC_POP(); capturePostReset(); } - void flip(HMD& _hmd) BX_OVERRIDE + bool isDeviceRemoved() override { - if (NULL != m_swapChain) + return m_lost; + } + + void flip(HMD& _hmd) override + { + if (NULL != m_swapChain + && !m_lost) { HRESULT hr = S_OK; uint32_t syncInterval = BX_ENABLED(!BX_PLATFORM_WINDOWS) @@ -2298,15 +2406,14 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } - if (isLost(hr) ) - { - ++m_lost; - BGFX_FATAL(10 > m_lost, bgfx::Fatal::DeviceLost, "Device is lost. FAILED 0x%08x", hr); - } - else - { - m_lost = 0; - } + m_lost = isLost(hr); + BGFX_FATAL(!m_lost + , bgfx::Fatal::DeviceLost + , "Device is lost. FAILED 0x%08x %s (%s)" + , hr + , getLostReason(hr) + , DXGI_ERROR_DEVICE_REMOVED == hr ? getLostReason(m_device->GetDeviceRemovedReason() ) : "no info" + ); } } @@ -2654,34 +2761,58 @@ BX_PRAGMA_DIAGNOSTIC_POP(); && (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_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(const VertexDecl& _vertexDecl, const ProgramD3D11& _program, uint16_t _numInstanceData) + void setInputLayout(uint8_t _numStreams, const VertexDecl** _vertexDecls, const ProgramD3D11& _program, uint16_t _numInstanceData) { - uint64_t layoutHash = (uint64_t(_vertexDecl.m_hash)<<32) | _program.m_vsh->m_hash; - layoutHash ^= _numInstanceData; + bx::HashMurmur2A murmur; + murmur.begin(); + murmur.add(_numInstanceData); + for (uint8_t stream = 0; stream < _numStreams; ++stream) + { + murmur.add(_vertexDecls[stream]->m_hash); + } + uint64_t layoutHash = (uint64_t(_program.m_vsh->m_hash)<<32) | murmur.end(); + ID3D11InputLayout* layout = m_inputLayoutCache.find(layoutHash); if (NULL == layout) { D3D11_INPUT_ELEMENT_DESC vertexElements[Attrib::Count+1+BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT]; + D3D11_INPUT_ELEMENT_DESC* elem = vertexElements; - VertexDecl decl; - bx::memCopy(&decl, &_vertexDecl, sizeof(VertexDecl) ); - const uint16_t* attrMask = _program.m_vsh->m_attrMask; + uint16_t attrMask[Attrib::Count]; + bx::memCopy(attrMask, _program.m_vsh->m_attrMask, sizeof(attrMask) ); - for (uint32_t ii = 0; ii < Attrib::Count; ++ii) + for (uint8_t stream = 0; stream < _numStreams; ++stream) { - uint16_t mask = attrMask[ii]; - uint16_t attr = (decl.m_attributes[ii] & mask); - decl.m_attributes[ii] = attr == 0 ? UINT16_MAX : attr == UINT16_MAX ? 0 : attr; + VertexDecl decl; + bx::memCopy(&decl, _vertexDecls[stream], sizeof(VertexDecl) ); + + const bool last = stream == _numStreams-1; + + for (uint32_t ii = 0; ii < Attrib::Count; ++ii) + { + uint16_t mask = attrMask[ii]; + uint16_t attr = (decl.m_attributes[ii] & mask); + if (0 == attr + || UINT16_MAX == attr) + { + decl.m_attributes[ii] = last ? ~attr : UINT16_MAX; + } + else + { + attrMask[ii] = 0; + } + } + + elem = fillVertexDecl(stream, elem, decl); } - D3D11_INPUT_ELEMENT_DESC* elem = fillVertexDecl(vertexElements, decl); 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 }; @@ -2695,7 +2826,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); for (jj = 0; jj < num; ++jj) { curr = &vertexElements[jj]; - if (0 == bx::strncmp(curr->SemanticName, "TEXCOORD") + if (0 == bx::strCmp(curr->SemanticName, "TEXCOORD") && curr->SemanticIndex == index) { break; @@ -2709,7 +2840,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } bx::memCopy(curr, &inst, sizeof(D3D11_INPUT_ELEMENT_DESC) ); - curr->InputSlot = 1; + curr->InputSlot = _numStreams; curr->SemanticIndex = index; curr->AlignedByteOffset = ii*16; } @@ -2727,6 +2858,12 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_deviceCtx->IASetInputLayout(layout); } + void setInputLayout(const VertexDecl& _vertexDecl, const ProgramD3D11& _program, uint16_t _numInstanceData) + { + const VertexDecl* decls[1] = { &_vertexDecl }; + setInputLayout(BX_COUNTOF(decls), decls, _program, _numInstanceData); + } + void setBlendState(uint64_t _state, uint32_t _rgba = 0) { _state &= BGFX_D3D11_BLEND_STATE_MASK; @@ -3021,7 +3158,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); sd.AddressU = s_textureAddress[(_flags&BGFX_TEXTURE_U_MASK)>>BGFX_TEXTURE_U_SHIFT]; sd.AddressV = s_textureAddress[(_flags&BGFX_TEXTURE_V_MASK)>>BGFX_TEXTURE_V_SHIFT]; sd.AddressW = s_textureAddress[(_flags&BGFX_TEXTURE_W_MASK)>>BGFX_TEXTURE_W_SHIFT]; - sd.MipLODBias = 0.0f; + sd.MipLODBias = float(BGFX_CONFIG_MIP_LOD_BIAS); sd.MaxAnisotropy = m_maxAnisotropy; sd.ComparisonFunc = 0 == cmpFunc ? D3D11_COMPARISON_NEVER : s_cmpFunc[cmpFunc]; sd.BorderColor[0] = _rgba[0]; @@ -3109,7 +3246,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); murmur.begin(); murmur.add(_handle); murmur.add(_mip); - murmur.add(0); + murmur.add(1); uint32_t hash = murmur.end(); IUnknown** ptr = m_srvUavLru.find(hash); @@ -3119,7 +3256,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); TextureD3D11& texture = m_textures[_handle.idx]; D3D11_UNORDERED_ACCESS_VIEW_DESC desc; - desc.Format = s_textureFormat[texture.m_textureFormat].m_fmtSrv; + desc.Format = texture.getSrvFormat(); switch (texture.m_type) { case TextureD3D11::Texture2D: @@ -3154,13 +3291,14 @@ BX_PRAGMA_DIAGNOSTIC_POP(); return uav; } - ID3D11ShaderResourceView* getCachedSrv(TextureHandle _handle, uint8_t _mip) + ID3D11ShaderResourceView* getCachedSrv(TextureHandle _handle, uint8_t _mip, bool _compute = false) { bx::HashMurmur2A murmur; murmur.begin(); murmur.add(_handle); murmur.add(_mip); murmur.add(0); + murmur.add(_compute); uint32_t hash = murmur.end(); IUnknown** ptr = m_srvUavLru.find(hash); @@ -3173,7 +3311,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); const bool msaaSample = 1 < msaa.Count && 0 != (texture.m_flags&BGFX_TEXTURE_MSAA_SAMPLE); D3D11_SHADER_RESOURCE_VIEW_DESC desc; - desc.Format = s_textureFormat[texture.m_textureFormat].m_fmtSrv; + desc.Format = texture.getSrvFormat(); switch (texture.m_type) { case TextureD3D11::Texture2D: @@ -3186,9 +3324,20 @@ BX_PRAGMA_DIAGNOSTIC_POP(); break; case TextureD3D11::TextureCube: - desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - desc.TextureCube.MostDetailedMip = _mip; - desc.TextureCube.MipLevels = 1; + if (_compute) + { + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; + desc.Texture2DArray.MostDetailedMip = _mip; + desc.Texture2DArray.MipLevels = 1; + desc.Texture2DArray.FirstArraySlice = 0; + desc.Texture2DArray.ArraySize = 6; + } + else + { + desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + desc.TextureCube.MostDetailedMip = _mip; + desc.TextureCube.MipLevels = 1; + } break; case TextureD3D11::Texture3D: @@ -3294,12 +3443,13 @@ BX_PRAGMA_DIAGNOSTIC_POP(); D3D11_MAPPED_SUBRESOURCE mapped; DX_CHECK(m_deviceCtx->Map(m_captureTexture, 0, D3D11_MAP_READ, 0, &mapped) ); - imageSwizzleBgra8( + bimg::imageSwizzleBgra8( mapped.pData + , mapped.RowPitch , getBufferWidth() , getBufferHeight() - , mapped.RowPitch , mapped.pData + , mapped.RowPitch ); g_callback->captureFrame(mapped.pData, getBufferHeight()*mapped.RowPitch); @@ -3537,6 +3687,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void* m_agsdll; AGSContext* m_ags; + NvApi m_nvapi; D3D_DRIVER_TYPE m_driverType; D3D_FEATURE_LEVEL m_featureLevel; @@ -3551,15 +3702,17 @@ BX_PRAGMA_DIAGNOSTIC_POP(); #endif // BX_PLATFORM_WINDOWS bool m_needPresent; - uint16_t m_lost; + bool m_lost; uint16_t m_numWindows; FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS]; - ID3D11Device* m_device; - ID3D11DeviceContext* m_deviceCtx; - ID3D11InfoQueue* m_infoQueue; - TimerQueryD3D11 m_gpuTimer; - OcclusionQueryD3D11 m_occlusionQuery; + ID3D11Device* m_device; + ID3D11DeviceContext* m_deviceCtx; + ID3DUserDefinedAnnotation* m_annotation; + ID3D11InfoQueue* m_infoQueue; + + TimerQueryD3D11 m_gpuTimer; + OcclusionQueryD3D11 m_occlusionQuery; uint32_t m_deviceInterfaceVersion; @@ -3673,6 +3826,23 @@ BX_PRAGMA_DIAGNOSTIC_POP(); agsDriverExtensions_MultiDrawIndexedInstancedIndirect(s_renderD3D11->m_ags, _numDrawIndirect, _ptr, _offset, _stride); } + int WINAPI d3d11Annotation_BeginEvent(DWORD _color, LPCWSTR _name) + { + BX_UNUSED(_color); + return s_renderD3D11->m_annotation->BeginEvent(_name); + } + + int WINAPI d3d11Annotation_EndEvent() + { + return s_renderD3D11->m_annotation->EndEvent(); + } + + void WINAPI d3d11Annotation_SetMarker(DWORD _color, LPCWSTR _name) + { + BX_UNUSED(_color); + s_renderD3D11->m_annotation->SetMarker(_name); + } + #if BGFX_CONFIG_USE_OVR VRImplOVRD3D11::VRImplOVRD3D11() @@ -3904,7 +4074,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); }; static const UavFormat s_uavFormat[] = - { // BGFX_BUFFER_COMPUTE_TYPE_UINT, BGFX_BUFFER_COMPUTE_TYPE_INT, BGFX_BUFFER_COMPUTE_TYPE_FLOAT + { // BGFX_BUFFER_COMPUTE_TYPE_INT, BGFX_BUFFER_COMPUTE_TYPE_UINT, BGFX_BUFFER_COMPUTE_TYPE_FLOAT { { DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN, DXGI_FORMAT_UNKNOWN }, 0 }, // ignored { { DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_UNKNOWN }, 1 }, // BGFX_BUFFER_COMPUTE_FORMAT_8x1 { { DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_UNKNOWN }, 2 }, // BGFX_BUFFER_COMPUTE_FORMAT_8x2 @@ -3982,6 +4152,11 @@ BX_PRAGMA_DIAGNOSTIC_POP(); ID3D11Device* device = s_renderD3D11->m_device; + D3D11_SUBRESOURCE_DATA srd; + srd.pSysMem = _data; + srd.SysMemPitch = 0; + srd.SysMemSlicePitch = 0; + if (needUav) { desc.Usage = D3D11_USAGE_DEFAULT; @@ -3989,7 +4164,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); desc.StructureByteStride = _stride; DX_CHECK(device->CreateBuffer(&desc - , NULL + , NULL == _data ? NULL : &srd , &m_ptr ) ); @@ -4006,24 +4181,38 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } else if (m_dynamic) { - desc.Usage = D3D11_USAGE_DYNAMIC; +#if USE_D3D11_STAGING_BUFFER + desc.Usage = D3D11_USAGE_DEFAULT; + desc.CPUAccessFlags = 0; + + DX_CHECK(device->CreateBuffer(&desc + , NULL + , &m_ptr + ) ); + + desc.BindFlags = 0; + desc.Usage = D3D11_USAGE_STAGING; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + + DX_CHECK(device->CreateBuffer(&desc + , NULL + , &m_staging + ) ); +#else + desc.Usage = D3D11_USAGE_DYNAMIC; desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; DX_CHECK(device->CreateBuffer(&desc , NULL , &m_ptr ) ); +#endif // USE_D3D11_STAGING_BUFFER } else { desc.Usage = D3D11_USAGE_IMMUTABLE; desc.CPUAccessFlags = 0; - D3D11_SUBRESOURCE_DATA srd; - srd.pSysMem = _data; - srd.SysMemPitch = 0; - srd.SysMemSlicePitch = 0; - DX_CHECK(device->CreateBuffer(&desc , &srd , &m_ptr @@ -4049,54 +4238,79 @@ BX_PRAGMA_DIAGNOSTIC_POP(); ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx; BX_CHECK(m_dynamic, "Must be dynamic!"); -#if 0 +#if USE_D3D11_STAGING_BUFFER BX_UNUSED(_discard); - D3D11_BUFFER_DESC desc; - desc.ByteWidth = _size; - desc.Usage = D3D11_USAGE_STAGING; - desc.BindFlags = 0; - desc.MiscFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - desc.StructureByteStride = 0; - - D3D11_SUBRESOURCE_DATA srd; - srd.pSysMem = _data; - srd.SysMemPitch = 0; - srd.SysMemSlicePitch = 0; - - D3D11_BOX srcBox; - srcBox.left = 0; - srcBox.top = 0; - srcBox.front = 0; - srcBox.right = _size; - srcBox.bottom = 1; - srcBox.back = 1; - ID3D11Device* device = s_renderD3D11->m_device; + D3D11_MAPPED_SUBRESOURCE mapped; + DX_CHECK(deviceCtx->Map(m_staging, 0, D3D11_MAP_WRITE, 0, &mapped) ); + bx::memCopy( (uint8_t*)mapped.pData + _offset, _data, _size); + deviceCtx->Unmap(m_staging, 0); - ID3D11Buffer* ptr; - DX_CHECK(device->CreateBuffer(&desc, &srd, &ptr) ); + D3D11_BOX box; + box.left = _offset; + box.top = 0; + box.front = 0; + box.right = _offset + _size; + box.bottom = 1; + box.back = 1; deviceCtx->CopySubresourceRegion(m_ptr , 0 , _offset , 0 , 0 - , ptr + , m_staging , 0 - , &srcBox + , &box ); - - DX_RELEASE(ptr, 0); #else - D3D11_MAPPED_SUBRESOURCE mapped; - D3D11_MAP type = _discard - ? D3D11_MAP_WRITE_DISCARD - : D3D11_MAP_WRITE_NO_OVERWRITE - ; - DX_CHECK(deviceCtx->Map(m_ptr, 0, type, 0, &mapped) ); - bx::memCopy( (uint8_t*)mapped.pData + _offset, _data, _size); - deviceCtx->Unmap(m_ptr, 0); + if (_discard) + { + D3D11_MAPPED_SUBRESOURCE mapped; + DX_CHECK(deviceCtx->Map(m_ptr, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped) ); + bx::memCopy( (uint8_t*)mapped.pData + _offset, _data, _size); + deviceCtx->Unmap(m_ptr, 0); + } + else + { + D3D11_BUFFER_DESC desc; + desc.ByteWidth = _size; + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.MiscFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + desc.StructureByteStride = 0; + + D3D11_SUBRESOURCE_DATA srd; + srd.pSysMem = _data; + srd.SysMemPitch = 0; + srd.SysMemSlicePitch = 0; + + D3D11_BOX srcBox; + srcBox.left = 0; + srcBox.top = 0; + srcBox.front = 0; + srcBox.right = _size; + srcBox.bottom = 1; + srcBox.back = 1; + + ID3D11Device* device = s_renderD3D11->m_device; + + ID3D11Buffer* ptr; + DX_CHECK(device->CreateBuffer(&desc, &srd, &ptr) ); + + deviceCtx->CopySubresourceRegion(m_ptr + , 0 + , _offset + , 0 + , 0 + , ptr + , 0 + , &srcBox + ); + + DX_RELEASE(ptr, 0); + } #endif // 0 } @@ -4257,7 +4471,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } - uint16_t shaderSize; + uint32_t shaderSize; bx::read(&reader, shaderSize); const void* code = reader.getDataPtr(); @@ -4271,7 +4485,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } else if (BGFX_CHUNK_MAGIC_VSH == magic) { - m_hash = bx::hashMurmur2A(code, shaderSize); + m_hash = bx::hash<bx::HashMurmur2A>(code, shaderSize); m_code = copy(code, shaderSize); DX_CHECK(s_renderD3D11->m_device->CreateVertexShader(code, shaderSize, NULL, &m_vertexShader) ); @@ -4319,14 +4533,14 @@ BX_PRAGMA_DIAGNOSTIC_POP(); void TextureD3D11::create(const Memory* _mem, uint32_t _flags, uint8_t _skip) { - ImageContainer imageContainer; + bimg::ImageContainer imageContainer; - if (imageParse(imageContainer, _mem->data, _mem->size) ) + if (bimg::imageParse(imageContainer, _mem->data, _mem->size) ) { uint8_t numMips = imageContainer.m_numMips; const uint8_t startLod = uint8_t(bx::uint32_min(_skip, numMips-1) ); numMips -= startLod; - const ImageBlockInfo& blockInfo = getBlockInfo(TextureFormat::Enum(imageContainer.m_format) ); + const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(imageContainer.m_format) ); const uint32_t textureWidth = bx::uint32_max(blockInfo.blockWidth, imageContainer.m_width >>startLod); const uint32_t textureHeight = bx::uint32_max(blockInfo.blockHeight, imageContainer.m_height>>startLod); const uint16_t numLayers = imageContainer.m_numLayers; @@ -4338,7 +4552,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_requestedFormat = uint8_t(imageContainer.m_format); m_textureFormat = uint8_t(getViableTextureFormat(imageContainer) ); const bool convert = m_textureFormat != m_requestedFormat; - const uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) ); + const uint8_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) ); if (imageContainer.m_cubeMap) { @@ -4361,7 +4575,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); uint32_t kk = 0; - const bool compressed = isCompressed(TextureFormat::Enum(m_textureFormat) ); + const bool compressed = bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) ); const bool swizzle = TextureFormat::BGRA8 == m_textureFormat && 0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE); BX_TRACE("Texture %3d: %s (requested: %s), layers %d, %dx%d%s%s%s." @@ -4388,8 +4602,8 @@ BX_PRAGMA_DIAGNOSTIC_POP(); height = bx::uint32_max(1, height); depth = bx::uint32_max(1, depth); - ImageMip mip; - if (imageGetRawData(imageContainer, side, lod+startLod, _mem->data, _mem->size, mip) ) + bimg::ImageMip mip; + if (bimg::imageGetRawData(imageContainer, side, lod+startLod, _mem->data, _mem->size, mip) ) { srd[kk].pSysMem = mip.m_data; @@ -4397,7 +4611,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { uint32_t srcpitch = mip.m_width*bpp/8; uint8_t* temp = (uint8_t*)BX_ALLOC(g_allocator, mip.m_width*mip.m_height*bpp/8); - imageDecodeToBgra8(temp, mip.m_data, mip.m_width, mip.m_height, srcpitch, mip.m_format); + bimg::imageDecodeToBgra8(temp, mip.m_data, mip.m_width, mip.m_height, srcpitch, mip.m_format); srd[kk].pSysMem = temp; srd[kk].SysMemPitch = srcpitch; @@ -4412,11 +4626,6 @@ BX_PRAGMA_DIAGNOSTIC_POP(); srd[kk].SysMemPitch = mip.m_width*mip.m_bpp/8; } - if (swizzle) - { -// imageSwizzleBgra8(temp, width, height, mip.m_width*4, data); - } - srd[kk].SysMemSlicePitch = mip.m_height*srd[kk].SysMemPitch; ++kk; } @@ -4430,7 +4639,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); const bool writeOnly = 0 != (m_flags&(BGFX_TEXTURE_RT_WRITE_ONLY|BGFX_TEXTURE_READ_BACK) ); const bool computeWrite = 0 != (m_flags&BGFX_TEXTURE_COMPUTE_WRITE); const bool renderTarget = 0 != (m_flags&BGFX_TEXTURE_RT_MASK); - const bool srgb = 0 != (m_flags&BGFX_TEXTURE_SRGB) || imageContainer.m_srgb; + const bool srgb = 0 != (m_flags&BGFX_TEXTURE_SRGB); const bool blit = 0 != (m_flags&BGFX_TEXTURE_BLIT_DST); const bool readBack = 0 != (m_flags&BGFX_TEXTURE_READ_BACK); const uint32_t msaaQuality = bx::uint32_satsub( (m_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT, 1); @@ -4466,7 +4675,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { // not swizzled and not sRGB, or sRGB unsupported format = s_textureFormat[m_textureFormat].m_fmt; - srvd.Format = s_textureFormat[m_textureFormat].m_fmtSrv; + srvd.Format = getSrvFormat(); } switch (m_type) @@ -4486,7 +4695,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); desc.CPUAccessFlags = 0; desc.MiscFlags = 0; - if (isDepth( (TextureFormat::Enum)m_textureFormat) ) + if (bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) ) { desc.BindFlags |= D3D11_BIND_DEPTH_STENCIL; desc.Usage = D3D11_USAGE_DEFAULT; @@ -4684,7 +4893,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } const uint32_t subres = _mip + ( (layer + _side) * m_numMips); - const uint32_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) ); + const uint32_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) ); const uint32_t rectpitch = _rect.m_width*bpp/8; const uint32_t srcpitch = UINT16_MAX == _pitch ? rectpitch : _pitch; const uint32_t slicepitch = rectpitch*_rect.m_height; @@ -4697,7 +4906,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (convert) { temp = (uint8_t*)BX_ALLOC(g_allocator, slicepitch); - imageDecodeToBgra8(temp, data, _rect.m_width, _rect.m_height, srcpitch, TextureFormat::Enum(m_requestedFormat) ); + bimg::imageDecodeToBgra8(temp, data, _rect.m_width, _rect.m_height, srcpitch, bimg::TextureFormat::Enum(m_requestedFormat) ); data = temp; } @@ -4754,6 +4963,19 @@ BX_PRAGMA_DIAGNOSTIC_POP(); return handle; } + DXGI_FORMAT TextureD3D11::getSrvFormat() const + { + if (bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) ) + { + return s_textureFormat[m_textureFormat].m_fmtSrv; + } + + return 0 != (m_flags&BGFX_TEXTURE_SRGB) + ? s_textureFormat[m_textureFormat].m_fmtSrgb + : s_textureFormat[m_textureFormat].m_fmt + ; + } + void FrameBufferD3D11::create(uint8_t _num, const Attachment* _attachment) { for (uint32_t ii = 0; ii < BX_COUNTOF(m_rtv); ++ii) @@ -4793,7 +5015,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); DX_CHECK(device->CreateRenderTargetView(ptr, NULL, &m_rtv[0]) ); DX_RELEASE(ptr, 0); - DXGI_FORMAT fmtDsv = isDepth(_depthFormat) + DXGI_FORMAT fmtDsv = bimg::isDepth(bimg::TextureFormat::Enum(_depthFormat) ) ? s_textureFormat[_depthFormat].m_fmtDsv : DXGI_FORMAT_D24_UNORM_S8_UINT ; @@ -4893,7 +5115,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); const uint32_t msaaQuality = bx::uint32_satsub( (texture.m_flags&BGFX_TEXTURE_RT_MSAA_MASK)>>BGFX_TEXTURE_RT_MSAA_SHIFT, 1); const DXGI_SAMPLE_DESC& msaa = s_msaa[msaaQuality]; - if (isDepth( (TextureFormat::Enum)texture.m_textureFormat) ) + if (bimg::isDepth(bimg::TextureFormat::Enum(texture.m_textureFormat) ) ) { BX_CHECK(NULL == m_dsv, "Frame buffer already has depth-stencil attached."); @@ -4943,62 +5165,52 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } else { + D3D11_RENDER_TARGET_VIEW_DESC desc; + desc.Format = texture.getSrvFormat(); switch (texture.m_type) { default: case TextureD3D11::Texture2D: + if (1 < msaa.Count) { - D3D11_RENDER_TARGET_VIEW_DESC desc; - desc.Format = s_textureFormat[texture.m_textureFormat].m_fmt; - if (1 < msaa.Count) - { - desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; - } - else - { - desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - desc.Texture2D.MipSlice = m_attachment[ii].mip; - } - - DX_CHECK(s_renderD3D11->m_device->CreateRenderTargetView( - NULL == texture.m_rt ? texture.m_ptr : texture.m_rt - , &desc - , &m_rtv[m_num] - ) ); + desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; } + else + { + desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + desc.Texture2D.MipSlice = m_attachment[ii].mip; + } + + DX_CHECK(s_renderD3D11->m_device->CreateRenderTargetView( + NULL == texture.m_rt ? texture.m_ptr : texture.m_rt + , &desc + , &m_rtv[m_num] + ) ); break; case TextureD3D11::TextureCube: + if (1 < msaa.Count) { - D3D11_RENDER_TARGET_VIEW_DESC desc; - desc.Format = s_textureFormat[texture.m_textureFormat].m_fmt; - if (1 < msaa.Count) - { - desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; - desc.Texture2DMSArray.ArraySize = 1; - desc.Texture2DMSArray.FirstArraySlice = m_attachment[ii].layer; - } - else - { - desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - desc.Texture2DArray.ArraySize = 1; - desc.Texture2DArray.FirstArraySlice = m_attachment[ii].layer; - desc.Texture2DArray.MipSlice = m_attachment[ii].mip; - } - DX_CHECK(s_renderD3D11->m_device->CreateRenderTargetView(texture.m_ptr, &desc, &m_rtv[m_num]) ); + desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; + desc.Texture2DMSArray.ArraySize = 1; + desc.Texture2DMSArray.FirstArraySlice = m_attachment[ii].layer; } + else + { + desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + desc.Texture2DArray.ArraySize = 1; + desc.Texture2DArray.FirstArraySlice = m_attachment[ii].layer; + desc.Texture2DArray.MipSlice = m_attachment[ii].mip; + } + DX_CHECK(s_renderD3D11->m_device->CreateRenderTargetView(texture.m_ptr, &desc, &m_rtv[m_num]) ); break; case TextureD3D11::Texture3D: - { - D3D11_RENDER_TARGET_VIEW_DESC desc; - desc.Format = s_textureFormat[texture.m_textureFormat].m_fmt; - desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; - desc.Texture3D.MipSlice = m_attachment[ii].mip; - desc.Texture3D.WSize = 1; - desc.Texture3D.FirstWSlice = m_attachment[ii].layer; - DX_CHECK(s_renderD3D11->m_device->CreateRenderTargetView(texture.m_ptr, &desc, &m_rtv[m_num]) ); - } + desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D; + desc.Texture3D.MipSlice = m_attachment[ii].mip; + desc.Texture3D.WSize = 1; + desc.Texture3D.FirstWSlice = m_attachment[ii].layer; + DX_CHECK(s_renderD3D11->m_device->CreateRenderTargetView(texture.m_ptr, &desc, &m_rtv[m_num]) ); break; } @@ -5098,68 +5310,94 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { ID3D11Device* device = s_renderD3D11->m_device; - D3D11_QUERY_DESC query; - query.MiscFlags = 0; - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frame); ++ii) + D3D11_QUERY_DESC qd; + qd.MiscFlags = 0; + for (uint32_t ii = 0; ii < BX_COUNTOF(m_query); ++ii) { - Frame& frame = m_frame[ii]; + Query& query = m_query[ii]; + query.m_ready = false; - query.Query = D3D11_QUERY_TIMESTAMP_DISJOINT; - DX_CHECK(device->CreateQuery(&query, &frame.m_disjoint) ); + qd.Query = D3D11_QUERY_TIMESTAMP_DISJOINT; + DX_CHECK(device->CreateQuery(&qd, &query.m_disjoint) ); + + qd.Query = D3D11_QUERY_TIMESTAMP; + DX_CHECK(device->CreateQuery(&qd, &query.m_begin) ); + DX_CHECK(device->CreateQuery(&qd, &query.m_end) ); + } - query.Query = D3D11_QUERY_TIMESTAMP; - DX_CHECK(device->CreateQuery(&query, &frame.m_begin) ); - DX_CHECK(device->CreateQuery(&query, &frame.m_end) ); + for (uint32_t ii = 0; ii < BX_COUNTOF(m_result); ++ii) + { + Result& result = m_result[ii]; + result.reset(); } - m_elapsed = 0; - m_frequency = 1; m_control.reset(); } void TimerQueryD3D11::preReset() { - for (uint32_t ii = 0; ii < BX_COUNTOF(m_frame); ++ii) + for (uint32_t ii = 0; ii < BX_COUNTOF(m_query); ++ii) { - Frame& frame = m_frame[ii]; - DX_RELEASE(frame.m_disjoint, 0); - DX_RELEASE(frame.m_begin, 0); - DX_RELEASE(frame.m_end, 0); + Query& query = m_query[ii]; + DX_RELEASE(query.m_disjoint, 0); + DX_RELEASE(query.m_begin, 0); + DX_RELEASE(query.m_end, 0); } } - void TimerQueryD3D11::begin() + uint32_t TimerQueryD3D11::begin(uint32_t _resultIdx) { ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx; while (0 == m_control.reserve(1) ) { - get(); + update(); } - Frame& frame = m_frame[m_control.m_current]; - deviceCtx->Begin(frame.m_disjoint); - deviceCtx->End(frame.m_begin); + Result& result = m_result[_resultIdx]; + ++result.m_pending; + + const uint32_t idx = m_control.m_current; + Query& query = m_query[idx]; + query.m_resultIdx = _resultIdx; + query.m_ready = false; + + deviceCtx->Begin(query.m_disjoint); + deviceCtx->End(query.m_begin); + + m_control.commit(1); + + return idx; } - void TimerQueryD3D11::end() + void TimerQueryD3D11::end(uint32_t _idx) { ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx; - Frame& frame = m_frame[m_control.m_current]; - deviceCtx->End(frame.m_end); - deviceCtx->End(frame.m_disjoint); - m_control.commit(1); + Query& query = m_query[_idx]; + query.m_ready = true; + + deviceCtx->End(query.m_end); + deviceCtx->End(query.m_disjoint); + + while (update() ) + { + } } - bool TimerQueryD3D11::get() + bool TimerQueryD3D11::update() { if (0 != m_control.available() ) { - ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx; - Frame& frame = m_frame[m_control.m_read]; + Query& query = m_query[m_control.m_read]; + + if (!query.m_ready) + { + return false; + } uint64_t timeEnd; - HRESULT hr = deviceCtx->GetData(frame.m_end, &timeEnd, sizeof(timeEnd), D3D11_ASYNC_GETDATA_DONOTFLUSH); + ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx; + HRESULT hr = deviceCtx->GetData(query.m_end, &timeEnd, sizeof(timeEnd), D3D11_ASYNC_GETDATA_DONOTFLUSH); if (S_OK == hr || isLost(hr) ) { @@ -5172,15 +5410,17 @@ BX_PRAGMA_DIAGNOSTIC_POP(); }; D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint; - deviceCtx->GetData(frame.m_disjoint, &disjoint, sizeof(disjoint), 0); + DX_CHECK(deviceCtx->GetData(query.m_disjoint, &disjoint, sizeof(disjoint), 0) ); uint64_t timeBegin; - deviceCtx->GetData(frame.m_begin, &timeBegin, sizeof(timeBegin), 0); + DX_CHECK(deviceCtx->GetData(query.m_begin, &timeBegin, sizeof(timeBegin), 0) ); - m_frequency = disjoint.Frequency; - m_begin = timeBegin; - m_end = timeEnd; - m_elapsed = timeEnd - timeBegin; + Result& result = m_result[query.m_resultIdx]; + --result.m_pending; + + result.m_frequency = disjoint.Frequency; + result.m_begin = timeBegin; + result.m_end = timeEnd; return true; } @@ -5266,14 +5506,94 @@ BX_PRAGMA_DIAGNOSTIC_POP(); Query& query = m_query[(m_control.m_read + ii) % size]; if (query.m_handle.idx == _handle.idx) { - query.m_handle.idx = bgfx::invalidHandle; + query.m_handle.idx = bgfx::kInvalidHandle; + } + } + } + + void RendererContextD3D11::submitBlit(BlitState& _bs, uint16_t _view) + { + ID3D11DeviceContext* deviceCtx = m_deviceCtx; + + while (_bs.hasItem(_view) ) + { + const BlitItem& blit = _bs.advance(); + + const TextureD3D11& src = m_textures[blit.m_src.idx]; + const TextureD3D11& dst = m_textures[blit.m_dst.idx]; + + uint32_t srcWidth = bx::uint32_min(src.m_width, blit.m_srcX + blit.m_width) - blit.m_srcX; + uint32_t srcHeight = bx::uint32_min(src.m_height, blit.m_srcY + blit.m_height) - blit.m_srcY; + uint32_t srcDepth = bx::uint32_min(src.m_depth, blit.m_srcZ + blit.m_depth) - blit.m_srcZ; + uint32_t dstWidth = bx::uint32_min(dst.m_width, blit.m_dstX + blit.m_width) - blit.m_dstX; + uint32_t dstHeight = bx::uint32_min(dst.m_height, blit.m_dstY + blit.m_height) - blit.m_dstY; + uint32_t dstDepth = bx::uint32_min(dst.m_depth, blit.m_dstZ + blit.m_depth) - blit.m_dstZ; + uint32_t width = bx::uint32_min(srcWidth, dstWidth); + uint32_t height = bx::uint32_min(srcHeight, dstHeight); + uint32_t depth = bx::uint32_min(srcDepth, dstDepth); + + if (TextureD3D11::Texture3D == src.m_type) + { + D3D11_BOX box; + box.left = blit.m_srcX; + box.top = blit.m_srcY; + box.front = blit.m_srcZ; + box.right = blit.m_srcX + width; + box.bottom = blit.m_srcY + height;; + box.back = blit.m_srcZ + bx::uint32_imax(1, depth); + + deviceCtx->CopySubresourceRegion(dst.m_ptr + , blit.m_dstMip + , blit.m_dstX + , blit.m_dstY + , blit.m_dstZ + , src.m_ptr + , blit.m_srcMip + , &box + ); + } + else + { + bool depthStencil = bimg::isDepth(bimg::TextureFormat::Enum(src.m_textureFormat) ); + BX_CHECK(!depthStencil + || (width == src.m_width && height == src.m_height) + , "When blitting depthstencil surface, source resolution must match destination." + ); + + D3D11_BOX box; + box.left = blit.m_srcX; + box.top = blit.m_srcY; + box.front = 0; + box.right = blit.m_srcX + width; + box.bottom = blit.m_srcY + height; + box.back = 1; + + const uint32_t srcZ = TextureD3D11::TextureCube == src.m_type + ? blit.m_srcZ + : 0 + ; + const uint32_t dstZ = TextureD3D11::TextureCube == dst.m_type + ? blit.m_dstZ + : 0 + ; + + deviceCtx->CopySubresourceRegion(dst.m_ptr + , dstZ*dst.m_numMips+blit.m_dstMip + , blit.m_dstX + , blit.m_dstY + , 0 + , src.m_ptr + , srcZ*src.m_numMips+blit.m_srcMip + , depthStencil ? NULL : &box + ); } } } void RendererContextD3D11::submit(Frame* _render, ClearQuad& _clearQuad, TextVideoMemBlitter& _textVideoMemBlitter) { - if (updateResolution(_render->m_resolution) ) + if (m_lost + || updateResolution(_render->m_resolution) ) { return; } @@ -5284,16 +5604,17 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } PIX_BEGINEVENT(D3DCOLOR_FRAME, L"rendererSubmit"); - BGFX_GPU_PROFILER_BEGIN_DYNAMIC("rendererSubmit"); ID3D11DeviceContext* deviceCtx = m_deviceCtx; - int64_t elapsed = -bx::getHPCounter(); + int64_t timeBegin = bx::getHPCounter(); int64_t captureElapsed = 0; + uint32_t frameQueryIdx = UINT32_MAX; + if (m_timerQuerySupport) { - m_gpuTimer.begin(); + frameQueryIdx = m_gpuTimer.begin(BGFX_CONFIG_MAX_VIEWS); } if (0 < _render->m_iboffset) @@ -5315,6 +5636,9 @@ BX_PRAGMA_DIAGNOSTIC_POP(); currentState.m_stateFlags = BGFX_STATE_NONE; currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE); + RenderBind currentBind; + currentBind.clear(); + _render->m_hmdInitialized = m_ovr.isInitialized(); const bool hmdEnabled = m_ovr.isEnabled(); @@ -5325,15 +5649,12 @@ BX_PRAGMA_DIAGNOSTIC_POP(); bool scissorEnabled = false; setDebugWireframe(wireframe); - uint16_t programIdx = invalidHandle; + uint16_t programIdx = kInvalidHandle; SortKey key; uint16_t view = UINT16_MAX; FrameBufferHandle fbh = { BGFX_CONFIG_MAX_FRAME_BUFFERS }; - BlitKey blitKey; - blitKey.decode(_render->m_blitKeys[0]); - uint16_t numBlitItems = _render->m_numBlitItems; - uint16_t blitItem = 0; + BlitState bs(_render); const uint64_t primType = _render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0; uint8_t primIndex = uint8_t(primType >> BGFX_STATE_PT_SHIFT); @@ -5352,6 +5673,13 @@ BX_PRAGMA_DIAGNOSTIC_POP(); uint32_t statsNumIndices = 0; uint32_t statsKeyType[2] = {}; + Profiler<TimerQueryD3D11> profiler( + _render + , m_gpuTimer + , s_viewName + , m_timerQuerySupport + ); + m_occlusionQuery.resolve(_render); if (0 == (_render->m_debug&BGFX_DEBUG_IFH) ) @@ -5364,9 +5692,9 @@ BX_PRAGMA_DIAGNOSTIC_POP(); bool viewRestart = false; uint8_t eye = 0; uint8_t restartState = 0; - viewState.m_rect = _render->m_rect[0]; + viewState.m_rect = _render->m_view[0].m_rect; - int32_t numItems = _render->m_num; + int32_t numItems = _render->m_numRenderItems; for (int32_t item = 0, restartItem = numItems; item < numItems || restartItem < numItems;) { const uint64_t encodedKey = _render->m_sortKeys[item]; @@ -5378,7 +5706,9 @@ BX_PRAGMA_DIAGNOSTIC_POP(); || item == numItems ; - const RenderItem& renderItem = _render->m_renderItem[_render->m_sortValues[item] ]; + const uint32_t itemIdx = _render->m_sortValues[item]; + const RenderItem& renderItem = _render->m_renderItem[itemIdx]; + const RenderBind& renderBind = _render->m_renderItemBind[itemIdx]; ++item; if (viewChanged) @@ -5393,15 +5723,15 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } view = key.m_view; - programIdx = invalidHandle; + programIdx = kInvalidHandle; - if (_render->m_fb[view].idx != fbh.idx) + if (_render->m_view[view].m_fbh.idx != fbh.idx) { - fbh = _render->m_fb[view]; + fbh = _render->m_view[view].m_fbh; setFrameBuffer(fbh); } - viewRestart = ( (BGFX_VIEW_STEREO == (_render->m_viewFlags[view] & BGFX_VIEW_STEREO) ) ); + viewRestart = ( (BGFX_VIEW_STEREO == (_render->m_view[view].m_flags & BGFX_VIEW_STEREO) ) ); viewRestart &= hmdEnabled; if (viewRestart) { @@ -5422,13 +5752,12 @@ BX_PRAGMA_DIAGNOSTIC_POP(); PIX_ENDEVENT(); if (item > 1) { - BGFX_GPU_PROFILER_END(); - BGFX_PROFILER_END(); + profiler.end(); } - BGFX_PROFILER_BEGIN_DYNAMIC(s_viewName[view]); - BGFX_GPU_PROFILER_BEGIN_DYNAMIC(s_viewName[view]); - viewState.m_rect = _render->m_rect[view]; + profiler.begin(view); + + viewState.m_rect = _render->m_view[view].m_rect; if (viewRestart) { if (BX_ENABLED(BGFX_CONFIG_DEBUG_PIX) ) @@ -5464,7 +5793,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } - const Rect& scissorRect = _render->m_scissor[view]; + const Rect& scissorRect = _render->m_view[view].m_scissor; viewHasScissor = !scissorRect.isZero(); viewScissorRect = viewHasScissor ? scissorRect : viewState.m_rect; @@ -5476,7 +5805,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); vp.MinDepth = 0.0f; vp.MaxDepth = 1.0f; deviceCtx->RSSetViewports(1, &vp); - Clear& clr = _render->m_clear[view]; + Clear& clr = _render->m_view[view].m_clear; if (BGFX_CLEAR_NONE != (clr.m_flags & BGFX_CLEAR_MASK) ) { @@ -5484,81 +5813,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); prim = s_primInfo[BX_COUNTOF(s_primName)]; // Force primitive type update after clear quad. } - const uint8_t blitView = SortKey::decodeView(encodedKey); - for (; blitItem < numBlitItems && blitKey.m_view <= blitView; blitItem++) - { - const BlitItem& blit = _render->m_blitItem[blitItem]; - blitKey.decode(_render->m_blitKeys[blitItem+1]); - - const TextureD3D11& src = m_textures[blit.m_src.idx]; - const TextureD3D11& dst = m_textures[blit.m_dst.idx]; - - uint32_t srcWidth = bx::uint32_min(src.m_width, blit.m_srcX + blit.m_width) - blit.m_srcX; - uint32_t srcHeight = bx::uint32_min(src.m_height, blit.m_srcY + blit.m_height) - blit.m_srcY; - uint32_t srcDepth = bx::uint32_min(src.m_depth, blit.m_srcZ + blit.m_depth) - blit.m_srcZ; - uint32_t dstWidth = bx::uint32_min(dst.m_width, blit.m_dstX + blit.m_width) - blit.m_dstX; - uint32_t dstHeight = bx::uint32_min(dst.m_height, blit.m_dstY + blit.m_height) - blit.m_dstY; - uint32_t dstDepth = bx::uint32_min(dst.m_depth, blit.m_dstZ + blit.m_depth) - blit.m_dstZ; - uint32_t width = bx::uint32_min(srcWidth, dstWidth); - uint32_t height = bx::uint32_min(srcHeight, dstHeight); - uint32_t depth = bx::uint32_min(srcDepth, dstDepth); - - if (TextureD3D11::Texture3D == src.m_type) - { - D3D11_BOX box; - box.left = blit.m_srcX; - box.top = blit.m_srcY; - box.front = blit.m_srcZ; - box.right = blit.m_srcX + width; - box.bottom = blit.m_srcY + height;; - box.back = blit.m_srcZ + bx::uint32_imax(1, depth); - - deviceCtx->CopySubresourceRegion(dst.m_ptr - , blit.m_dstMip - , blit.m_dstX - , blit.m_dstY - , blit.m_dstZ - , src.m_ptr - , blit.m_srcMip - , &box - ); - } - else - { - bool depthStencil = isDepth(TextureFormat::Enum(src.m_textureFormat) ); - BX_CHECK(!depthStencil - || (width == src.m_width && height == src.m_height) - , "When blitting depthstencil surface, source resolution must match destination." - ); - - D3D11_BOX box; - box.left = blit.m_srcX; - box.top = blit.m_srcY; - box.front = 0; - box.right = blit.m_srcX + width; - box.bottom = blit.m_srcY + height; - box.back = 1; - - const uint32_t srcZ = TextureD3D11::TextureCube == src.m_type - ? blit.m_srcZ - : 0 - ; - const uint32_t dstZ = TextureD3D11::TextureCube == dst.m_type - ? blit.m_dstZ - : 0 - ; - - deviceCtx->CopySubresourceRegion(dst.m_ptr - , dstZ*dst.m_numMips+blit.m_dstMip - , blit.m_dstX - , blit.m_dstY - , 0 - , src.m_ptr - , srcZ*src.m_numMips+blit.m_srcMip - , depthStencil ? NULL : &box - ); - } - } + submitBlit(bs, view); } if (isCompute) @@ -5594,8 +5849,8 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } bool programChanged = false; - bool constantsChanged = compute.m_constBegin < compute.m_constEnd; - rendererUpdateUniforms(this, _render->m_uniformBuffer, compute.m_constBegin, compute.m_constEnd); + bool constantsChanged = compute.m_uniformBegin < compute.m_uniformEnd; + rendererUpdateUniforms(this, _render->m_uniformBuffer[compute.m_uniformIdx], compute.m_uniformBegin, compute.m_uniformEnd); if (key.m_program != programIdx) { @@ -5611,7 +5866,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); constantsChanged = true; } - if (invalidHandle != programIdx) + if (kInvalidHandle != programIdx) { ProgramD3D11& program = m_program[programIdx]; @@ -5639,12 +5894,13 @@ BX_PRAGMA_DIAGNOSTIC_POP(); for (uint32_t ii = 0; ii < BGFX_MAX_COMPUTE_BINDINGS; ++ii) { - const Binding& bind = compute.m_bind[ii]; - if (invalidHandle != bind.m_idx) + const Binding& bind = renderBind.m_bind[ii]; + if (kInvalidHandle != bind.m_idx) { switch (bind.m_type) { case Binding::Image: + case Binding::Texture: { TextureD3D11& texture = m_textures[bind.m_idx]; if (Access::Read != bind.m_un.m_compute.m_access) @@ -5656,10 +5912,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } else { - srv[ii] = 0 == bind.m_un.m_compute.m_mip - ? texture.m_srv - : s_renderD3D11->getCachedSrv(texture.getHandle(), bind.m_un.m_compute.m_mip) - ; + srv[ii] = s_renderD3D11->getCachedSrv(texture.getHandle(), bind.m_un.m_compute.m_mip, true); sampler[ii] = s_renderD3D11->getSamplerState(texture.m_flags, NULL); } } @@ -5727,7 +5980,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); PIX_BEGINEVENT(D3DCOLOR_DRAW, viewNameW); } - programIdx = invalidHandle; + programIdx = kInvalidHandle; m_currentProgram = NULL; invalidateCompute(); @@ -5764,6 +6017,8 @@ BX_PRAGMA_DIAGNOSTIC_POP(); currentState.m_stateFlags = newFlags; currentState.m_stencil = newStencil; + currentBind.clear(); + setBlendState(newFlags); setDepthStencilState(newFlags, packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT) ); @@ -5798,7 +6053,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); else { Rect scissorRect; - scissorRect.setIntersect(viewScissorRect, _render->m_rectCache.m_cache[scissor]); + scissorRect.setIntersect(viewScissorRect, _render->m_frameCache.m_rectCache.m_cache[scissor]); if (scissorRect.isZeroArea() ) { continue; @@ -5863,14 +6118,14 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } bool programChanged = false; - bool constantsChanged = draw.m_constBegin < draw.m_constEnd; - rendererUpdateUniforms(this, _render->m_uniformBuffer, draw.m_constBegin, draw.m_constEnd); + bool constantsChanged = draw.m_uniformBegin < draw.m_uniformEnd; + rendererUpdateUniforms(this, _render->m_uniformBuffer[draw.m_uniformIdx], draw.m_uniformBegin, draw.m_uniformEnd); if (key.m_program != programIdx) { programIdx = key.m_program; - if (invalidHandle == programIdx) + if (kInvalidHandle == programIdx) { m_currentProgram = NULL; @@ -5903,7 +6158,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); constantsChanged = true; } - if (invalidHandle != programIdx) + if (kInvalidHandle != programIdx) { ProgramD3D11& program = m_program[programIdx]; @@ -5935,16 +6190,36 @@ BX_PRAGMA_DIAGNOSTIC_POP(); uint32_t changes = 0; for (uint8_t stage = 0; stage < BGFX_CONFIG_MAX_TEXTURE_SAMPLERS; ++stage) { - const Binding& bind = draw.m_bind[stage]; - Binding& current = currentState.m_bind[stage]; + const Binding& bind = renderBind.m_bind[stage]; + Binding& current = currentBind.m_bind[stage]; if (current.m_idx != bind.m_idx + || current.m_type != bind.m_type || current.m_un.m_draw.m_textureFlags != bind.m_un.m_draw.m_textureFlags || programChanged) { - if (invalidHandle != bind.m_idx) + if (kInvalidHandle != bind.m_idx) { - TextureD3D11& texture = m_textures[bind.m_idx]; - texture.commit(stage, bind.m_un.m_draw.m_textureFlags, _render->m_colorPalette); + switch (bind.m_type) + { + case Binding::Texture: + { + TextureD3D11& texture = m_textures[bind.m_idx]; + texture.commit(stage, bind.m_un.m_draw.m_textureFlags, _render->m_colorPalette); + } + break; + + case Binding::IndexBuffer: + case Binding::VertexBuffer: + { + const BufferD3D11& buffer = Binding::IndexBuffer == bind.m_type + ? m_indexBuffers[bind.m_idx] + : m_vertexBuffers[bind.m_idx] + ; + m_textureStage.m_srv[stage] = buffer.m_srv; + m_textureStage.m_sampler[stage] = NULL; + } + break; + } } else { @@ -5964,43 +6239,70 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } + bool vertexStreamChanged = hasVertexStreamChanged(currentState, draw); + if (programChanged - || currentState.m_streamMask != draw.m_streamMask - || currentState.m_stream[0].m_decl.idx != draw.m_stream[0].m_decl.idx - || currentState.m_stream[0].m_handle.idx != draw.m_stream[0].m_handle.idx - || currentState.m_instanceDataBuffer.idx != draw.m_instanceDataBuffer.idx - || currentState.m_instanceDataOffset != draw.m_instanceDataOffset - || currentState.m_instanceDataStride != draw.m_instanceDataStride) + || vertexStreamChanged) { currentState.m_streamMask = draw.m_streamMask; - currentState.m_stream[0].m_decl = draw.m_stream[0].m_decl; - currentState.m_stream[0].m_handle = draw.m_stream[0].m_handle; currentState.m_instanceDataBuffer.idx = draw.m_instanceDataBuffer.idx; currentState.m_instanceDataOffset = draw.m_instanceDataOffset; currentState.m_instanceDataStride = draw.m_instanceDataStride; - uint16_t handle = draw.m_stream[0].m_handle.idx; - if (invalidHandle != handle) + ID3D11Buffer* buffers[BGFX_CONFIG_MAX_VERTEX_STREAMS]; + uint32_t strides[BGFX_CONFIG_MAX_VERTEX_STREAMS]; + uint32_t offsets[BGFX_CONFIG_MAX_VERTEX_STREAMS]; + const VertexDecl* decls[BGFX_CONFIG_MAX_VERTEX_STREAMS]; + + uint32_t numVertices = draw.m_numVertices; + uint8_t numStreams = 0; + for (uint32_t idx = 0, streamMask = draw.m_streamMask, ntz = bx::uint32_cnttz(streamMask) + ; 0 != streamMask + ; streamMask >>= 1, idx += 1, ntz = bx::uint32_cnttz(streamMask), ++numStreams + ) { - const VertexBufferD3D11& vb = m_vertexBuffers[handle]; + streamMask >>= ntz; + idx += ntz; + + currentState.m_stream[idx].m_decl = draw.m_stream[idx].m_decl; + currentState.m_stream[idx].m_handle = draw.m_stream[idx].m_handle; + currentState.m_stream[idx].m_startVertex = draw.m_stream[idx].m_startVertex; - uint16_t decl = !isValid(vb.m_decl) ? draw.m_stream[0].m_decl.idx : vb.m_decl.idx; + uint16_t handle = draw.m_stream[idx].m_handle.idx; + const VertexBufferD3D11& vb = m_vertexBuffers[handle]; + uint16_t decl = !isValid(vb.m_decl) ? draw.m_stream[idx].m_decl.idx : vb.m_decl.idx; const VertexDecl& vertexDecl = m_vertexDecls[decl]; uint32_t stride = vertexDecl.m_stride; - uint32_t offset = 0; - deviceCtx->IASetVertexBuffers(0, 1, &vb.m_ptr, &stride, &offset); + + buffers[numStreams] = vb.m_ptr; + strides[numStreams] = stride; + offsets[numStreams] = draw.m_stream[idx].m_startVertex * stride; + decls[numStreams] = &vertexDecl; + + numVertices = bx::uint32_min(UINT32_MAX == draw.m_numVertices + ? vb.m_size/stride + : draw.m_numVertices + , numVertices + ); + } + + currentState.m_numVertices = numVertices; + + if (0 < numStreams) + { + deviceCtx->IASetVertexBuffers(0, numStreams, buffers, strides, offsets); if (isValid(draw.m_instanceDataBuffer) ) { const VertexBufferD3D11& inst = m_vertexBuffers[draw.m_instanceDataBuffer.idx]; uint32_t instStride = draw.m_instanceDataStride; - deviceCtx->IASetVertexBuffers(1, 1, &inst.m_ptr, &instStride, &draw.m_instanceDataOffset); - setInputLayout(vertexDecl, m_program[programIdx], draw.m_instanceDataStride/16); + deviceCtx->IASetVertexBuffers(numStreams, 1, &inst.m_ptr, &instStride, &draw.m_instanceDataOffset); + setInputLayout(numStreams, decls, m_program[programIdx], draw.m_instanceDataStride/16); } else { - deviceCtx->IASetVertexBuffers(1, 1, s_zero.m_buffer, s_zero.m_zero, s_zero.m_zero); - setInputLayout(vertexDecl, m_program[programIdx], 0); + deviceCtx->IASetVertexBuffers(numStreams, 1, s_zero.m_buffer, s_zero.m_zero, s_zero.m_zero); + setInputLayout(numStreams, decls, m_program[programIdx], 0); } } else @@ -6014,7 +6316,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); currentState.m_indexBuffer = draw.m_indexBuffer; uint16_t handle = draw.m_indexBuffer.idx; - if (invalidHandle != handle) + if (kInvalidHandle != handle) { const IndexBufferD3D11& ib = m_indexBuffers[handle]; deviceCtx->IASetIndexBuffer(ib.m_ptr @@ -6030,15 +6332,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); if (0 != currentState.m_streamMask) { - uint32_t numVertices = draw.m_numVertices; - if (UINT32_MAX == numVertices) - { - const VertexBufferD3D11& vb = m_vertexBuffers[currentState.m_stream[0].m_handle.idx]; - uint16_t decl = !isValid(vb.m_decl) ? draw.m_stream[0].m_decl.idx : vb.m_decl.idx; - const VertexDecl& vertexDecl = m_vertexDecls[decl]; - numVertices = vb.m_size/vertexDecl.m_stride; - } - + uint32_t numVertices = currentState.m_numVertices; uint32_t numIndices = 0; uint32_t numPrimsSubmitted = 0; uint32_t numInstances = 0; @@ -6100,7 +6394,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); deviceCtx->DrawIndexedInstanced(numIndices , draw.m_numInstances , 0 - , draw.m_stream[0].m_startVertex + , 0 , 0 ); } @@ -6108,7 +6402,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { deviceCtx->DrawIndexed(numIndices , 0 - , draw.m_stream[0].m_startVertex + , 0 ); } } @@ -6124,7 +6418,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); deviceCtx->DrawIndexedInstanced(numIndices , draw.m_numInstances , draw.m_startIndex - , draw.m_stream[0].m_startVertex + , 0 , 0 ); } @@ -6132,7 +6426,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { deviceCtx->DrawIndexed(numIndices , draw.m_startIndex - , draw.m_stream[0].m_startVertex + , 0 ); } } @@ -6147,14 +6441,14 @@ BX_PRAGMA_DIAGNOSTIC_POP(); { deviceCtx->DrawInstanced(numVertices , draw.m_numInstances - , draw.m_stream[0].m_startVertex + , 0 , 0 ); } else { deviceCtx->Draw(numVertices - , draw.m_stream[0].m_startVertex + , 0 ); } } @@ -6186,7 +6480,9 @@ BX_PRAGMA_DIAGNOSTIC_POP(); invalidateCompute(); } - if (0 < _render->m_num) + submitBlit(bs, BGFX_CONFIG_MAX_VIEWS); + + if (0 < _render->m_numRenderItems) { if (0 != (m_resolution.m_flags & BGFX_RESET_FLUSH_AFTER_RENDER) ) { @@ -6197,24 +6493,14 @@ BX_PRAGMA_DIAGNOSTIC_POP(); capture(); captureElapsed += bx::getHPCounter(); - BGFX_GPU_PROFILER_END(); - BGFX_PROFILER_END(); + profiler.end(); } } PIX_ENDEVENT(); - BGFX_GPU_PROFILER_END(); - int64_t now = bx::getHPCounter(); - elapsed += now; - - static int64_t last = now; - - Stats& perfStats = _render->m_perfStats; - perfStats.cpuTimeBegin = last; - - int64_t frameTime = now - last; - last = now; + int64_t timeEnd = bx::getHPCounter(); + int64_t frameTime = timeEnd - timeBegin; static int64_t min = frameTime; static int64_t max = frameTime; @@ -6225,31 +6511,32 @@ BX_PRAGMA_DIAGNOSTIC_POP(); static double maxGpuElapsed = 0.0f; double elapsedGpuMs = 0.0; - if (m_timerQuerySupport) + if (UINT32_MAX != frameQueryIdx) { - m_gpuTimer.end(); + m_gpuTimer.end(frameQueryIdx); - do - { - double toGpuMs = 1000.0 / double(m_gpuTimer.m_frequency); - elapsedGpuMs = m_gpuTimer.m_elapsed * toGpuMs; - maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed; - } - while (m_gpuTimer.get() ); + const TimerQueryD3D11::Result& result = m_gpuTimer.m_result[BGFX_CONFIG_MAX_VIEWS]; + double toGpuMs = 1000.0 / double(result.m_frequency); + elapsedGpuMs = (result.m_end - result.m_begin) * toGpuMs; + maxGpuElapsed = elapsedGpuMs > maxGpuElapsed ? elapsedGpuMs : maxGpuElapsed; - maxGpuLatency = bx::uint32_imax(maxGpuLatency, m_gpuTimer.m_control.available()-1); + maxGpuLatency = bx::uint32_imax(maxGpuLatency, result.m_pending-1); } const int64_t timerFreq = bx::getHPFrequency(); - perfStats.cpuTimeEnd = now; + Stats& perfStats = _render->m_perfStats; + perfStats.cpuTimeBegin = timeBegin; + perfStats.cpuTimeEnd = timeEnd; perfStats.cpuTimerFreq = timerFreq; - perfStats.gpuTimeBegin = m_gpuTimer.m_begin; - perfStats.gpuTimeEnd = m_gpuTimer.m_end; - perfStats.gpuTimerFreq = m_gpuTimer.m_frequency; + const TimerQueryD3D11::Result& result = m_gpuTimer.m_result[BGFX_CONFIG_MAX_VIEWS]; + perfStats.gpuTimeBegin = result.m_begin; + perfStats.gpuTimeEnd = result.m_end; + perfStats.gpuTimerFreq = result.m_frequency; perfStats.numDraw = statsKeyType[0]; perfStats.numCompute = statsKeyType[1]; perfStats.maxGpuLatency = maxGpuLatency; + m_nvapi.getMemoryInfo(perfStats.gpuMemoryUsed, perfStats.gpuMemoryMax); if (_render->m_debug & (BGFX_DEBUG_IFH|BGFX_DEBUG_STATS) ) { @@ -6258,12 +6545,13 @@ BX_PRAGMA_DIAGNOSTIC_POP(); m_needPresent = true; TextVideoMem& tvm = m_textVideoMem; - static int64_t next = now; + static int64_t next = timeEnd; - if (now >= next) + if (timeEnd >= next) { - next = now + timerFreq; - double freq = double(bx::getHPFrequency() ); + next = timeEnd + timerFreq; + + double freq = double(timerFreq); double toMs = 1000.0/freq; tvm.clear(); @@ -6320,9 +6608,9 @@ BX_PRAGMA_DIAGNOSTIC_POP(); , !!(m_resolution.m_flags&BGFX_RESET_MAXANISOTROPY) ? '\xfe' : ' ' ); - double elapsedCpuMs = double(elapsed)*toMs; + double elapsedCpuMs = double(frameTime)*toMs; tvm.printf(10, pos++, 0x8e, " Submitted: %5d (draw %5d, compute %4d) / CPU %7.4f [ms] %c GPU %7.4f [ms] (latency %d) " - , _render->m_num + , _render->m_numRenderItems , statsKeyType[0] , statsKeyType[1] , elapsedCpuMs @@ -6350,7 +6638,7 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } tvm.printf(10, pos++, 0x8e, " Indices: %7d ", statsNumIndices); - tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); +// tvm.printf(10, pos++, 0x8e, " Uniform size: %7d, Max: %7d ", _render->m_uniformEnd, _render->m_uniformMax); tvm.printf(10, pos++, 0x8e, " DVB size: %7d ", _render->m_vboffset); tvm.printf(10, pos++, 0x8e, " DIB size: %7d ", _render->m_iboffset); @@ -6397,12 +6685,6 @@ BX_PRAGMA_DIAGNOSTIC_POP(); } } /* namespace d3d11 */ } // namespace bgfx -#undef BGFX_GPU_PROFILER_BIND -#undef BGFX_GPU_PROFILER_UNBIND -#undef BGFX_GPU_PROFILER_BEGIN -#undef BGFX_GPU_PROFILER_BEGIN_DYNAMIC -#undef BGFX_GPU_PROFILER_END - #else namespace bgfx { namespace d3d11 |