Commit 3a20405e authored by Laszlo Agocs's avatar Laszlo Agocs

vk: start adding support for rsh

parent 92c6904d
......@@ -142,6 +142,7 @@ void createRhi()
#ifdef Q_OS_WIN
if (graphicsApi == D3D11) {
QRhiD3D11InitParams params;
params.enableDebugLayer = true;
r.r = QRhi::create(QRhi::D3D11, &params);
}
#endif
......
......@@ -382,6 +382,7 @@ void Renderer::createRhi()
#ifdef USE_RSH
params.resourceSharingHost = rsh;
#endif
params.enableDebugLayer = true;
r = QRhi::create(QRhi::D3D11, &params);
}
#endif
......
......@@ -144,6 +144,7 @@ void createRhi(QWindow *window, QRhi **rhi, QOffscreenSurface **fallbackSurface)
if (graphicsApi == D3D11) {
QRhiD3D11InitParams params;
params.resourceSharingHost = rsh;
params.enableDebugLayer = true;
*rhi = QRhi::create(QRhi::D3D11, &params);
}
#endif
......
......@@ -318,13 +318,15 @@ QT_BEGIN_NAMESPACE
different threads with QRhiResourceSharingHost set is allowed. Backends
where the underlying graphics API cannot safely support using the same
device or context from multiple threads will report this feature as
unsupported. In that case creating a QRhi with a QRhiResourceSharingHost
set will behave as if the QRhiResourceSharingHost was not provided at all.
Application and framework design may need to take support for this feature
into account: making resources like textures visible to multiple QRhi
instances is not neccessarily possible, so the design should be flexible
enough to allow functioning in that case as well (by using per-QRhi
resources instead of a single shared one, and possibly duplicating work).
unsupported. When not supported, creating a QRhi with a
QRhiResourceSharingHost when there are already other QRhi instances on
other threads associated with the same QRhiResourceSharingHost will behave
as if the QRhiResourceSharingHost was not set at all. Application and
framework design may need to take support for this feature into account:
making resources like textures visible to multiple QRhi instances is not
neccessarily possible, so the design should be flexible enough to allow
functioning in that case as well (by using per-QRhi resources instead of a
single shared one, and possibly duplicating work).
*/
/*!
......
......@@ -264,6 +264,7 @@ bool QRhiD3D11::create(QRhi::Flags flags)
nativeHandlesStruct.context = context;
if (rsh) {
qDebug("Attached to QRhiResourceSharingHost %p, currently %d other QRhi instances", rsh, rsh->rhiCount);
rsh->rhiCount += 1;
rsh->rhiThreads.append(QThread::currentThread());
}
......
......@@ -287,6 +287,7 @@ bool QRhiGles2::create(QRhi::Flags flags)
nativeHandlesStruct.context = ctx;
if (rsh) {
qDebug("Attached to QRhiResourceSharingHost %p, currently %d other QRhi instances", rsh, rsh->rhiCount);
rsh->rhiCount += 1;
rsh->rhiThreads.append(QThread::currentThread());
if (rshWantsContext)
......
......@@ -35,6 +35,7 @@
****************************************************************************/
#include "qrhivulkan_p.h"
#include "qrhirsh_p.h"
#define VMA_IMPLEMENTATION
#define VMA_STATIC_VULKAN_FUNCTIONS 0
......@@ -254,6 +255,9 @@ static inline VmaAllocator toVmaAllocator(QVkAllocator a)
QRhiVulkan::QRhiVulkan(QRhiVulkanInitParams *params, QRhiVulkanNativeHandles *importDevice)
: ofr(this)
{
if (params->resourceSharingHost)
rsh = QRhiResourceSharingHostPrivate::get(params->resourceSharingHost);
inst = params->inst;
maybeWindow = params->window; // may be null
......@@ -284,11 +288,27 @@ bool QRhiVulkan::create(QRhi::Flags flags)
Q_UNUSED(flags);
Q_ASSERT(inst);
QMutexLocker lock(rsh ? &rsh->mtx : nullptr);
globalVulkanInstance = inst; // assume this will not change during the lifetime of the entire application
f = inst->functions();
if (!importedDevice) {
bool rshWantsDevice = false;
if (rsh) {
if (rsh->d_vulkan.dev) {
physDev = rsh->d_vulkan.physDev;
dev = rsh->d_vulkan.dev;
gfxQueueFamilyIdx = rsh->d_vulkan.gfxQueueFamilyIdx;
gfxQueue = rsh->d_vulkan.gfxQueue;
cmdPool = rsh->d_vulkan.cmdPool;
allocator = rsh->d_vulkan.vmemAllocator;
} else {
rshWantsDevice = true;
}
}
if (!importedDevice && (!rsh || rshWantsDevice)) {
uint32_t devCount = 0;
f->vkEnumeratePhysicalDevices(inst->vkInstance(), &devCount, nullptr);
qDebug("%d physical devices", devCount);
......@@ -399,7 +419,7 @@ bool QRhiVulkan::create(QRhi::Flags flags)
df = inst->deviceFunctions(dev);
if (!importedCmdPool) {
if (!importedCmdPool && (!rsh || rshWantsDevice)) {
VkCommandPoolCreateInfo poolInfo;
memset(&poolInfo, 0, sizeof(poolInfo));
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
......@@ -423,7 +443,7 @@ bool QRhiVulkan::create(QRhi::Flags flags)
VK_VERSION_MINOR(physDevProperties.driverVersion),
VK_VERSION_PATCH(physDevProperties.driverVersion));
if (!importedAllocator) {
if (!importedAllocator && (!rsh || rshWantsDevice)) {
VmaVulkanFunctions afuncs;
afuncs.vkGetPhysicalDeviceProperties = wrap_vkGetPhysicalDeviceProperties;
afuncs.vkGetPhysicalDeviceMemoryProperties = wrap_vkGetPhysicalDeviceMemoryProperties;
......@@ -490,6 +510,14 @@ bool QRhiVulkan::create(QRhi::Flags flags)
nativeHandlesStruct.cmdPool = cmdPool;
nativeHandlesStruct.vmemAllocator = allocator;
if (rsh) {
qDebug("Attached to QRhiResourceSharingHost %p, currently %d other QRhi instances", rsh, rsh->rhiCount);
rsh->rhiCount += 1;
rsh->rhiThreads.append(QThread::currentThread());
if (rshWantsDevice)
rsh->d_vulkan = nativeHandlesStruct;
}
return true;
}
......@@ -529,23 +557,41 @@ void QRhiVulkan::destroy()
}
if (!importedAllocator && allocator) {
vmaDestroyAllocator(toVmaAllocator(allocator));
if (!rsh || allocator != rsh->d_vulkan.vmemAllocator)
vmaDestroyAllocator(toVmaAllocator(allocator));
allocator = nullptr;
}
if (!importedCmdPool && cmdPool) {
df->vkDestroyCommandPool(dev, cmdPool, nullptr);
if (!rsh || cmdPool != rsh->d_vulkan.cmdPool)
df->vkDestroyCommandPool(dev, cmdPool, nullptr);
cmdPool = VK_NULL_HANDLE;
}
if (!importedDevice && dev) {
df->vkDestroyDevice(dev, nullptr);
inst->resetDeviceFunctions(dev);
if (!rsh || dev != rsh->d_vulkan.dev) {
df->vkDestroyDevice(dev, nullptr);
inst->resetDeviceFunctions(dev);
}
dev = VK_NULL_HANDLE;
}
f = nullptr;
df = nullptr;
if (rsh) {
rsh->rhiCount -= 1;
rsh->rhiThreads.removeOne(QThread::currentThread());
if (rsh->rhiCount == 0) {
vmaDestroyAllocator(toVmaAllocator(rsh->d_vulkan.vmemAllocator));
df = inst->deviceFunctions(rsh->d_vulkan.dev);
df->vkDestroyCommandPool(rsh->d_vulkan.dev, rsh->d_vulkan.cmdPool, nullptr);
df->vkDestroyDevice(rsh->d_vulkan.dev, nullptr);
inst->resetDeviceFunctions(dev);
df = nullptr;
rsh->d_vulkan = QRhiVulkanNativeHandles();
}
}
}
VkResult QRhiVulkan::createDescriptorPool(VkDescriptorPool *pool)
......
......@@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE
class QVulkanFunctions;
class QVulkanDeviceFunctions;
class QVulkanWindow;
class QRhiResourceSharingHostPrivate;
static const int QVK_FRAMES_IN_FLIGHT = 2;
......@@ -483,6 +484,7 @@ public:
// in case they changed in the meantime.
void updateShaderResourceBindings(QRhiShaderResourceBindings *srb, int descSetIdx = -1);
QRhiResourceSharingHostPrivate *rsh = nullptr;
QVulkanInstance *inst = nullptr;
QWindow *maybeWindow = nullptr;
bool importedDevice = false;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment