Merge remote-tracking branch 'upstream/master' into newqt2
This commit is contained in:
@@ -148,6 +148,9 @@ add_library(ui STATIC
|
||||
qt_vulkanwindowrenderer.hpp
|
||||
qt_vulkanwindowrenderer.cpp
|
||||
|
||||
qt_vulkanrenderer.hpp
|
||||
qt_vulkanrenderer.cpp
|
||||
|
||||
../qt_resources.qrc
|
||||
)
|
||||
|
||||
|
||||
@@ -207,18 +207,12 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
qt_mouse_capture(mouse_capture);
|
||||
if (mouse_capture) {
|
||||
this->grabKeyboard();
|
||||
#ifdef WAYLAND
|
||||
if (QGuiApplication::platformName().contains("wayland")) {
|
||||
wl_mouse_capture(this->windowHandle());
|
||||
}
|
||||
#endif
|
||||
if (ui->stackedWidget->mouse_capture)
|
||||
ui->stackedWidget->mouse_capture(this->windowHandle());
|
||||
} else {
|
||||
this->releaseKeyboard();
|
||||
#ifdef WAYLAND
|
||||
if (QGuiApplication::platformName().contains("wayland")) {
|
||||
wl_mouse_uncapture();
|
||||
}
|
||||
#endif
|
||||
if (ui->stackedWidget->mouse_uncapture)
|
||||
ui->stackedWidget->mouse_uncapture();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -520,10 +514,11 @@ void MainWindow::closeEvent(QCloseEvent *event) {
|
||||
}
|
||||
qt_nvr_save();
|
||||
config_save();
|
||||
#if defined __unix__ && !defined __HAIKU__
|
||||
extern void xinput2_exit();
|
||||
if (QApplication::platformName() == "xcb") xinput2_exit();
|
||||
#endif
|
||||
if (ui->stackedWidget->mouse_exit)
|
||||
ui->stackedWidget->mouse_exit();
|
||||
|
||||
ui->stackedWidget->switchRenderer(RendererStack::Renderer::Software);
|
||||
|
||||
event->accept();
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +88,7 @@ extern "C" {
|
||||
#include <86box/gameport.h>
|
||||
#include <86box/timer.h>
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/path.h>
|
||||
#include <86box/plat_dynld.h>
|
||||
#include <86box/mem.h>
|
||||
#include <86box/rom.h>
|
||||
@@ -140,7 +141,7 @@ void plat_get_exe_name(char *s, int size)
|
||||
|
||||
memcpy(s, exepath_temp.data(), std::min((qsizetype)exepath_temp.size(),(qsizetype)size));
|
||||
|
||||
plat_path_slash(s);
|
||||
path_slash(s);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -183,19 +184,24 @@ plat_dir_check(char *path)
|
||||
int
|
||||
plat_getcwd(char *bufp, int max)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
/* Working directory for .app bundles is undefined. */
|
||||
strncpy(bufp, exe_path, max);
|
||||
#else
|
||||
CharPointer(bufp, max) = QDir::currentPath().toUtf8();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
plat_get_dirname(char *dest, const char *path)
|
||||
path_get_dirname(char *dest, const char *path)
|
||||
{
|
||||
QFileInfo fi(path);
|
||||
CharPointer(dest, -1) = fi.dir().path().toUtf8();
|
||||
}
|
||||
|
||||
char *
|
||||
plat_get_extension(char *s)
|
||||
path_get_extension(char *s)
|
||||
{
|
||||
auto len = strlen(s);
|
||||
auto idx = QByteArray::fromRawData(s, len).lastIndexOf('.');
|
||||
@@ -206,7 +212,7 @@ plat_get_extension(char *s)
|
||||
}
|
||||
|
||||
char *
|
||||
plat_get_filename(char *s)
|
||||
path_get_filename(char *s)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
int c = strlen(s) - 1;
|
||||
@@ -228,7 +234,7 @@ plat_get_filename(char *s)
|
||||
}
|
||||
|
||||
int
|
||||
plat_path_abs(char *path)
|
||||
path_abs(char *path)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
if ((path[1] == ':') || (path[0] == '\\') || (path[0] == '/'))
|
||||
@@ -241,7 +247,7 @@ plat_path_abs(char *path)
|
||||
}
|
||||
|
||||
void
|
||||
plat_path_normalize(char* path)
|
||||
path_normalize(char* path)
|
||||
{
|
||||
#ifdef Q_OS_WINDOWS
|
||||
while (*path++ != 0)
|
||||
@@ -252,7 +258,7 @@ plat_path_normalize(char* path)
|
||||
}
|
||||
|
||||
void
|
||||
plat_path_slash(char *path)
|
||||
path_slash(char *path)
|
||||
{
|
||||
auto len = strlen(path);
|
||||
auto separator = '/';
|
||||
@@ -260,14 +266,14 @@ plat_path_slash(char *path)
|
||||
path[len] = separator;
|
||||
path[len+1] = 0;
|
||||
}
|
||||
plat_path_normalize(path);
|
||||
path_normalize(path);
|
||||
}
|
||||
|
||||
void
|
||||
plat_append_filename(char *dest, const char *s1, const char *s2)
|
||||
path_append_filename(char *dest, const char *s1, const char *s2)
|
||||
{
|
||||
strcpy(dest, s1);
|
||||
plat_path_slash(dest);
|
||||
path_slash(dest);
|
||||
strcat(dest, s2);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "evdev_mouse.hpp"
|
||||
|
||||
#include <QScreen>
|
||||
#include <QMessageBox>
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <CoreGraphics/CoreGraphics.h>
|
||||
@@ -51,21 +52,45 @@ RendererStack::RendererStack(QWidget *parent)
|
||||
ui->setupUi(this);
|
||||
|
||||
#if defined __unix__ && !defined __HAIKU__
|
||||
# ifdef WAYLAND
|
||||
if (QApplication::platformName().contains("wayland")) {
|
||||
wl_init();
|
||||
char *mouse_type = getenv("EMU86BOX_MOUSE"), auto_mouse_type[16];
|
||||
if (!mouse_type || (mouse_type[0] == '\0') || !stricmp(mouse_type, "auto")) {
|
||||
if (QApplication::platformName().contains("wayland"))
|
||||
strcpy(auto_mouse_type, "wayland");
|
||||
else if (QApplication::platformName() == "eglfs")
|
||||
strcpy(auto_mouse_type, "evdev");
|
||||
else if (QApplication::platformName() == "xcb")
|
||||
strcpy(auto_mouse_type, "xinput2");
|
||||
else
|
||||
auto_mouse_type[0] = '\0';
|
||||
mouse_type = auto_mouse_type;
|
||||
}
|
||||
|
||||
# ifdef WAYLAND
|
||||
if (!stricmp(mouse_type, "wayland")) {
|
||||
this->mouse_init = wl_init;
|
||||
this->mouse_poll = wl_mouse_poll;
|
||||
this->mouse_capture = wl_mouse_capture;
|
||||
this->mouse_uncapture = wl_mouse_uncapture;
|
||||
} else
|
||||
# endif
|
||||
# ifdef EVDEV_INPUT
|
||||
if (QApplication::platformName() == "eglfs") {
|
||||
evdev_init();
|
||||
}
|
||||
if (!stricmp(mouse_type, "evdev")) {
|
||||
this->mouse_init = evdev_init;
|
||||
this->mouse_poll = evdev_mouse_poll;
|
||||
} else
|
||||
# endif
|
||||
if (QApplication::platformName() == "xcb") {
|
||||
if (!stricmp(mouse_type, "xinput2")) {
|
||||
extern void xinput2_init();
|
||||
xinput2_init();
|
||||
extern void xinput2_poll();
|
||||
extern void xinput2_exit();
|
||||
this->mouse_init = xinput2_init;
|
||||
this->mouse_poll = xinput2_poll;
|
||||
this->mouse_exit = xinput2_exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (this->mouse_init)
|
||||
this->mouse_init();
|
||||
}
|
||||
|
||||
RendererStack::~RendererStack()
|
||||
@@ -105,23 +130,9 @@ RendererStack::mousePoll()
|
||||
mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0;
|
||||
mouse_buttons = mousedata.mousebuttons;
|
||||
|
||||
# if defined __unix__ && !defined __HAIKU__
|
||||
# ifdef WAYLAND
|
||||
if (QApplication::platformName().contains("wayland"))
|
||||
wl_mouse_poll();
|
||||
# endif
|
||||
|
||||
# ifdef EVDEV_INPUT
|
||||
if (QApplication::platformName() == "eglfs")
|
||||
evdev_mouse_poll();
|
||||
else
|
||||
# endif
|
||||
if (QApplication::platformName() == "xcb") {
|
||||
extern void xinput2_poll();
|
||||
xinput2_poll();
|
||||
}
|
||||
# endif /* defined __unix__ */
|
||||
#endif /* !defined __APPLE__ */
|
||||
if (this->mouse_poll)
|
||||
this->mouse_poll();
|
||||
#endif /* !defined __APPLE__ */
|
||||
}
|
||||
|
||||
int ignoreNextMouseEvent = 1;
|
||||
@@ -271,13 +282,13 @@ RendererStack::createRenderer(Renderer renderer)
|
||||
rendererWindow = hw;
|
||||
connect(this, &RendererStack::blitToRenderer, hw, &OpenGLRenderer::onBlit, Qt::QueuedConnection);
|
||||
connect(hw, &OpenGLRenderer::initialized, [=]() {
|
||||
/* Buffers are awailable only after initialization. */
|
||||
/* Buffers are available only after initialization. */
|
||||
imagebufs = rendererWindow->getBuffers();
|
||||
endblit();
|
||||
emit rendererChanged();
|
||||
});
|
||||
connect(hw, &OpenGLRenderer::errorInitializing, [=]() {
|
||||
/* Renderer could initialize, fallback to software. */
|
||||
/* Renderer not could initialize, fallback to software. */
|
||||
imagebufs = {};
|
||||
endblit();
|
||||
QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); });
|
||||
@@ -288,15 +299,35 @@ RendererStack::createRenderer(Renderer renderer)
|
||||
case Renderer::Vulkan:
|
||||
{
|
||||
this->createWinId();
|
||||
auto hw = new VulkanWindowRenderer(this);
|
||||
VulkanWindowRenderer *hw = nullptr;
|
||||
try {
|
||||
hw = new VulkanWindowRenderer(this);
|
||||
} catch(std::runtime_error& e) {
|
||||
auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", e.what() + QString("\nFalling back to software rendering."), QMessageBox::Ok);
|
||||
msgBox->setAttribute(Qt::WA_DeleteOnClose);
|
||||
msgBox->show();
|
||||
imagebufs = {};
|
||||
endblit();
|
||||
QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); });
|
||||
break;
|
||||
};
|
||||
rendererWindow = hw;
|
||||
connect(this, &RendererStack::blitToRenderer, hw, &VulkanWindowRenderer::onBlit, Qt::QueuedConnection);
|
||||
connect(hw, &VulkanWindowRenderer::rendererInitialized, [=]() {
|
||||
/* Buffers are awailable only after initialization. */
|
||||
/* Buffers are available only after initialization. */
|
||||
imagebufs = rendererWindow->getBuffers();
|
||||
endblit();
|
||||
emit rendererChanged();
|
||||
});
|
||||
connect(hw, &VulkanWindowRenderer::errorInitializing, [=]() {
|
||||
/* Renderer could not initialize, fallback to software. */
|
||||
auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize Vulkan renderer.\nFalling back to software rendering."), QMessageBox::Ok);
|
||||
msgBox->setAttribute(Qt::WA_DeleteOnClose);
|
||||
msgBox->show();
|
||||
imagebufs = {};
|
||||
endblit();
|
||||
QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); });
|
||||
});
|
||||
current.reset(this->createWindowContainer(hw, this));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,12 @@ public:
|
||||
rendererWindow->onResize(width, height);
|
||||
}
|
||||
|
||||
void (*mouse_init)() = nullptr;
|
||||
void (*mouse_poll)() = nullptr;
|
||||
void (*mouse_capture)(QWindow *window) = nullptr;
|
||||
void (*mouse_uncapture)() = nullptr;
|
||||
void (*mouse_exit)() = nullptr;
|
||||
|
||||
signals:
|
||||
void blitToRenderer(int buf_idx, int x, int y, int w, int h);
|
||||
void rendererChanged();
|
||||
|
||||
1005
src/qt/qt_vulkanrenderer.cpp
Normal file
1005
src/qt/qt_vulkanrenderer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
110
src/qt/qt_vulkanrenderer.hpp
Normal file
110
src/qt/qt_vulkanrenderer.hpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#pragma once
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QVulkanWindow>
|
||||
#include <QImage>
|
||||
|
||||
#include "qt_vulkanwindowrenderer.hpp"
|
||||
|
||||
class VulkanRenderer2 : public QVulkanWindowRenderer
|
||||
{
|
||||
public:
|
||||
void* mappedPtr = nullptr;
|
||||
size_t imagePitch = 2048 * 4;
|
||||
VulkanRenderer2(QVulkanWindow *w);
|
||||
|
||||
void initResources() override;
|
||||
void initSwapChainResources() override;
|
||||
void releaseSwapChainResources() override;
|
||||
void releaseResources() override;
|
||||
|
||||
void startNextFrame() override;
|
||||
|
||||
private:
|
||||
VkShaderModule createShader(const QString &name);
|
||||
bool createTexture();
|
||||
bool createTextureImage(const QSize &size, VkImage *image, VkDeviceMemory *mem,
|
||||
VkImageTiling tiling, VkImageUsageFlags usage, uint32_t memIndex);
|
||||
bool writeLinearImage(const QImage &img, VkImage image, VkDeviceMemory memory);
|
||||
void ensureTexture();
|
||||
void updateSamplers();
|
||||
|
||||
QVulkanWindow *m_window;
|
||||
QVulkanDeviceFunctions *m_devFuncs;
|
||||
|
||||
VkDeviceMemory m_bufMem = VK_NULL_HANDLE;
|
||||
VkBuffer m_buf = VK_NULL_HANDLE;
|
||||
VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT];
|
||||
|
||||
VkDescriptorPool m_descPool = VK_NULL_HANDLE;
|
||||
VkDescriptorSetLayout m_descSetLayout = VK_NULL_HANDLE;
|
||||
VkDescriptorSet m_descSet[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT];
|
||||
|
||||
VkPipelineCache m_pipelineCache = VK_NULL_HANDLE;
|
||||
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
||||
VkPipeline m_pipeline = VK_NULL_HANDLE;
|
||||
|
||||
VkSampler m_sampler = VK_NULL_HANDLE;
|
||||
VkSampler m_linearSampler = VK_NULL_HANDLE;
|
||||
VkImage m_texImage = VK_NULL_HANDLE;
|
||||
VkDeviceMemory m_texMem = VK_NULL_HANDLE;
|
||||
bool m_texLayoutPending = false;
|
||||
VkImageView m_texView = VK_NULL_HANDLE;
|
||||
VkImage m_texStaging = VK_NULL_HANDLE;
|
||||
VkDeviceMemory m_texStagingMem = VK_NULL_HANDLE;
|
||||
bool m_texStagingPending = false;
|
||||
bool m_texStagingTransferLayout = false;
|
||||
QSize m_texSize;
|
||||
VkFormat m_texFormat;
|
||||
|
||||
QMatrix4x4 m_proj;
|
||||
float m_rotation = 0.0f;
|
||||
};
|
||||
@@ -7,16 +7,15 @@
|
||||
|
||||
#include <array>
|
||||
|
||||
#define VMA_IMPLEMENTATION
|
||||
#include "vk_mem_alloc.h"
|
||||
#include "qt_mainwindow.hpp"
|
||||
#include "qt_vulkanrenderer.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <86box/86box.h>
|
||||
#include <86box/video.h>
|
||||
}
|
||||
|
||||
#if 0
|
||||
extern MainWindow* main_window;
|
||||
/*
|
||||
#version 450
|
||||
@@ -194,7 +193,7 @@ void main()
|
||||
static const uint8_t fragShaderCode[]
|
||||
{
|
||||
0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x08, 0x00,
|
||||
0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@@ -231,18 +230,26 @@ static const uint8_t fragShaderCode[]
|
||||
0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
|
||||
0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00,
|
||||
0x05, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00,
|
||||
0x0e, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
|
||||
0x0f, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
|
||||
0x57, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
|
||||
0x0e, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00,
|
||||
0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x3f, 0x15, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
|
||||
0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x20, 0x00, 0x04, 0x00, 0x17, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
|
||||
0x0b, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
|
||||
0x3d, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
|
||||
0x11, 0x00, 0x00, 0x00, 0x57, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00,
|
||||
0x13, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
|
||||
0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
|
||||
0x41, 0x00, 0x05, 0x00, 0x17, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00,
|
||||
0x18, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00,
|
||||
0x38, 0x00, 0x01, 0x00
|
||||
};
|
||||
|
||||
class VulkanRenderer : public QVulkanWindowRenderer
|
||||
class VulkanRendererEmu : public QVulkanWindowRenderer
|
||||
{
|
||||
VulkanWindowRenderer* m_window{nullptr};
|
||||
QVulkanDeviceFunctions* m_devFuncs{nullptr};
|
||||
@@ -308,7 +315,7 @@ private:
|
||||
public:
|
||||
void* mappedPtr = nullptr;
|
||||
uint32_t imagePitch{2048 * 4};
|
||||
VulkanRenderer(VulkanWindowRenderer *w) : m_window(w), m_devFuncs(nullptr) { }
|
||||
VulkanRendererEmu(VulkanWindowRenderer *w) : m_window(w), m_devFuncs(nullptr) { }
|
||||
|
||||
void initResources() override
|
||||
{
|
||||
@@ -344,8 +351,8 @@ public:
|
||||
VmaAllocationCreateInfo allocInfo{};
|
||||
allocInfo.pUserData = allocInfo.pool = nullptr;
|
||||
allocInfo.requiredFlags = allocInfo.preferredFlags = 0;
|
||||
allocInfo.usage = VmaMemoryUsage::VMA_MEMORY_USAGE_UNKNOWN;
|
||||
allocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT |
|
||||
allocInfo.usage = VmaMemoryUsage::VMA_MEMORY_USAGE_AUTO;
|
||||
allocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
|
||||
VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
||||
|
||||
if ((res = vmaCreateImage(allocator, &imageInfo, &allocInfo, &image, &allocation, &allocatedInfo)) != VK_SUCCESS) {
|
||||
@@ -363,6 +370,10 @@ public:
|
||||
imageViewInfo.subresourceRange.levelCount = 1;
|
||||
imageViewInfo.subresourceRange.baseArrayLayer = 0;
|
||||
imageViewInfo.subresourceRange.layerCount = 1;
|
||||
imageViewInfo.components.r = VK_COMPONENT_SWIZZLE_R;
|
||||
imageViewInfo.components.g = VK_COMPONENT_SWIZZLE_G;
|
||||
imageViewInfo.components.b = VK_COMPONENT_SWIZZLE_B;
|
||||
imageViewInfo.components.a = VK_COMPONENT_SWIZZLE_A;
|
||||
|
||||
if ((res = m_devFuncs->vkCreateImageView(m_window->device(), &imageViewInfo, nullptr, &imageView)) != VK_SUCCESS) {
|
||||
QMessageBox::critical(main_window, "86Box", "Could not create Vulkan image view. Switch to another renderer. " + Vulkan_GetResultString(res));
|
||||
@@ -408,7 +419,7 @@ public:
|
||||
rasterizer.rasterizerDiscardEnable = VK_FALSE;
|
||||
rasterizer.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rasterizer.lineWidth = 1.0f;
|
||||
rasterizer.cullMode = VK_CULL_MODE_NONE;
|
||||
rasterizer.cullMode = VK_CULL_MODE_BACK_BIT;
|
||||
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
|
||||
rasterizer.depthBiasEnable = VK_FALSE;
|
||||
rasterizer.depthBiasConstantFactor = 0.0f;
|
||||
@@ -426,12 +437,12 @@ public:
|
||||
|
||||
VkPipelineColorBlendAttachmentState colorBlendAttachment{};
|
||||
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
|
||||
colorBlendAttachment.blendEnable = VK_FALSE;
|
||||
colorBlendAttachment.blendEnable = VK_TRUE;
|
||||
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
|
||||
colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
|
||||
colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
|
||||
colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
|
||||
|
||||
VkPipelineColorBlendStateCreateInfo colorBlending{};
|
||||
@@ -521,10 +532,10 @@ public:
|
||||
VkPipelineDepthStencilStateCreateInfo depthInfo{};
|
||||
depthInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
|
||||
depthInfo.pNext = nullptr;
|
||||
depthInfo.depthTestEnable = VK_FALSE;
|
||||
depthInfo.depthTestEnable = VK_TRUE;
|
||||
depthInfo.depthWriteEnable = VK_TRUE;
|
||||
depthInfo.depthBoundsTestEnable = VK_FALSE;
|
||||
depthInfo.depthCompareOp = VK_COMPARE_OP_ALWAYS;
|
||||
depthInfo.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
|
||||
depthInfo.stencilTestEnable = VK_FALSE;
|
||||
depthInfo.maxDepthBounds = 1.0f;
|
||||
|
||||
@@ -543,8 +554,6 @@ public:
|
||||
pipelineInfo.layout = pipelineLayout;
|
||||
pipelineInfo.renderPass = m_window->defaultRenderPass();
|
||||
pipelineInfo.subpass = 0;
|
||||
pipelineInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||
pipelineInfo.basePipelineIndex = -1;
|
||||
|
||||
if ((res = m_devFuncs->vkCreateGraphicsPipelines(m_window->device(), VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline)) != VK_SUCCESS) {
|
||||
m_devFuncs->vkDestroyShaderModule(m_window->device(), vertModule, nullptr);
|
||||
@@ -560,18 +569,17 @@ public:
|
||||
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
samplerInfo.magFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.minFilter = VK_FILTER_LINEAR;
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||
samplerInfo.anisotropyEnable = VK_FALSE;
|
||||
samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||
samplerInfo.unnormalizedCoordinates = VK_FALSE;
|
||||
samplerInfo.compareEnable = VK_TRUE;
|
||||
samplerInfo.compareEnable = VK_FALSE;
|
||||
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
|
||||
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||
samplerInfo.mipLodBias = 0.0f;
|
||||
samplerInfo.minLod = 0.0f;
|
||||
samplerInfo.maxLod = 0.25f;
|
||||
samplerInfo.maxLod = 0.0;
|
||||
|
||||
if ((res = m_devFuncs->vkCreateSampler(m_window->device(), &samplerInfo, nullptr, &sampler)) != VK_SUCCESS) {
|
||||
QMessageBox::critical(main_window, "86Box", "Could not create linear image sampler. Switch to another renderer. " + Vulkan_GetResultString(res));
|
||||
@@ -716,9 +724,12 @@ public:
|
||||
|
||||
void startNextFrame() override
|
||||
{
|
||||
m_devFuncs->vkDeviceWaitIdle(m_window->device());
|
||||
VkClearValue values[2];
|
||||
auto cmdBufs = m_window->currentCommandBuffer();
|
||||
memset(values, 0, sizeof(values));
|
||||
values[0].depthStencil = { 1, 0 };
|
||||
values[1].depthStencil = { 1, 0 };
|
||||
VkRenderPassBeginInfo info{};
|
||||
VkSubpassDependency deps{};
|
||||
info.pClearValues = values;
|
||||
@@ -749,8 +760,8 @@ public:
|
||||
|
||||
m_devFuncs->vkCmdPipelineBarrier(cmdBufs, srcflags, dstflags, 0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||
imageLayoutTransitioned = true;
|
||||
return m_window->frameReady();
|
||||
}
|
||||
vmaFlushAllocation(allocator, allocation, 0, VK_WHOLE_SIZE);
|
||||
VkViewport viewport{};
|
||||
viewport.x = m_window->destination.x();
|
||||
viewport.y = m_window->destination.y();
|
||||
@@ -776,6 +787,7 @@ public:
|
||||
m_devFuncs->vkDeviceWaitIdle(m_window->device());
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
VulkanWindowRenderer::VulkanWindowRenderer(QWidget* parent)
|
||||
: QVulkanWindow(parent->windowHandle())
|
||||
@@ -783,9 +795,17 @@ VulkanWindowRenderer::VulkanWindowRenderer(QWidget* parent)
|
||||
parentWidget = parent;
|
||||
instance.setLayers(QByteArrayList() << "VK_LAYER_KHRONOS_validation");
|
||||
instance.setExtensions(QByteArrayList() << "VK_EXT_debug_report");
|
||||
instance.create();
|
||||
if (!instance.create()) {
|
||||
throw std::runtime_error("Could not create Vulkan instance");
|
||||
}
|
||||
uint32_t physicalDevices = 0;
|
||||
instance.functions()->vkEnumeratePhysicalDevices(instance.vkInstance(), &physicalDevices, nullptr);
|
||||
if (physicalDevices == 0) {
|
||||
throw std::runtime_error("No physical devices available.");
|
||||
}
|
||||
qDebug() << instance.layers();
|
||||
setVulkanInstance(&instance);
|
||||
setPhysicalDeviceIndex(0);
|
||||
setFlags(Flag::PersistentResources);
|
||||
buf_usage = std::vector<std::atomic_flag>(1);
|
||||
buf_usage[0].clear();
|
||||
@@ -793,7 +813,7 @@ VulkanWindowRenderer::VulkanWindowRenderer(QWidget* parent)
|
||||
|
||||
QVulkanWindowRenderer* VulkanWindowRenderer::createRenderer()
|
||||
{
|
||||
renderer = new VulkanRenderer(this);
|
||||
renderer = new VulkanRenderer2(this);
|
||||
return renderer;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
#include <QVulkanWindow>
|
||||
|
||||
#include "qt_renderercommon.hpp"
|
||||
#include "qt_vulkanrenderer.hpp"
|
||||
|
||||
class VulkanRenderer;
|
||||
class VulkanRenderer2;
|
||||
|
||||
class VulkanWindowRenderer : public QVulkanWindow, public RendererCommon
|
||||
{
|
||||
@@ -16,6 +17,7 @@ public slots:
|
||||
void onBlit(int buf_idx, int x, int y, int w, int h);
|
||||
signals:
|
||||
void rendererInitialized();
|
||||
void errorInitializing();
|
||||
protected:
|
||||
virtual std::vector<std::tuple<uint8_t *, std::atomic_flag *>> getBuffers() override;
|
||||
void resizeEvent(QResizeEvent*) override;
|
||||
@@ -26,9 +28,10 @@ private:
|
||||
|
||||
QVulkanWindowRenderer* createRenderer() override;
|
||||
|
||||
friend class VulkanRenderer;
|
||||
friend class VulkanRendererEmu;
|
||||
friend class VulkanRenderer2;
|
||||
|
||||
VulkanRenderer* renderer;
|
||||
VulkanRenderer2* renderer;
|
||||
};
|
||||
|
||||
#endif // VULKANWINDOWRENDERER_HPP
|
||||
|
||||
BIN
src/qt/texture_frag.spv
Normal file
BIN
src/qt/texture_frag.spv
Normal file
Binary file not shown.
BIN
src/qt/texture_vert.spv
Normal file
BIN
src/qt/texture_vert.spv
Normal file
Binary file not shown.
19564
src/qt/vk_mem_alloc.h
19564
src/qt/vk_mem_alloc.h
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user