Loading...
Searching...
No Matches
VkHostImportUpload.hpp File Reference

Zero-copy CPU->GPU upload on Vulkan via VK_EXT_external_memory_host. More...

Detailed Description

Zero-copy CPU->GPU upload on Vulkan via VK_EXT_external_memory_host.

QRhi's own texture upload stages every frame through a buffer that VMA is asked for with VMA_MEMORY_USAGE_CPU_TO_GPU (qrhivulkan.cpp). On a discrete GPU that prefers DEVICE_LOCAL|HOST_VISIBLE, i.e. the small (~214-246 MB) host-visible BAR heap. VMA treats a heap that size as "small", so its block size is heapSize/8 and any allocation above half a block becomes a dedicated vkAllocateMemory — and Qt destroys the staging buffer after every upload ("no reuse of staging, this is intentional"). Past that threshold – half a block, i.e. heapSize/16 – each frame therefore pays a fresh BAR allocation, and the effective upload bandwidth collapses.

A capture slot has already been filled by the vendor SDK, so the right answer is not a cheaper copy but no copy: import the slot's own pages as VkDeviceMemory once at setup and let the GPU DMA straight out of them.

Requirements: the imported pointer and the imported length must both be multiples of minImportedHostPointerAlignment (4096 on NVIDIA), which is why slots that want this path must be allocated through alignedSlotAlloc.

Go to the source code of this file.

Classes

struct  score::gfx::interop::VkHostImportedBuffer
 
class  score::gfx::interop::VkHostImportUpload
 

Namespaces

namespace  score
 Base toolkit upon which the software is built.
 
namespace  score::gfx
 Graphics rendering pipeline for ossia score.
 

Functions

void * score::gfx::interop::alignedSlotAlloc (std::size_t bytes, std::size_t alignment)
 
void score::gfx::interop::alignedSlotFree (void *p)
 
void * score::gfx::interop::importableAlloc (std::size_t bytes)
 
void score::gfx::interop::importableFree (void *p)
 
bool score::gfx::interop::importHostPointerBuffer (QRhi &, void *, std::size_t, unsigned, bool, VkHostImportedBuffer &out)
 
void score::gfx::interop::releaseHostImportedBuffer (QRhi &rhi, VkHostImportedBuffer &buf)
 GPU must be done with the buffer (e.g. after QRhi::finish()).
 

Function Documentation

◆ alignedSlotAlloc()

void * score::gfx::interop::alignedSlotAlloc ( std::size_t  bytes,
std::size_t  alignment 
)

Page-aligned slot storage. Plain new/vector alignment is not enough for VK_EXT_external_memory_host.

◆ importableAlloc()

void * score::gfx::interop::importableAlloc ( std::size_t  bytes)

Storage a graphics API can import directly, as opposed to merely being page-aligned.

On Windows the two are not the same thing: ID3D12Device3::OpenExistingHeapFromAddress rejects _aligned_malloc memory with E_INVALIDARG because it needs the base address of a virtual-memory reservation at the 64 KB system allocation granularity, and a 4 KB-aligned heap pointer lands mid-block. VirtualAlloc gives that; Vulkan's VK_EXT_external_memory_host accepts it too, so one allocator serves both rungs. Elsewhere this is just the page-aligned allocation.

Use for buffers a capture rung may hand to the GPU. Ordinary staging slots should keep alignedSlotAlloc – reserving 64 KB blocks for them would waste address space for no benefit.

◆ importHostPointerBuffer()

bool score::gfx::interop::importHostPointerBuffer ( QRhi &  rhi,
void *  host,
std::size_t  bytes,
unsigned  bufferUsage,
bool  requireHostCoherent,
VkHostImportedBuffer out 
)

Imports host as the storage of a new VkBuffer with the given VkBufferUsageFlags. host must be VkHostImportUpload::requiredAlignment aligned; the imported length is bytes rounded up to that alignment, so the caller must own that much. With requireHostCoherent, only HOST_COHERENT memory types are accepted (CPU reads then need no vkInvalidateMappedMemoryRanges), preferring HOST_CACHED ones.