Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
85ef916
gfx: add the NVIDIA GPUDirect-for-Video bridge
jcelerier Jul 12, 2026
0c5cbed
gfx: add high-bit-depth, planar and packed GPU video encoders
jcelerier Jul 12, 2026
69a3f3f
gfx: add the GPU texture-interop layer
jcelerier Jul 12, 2026
1bdc1b6
gfx: add wire-format and hardware video decoders
jcelerier Jul 12, 2026
e6d88ee
gfx: add direct video output and capture graph nodes
jcelerier Jul 12, 2026
dd0dc3d
gfx: drive rendering from an external genlock clock
jcelerier Jul 12, 2026
fda2365
gfx: add PipeWire video input and output devices
jcelerier Jul 12, 2026
2f05cbe
gfx: use the new encoders and dma-buf paths in the existing video bac…
jcelerier Jul 12, 2026
c572f2b
gfx: add GPU encoder and PipeWire round-trip test harnesses
jcelerier Jul 12, 2026
2ce426f
tests: encoder matrix, pixel-format and video-decoder suites
jcelerier Jul 28, 2026
dd4de40
gfx: fix mid-play live-update crash + vsync freeze on a real window
jcelerier Jul 17, 2026
5ab08d3
tests: video decode-correctness sweep
jcelerier Jul 28, 2026
276640a
tests: L3 GPU render/readback suites (ISF, CSF, raw-raster, VSA)
jcelerier Jul 20, 2026
cbc4789
gfx: zero-copy Vulkan capture upload via VK_EXT_external_memory_host
jcelerier Jul 26, 2026
e489e69
gfx: make the capture ladder explicit and pinnable for matrix testing
jcelerier Jul 26, 2026
a2ec3bd
gfx: add GPU->CPU texture readback into caller-provided host memory
jcelerier Jul 26, 2026
97c24a8
gfx: let the GPU write encoded output frames into the card's frame me…
jcelerier Jul 26, 2026
49447f5
gfx: pooled host frames behind FrameMemoryProvider for synchronous-DM…
jcelerier Jul 26, 2026
3bdc344
gfx: build EncoderTester in static-plugin builds too
jcelerier Jul 26, 2026
7969656
gfx: run the LSan leak check the testers' _Exit was skipping
jcelerier Jul 26, 2026
27b9f09
gfx: direct DRM/KMS output device
jcelerier Jul 27, 2026
cd4e8c7
gfx: zero-copy DMA-BUF capture strategy, and stop claiming LINEAR is …
jcelerier Jul 27, 2026
e959cd9
gfx: upload every plane of a planar capture, not just the luma
jcelerier Jul 28, 2026
acadaa2
gfx: make the AMD pinned-memory rung actually reachable
jcelerier Jul 29, 2026
48fa068
gfx: gate the AMD and DVP rungs on the real vendor and driver
jcelerier Jul 29, 2026
e458bff
gfx: hand the probed GPU identity to the capture-strategy pickers
jcelerier Jul 29, 2026
144a8ca
gfx: capture rung that samples the producer's own buffers (Vulkan)
jcelerier Jul 29, 2026
572b5e1
gfx: walk the capture ladder instead of stopping at the first failure
jcelerier Jul 29, 2026
96fa309
gfx: D3D12 host-import capture rung
jcelerier Jul 29, 2026
3f87b16
gfx: CpuStagedCapture takes the D3D12 host import too
jcelerier Jul 29, 2026
621803a
gfx: report the ring rung that engaged, not the one that was asked for
jcelerier Jul 29, 2026
56525c1
gfx: wire the last six planar decoders into makeWireDecoder
jcelerier Jul 29, 2026
2745b5d
gfx: fix the five resource defects from the adversarial review
jcelerier Jul 29, 2026
4267586
gfx: expose the capture threads own frame count on DMACaptureInputNode
jcelerier Jul 30, 2026
e7a4a5a
gfx: point the DRM and PipeWire helpers at the vocabulary
jcelerier Jul 30, 2026
382de57
gfx: import planar dma-buf frames one texture per plane
jcelerier Aug 12, 2026
b5a7630
gfx: upload planar frames per plane on the borrowed host-import rung
jcelerier Aug 12, 2026
43d4e1f
gfx: spell BGRA the way OpenGL ES does
jcelerier Aug 12, 2026
2818a66
gfx: let a producer state its plane layout instead of deriving it
jcelerier Aug 12, 2026
4f87805
gfx: import planar dma-buf frames as one external image
jcelerier Aug 12, 2026
474f185
gfx: do not count the modeset as a flip interval
jcelerier Aug 12, 2026
07bebee
gfx: make the external-image probe say why it refused
jcelerier Aug 12, 2026
be5563b
gfx: validate the slot pitch against the real format, not the nominal…
jcelerier Aug 12, 2026
50b91d6
gfx: rewrite the baked GLSL surgically for the external sampler
jcelerier Aug 12, 2026
6c8c85a
gfx: keep the external-image flag on the imported texture
jcelerier Aug 12, 2026
2b99084
gfx: correlate frames across capture streams
jcelerier Aug 12, 2026
87ee6c4
gfx: let a sync group drive which slot the renderer binds
jcelerier Aug 12, 2026
55e198a
gfx: scan out the rendered frame directly through KMS
jcelerier Aug 12, 2026
19373bb
gfx: give the KMS output an input port, and a harness to drive it
jcelerier Aug 12, 2026
b4589e4
gfx: say which DRM master failure this is
jcelerier Aug 12, 2026
a166073
gfx: build the KMS output's QRhi without the GUI settings
jcelerier Aug 13, 2026
9d70290
gfx: standalone probe for dma-buf import correctness
jcelerier Aug 13, 2026
6a427d6
gfx: gate the Vulkan dma-buf rung on who allocated the buffer
jcelerier Aug 14, 2026
f33a14a
gfx: release the V4L2 queue before closing it, and warn off vivid
jcelerier Aug 14, 2026
561ff7c
gfx: import a single-plane frame with the producer's pitch, not a der…
jcelerier Aug 14, 2026
816500d
gfx: DRM_FORMAT_GR1616 is 'GR32', not 'GR16'
jcelerier Aug 14, 2026
51b8848
cmake: give each avnd addon its own generated-header directory
jcelerier Aug 14, 2026
85efdc5
gfx: give the 10-bit Bayer CFA orders a place in the vocabulary
jcelerier Aug 14, 2026
578a73e
gfx: demosaic colour-filter-array frames on the GPU
jcelerier Aug 14, 2026
3c9cf2d
gfx: assemble a frame set from independently captured sensors
jcelerier Aug 14, 2026
939eff4
gfx: bind the sync group to the rung that actually engaged
jcelerier Aug 14, 2026
fcc8ff4
gfx: demosaic through the one texture target Tegra will bind
jcelerier Aug 14, 2026
a3099b8
gfx: derive the single plane the external import was refusing
jcelerier Aug 14, 2026
63fc6f8
gfx: let a texture input device expose several streams
jcelerier Aug 15, 2026
12b4f53
gfx: rebuild the decoder when the external-image rung declines
jcelerier Aug 15, 2026
d39ee7a
gfx: share the libv4l2 loader instead of copying it
jcelerier Aug 15, 2026
02cb2ed
gfx: build device-tree control groups from a description
jcelerier Aug 15, 2026
59c7113
gfx: sensor corrections and viewport fitting for capture nodes
jcelerier Aug 15, 2026
1d8b490
gfx: check the capture shader against its CPU reference on a real GPU
jcelerier Aug 15, 2026
3a82aa0
gfx: give back the slots of a capture the renderer skipped
jcelerier Aug 15, 2026
a5779dc
gfx: tell the capture backend whether its sync group engaged
jcelerier Aug 15, 2026
ffbbcaf
gfx: run a whole rig loop against the correlator and the group together
jcelerier Aug 15, 2026
da7935b
tests: drive the shader corpus through the graphs it was authored for
jcelerier Aug 17, 2026
ae8207a
tests: guard the storage-buffer-into-uniform_input mismatch
jcelerier Aug 18, 2026
2816edd
tests: pin the wire-decoder, DRM fourcc and PipeWire format tables
jcelerier Aug 18, 2026
a66ae80
tests: pin the capture slot, frame pacing and host pool lifetimes
jcelerier Aug 18, 2026
7115464
tests: pin the corrected dma-buf and external-sampler predicates
jcelerier Aug 18, 2026
e3cf633
tests: pin the GStreamer appsink classifier and audio-span resize (68…
jcelerier Aug 18, 2026
fea4313
tests: cover the three scene-filter nodes
jcelerier Aug 18, 2026
e0a56b6
tests: cover the scalar arenas and the mesh-slab arena
jcelerier Aug 18, 2026
e454597
tests: assert frame-step determinism on the in-tree corpus (a16977f69…
jcelerier Aug 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,10 @@ endif()

add_subdirectory(src)

if(SCORE_STATIC_PLUGINS AND TARGET EncoderTester)
target_link_libraries(EncoderTester PRIVATE ${SCORE_PLUGINS_LIST})
endif()

include(cmake/ScoreFeatureCheck.cmake)

if(EXISTS Documentation/Models/score.qmodel)
Expand Down
24 changes: 18 additions & 6 deletions cmake/ScoreAvndHelper.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -22,42 +22,54 @@ endfunction()
function(avnd_score_plugin_finalize)
cmake_parse_arguments(AVND "CUSTOM_PLUGIN;MODULE" "BASE_TARGET;PLUGIN_VERSION;PLUGIN_UUID" "" ${ARGN})

# Each addon's generated files live in their own directory, exposed only to
# targets that link the addon. score_static_plugins.hpp registers plug-ins
# behind `#if __has_include(<score_addon_foo.hpp>)`, so a header sitting in
# CMAKE_BINARY_DIR -- which is on every target's include path -- makes that
# guard true everywhere, and any target compiling that header then references
# a constructor it does not link. Small unit tests are the ones that break.
set(AVND_GEN_DIR "${CMAKE_BINARY_DIR}/score_addons/${AVND_BASE_TARGET}")

if(NOT AVND_CUSTOM_PLUGIN)
# Generate the score_plugin_foo.{h,c}pp
configure_file(
"${SCORE_AVND_SOURCE_DIR}/plugin_prototype.hpp.in"
"${CMAKE_BINARY_DIR}/${AVND_BASE_TARGET}.hpp"
"${AVND_GEN_DIR}/${AVND_BASE_TARGET}.hpp"
@ONLY
NEWLINE_STYLE LF
)
if(AVND_MODULE)
configure_file(
"${SCORE_AVND_SOURCE_DIR}/module_plugin_prototype.cpp.in"
"${CMAKE_BINARY_DIR}/${AVND_BASE_TARGET}.cpp"
"${AVND_GEN_DIR}/${AVND_BASE_TARGET}.cpp"
@ONLY
NEWLINE_STYLE LF
)
target_sources(${AVND_BASE_TARGET} PRIVATE FILE_SET CXX_MODULES FILES
"${CMAKE_BINARY_DIR}/${AVND_BASE_TARGET}.cpp"
"${AVND_GEN_DIR}/${AVND_BASE_TARGET}.cpp"
)
else()
configure_file(
"${SCORE_AVND_SOURCE_DIR}/plugin_prototype.cpp.in"
"${CMAKE_BINARY_DIR}/${AVND_BASE_TARGET}.cpp"
"${AVND_GEN_DIR}/${AVND_BASE_TARGET}.cpp"
@ONLY
NEWLINE_STYLE LF
)
target_sources(${AVND_BASE_TARGET} PRIVATE
"${CMAKE_BINARY_DIR}/${AVND_BASE_TARGET}.cpp"
"${AVND_GEN_DIR}/${AVND_BASE_TARGET}.cpp"
)
endif()
else()
file(CONFIGURE OUTPUT
"${CMAKE_BINARY_DIR}/include.${AVND_BASE_TARGET}.cpp"
"${AVND_GEN_DIR}/include.${AVND_BASE_TARGET}.cpp"
CONTENT "${AVND_ADDITIONAL_CLASSES}\nstatic void all_custom_factories(auto& fx, auto& ctx, auto& key) { ${AVND_CUSTOM_FACTORIES} }\n"
NEWLINE_STYLE LF)
endif()

# PUBLIC: the addon's own generated .cpp includes the header, and so must the
# app that links it -- but nothing else.
target_include_directories(${AVND_BASE_TARGET} PUBLIC "${AVND_GEN_DIR}")

setup_score_plugin(${AVND_BASE_TARGET})
target_link_libraries(${AVND_BASE_TARGET} PUBLIC score_plugin_engine score_plugin_avnd)

Expand Down
8 changes: 6 additions & 2 deletions src/app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,12 @@ static void setup_x11(int argc, char** argv)
helper_dylibs.run_under_x11 = true;
helper_dylibs.xwayland = wayland;

// EGL is the only way to get zero-copy with dma-buf import
qputenv("QT_XCB_GL_INTEGRATION", "xcb_egl");
// EGL is the only way to get zero-copy with dma-buf import, so it is
// the default -- but NVIDIA's GPUDirect-for-Video (libdvp) interops
// only with GLX, so a user who needs DVP must be able to ask for
// xcb_glx and have it stick.
if(qEnvironmentVariableIsEmpty("QT_XCB_GL_INTEGRATION"))
qputenv("QT_XCB_GL_INTEGRATION", "xcb_egl");
}
}
};
Expand Down
70 changes: 70 additions & 0 deletions src/plugins/score-plugin-gfx/3rdparty/nv-dvp-bridge/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# nv-dvp-bridge: NVIDIA "GPUDirect for Video" runtime-loaded shim +
# C API wrapper. Cross-platform: Windows uses dvp.dll; Linux uses
# libdvp.so.1. Consumers (AJA, planned DeckLink) link this target via
# its score-plugin-gfx parent.
#
# The bridge itself has no NVIDIA-SDK headers as a build dependency —
# all DVP entry points are dlsym'd at runtime from the NVIDIA library.

