[App/Qt] Initial GraphicsWindow work
This code does not work at all and needs a major refactoring
This commit is contained in:
parent
72ae10dc2b
commit
c22d27d901
|
@ -11,22 +11,29 @@
|
||||||
|
|
||||||
#include <QVulkanWindow>
|
#include <QVulkanWindow>
|
||||||
|
|
||||||
|
#include "emulator_window.h"
|
||||||
#include "third_party/imgui/imgui.h"
|
#include "third_party/imgui/imgui.h"
|
||||||
|
#include "xenia/apu/nop/nop_audio_system.h"
|
||||||
|
#include "xenia/apu/sdl/sdl_audio_system.h"
|
||||||
#include "xenia/apu/xaudio2/xaudio2_audio_system.h"
|
#include "xenia/apu/xaudio2/xaudio2_audio_system.h"
|
||||||
#include "xenia/base/clock.h"
|
|
||||||
#include "xenia/base/cvar.h"
|
#include "xenia/base/cvar.h"
|
||||||
#include "xenia/base/debugging.h"
|
#include "xenia/base/debugging.h"
|
||||||
|
#include "xenia/base/factory.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/platform.h"
|
#include "xenia/base/platform.h"
|
||||||
#include "xenia/base/profiling.h"
|
#include "xenia/base/profiling.h"
|
||||||
#include "xenia/base/threading.h"
|
#include "xenia/base/threading.h"
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
|
#include "xenia/gpu/command_processor.h"
|
||||||
|
#include "xenia/gpu/d3d12/d3d12_graphics_system.h"
|
||||||
#include "xenia/gpu/graphics_system.h"
|
#include "xenia/gpu/graphics_system.h"
|
||||||
|
#include "xenia/gpu/null/null_graphics_system.h"
|
||||||
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"
|
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"
|
||||||
#include "xenia/hid/input_system.h"
|
#include "xenia/hid/input_system.h"
|
||||||
|
#include "xenia/hid/nop/nop_hid.h"
|
||||||
|
#include "xenia/hid/sdl/sdl_hid.h"
|
||||||
|
#include "xenia/hid/winkey/winkey_hid.h"
|
||||||
#include "xenia/hid/xinput/xinput_hid.h"
|
#include "xenia/hid/xinput/xinput_hid.h"
|
||||||
#include "xenia/ui/vulkan/vulkan_instance.h"
|
|
||||||
#include "xenia/ui/vulkan/vulkan_provider.h"
|
|
||||||
|
|
||||||
DEFINE_string(apu, "any", "Audio system. Use: [any, nop, xaudio2]", "General");
|
DEFINE_string(apu, "any", "Audio system. Use: [any, nop, xaudio2]", "General");
|
||||||
DEFINE_string(gpu, "any", "Graphics system. Use: [any, vulkan, null]",
|
DEFINE_string(gpu, "any", "Graphics system. Use: [any, vulkan, null]",
|
||||||
|
@ -41,158 +48,97 @@ DEFINE_bool(fullscreen, false, "Toggles fullscreen", "General");
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
class VulkanWindow : public QVulkanWindow {
|
std::unique_ptr<apu::AudioSystem> CreateAudioSystem(cpu::Processor* processor) {
|
||||||
public:
|
Factory<apu::AudioSystem, cpu::Processor*> factory;
|
||||||
VulkanWindow(gpu::vulkan::VulkanGraphicsSystem* gfx)
|
#if XE_PLATFORM_WIN32
|
||||||
: graphics_system_(gfx) {}
|
factory.Add<apu::xaudio2::XAudio2AudioSystem>("xaudio2");
|
||||||
QVulkanWindowRenderer* createRenderer() override;
|
#endif // XE_PLATFORM_WIN32
|
||||||
|
factory.Add<apu::sdl::SDLAudioSystem>("sdl");
|
||||||
|
factory.Add<apu::nop::NopAudioSystem>("nop");
|
||||||
|
return factory.Create(cvars::apu, processor);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() {
|
||||||
gpu::vulkan::VulkanGraphicsSystem* graphics_system_;
|
Factory<gpu::GraphicsSystem> factory;
|
||||||
};
|
#if XE_PLATFORM_WIN32
|
||||||
|
factory.Add<gpu::d3d12::D3D12GraphicsSystem>("d3d12");
|
||||||
|
#endif // XE_PLATFORM_WIN32
|
||||||
|
factory.Add<gpu::vulkan::VulkanGraphicsSystem>("vulkan");
|
||||||
|
factory.Add<gpu::null::NullGraphicsSystem>("null");
|
||||||
|
return factory.Create(cvars::gpu);
|
||||||
|
}
|
||||||
|
|
||||||
class VulkanRenderer : public QVulkanWindowRenderer {
|
std::vector<std::unique_ptr<hid::InputDriver>> CreateInputDrivers(
|
||||||
public:
|
ui::Window* window) {
|
||||||
VulkanRenderer(VulkanWindow* window,
|
std::vector<std::unique_ptr<hid::InputDriver>> drivers;
|
||||||
gpu::vulkan::VulkanGraphicsSystem* graphics_system)
|
if (cvars::hid.compare("nop") == 0) {
|
||||||
: window_(window), graphics_system_(graphics_system) {}
|
drivers.emplace_back(hid::nop::Create(window));
|
||||||
|
} else {
|
||||||
void startNextFrame() override {
|
Factory<hid::InputDriver, ui::Window*> factory;
|
||||||
// Copy the graphics frontbuffer to our backbuffer.
|
#if XE_PLATFORM_WIN32
|
||||||
//auto swap_state = graphics_system_->swap_state();
|
factory.Add("xinput", hid::xinput::Create);
|
||||||
|
// WinKey input driver should always be the last input driver added!
|
||||||
auto cmd = window_->currentCommandBuffer();
|
factory.Add("winkey", hid::winkey::Create);
|
||||||
//auto src = reinterpret_cast<VkImage>(
|
#endif // XE_PLATFORM_WIN32
|
||||||
// swap_state->buffer_textures[swap_state->current_buffer]);
|
factory.Add("sdl", hid::sdl::Create);
|
||||||
auto dest = window_->swapChainImage(window_->currentSwapChainImageIndex());
|
for (auto& driver : factory.CreateAll(cvars::hid, window)) {
|
||||||
auto dest_size = window_->swapChainImageSize();
|
if (XSUCCEEDED(driver->Setup())) {
|
||||||
|
drivers.emplace_back(std::move(driver));
|
||||||
VkImageMemoryBarrier barrier;
|
}
|
||||||
std::memset(&barrier, 0, sizeof(VkImageMemoryBarrier));
|
}
|
||||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
if (drivers.empty()) {
|
||||||
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
// Fallback to nop if none created.
|
||||||
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
|
drivers.emplace_back(xe::hid::nop::Create(window));
|
||||||
barrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
|
}
|
||||||
barrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
|
|
||||||
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
//barrier.image = src;
|
|
||||||
barrier.subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1};
|
|
||||||
vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
|
||||||
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0,
|
|
||||||
nullptr, 1, &barrier);
|
|
||||||
|
|
||||||
VkImageBlit region;
|
|
||||||
region.srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
|
|
||||||
region.srcOffsets[0] = {0, 0, 0};
|
|
||||||
/*region.srcOffsets[1] = {static_cast<int32_t>(swap_state->width),
|
|
||||||
static_cast<int32_t>(swap_state->height), 1};*/
|
|
||||||
|
|
||||||
region.dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1};
|
|
||||||
region.dstOffsets[0] = {0, 0, 0};
|
|
||||||
region.dstOffsets[1] = {static_cast<int32_t>(dest_size.width()),
|
|
||||||
static_cast<int32_t>(dest_size.height()), 1};
|
|
||||||
/* vkCmdBlitImage(cmd, src, VK_IMAGE_LAYOUT_GENERAL, dest,
|
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion,
|
|
||||||
VK_FILTER_LINEAR);*/
|
|
||||||
|
|
||||||
//swap_state->pending = false;
|
|
||||||
window_->frameReady();
|
|
||||||
}
|
}
|
||||||
|
return drivers;
|
||||||
private:
|
|
||||||
gpu::vulkan::VulkanGraphicsSystem* graphics_system_;
|
|
||||||
VulkanWindow* window_;
|
|
||||||
};
|
|
||||||
|
|
||||||
QVulkanWindowRenderer* VulkanWindow::createRenderer() {
|
|
||||||
return new VulkanRenderer(this, graphics_system_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EmulatorWindow::EmulatorWindow(Loop* loop, const std::string& title)
|
EmulatorWindow::EmulatorWindow(Loop* loop, const std::string& title)
|
||||||
: QtWindow(loop, title) {
|
: QtWindow(loop, title) {
|
||||||
// TODO(DrChat): Pass in command line arguments.
|
// TODO(DrChat): Pass in command line arguments.
|
||||||
emulator_ = std::make_unique<xe::Emulator>("","","");
|
emulator_ = std::make_unique<xe::Emulator>("", "", "");
|
||||||
|
|
||||||
auto audio_factory = [&](cpu::Processor* processor,
|
X_STATUS result = emulator_->Setup(this, CreateAudioSystem,
|
||||||
kernel::KernelState* kernel_state) {
|
CreateGraphicsSystem, CreateInputDrivers);
|
||||||
auto audio = apu::xaudio2::XAudio2AudioSystem::Create(processor);
|
if (result == X_STATUS_SUCCESS) {
|
||||||
if (audio->Setup(kernel_state) != X_STATUS_SUCCESS) {
|
// Setup a callback called when the emulator wants to swap.
|
||||||
audio->Shutdown();
|
emulator_->graphics_system()->command_processor()->set_swap_request_handler(
|
||||||
return std::unique_ptr<apu::AudioSystem>(nullptr);
|
[&]() {
|
||||||
}
|
auto graphics_window =
|
||||||
|
reinterpret_cast<QWindow*>(this->graphics_window_.get());
|
||||||
return audio;
|
QMetaObject::invokeMethod(graphics_window, "requestUpdate",
|
||||||
};
|
Qt::QueuedConnection);
|
||||||
|
});
|
||||||
graphics_provider_ = ui::vulkan::VulkanProvider::Create(nullptr);
|
|
||||||
auto graphics_factory = [&](cpu::Processor* processor,
|
|
||||||
kernel::KernelState* kernel_state) {
|
|
||||||
auto graphics = std::make_unique<gpu::vulkan::VulkanGraphicsSystem>();
|
|
||||||
if (graphics->Setup(processor, kernel_state,
|
|
||||||
graphics_provider_->CreateOffscreenContext()->target_window())) {
|
|
||||||
graphics->Shutdown();
|
|
||||||
return std::unique_ptr<gpu::vulkan::VulkanGraphicsSystem>(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return graphics;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto input_factory = [&](ui::Window* window) {
|
|
||||||
std::vector<std::unique_ptr<hid::InputDriver>> drivers;
|
|
||||||
auto xinput_driver = hid::xinput::Create(window);
|
|
||||||
xinput_driver->Setup();
|
|
||||||
drivers.push_back(std::move(xinput_driver));
|
|
||||||
|
|
||||||
return drivers;
|
|
||||||
};
|
|
||||||
|
|
||||||
//X_STATUS result = emulator_->Setup(this, audio_factory, graphics_factory, input_factory);
|
|
||||||
//if (result == X_STATUS_SUCCESS) {
|
|
||||||
// // Setup a callback called when the emulator wants to swap.
|
|
||||||
// emulator_->graphics_system()->SetSwapCallback([&]() {
|
|
||||||
// QMetaObject::invokeMethod(this->graphics_window_.get(), "requestUpdate",
|
|
||||||
// Qt::QueuedConnection);
|
|
||||||
// });
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// Initialize our backend display window.
|
|
||||||
//if (!InitializeVulkan()) {
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//// Set a callback on launch
|
|
||||||
//emulator_->on_launch.AddListener([this]() {
|
|
||||||
// auto title_db = this->emulator()->game_data();
|
|
||||||
// if (title_db) {
|
|
||||||
// QPixmap p;
|
|
||||||
// auto icon_block = title_db->icon();
|
|
||||||
// if (icon_block.buffer &&
|
|
||||||
// p.loadFromData(icon_block.buffer, uint(icon_block.size), "PNG")) {
|
|
||||||
// this->setWindowIcon(QIcon(p));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EmulatorWindow::InitializeVulkan() {
|
|
||||||
auto provider =
|
|
||||||
reinterpret_cast<ui::vulkan::VulkanProvider*>(graphics_provider_.get());
|
|
||||||
|
|
||||||
// Create a Qt wrapper around our vulkan instance.
|
|
||||||
vulkan_instance_ = std::make_unique<QVulkanInstance>();
|
|
||||||
vulkan_instance_->setVkInstance(*provider->instance());
|
|
||||||
if (!vulkan_instance_->create()) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics_window_ = std::make_unique<VulkanWindow>(
|
if (!EmulatorWindow::Initialize()) {
|
||||||
reinterpret_cast<gpu::vulkan::VulkanGraphicsSystem*>(
|
return;
|
||||||
emulator_->graphics_system()));
|
}
|
||||||
graphics_window_->setVulkanInstance(vulkan_instance_.get());
|
|
||||||
|
|
||||||
|
// Set a callback on launch
|
||||||
|
emulator_->on_launch.AddListener(
|
||||||
|
[this](unsigned int title_id, std ::string_view title) {
|
||||||
|
auto title_db = this->emulator()->game_data();
|
||||||
|
if (title_db) {
|
||||||
|
QPixmap p;
|
||||||
|
auto icon_block = title_db->icon();
|
||||||
|
if (icon_block.buffer &&
|
||||||
|
p.loadFromData(icon_block.buffer, uint(icon_block.size), "PNG")) {
|
||||||
|
this->setWindowIcon(QIcon(p));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EmulatorWindow::Initialize() {
|
||||||
|
if (!graphics_window_->Initialize()) {
|
||||||
|
XELOGE("Could not initialize graphics window");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// Now set the graphics window as our central widget.
|
// Now set the graphics window as our central widget.
|
||||||
QWidget* wrapper = QWidget::createWindowContainer(graphics_window_.get());
|
QWidget* wrapper = QWidget::createWindowContainer(
|
||||||
|
dynamic_cast<QWindow*>(graphics_window_.get()));
|
||||||
setCentralWidget(wrapper);
|
setCentralWidget(wrapper);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Xenia : Xbox 360 Emulator Research Project *
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
* Copyright 2018 Ben Vanik. All rights reserved. *
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
@ -10,15 +10,11 @@
|
||||||
#ifndef XENIA_APP_MAIN_WINDOW_H_
|
#ifndef XENIA_APP_MAIN_WINDOW_H_
|
||||||
#define XENIA_APP_MAIN_WINDOW_H_
|
#define XENIA_APP_MAIN_WINDOW_H_
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
#include <QVulkanInstance>
|
|
||||||
#include <QWindow>
|
|
||||||
|
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/emulator.h"
|
||||||
#include "xenia/ui/graphics_context.h"
|
#include "xenia/ui/graphics_context.h"
|
||||||
#include "xenia/ui/graphics_provider.h"
|
#include "xenia/ui/qt/graphics_window.h"
|
||||||
#include "xenia/ui/qt/window_qt.h"
|
|
||||||
#include "xenia/ui/qt/loop_qt.h"
|
#include "xenia/ui/qt/loop_qt.h"
|
||||||
|
#include "xenia/ui/qt/window_qt.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace app {
|
namespace app {
|
||||||
|
@ -26,36 +22,28 @@ namespace app {
|
||||||
class VulkanWindow;
|
class VulkanWindow;
|
||||||
class VulkanRenderer;
|
class VulkanRenderer;
|
||||||
|
|
||||||
using ui::qt::QtWindow;
|
|
||||||
using ui::Loop;
|
using ui::Loop;
|
||||||
|
using ui::qt::GraphicsWindow;
|
||||||
|
using ui::qt::QtWindow;
|
||||||
|
|
||||||
class EmulatorWindow : public ui::qt::QtWindow {
|
class EmulatorWindow : public QtWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EmulatorWindow(Loop *loop, const std::string& title);
|
EmulatorWindow(Loop* loop, const std::string& title);
|
||||||
|
|
||||||
bool Launch(const std::string& path);
|
bool Launch(const std::string& path);
|
||||||
|
|
||||||
xe::Emulator* emulator() { return emulator_.get(); }
|
Emulator* emulator() const { return emulator_.get(); }
|
||||||
|
GraphicsWindow* graphics_window() const { return graphics_window_.get(); }
|
||||||
protected:
|
hid::InputSystem* input_system() const { return input_system_.get(); }
|
||||||
// Events
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool Initialize() override;
|
||||||
void CreateMenuBar();
|
void CreateMenuBar();
|
||||||
|
|
||||||
bool InitializeVulkan();
|
std::unique_ptr<Emulator> emulator_;
|
||||||
|
std::unique_ptr<GraphicsWindow> graphics_window_;
|
||||||
std::unique_ptr<xe::Emulator> emulator_;
|
|
||||||
|
|
||||||
std::unique_ptr<QWindow> graphics_window_;
|
|
||||||
std::unique_ptr<ui::GraphicsProvider> graphics_provider_;
|
|
||||||
std::unique_ptr<hid::InputSystem> input_system_;
|
std::unique_ptr<hid::InputSystem> input_system_;
|
||||||
|
|
||||||
std::unique_ptr<QVulkanInstance> vulkan_instance_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "d3d12_graphics_window.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
bool D3D12GraphicsWindow::Initialize() {
|
||||||
|
// TODO:
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
|
@ -0,0 +1,31 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_UI_QT_D3D12_GRAPHICS_WINDOW_H_
|
||||||
|
#define XENIA_UI_QT_D3D12_GRAPHICS_WINDOW_H_
|
||||||
|
|
||||||
|
#include "graphics_window.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
class D3D12GraphicsWindow : public GraphicsWindowImpl<> {
|
||||||
|
Q_OBJECT
|
||||||
|
D3D12GraphicsWindow(Emulator* emulator) : GraphicsWindowImpl(emulator) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool Initialize() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_UI_QT_GRAPHICS_WINDOW_H_
|
||||||
|
#define XENIA_UI_QT_GRAPHICS_WINDOW_H_
|
||||||
|
|
||||||
|
#include <QWindow>
|
||||||
|
|
||||||
|
#include "xenia/emulator.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
class GraphicsWindow {
|
||||||
|
public:
|
||||||
|
GraphicsWindow(Emulator* emulator) : emulator_(emulator) {}
|
||||||
|
virtual ~GraphicsWindow() = default;
|
||||||
|
|
||||||
|
Emulator* emulator() const { return emulator_; }
|
||||||
|
virtual bool Initialize() = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Emulator* emulator_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T = QWindow>
|
||||||
|
class GraphicsWindowImpl : public T, public GraphicsWindow {
|
||||||
|
static_assert(std::is_base_of_v<QWindow, T>,
|
||||||
|
"GraphicsWindow must inherit from a QWindow-based class");
|
||||||
|
public:
|
||||||
|
GraphicsWindowImpl(Emulator* emulator) : T(), GraphicsWindow(emulator) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "vulkan_graphics_window.h"
|
||||||
|
|
||||||
|
#include <QVulkanWindow>
|
||||||
|
|
||||||
|
#include "xenia/gpu/command_processor.h"
|
||||||
|
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"
|
||||||
|
#include "xenia/ui/vulkan/vulkan_instance.h"
|
||||||
|
#include "xenia/ui/vulkan/vulkan_provider.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
class VulkanRenderer : public QVulkanWindowRenderer {
|
||||||
|
public:
|
||||||
|
VulkanRenderer(VulkanGraphicsWindow* window,
|
||||||
|
gpu::vulkan::VulkanGraphicsSystem* graphics_system)
|
||||||
|
: window_(window), graphics_system_(graphics_system) {}
|
||||||
|
|
||||||
|
void startNextFrame() override {
|
||||||
|
// NEED TO DO STUFF HERE IDK
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
VulkanGraphicsWindow* window_;
|
||||||
|
gpu::vulkan::VulkanGraphicsSystem* graphics_system_;
|
||||||
|
};
|
||||||
|
|
||||||
|
QVulkanWindowRenderer* VulkanGraphicsWindow::createRenderer() {
|
||||||
|
auto graphics_system = reinterpret_cast<gpu::vulkan::VulkanGraphicsSystem*>(
|
||||||
|
emulator()->graphics_system());
|
||||||
|
return new VulkanRenderer(
|
||||||
|
this, graphics_system);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VulkanGraphicsWindow::Initialize() {
|
||||||
|
// copied from DrChat's original Qt branch
|
||||||
|
auto provider = reinterpret_cast<ui::vulkan::VulkanProvider*>(
|
||||||
|
emulator()->graphics_system()->provider());
|
||||||
|
|
||||||
|
// Create a Qt wrapper around our vulkan instance.
|
||||||
|
vulkan_instance_.setVkInstance(*provider->instance());
|
||||||
|
if (!vulkan_instance_.create()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
setVulkanInstance(&vulkan_instance_);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XENIA_UI_QT_VULKAN_GRAPHICS_WINDOW_H_
|
||||||
|
#define XENIA_UI_QT_VULKAN_GRAPHICS_WINDOW_H_
|
||||||
|
|
||||||
|
#include <QVulkanWindow>
|
||||||
|
#include "graphics_window.h"
|
||||||
|
|
||||||
|
namespace xe {
|
||||||
|
namespace ui {
|
||||||
|
namespace qt {
|
||||||
|
|
||||||
|
class VulkanGraphicsWindow : public GraphicsWindowImpl<QVulkanWindow> {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
VulkanGraphicsWindow(Emulator* emulator)
|
||||||
|
: GraphicsWindowImpl(emulator) {}
|
||||||
|
|
||||||
|
bool Initialize() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVulkanWindowRenderer* createRenderer() override;
|
||||||
|
|
||||||
|
QVulkanInstance vulkan_instance_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace xe
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue