qt: add Direct3D 9 renderer

This commit is contained in:
Cacodemon345
2022-06-22 16:36:38 +06:00
parent f17888c4d6
commit 32b29e91ee
9 changed files with 302 additions and 8 deletions

View File

@@ -25,6 +25,9 @@
#include "qt_openglrenderer.hpp"
#include "qt_softwarerenderer.hpp"
#include "qt_vulkanwindowrenderer.hpp"
#ifdef Q_OS_WIN
#include "qt_d3d9renderer.hpp"
#endif
#include "qt_mainwindow.hpp"
#include "qt_util.hpp"
@@ -223,12 +226,18 @@ RendererStack::switchRenderer(Renderer renderer)
{
startblit();
if (current) {
if (rendererWindow->hasBlitFunc()) {
while (directBlitting) {}
disconnect(this, &RendererStack::blit, this, &RendererStack::blitRenderer);
video_blit_complete();
}
rendererWindow->finalize();
removeWidget(current.get());
disconnect(this, &RendererStack::blitToRenderer, nullptr, nullptr);
/* Create new renderer only after previous is destroyed! */
connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { createRenderer(renderer); });
connect(current.get(), &QObject::destroyed, [this, renderer](QObject *) { video_blit_complete(); createRenderer(renderer); video_blit_complete(); });
current.release()->deleteLater();
} else {
@@ -292,6 +301,31 @@ RendererStack::createRenderer(Renderer renderer)
current.reset(this->createWindowContainer(hw, this));
break;
}
#ifdef Q_OS_WIN
case Renderer::Direct3D9:
{
this->createWinId();
auto hw = new D3D9Renderer(this);
rendererWindow = hw;
connect(hw, &D3D9Renderer::error, this, [this](QString str)
{
auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize D3D9 renderer. Falling back to software rendering.\n\n") + str, QMessageBox::Ok);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->show();
imagebufs = {};
endblit();
QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); });
});
connect(hw, &D3D9Renderer::initialized, this, [this]()
{
qDebug() << "initialized";
endblit();
emit rendererChanged();
});
current.reset(hw);
break;
}
#endif
#if QT_CONFIG(vulkan)
case Renderer::Vulkan:
{
@@ -340,16 +374,31 @@ RendererStack::createRenderer(Renderer renderer)
currentBuf = 0;
if (renderer != Renderer::OpenGL3 && renderer != Renderer::Vulkan) {
if (rendererWindow->hasBlitFunc()) {
connect(this, &RendererStack::blit, this, &RendererStack::blitRenderer, Qt::DirectConnection);
}
else {
connect(this, &RendererStack::blit, this, &RendererStack::blitCommon, Qt::DirectConnection);
}
if (renderer != Renderer::OpenGL3 && renderer != Renderer::Vulkan && renderer != Renderer::Direct3D9) {
imagebufs = rendererWindow->getBuffers();
endblit();
emit rendererChanged();
}
}
void
RendererStack::blitRenderer(int x, int y, int w, int h)
{
directBlitting = true;
rendererWindow->blit(x, y, w, h);
directBlitting = false;
}
// called from blitter thread
void
RendererStack::blit(int x, int y, int w, int h)
RendererStack::blitCommon(int x, int y, int w, int h)
{
if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || imagebufs.empty() || std::get<std::atomic_flag *>(imagebufs[currentBuf])->test_and_set()) {
video_blit_complete();