add_library(score_nv_dvp_bridge STATIC
"${CMAKE_CURRENT_SOURCE_DIR}/nv_dvp_bridge.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/nv_dvp_bridge.h"
"${CMAKE_CURRENT_SOURCE_DIR}/dvpapi_shim.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/dvpapi_shim.h"
)

target_include_directories(score_nv_dvp_bridge
PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}"
)

# Qt is used to identify the current GL context: libdvp's GL entry points
# only exist for GLX, and QNativeInterface::QGLXContext is the reliable way
# to know whether that is what we have.
target_link_libraries(score_nv_dvp_bridge PRIVATE ${QT_PREFIX}::Gui)

if(WIN32)
# D3D11 path uses ID3D11Device / ID3D11Texture2D via d3d11.h.
target_link_libraries(score_nv_dvp_bridge PRIVATE d3d11)
else()
# Linux dlopen path needs libdl.
target_link_libraries(score_nv_dvp_bridge PRIVATE ${CMAKE_DL_LIBS})
endif()

target_compile_definitions(score_nv_dvp_bridge PUBLIC
SCORE_HAS_NV_DVP_BRIDGE=1
# Bridge is built as a STATIC lib and linked into the consumer. The
# INLINE define makes NV_DVP_API empty (no dllexport/dllimport
# decoration) for both the bridge build and its consumers on Windows.
NV_DVP_BRIDGE_INLINE=1
)

