Loading...
Searching...
No Matches
VulkanCudaBounce.hpp
Go to the documentation of this file.
1#pragma once
2
26#include <score_plugin_gfx_export.h>
27
28#include <QtGui/qtguiglobal.h>
29
30#if QT_CONFIG(vulkan) && __has_include(<vulkan/vulkan.h>)
31#define SCORE_HAS_VULKAN_CUDA_BOUNCE 1
32
33#include <Gfx/Graph/interop/CudaInterop.h>
36
37#include <cstdint>
38#include <vector>
39
40class QRhi;
41class QRhiBuffer;
42class QRhiCommandBuffer;
43class QRhiTexture;
44
45namespace score::gfx::interop
46{
47
48struct VulkanCudaBounceConfig
49{
50 QRhi* rhi{};
51 int slotCount{1};
52 std::size_t frameBytes{};
53 const char* debugName{"vk-cuda-bounce"};
54};
55
56class SCORE_PLUGIN_GFX_EXPORT VulkanCudaBounce
57{
58public:
59 VulkanCudaBounce() = default;
60 ~VulkanCudaBounce() { release(); }
61 VulkanCudaBounce(const VulkanCudaBounce&) = delete;
62 VulkanCudaBounce& operator=(const VulkanCudaBounce&) = delete;
63
65 bool init(const VulkanCudaBounceConfig& cfg);
66 void release();
67
68 bool valid() const noexcept { return !m_slots.empty(); }
69 std::size_t slotCount() const noexcept { return m_slots.size(); }
70
73 void* cudaPtr(std::size_t i) const noexcept
74 {
75 return i < m_slots.size() ? m_slots[i].bouncePtr : nullptr;
76 }
77
80 bool flushToBounce(std::size_t i, std::size_t bytes);
81
84 bool flushFromBounce(std::size_t i, std::size_t bytes);
85
89 bool recordCopyToSlot(
90 QRhiCommandBuffer& cb, void* srcVkBuffer, std::size_t bytes,
91 std::size_t i);
92
95 void debugPeek(std::size_t i, const char* tag);
96
99 bool timelineSupported() const noexcept
100 {
101 return m_gfxQueue && m_fnQueueSubmit && m_sem.valid();
102 }
103
109 bool signalCopyDoneOnQueue();
110
114 bool waitCopyDoneOnStream();
115
120 bool recordCopySlotToTexture(
121 QRhiCommandBuffer& cb, QRhiTexture* dst, int width, int height,
122 int texelBytes, std::size_t i);
123
124private:
125 struct Slot
126 {
127 vkinterop::ExternalBuffer vk{};
128 void* vkCudaPtr{};
129 CudaInteropResourceHandle vkCudaHandle{};
130 void* bouncePtr{};
131 };
132
133 CudaInteropContextHandle m_p2p{};
134 vkinterop::VulkanCtx m_vk{};
135 std::vector<Slot> m_slots;
136 std::size_t m_frameBytes{};
137
138 // Resolved once in init().
139 void* m_fnCopyBuffer{};
140 void* m_fnCopyBufferToImage{};
141 void* m_fnPipelineBarrier{};
142
143 // Timeline-semaphore fast path (replaces QRhi::finish() when supported).
144 vkinterop::VkCudaTimelineSemaphore m_sem;
145 uint64_t m_semValue{0};
146 void* m_gfxQueue{};
147 void* m_fnQueueSubmit{};
148};
149
150} // namespace score::gfx::interop
151
152#endif
Exportable Vulkan timeline semaphore + CUDA-side import pair.
Vulkan external-memory image/buffer create + export + import helpers.