style: adjust clang-format rules (#2186)

Co-authored-by: Vithorio Polten <reach@vithor.io>
This commit is contained in:
ReenigneArcher
2025-01-19 22:34:47 -05:00
committed by GitHub
parent f57aee9025
commit c2420427b1
158 changed files with 8754 additions and 9994 deletions

View File

@@ -2,13 +2,16 @@
* @file src/platform/windows/display_base.cpp
* @brief Definitions for the Windows display base code.
*/
// standard includes
#include <cmath>
#include <initguid.h>
#include <thread>
// platform includes
#include <initguid.h>
// lib includes
#include <boost/algorithm/string/join.hpp>
#include <boost/process/v1.hpp>
#include <MinHook.h>
// We have to include boost/process/v1.hpp before display.h due to WinSock.h,
@@ -36,14 +39,14 @@ typedef enum _D3DKMT_GPU_PREFERENCE_QUERY_STATE: DWORD {
namespace platf {
using namespace std::literals;
}
namespace platf::dxgi {
namespace bp = boost::process;
/**
* DDAPI-specific initialization goes here.
*/
int
duplication_t::init(display_base_t *display, const ::video::config_t &config) {
int duplication_t::init(display_base_t *display, const ::video::config_t &config) {
HRESULT status;
// Capture format will be determined from the first call to AcquireNextFrame()
@@ -81,8 +84,7 @@ namespace platf::dxgi {
BOOST_LOG(warning) << "DuplicateOutput1 Failed [0x"sv << util::hex(status).to_string_view() << ']';
return -1;
}
}
else {
} else {
BOOST_LOG(warning) << "IDXGIOutput5 is not supported by your OS. Capture performance may be reduced."sv;
dxgi::output1_t output1 {};
@@ -124,8 +126,7 @@ namespace platf::dxgi {
return 0;
}
capture_e
duplication_t::next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::chrono::milliseconds timeout, resource_t::pointer *res_p) {
capture_e duplication_t::next_frame(DXGI_OUTDUPL_FRAME_INFO &frame_info, std::chrono::milliseconds timeout, resource_t::pointer *res_p) {
auto capture_status = release_frame();
if (capture_status != capture_e::ok) {
return capture_status;
@@ -157,8 +158,7 @@ namespace platf::dxgi {
}
}
capture_e
duplication_t::reset(dup_t::pointer dup_p) {
capture_e duplication_t::reset(dup_t::pointer dup_p) {
auto capture_status = release_frame();
dup.reset(dup_p);
@@ -166,8 +166,7 @@ namespace platf::dxgi {
return capture_status;
}
capture_e
duplication_t::release_frame() {
capture_e duplication_t::release_frame() {
if (!has_frame) {
return capture_e::ok;
}
@@ -195,16 +194,14 @@ namespace platf::dxgi {
release_frame();
}
capture_e
display_base_t::capture(const push_captured_image_cb_t &push_captured_image_cb, const pull_free_image_cb_t &pull_free_image_cb, bool *cursor) {
capture_e display_base_t::capture(const push_captured_image_cb_t &push_captured_image_cb, const pull_free_image_cb_t &pull_free_image_cb, bool *cursor) {
auto adjust_client_frame_rate = [&]() -> DXGI_RATIONAL {
// Adjust capture frame interval when display refresh rate is not integral but very close to requested fps.
if (display_refresh_rate.Denominator > 1) {
DXGI_RATIONAL candidate = display_refresh_rate;
if (client_frame_rate % display_refresh_rate_rounded == 0) {
candidate.Numerator *= client_frame_rate / display_refresh_rate_rounded;
}
else if (display_refresh_rate_rounded % client_frame_rate == 0) {
} else if (display_refresh_rate_rounded % client_frame_rate == 0) {
candidate.Denominator *= display_refresh_rate_rounded / client_frame_rate;
}
double candidate_rate = (double) candidate.Numerator / candidate.Denominator;
@@ -215,7 +212,7 @@ namespace platf::dxgi {
}
}
return { (uint32_t) client_frame_rate, 1 };
return {(uint32_t) client_frame_rate, 1};
};
DXGI_RATIONAL client_frame_rate_adjusted = adjust_client_frame_rate();
@@ -258,8 +255,7 @@ namespace platf::dxgi {
frame_pacing_group_start = std::nullopt;
frame_pacing_group_frames = 0;
status = capture_e::timeout;
}
else {
} else {
timer->sleep_for(sleep_period);
sleep_overshoot_logger.first_point(sleep_target);
sleep_overshoot_logger.second_point_now_and_log();
@@ -268,8 +264,7 @@ namespace platf::dxgi {
if (status == capture_e::ok && img_out) {
frame_pacing_group_frames += 1;
}
else {
} else {
frame_pacing_group_start = std::nullopt;
frame_pacing_group_frames = 0;
}
@@ -289,8 +284,7 @@ namespace platf::dxgi {
}
frame_pacing_group_frames = 1;
}
else if (status == platf::capture_e::timeout) {
} else if (status == platf::capture_e::timeout) {
// The D3D11 device is protected by an unfair lock that is held the entire time that
// IDXGIOutputDuplication::AcquireNextFrame() is running. This is normally harmless,
// however sometimes the encoding thread needs to interact with our ID3D11Device to
@@ -348,8 +342,7 @@ namespace platf::dxgi {
* @param output The DXGI output to capture.
* @param enumeration_only Specifies whether this test is occurring for display enumeration.
*/
bool
test_dxgi_duplication(adapter_t &adapter, output_t &output, bool enumeration_only) {
bool test_dxgi_duplication(adapter_t &adapter, output_t &output, bool enumeration_only) {
D3D_FEATURE_LEVEL featureLevels[] {
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
@@ -366,11 +359,13 @@ namespace platf::dxgi {
D3D_DRIVER_TYPE_UNKNOWN,
nullptr,
D3D11_CREATE_DEVICE_FLAGS,
featureLevels, sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL),
featureLevels,
sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL),
D3D11_SDK_VERSION,
&device,
nullptr,
nullptr);
nullptr
);
if (FAILED(status)) {
BOOST_LOG(error) << "Failed to create D3D11 device for DD test [0x"sv << util::hex(status).to_string_view() << ']';
return false;
@@ -403,8 +398,7 @@ namespace platf::dxgi {
// capture the current desktop, just bail immediately. Retrying won't help.
if (enumeration_only && status == E_ACCESSDENIED) {
break;
}
else {
} else {
std::this_thread::sleep_for(200ms);
}
}
@@ -418,8 +412,7 @@ namespace platf::dxgi {
* @param gpuPreference A pointer to the location where the preference will be written.
* @return Always STATUS_SUCCESS if valid arguments are provided.
*/
NTSTATUS
__stdcall NtGdiDdDDIGetCachedHybridQueryValueHook(D3DKMT_GPU_PREFERENCE_QUERY_STATE *gpuPreference) {
NTSTATUS __stdcall NtGdiDdDDIGetCachedHybridQueryValueHook(D3DKMT_GPU_PREFERENCE_QUERY_STATE *gpuPreference) {
// By faking a cached GPU preference state of D3DKMT_GPU_PREFERENCE_STATE_UNSPECIFIED, this will
// prevent DXGI from performing the normal GPU preference resolution that looks at the registry,
// power settings, and the hybrid adapter DDI interface to pick a GPU. Instead, we will not be
@@ -428,14 +421,12 @@ namespace platf::dxgi {
if (gpuPreference) {
*gpuPreference = D3DKMT_GPU_PREFERENCE_STATE_UNSPECIFIED;
return 0; // STATUS_SUCCESS
}
else {
} else {
return STATUS_INVALID_PARAMETER;
}
}
int
display_base_t::init(const ::video::config_t &config, const std::string &display_name) {
int display_base_t::init(const ::video::config_t &config, const std::string &display_name) {
std::once_flag windows_cpp_once_flag;
std::call_once(windows_cpp_once_flag, []() {
@@ -479,7 +470,7 @@ namespace platf::dxgi {
adapter_t::pointer adapter_p;
for (int tries = 0; tries < 2; ++tries) {
for (int x = 0; factory->EnumAdapters1(x, &adapter_p) != DXGI_ERROR_NOT_FOUND; ++x) {
dxgi::adapter_t adapter_tmp { adapter_p };
dxgi::adapter_t adapter_tmp {adapter_p};
DXGI_ADAPTER_DESC1 adapter_desc;
adapter_tmp->GetDesc1(&adapter_desc);
@@ -490,7 +481,7 @@ namespace platf::dxgi {
dxgi::output_t::pointer output_p;
for (int y = 0; adapter_tmp->EnumOutputs(y, &output_p) != DXGI_ERROR_NOT_FOUND; ++y) {
dxgi::output_t output_tmp { output_p };
dxgi::output_t output_tmp {output_p};
DXGI_OUTPUT_DESC desc;
output_tmp->GetDesc(&desc);
@@ -512,8 +503,7 @@ namespace platf::dxgi {
display_rotation == DXGI_MODE_ROTATION_ROTATE270) {
width_before_rotation = height;
height_before_rotation = width;
}
else {
} else {
width_before_rotation = width;
height_before_rotation = height;
}
@@ -570,11 +560,13 @@ namespace platf::dxgi {
D3D_DRIVER_TYPE_UNKNOWN,
nullptr,
D3D11_CREATE_DEVICE_FLAGS,
featureLevels, sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL),
featureLevels,
sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL),
D3D11_SDK_VERSION,
&device,
&feature_level,
&device_ctx);
&device_ctx
);
adapter_p->Release();
@@ -632,7 +624,7 @@ namespace platf::dxgi {
return false;
}
D3DKMT_OPENADAPTERFROMLUID d3dkmt_adapter = { adapter };
D3DKMT_OPENADAPTERFROMLUID d3dkmt_adapter = {adapter};
if (FAILED(d3dkmt_open_adapter(&d3dkmt_adapter))) {
BOOST_LOG(error) << "D3DKMTOpenAdapterFromLuid() failed while trying to determine GPU HAGS status";
return false;
@@ -649,13 +641,12 @@ namespace platf::dxgi {
if (SUCCEEDED(d3dkmt_query_adapter_info(&d3dkmt_adapter_info))) {
result = d3dkmt_adapter_caps.HwSchEnabled;
}
else {
} else {
BOOST_LOG(warning) << "D3DKMTQueryAdapterInfo() failed while trying to determine GPU HAGS status";
result = false;
}
D3DKMT_CLOSEADAPTER d3dkmt_close_adapter_wrap = { d3dkmt_adapter.hAdapter };
D3DKMT_CLOSEADAPTER d3dkmt_close_adapter_wrap = {d3dkmt_adapter.hAdapter};
if (FAILED(d3dkmt_close_adapter(&d3dkmt_close_adapter_wrap))) {
BOOST_LOG(error) << "D3DKMTCloseAdapter() failed while trying to determine GPU HAGS status";
}
@@ -671,15 +662,16 @@ namespace platf::dxgi {
// As of 2023.07, NVIDIA driver has unfixed bug(s) where "realtime" can cause unrecoverable encoding freeze or outright driver crash
// This issue happens more frequently with HAGS, in DX12 games or when VRAM is filled close to max capacity
// Track OBS to see if they find better workaround or NVIDIA fixes it on their end, they seem to be in communication
if (hags_enabled && !config::video.nv_realtime_hags) priority = D3DKMT_SCHEDULINGPRIORITYCLASS_HIGH;
if (hags_enabled && !config::video.nv_realtime_hags) {
priority = D3DKMT_SCHEDULINGPRIORITYCLASS_HIGH;
}
}
BOOST_LOG(info) << "Active GPU has HAGS " << (hags_enabled ? "enabled" : "disabled");
BOOST_LOG(info) << "Using " << (priority == D3DKMT_SCHEDULINGPRIORITYCLASS_HIGH ? "high" : "realtime") << " GPU priority";
if (FAILED(d3dkmt_set_process_priority(GetCurrentProcess(), priority))) {
BOOST_LOG(warning) << "Failed to adjust GPU priority. Please run application as administrator for optimal performance.";
}
}
else {
} else {
BOOST_LOG(error) << "Couldn't load D3DKMTSetProcessSchedulingPriorityClass function from gdi32.dll to adjust GPU priority";
}
}
@@ -740,8 +732,7 @@ namespace platf::dxgi {
return 0;
}
bool
display_base_t::is_hdr() {
bool display_base_t::is_hdr() {
dxgi::output6_t output6 {};
auto status = output->QueryInterface(IID_IDXGIOutput6, (void **) &output6);
@@ -756,8 +747,7 @@ namespace platf::dxgi {
return desc1.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
}
bool
display_base_t::get_hdr_metadata(SS_HDR_METADATA &metadata) {
bool display_base_t::get_hdr_metadata(SS_HDR_METADATA &metadata) {
dxgi::output6_t output6 {};
std::memset(&metadata, 0, sizeof(metadata));
@@ -928,20 +918,31 @@ namespace platf::dxgi {
"DXGI_FORMAT_A8P8",
"DXGI_FORMAT_B4G4R4A4_UNORM",
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
"DXGI_FORMAT_P208",
"DXGI_FORMAT_V208",
"DXGI_FORMAT_V408"
};
const char *
display_base_t::dxgi_format_to_string(DXGI_FORMAT format) {
const char *display_base_t::dxgi_format_to_string(DXGI_FORMAT format) {
return format_str[format];
}
const char *
display_base_t::colorspace_to_string(DXGI_COLOR_SPACE_TYPE type) {
const char *display_base_t::colorspace_to_string(DXGI_COLOR_SPACE_TYPE type) {
const char *type_str[] = {
"DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709",
"DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709",
@@ -972,8 +973,7 @@ namespace platf::dxgi {
if (type < ARRAYSIZE(type_str)) {
return type_str[type];
}
else {
} else {
return "UNKNOWN";
}
}
@@ -985,8 +985,7 @@ namespace platf {
* Pick a display adapter and capture method.
* @param hwdevice_type enables possible use of hardware encoder
*/
std::shared_ptr<display_t>
display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config) {
std::shared_ptr<display_t> display(mem_type_e hwdevice_type, const std::string &display_name, const video::config_t &config) {
if (config::video.capture == "ddx" || config::video.capture.empty()) {
if (hwdevice_type == mem_type_e::dxgi) {
auto disp = std::make_shared<dxgi::display_ddup_vram_t>();
@@ -994,8 +993,7 @@ namespace platf {
if (!disp->init(config, display_name)) {
return disp;
}
}
else if (hwdevice_type == mem_type_e::system) {
} else if (hwdevice_type == mem_type_e::system) {
auto disp = std::make_shared<dxgi::display_ddup_ram_t>();
if (!disp->init(config, display_name)) {
@@ -1011,8 +1009,7 @@ namespace platf {
if (!disp->init(config, display_name)) {
return disp;
}
}
else if (hwdevice_type == mem_type_e::system) {
} else if (hwdevice_type == mem_type_e::system) {
auto disp = std::make_shared<dxgi::display_wgc_ram_t>();
if (!disp->init(config, display_name)) {
@@ -1025,8 +1022,7 @@ namespace platf {
return nullptr;
}
std::vector<std::string>
display_names(mem_type_e) {
std::vector<std::string> display_names(mem_type_e) {
std::vector<std::string> display_names;
HRESULT status;
@@ -1066,7 +1062,7 @@ namespace platf {
dxgi::output_t::pointer output_p {};
for (int y = 0; adapter->EnumOutputs(y, &output_p) != DXGI_ERROR_NOT_FOUND; ++y) {
dxgi::output_t output { output_p };
dxgi::output_t output {output_p};
DXGI_OUTPUT_DESC desc;
output->GetDesc(&desc);
@@ -1096,8 +1092,7 @@ namespace platf {
* @brief Returns if GPUs/drivers have changed since the last call to this function.
* @return `true` if a change has occurred or if it is unknown whether a change occurred.
*/
bool
needs_encoder_reenumeration() {
bool needs_encoder_reenumeration() {
// Serialize access to the static DXGI factory
static std::mutex reenumeration_state_lock;
auto lg = std::lock_guard(reenumeration_state_lock);
@@ -1117,8 +1112,7 @@ namespace platf {
// can deal with any initialization races that may occur when the system is booting.
BOOST_LOG(info) << "Encoder reenumeration is required"sv;
return true;
}
else {
} else {
// The DXGI factory from last time is still current, so no encoder changes have occurred.
return false;
}