30 using MakeEncoder = std::function<std::unique_ptr<score::gfx::GPUVideoEncoder>()>;
31 using GetOutputTexture
35 Lock lock, MakeEncoder makeEncoder, GetOutputTexture getOutputTexture,
36 const char*
name) noexcept
38 , m_makeEncoder{std::move(makeEncoder)}
39 , m_getOutputTexture{std::move(getOutputTexture)}
45 MakeEncoder m_makeEncoder;
46 GetOutputTexture m_getOutputTexture;
47 const char* m_name{
"DVP-D3D11"};
51 ID3D11Device* m_dev{};
53 NvDvpContextHandle m_dvpCtx{};
54 NvDvpResourceHandle m_dvpTex{};
55 NvDvpResourceHandle m_dvpBuf{};
56 bool m_threadStarted{};
58 std::unique_ptr<score::gfx::GPUVideoEncoder> m_encoder;
59 QRhiTexture* m_encoderOutput{};
62 uint32_t m_sysmemBytes{};
63 uint32_t m_sysmemStrideBytes{};
64 uint32_t m_sysmemRows{};
67 const char*
name() const noexcept
override {
return m_name; }
69 static bool isSupported(QRhi* rhi) {
return rhi !=
nullptr; }
74 if(!isSupported(cfg.rhi) || !cfg.
state || !m_lock.valid())
78 =
static_cast<const QRhiD3D11NativeHandles*
>(cfg.rhi->nativeHandles());
79 if(!native || !native->dev)
81 m_dev =
static_cast<ID3D11Device*
>(native->dev);
83 qDebug() <<
"DVP(D3D11): loading dvp.dll...";
84 if(nv_dvp_init_d3d11(&m_dvpCtx, m_dev) != NV_DVP_SUCCESS || !m_dvpCtx)
86 qWarning() <<
"DVP(D3D11): init failed:"
87 << nv_dvp_get_error_string(m_dvpCtx);
90 qDebug() <<
"DVP(D3D11): dvp.dll loaded + D3D11 device bound";
92 if(nv_dvp_thread_begin(m_dvpCtx) != NV_DVP_SUCCESS)
94 qWarning() <<
"DVP(D3D11): thread_begin failed:"
95 << nv_dvp_get_error_string(m_dvpCtx);
96 nv_dvp_shutdown(m_dvpCtx);
100 m_threadStarted =
true;
102 auto colorShader = score::gfx::colorMatrixOut(
103 AVCOL_SPC_BT709, AVCOL_TRC_BT709, AVCOL_RANGE_MPEG, AVCOL_PRI_BT709);
105 m_encoder = m_makeEncoder();
108 qWarning() <<
"DVP(D3D11): no fragment encoder for format";
115 m_encoderOutput = m_getOutputTexture(m_encoder.get());
118 qWarning() <<
"DVP(D3D11): encoder did not produce an output texture";
123 const QSize texSize = m_encoderOutput->pixelSize();
124 m_sysmemRows = uint32_t(texSize.height());
125 m_sysmemStrideBytes = uint32_t(texSize.width()) * 4u;
126 m_sysmemBytes = m_sysmemStrideBytes * m_sysmemRows;
130 qWarning() <<
"DVP(D3D11): encoder output size" << m_sysmemBytes
137 m_sysmem = nv_dvp_aligned_alloc(m_sysmemBytes);
140 qWarning() <<
"DVP(D3D11): nv_dvp_aligned_alloc(" << m_sysmemBytes
145 std::memset(m_sysmem, 0, m_sysmemBytes);
147 if(!m_lock.lock(m_sysmem, m_sysmemBytes))
149 qWarning() <<
"DVP(D3D11): DMABufferLock(sysmem) failed";
155 auto nt = m_encoderOutput->nativeTexture();
158 qWarning() <<
"DVP(D3D11): encoder texture has no native handle";
162 auto* d3d11Tex =
reinterpret_cast<ID3D11Texture2D*
>(nt.object);
164 if(nv_dvp_register_d3d11_texture(
165 m_dvpCtx, d3d11Tex, NV_DVP_FORMAT_RGBA8,
166 uint32_t(texSize.width()), uint32_t(texSize.height()), &m_dvpTex)
169 qWarning() <<
"DVP(D3D11): register_d3d11_texture failed:"
170 << nv_dvp_get_error_string(m_dvpCtx);
175 if(nv_dvp_register_sysmem_buffer(
176 m_dvpCtx, m_sysmem, NV_DVP_FORMAT_RGBA8, uint32_t(texSize.width()),
177 uint32_t(texSize.height()), m_sysmemStrideBytes, &m_dvpBuf)
180 qWarning() <<
"DVP(D3D11): register_sysmem_buffer failed:"
181 << nv_dvp_get_error_string(m_dvpCtx);
189 void release()
override
195 nv_dvp_unregister(m_dvpCtx, m_dvpTex);
200 nv_dvp_unregister(m_dvpCtx, m_dvpBuf);
205 nv_dvp_thread_end(m_dvpCtx);
206 m_threadStarted =
false;
208 nv_dvp_shutdown(m_dvpCtx);
213 m_encoder->release();
216 m_encoderOutput =
nullptr;
218 if(m_dmaLocked && m_sysmem)
220 m_lock.unlock(m_sysmem, m_sysmemBytes);
225 nv_dvp_aligned_free(m_sysmem);
233 if(nv_dvp_acquire_texture(m_dvpCtx, m_dvpTex) != NV_DVP_SUCCESS)
235 qWarning() <<
"DVP(D3D11): acquire_texture failed:"
236 << nv_dvp_get_error_string(m_dvpCtx);
238 m_encoder->exec(*cfg.rhi, cb);
243 if(nv_dvp_release_texture(m_dvpCtx, m_dvpTex) != NV_DVP_SUCCESS)
245 qWarning() <<
"DVP(D3D11): release_texture failed:"
246 << nv_dvp_get_error_string(m_dvpCtx);
249 if(nv_dvp_copy_texture_to_buffer(m_dvpCtx, m_dvpTex, m_dvpBuf)
252 qWarning() <<
"DVP(D3D11): copy_texture_to_buffer failed:"
253 << nv_dvp_get_error_string(m_dvpCtx);