No more dumb pointers for initialization
This commit is contained in:
+4
-4
@@ -187,10 +187,10 @@ x509_t x509(const std::string_view &x) {
|
|||||||
|
|
||||||
BIO_write(io.get(), x.data(), x.size());
|
BIO_write(io.get(), x.data(), x.size());
|
||||||
|
|
||||||
X509 *p = nullptr;
|
x509_t p;
|
||||||
PEM_read_bio_X509(io.get(), &p, nullptr, nullptr);
|
PEM_read_bio_X509(io.get(), &p, nullptr, nullptr);
|
||||||
|
|
||||||
return x509_t { p };
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
pkey_t pkey(const std::string_view &k) {
|
pkey_t pkey(const std::string_view &k) {
|
||||||
@@ -198,10 +198,10 @@ pkey_t pkey(const std::string_view &k) {
|
|||||||
|
|
||||||
BIO_write(io.get(), k.data(), k.size());
|
BIO_write(io.get(), k.data(), k.size());
|
||||||
|
|
||||||
EVP_PKEY *p = nullptr;
|
pkey_t p = nullptr;
|
||||||
PEM_read_bio_PrivateKey(io.get(), &p, nullptr, nullptr);
|
PEM_read_bio_PrivateKey(io.get(), &p, nullptr, nullptr);
|
||||||
|
|
||||||
return pkey_t { p };
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string pem(x509_t &x509) {
|
std::string pem(x509_t &x509) {
|
||||||
|
|||||||
@@ -81,50 +81,43 @@ public:
|
|||||||
|
|
||||||
HRESULT status;
|
HRESULT status;
|
||||||
|
|
||||||
device_enum_t::pointer device_enum_p{};
|
|
||||||
status = CoCreateInstance(
|
status = CoCreateInstance(
|
||||||
CLSID_MMDeviceEnumerator,
|
CLSID_MMDeviceEnumerator,
|
||||||
nullptr,
|
nullptr,
|
||||||
CLSCTX_ALL,
|
CLSCTX_ALL,
|
||||||
IID_IMMDeviceEnumerator,
|
IID_IMMDeviceEnumerator,
|
||||||
(void **) &device_enum_p);
|
(void **) &device_enum);
|
||||||
device_enum.reset(device_enum_p);
|
|
||||||
|
|
||||||
if (FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Couldn't create Device Enumerator [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Couldn't create Device Enumerator [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
device_t::pointer device_p{};
|
|
||||||
|
|
||||||
if(config::audio.sink.empty()) {
|
if(config::audio.sink.empty()) {
|
||||||
status = device_enum->GetDefaultAudioEndpoint(
|
status = device_enum->GetDefaultAudioEndpoint(
|
||||||
eRender,
|
eRender,
|
||||||
eConsole,
|
eConsole,
|
||||||
&device_p);
|
&device);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter;
|
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> converter;
|
||||||
auto wstring_device_id = converter.from_bytes(config::audio.sink);
|
auto wstring_device_id = converter.from_bytes(config::audio.sink);
|
||||||
|
|
||||||
status = device_enum->GetDevice(wstring_device_id.c_str(), &device_p);
|
status = device_enum->GetDevice(wstring_device_id.c_str(), &device);
|
||||||
}
|
}
|
||||||
device.reset(device_p);
|
|
||||||
|
|
||||||
if (FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Couldn't create audio Device [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Couldn't create audio Device [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
audio_client_t::pointer audio_client_p{};
|
|
||||||
status = device->Activate(
|
status = device->Activate(
|
||||||
IID_IAudioClient,
|
IID_IAudioClient,
|
||||||
CLSCTX_ALL,
|
CLSCTX_ALL,
|
||||||
nullptr,
|
nullptr,
|
||||||
(void **) &audio_client_p);
|
(void **) &audio_client);
|
||||||
audio_client.reset(audio_client_p);
|
|
||||||
|
|
||||||
if (FAILED(status)) {
|
if (FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Couldn't activate audio Device [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Couldn't activate audio Device [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
@@ -132,11 +125,8 @@ public:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wave_format_t::pointer wave_format_p{};
|
status = audio_client->GetMixFormat(&wave_format);
|
||||||
status = audio_client->GetMixFormat(&wave_format_p);
|
if(FAILED(status)) {
|
||||||
wave_format.reset(wave_format_p);
|
|
||||||
|
|
||||||
if (FAILED(status)) {
|
|
||||||
BOOST_LOG(error) << "Couldn't acquire Wave Format [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Couldn't acquire Wave Format [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
@@ -198,9 +188,7 @@ public:
|
|||||||
sample_buf = util::buffer_t<std::int16_t> { frames };
|
sample_buf = util::buffer_t<std::int16_t> { frames };
|
||||||
sample_buf_pos = std::begin(sample_buf);
|
sample_buf_pos = std::begin(sample_buf);
|
||||||
|
|
||||||
audio_capture_t::pointer audio_capture_p {};
|
status = audio_client->GetService(IID_IAudioCaptureClient, (void**)&audio_capture);
|
||||||
status = audio_client->GetService(IID_IAudioCaptureClient, (void**)&audio_capture_p);
|
|
||||||
audio_capture.reset(audio_capture_p);
|
|
||||||
if (FAILED(status)) {
|
if (FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Couldn't initialize audio capture client [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Couldn't initialize audio capture client [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
|
|
||||||
|
|||||||
@@ -90,17 +90,10 @@ int display_base_t::init() {
|
|||||||
FreeLibrary(user32);
|
FreeLibrary(user32);
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dxgi::factory1_t::pointer factory_p {};
|
|
||||||
dxgi::adapter_t::pointer adapter_p {};
|
|
||||||
dxgi::output_t::pointer output_p {};
|
|
||||||
dxgi::device_t::pointer device_p {};
|
|
||||||
dxgi::device_ctx_t::pointer device_ctx_p {};
|
|
||||||
|
|
||||||
HRESULT status;
|
HRESULT status;
|
||||||
|
|
||||||
status = CreateDXGIFactory1(IID_IDXGIFactory1, (void**)&factory_p);
|
status = CreateDXGIFactory1(IID_IDXGIFactory1, (void**)&factory);
|
||||||
factory.reset(factory_p);
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to create DXGIFactory1 [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create DXGIFactory1 [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
@@ -111,7 +104,8 @@ int display_base_t::init() {
|
|||||||
auto adapter_name = converter.from_bytes(config::video.adapter_name);
|
auto adapter_name = converter.from_bytes(config::video.adapter_name);
|
||||||
auto output_name = converter.from_bytes(config::video.output_name);
|
auto output_name = converter.from_bytes(config::video.output_name);
|
||||||
|
|
||||||
for(int x = 0; factory_p->EnumAdapters1(x, &adapter_p) != DXGI_ERROR_NOT_FOUND; ++x) {
|
adapter_t::pointer adapter_p;
|
||||||
|
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;
|
DXGI_ADAPTER_DESC1 adapter_desc;
|
||||||
@@ -121,8 +115,9 @@ int display_base_t::init() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dxgi::output_t::pointer output_p;
|
||||||
for(int y = 0; adapter_tmp->EnumOutputs(y, &output_p) != DXGI_ERROR_NOT_FOUND; ++y) {
|
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;
|
DXGI_OUTPUT_DESC desc;
|
||||||
output_tmp->GetDesc(&desc);
|
output_tmp->GetDesc(&desc);
|
||||||
@@ -173,14 +168,12 @@ int display_base_t::init() {
|
|||||||
D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
|
D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
|
||||||
featureLevels, sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL),
|
featureLevels, sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL),
|
||||||
D3D11_SDK_VERSION,
|
D3D11_SDK_VERSION,
|
||||||
&device_p,
|
&device,
|
||||||
&feature_level,
|
&feature_level,
|
||||||
&device_ctx_p);
|
&device_ctx);
|
||||||
|
|
||||||
adapter_p->Release();
|
adapter_p->Release();
|
||||||
|
|
||||||
device.reset(device_p);
|
|
||||||
device_ctx.reset(device_ctx_p);
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to create D3D11 device [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create D3D11 device [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
|
|
||||||
@@ -216,7 +209,7 @@ int display_base_t::init() {
|
|||||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
|
||||||
if (!AdjustTokenPrivileges(token, false, &tp, sizeof(tp), NULL, NULL)) {
|
if (!AdjustTokenPrivileges(token, false, &tp, sizeof(tp), NULL, NULL)) {
|
||||||
BOOST_LOG(error) << "Could not set privilege to increase GPU priority";
|
BOOST_LOG(warning) << "Could not set privilege to increase GPU priority";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,17 +222,15 @@ int display_base_t::init() {
|
|||||||
if (fn) {
|
if (fn) {
|
||||||
status = fn(GetCurrentProcess(), D3DKMT_SCHEDULINGPRIORITYCLASS_REALTIME);
|
status = fn(GetCurrentProcess(), D3DKMT_SCHEDULINGPRIORITYCLASS_REALTIME);
|
||||||
if (FAILED(status)) {
|
if (FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to set realtime GPU priority. Please run application as administrator for optimal performance.";
|
BOOST_LOG(warning) << "Failed to set realtime GPU priority. Please run application as administrator for optimal performance.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dxgi::dxgi_t::pointer dxgi_p {};
|
dxgi::dxgi_t dxgi;
|
||||||
status = device->QueryInterface(IID_IDXGIDevice, (void**)&dxgi_p);
|
status = device->QueryInterface(IID_IDXGIDevice, (void**)&dxgi);
|
||||||
dxgi::dxgi_t dxgi { dxgi_p };
|
|
||||||
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to query DXGI interface from device [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(warning) << "Failed to query DXGI interface from device [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,25 +239,24 @@ int display_base_t::init() {
|
|||||||
|
|
||||||
// Try to reduce latency
|
// Try to reduce latency
|
||||||
{
|
{
|
||||||
dxgi::dxgi1_t::pointer dxgi_p {};
|
dxgi::dxgi1_t dxgi {};
|
||||||
status = device->QueryInterface(IID_IDXGIDevice, (void**)&dxgi_p);
|
status = device->QueryInterface(IID_IDXGIDevice, (void**)&dxgi);
|
||||||
dxgi::dxgi1_t dxgi { dxgi_p };
|
|
||||||
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to query DXGI interface from device [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to query DXGI interface from device [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dxgi->SetMaximumFrameLatency(1);
|
status = dxgi->SetMaximumFrameLatency(1);
|
||||||
|
if(FAILED(status)) {
|
||||||
|
BOOST_LOG(warning) << "Failed to set maximum frame latency [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: Duplicate output on RX580 in combination with DOOM (2016) --> BSOD
|
//FIXME: Duplicate output on RX580 in combination with DOOM (2016) --> BSOD
|
||||||
//TODO: Use IDXGIOutput5 for improved performance
|
//TODO: Use IDXGIOutput5 for improved performance
|
||||||
{
|
{
|
||||||
dxgi::output1_t::pointer output1_p {};
|
dxgi::output1_t output1 {};
|
||||||
status = output->QueryInterface(IID_IDXGIOutput1, (void**)&output1_p);
|
status = output->QueryInterface(IID_IDXGIOutput1, (void**)&output1);
|
||||||
dxgi::output1_t output1 {output1_p };
|
|
||||||
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to query IDXGIOutput1 from the output"sv;
|
BOOST_LOG(error) << "Failed to query IDXGIOutput1 from the output"sv;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -274,10 +264,8 @@ int display_base_t::init() {
|
|||||||
|
|
||||||
// We try this twice, in case we still get an error on reinitialization
|
// We try this twice, in case we still get an error on reinitialization
|
||||||
for(int x = 0; x < 2; ++x) {
|
for(int x = 0; x < 2; ++x) {
|
||||||
dxgi::dup_t::pointer dup_p {};
|
status = output1->DuplicateOutput((IUnknown*)device.get(), &dup.dup);
|
||||||
status = output1->DuplicateOutput((IUnknown*)device.get(), &dup_p);
|
|
||||||
if(SUCCEEDED(status)) {
|
if(SUCCEEDED(status)) {
|
||||||
dup.reset(dup_p);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::this_thread::sleep_for(200ms);
|
std::this_thread::sleep_for(200ms);
|
||||||
|
|||||||
@@ -203,9 +203,8 @@ capture_e display_ram_t::snapshot(::platf::img_t *img_base, std::chrono::millise
|
|||||||
// If frame has been updated
|
// If frame has been updated
|
||||||
if (frame_info.LastPresentTime.QuadPart != 0) {
|
if (frame_info.LastPresentTime.QuadPart != 0) {
|
||||||
{
|
{
|
||||||
texture2d_t::pointer src_p {};
|
texture2d_t src {};
|
||||||
status = res->QueryInterface(IID_ID3D11Texture2D, (void **)&src_p);
|
status = res->QueryInterface(IID_ID3D11Texture2D, (void **)&src);
|
||||||
texture2d_t src{src_p};
|
|
||||||
|
|
||||||
if (FAILED(status)) {
|
if (FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Couldn't query interface [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Couldn't query interface [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
@@ -279,10 +278,7 @@ int display_ram_t::init() {
|
|||||||
t.Format = format;
|
t.Format = format;
|
||||||
t.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
t.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||||
|
|
||||||
dxgi::texture2d_t::pointer tex_p {};
|
auto status = device->CreateTexture2D(&t, nullptr, &texture);
|
||||||
auto status = device->CreateTexture2D(&t, nullptr, &tex_p);
|
|
||||||
|
|
||||||
texture.reset(tex_p);
|
|
||||||
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to create texture [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create texture [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
|
|||||||
@@ -106,14 +106,14 @@ blend_t make_blend(device_t::pointer device, bool enable) {
|
|||||||
rt.DestBlendAlpha = D3D11_BLEND_ZERO;
|
rt.DestBlendAlpha = D3D11_BLEND_ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
blend_t::pointer blend_p;
|
blend_t blend;
|
||||||
auto status = device->CreateBlendState(&bdesc, &blend_p);
|
auto status = device->CreateBlendState(&bdesc, &blend);
|
||||||
if(status) {
|
if(status) {
|
||||||
BOOST_LOG(error) << "Failed to create blend state: [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create blend state: [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return blend_t { blend_p };
|
return blend;
|
||||||
}
|
}
|
||||||
|
|
||||||
blob_t convert_UV_vs_hlsl;
|
blob_t convert_UV_vs_hlsl;
|
||||||
@@ -280,13 +280,11 @@ public:
|
|||||||
};
|
};
|
||||||
desc.Texture2D.MipLevels = 1;
|
desc.Texture2D.MipLevels = 1;
|
||||||
|
|
||||||
shader_res_t::pointer cursor_res_p;
|
auto status = device->CreateShaderResourceView(texture, &desc, &img.input_res);
|
||||||
auto status = device->CreateShaderResourceView(texture, &desc, &cursor_res_p);
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to create cursor shader resource view [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create cursor shader resource view [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
img.input_res.reset(cursor_res_p);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -303,26 +301,19 @@ public:
|
|||||||
};
|
};
|
||||||
desc.Texture2D.MipLevels = 1;
|
desc.Texture2D.MipLevels = 1;
|
||||||
|
|
||||||
shader_res_t::pointer input_res_p;
|
auto status = device->CreateShaderResourceView(img.texture.get(), &desc, &img.input_res);
|
||||||
auto status = device->CreateShaderResourceView(img.texture.get(), &desc, &input_res_p);
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to create input shader resource view [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create input shader resource view [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
img.input_res.reset(input_res_p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto input_res_p = img.input_res.get();
|
auto input_res_p = img.input_res.get();
|
||||||
auto cursor_res_p = this->img.input_res.get();
|
|
||||||
|
|
||||||
auto scene_rt_p = scene_rt.get();
|
|
||||||
auto Y_rt_p = nv12_Y_rt.get();
|
|
||||||
auto UV_rt_p = nv12_UV_rt.get();
|
|
||||||
|
|
||||||
if(cursor_visible) {
|
if(cursor_visible) {
|
||||||
_init_view_port(img.width, img.height);
|
_init_view_port(img.width, img.height);
|
||||||
|
|
||||||
device_ctx_p->OMSetRenderTargets(1, &scene_rt_p, nullptr);
|
device_ctx_p->OMSetRenderTargets(1, &scene_rt, nullptr);
|
||||||
device_ctx_p->VSSetShader(scene_vs.get(), nullptr, 0);
|
device_ctx_p->VSSetShader(scene_vs.get(), nullptr, 0);
|
||||||
device_ctx_p->PSSetShader(scene_ps.get(), nullptr, 0);
|
device_ctx_p->PSSetShader(scene_ps.get(), nullptr, 0);
|
||||||
device_ctx_p->PSSetShaderResources(0, 1, &input_res_p);
|
device_ctx_p->PSSetShaderResources(0, 1, &input_res_p);
|
||||||
@@ -331,7 +322,7 @@ public:
|
|||||||
|
|
||||||
device_ctx_p->OMSetBlendState(blend_enable.get(), nullptr, 0xFFFFFFFFu);
|
device_ctx_p->OMSetBlendState(blend_enable.get(), nullptr, 0xFFFFFFFFu);
|
||||||
device_ctx_p->RSSetViewports(1, &cursor_view);
|
device_ctx_p->RSSetViewports(1, &cursor_view);
|
||||||
device_ctx_p->PSSetShaderResources(0, 1, &cursor_res_p);
|
device_ctx_p->PSSetShaderResources(0, 1, &this->img.input_res);
|
||||||
device_ctx_p->Draw(3, 0);
|
device_ctx_p->Draw(3, 0);
|
||||||
device_ctx_p->OMSetBlendState(blend_disable.get(), nullptr, 0xFFFFFFFFu);
|
device_ctx_p->OMSetBlendState(blend_disable.get(), nullptr, 0xFFFFFFFFu);
|
||||||
|
|
||||||
@@ -339,14 +330,14 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
_init_view_port(out_width, out_height);
|
_init_view_port(out_width, out_height);
|
||||||
device_ctx_p->OMSetRenderTargets(1, &Y_rt_p, nullptr);
|
device_ctx_p->OMSetRenderTargets(1, &nv12_Y_rt, nullptr);
|
||||||
device_ctx_p->VSSetShader(scene_vs.get(), nullptr, 0);
|
device_ctx_p->VSSetShader(scene_vs.get(), nullptr, 0);
|
||||||
device_ctx_p->PSSetShader(convert_Y_ps.get(), nullptr, 0);
|
device_ctx_p->PSSetShader(convert_Y_ps.get(), nullptr, 0);
|
||||||
device_ctx_p->PSSetShaderResources(0, 1, &input_res_p);
|
device_ctx_p->PSSetShaderResources(0, 1, &input_res_p);
|
||||||
device_ctx_p->Draw(3, 0);
|
device_ctx_p->Draw(3, 0);
|
||||||
|
|
||||||
_init_view_port(out_width / 2, out_height / 2);
|
_init_view_port(out_width / 2, out_height / 2);
|
||||||
device_ctx_p->OMSetRenderTargets(1, &UV_rt_p, nullptr);
|
device_ctx_p->OMSetRenderTargets(1, &nv12_UV_rt, nullptr);
|
||||||
device_ctx_p->VSSetShader(convert_UV_vs.get(), nullptr, 0);
|
device_ctx_p->VSSetShader(convert_UV_vs.get(), nullptr, 0);
|
||||||
device_ctx_p->PSSetShader(convert_UV_ps.get(), nullptr, 0);
|
device_ctx_p->PSSetShader(convert_UV_ps.get(), nullptr, 0);
|
||||||
device_ctx_p->PSSetShaderResources(0, 1, &input_res_p);
|
device_ctx_p->PSSetShaderResources(0, 1, &input_res_p);
|
||||||
@@ -380,8 +371,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto buf_p = color_matrix.get();
|
device_ctx_p->PSSetConstantBuffers(0, 1, &color_matrix);
|
||||||
device_ctx_p->PSSetConstantBuffers(0, 1, &buf_p);
|
|
||||||
this->color_matrix = std::move(color_matrix);
|
this->color_matrix = std::move(color_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,46 +396,43 @@ public:
|
|||||||
this->out_width = out_width;
|
this->out_width = out_width;
|
||||||
this->out_height = out_height;
|
this->out_height = out_height;
|
||||||
|
|
||||||
vs_t::pointer vs_p;
|
status = device_p->CreateVertexShader(scene_vs_hlsl->GetBufferPointer(), scene_vs_hlsl->GetBufferSize(), nullptr, &scene_vs);
|
||||||
status = device_p->CreateVertexShader(scene_vs_hlsl->GetBufferPointer(), scene_vs_hlsl->GetBufferSize(), nullptr, &vs_p);
|
|
||||||
if(status) {
|
if(status) {
|
||||||
BOOST_LOG(error) << "Failed to create mergeY vertex shader [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create scene vertex shader [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
scene_vs.reset(vs_p);
|
|
||||||
|
|
||||||
ps_t::pointer ps_p;
|
status = device_p->CreatePixelShader(convert_Y_ps_hlsl->GetBufferPointer(), convert_Y_ps_hlsl->GetBufferSize(), nullptr, &convert_Y_ps);
|
||||||
status = device_p->CreatePixelShader(convert_Y_ps_hlsl->GetBufferPointer(), convert_Y_ps_hlsl->GetBufferSize(), nullptr, &ps_p);
|
|
||||||
if(status) {
|
if(status) {
|
||||||
BOOST_LOG(error) << "Failed to create mergeY pixel shader [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create convertY pixel shader [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
convert_Y_ps.reset(ps_p);
|
|
||||||
|
|
||||||
status = device_p->CreatePixelShader(convert_UV_ps_hlsl->GetBufferPointer(), convert_UV_ps_hlsl->GetBufferSize(), nullptr, &ps_p);
|
status = device_p->CreatePixelShader(convert_UV_ps_hlsl->GetBufferPointer(), convert_UV_ps_hlsl->GetBufferSize(), nullptr, &convert_UV_ps);
|
||||||
if(status) {
|
if(status) {
|
||||||
BOOST_LOG(error) << "Failed to create mergeUV pixel shader [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create convertUV pixel shader [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
convert_UV_ps.reset(ps_p);
|
|
||||||
|
|
||||||
status = device_p->CreateVertexShader(convert_UV_vs_hlsl->GetBufferPointer(), convert_UV_vs_hlsl->GetBufferSize(), nullptr, &vs_p);
|
status = device_p->CreateVertexShader(convert_UV_vs_hlsl->GetBufferPointer(), convert_UV_vs_hlsl->GetBufferSize(), nullptr, &convert_UV_vs);
|
||||||
if(status) {
|
if(status) {
|
||||||
BOOST_LOG(error) << "Failed to create mergeUV vertex shader [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create convertUV vertex shader [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
convert_UV_vs.reset(vs_p);
|
|
||||||
|
|
||||||
status = device_p->CreatePixelShader(scene_ps_hlsl->GetBufferPointer(), scene_ps_hlsl->GetBufferSize(), nullptr, &ps_p);
|
status = device_p->CreatePixelShader(scene_ps_hlsl->GetBufferPointer(), scene_ps_hlsl->GetBufferSize(), nullptr, &scene_ps);
|
||||||
if(status) {
|
if(status) {
|
||||||
BOOST_LOG(error) << "Failed to create scene pixel shader [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create scene pixel shader [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
scene_ps.reset(ps_p);
|
|
||||||
|
|
||||||
blend_disable = make_blend(device_p, false);
|
blend_disable = make_blend(device_p, false);
|
||||||
blend_enable = make_blend(device_p, true);
|
blend_enable = make_blend(device_p, true);
|
||||||
|
|
||||||
|
if(!blend_disable || !blend_enable) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if(_init_rt(scene_sr, scene_rt, in_width, in_height, DXGI_FORMAT_B8G8R8A8_UNORM)) {
|
if(_init_rt(scene_sr, scene_rt, in_width, in_height, DXGI_FORMAT_B8G8R8A8_UNORM)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -467,12 +454,10 @@ public:
|
|||||||
"SV_Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0
|
"SV_Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
input_layout_t::pointer input_layout_p;
|
|
||||||
status = device_p->CreateInputLayout(
|
status = device_p->CreateInputLayout(
|
||||||
&layout_desc, 1,
|
&layout_desc, 1,
|
||||||
convert_UV_vs_hlsl->GetBufferPointer(), convert_UV_vs_hlsl->GetBufferSize(),
|
convert_UV_vs_hlsl->GetBufferPointer(), convert_UV_vs_hlsl->GetBufferSize(),
|
||||||
&input_layout_p);
|
&input_layout);
|
||||||
input_layout.reset(input_layout_p);
|
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC t {};
|
D3D11_TEXTURE2D_DESC t {};
|
||||||
t.Width = out_width;
|
t.Width = out_width;
|
||||||
@@ -484,18 +469,16 @@ public:
|
|||||||
t.Format = pix_fmt == pix_fmt_e::nv12 ? DXGI_FORMAT_NV12 : DXGI_FORMAT_P010;
|
t.Format = pix_fmt == pix_fmt_e::nv12 ? DXGI_FORMAT_NV12 : DXGI_FORMAT_P010;
|
||||||
t.BindFlags = D3D11_BIND_RENDER_TARGET;
|
t.BindFlags = D3D11_BIND_RENDER_TARGET;
|
||||||
|
|
||||||
dxgi::texture2d_t::pointer tex_p {};
|
status = device_p->CreateTexture2D(&t, nullptr, &img.texture);
|
||||||
status = device_p->CreateTexture2D(&t, nullptr, &tex_p);
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to create render target texture [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create render target texture [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
img.texture.reset(tex_p);
|
|
||||||
img.display = std::move(display);
|
img.display = std::move(display);
|
||||||
img.width = out_width;
|
img.width = out_width;
|
||||||
img.height = out_height;
|
img.height = out_height;
|
||||||
img.data = (std::uint8_t*)tex_p;
|
img.data = (std::uint8_t*)img.texture.get();
|
||||||
img.row_pitch = out_width;
|
img.row_pitch = out_width;
|
||||||
img.pixel_pitch = 1;
|
img.pixel_pitch = 1;
|
||||||
|
|
||||||
@@ -504,21 +487,18 @@ public:
|
|||||||
D3D11_RTV_DIMENSION_TEXTURE2D
|
D3D11_RTV_DIMENSION_TEXTURE2D
|
||||||
};
|
};
|
||||||
|
|
||||||
render_target_t::pointer nv12_rt_p;
|
status = device_p->CreateRenderTargetView(img.texture.get(), &nv12_rt_desc, &nv12_Y_rt);
|
||||||
status = device_p->CreateRenderTargetView(img.texture.get(), &nv12_rt_desc, &nv12_rt_p);
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to create render target view [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create render target view [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
nv12_Y_rt.reset(nv12_rt_p);
|
|
||||||
|
|
||||||
nv12_rt_desc.Format = DXGI_FORMAT_R8G8_UNORM;
|
nv12_rt_desc.Format = DXGI_FORMAT_R8G8_UNORM;
|
||||||
status = device_p->CreateRenderTargetView(img.texture.get(), &nv12_rt_desc, &nv12_rt_p);
|
status = device_p->CreateRenderTargetView(img.texture.get(), &nv12_rt_desc, &nv12_UV_rt);
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to create render target view [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create render target view [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
nv12_UV_rt.reset(nv12_rt_p);
|
|
||||||
|
|
||||||
D3D11_SAMPLER_DESC sampler_desc {};
|
D3D11_SAMPLER_DESC sampler_desc {};
|
||||||
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
@@ -529,21 +509,16 @@ public:
|
|||||||
sampler_desc.MinLOD = 0;
|
sampler_desc.MinLOD = 0;
|
||||||
sampler_desc.MaxLOD = D3D11_FLOAT32_MAX;
|
sampler_desc.MaxLOD = D3D11_FLOAT32_MAX;
|
||||||
|
|
||||||
sampler_state_t::pointer sampler_state_p;
|
status = device_p->CreateSamplerState(&sampler_desc, &sampler_linear);
|
||||||
status = device_p->CreateSamplerState(&sampler_desc, &sampler_state_p);
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to create point sampler state [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create point sampler state [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
sampler_linear.reset(sampler_state_p);
|
|
||||||
|
|
||||||
auto sampler_linear_p = sampler_linear.get();
|
|
||||||
auto color_matrix_buf_p = color_matrix.get();
|
|
||||||
auto info_buf_p = info_scene.get();
|
|
||||||
device_ctx_p->OMSetBlendState(blend_disable.get(), nullptr, 0xFFFFFFFFu);
|
device_ctx_p->OMSetBlendState(blend_disable.get(), nullptr, 0xFFFFFFFFu);
|
||||||
device_ctx_p->PSSetSamplers(0, 1, &sampler_linear_p);
|
device_ctx_p->PSSetSamplers(0, 1, &sampler_linear);
|
||||||
device_ctx_p->PSSetConstantBuffers(0, 1, &color_matrix_buf_p);
|
device_ctx_p->PSSetConstantBuffers(0, 1, &color_matrix);
|
||||||
device_ctx_p->VSSetConstantBuffers(0, 1, &info_buf_p);
|
device_ctx_p->VSSetConstantBuffers(0, 1, &info_scene);
|
||||||
device_ctx_p->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
device_ctx_p->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
|
||||||
device_ctx_p->IASetInputLayout(input_layout.get());
|
device_ctx_p->IASetInputLayout(input_layout.get());
|
||||||
|
|
||||||
@@ -589,13 +564,12 @@ private:
|
|||||||
|
|
||||||
auto device = (device_t::pointer)data;
|
auto device = (device_t::pointer)data;
|
||||||
|
|
||||||
texture2d_t::pointer tex_p;
|
texture2d_t tex;
|
||||||
auto status = device->CreateTexture2D(&desc, nullptr, &tex_p);
|
auto status = device->CreateTexture2D(&desc, nullptr, &tex);
|
||||||
if(status) {
|
if(status) {
|
||||||
BOOST_LOG(error) << "Failed to create render target texture for luma [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create render target texture for luma [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
texture2d_t tex { tex_p };
|
|
||||||
|
|
||||||
|
|
||||||
D3D11_SHADER_RESOURCE_VIEW_DESC shader_resource_desc {
|
D3D11_SHADER_RESOURCE_VIEW_DESC shader_resource_desc {
|
||||||
@@ -604,26 +578,22 @@ private:
|
|||||||
};
|
};
|
||||||
shader_resource_desc.Texture2D.MipLevels = 1;
|
shader_resource_desc.Texture2D.MipLevels = 1;
|
||||||
|
|
||||||
shader_res_t::pointer shader_res_p;
|
device->CreateShaderResourceView(tex.get(), &shader_resource_desc, &shader_res);
|
||||||
device->CreateShaderResourceView(tex_p, &shader_resource_desc, &shader_res_p);
|
|
||||||
if(status) {
|
if(status) {
|
||||||
BOOST_LOG(error) << "Failed to create render target texture for luma [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create render target texture for luma [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
shader_res.reset(shader_res_p);
|
|
||||||
|
|
||||||
D3D11_RENDER_TARGET_VIEW_DESC render_target_desc {
|
D3D11_RENDER_TARGET_VIEW_DESC render_target_desc {
|
||||||
format,
|
format,
|
||||||
D3D11_RTV_DIMENSION_TEXTURE2D
|
D3D11_RTV_DIMENSION_TEXTURE2D
|
||||||
};
|
};
|
||||||
|
|
||||||
render_target_t::pointer render_target_p;
|
device->CreateRenderTargetView(tex.get(), &render_target_desc, &render_target);
|
||||||
device->CreateRenderTargetView(tex_p, &render_target_desc, &render_target_p);
|
|
||||||
if(status) {
|
if(status) {
|
||||||
BOOST_LOG(error) << "Failed to create render target view [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create render target view [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
render_target.reset(render_target_p);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -721,16 +691,15 @@ capture_e display_vram_t::snapshot(platf::img_t *img_base, std::chrono::millisec
|
|||||||
t.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
t.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
t.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
t.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
|
||||||
dxgi::texture2d_t::pointer tex_p {};
|
texture2d_t texture;
|
||||||
auto status = device->CreateTexture2D(&t, &data, &tex_p);
|
auto status = device->CreateTexture2D(&t, &data, &texture);
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to create mouse texture [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create mouse texture [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return capture_e::error;
|
return capture_e::error;
|
||||||
}
|
}
|
||||||
texture2d_t texture { tex_p };
|
|
||||||
|
|
||||||
for(auto *hwdevice : hwdevices) {
|
for(auto *hwdevice : hwdevices) {
|
||||||
if(hwdevice->set_cursor_texture(tex_p, t.Width, t.Height)) {
|
if(hwdevice->set_cursor_texture(texture.get(), t.Width, t.Height)) {
|
||||||
return capture_e::error;
|
return capture_e::error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -747,15 +716,14 @@ capture_e display_vram_t::snapshot(platf::img_t *img_base, std::chrono::millisec
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(frame_update_flag) {
|
if(frame_update_flag) {
|
||||||
texture2d_t::pointer src_p {};
|
texture2d_t src;
|
||||||
status = res->QueryInterface(IID_ID3D11Texture2D, (void **)&src_p);
|
status = res->QueryInterface(IID_ID3D11Texture2D, (void **)&src);
|
||||||
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Couldn't query interface [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Couldn't query interface [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return capture_e::error;
|
return capture_e::error;
|
||||||
}
|
}
|
||||||
|
|
||||||
texture2d_t src { src_p };
|
|
||||||
device_ctx->CopyResource(img->texture.get(), src.get());
|
device_ctx->CopyResource(img->texture.get(), src.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -775,15 +743,13 @@ std::shared_ptr<platf::img_t> display_vram_t::alloc_img() {
|
|||||||
t.Format = format;
|
t.Format = format;
|
||||||
t.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
t.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
|
||||||
dxgi::texture2d_t::pointer tex_p {};
|
auto status = device->CreateTexture2D(&t, nullptr, &img->texture);
|
||||||
auto status = device->CreateTexture2D(&t, nullptr, &tex_p);
|
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to create img buf texture [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create img buf texture [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
img->texture.reset(tex_p);
|
img->data = (std::uint8_t*)img->texture.get();
|
||||||
img->data = (std::uint8_t*)tex_p;
|
|
||||||
img->row_pitch = 0;
|
img->row_pitch = 0;
|
||||||
img->pixel_pitch = 4;
|
img->pixel_pitch = 4;
|
||||||
img->width = 0;
|
img->width = 0;
|
||||||
@@ -813,15 +779,15 @@ int display_vram_t::dummy_img(platf::img_t *img_base) {
|
|||||||
t.Format = format;
|
t.Format = format;
|
||||||
t.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
t.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
|
||||||
dxgi::texture2d_t::pointer tex_p {};
|
dxgi::texture2d_t tex;
|
||||||
auto status = device->CreateTexture2D(&t, &data, &tex_p);
|
auto status = device->CreateTexture2D(&t, &data, &tex);
|
||||||
if(FAILED(status)) {
|
if(FAILED(status)) {
|
||||||
BOOST_LOG(error) << "Failed to create dummy texture [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "Failed to create dummy texture [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
img->texture.reset(tex_p);
|
img->texture = std::move(tex);
|
||||||
img->data = (std::uint8_t*)tex_p;
|
img->data = (std::uint8_t*)img->texture.get();
|
||||||
img->height = height;
|
img->height = height;
|
||||||
img->width = width;
|
img->width = width;
|
||||||
img->pixel_pitch = 4;
|
img->pixel_pitch = 4;
|
||||||
|
|||||||
+223
-60
@@ -76,37 +76,6 @@ struct __either<false, X, Y> {
|
|||||||
template<bool V, class X, class Y>
|
template<bool V, class X, class Y>
|
||||||
using either_t = typename __either<V, X, Y>::type;
|
using either_t = typename __either<V, X, Y>::type;
|
||||||
|
|
||||||
template<class T, class V = void>
|
|
||||||
struct __false_v;
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct __false_v<T, std::enable_if_t<instantiation_of_v<std::optional, T>>> {
|
|
||||||
static constexpr std::nullopt_t value = std::nullopt;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct __false_v<T, std::enable_if_t<
|
|
||||||
(std::is_pointer_v<T> || instantiation_of_v<std::unique_ptr, T> || instantiation_of_v<std::shared_ptr, T>)
|
|
||||||
>> {
|
|
||||||
static constexpr std::nullptr_t value = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct __false_v<T, std::enable_if_t<std::is_same_v<T, bool>>> {
|
|
||||||
static constexpr bool value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
static constexpr auto false_v = __false_v<T>::value;
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
using optional_t = either_t<
|
|
||||||
(std::is_same_v<T, bool> ||
|
|
||||||
instantiation_of_v<std::unique_ptr, T> ||
|
|
||||||
instantiation_of_v<std::shared_ptr, T> ||
|
|
||||||
std::is_pointer_v<T>),
|
|
||||||
T, std::optional<T>>;
|
|
||||||
|
|
||||||
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
|
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
|
||||||
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
|
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
|
||||||
|
|
||||||
@@ -362,35 +331,6 @@ auto enm(T& val) -> std::underlying_type_t<T>& {
|
|||||||
return *reinterpret_cast<std::underlying_type_t<T>*>(&val);
|
return *reinterpret_cast<std::underlying_type_t<T>*>(&val);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class ReturnType, class ...Args>
|
|
||||||
struct Function {
|
|
||||||
typedef ReturnType (*type)(Args...);
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T, class ReturnType, typename Function<ReturnType, T>::type function>
|
|
||||||
struct Destroy {
|
|
||||||
typedef T pointer;
|
|
||||||
|
|
||||||
void operator()(pointer p) {
|
|
||||||
function(p);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T, typename Function<void, T*>::type function>
|
|
||||||
using safe_ptr = std::unique_ptr<T, Destroy<T*, void, function>>;
|
|
||||||
|
|
||||||
// You cannot specialize an alias
|
|
||||||
template<class T, class ReturnType, typename Function<ReturnType, T*>::type function>
|
|
||||||
using safe_ptr_v2 = std::unique_ptr<T, Destroy<T*, ReturnType, function>>;
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
void c_free(T *p) {
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
using c_ptr = safe_ptr<T, c_free<T>>;
|
|
||||||
|
|
||||||
inline std::int64_t from_chars(const char *begin, const char *end) {
|
inline std::int64_t from_chars(const char *begin, const char *end) {
|
||||||
std::int64_t res {};
|
std::int64_t res {};
|
||||||
std::int64_t mul = 1;
|
std::int64_t mul = 1;
|
||||||
@@ -436,6 +376,163 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Compared to std::unique_ptr, it adds the ability to get the address of the pointer itself
|
||||||
|
template <typename T, typename D = std::default_delete<T>>
|
||||||
|
class uniq_ptr {
|
||||||
|
public:
|
||||||
|
using element_type = T;
|
||||||
|
using pointer = element_type*;
|
||||||
|
using deleter_type = D;
|
||||||
|
|
||||||
|
constexpr uniq_ptr() noexcept : _p { nullptr } {}
|
||||||
|
constexpr uniq_ptr(std::nullptr_t) noexcept : _p { nullptr } {}
|
||||||
|
|
||||||
|
uniq_ptr(const uniq_ptr &other) noexcept = delete;
|
||||||
|
uniq_ptr &operator=(const uniq_ptr &other) noexcept = delete;
|
||||||
|
|
||||||
|
template<class V>
|
||||||
|
uniq_ptr(V *p) noexcept : _p { p } {
|
||||||
|
static_assert(std::is_same_v<element_type, void> || std::is_same_v<element_type, V> || std::is_base_of_v<element_type, V>, "element_type must be base class of V");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class V>
|
||||||
|
uniq_ptr(std::unique_ptr<V, deleter_type> &&uniq) noexcept : _p { uniq.release() } {
|
||||||
|
static_assert(std::is_same_v<element_type, void> || std::is_same_v<T, V> || std::is_base_of_v<element_type, V>, "element_type must be base class of V");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class V>
|
||||||
|
uniq_ptr(uniq_ptr<V, deleter_type> &&other) noexcept : _p { other.release() } {
|
||||||
|
static_assert(std::is_same_v<element_type, void> || std::is_same_v<T, V> || std::is_base_of_v<element_type, V>, "element_type must be base class of V");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class V>
|
||||||
|
uniq_ptr &operator=(uniq_ptr<V, deleter_type> &&other) noexcept {
|
||||||
|
static_assert(std::is_same_v<element_type, void> || std::is_same_v<T, V> || std::is_base_of_v<element_type, V>, "element_type must be base class of V");
|
||||||
|
reset(other.release());
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class V>
|
||||||
|
uniq_ptr &operator=(std::unique_ptr<V, deleter_type> &&uniq) noexcept {
|
||||||
|
static_assert(std::is_same_v<element_type, void> || std::is_same_v<T, V> || std::is_base_of_v<element_type, V>, "element_type must be base class of V");
|
||||||
|
|
||||||
|
reset(uniq.release());
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~uniq_ptr() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(pointer p = pointer()) {
|
||||||
|
if(_p) {
|
||||||
|
_deleter(_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
_p = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer release() {
|
||||||
|
auto tmp = _p;
|
||||||
|
_p = nullptr;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer get() {
|
||||||
|
return _p;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pointer get() const {
|
||||||
|
return _p;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::add_lvalue_reference_t<element_type> operator*() const {
|
||||||
|
return *_p;
|
||||||
|
}
|
||||||
|
std::add_lvalue_reference_t<element_type> operator*() {
|
||||||
|
return *_p;
|
||||||
|
}
|
||||||
|
const pointer operator->() const {
|
||||||
|
return _p;
|
||||||
|
}
|
||||||
|
pointer operator->() {
|
||||||
|
return _p;
|
||||||
|
}
|
||||||
|
pointer *operator&() const {
|
||||||
|
return &_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer *operator&() {
|
||||||
|
return &_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleter_type& get_deleter() {
|
||||||
|
return _deleter;
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleter_type& get_deleter() const {
|
||||||
|
return _deleter;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator bool() const {
|
||||||
|
return _p != nullptr;
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
pointer _p;
|
||||||
|
deleter_type _deleter;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T1, class D1, class T2, class D2>
|
||||||
|
bool operator==(const uniq_ptr<T1, D1>& x, const uniq_ptr<T2, D2>& y) {
|
||||||
|
return x.get() == y.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T1, class D1, class T2, class D2>
|
||||||
|
bool operator!=(const uniq_ptr<T1, D1>& x, const uniq_ptr<T2, D2>& y) {
|
||||||
|
return x.get() != y.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T1, class D1, class T2, class D2>
|
||||||
|
bool operator==(const std::unique_ptr<T1, D1>& x, const uniq_ptr<T2, D2>& y) {
|
||||||
|
return x.get() == y.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T1, class D1, class T2, class D2>
|
||||||
|
bool operator!=(const std::unique_ptr<T1, D1>& x, const uniq_ptr<T2, D2>& y) {
|
||||||
|
return x.get() != y.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T1, class D1, class T2, class D2>
|
||||||
|
bool operator==(const uniq_ptr<T1, D1>& x, const std::unique_ptr<T1, D1>& y) {
|
||||||
|
return x.get() == y.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T1, class D1, class T2, class D2>
|
||||||
|
bool operator!=(const uniq_ptr<T1, D1>& x, const std::unique_ptr<T1, D1>& y) {
|
||||||
|
return x.get() != y.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class D>
|
||||||
|
bool operator==(const uniq_ptr<T, D>& x, std::nullptr_t) {
|
||||||
|
return !(bool)x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class D>
|
||||||
|
bool operator!=(const uniq_ptr<T, D>& x, std::nullptr_t) {
|
||||||
|
return (bool)x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class D>
|
||||||
|
bool operator==(std::nullptr_t, const uniq_ptr<T, D>& y) {
|
||||||
|
return !(bool)y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class D>
|
||||||
|
bool operator!=(std::nullptr_t, const uniq_ptr<T, D>& y) {
|
||||||
|
return (bool)y;
|
||||||
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class wrap_ptr {
|
class wrap_ptr {
|
||||||
@@ -510,6 +607,43 @@ private:
|
|||||||
pointer _p;
|
pointer _p;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class T, class V = void>
|
||||||
|
struct __false_v;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct __false_v<T, std::enable_if_t<instantiation_of_v<std::optional, T>>> {
|
||||||
|
static constexpr std::nullopt_t value = std::nullopt;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct __false_v<T, std::enable_if_t<
|
||||||
|
(
|
||||||
|
std::is_pointer_v<T> ||
|
||||||
|
instantiation_of_v<std::unique_ptr, T> ||
|
||||||
|
instantiation_of_v<std::shared_ptr, T> ||
|
||||||
|
instantiation_of_v<uniq_ptr, T>
|
||||||
|
)
|
||||||
|
>> {
|
||||||
|
static constexpr std::nullptr_t value = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct __false_v<T, std::enable_if_t<std::is_same_v<T, bool>>> {
|
||||||
|
static constexpr bool value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
static constexpr auto false_v = __false_v<T>::value;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using optional_t = either_t<
|
||||||
|
(std::is_same_v<T, bool> ||
|
||||||
|
instantiation_of_v<std::unique_ptr, T> ||
|
||||||
|
instantiation_of_v<std::shared_ptr, T> ||
|
||||||
|
instantiation_of_v<uniq_ptr, T> ||
|
||||||
|
std::is_pointer_v<T>),
|
||||||
|
T, std::optional<T>>;
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class buffer_t {
|
class buffer_t {
|
||||||
public:
|
public:
|
||||||
@@ -569,6 +703,35 @@ T either(std::optional<T> &&l, T &&r) {
|
|||||||
return std::forward<T>(r);
|
return std::forward<T>(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class ReturnType, class ...Args>
|
||||||
|
struct Function {
|
||||||
|
typedef ReturnType (*type)(Args...);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, class ReturnType, typename Function<ReturnType, T>::type function>
|
||||||
|
struct Destroy {
|
||||||
|
typedef T pointer;
|
||||||
|
|
||||||
|
void operator()(pointer p) {
|
||||||
|
function(p);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T, typename Function<void, T*>::type function>
|
||||||
|
using safe_ptr = uniq_ptr<T, Destroy<T*, void, function>>;
|
||||||
|
|
||||||
|
// You cannot specialize an alias
|
||||||
|
template<class T, class ReturnType, typename Function<ReturnType, T*>::type function>
|
||||||
|
using safe_ptr_v2 = uniq_ptr<T, Destroy<T*, ReturnType, function>>;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void c_free(T *p) {
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using c_ptr = safe_ptr<T, c_free<T>>;
|
||||||
|
|
||||||
namespace endian {
|
namespace endian {
|
||||||
template<class T = void>
|
template<class T = void>
|
||||||
struct endianness {
|
struct endianness {
|
||||||
|
|||||||
Reference in New Issue
Block a user