29 : m_lock{lock}, m_dvpFormat{dvpFormat}, m_name{
name} {}
32 NvDvpFormat m_dvpFormat{};
33 const char* m_name{
"DVP-D3D11"};
37 static constexpr int kMaxFailures = 8;
40 ID3D11Device* m_dev{};
42 NvDvpContextHandle m_dvpCtx{};
43 NvDvpResourceHandle m_dvpTex{};
44 bool m_threadStarted{};
46 static constexpr std::size_t kSlotCount = 3;
50 NvDvpResourceHandle dvpBuf{};
53 std::array<Slot, kSlotCount> m_slots{};
55 uint32_t m_sysmemBytes{};
56 uint32_t m_sysmemStrideBytes{};
60 const char*
name() const noexcept
override {
return m_name; }
69 =
static_cast<const QRhiD3D11NativeHandles*
>(cfg.rhi->nativeHandles());
70 if(!native || !native->dev)
72 m_dev =
static_cast<ID3D11Device*
>(native->dev);
74 qDebug() <<
"DVP-IN(D3D11): loading dvp.dll...";
75 if(nv_dvp_init_d3d11(&m_dvpCtx, m_dev) != NV_DVP_SUCCESS || !m_dvpCtx)
77 qWarning() <<
"DVP-IN(D3D11): init failed:"
78 << nv_dvp_get_error_string(m_dvpCtx);
81 if(nv_dvp_thread_begin(m_dvpCtx) != NV_DVP_SUCCESS)
83 qWarning() <<
"DVP-IN(D3D11): thread_begin failed:"
84 << nv_dvp_get_error_string(m_dvpCtx);
88 m_threadStarted =
true;
89 qDebug() <<
"DVP-IN(D3D11): dvp.dll loaded + D3D11 device bound";
94 m_texW = texSize.width();
95 m_texH = texSize.height();
96 m_sysmemStrideBytes =
static_cast<uint32_t
>(m_texW) * 4u;
97 m_sysmemBytes = m_sysmemStrideBytes *
static_cast<uint32_t
>(m_texH);
101 qWarning() <<
"DVP-IN(D3D11): texture byte size" << m_sysmemBytes
102 <<
"(" << m_texW <<
"x" << m_texH <<
" RGBA8/BGRA8) !="
104 <<
"- texture geometry doesn't match captured layout";
112 qWarning() <<
"DVP-IN(D3D11): output texture has no native handle";
116 auto* d3d11Tex =
reinterpret_cast<ID3D11Texture2D*
>(nt.object);
118 const NvDvpFormat dvpFmt = m_dvpFormat;
120 if(nv_dvp_register_d3d11_texture(
121 m_dvpCtx, d3d11Tex, dvpFmt, uint32_t(m_texW), uint32_t(m_texH),
125 qWarning() <<
"DVP-IN(D3D11): register_d3d11_texture failed:"
126 << nv_dvp_get_error_string(m_dvpCtx);
135 for(
auto& slot : m_slots)
137 slot.sysmem = nv_dvp_aligned_alloc(m_sysmemBytes);
140 qWarning() <<
"DVP-IN(D3D11): nv_dvp_aligned_alloc(" << m_sysmemBytes
145 std::memset(slot.sysmem, 0, m_sysmemBytes);
146 if(!m_lock.lock(slot.sysmem, m_sysmemBytes))
148 qWarning() <<
"DVP-IN(D3D11): DMABufferLock(slot) failed";
152 slot.dmaLocked =
true;
153 if(nv_dvp_register_sysmem_buffer(
154 m_dvpCtx, slot.sysmem, dvpFmt, uint32_t(m_texW),
155 uint32_t(m_texH), m_sysmemStrideBytes, &slot.dvpBuf)
158 qWarning() <<
"DVP-IN(D3D11): register_sysmem_buffer failed:"
159 << nv_dvp_get_error_string(m_dvpCtx);
173 if(!qEnvironmentVariableIsSet(
"SCORE_GFX_DVP_NO_PROBE"))
175 if(m_slots[0].dvpBuf && m_dvpTex
176 && nv_dvp_copy_buffer_to_texture(m_dvpCtx, m_slots[0].dvpBuf, m_dvpTex)
179 qWarning() <<
"DVP-IN(D3D11): probe transfer failed:"
180 << nv_dvp_get_error_string(m_dvpCtx)
181 <<
"- DVP capture unusable here, falling back";
190 void release()
override
194 for(
auto& slot : m_slots)
198 nv_dvp_unregister(m_dvpCtx, slot.dvpBuf);
199 slot.dvpBuf =
nullptr;
203 m_lock.unlock(slot.sysmem, m_sysmemBytes);
204 slot.dmaLocked =
false;
208 nv_dvp_aligned_free(slot.sysmem);
209 slot.sysmem =
nullptr;
214 nv_dvp_unregister(m_dvpCtx, m_dvpTex);
219 nv_dvp_thread_end(m_dvpCtx);
220 m_threadStarted =
false;
222 nv_dvp_shutdown(m_dvpCtx);
232 bool healthy() const noexcept {
return !m_dead; }
234 std::size_t
slotCount() const noexcept
override {
return kSlotCount; }
237 return i < kSlotCount ? m_slots[i].sysmem :
nullptr;
244 auto& slot = m_slots[i];
245 if(!slot.dvpBuf || !m_dvpTex)
249 if(nv_dvp_copy_buffer_to_texture(m_dvpCtx, slot.dvpBuf, m_dvpTex)
257 if(++m_failures <= 3)
258 qWarning() <<
"DVP-IN(D3D11): copy_buffer_to_texture failed:"
259 << nv_dvp_get_error_string(m_dvpCtx);
260 if(m_failures == kMaxFailures)
263 qWarning() <<
"DVP-IN(D3D11): giving up after" << kMaxFailures
264 <<
"consecutive failures; the DVP capture rung is unusable "
277 if(m_dvpCtx && m_dvpTex)
279 if(nv_dvp_acquire_texture(m_dvpCtx, m_dvpTex) != NV_DVP_SUCCESS)
281 qWarning() <<
"DVP-IN(D3D11): acquire_texture failed:"
282 << nv_dvp_get_error_string(m_dvpCtx);
287 void releaseAfterRender()
override
289 if(m_dvpCtx && m_dvpTex)
291 if(nv_dvp_release_texture(m_dvpCtx, m_dvpTex) != NV_DVP_SUCCESS)
293 qWarning() <<
"DVP-IN(D3D11): release_texture failed:"
294 << nv_dvp_get_error_string(m_dvpCtx);