Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/platform/windows/display.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ using dup_t = util::safe_ptr<IDXGIOutputDuplication, Release<IDX
using texture2d_t = util::safe_ptr<ID3D11Texture2D, Release<ID3D11Texture2D>>;
using texture1d_t = util::safe_ptr<ID3D11Texture1D, Release<ID3D11Texture1D>>;
using resource_t = util::safe_ptr<IDXGIResource, Release<IDXGIResource>>;
using multithread_t = util::safe_ptr<ID3D11Multithread, Release<ID3D11Multithread>>;
using multithread_t = util::safe_ptr<ID3D10Multithread, Release<ID3D10Multithread>>;
using vs_t = util::safe_ptr<ID3D11VertexShader, Release<ID3D11VertexShader>>;
using ps_t = util::safe_ptr<ID3D11PixelShader, Release<ID3D11PixelShader>>;
using blend_t = util::safe_ptr<ID3D11BlendState, Release<ID3D11BlendState>>;
Expand Down Expand Up @@ -176,6 +176,8 @@ class display_vram_t : public display_base_t, public std::enable_shared_from_thi

std::shared_ptr<platf::hwdevice_t> make_hwdevice(pix_fmt_e pix_fmt) override;

multithread_t multithread;

sampler_state_t sampler_linear;

blend_t blend_enable;
Expand Down
44 changes: 37 additions & 7 deletions src/platform/windows/display_vram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ class hwdevice_t : public platf::hwdevice_t {
int convert(platf::img_t &img_base) override {
auto &img = (img_d3d_t &)img_base;

multithread->Enter();

device_ctx_p->IASetInputLayout(input_layout.get());

_init_view_port(this->img.width, this->img.height);
Expand Down Expand Up @@ -266,6 +268,8 @@ class hwdevice_t : public platf::hwdevice_t {
device_ctx_p->Draw(3, 0);
device_ctx_p->Flush();

multithread->Leave();

return 0;
}

Expand All @@ -288,23 +292,24 @@ class hwdevice_t : public platf::hwdevice_t {
++color_p;
}

auto color_matrix = make_buffer((device_t::pointer)data, *color_p);
auto color_matrix = make_buffer(device_p, *color_p);
if(!color_matrix) {
BOOST_LOG(warning) << "Failed to create color matrix"sv;
return;
}

multithread->Enter();
device_ctx_p->VSSetConstantBuffers(0, 1, &info_scene);
device_ctx_p->PSSetConstantBuffers(0, 1, &color_matrix);
multithread->Leave();

this->color_matrix = std::move(color_matrix);
}

int set_frame(AVFrame *frame) {
this->hwframe.reset(frame);
this->frame = frame;

auto device_p = (device_t::pointer)data;

auto out_width = frame->width;
auto out_height = frame->height;

Expand Down Expand Up @@ -399,10 +404,20 @@ class hwdevice_t : public platf::hwdevice_t {
HRESULT status;

device_p->AddRef();
data = device_p;

this->device_p = device_p;
this->device_ctx_p = device_ctx_p;

status = device_p->QueryInterface(IID_ID3D10Multithread, (void **)&multithread);
if(FAILED(status)) {
BOOST_LOG(error) << "Couldn't query ID3D10Multithread [0x"sv << util::hex(status).to_string_view() << ']';
return -1;
}

data_ptrs[0] = device_p;
data_ptrs[1] = multithread.get();
this->data = data_ptrs;

format = (pix_fmt == pix_fmt_e::nv12 ? DXGI_FORMAT_NV12 : DXGI_FORMAT_P010);
status = device_p->CreateVertexShader(scene_vs_hlsl->GetBufferPointer(), scene_vs_hlsl->GetBufferSize(), nullptr, &scene_vs);
if(status) {
Expand Down Expand Up @@ -467,8 +482,8 @@ class hwdevice_t : public platf::hwdevice_t {
}

~hwdevice_t() override {
if(data) {
((ID3D11Device *)data)->Release();
if(device_p) {
device_p->Release();
}
}

Expand Down Expand Up @@ -518,7 +533,11 @@ class hwdevice_t : public platf::hwdevice_t {

DXGI_FORMAT format;

device_t::pointer device_p;
device_ctx_t::pointer device_ctx_p;
multithread_t multithread;

void *data_ptrs[2] {};
};

capture_e display_vram_t::capture(snapshot_cb_t &&snapshot_cb, std::shared_ptr<::platf::img_t> img, bool *cursor) {
Expand Down Expand Up @@ -685,6 +704,7 @@ capture_e display_vram_t::snapshot(platf::img_t *img_base, std::chrono::millisec
0.0f, 1.0f
};

multithread->Enter();
device_ctx->VSSetShader(scene_vs.get(), nullptr, 0);
device_ctx->PSSetShader(scene_ps.get(), nullptr, 0);
device_ctx->RSSetViewports(1, &view);
Expand All @@ -694,6 +714,7 @@ capture_e display_vram_t::snapshot(platf::img_t *img_base, std::chrono::millisec
device_ctx->RSSetViewports(1, &cursor.cursor_view);
device_ctx->Draw(3, 0);
device_ctx->OMSetBlendState(blend_disable.get(), nullptr, 0xFFFFFFFFu);
multithread->Leave();
}

return capture_e::ok;
Expand All @@ -704,6 +725,15 @@ int display_vram_t::init(int framerate, const std::string &display_name) {
return -1;
}

auto status = device->QueryInterface(IID_ID3D10Multithread, (void **)&multithread);
if(FAILED(status)) {
BOOST_LOG(error) << "Couldn't query ID3D10Multithread [0x"sv << util::hex(status).to_string_view() << ']';
return -1;
}

// Enable multi-thread protection on our device for PARALLEL_ENCODING
multithread->SetMultithreadProtected(true);

D3D11_SAMPLER_DESC sampler_desc {};
sampler_desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sampler_desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
Expand All @@ -713,7 +743,7 @@ int display_vram_t::init(int framerate, const std::string &display_name) {
sampler_desc.MinLOD = 0;
sampler_desc.MaxLOD = D3D11_FLOAT32_MAX;

auto status = device->CreateSamplerState(&sampler_desc, &sampler_linear);
status = device->CreateSamplerState(&sampler_desc, &sampler_linear);
if(FAILED(status)) {
BOOST_LOG(error) << "Failed to create point sampler state [0x"sv << util::hex(status).to_string_view() << ']';
return -1;
Expand Down
32 changes: 20 additions & 12 deletions src/video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ static encoder_t nvenc {
"h264_nvenc"s,
},
#ifdef _WIN32
DEFAULT,
PARALLEL_ENCODING,
dxgi_make_hwdevice_ctx
#else
PARALLEL_ENCODING,
Expand Down Expand Up @@ -486,7 +486,7 @@ static encoder_t amdvce {
std::make_optional<encoder_t::option_t>({ "qp_p"s, &config::video.qp }),
"h264_amf"s,
},
DEFAULT,
PARALLEL_ENCODING,
dxgi_make_hwdevice_ctx
};
#endif
Expand Down Expand Up @@ -1334,7 +1334,7 @@ void captureThreadSync() {
ctx.shutdown_event->raise(true);
ctx.join_event->raise(true);
}
});
});

while(encode_run_sync(synced_session_ctxs, ctx) == encode_e::reinit) {}
}
Expand All @@ -1350,7 +1350,7 @@ void capture_async(
auto lg = util::fail_guard([&]() {
images->stop();
shutdown_event->raise(true);
});
});

auto ref = capture_thread_async.ref();
if(!ref) {
Expand Down Expand Up @@ -1756,7 +1756,15 @@ util::Either<buffer_t, int> cuda_make_hwdevice_ctx(platf::hwdevice_t *base) {
#ifdef _WIN32
}

void do_nothing(void *) {}
void enter_multithread(void *ctx) {
auto mt = (ID3D10Multithread *)ctx;
mt->Enter();
}

void leave_multithread(void *ctx) {
auto mt = (ID3D10Multithread *)ctx;
mt->Leave();
}

namespace video {
util::Either<buffer_t, int> dxgi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_ctx) {
Expand All @@ -1765,14 +1773,14 @@ util::Either<buffer_t, int> dxgi_make_hwdevice_ctx(platf::hwdevice_t *hwdevice_c

std::fill_n((std::uint8_t *)ctx, sizeof(AVD3D11VADeviceContext), 0);

auto device = (ID3D11Device *)hwdevice_ctx->data;

device->AddRef();
ctx->device = device;
// display_vram_t sets data to [ID3D11Device*, ID3D10Multithread*]
auto data = (void **)hwdevice_ctx->data;
ctx->device = (ID3D11Device *)data[0];
ctx->lock_ctx = (ID3D10Multithread *)data[1];
ctx->lock = enter_multithread;
ctx->unlock = leave_multithread;

ctx->lock_ctx = (void *)1;
ctx->lock = do_nothing;
ctx->unlock = do_nothing;
ctx->device->AddRef();

auto err = av_hwdevice_ctx_init(ctx_buf.get());
if(err) {
Expand Down