diff --git a/examples/25-c99/helloworld.c b/examples/25-c99/helloworld.c index eb0fc025d..517573005 100644 --- a/examples/25-c99/helloworld.c +++ b/examples/25-c99/helloworld.c @@ -26,7 +26,7 @@ int32_t _main_(int32_t _argc, char** _argv) bgfx_init_ctor(&init); bgfx_init(&init); - bgfx_reset(width, height, reset); + bgfx_reset(width, height, reset, init.resolution.format); // Enable debug text. bgfx_set_debug(debug); diff --git a/include/bgfx/bgfx.h b/include/bgfx/bgfx.h index f1fa03568..80a374ff1 100644 --- a/include/bgfx/bgfx.h +++ b/include/bgfx/bgfx.h @@ -604,9 +604,10 @@ namespace bgfx { Resolution(); - uint32_t width; //!< Backbuffer width. - uint32_t height; //!< Backbuffer height. - uint32_t reset; //!< Reset parameters. + TextureFormat::Enum format; //!< Backbuffer format. + uint32_t width; //!< Backbuffer width. + uint32_t height; //!< Backbuffer height. + uint32_t reset; //!< Reset parameters. }; /// Initialization parameters used by `bgfx::init`. @@ -1874,6 +1875,7 @@ namespace bgfx /// occurs. Default behavior is that flip occurs before rendering new /// frame. This flag only has effect when `BGFX_CONFIG_MULTITHREADED=0`. /// - `BGFX_RESET_SRGB_BACKBUFFER` - Enable sRGB backbuffer. + /// @param[in] _format Texture format. See: `TextureFormat::Enum`. /// /// @attention This call doesn't actually change window size, it just /// resizes back-buffer. Windowing code has to change window size. @@ -1884,6 +1886,7 @@ namespace bgfx uint32_t _width , uint32_t _height , uint32_t _flags = BGFX_RESET_NONE + , TextureFormat::Enum _format = TextureFormat::Count ); /// Begin submitting draw calls from thread. diff --git a/include/bgfx/c99/bgfx.h b/include/bgfx/c99/bgfx.h index c68d474fd..20e0b7222 100644 --- a/include/bgfx/c99/bgfx.h +++ b/include/bgfx/c99/bgfx.h @@ -598,6 +598,7 @@ typedef struct bgfx_allocator_vtbl_s /**/ typedef struct bgfx_resolution_s { + bgfx_texture_format_t format; uint32_t width; uint32_t height; uint32_t reset; @@ -682,7 +683,7 @@ BGFX_C_API bool bgfx_init(const bgfx_init_t* _init); BGFX_C_API void bgfx_shutdown(void); /**/ -BGFX_C_API void bgfx_reset(uint32_t _width, uint32_t _height, uint32_t _flags); +BGFX_C_API void bgfx_reset(uint32_t _width, uint32_t _height, uint32_t _flags, bgfx_texture_format_t _format); /**/ BGFX_C_API struct bgfx_encoder_s* bgfx_begin(void); diff --git a/include/bgfx/c99/platform.h b/include/bgfx/c99/platform.h index 965f6eed8..a9abb81f7 100644 --- a/include/bgfx/c99/platform.h +++ b/include/bgfx/c99/platform.h @@ -88,7 +88,7 @@ typedef struct bgfx_interface_vtbl void (*init_ctor)(bgfx_init_t* _init); bool (*init)(const bgfx_init_t* _init); void (*shutdown)(); - void (*reset)(uint32_t _width, uint32_t _height, uint32_t _flags); + void (*reset)(uint32_t _width, uint32_t _height, uint32_t _flags, bgfx_texture_format_t _format); uint32_t (*frame)(bool _capture); bgfx_renderer_type_t (*get_renderer_type)(); const bgfx_caps_t* (*get_caps)(); diff --git a/include/bgfx/defines.h b/include/bgfx/defines.h index be06569dc..9451c17be 100644 --- a/include/bgfx/defines.h +++ b/include/bgfx/defines.h @@ -6,7 +6,7 @@ #ifndef BGFX_DEFINES_H_HEADER_GUARD #define BGFX_DEFINES_H_HEADER_GUARD -#define BGFX_API_VERSION UINT32_C(77) +#define BGFX_API_VERSION UINT32_C(78) /// Color RGB/alpha/depth write. When it's not specified write will be disabled. #define BGFX_STATE_WRITE_R UINT64_C(0x0000000000000001) //!< Enable R write. @@ -423,9 +423,10 @@ #define BGFX_RESET_FLUSH_AFTER_RENDER UINT32_C(0x00002000) //!< Flush rendering after submitting to GPU. #define BGFX_RESET_FLIP_AFTER_RENDER UINT32_C(0x00004000) //!< This flag specifies where flip occurs. Default behavior is that flip occurs before rendering new frame. This flag only has effect when `BGFX_CONFIG_MULTITHREADED=0`. #define BGFX_RESET_SRGB_BACKBUFFER UINT32_C(0x00008000) //!< Enable sRGB backbuffer. -#define BGFX_RESET_HIDPI UINT32_C(0x00010000) //!< Enable HiDPI rendering. -#define BGFX_RESET_DEPTH_CLAMP UINT32_C(0x00020000) //!< Enable depth clamp. -#define BGFX_RESET_SUSPEND UINT32_C(0x00040000) //!< Suspend rendering. +#define BGFX_RESET_HDR10 UINT32_C(0x00010000) //!< Enable HDR10 rendering. +#define BGFX_RESET_HIDPI UINT32_C(0x00020000) //!< Enable HiDPI rendering. +#define BGFX_RESET_DEPTH_CLAMP UINT32_C(0x00040000) //!< Enable depth clamp. +#define BGFX_RESET_SUSPEND UINT32_C(0x00080000) //!< Suspend rendering. #define BGFX_RESET_RESERVED_SHIFT 31 //!< Internal bits shift. #define BGFX_RESET_RESERVED_MASK UINT32_C(0x80000000) //!< Internal bits mask. @@ -439,23 +440,24 @@ #define BGFX_CAPS_FRAGMENT_DEPTH UINT64_C(0x0000000000000020) //!< Fragment depth is accessible in fragment shader. #define BGFX_CAPS_FRAGMENT_ORDERING UINT64_C(0x0000000000000040) //!< Fragment ordering is available in fragment shader. #define BGFX_CAPS_GRAPHICS_DEBUGGER UINT64_C(0x0000000000000080) //!< Graphics debugger is present. -#define BGFX_CAPS_HIDPI UINT64_C(0x0000000000000100) //!< HiDPI rendering is supported. -#define BGFX_CAPS_INDEX32 UINT64_C(0x0000000000000400) //!< 32-bit indices are supported. -#define BGFX_CAPS_INSTANCING UINT64_C(0x0000000000000800) //!< Instancing is supported. -#define BGFX_CAPS_OCCLUSION_QUERY UINT64_C(0x0000000000001000) //!< Occlusion query is supported. -#define BGFX_CAPS_RENDERER_MULTITHREADED UINT64_C(0x0000000000002000) //!< Renderer is on separate thread. -#define BGFX_CAPS_SWAP_CHAIN UINT64_C(0x0000000000004000) //!< Multiple windows are supported. -#define BGFX_CAPS_TEXTURE_2D_ARRAY UINT64_C(0x0000000000008000) //!< 2D texture array is supported. -#define BGFX_CAPS_TEXTURE_3D UINT64_C(0x0000000000010000) //!< 3D textures are supported. -#define BGFX_CAPS_TEXTURE_BLIT UINT64_C(0x0000000000020000) //!< Texture blit is supported. -#define BGFX_CAPS_TEXTURE_COMPARE_ALL UINT64_C(0x00000000000c0000) //!< All texture compare modes are supported. -#define BGFX_CAPS_TEXTURE_COMPARE_LEQUAL UINT64_C(0x0000000000080000) //!< Texture compare less equal mode is supported. -#define BGFX_CAPS_TEXTURE_CUBE_ARRAY UINT64_C(0x0000000000100000) //!< Cubemap texture array is supported. -#define BGFX_CAPS_TEXTURE_DIRECT_ACCESS UINT64_C(0x0000000000200000) //!< CPU direct access to GPU texture memory. -#define BGFX_CAPS_TEXTURE_READ_BACK UINT64_C(0x0000000000400000) //!< Read-back texture is supported. +#define BGFX_CAPS_HDR10 UINT64_C(0x0000000000000100) //!< HDR10 rendering is supported. +#define BGFX_CAPS_HIDPI UINT64_C(0x0000000000000400) //!< HiDPI rendering is supported. +#define BGFX_CAPS_INDEX32 UINT64_C(0x0000000000000800) //!< 32-bit indices are supported. +#define BGFX_CAPS_INSTANCING UINT64_C(0x0000000000001000) //!< Instancing is supported. +#define BGFX_CAPS_OCCLUSION_QUERY UINT64_C(0x0000000000002000) //!< Occlusion query is supported. +#define BGFX_CAPS_RENDERER_MULTITHREADED UINT64_C(0x0000000000004000) //!< Renderer is on separate thread. +#define BGFX_CAPS_SWAP_CHAIN UINT64_C(0x0000000000008000) //!< Multiple windows are supported. +#define BGFX_CAPS_TEXTURE_2D_ARRAY UINT64_C(0x0000000000010000) //!< 2D texture array is supported. +#define BGFX_CAPS_TEXTURE_3D UINT64_C(0x0000000000020000) //!< 3D textures are supported. +#define BGFX_CAPS_TEXTURE_BLIT UINT64_C(0x00000000000c0000) //!< Texture blit is supported. +#define BGFX_CAPS_TEXTURE_COMPARE_ALL UINT64_C(0x0000000000080000) //!< All texture compare modes are supported. +#define BGFX_CAPS_TEXTURE_COMPARE_LEQUAL UINT64_C(0x0000000000100000) //!< Texture compare less equal mode is supported. +#define BGFX_CAPS_TEXTURE_CUBE_ARRAY UINT64_C(0x0000000000200000) //!< Cubemap texture array is supported. +#define BGFX_CAPS_TEXTURE_DIRECT_ACCESS UINT64_C(0x0000000000400000) //!< CPU direct access to GPU texture memory. +#define BGFX_CAPS_TEXTURE_READ_BACK UINT64_C(0x0000000000800000) //!< Read-back texture is supported. #define BGFX_CAPS_VERTEX_ATTRIB_HALF UINT64_C(0x0000000000800000) //!< Vertex attribute half-float is supported. -#define BGFX_CAPS_VERTEX_ATTRIB_UINT10 UINT64_C(0x0000000000800000) //!< Vertex attribute 10_10_10_2 is supported. -#define BGFX_CAPS_VERTEX_ID UINT64_C(0x0000000001000000) //!< Rendering with VertexID only is supported. +#define BGFX_CAPS_VERTEX_ATTRIB_UINT10 UINT64_C(0x0000000001000000) //!< Vertex attribute 10_10_10_2 is supported. +#define BGFX_CAPS_VERTEX_ID UINT64_C(0x0000000002000000) //!< Rendering with VertexID only is supported. /// #define BGFX_CAPS_FORMAT_TEXTURE_NONE UINT16_C(0x0000) //!< Texture format is not supported. diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 92f2f0e56..af15a54db 100644 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -1158,6 +1158,7 @@ namespace bgfx CAPS_FLAGS(BGFX_CAPS_FRAGMENT_DEPTH), CAPS_FLAGS(BGFX_CAPS_FRAGMENT_ORDERING), CAPS_FLAGS(BGFX_CAPS_GRAPHICS_DEBUGGER), + CAPS_FLAGS(BGFX_CAPS_HDR10), CAPS_FLAGS(BGFX_CAPS_HIDPI), CAPS_FLAGS(BGFX_CAPS_INDEX32), CAPS_FLAGS(BGFX_CAPS_INSTANCING), @@ -2804,7 +2805,8 @@ namespace bgfx } Resolution::Resolution() - : width(1280) + : format(TextureFormat::RGBA8) + , width(1280) , height(720) , reset(BGFX_RESET_NONE) { @@ -2985,11 +2987,11 @@ error: g_allocator = NULL; } - void reset(uint32_t _width, uint32_t _height, uint32_t _flags) + void reset(uint32_t _width, uint32_t _height, uint32_t _flags, TextureFormat::Enum _format) { BGFX_CHECK_API_THREAD(); BX_CHECK(0 == (_flags&BGFX_RESET_RESERVED_MASK), "Do not set reset reserved flags!"); - s_ctx->reset(_width, _height, _flags); + s_ctx->reset(_width, _height, _flags, _format); } Encoder* begin() @@ -4848,9 +4850,9 @@ BGFX_C_API void bgfx_shutdown(void) return bgfx::shutdown(); } -BGFX_C_API void bgfx_reset(uint32_t _width, uint32_t _height, uint32_t _flags) +BGFX_C_API void bgfx_reset(uint32_t _width, uint32_t _height, uint32_t _flags, bgfx_texture_format_t _format) { - bgfx::reset(_width, _height, _flags); + bgfx::reset(_width, _height, _flags, bgfx::TextureFormat::Enum(_format) ); } BGFX_C_API uint32_t bgfx_frame(bool _capture) diff --git a/src/bgfx_p.h b/src/bgfx_p.h index d279ab888..493fdea7a 100644 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -2728,7 +2728,7 @@ namespace bgfx return cmdbuf; } - BGFX_API_FUNC(void reset(uint32_t _width, uint32_t _height, uint32_t _flags) ) + BGFX_API_FUNC(void reset(uint32_t _width, uint32_t _height, uint32_t _flags, TextureFormat::Enum _format) ) { BX_WARN(g_caps.limits.maxTextureSize >= _width && g_caps.limits.maxTextureSize >= _height @@ -2737,6 +2737,7 @@ namespace bgfx , _width , _height ); + m_init.resolution.format = TextureFormat::Count != _format ? _format : m_init.resolution.format; m_init.resolution.width = bx::clamp(_width, 1u, g_caps.limits.maxTextureSize); m_init.resolution.height = bx::clamp(_height, 1u, g_caps.limits.maxTextureSize); m_init.resolution.reset = 0 diff --git a/src/dxgi.cpp b/src/dxgi.cpp index e5b8b8bc8..0355be51d 100644 --- a/src/dxgi.cpp +++ b/src/dxgi.cpp @@ -189,51 +189,55 @@ namespace bgfx ; ++ii ) { - DXGI_ADAPTER_DESC desc; - hr = adapter->GetDesc(&desc); - if (SUCCEEDED(hr) ) { - BX_TRACE("Adapter #%d", ii); - - char description[BX_COUNTOF(desc.Description)]; - wcstombs(description, desc.Description, BX_COUNTOF(desc.Description) ); - BX_TRACE("\tDescription: %s", description); - BX_TRACE("\tVendorId: 0x%08x, DeviceId: 0x%08x, SubSysId: 0x%08x, Revision: 0x%08x" - , desc.VendorId - , desc.DeviceId - , desc.SubSysId - , desc.Revision - ); - BX_TRACE("\tMemory: %" PRIi64 " (video), %" PRIi64 " (system), %" PRIi64 " (shared)" - , desc.DedicatedVideoMemory - , desc.DedicatedSystemMemory - , desc.SharedSystemMemory - ); - - _caps.gpu[ii].vendorId = (uint16_t)desc.VendorId; - _caps.gpu[ii].deviceId = (uint16_t)desc.DeviceId; - ++_caps.numGPUs; - - if (NULL == m_adapter) + DXGI_ADAPTER_DESC desc; + hr = adapter->GetDesc(&desc); + if (SUCCEEDED(hr) ) { - if ( (BGFX_PCI_ID_NONE != _caps.vendorId || 0 != _caps.deviceId) - && (BGFX_PCI_ID_NONE == _caps.vendorId || desc.VendorId == _caps.vendorId) - && ( 0 == _caps.deviceId || desc.DeviceId == _caps.deviceId) ) - { - m_adapter = adapter; - m_adapter->AddRef(); - m_driverType = D3D_DRIVER_TYPE_UNKNOWN; - } + BX_TRACE("Adapter #%d", ii); - if (BX_ENABLED(BGFX_CONFIG_DEBUG_PERFHUD) - && 0 != bx::strFind(description, "PerfHUD") ) + char description[BX_COUNTOF(desc.Description)]; + wcstombs(description, desc.Description, BX_COUNTOF(desc.Description) ); + BX_TRACE("\tDescription: %s", description); + BX_TRACE("\tVendorId: 0x%08x, DeviceId: 0x%08x, SubSysId: 0x%08x, Revision: 0x%08x" + , desc.VendorId + , desc.DeviceId + , desc.SubSysId + , desc.Revision + ); + BX_TRACE("\tMemory: %" PRIi64 " (video), %" PRIi64 " (system), %" PRIi64 " (shared)" + , desc.DedicatedVideoMemory + , desc.DedicatedSystemMemory + , desc.SharedSystemMemory + ); + + _caps.gpu[ii].vendorId = (uint16_t)desc.VendorId; + _caps.gpu[ii].deviceId = (uint16_t)desc.DeviceId; + ++_caps.numGPUs; + + if (NULL == m_adapter) { - m_adapter = adapter; - m_driverType = D3D_DRIVER_TYPE_REFERENCE; + if ( (BGFX_PCI_ID_NONE != _caps.vendorId || 0 != _caps.deviceId) + && (BGFX_PCI_ID_NONE == _caps.vendorId || desc.VendorId == _caps.vendorId) + && ( 0 == _caps.deviceId || desc.DeviceId == _caps.deviceId) ) + { + m_adapter = adapter; + m_adapter->AddRef(); + m_driverType = D3D_DRIVER_TYPE_UNKNOWN; + } + + if (BX_ENABLED(BGFX_CONFIG_DEBUG_PERFHUD) + && 0 != bx::strFind(description, "PerfHUD") ) + { + m_adapter = adapter; + m_driverType = D3D_DRIVER_TYPE_REFERENCE; + } } } } + bool hdr10 = false; + IDXGIOutput* output; for (uint32_t jj = 0 ; DXGI_ERROR_NOT_FOUND != adapter->EnumOutputs(jj, &output) @@ -248,20 +252,52 @@ namespace bgfx char deviceName[BX_COUNTOF(outputDesc.DeviceName)]; wcstombs(deviceName, outputDesc.DeviceName, BX_COUNTOF(outputDesc.DeviceName)); - BX_TRACE("\t\tDeviceName: %s", deviceName); - BX_TRACE("\t\tDesktopCoordinates: %d, %d, %d, %d" + BX_TRACE("\t\t DeviceName: %s", deviceName); + BX_TRACE("\t\t DesktopCoordinates: %d, %d, %d, %d" , outputDesc.DesktopCoordinates.left , outputDesc.DesktopCoordinates.top , outputDesc.DesktopCoordinates.right , outputDesc.DesktopCoordinates.bottom ); - BX_TRACE("\t\tAttachedToDesktop: %d", outputDesc.AttachedToDesktop); - BX_TRACE("\t\tRotation: %d", outputDesc.Rotation); + BX_TRACE("\t\t AttachedToDesktop: %d", outputDesc.AttachedToDesktop); + BX_TRACE("\t\t Rotation: %d", outputDesc.Rotation); + +#if BX_PLATFORM_WINDOWS + IDXGIOutput6* output6; + hr = output->QueryInterface(IID_IDXGIOutput6, (void**)&output6); + if (SUCCEEDED(hr) ) + { + DXGI_OUTPUT_DESC1 desc; + hr = output6->GetDesc1(&desc); + if (SUCCEEDED(hr) ) + { + BX_TRACE("\t\t BitsPerColor: %d", desc.BitsPerColor); + BX_TRACE("\t\t Color space: %s (colorspace, range, gamma, sitting, primaries, transform)" + , s_colorSpaceStr[bx::min(desc.ColorSpace, kDxgiLastColorSpace+1)] + ); + BX_TRACE("\t\t RedPrimary: %f, %f", desc.RedPrimary[0], desc.RedPrimary[1]); + BX_TRACE("\t\t GreenPrimary: %f, %f", desc.GreenPrimary[0], desc.GreenPrimary[1]); + BX_TRACE("\t\t BluePrimary: %f, %f", desc.BluePrimary[0], desc.BluePrimary[1]); + BX_TRACE("\t\t WhitePoint: %f, %f", desc.WhitePoint[0], desc.WhitePoint[1]); + BX_TRACE("\t\t MinLuminance: %f", desc.MinLuminance); + BX_TRACE("\t\t MaxLuminance: %f", desc.MaxLuminance); + BX_TRACE("\t\tMaxFullFrameLuminance: %f", desc.MaxFullFrameLuminance); + BX_TRACE("\t\t HDR support: %s", DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 == desc.ColorSpace ? "true" : "false"); + + hdr10 |= DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 == desc.ColorSpace; + } + + // BK - warn only because RenderDoc might be present. + DX_RELEASE_WARNONLY(output6, 1); + } +#endif // BX_PLATFORM_WINDOWS DX_RELEASE(output, 0); } } + _caps.supported |= hdr10 ? BGFX_CAPS_HDR10 : 0; + DX_RELEASE(adapter, adapter == m_adapter ? 1 : 0); } @@ -540,8 +576,9 @@ namespace bgfx { uint32_t colorSpaceSupport; reinterpret_cast(*_swapChain)->CheckColorSpaceSupport(s_colorSpace[jj], &colorSpaceSupport); - BX_TRACE("\t%2d, 0x%08x, %s" + BX_TRACE("\t%2d: \"%-20s\", 0x%08x, %s" , s_colorSpace[jj] + , s_colorSpaceStr[s_colorSpace[jj]] , colorSpaceSupport , 0 != (colorSpaceSupport & DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT) ? "supported" @@ -553,45 +590,127 @@ namespace bgfx } } } - - { - IDXGIOutput* output; - hr = (*_swapChain)->GetContainingOutput(&output); - if (SUCCEEDED(hr) ) - { - IDXGIOutput6* output6; - hr = output->QueryInterface(IID_IDXGIOutput6, (void**)&output6); - if (SUCCEEDED(hr) ) - { - DXGI_OUTPUT_DESC1 desc; - hr = output6->GetDesc1(&desc); - if (SUCCEEDED(hr) ) - { - BX_TRACE("Display specs:") - BX_TRACE("\t BitsPerColor: %d", desc.BitsPerColor); - BX_TRACE("\t Color space: %s (colorspace, range, gamma, sitting, primaries, transform)" - , s_colorSpaceStr[bx::min(desc.ColorSpace, kDxgiLastColorSpace+1)] - ); - BX_TRACE("\t RedPrimary: %f, %f", desc.RedPrimary[0], desc.RedPrimary[1]); - BX_TRACE("\t GreenPrimary: %f, %f", desc.GreenPrimary[0], desc.GreenPrimary[1]); - BX_TRACE("\t BluePrimary: %f, %f", desc.BluePrimary[0], desc.BluePrimary[1]); - BX_TRACE("\t WhitePoint: %f, %f", desc.WhitePoint[0], desc.WhitePoint[1]); - BX_TRACE("\t MinLuminance: %f", desc.MinLuminance); - BX_TRACE("\t MaxLuminance: %f", desc.MaxLuminance); - BX_TRACE("\tMaxFullFrameLuminance: %f", desc.MaxFullFrameLuminance); - } - - DX_RELEASE(output6, 1); - } - - DX_RELEASE(output, 0); - } - } #endif // BX_PLATFORM_WINDOWS + updateHdr10(*_swapChain, _scd); + return S_OK; } + void Dxgi::updateHdr10(SwapChainI* _swapChain, const SwapChainDesc& _scd) + { +#if BX_PLATFORM_WINDOWS + ::IDXGISwapChain4* swapChain4; + HRESULT hr = _swapChain->QueryInterface(IID_IDXGISwapChain4, (void**)&swapChain4); + + if (SUCCEEDED(hr) ) + { + const DXGI_COLOR_SPACE_TYPE colorSpace = + _scd.format == DXGI_FORMAT_R10G10B10A2_UNORM ? DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 + : _scd.format == DXGI_FORMAT_R16G16B16A16_FLOAT ? DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709 + : DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 + ; + + hr = swapChain4->SetColorSpace1(colorSpace); + + if (SUCCEEDED(hr) ) + { + DXGI_OUTPUT_DESC1 desc; + + IDXGIOutput* output; + hr = _swapChain->GetContainingOutput(&output); + if (SUCCEEDED(hr) ) + { + IDXGIOutput6* output6; + hr = output->QueryInterface(IID_IDXGIOutput6, (void**)&output6); + if (SUCCEEDED(hr) ) + { + hr = output6->GetDesc1(&desc); + if (SUCCEEDED(hr) ) + { + BX_TRACE("Display specs:") + BX_TRACE("\t BitsPerColor: %d", desc.BitsPerColor); + BX_TRACE("\t Color space: %s (colorspace, range, gamma, sitting, primaries, transform)" + , s_colorSpaceStr[bx::min(desc.ColorSpace, kDxgiLastColorSpace+1)] + ); + BX_TRACE("\t RedPrimary: %f, %f", desc.RedPrimary[0], desc.RedPrimary[1]); + BX_TRACE("\t GreenPrimary: %f, %f", desc.GreenPrimary[0], desc.GreenPrimary[1]); + BX_TRACE("\t BluePrimary: %f, %f", desc.BluePrimary[0], desc.BluePrimary[1]); + BX_TRACE("\t WhitePoint: %f, %f", desc.WhitePoint[0], desc.WhitePoint[1]); + BX_TRACE("\t MinLuminance: %f", desc.MinLuminance); + BX_TRACE("\t MaxLuminance: %f", desc.MaxLuminance); + BX_TRACE("\tMaxFullFrameLuminance: %f", desc.MaxFullFrameLuminance); + } + + DX_RELEASE(output6, 1); + } + + DX_RELEASE(output, 0); + } + + DXGI_HDR_METADATA_HDR10 hdr10; + hdr10.RedPrimary[0] = uint16_t(desc.RedPrimary[0] * 50000.0f); + hdr10.RedPrimary[1] = uint16_t(desc.RedPrimary[1] * 50000.0f); + hdr10.GreenPrimary[0] = uint16_t(desc.GreenPrimary[0] * 50000.0f); + hdr10.GreenPrimary[1] = uint16_t(desc.GreenPrimary[1] * 50000.0f); + hdr10.BluePrimary[0] = uint16_t(desc.BluePrimary[0] * 50000.0f); + hdr10.BluePrimary[1] = uint16_t(desc.BluePrimary[1] * 50000.0f); + hdr10.WhitePoint[0] = uint16_t(desc.WhitePoint[0] * 50000.0f); + hdr10.WhitePoint[1] = uint16_t(desc.WhitePoint[1] * 50000.0f); + hdr10.MaxMasteringLuminance = uint32_t(desc.MaxLuminance * 10000.0f); + hdr10.MinMasteringLuminance = uint32_t(desc.MinLuminance * 10000.0f); + hdr10.MaxContentLightLevel = uint16_t(desc.MaxFullFrameLuminance); + hdr10.MaxFrameAverageLightLevel = uint16_t(desc.MaxFullFrameLuminance); + hr = swapChain4->SetHDRMetaData(DXGI_HDR_METADATA_TYPE_HDR10, sizeof(DXGI_HDR_METADATA_HDR10), &hdr10); + } + + DX_RELEASE(swapChain4, 1); + } +#else + BX_UNUSED(_swapChain, _scd); +#endif // BX_PLATFORM_WINDOWS + } + + HRESULT Dxgi::resizeBuffers(SwapChainI* _swapChain, const SwapChainDesc& _scd, const uint32_t* _nodeMask, IUnknown* const* _presentQueue) + { + HRESULT hr; + +#if BX_PLATFORM_WINDOWS + if (NULL != _nodeMask + && NULL != _presentQueue) + { + hr = _swapChain->ResizeBuffers1( + _scd.bufferCount + , _scd.width + , _scd.height + , _scd.format + , _scd.flags + , _nodeMask + , _presentQueue + ); + } + else +#endif // BX_PLATFORM_WINDOWS + { + BX_UNUSED(_nodeMask, _presentQueue); + + hr = _swapChain->ResizeBuffers( + _scd.bufferCount + , _scd.width + , _scd.height + , _scd.format + , _scd.flags + ); + } + + if (SUCCEEDED(hr) ) + { + updateHdr10(_swapChain, _scd); + } + + return hr; + } + void Dxgi::trim() { #if BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT diff --git a/src/dxgi.h b/src/dxgi.h index 2a3d15fa2..b9cf4b304 100644 --- a/src/dxgi.h +++ b/src/dxgi.h @@ -82,7 +82,13 @@ namespace bgfx void update(IUnknown* _device); /// - HRESULT createSwapChain(IUnknown* _device, const SwapChainDesc& _desc, SwapChainI** _swapChain); + HRESULT createSwapChain(IUnknown* _device, const SwapChainDesc& _scd, SwapChainI** _swapChain); + + /// + void updateHdr10(SwapChainI* _swapChain, const SwapChainDesc& _scd); + + /// + HRESULT resizeBuffers(SwapChainI* _swapChain, const SwapChainDesc& _scd, const uint32_t* _nodeMask = NULL, IUnknown* const* _presentQueue = NULL); /// void trim(); diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index 66f88fe09..c1067b6c7 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -964,8 +964,8 @@ namespace bgfx { namespace d3d11 if (NULL == g_platformData.backBuffer) { #if BX_PLATFORM_WINDOWS - m_swapEffect = DXGI_SWAP_EFFECT_DISCARD; - m_swapBufferCount = 1; + m_swapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + m_swapBufferCount = 2; #else m_swapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; m_swapBufferCount = 2; @@ -974,7 +974,7 @@ namespace bgfx { namespace d3d11 bx::memSet(&m_scd, 0, sizeof(m_scd) ); m_scd.width = _init.resolution.width; m_scd.height = _init.resolution.height; - m_scd.format = DXGI_FORMAT_R8G8B8A8_UNORM; + 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]; @@ -2075,8 +2075,8 @@ namespace bgfx { namespace d3d11 ; desc.Texture2D.MipSlice = 0; desc.Format = (m_resolution.reset & BGFX_RESET_SRGB_BACKBUFFER) - ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB - : DXGI_FORMAT_R8G8B8A8_UNORM + ? m_scd.format == DXGI_FORMAT_R8G8B8A8_UNORM ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : m_scd.format + : m_scd.format ; DX_CHECK(m_device->CreateRenderTargetView(color, &desc, &m_backBufferColor) ); @@ -2265,6 +2265,7 @@ namespace bgfx { namespace d3d11 if (m_resolution.width != _resolution.width || m_resolution.height != _resolution.height + || m_resolution.format != _resolution.format || (m_resolution.reset&maskFlags) != (_resolution.reset&maskFlags) ) { uint32_t flags = _resolution.reset & (~BGFX_RESET_INTERNAL_FORCE); @@ -2282,6 +2283,7 @@ namespace bgfx { namespace d3d11 m_scd.width = _resolution.width; m_scd.height = _resolution.height; + m_scd.format = s_textureFormat[_resolution.format].m_fmt; preReset(); @@ -2299,13 +2301,8 @@ namespace bgfx { namespace d3d11 if (resize) { m_deviceCtx->OMSetRenderTargets(1, s_zero.m_rtv, NULL); - DX_CHECK(m_swapChain->ResizeBuffers( - m_swapBufferCount - , m_scd.width - , m_scd.height - , m_scd.format - , DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH - ) ); + + DX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd) ); } else { diff --git a/src/renderer_d3d12.cpp b/src/renderer_d3d12.cpp index 936324e23..467a46c90 100644 --- a/src/renderer_d3d12.cpp +++ b/src/renderer_d3d12.cpp @@ -869,7 +869,7 @@ namespace bgfx { namespace d3d12 bx::memSet(&m_scd, 0, sizeof(m_scd) ); m_scd.width = _init.resolution.width; m_scd.height = _init.resolution.height; - m_scd.format = DXGI_FORMAT_R8G8B8A8_UNORM; + m_scd.format = s_textureFormat[_init.resolution.format].m_fmt; m_scd.stereo = false; updateMsaa(m_scd.format); @@ -2108,6 +2108,7 @@ namespace bgfx { namespace d3d12 if (m_resolution.width != _resolution.width || m_resolution.height != _resolution.height + || m_resolution.format != _resolution.format || (m_resolution.reset&maskFlags) != (_resolution.reset&maskFlags) ) { uint32_t flags = _resolution.reset & (~BGFX_RESET_INTERNAL_FORCE); @@ -2125,6 +2126,7 @@ namespace bgfx { namespace d3d12 m_scd.width = _resolution.width; m_scd.height = _resolution.height; + m_scd.format = s_textureFormat[_resolution.format].m_fmt; preReset(); @@ -2138,24 +2140,9 @@ namespace bgfx { namespace d3d12 BX_STATIC_ASSERT(BX_COUNTOF(m_backBufferColor) == BX_COUNTOF(nodeMask) ); IUnknown* presentQueue[] ={ m_cmd.m_commandQueue, m_cmd.m_commandQueue, m_cmd.m_commandQueue, m_cmd.m_commandQueue }; BX_STATIC_ASSERT(BX_COUNTOF(m_backBufferColor) == BX_COUNTOF(presentQueue) ); - - DX_CHECK(m_swapChain->ResizeBuffers1( - m_scd.bufferCount - , m_scd.width - , m_scd.height - , m_scd.format - , m_scd.flags - , nodeMask - , presentQueue - ) ); + DX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd, nodeMask, presentQueue) ); #elif BX_PLATFORM_WINRT - DX_CHECK(m_swapChain->ResizeBuffers( - m_scd.bufferCount - , m_scd.width - , m_scd.height - , m_scd.format - , m_scd.flags - ) ); + DX_CHECK(m_dxgi.resizeBuffers(m_swapChain, m_scd); m_backBufferColorIdx = m_scd.bufferCount-1; #endif // BX_PLATFORM_WINDOWS }