mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-09 01:22:21 +02:00
Vulkan fixes
This commit is contained in:
parent
19861fe0cf
commit
1a2a401d3f
7 changed files with 91 additions and 53 deletions
|
@ -100,12 +100,12 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void setContext(gl::Context* context) {
|
||||
void setContext(vks::Context* context) {
|
||||
// Move the OpenGL context to the present thread
|
||||
// Extra code because of the widget 'wrapper' context
|
||||
_context = context;
|
||||
_context->doneCurrent();
|
||||
_context->moveToThread(this);
|
||||
//_context->doneCurrent();
|
||||
//_context->moveToThread(this);
|
||||
}
|
||||
|
||||
virtual void run() override {
|
||||
|
@ -119,16 +119,16 @@ public:
|
|||
setPriority(QThread::HighPriority);
|
||||
VulkanDisplayPlugin* currentPlugin{ nullptr };
|
||||
Q_ASSERT(_context);
|
||||
_context->makeCurrent();
|
||||
CHECK_GL_ERROR();
|
||||
//_context->makeCurrent();
|
||||
//CHECK_GL_ERROR();
|
||||
while (!_shutdown) {
|
||||
if (_pendingOtherThreadOperation) {
|
||||
PROFILE_RANGE(render, "MainThreadOp")
|
||||
{
|
||||
Lock lock(_mutex);
|
||||
_context->doneCurrent();
|
||||
//_context->doneCurrent();
|
||||
// Move the context to the main thread
|
||||
_context->moveToThread(_targetOperationThread);
|
||||
//_context->moveToThread(_targetOperationThread);
|
||||
_pendingOtherThreadOperation = false;
|
||||
// Release the main thread to do it's action
|
||||
_condition.notify_one();
|
||||
|
@ -139,7 +139,7 @@ public:
|
|||
Lock lock(_mutex);
|
||||
_condition.wait(lock, [&] { return _finishedOtherThreadOperation; });
|
||||
}
|
||||
_context->makeCurrent();
|
||||
//_context->makeCurrent();
|
||||
}
|
||||
|
||||
// Check for a new display plugin
|
||||
|
@ -152,9 +152,9 @@ public:
|
|||
// Deactivate the old plugin
|
||||
if (currentPlugin != nullptr) {
|
||||
currentPlugin->uncustomizeContext();
|
||||
CHECK_GL_ERROR();
|
||||
//CHECK_GL_ERROR();
|
||||
// Force completion of all pending GL commands
|
||||
glFinish();
|
||||
//glFinish();
|
||||
}
|
||||
|
||||
if (newPlugin) {
|
||||
|
@ -164,16 +164,16 @@ public:
|
|||
#if defined(Q_OS_MAC)
|
||||
newPlugin->swapBuffers();
|
||||
#endif
|
||||
gl::setSwapInterval(wantVsync ? 1 : 0);
|
||||
//gl::setSwapInterval(wantVsync ? 1 : 0);
|
||||
#if defined(Q_OS_MAC)
|
||||
newPlugin->swapBuffers();
|
||||
#endif
|
||||
hasVsync = gl::getSwapInterval() != 0;
|
||||
newPlugin->setVsyncEnabled(hasVsync);
|
||||
newPlugin->customizeContext();
|
||||
CHECK_GL_ERROR();
|
||||
//hasVsync = gl::getSwapInterval() != 0;
|
||||
//newPlugin->setVsyncEnabled(hasVsync);
|
||||
//newPlugin->customizeContext();
|
||||
//CHECK_GL_ERROR();
|
||||
// Force completion of all pending GL commands
|
||||
glFinish();
|
||||
//glFinish();
|
||||
}
|
||||
currentPlugin = newPlugin;
|
||||
}
|
||||
|
@ -194,11 +194,11 @@ public:
|
|||
#endif
|
||||
// Execute the frame and present it to the display device.
|
||||
{
|
||||
PROFILE_RANGE(render, "PluginPresent")
|
||||
gl::globalLock();
|
||||
//PROFILE_RANGE(render, "PluginPresent")
|
||||
//gl::globalLock();
|
||||
currentPlugin->present(_refreshRateController);
|
||||
gl::globalRelease(false);
|
||||
CHECK_GL_ERROR();
|
||||
//gl::globalRelease(false);
|
||||
//CHECK_GL_ERROR();
|
||||
}
|
||||
#if defined(Q_OS_MAC)
|
||||
_context->doneCurrent();
|
||||
|
@ -207,9 +207,9 @@ public:
|
|||
_refreshRateController->sleepThreadIfNeeded(this, currentPlugin->isHmd());
|
||||
}
|
||||
|
||||
_context->doneCurrent();
|
||||
//_context->doneCurrent();
|
||||
Lock lock(_mutex);
|
||||
_context->moveToThread(qApp->thread());
|
||||
//_context->moveToThread(qApp->thread());
|
||||
_shutdown = false;
|
||||
_condition.notify_one();
|
||||
}
|
||||
|
@ -222,13 +222,13 @@ public:
|
|||
_finishedOtherThreadOperation = false;
|
||||
_condition.wait(lock, [&] { return !_pendingOtherThreadOperation; });
|
||||
|
||||
_context->makeCurrent();
|
||||
//_context->makeCurrent();
|
||||
f();
|
||||
_context->doneCurrent();
|
||||
//_context->doneCurrent();
|
||||
|
||||
_targetOperationThread = nullptr;
|
||||
// Move the context back to the presentation thread
|
||||
_context->moveToThread(this);
|
||||
//_context->moveToThread(this);
|
||||
|
||||
// restore control of the context to the presentation thread and signal
|
||||
// the end of the operation
|
||||
|
@ -250,7 +250,7 @@ private:
|
|||
bool _pendingOtherThreadOperation { false };
|
||||
bool _finishedOtherThreadOperation { false };
|
||||
std::queue<VulkanDisplayPlugin*> _newPluginQueue;
|
||||
gl::Context* _context { nullptr };
|
||||
vks::Context* _context { nullptr };
|
||||
std::shared_ptr<RefreshRateController> _refreshRateController { nullptr };
|
||||
};
|
||||
|
||||
|
@ -284,10 +284,10 @@ bool VulkanDisplayPlugin::activate() {
|
|||
if (!widget->context()->makeCurrent()) {
|
||||
throw std::runtime_error("Failed to make context current");
|
||||
}
|
||||
CHECK_GL_ERROR();
|
||||
//CHECK_GL_ERROR();
|
||||
widget->context()->doneCurrent();
|
||||
|
||||
presentThread->setContext(widget->context());
|
||||
presentThread->setContext(&vks::Context::get());
|
||||
connect(presentThread.data(), &QThread::started, [] { setThreadName("OpenGL Present Thread"); });
|
||||
// Start execution
|
||||
presentThread->start();
|
||||
|
@ -496,6 +496,7 @@ ktx::StoragePointer textureToKtxVulkan(const gpu::Texture& texture) {
|
|||
}
|
||||
|
||||
{
|
||||
// TODO
|
||||
auto gltexelformat = gpu::gl::GLTexelFormat::evalGLTexelFormat(texture.getStoredMipFormat());
|
||||
header.glInternalFormat = gltexelformat.internalFormat;
|
||||
header.glFormat = gltexelformat.format;
|
||||
|
@ -707,8 +708,13 @@ void VulkanDisplayPlugin::present(const std::shared_ptr<RefreshRateController>&
|
|||
|
||||
if (_currentFrame) {
|
||||
auto correction = getViewCorrection();
|
||||
getBackend()->setCameraCorrection(correction, _prevRenderView);
|
||||
auto vkBackend = std::dynamic_pointer_cast<gpu::vulkan::VKBackend>(getBackend());
|
||||
Q_ASSERT(vkBackend);
|
||||
vkBackend->setCameraCorrection(correction, _prevRenderView);
|
||||
_prevRenderView = correction * _currentFrame->view;
|
||||
uint32_t currentImageIndex = UINT32_MAX;
|
||||
VK_CHECK_RESULT(_vkWindow->_swapchain.acquireNextImage(_vkWindow->_presentCompleteSemaphore, ¤tImageIndex));
|
||||
Q_ASSERT(currentImageIndex != UINT32_MAX);
|
||||
{
|
||||
withPresentThreadLock([&] {
|
||||
_renderRate.increment();
|
||||
|
@ -719,6 +725,8 @@ void VulkanDisplayPlugin::present(const std::shared_ptr<RefreshRateController>&
|
|||
});
|
||||
// Execute the frame rendering commands
|
||||
PROFILE_RANGE_EX(render, "execute", 0xff00ff00, frameId)
|
||||
|
||||
vkBackend->setDrawCommandBuffer(_vkWindow->_drawCommandBuffers[currentImageIndex]);
|
||||
_gpuContext->executeFrame(_currentFrame);
|
||||
}
|
||||
|
||||
|
@ -747,6 +755,7 @@ void VulkanDisplayPlugin::present(const std::shared_ptr<RefreshRateController>&
|
|||
PROFILE_RANGE_EX(render, "internalPresent", 0xff00ffff, frameId)
|
||||
internalPresent();
|
||||
}
|
||||
_vkWindow->_swapchain.queuePresent(_vkWindow->_context.queue, currentImageIndex, _vkWindow->_renderCompleteSemaphore);
|
||||
|
||||
gpu::Backend::freeGPUMemSize.set(gpu::gl::getFreeDedicatedMemory());
|
||||
} else if (alwaysPresent()) {
|
||||
|
|
|
@ -334,15 +334,16 @@ struct Cache {
|
|||
std::vector<VkAttachmentDescription> attachments;
|
||||
attachments.reserve(key.size());
|
||||
std::vector<VkAttachmentReference> colorAttachmentReferences;
|
||||
VkAttachmentReference depthReference;
|
||||
VkAttachmentReference depthReference{};
|
||||
for (const auto& format : key) {
|
||||
VkAttachmentDescription attachment;
|
||||
VkAttachmentDescription attachment{};
|
||||
attachment.format = format;
|
||||
attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
attachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
if (isDepthStencilFormat(format)) {
|
||||
attachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
depthReference.attachment = (uint32_t)(attachments.size());
|
||||
|
@ -359,7 +360,7 @@ struct Cache {
|
|||
|
||||
std::vector<VkSubpassDescription> subpasses;
|
||||
{
|
||||
VkSubpassDescription subpass;
|
||||
VkSubpassDescription subpass{};
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
if (depthReference.layout != VK_IMAGE_LAYOUT_UNDEFINED) {
|
||||
subpass.pDepthStencilAttachment = &depthReference;
|
||||
|
@ -461,15 +462,17 @@ struct Cache {
|
|||
|
||||
// Shader modules
|
||||
{
|
||||
builder.shaderStages.resize(2);
|
||||
builder.shaderStages.resize(2,{});
|
||||
{
|
||||
auto& shaderStage = builder.shaderStages[0];
|
||||
shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
shaderStage.stage = VK_SHADER_STAGE_VERTEX_BIT;
|
||||
shaderStage.pName = "main";
|
||||
shaderStage.module = getShaderModule(context, vertexShader);
|
||||
}
|
||||
{
|
||||
auto& shaderStage = builder.shaderStages[1];
|
||||
shaderStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
|
||||
shaderStage.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
|
||||
shaderStage.pName = "main";
|
||||
shaderStage.module = getShaderModule(context, fragmentShader);
|
||||
|
@ -564,14 +567,11 @@ struct Cache {
|
|||
|
||||
Cache _cache;
|
||||
|
||||
// TODO: this is very cursed and will need to be changed in the future
|
||||
VkCommandBuffer currentCommandBuffer;
|
||||
|
||||
void VKBackend::executeFrame(const FramePointer& frame) {
|
||||
using namespace vks::debugutils;
|
||||
{
|
||||
PROFILE_RANGE(gpu_vk_detail, "Preprocess");
|
||||
const auto& commandBuffer = currentCommandBuffer;
|
||||
const auto& commandBuffer = _currentCommandBuffer;
|
||||
for (const auto& batchPtr : frame->batches) {
|
||||
const auto& batch = *batchPtr;
|
||||
cmdBeginLabel(commandBuffer, "batch:" + batch.getName(), glm::vec4{ 1, 1, 0, 1 });
|
||||
|
@ -706,6 +706,10 @@ void VKBackend::executeFrame(const FramePointer& frame) {
|
|||
// _stereo._enable = savedStereo;
|
||||
}
|
||||
|
||||
void VKBackend::setDrawCommandBuffer(VkCommandBuffer commandBuffer) {
|
||||
_currentCommandBuffer = commandBuffer;
|
||||
}
|
||||
|
||||
void VKBackend::trash(const VKBuffer& buffer) {
|
||||
}
|
||||
#if 0
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
bool supportedTextureFormat(const gpu::Element& format) const override;
|
||||
const std::string& getVersion() const override;
|
||||
void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) final override {}
|
||||
void setDrawCommandBuffer(VkCommandBuffer commandBuffer);
|
||||
|
||||
void trash(const VKBuffer& buffer);
|
||||
|
||||
|
@ -133,6 +134,7 @@ protected:
|
|||
VkQueue _graphicsQueue; //TODO: initialize from device
|
||||
VkQueue _transferQueue; //TODO: initialize from device
|
||||
friend class VKBuffer;
|
||||
VkCommandBuffer _currentCommandBuffer;
|
||||
};
|
||||
|
||||
}} // namespace gpu::vulkan
|
||||
|
|
|
@ -144,21 +144,24 @@ namespace vks {
|
|||
|
||||
const VkDevice& device;
|
||||
VkPipelineCache pipelineCache;
|
||||
// TODO: is this initialized properly
|
||||
VkRenderPass& renderPass { pipelineCreateInfo.renderPass };
|
||||
VkPipelineLayout& layout { pipelineCreateInfo.layout };
|
||||
PipelineInputAssemblyStateCreateInfo inputAssemblyState;
|
||||
PipelineRasterizationStateCreateInfo rasterizationState;
|
||||
VkPipelineMultisampleStateCreateInfo multisampleState;
|
||||
PipelineDepthStencilStateCreateInfo depthStencilState;
|
||||
PipelineViewportStateCreateInfo viewportState;
|
||||
PipelineDynamicStateCreateInfo dynamicState;
|
||||
PipelineColorBlendStateCreateInfo colorBlendState;
|
||||
PipelineVertexInputStateCreateInfo vertexInputState;
|
||||
std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
|
||||
// TODO: these need to be initialized
|
||||
PipelineInputAssemblyStateCreateInfo inputAssemblyState {};
|
||||
PipelineRasterizationStateCreateInfo rasterizationState {};
|
||||
VkPipelineMultisampleStateCreateInfo multisampleState {};
|
||||
PipelineDepthStencilStateCreateInfo depthStencilState {};
|
||||
PipelineViewportStateCreateInfo viewportState {};
|
||||
PipelineDynamicStateCreateInfo dynamicState {};
|
||||
PipelineColorBlendStateCreateInfo colorBlendState {};
|
||||
PipelineVertexInputStateCreateInfo vertexInputState {};
|
||||
std::vector<VkPipelineShaderStageCreateInfo> shaderStages {};
|
||||
|
||||
VkGraphicsPipelineCreateInfo pipelineCreateInfo;
|
||||
VkGraphicsPipelineCreateInfo pipelineCreateInfo{};
|
||||
|
||||
void update() {
|
||||
pipelineCreateInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
pipelineCreateInfo.stageCount = static_cast<uint32_t>(shaderStages.size());
|
||||
pipelineCreateInfo.pStages = shaderStages.data();
|
||||
dynamicState.update();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
// TODO: based on Vulkan Samples
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QGuiApplication>
|
||||
|
@ -57,11 +58,26 @@ void VKWindow::createSwapchain() {
|
|||
}
|
||||
_swapchain.create(&_extent.width, &_extent.height, false, false);
|
||||
|
||||
createCommandBuffers();
|
||||
setupRenderPass();
|
||||
setupDepthStencil();
|
||||
setupFramebuffers();
|
||||
}
|
||||
|
||||
void VKWindow::createCommandBuffers() {
|
||||
VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
|
||||
// Create a semaphore used to synchronize image presentation
|
||||
// Ensures that the image is displayed before we start submitting new commands to the queue
|
||||
VK_CHECK_RESULT(vkCreateSemaphore(_device, &semaphoreCreateInfo, nullptr, &_presentCompleteSemaphore));
|
||||
// Create a semaphore used to synchronize command submission
|
||||
// Ensures that the image is not presented until all commands have been submitted and executed
|
||||
VK_CHECK_RESULT(vkCreateSemaphore(_device, &semaphoreCreateInfo, nullptr, &_renderCompleteSemaphore));
|
||||
// Create one command buffer for each swap chain image
|
||||
_drawCommandBuffers.resize(_swapchain.imageCount);
|
||||
VkCommandBufferAllocateInfo cmdBufAllocateInfo = vks::initializers::commandBufferAllocateInfo(_context.device->commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, static_cast<uint32_t>(_drawCommandBuffers.size()));
|
||||
VK_CHECK_RESULT(vkAllocateCommandBuffers(_device, &cmdBufAllocateInfo, _drawCommandBuffers.data()));
|
||||
}
|
||||
|
||||
void VKWindow::setupDepthStencil() {
|
||||
auto &device = _context.device->logicalDevice;
|
||||
if (_depthStencil.isAllocated) {
|
||||
|
@ -252,6 +268,8 @@ void VKWindow::resizeFramebuffer() {
|
|||
}
|
||||
|
||||
VKWindow::~VKWindow() {
|
||||
vkDestroySemaphore(_device, _presentCompleteSemaphore, nullptr);
|
||||
vkDestroySemaphore(_device, _renderCompleteSemaphore, nullptr);
|
||||
_swapchain.cleanup();
|
||||
}
|
||||
|
||||
|
|
|
@ -48,14 +48,18 @@ protected:
|
|||
void setupRenderPass();
|
||||
void setupDepthStencil();
|
||||
void setupFramebuffers();
|
||||
void createCommandBuffers();
|
||||
|
||||
public:
|
||||
vks::Context& _context{ vks::Context::get() };
|
||||
const VkDevice& _device{ _context.device->logicalDevice };
|
||||
//VkSurfaceKHR _surface;
|
||||
VkRenderPass _renderPass;
|
||||
VkRenderPass _renderPass{};
|
||||
VkExtent2D _extent;
|
||||
VulkanSwapChain _swapchain;
|
||||
VkSemaphore _presentCompleteSemaphore{};
|
||||
VkSemaphore _renderCompleteSemaphore{};
|
||||
std::vector<VkCommandBuffer> _drawCommandBuffers;
|
||||
struct : vks::Allocation {
|
||||
bool isAllocated {false};
|
||||
VkImage image;
|
||||
|
|
|
@ -131,10 +131,6 @@ void RenderThread::shutdown() {
|
|||
_gpuContext.reset();
|
||||
}
|
||||
|
||||
#ifndef USE_GL
|
||||
extern VkCommandBuffer currentCommandBuffer;
|
||||
#endif
|
||||
|
||||
void RenderThread::renderFrame(gpu::FramePointer& frame) {
|
||||
#ifdef USE_GL
|
||||
PROFILE_RANGE(render_gpu_gl, __FUNCTION__);
|
||||
|
@ -178,7 +174,9 @@ void RenderThread::renderFrame(gpu::FramePointer& frame) {
|
|||
uint32_t swapchainIndex;
|
||||
VK_CHECK_RESULT(_swapchain.acquireNextImage(acquireComplete, &swapchainIndex));
|
||||
auto framebuffer = _framebuffers[swapchainIndex];
|
||||
const auto& commandBuffer = currentCommandBuffer = _vkcontext.createCommandBuffer();
|
||||
const auto& commandBuffer = _vkcontext.createCommandBuffer();
|
||||
//auto vkBackend = dynamic_pointer_cast<gpu::vulkan::VKBackend>(getBackend());
|
||||
//Q_ASSERT(vkBackend);
|
||||
|
||||
auto rect = VkRect2D{ offset, _extent };
|
||||
VkRenderPassBeginInfo beginInfo = vks::initializers::renderPassBeginInfo();
|
||||
|
|
Loading…
Reference in a new issue