Skip to content

Commit

Permalink
Vulkan window resizing
Browse files Browse the repository at this point in the history
  • Loading branch information
ksuprynowicz committed Feb 9, 2025
1 parent 05cf269 commit 2adf2d8
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ std::chrono::nanoseconds RefreshRateController::sleepThreadIfNeeded(QThread* thr
if (!isHmd) {
static const std::chrono::nanoseconds EPSILON = std::chrono::milliseconds(1);
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(_endTime - _startTime);
if (duration.count() < 0) {
return std::chrono::nanoseconds(0);
}
auto refreshRateLimitPeriod = std::chrono::nanoseconds(_refreshRateLimitPeriod);
auto sleepDuration = refreshRateLimitPeriod - (duration + EPSILON);
if (sleepDuration.count() > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,14 @@ bool VulkanDisplayPlugin::activate() {
//CHECK_GL_ERROR();
widget->context()->doneCurrent();
widget->context()->moveToThread(presentThread.get());
VKWidget *vkWidget = _container->getPrimaryWidget();
_vkWindow = vkWidget->_mainWindow;
_vkWindow->setVisible(true);
_vkWindow->createSurface();
_vkWindow->createSwapchain();
_vkWindow->moveToThread(presentThread.get());

//_vkWindow->connectResizeTimer(presentThread.get());

presentThread->setContext(&vks::Context::get());
connect(presentThread.data(), &QThread::started, [] { setThreadName("Vulkan Present Thread"); });
Expand Down Expand Up @@ -328,11 +336,12 @@ bool VulkanDisplayPlugin::activate() {

//_vkWindow = std::make_shared<VKWindow>();
//_vkWindow = new VKWindow();
VKWidget *vkWidget = _container->getPrimaryWidget();
/*VKWidget *vkWidget = _container->getPrimaryWidget();
_vkWindow = vkWidget->_mainWindow;
_vkWindow->setVisible(true);
_vkWindow->createSurface();
_vkWindow->createSwapchain();
_vkWindow->moveToThread(presentThread.get());*/
/*_vkWidget = _container->getPrimaryWidget();
_vkWidget->setVisible(true);
_vkWidget->createSurface();
Expand Down Expand Up @@ -716,6 +725,10 @@ void VulkanDisplayPlugin::internalPresent() {
}

void VulkanDisplayPlugin::present(const std::shared_ptr<RefreshRateController>& refreshRateController) {
if (_vkWindow->_needsResizing) {
_vkWindow->resizeFramebuffer();
_vkWindow->_needsResizing = false;
}
auto frameId = (uint64_t)presentCount();
PROFILE_RANGE_EX(render, __FUNCTION__, 0xffffff00, frameId)
uint64_t startPresent = usecTimestampNow();
Expand All @@ -738,8 +751,10 @@ void VulkanDisplayPlugin::present(const std::shared_ptr<RefreshRateController>&
//VK_CHECK_RESULT(_vkWindow->_swapchain.acquireNextImage(_vkWindow->_acquireCompleteSemaphore, &currentImageIndex));
if(_vkWindow->_swapchain.acquireNextImage(_vkWindow->_acquireCompleteSemaphore, &currentImageIndex) != VK_SUCCESS) {
qDebug() << "_vkWindow->_swapchain.acquireNextImage fail";
_vkWindow->resizeFramebuffer(); //VKTODO: workaround
}
if (currentImageIndex == UINT32_MAX) {
refreshRateController->clockEndTime();
return;
}
//auto framebuffer = _vkWindow->_frameBuffers[currentImageIndex];
Expand Down
18 changes: 17 additions & 1 deletion libraries/gpu-vk/src/gpu/vk/VKBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ void VKBackend::init() {

VKBackend::VKBackend() {
if (!_context.instance) {
#ifdef QT_NO_DEBUG
_context.setValidationEnabled(false); // VKTODO: find nicer way of toggling this
#else
_context.setValidationEnabled(true); // VKTODO: find nicer way of toggling this
#endif
_context.createInstance();
_context.createDevice();
}
Expand Down Expand Up @@ -1159,7 +1163,19 @@ void VKBackend::updateRenderPass() {
}
}
renderPassBeginInfo.pClearValues = clearValues.data();
renderPassBeginInfo.renderArea = VkRect2D{VkOffset2D {_transform._viewport.x, _transform._viewport.y}, VkExtent2D {(uint32_t)_transform._viewport.z, (uint32_t)_transform._viewport.w}};
VkOffset2D offset{_transform._viewport.x, _transform._viewport.y};
VkExtent2D extent{static_cast<uint32_t>(_transform._viewport.z), static_cast<uint32_t>(_transform._viewport.w)};
if (offset.x > framebuffer->_gpuObject.getWidth() || offset.y > framebuffer->_gpuObject.getHeight()) {
offset.x = std::min(offset.x, (int32_t)framebuffer->_gpuObject.getWidth());
offset.y = std::min(offset.y, (int32_t)framebuffer->_gpuObject.getHeight());
qDebug() << "Vulkan framebuffer offset too high";
}
if (extent.width + offset.x > framebuffer->_gpuObject.getWidth() || extent.height + offset.y > framebuffer->_gpuObject.getHeight()) {
extent.width = std::min(extent.width + offset.x, (uint32_t)framebuffer->_gpuObject.getWidth()) - offset.x;
extent.height = std::min(extent.height + offset.y, (uint32_t)framebuffer->_gpuObject.getHeight()) - offset.y;
qDebug() << "Vulkan framebuffer extent too large";
}
renderPassBeginInfo.renderArea = VkRect2D{offset, extent};
vkCmdBeginRenderPass(_currentCommandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
}

Expand Down
19 changes: 16 additions & 3 deletions libraries/vk/src/vk/VKWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,23 @@ VKWindow::VKWindow(QScreen* screen) : QWindow(screen) {
vks::Context::get().registerWindow(this);
setBaseSize(QSize(1280, 720));
resize(QSize(1280, 720));
_resizeTimer = new QTimer(this);
/*_resizeTimer = new QTimer(this);
_resizeTimer->setTimerType(Qt::TimerType::PreciseTimer);
_resizeTimer->setInterval(50);
_resizeTimer->setSingleShot(true);
connect(_resizeTimer, &QTimer::timeout, this, &VKWindow::resizeFramebuffer);
connect(_resizeTimer, &QTimer::timeout, this, &VKWindow::resizeFramebuffer);*/
}

/*void VKWindow::connectResizeTimer(QThread *timerThread) {
_resizeTimer = new QTimer(this);
_resizeTimer->moveToThread(timerThread);
_resizeTimer->setTimerType(Qt::TimerType::PreciseTimer);
_resizeTimer->setInterval(50);
_resizeTimer->setSingleShot(true);
connect(_resizeTimer, &QTimer::timeout, this, &VKWindow::resizeFramebuffer, Qt::QueuedConnection);
//connect(_resizeTimer, &QTimer::timeout, this, [this] { QMetaObject::invokeMethod(this, "resizeFramebuffer", Qt::QueuedConnection); }, Qt::QueuedConnection);
}*/

void VKWindow::createSurface() {
_swapchain.setContext(&_context);
#ifdef WIN32
Expand Down Expand Up @@ -287,7 +297,10 @@ void VKWindow::resizeEvent(QResizeEvent* event) {
QWindow::resizeEvent(event);
auto qsize = event->size();
if (qsize.width() != (int)(_extent.width) || qsize.height() != (int)(_extent.height)) {
_resizeTimer->start();
/*if (_resizeTimer) {
_resizeTimer->start();
}*/
_needsResizing = true;
}
}

Expand Down
7 changes: 5 additions & 2 deletions libraries/vk/src/vk/VKWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class VKWindow : public QWindow {

bool event(QEvent *event) override;

//void connectResizeTimer(QThread *timerThread);

signals:
void aboutToClose();

Expand All @@ -42,7 +44,7 @@ class VKWindow : public QWindow {
friend struct vks::Context;
void emitClosing();

protected slots:
public slots:
virtual void resizeFramebuffer();

protected:
Expand Down Expand Up @@ -71,6 +73,7 @@ protected slots:
VkImageView view;
} _depthStencil{};
std::vector<VkFramebuffer> _frameBuffers;
QTimer* _resizeTimer{ nullptr };
//QTimer* _resizeTimer{ nullptr };
std::atomic<bool> _isVulkanCleanupComplete{ false };
std::atomic<bool> _needsResizing{ true };
};

0 comments on commit 2adf2d8

Please sign in to comment.