set_property(TARGET score_nv_dvp_bridge PROPERTY POSITION_INDEPENDENT_CODE ON)

# Optional dvp.dll fetch on Windows. Mirrors the previous AJA addon's
# SCORE_FETCH_DVP_DLL option so existing build invocations keep working.
if(WIN32 AND SCORE_FETCH_DVP_DLL)
set(_dvp_dll "${CMAKE_BINARY_DIR}/3rdparty/dvp/dvp.dll")
if(NOT EXISTS "${_dvp_dll}")
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/3rdparty/dvp")
message(STATUS "nv-dvp-bridge: fetching dvp.dll v1.70 from PlusToolkit/PlusLib")
file(DOWNLOAD
"https://github.com/PlusToolkit/PlusLib/raw/master/Tools/NVidia/dvp170/bin/x64/dvp.dll"
"${_dvp_dll}"
EXPECTED_HASH SHA256=602f2cefecb9b7c67d4ffebb3b15e11291bacf5a7342fcec6d52dd0118cbaddd
STATUS _dvp_dl_status
SHOW_PROGRESS)
list(GET _dvp_dl_status 0 _dvp_dl_rc)
if(NOT _dvp_dl_rc EQUAL 0)
message(WARNING "nv-dvp-bridge: dvp.dll download failed: ${_dvp_dl_status}")
endif()
endif()
if(EXISTS "${_dvp_dll}")
# Expose path so the consuming addon can copy_if_different next to its DLL.
set(SCORE_NV_DVP_DLL "${_dvp_dll}" CACHE INTERNAL "Fetched dvp.dll path")
endif()
elseif(WIN32 AND AJA_DVP_DLL AND EXISTS "${AJA_DVP_DLL}")
set(SCORE_NV_DVP_DLL "${AJA_DVP_DLL}" CACHE INTERNAL "User-supplied dvp.dll path")
endif()

message(STATUS "score-plugin-gfx: nv-dvp-bridge enabled")
Loading