mirror of
https://github.com/flyinghead/flycast.git
synced 2026-11-07 09:16:10 -10:00
wsi: get rid of static graphics contexts
This commit is contained in:
1 parent
02a335e2dd
commit
08c63bd39b
39 files changed
+417
-292
No files matched your search
@@ -166,10 +166,10 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
io.BackendRendererName = "imgui_impl_opengl3";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures;
|
||||
|
||||
// Flycast: Detect version using theGLContext
|
||||
// Flycast: Detect version using GL context
|
||||
if (glsl_version == nullptr)
|
||||
{
|
||||
if (theGLContext.isGLES())
|
||||
if (GLGraphicsContext::Instance()->isGLES())
|
||||
glsl_version = "#version 100"; // OpenGL ES 2.0
|
||||
else
|
||||
#if defined(__APPLE__)
|
||||
@@ -183,10 +183,18 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
strcat(bd->GlslVersionString, "\n");
|
||||
|
||||
// Detect extensions we support
|
||||
bd->HasPolygonMode = !theGLContext.isGLES();
|
||||
bd->HasBindSampler = (theGLContext.getMajorVersion() >= 3 && !theGLContext.isGLES()) || (theGLContext.isGLES() && theGLContext.getMajorVersion() >= 3);
|
||||
const bool isGLES = GLGraphicsContext::Instance()->isGLES();
|
||||
const int majorVer = GLGraphicsContext::Instance()->getMajorVersion();
|
||||
bd->HasPolygonMode = !isGLES;
|
||||
if (isGLES)
|
||||
// GLES 3.0+
|
||||
bd->HasBindSampler = majorVer >= 3;
|
||||
else
|
||||
// OpenGL 3.3+
|
||||
bd->HasBindSampler = majorVer > 3
|
||||
|| (majorVer == 3 && GLGraphicsContext::Instance()->getMinorVersion() >= 3);
|
||||
#ifdef GL_CLIP_ORIGIN
|
||||
bd->HasClipOrigin = (theGLContext.getMajorVersion() >= 4 && glClipControl != NULL);
|
||||
bd->HasClipOrigin = (majorVer >= 4 && glClipControl != NULL);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
@@ -272,7 +280,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
||||
#endif
|
||||
vertex_array_object = 0;
|
||||
#ifndef GLES2
|
||||
if (theGLContext.getMajorVersion() >= 3)
|
||||
if (GLGraphicsContext::Instance()->getMajorVersion() >= 3)
|
||||
{
|
||||
// Recreate the VAO every time
|
||||
// (This is to easily allow multiple GL contexts. VAO are not shared among GL contexts, and we don't track creation/deletion of windows so we don't have an obvious key to use to cache them.)
|
||||
@@ -390,7 +398,7 @@ void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex)
|
||||
|
||||
if (tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates)
|
||||
{
|
||||
if (theGLContext.getMajorVersion() >= 3)
|
||||
if (GLGraphicsContext::Instance()->getMajorVersion() >= 3)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
}
|
||||
|
||||
@@ -410,7 +418,7 @@ void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex)
|
||||
{
|
||||
GLuint gl_tex_id = (GLuint)(intptr_t)tex->TexID;
|
||||
glcache.BindTexture(GL_TEXTURE_2D, gl_tex_id);
|
||||
if (theGLContext.getMajorVersion() >= 3)
|
||||
if (GLGraphicsContext::Instance()->getMajorVersion() >= 3)
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->Width);
|
||||
for (auto& r : tex->Updates)
|
||||
|
||||
@@ -39,14 +39,14 @@ public:
|
||||
}
|
||||
|
||||
void renderDrawData(ImDrawData *drawData, bool gui_open) override {
|
||||
theDX11Context.EndImGuiFrame();
|
||||
DX11Context::Instance()->EndImGuiFrame();
|
||||
if (gui_open)
|
||||
frameRendered = true;
|
||||
}
|
||||
|
||||
void present() override {
|
||||
if (frameRendered)
|
||||
theDX11Context.Present();
|
||||
DX11Context::Instance()->Present();
|
||||
frameRendered = false;
|
||||
}
|
||||
|
||||
@@ -77,15 +77,15 @@ public:
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
desc.MipLevels = 1;
|
||||
theDX11Context.getDevice()->CreateTexture2D(&desc, nullptr, &texture.texture.get());
|
||||
DX11Context::Instance()->getDevice()->CreateTexture2D(&desc, nullptr, &texture.texture.get());
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc{};
|
||||
viewDesc.Format = desc.Format;
|
||||
viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
viewDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||
theDX11Context.getDevice()->CreateShaderResourceView(texture.texture, &viewDesc, &texture.textureView.get());
|
||||
DX11Context::Instance()->getDevice()->CreateShaderResourceView(texture.texture, &viewDesc, &texture.textureView.get());
|
||||
|
||||
theDX11Context.getDeviceContext()->UpdateSubresource(texture.texture, 0, nullptr, data, width * 4, width * 4 * height);
|
||||
DX11Context::Instance()->getDeviceContext()->UpdateSubresource(texture.texture, 0, nullptr, data, width * 4, width * 4 * height);
|
||||
texture.imTexture.shaderResourceView = texture.textureView.get();
|
||||
texture.imTexture.pointSampling = nearestSampling;
|
||||
|
||||
|
||||
@@ -43,16 +43,16 @@ const D3D11_INPUT_ELEMENT_DESC ModVolLayout[]
|
||||
bool DX11Renderer::Init()
|
||||
{
|
||||
NOTICE_LOG(RENDERER, "DX11 renderer initializing");
|
||||
device = theDX11Context.getDevice();
|
||||
deviceContext = theDX11Context.getDeviceContext();
|
||||
device = DX11Context::Instance()->getDevice();
|
||||
deviceContext = DX11Context::Instance()->getDeviceContext();
|
||||
if (!device || !deviceContext)
|
||||
{
|
||||
WARN_LOG(RENDERER, "Null device or device context. Aborting");
|
||||
return false;
|
||||
}
|
||||
|
||||
shaders = &theDX11Context.getShaders();
|
||||
samplers = &theDX11Context.getSamplers();
|
||||
shaders = &DX11Context::Instance()->getShaders();
|
||||
samplers = &DX11Context::Instance()->getSamplers();
|
||||
bool success = (bool)shaders->getVertexShader(true, true);
|
||||
ComPtr<ID3DBlob> blob = shaders->getVertexShaderBlob();
|
||||
success = success && SUCCEEDED(device->CreateInputLayout(MainLayout, std::size(MainLayout), blob->GetBufferPointer(), blob->GetBufferSize(), &mainInputLayout.get()));
|
||||
@@ -325,7 +325,7 @@ void DX11Renderer::Process(TA_context* ctx)
|
||||
}
|
||||
texCache.Cleanup();
|
||||
if (!ctx->rend.isRTT && ctx->rend.swapInterval > 0)
|
||||
theDX11Context.setSwapInterval(ctx->rend.swapInterval);
|
||||
DX11Context::Instance()->setSwapInterval(ctx->rend.swapInterval);
|
||||
|
||||
ta_parse(ctx, true);
|
||||
}
|
||||
@@ -514,15 +514,15 @@ bool DX11Renderer::Render()
|
||||
{
|
||||
aspectRatio = getOutputFramebufferAspectRatio();
|
||||
#ifndef LIBRETRO
|
||||
deviceContext->OMSetRenderTargets(1, &theDX11Context.getRenderTarget().get(), nullptr);
|
||||
deviceContext->OMSetRenderTargets(1, &DX11Context::Instance()->getRenderTarget().get(), nullptr);
|
||||
displayFramebuffer();
|
||||
drawOSD();
|
||||
renderVideoRouting();
|
||||
theDX11Context.setFrameRendered();
|
||||
DX11Context::Instance()->setFrameRendered();
|
||||
#else
|
||||
ID3D11RenderTargetView *nullView = nullptr;
|
||||
deviceContext->OMSetRenderTargets(1, &nullView, nullptr);
|
||||
theDX11Context.presentFrame(fbTextureView, width, height);
|
||||
DX11Context::Instance()->presentFrame(fbTextureView, width, height);
|
||||
#endif
|
||||
frameRendered = true;
|
||||
frameRenderedOnce = true;
|
||||
@@ -547,7 +547,7 @@ void DX11Renderer::displayFramebuffer()
|
||||
float colors[4];
|
||||
VO_BORDER_COL.getRGBColor(colors);
|
||||
colors[3] = 1.f;
|
||||
deviceContext->ClearRenderTargetView(theDX11Context.getRenderTarget(), colors);
|
||||
deviceContext->ClearRenderTargetView(DX11Context::Instance()->getRenderTarget(), colors);
|
||||
|
||||
float shiftX, shiftY;
|
||||
getVideoShift(shiftX, shiftY);
|
||||
@@ -1031,15 +1031,15 @@ void DX11Renderer::RenderFramebuffer(const FramebufferInfo& info)
|
||||
|
||||
aspectRatio = getDCFramebufferAspectRatio();
|
||||
|
||||
deviceContext->OMSetRenderTargets(1, &theDX11Context.getRenderTarget().get(), nullptr);
|
||||
deviceContext->OMSetRenderTargets(1, &DX11Context::Instance()->getRenderTarget().get(), nullptr);
|
||||
displayFramebuffer();
|
||||
drawOSD();
|
||||
renderVideoRouting();
|
||||
theDX11Context.setFrameRendered();
|
||||
DX11Context::Instance()->setFrameRendered();
|
||||
#else
|
||||
ID3D11RenderTargetView *nullView = nullptr;
|
||||
deviceContext->OMSetRenderTargets(1, &nullView, nullptr);
|
||||
theDX11Context.presentFrame(dcfbTextureView, width, height);
|
||||
DX11Context::Instance()->presentFrame(dcfbTextureView, width, height);
|
||||
#endif
|
||||
frameRendered = true;
|
||||
frameRenderedOnce = true;
|
||||
@@ -1196,9 +1196,9 @@ void DX11Renderer::updateFogTexture()
|
||||
void DX11Renderer::drawOSD()
|
||||
{
|
||||
#ifndef LIBRETRO
|
||||
theDX11Context.setOverlay(true);
|
||||
DX11Context::Instance()->setOverlay(true);
|
||||
gui_display_osd();
|
||||
theDX11Context.setOverlay(false);
|
||||
DX11Context::Instance()->setOverlay(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1348,7 +1348,7 @@ bool DX11Renderer::GetLastFrame(std::vector<u8>& data, int& width, int& height)
|
||||
quad->draw(fbTextureView, samplers->getSampler(true), nullptr, -1.f, -1.f, 2.f, 2.f, config::Rotate90);
|
||||
|
||||
#ifndef LIBRETRO
|
||||
deviceContext->OMSetRenderTargets(1, &theDX11Context.getRenderTarget().get(), nullptr);
|
||||
deviceContext->OMSetRenderTargets(1, &DX11Context::Instance()->getRenderTarget().get(), nullptr);
|
||||
#else
|
||||
ID3D11RenderTargetView *nullView = nullptr;
|
||||
deviceContext->OMSetRenderTargets(1, &nullView, nullptr);
|
||||
@@ -1399,7 +1399,7 @@ void DX11Renderer::renderVideoRouting()
|
||||
{
|
||||
extern void os_VideoRoutingPublishFrameTexture(ID3D11Texture2D* pTexture);
|
||||
|
||||
ID3D11RenderTargetView* pRenderTargetView = theDX11Context.getRenderTarget().get();
|
||||
ID3D11RenderTargetView* pRenderTargetView = DX11Context::Instance()->getRenderTarget().get();
|
||||
|
||||
// Backbuffer texture would be different after resizing, fetching new address everytime
|
||||
ID3D11Resource* pResource = nullptr;
|
||||
@@ -1458,7 +1458,7 @@ void DX11Renderer::renderVideoRouting()
|
||||
quad->draw(vrStagingTextureSRV, samplers->getSampler(true));
|
||||
os_VideoRoutingPublishFrameTexture(vrScaledTexture);
|
||||
|
||||
deviceContext->OMSetRenderTargets(1, &theDX11Context.getRenderTarget().get(), nullptr);
|
||||
deviceContext->OMSetRenderTargets(1, &DX11Context::Instance()->getRenderTarget().get(), nullptr);
|
||||
|
||||
} else {
|
||||
os_VideoRoutingPublishFrameTexture(backBufferTexture);
|
||||
|
||||
@@ -48,7 +48,7 @@ struct DX11Renderer : public Renderer
|
||||
#ifndef LIBRETRO
|
||||
imguiDriver->setFrameRendered();
|
||||
#else
|
||||
theDX11Context.present();
|
||||
DX11Context::Instance()->present();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -21,10 +21,10 @@
|
||||
|
||||
HRESULT DepthStencilStates::createDepthStencilState(const D3D11_DEPTH_STENCIL_DESC *desc, ID3D11DepthStencilState **state)
|
||||
{
|
||||
return theDX11Context.getDevice()->CreateDepthStencilState(desc, state);
|
||||
return DX11Context::Instance()->getDevice()->CreateDepthStencilState(desc, state);
|
||||
}
|
||||
|
||||
HRESULT BlendStates::createBlendState(const D3D11_BLEND_DESC *desc, ID3D11BlendState **state)
|
||||
{
|
||||
return theDX11Context.getDevice()->CreateBlendState(desc, state);
|
||||
return DX11Context::Instance()->getDevice()->CreateBlendState(desc, state);
|
||||
}
|
||||
@@ -716,7 +716,7 @@ void DX11Shaders::init(const ComPtr<ID3D11Device>& device, pD3DCompile D3DCompil
|
||||
{
|
||||
this->device = device;
|
||||
this->D3DCompile = D3DCompile;
|
||||
enableCache(!theDX11Context.hasShaderCache());
|
||||
enableCache(!DX11Context::Instance()->hasShaderCache());
|
||||
loadCache(CacheFile);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,13 +86,13 @@ void DX11Texture::UploadToGPU(int width, int height, const u8* temp_tex_buffer,
|
||||
desc.BindFlags |= D3D11_BIND_RENDER_TARGET;
|
||||
mipmapLevels = 1;
|
||||
}
|
||||
if (SUCCEEDED(theDX11Context.getDevice()->CreateTexture2D(&desc, nullptr, &texture.get())))
|
||||
if (SUCCEEDED(DX11Context::Instance()->getDevice()->CreateTexture2D(&desc, nullptr, &texture.get())))
|
||||
{
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc{};
|
||||
viewDesc.Format = desc.Format;
|
||||
viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
viewDesc.Texture2D.MipLevels = desc.MipLevels == 0 ? -1 : desc.MipLevels;
|
||||
theDX11Context.getDevice()->CreateShaderResourceView(texture, &viewDesc, &textureView.get());
|
||||
DX11Context::Instance()->getDevice()->CreateShaderResourceView(texture, &viewDesc, &textureView.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -106,17 +106,17 @@ void DX11Texture::UploadToGPU(int width, int height, const u8* temp_tex_buffer,
|
||||
{
|
||||
u32 w = mipmapLevels == 1 ? width : 1 << i;
|
||||
u32 h = mipmapLevels == 1 ? height : 1 << i;
|
||||
theDX11Context.getDeviceContext()->UpdateSubresource(texture, mipmapLevels - i - 1, nullptr, temp_tex_buffer, w * bpp, w * bpp * h);
|
||||
DX11Context::Instance()->getDeviceContext()->UpdateSubresource(texture, mipmapLevels - i - 1, nullptr, temp_tex_buffer, w * bpp, w * bpp * h);
|
||||
temp_tex_buffer += (1 << (2 * i)) * bpp;
|
||||
}
|
||||
if (mipmapped && !mipmapsIncluded)
|
||||
theDX11Context.getDeviceContext()->GenerateMips(textureView);
|
||||
DX11Context::Instance()->getDeviceContext()->GenerateMips(textureView);
|
||||
}
|
||||
|
||||
#ifndef TARGET_UWP
|
||||
bool DX11Texture::Force32BitTexture(TextureType type) const
|
||||
{
|
||||
if (!theDX11Context.textureFormatSupported(type))
|
||||
if (!DX11Context::Instance()->textureFormatSupported(type))
|
||||
return true;
|
||||
if (IsWindows8OrGreater())
|
||||
return false;
|
||||
@@ -151,5 +151,5 @@ void DX11Texture::loadCustomTexture()
|
||||
|
||||
HRESULT Samplers::createSampler(const D3D11_SAMPLER_DESC *desc, ID3D11SamplerState **sampler)
|
||||
{
|
||||
return theDX11Context.getDevice()->CreateSamplerState(desc, sampler);
|
||||
return DX11Context::Instance()->getDevice()->CreateSamplerState(desc, sampler);
|
||||
}
|
||||
@@ -34,12 +34,24 @@
|
||||
|
||||
#include "nowide/stackstring.hpp"
|
||||
|
||||
DX11Context theDX11Context;
|
||||
void DX11Context::Create(void *window, void *display) {
|
||||
new DX11Context(window, display);
|
||||
}
|
||||
|
||||
DX11Context::DX11Context(void *window, void *display)
|
||||
: GraphicsContext(window, display)
|
||||
{
|
||||
if (!init())
|
||||
throw FlycastException("DX11 initialization failed");
|
||||
}
|
||||
|
||||
DX11Context::~DX11Context() {
|
||||
term();
|
||||
}
|
||||
|
||||
bool DX11Context::init(bool keepCurrentWindow)
|
||||
{
|
||||
NOTICE_LOG(RENDERER, "DX11 Context initializing");
|
||||
GraphicsContext::instance = this;
|
||||
#ifdef USE_SDL
|
||||
if (!keepCurrentWindow && !sdl_recreate_window(0))
|
||||
return false;
|
||||
@@ -199,7 +211,6 @@ bool DX11Context::init(bool keepCurrentWindow)
|
||||
void DX11Context::term()
|
||||
{
|
||||
NOTICE_LOG(RENDERER, "DX11 Context terminating");
|
||||
GraphicsContext::instance = nullptr;
|
||||
overlay.term();
|
||||
samplers.term();
|
||||
shaders.term();
|
||||
|
||||
@@ -33,8 +33,9 @@
|
||||
class DX11Context : public GraphicsContext
|
||||
{
|
||||
public:
|
||||
bool init(bool keepCurrentWindow = false);
|
||||
void term() override;
|
||||
static void Create(void *window, void *display = nullptr);
|
||||
static DX11Context *Instance() { return static_cast<DX11Context *>(GraphicsContext::Instance()); }
|
||||
|
||||
void EndImGuiFrame();
|
||||
void Present();
|
||||
const ComPtr<ID3D11Device>& getDevice() const { return pDevice; }
|
||||
@@ -80,6 +81,10 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
DX11Context(void *window, void *display);
|
||||
~DX11Context();
|
||||
bool init(bool keepCurrentWindow = false);
|
||||
void term();
|
||||
void handleDeviceLost();
|
||||
bool checkTextureSupport();
|
||||
|
||||
@@ -109,5 +114,4 @@ private:
|
||||
static constexpr UINT VENDOR_ATI = 0x1002;
|
||||
static constexpr UINT VENDOR_AMD = 0x1022;
|
||||
};
|
||||
extern DX11Context theDX11Context;
|
||||
#endif
|
||||
@@ -22,7 +22,19 @@
|
||||
#include "rend/osd.h"
|
||||
#include "rend/transform_matrix.h"
|
||||
|
||||
DX11Context theDX11Context;
|
||||
void DX11Context::Create(ID3D11Device *device, ID3D11DeviceContext *deviceContext, pD3DCompile D3DCompile, D3D_FEATURE_LEVEL featureLevel) {
|
||||
new DX11Context(device, deviceContext, D3DCompile, featureLevel);
|
||||
}
|
||||
|
||||
DX11Context::DX11Context(ID3D11Device *device, ID3D11DeviceContext *deviceContext, pD3DCompile D3DCompile, D3D_FEATURE_LEVEL featureLevel)
|
||||
{
|
||||
if (!init(device, deviceContext, D3DCompile, featureLevel))
|
||||
throw FlycastException("DX11 initialization failed");
|
||||
}
|
||||
|
||||
DX11Context::~DX11Context() {
|
||||
term();
|
||||
}
|
||||
|
||||
bool DX11Context::init(ID3D11Device *device, ID3D11DeviceContext *deviceContext, pD3DCompile D3DCompile, D3D_FEATURE_LEVEL featureLevel)
|
||||
{
|
||||
@@ -33,7 +45,6 @@ bool DX11Context::init(ID3D11Device *device, ID3D11DeviceContext *deviceContext,
|
||||
pDeviceContext.reset(deviceContext);
|
||||
this->D3DCompile = D3DCompile;
|
||||
this->featureLevel = featureLevel;
|
||||
GraphicsContext::instance = this;
|
||||
|
||||
ComPtr<IDXGIDevice2> dxgiDevice;
|
||||
pDevice.as(dxgiDevice);
|
||||
@@ -66,7 +77,6 @@ bool DX11Context::init(ID3D11Device *device, ID3D11DeviceContext *deviceContext,
|
||||
void DX11Context::term()
|
||||
{
|
||||
NOTICE_LOG(RENDERER, "DX11 Context terminating");
|
||||
GraphicsContext::instance = nullptr;
|
||||
blendStates.term();
|
||||
quad.reset();
|
||||
textureView.reset();
|
||||
|
||||
@@ -33,8 +33,9 @@
|
||||
class DX11Context : public GraphicsContext
|
||||
{
|
||||
public:
|
||||
bool init(ID3D11Device *device, ID3D11DeviceContext *deviceContext, pD3DCompile D3DCompile, D3D_FEATURE_LEVEL featureLevel);
|
||||
void term() override;
|
||||
static void Create(ID3D11Device *device, ID3D11DeviceContext *deviceContext, pD3DCompile D3DCompile, D3D_FEATURE_LEVEL featureLevel);
|
||||
static DX11Context *Instance() { return static_cast<DX11Context *>(GraphicsContext::Instance()); }
|
||||
~DX11Context();
|
||||
void present();
|
||||
|
||||
const ComPtr<ID3D11Device>& getDevice() const { return pDevice; }
|
||||
@@ -71,6 +72,9 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
DX11Context(ID3D11Device *device, ID3D11DeviceContext *deviceContext, pD3DCompile D3DCompile, D3D_FEATURE_LEVEL featureLevel);
|
||||
bool init(ID3D11Device *device, ID3D11DeviceContext *deviceContext, pD3DCompile D3DCompile, D3D_FEATURE_LEVEL featureLevel);
|
||||
void term();
|
||||
bool checkTextureSupport();
|
||||
ComPtr<ID3D11RenderTargetView>& getRenderTarget(int width, int height);
|
||||
|
||||
@@ -97,5 +101,4 @@ private:
|
||||
static constexpr UINT VENDOR_ATI = 0x1002;
|
||||
static constexpr UINT VENDOR_AMD = 0x1022;
|
||||
};
|
||||
extern DX11Context theDX11Context;
|
||||
#endif
|
||||
@@ -75,7 +75,7 @@ struct DX11OITRenderer : public DX11Renderer
|
||||
desc.ByteWidth = (((desc.ByteWidth - 1) >> 4) + 1) << 4;
|
||||
bool success = SUCCEEDED(device->CreateBuffer(&desc, nullptr, &pxlPolyConstants.get()));
|
||||
|
||||
shaders.init(device, theDX11Context.getCompiler());
|
||||
shaders.init(device, DX11Context::Instance()->getCompiler());
|
||||
buffers.init(device, deviceContext);
|
||||
pixelBufferSize = config::PixelBufferSize;
|
||||
ComPtr<ID3DBlob> blob = shaders.getVertexShaderBlob();
|
||||
@@ -579,7 +579,7 @@ struct DX11OITRenderer : public DX11Renderer
|
||||
drawList<ListType_Translucent, true, DX11OITShaders::OIT>(rendContext->global_param_tr, previous_pass.tr_count, tr_count);
|
||||
// unbind depth tex
|
||||
deviceContext->PSSetShaderResources(4, 1, &nullView);
|
||||
if (!theDX11Context.isIntel())
|
||||
if (!DX11Context::Instance()->isIntel())
|
||||
{
|
||||
// Intel Iris Plus 640 just crashes
|
||||
if (current_pass.mv_op_tr_shared)
|
||||
@@ -681,15 +681,15 @@ struct DX11OITRenderer : public DX11Renderer
|
||||
{
|
||||
aspectRatio = getOutputFramebufferAspectRatio();
|
||||
#ifndef LIBRETRO
|
||||
deviceContext->OMSetRenderTargets(1, &theDX11Context.getRenderTarget().get(), nullptr);
|
||||
deviceContext->OMSetRenderTargets(1, &DX11Context::Instance()->getRenderTarget().get(), nullptr);
|
||||
displayFramebuffer();
|
||||
drawOSD();
|
||||
renderVideoRouting();
|
||||
theDX11Context.setFrameRendered();
|
||||
DX11Context::Instance()->setFrameRendered();
|
||||
#else
|
||||
ID3D11RenderTargetView *nullView = nullptr;
|
||||
deviceContext->OMSetRenderTargets(1, &nullView, nullptr);
|
||||
theDX11Context.presentFrame(fbTextureView, width, height);
|
||||
DX11Context::Instance()->presentFrame(fbTextureView, width, height);
|
||||
#endif
|
||||
frameRendered = true;
|
||||
frameRenderedOnce = true;
|
||||
|
||||
@@ -1078,6 +1078,6 @@ void DX11OITShaders::init(const ComPtr<ID3D11Device>& device, pD3DCompile D3DCom
|
||||
{
|
||||
this->device = device;
|
||||
this->D3DCompile = D3DCompile;
|
||||
enableCache(!theDX11Context.hasShaderCache());
|
||||
enableCache(!DX11Context::Instance()->hasShaderCache());
|
||||
loadCache(CacheFile);
|
||||
}
|
||||
@@ -113,7 +113,7 @@ bool D3DRenderer::ensureIndexBufferSize(ComPtr<IDirect3DIndexBuffer9>& buffer, u
|
||||
|
||||
bool D3DRenderer::Init()
|
||||
{
|
||||
ComPtr<IDirect3D9> d3d9 = theDXContext.getD3D();
|
||||
ComPtr<IDirect3D9> d3d9 = DXContext::Instance()->getD3D();
|
||||
D3DCAPS9 caps;
|
||||
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
|
||||
if (caps.VertexShaderVersion < D3DVS_VERSION(1, 0))
|
||||
@@ -128,7 +128,7 @@ bool D3DRenderer::Init()
|
||||
}
|
||||
maxAnisotropy = caps.MaxAnisotropy;
|
||||
|
||||
device = theDXContext.getDevice();
|
||||
device = DXContext::Instance()->getDevice();
|
||||
devCache.setDevice(device);
|
||||
|
||||
bool success = ensureVertexBufferSize(vertexBuffer, vertexBufferSize, 4_MB);
|
||||
@@ -215,7 +215,7 @@ void D3DRenderer::Term()
|
||||
|
||||
BaseTextureCacheData *D3DRenderer::GetTexture(TSP tsp, TCW tcw, int area)
|
||||
{
|
||||
if (!theDXContext.isReady())
|
||||
if (!DXContext::Instance()->isReady())
|
||||
return nullptr;
|
||||
//lookup texture
|
||||
D3DTexture* tf = texCache.getTextureCacheData(tsp, tcw, area);
|
||||
@@ -237,7 +237,7 @@ BaseTextureCacheData *D3DRenderer::GetTexture(TSP tsp, TCW tcw, int area)
|
||||
|
||||
void D3DRenderer::RenderFramebuffer(const FramebufferInfo& info)
|
||||
{
|
||||
if (!theDXContext.isReady()) {
|
||||
if (!DXContext::Instance()->isReady()) {
|
||||
// force a Present
|
||||
frameRendered = true;
|
||||
return;
|
||||
@@ -306,12 +306,12 @@ void D3DRenderer::RenderFramebuffer(const FramebufferInfo& info)
|
||||
frameRendered = true;
|
||||
frameRenderedOnce = true;
|
||||
clearLastFrame = false;
|
||||
theDXContext.setFrameRendered();
|
||||
DXContext::Instance()->setFrameRendered();
|
||||
}
|
||||
|
||||
void D3DRenderer::Process(TA_context* ctx)
|
||||
{
|
||||
if (!theDXContext.isReady()) {
|
||||
if (!DXContext::Instance()->isReady()) {
|
||||
// force a Present
|
||||
frameRendered = true;
|
||||
return;
|
||||
@@ -953,7 +953,7 @@ void D3DRenderer::readRttRenderTarget(u32 texAddress)
|
||||
|
||||
bool D3DRenderer::Render()
|
||||
{
|
||||
if (!theDXContext.isReady())
|
||||
if (!DXContext::Instance()->isReady())
|
||||
return false;
|
||||
|
||||
bool is_rtt = rendContext->isRTT;
|
||||
@@ -1139,7 +1139,7 @@ bool D3DRenderer::Render()
|
||||
frameRendered = true;
|
||||
frameRenderedOnce = true;
|
||||
clearLastFrame = false;
|
||||
theDXContext.setFrameRendered();
|
||||
DXContext::Instance()->setFrameRendered();
|
||||
}
|
||||
|
||||
return !is_rtt;
|
||||
@@ -1236,7 +1236,7 @@ void D3DRenderer::displayFramebuffer()
|
||||
|
||||
bool D3DRenderer::RenderLastFrame()
|
||||
{
|
||||
if (clearLastFrame || !frameRenderedOnce || !theDXContext.isReady())
|
||||
if (clearLastFrame || !frameRenderedOnce || !DXContext::Instance()->isReady())
|
||||
return false;
|
||||
backbuffer.reset();
|
||||
bool rc = SUCCEEDED(device->GetRenderTarget(0, &backbuffer.get()));
|
||||
@@ -1298,9 +1298,9 @@ void D3DRenderer::updateFogTexture()
|
||||
|
||||
void D3DRenderer::drawOSD()
|
||||
{
|
||||
theDXContext.setOverlay(true);
|
||||
DXContext::Instance()->setOverlay(true);
|
||||
gui_display_osd();
|
||||
theDXContext.setOverlay(false);
|
||||
DXContext::Instance()->setOverlay(false);
|
||||
}
|
||||
|
||||
void D3DRenderer::writeFramebufferToVRAM()
|
||||
@@ -1376,7 +1376,7 @@ void D3DRenderer::writeFramebufferToVRAM()
|
||||
|
||||
bool D3DRenderer::GetLastFrame(std::vector<u8>& data, int& width, int& height)
|
||||
{
|
||||
if (!frameRenderedOnce || !theDXContext.isReady())
|
||||
if (!frameRenderedOnce || !DXContext::Instance()->isReady())
|
||||
return false;
|
||||
|
||||
if (width != 0) {
|
||||
|
||||
@@ -68,7 +68,7 @@ void D3DTexture::UploadToGPU(int width, int height, const u8* temp_tex_buffer, b
|
||||
levels = 0;
|
||||
usage = D3DUSAGE_AUTOGENMIPMAP;
|
||||
}
|
||||
theDXContext.getDevice()->CreateTexture(width, height, levels, usage, d3dFormat, D3DPOOL_MANAGED, &texture.get(), 0); // TODO the managed pool persists between device resets
|
||||
DXContext::Instance()->getDevice()->CreateTexture(width, height, levels, usage, d3dFormat, D3DPOOL_MANAGED, &texture.get(), 0); // TODO the managed pool persists between device resets
|
||||
verify(texture != nullptr);
|
||||
}
|
||||
if (SUCCEEDED(texture->LockRect(mipmapLevels - 1, &rect, nullptr, 0)))
|
||||
|
||||
@@ -38,14 +38,14 @@ public:
|
||||
}
|
||||
|
||||
void renderDrawData(ImDrawData *drawData, bool gui_open) override {
|
||||
theDXContext.EndImGuiFrame();
|
||||
DXContext::Instance()->EndImGuiFrame();
|
||||
if (gui_open)
|
||||
frameRendered = true;
|
||||
}
|
||||
|
||||
void present() override {
|
||||
if (frameRendered)
|
||||
theDXContext.Present();
|
||||
DXContext::Instance()->Present();
|
||||
frameRendered = false;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ public:
|
||||
{
|
||||
Texture& texture = textures[name];
|
||||
texture.tex.reset();
|
||||
HRESULT hr = theDXContext.getDevice()->CreateTexture(width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture.tex.get(), 0);
|
||||
HRESULT hr = DXContext::Instance()->getDevice()->CreateTexture(width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture.tex.get(), 0);
|
||||
if (FAILED(hr) || !texture.tex)
|
||||
{
|
||||
WARN_LOG(RENDERER, "CreateTexture failed (%d x %d): error %x", width, height, hr);
|
||||
|
||||
@@ -27,12 +27,24 @@
|
||||
#include "dx9_driver.h"
|
||||
#include "imgui_impl_dx9.h"
|
||||
|
||||
DXContext theDXContext;
|
||||
void DXContext::Create(void *window, void *display) {
|
||||
new DXContext(window, display);
|
||||
}
|
||||
|
||||
DXContext::DXContext(void *window, void *display)
|
||||
: GraphicsContext(window, display)
|
||||
{
|
||||
if (!init())
|
||||
throw FlycastException("DX9 initialization failed");
|
||||
}
|
||||
|
||||
DXContext::~DXContext() {
|
||||
term();
|
||||
}
|
||||
|
||||
bool DXContext::init(bool keepCurrentWindow)
|
||||
{
|
||||
NOTICE_LOG(RENDERER, "DX9 Context initializing");
|
||||
GraphicsContext::instance = this;
|
||||
#ifdef USE_SDL
|
||||
if (!keepCurrentWindow && !sdl_recreate_window(0)) {
|
||||
term();
|
||||
@@ -93,7 +105,6 @@ bool DXContext::init(bool keepCurrentWindow)
|
||||
void DXContext::term()
|
||||
{
|
||||
NOTICE_LOG(RENDERER, "DX9 Context terminating");
|
||||
GraphicsContext::instance = nullptr;
|
||||
overlay.term();
|
||||
imguiDriver.reset();
|
||||
pDevice.reset();
|
||||
|
||||
@@ -30,8 +30,9 @@
|
||||
class DXContext : public GraphicsContext
|
||||
{
|
||||
public:
|
||||
bool init(bool keepCurrentWindow = false);
|
||||
void term() override;
|
||||
static void Create(void *window, void *display);
|
||||
static DXContext *Instance() { return static_cast<DXContext *>(GraphicsContext::Instance()); }
|
||||
~DXContext();
|
||||
void EndImGuiFrame();
|
||||
void Present();
|
||||
void resize() override;
|
||||
@@ -62,6 +63,9 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
DXContext(void *window, void *display);
|
||||
bool init(bool keepCurrentWindow = false);
|
||||
void term();
|
||||
void resetDevice();
|
||||
|
||||
WinLibLoader d3d9Library{ "D3D9.DLL" };
|
||||
@@ -77,5 +81,4 @@ private:
|
||||
bool amd = false;
|
||||
bool deviceReady = false;
|
||||
};
|
||||
extern DXContext theDXContext;
|
||||
#endif
|
||||
@@ -505,9 +505,9 @@ bool testBlitFramebuffer();
|
||||
void findGLVersion()
|
||||
{
|
||||
gl.index_type = GL_UNSIGNED_INT;
|
||||
gl.gl_major = theGLContext.getMajorVersion();
|
||||
gl.gl_minor = theGLContext.getMinorVersion();
|
||||
gl.is_gles = theGLContext.isGLES();
|
||||
gl.gl_major = GLGraphicsContext::Instance()->getMajorVersion();
|
||||
gl.gl_minor = GLGraphicsContext::Instance()->getMinorVersion();
|
||||
gl.is_gles = GLGraphicsContext::Instance()->isGLES();
|
||||
if (gl.is_gles)
|
||||
{
|
||||
gl.border_clamp_supported = false;
|
||||
@@ -1079,7 +1079,7 @@ void OpenGLRenderer::Process(TA_context* ctx)
|
||||
updatePalette = false;
|
||||
}
|
||||
if (!ctx->rend.isRTT && ctx->rend.swapInterval > 0)
|
||||
theGLContext.setSwapInterval(ctx->rend.swapInterval);
|
||||
GraphicsContext::Instance()->setSwapInterval(ctx->rend.swapInterval);
|
||||
ta_parse(ctx, gl.prim_restart_fixed_supported || gl.prim_restart_supported);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ void OpenGLDriver::renderDrawData(ImDrawData* drawData, bool gui_open)
|
||||
void OpenGLDriver::present()
|
||||
{
|
||||
if (frameRendered)
|
||||
theGLContext.swap();
|
||||
GLGraphicsContext::Instance()->swap();
|
||||
frameRendered = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,10 @@
|
||||
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
||||
#endif
|
||||
|
||||
VulkanContext *VulkanContext::contextInstance;
|
||||
bool VulkanContext::fragmentStoresAndAtomics = false;
|
||||
bool VulkanContext::samplerAnisotropy = false;
|
||||
bool VulkanContext::dedicatedAllocationSupported = false;
|
||||
bool VulkanContext::provokingVertexSupported = false;
|
||||
|
||||
const VkApplicationInfo* VkGetApplicationInfo()
|
||||
{
|
||||
@@ -156,18 +159,15 @@ bool VkCreateDevice(retro_vulkan_context* context, VkInstance instance, VkPhysic
|
||||
tryAddDeviceExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
|
||||
|
||||
// Enable VK_KHR_dedicated_allocation if available
|
||||
if (physicalDeviceProperties.apiVersion >= VK_API_VERSION_1_1)
|
||||
{
|
||||
if (physicalDeviceProperties.apiVersion >= VK_API_VERSION_1_1) {
|
||||
// Core in Vulkan 1.1
|
||||
VulkanContext::Instance()->dedicatedAllocationSupported = true;
|
||||
VulkanContext::dedicatedAllocationSupported = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool getMemReq2Supported = tryAddDeviceExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME);
|
||||
if (getMemReq2Supported)
|
||||
{
|
||||
VulkanContext::Instance()->dedicatedAllocationSupported = tryAddDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
|
||||
}
|
||||
VulkanContext::dedicatedAllocationSupported = tryAddDeviceExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
// Check for VK_KHR_get_physical_device_properties2
|
||||
@@ -177,10 +177,8 @@ bool VkCreateDevice(retro_vulkan_context* context, VkInstance instance, VkPhysic
|
||||
? true : tryAddDeviceExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
|
||||
|
||||
if (getPhysicalDeviceProperties2Supported)
|
||||
{
|
||||
// Enable VK_EXT_provoking_vertex if available
|
||||
VulkanContext::Instance()->provokingVertexSupported = tryAddDeviceExtension(VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME);
|
||||
}
|
||||
VulkanContext::provokingVertexSupported = tryAddDeviceExtension(VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME);
|
||||
|
||||
// Get device features
|
||||
|
||||
@@ -188,28 +186,20 @@ bool VkCreateDevice(retro_vulkan_context* context, VkInstance instance, VkPhysic
|
||||
vk::PhysicalDeviceFeatures& features = featuresChain.features;
|
||||
|
||||
vk::PhysicalDeviceProvokingVertexFeaturesEXT provokingVertexFeatures{};
|
||||
if (VulkanContext::Instance()->provokingVertexSupported)
|
||||
{
|
||||
if (VulkanContext::provokingVertexSupported)
|
||||
featuresChain.pNext = &provokingVertexFeatures;
|
||||
}
|
||||
|
||||
// Get the physical device's features
|
||||
if (getPhysicalDeviceProperties2Supported && featuresChain.pNext)
|
||||
{
|
||||
physicalDevice.getFeatures2(&featuresChain);
|
||||
}
|
||||
else
|
||||
{
|
||||
physicalDevice.getFeatures(&features);
|
||||
}
|
||||
|
||||
if (VulkanContext::Instance()->provokingVertexSupported)
|
||||
{
|
||||
VulkanContext::Instance()->provokingVertexSupported &= provokingVertexFeatures.provokingVertexLast;
|
||||
}
|
||||
if (VulkanContext::provokingVertexSupported)
|
||||
VulkanContext::provokingVertexSupported &= provokingVertexFeatures.provokingVertexLast;
|
||||
|
||||
VulkanContext::Instance()->samplerAnisotropy = features.samplerAnisotropy;
|
||||
VulkanContext::Instance()->fragmentStoresAndAtomics = features.fragmentStoresAndAtomics;
|
||||
VulkanContext::samplerAnisotropy = features.samplerAnisotropy;
|
||||
VulkanContext::fragmentStoresAndAtomics = features.fragmentStoresAndAtomics;
|
||||
|
||||
// create a Device
|
||||
float queuePriority = 1.0f;
|
||||
@@ -248,7 +238,6 @@ bool VulkanContext::init(retro_hw_render_interface_vulkan *retro_render_if)
|
||||
|| retro_render_if->interface_version != RETRO_HW_RENDER_INTERFACE_VULKAN_VERSION)
|
||||
return false;
|
||||
this->retro_render_if = retro_render_if;
|
||||
GraphicsContext::instance = this;
|
||||
|
||||
instance = vk::Instance(retro_render_if->instance);
|
||||
physicalDevice = vk::PhysicalDevice(retro_render_if->gpu);
|
||||
@@ -510,7 +499,6 @@ void VulkanContext::endFrame(vk::Image barrierImage)
|
||||
|
||||
void VulkanContext::term()
|
||||
{
|
||||
GraphicsContext::instance = nullptr;
|
||||
if (device)
|
||||
{
|
||||
device.waitIdle();
|
||||
@@ -544,14 +532,17 @@ void VulkanContext::term()
|
||||
pipelineCache.reset();
|
||||
}
|
||||
|
||||
VulkanContext::VulkanContext()
|
||||
{
|
||||
assert(contextInstance == nullptr);
|
||||
contextInstance = this;
|
||||
void VulkanContext::Create(retro_hw_render_interface_vulkan *render_if) {
|
||||
new VulkanContext(render_if);
|
||||
}
|
||||
|
||||
VulkanContext::~VulkanContext()
|
||||
VulkanContext::VulkanContext(retro_hw_render_interface_vulkan *render_if)
|
||||
: GraphicsContext(nullptr, nullptr)
|
||||
{
|
||||
assert(contextInstance == this);
|
||||
contextInstance = nullptr;
|
||||
if (!init(render_if))
|
||||
throw FlycastException("Vulkan initialization failed");
|
||||
}
|
||||
|
||||
VulkanContext::~VulkanContext() {
|
||||
term();
|
||||
}
|
||||
@@ -36,11 +36,8 @@ class FramebufferAttachment;
|
||||
class VulkanContext : public GraphicsContext, public FlightManager
|
||||
{
|
||||
public:
|
||||
VulkanContext();
|
||||
~VulkanContext() override;
|
||||
|
||||
bool init(retro_hw_render_interface_vulkan *render_if);
|
||||
void term() override;
|
||||
~VulkanContext();
|
||||
static void Create(retro_hw_render_interface_vulkan *render_if);
|
||||
|
||||
u32 GetGraphicsQueueFamilyIndex() const { return retro_render_if->queue_index; }
|
||||
void PresentFrame(vk::Image image, vk::ImageView imageView, const vk::Extent2D& extent, float aspectRatio);
|
||||
@@ -88,7 +85,7 @@ public:
|
||||
return vendorID == VENDOR_ATI || vendorID == VENDOR_AMD;
|
||||
}
|
||||
vk::Format GetDepthFormat() const { return depthFormat; }
|
||||
static VulkanContext *Instance() { return contextInstance; }
|
||||
static VulkanContext *Instance() { return static_cast<VulkanContext *>(GraphicsContext::Instance()); }
|
||||
bool SupportsSamplerAnisotropy() const { return samplerAnisotropy; }
|
||||
bool SupportsDedicatedAllocation() const { return dedicatedAllocationSupported; }
|
||||
bool hasPerPixel() override { return fragmentStoresAndAtomics; }
|
||||
@@ -117,6 +114,9 @@ public:
|
||||
constexpr static int VENDOR_MESA = 0x10005;
|
||||
|
||||
private:
|
||||
VulkanContext(retro_hw_render_interface_vulkan *render_if);
|
||||
bool init(retro_hw_render_interface_vulkan *render_if);
|
||||
void term();
|
||||
void beginFrame(vk::Extent2D extent, vk::Image barrierImage);
|
||||
void endFrame(vk::Image barrierImage);
|
||||
|
||||
@@ -130,11 +130,11 @@ private:
|
||||
bool optimalTilingSupported1555 = false;
|
||||
bool optimalTilingSupported4444 = false;
|
||||
public:
|
||||
bool fragmentStoresAndAtomics = false;
|
||||
bool samplerAnisotropy = false;
|
||||
static bool fragmentStoresAndAtomics;
|
||||
static bool samplerAnisotropy;
|
||||
f32 maxSamplerAnisotropy = 0.f;
|
||||
bool dedicatedAllocationSupported = false;
|
||||
bool provokingVertexSupported = false;
|
||||
static bool dedicatedAllocationSupported;
|
||||
static bool provokingVertexSupported;
|
||||
private:
|
||||
u32 vendorID = 0;
|
||||
|
||||
@@ -162,8 +162,6 @@ private:
|
||||
std::unique_ptr<VulkanOverlay> overlay;
|
||||
|
||||
retro_vulkan_image retro_image;
|
||||
|
||||
static VulkanContext *contextInstance;
|
||||
};
|
||||
|
||||
const VkApplicationInfo* VkGetApplicationInfo();
|
||||
|
||||
@@ -50,8 +50,6 @@ VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
|
||||
|
||||
void ReInitOSD();
|
||||
|
||||
VulkanContext *VulkanContext::contextInstance;
|
||||
|
||||
#ifdef VK_DEBUG
|
||||
#ifndef __ANDROID__
|
||||
VKAPI_ATTR static VkBool32 VKAPI_CALL debugUtilsMessengerCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
|
||||
@@ -370,7 +368,7 @@ void VulkanContext::InitImgui()
|
||||
|
||||
#if VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1
|
||||
ImGui_ImplVulkan_LoadFunctions(0, [](const char *function_name, void *) {
|
||||
return VULKAN_HPP_DEFAULT_DISPATCHER.vkGetInstanceProcAddr((VkInstance) *contextInstance->instance, function_name);
|
||||
return VULKAN_HPP_DEFAULT_DISPATCHER.vkGetInstanceProcAddr((VkInstance) *Instance()->instance, function_name);
|
||||
});
|
||||
#endif
|
||||
|
||||
@@ -875,8 +873,6 @@ void VulkanContext::CreateSwapChain()
|
||||
|
||||
bool VulkanContext::init()
|
||||
{
|
||||
GraphicsContext::instance = this;
|
||||
|
||||
std::vector<const char *> extensions;
|
||||
extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME);
|
||||
#if defined(USE_SDL)
|
||||
@@ -1183,7 +1179,6 @@ void VulkanContext::PresentLastFrame()
|
||||
|
||||
void VulkanContext::term()
|
||||
{
|
||||
GraphicsContext::instance = nullptr;
|
||||
lastFrameView = nullptr;
|
||||
if (device && graphicsQueue)
|
||||
WaitIdle();
|
||||
@@ -1415,16 +1410,19 @@ void VulkanContext::SetWindowSize(u32 width, u32 height)
|
||||
}
|
||||
}
|
||||
|
||||
VulkanContext::VulkanContext()
|
||||
{
|
||||
assert(contextInstance == nullptr);
|
||||
contextInstance = this;
|
||||
void VulkanContext::Create(void *window, void *display) {
|
||||
new VulkanContext(window, display);
|
||||
}
|
||||
|
||||
VulkanContext::~VulkanContext()
|
||||
VulkanContext::VulkanContext(void *window, void *display)
|
||||
: GraphicsContext(window, display)
|
||||
{
|
||||
assert(contextInstance == this);
|
||||
contextInstance = nullptr;
|
||||
if (!init())
|
||||
throw FlycastException("Vulkan initialization failed");
|
||||
}
|
||||
|
||||
VulkanContext::~VulkanContext() {
|
||||
term();
|
||||
}
|
||||
|
||||
bool VulkanContext::GetLastFrame(std::vector<u8>& data, int& width, int& height)
|
||||
|
||||
@@ -97,12 +97,9 @@ struct ImDrawData;
|
||||
class VulkanContext : public GraphicsContext, public FlightManager
|
||||
{
|
||||
public:
|
||||
VulkanContext();
|
||||
static void Create(void *window, void *display);
|
||||
~VulkanContext() override;
|
||||
|
||||
bool init();
|
||||
void term() override;
|
||||
|
||||
VkInstance GetInstance() const { return static_cast<VkInstance>(instance.get()); }
|
||||
u32 GetGraphicsQueueFamilyIndex() const { return graphicsQueueIndex; }
|
||||
void resize() override { resized = true; }
|
||||
@@ -153,7 +150,7 @@ public:
|
||||
return vendorID == VENDOR_ATI || vendorID == VENDOR_AMD;
|
||||
}
|
||||
vk::Format GetDepthFormat() const { return depthFormat; }
|
||||
static VulkanContext *Instance() { return contextInstance; }
|
||||
static VulkanContext *Instance() { return static_cast<VulkanContext *>(GraphicsContext::Instance()); }
|
||||
bool SupportsSamplerAnisotropy() const { return samplerAnisotropy; }
|
||||
float GetMaxSamplerAnisotropy() const { return samplerAnisotropy ? maxSamplerAnisotropy : 1.f; }
|
||||
bool SupportsDedicatedAllocation() const { return dedicatedAllocationSupported; }
|
||||
@@ -197,6 +194,9 @@ public:
|
||||
constexpr static int VENDOR_MESA = 0x10005;
|
||||
|
||||
private:
|
||||
VulkanContext(void *window, void *display);
|
||||
bool init();
|
||||
void term();
|
||||
void CreateSwapChain();
|
||||
bool InitDevice();
|
||||
bool InitInstance(const char** extensions, uint32_t extensions_count);
|
||||
@@ -286,7 +286,6 @@ private:
|
||||
vk::UniqueDebugReportCallbackEXT debugReportCallback;
|
||||
#endif
|
||||
#endif
|
||||
static VulkanContext *contextInstance;
|
||||
};
|
||||
#endif // !LIBRETRO
|
||||
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
#endif
|
||||
#include "vgamepad.h"
|
||||
#include "settings.h"
|
||||
#include "wsi/context.h"
|
||||
#include "oslib/i18n.h"
|
||||
#include "gui_font.h"
|
||||
using namespace i18n;
|
||||
@@ -111,8 +110,6 @@ static void emuEventCallback(Event event, void *)
|
||||
case Event::Terminate:
|
||||
GamepadDevice::load_system_mappings();
|
||||
game_started = false;
|
||||
if (GraphicsContext::Instance() != nullptr)
|
||||
GraphicsContext::Instance()->setSwapInterval(1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
context.cpp
|
||||
context.h
|
||||
libretro.cpp
|
||||
libretro.h
|
||||
switcher.cpp)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
Copyright 2021 flyinghead
|
||||
Copyright 2026 flyinghead
|
||||
|
||||
This file is part of Flycast.
|
||||
This file is part of Flycast.
|
||||
|
||||
Flycast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -15,16 +15,26 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "libretro.h"
|
||||
|
||||
#ifdef LIBRETRO
|
||||
|
||||
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
|
||||
LibretroGraphicsContext theGLContext;
|
||||
#endif
|
||||
|
||||
*/
|
||||
#include "context.h"
|
||||
|
||||
GraphicsContext *GraphicsContext::instance;
|
||||
#endif
|
||||
|
||||
GraphicsContext::GraphicsContext(void *window, void *display)
|
||||
: window(window), display(display)
|
||||
{
|
||||
instance = this;
|
||||
EventManager::listen(Event::Pause, GraphicsContext::onEvent, this);
|
||||
EventManager::listen(Event::Terminate, GraphicsContext::onEvent, this);
|
||||
}
|
||||
|
||||
GraphicsContext::~GraphicsContext() {
|
||||
EventManager::unlisten(Event::Pause, GraphicsContext::onEvent, this);
|
||||
EventManager::unlisten(Event::Terminate, GraphicsContext::onEvent, this);
|
||||
instance = nullptr;
|
||||
}
|
||||
|
||||
void GraphicsContext::onEvent(Event event, void *arg) {
|
||||
GraphicsContext *self = (GraphicsContext *)arg;
|
||||
self->setSwapInterval(1);
|
||||
}
|
||||
+15
-2
@@ -19,7 +19,9 @@
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "emulator.h"
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
void initRenderApi(void *window = nullptr, void *display = nullptr);
|
||||
void termRenderApi();
|
||||
@@ -28,8 +30,7 @@ void switchRenderApi();
|
||||
class GraphicsContext
|
||||
{
|
||||
public:
|
||||
virtual ~GraphicsContext() = default;
|
||||
virtual void term() = 0;
|
||||
virtual ~GraphicsContext();
|
||||
virtual void resize() {}
|
||||
virtual std::string getDriverName() = 0;
|
||||
virtual std::string getDriverVersion() = 0;
|
||||
@@ -50,9 +51,21 @@ public:
|
||||
static GraphicsContext *Instance() {
|
||||
return instance;
|
||||
}
|
||||
static void Term()
|
||||
{
|
||||
if (instance != nullptr) {
|
||||
delete instance;
|
||||
assert(instance == nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
GraphicsContext(void *window, void *display = nullptr);
|
||||
|
||||
void *window = nullptr;
|
||||
void *display = nullptr;
|
||||
|
||||
private:
|
||||
static void onEvent(Event event, void *arg);
|
||||
static GraphicsContext *instance;
|
||||
};
|
||||
+14
-2
@@ -18,7 +18,7 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "gl_context.h"
|
||||
#include "egl.h"
|
||||
|
||||
#ifdef USE_EGL
|
||||
#include "types.h"
|
||||
@@ -28,7 +28,19 @@
|
||||
#include <android/native_window.h> // requires ndk r5 or newer
|
||||
#endif
|
||||
|
||||
EGLGraphicsContext theGLContext;
|
||||
#ifndef SWAPPY
|
||||
void EGLGraphicsContext::Create(void *window, void *display)
|
||||
{
|
||||
new EGLGraphicsContext(window, display);
|
||||
}
|
||||
#endif
|
||||
|
||||
EGLGraphicsContext::EGLGraphicsContext(void *window, void *display)
|
||||
: GLGraphicsContext(window, display)
|
||||
{
|
||||
if (!init())
|
||||
throw FlycastException("OpenGL initialization failed");
|
||||
}
|
||||
|
||||
bool EGLGraphicsContext::makeCurrent()
|
||||
{
|
||||
|
||||
+9
-7
@@ -21,19 +21,22 @@
|
||||
#pragma once
|
||||
#include "gl_context.h"
|
||||
|
||||
#if !defined(USE_SDL) && !defined(LIBRETRO) && (defined(__ANDROID__) || defined(SUPPORT_X11))
|
||||
#define USE_EGL
|
||||
#include <glad/egl.h>
|
||||
|
||||
class EGLGraphicsContext : public GLGraphicsContext
|
||||
{
|
||||
public:
|
||||
~EGLGraphicsContext() override { term(); }
|
||||
~EGLGraphicsContext() { term(); }
|
||||
|
||||
void swap() override;
|
||||
static void Create(void *window, void *display);
|
||||
|
||||
protected:
|
||||
EGLGraphicsContext(void *window, void *display);
|
||||
bool init();
|
||||
void term() override;
|
||||
void swap();
|
||||
|
||||
private:
|
||||
void term();
|
||||
bool makeCurrent();
|
||||
void changeSwapInterval();
|
||||
|
||||
@@ -44,5 +47,4 @@ private:
|
||||
int maxSwapInterval = 1;
|
||||
int currentSwapInterval = 1;
|
||||
};
|
||||
|
||||
extern EGLGraphicsContext theGLContext;
|
||||
#endif
|
||||
+24
-2
@@ -19,6 +19,17 @@
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "gl_context.h"
|
||||
#if defined(LIBRETRO)
|
||||
#include "libretro.h"
|
||||
#elif defined(TARGET_IPHONE)
|
||||
#include "osx.h"
|
||||
#elif defined(USE_SDL)
|
||||
#include "sdl.h"
|
||||
#elif defined(__ANDROID__) || defined(SUPPORT_X11)
|
||||
#include "egl.h"
|
||||
#else
|
||||
#error Unsupported window system
|
||||
#endif
|
||||
|
||||
#ifndef LIBRETRO
|
||||
#include "rend/gles/opengl_driver.h"
|
||||
@@ -60,7 +71,6 @@ void GLGraphicsContext::findGLVersion()
|
||||
|
||||
void GLGraphicsContext::postInit()
|
||||
{
|
||||
instance = this;
|
||||
findGLVersion();
|
||||
resetUIDriver();
|
||||
}
|
||||
@@ -70,7 +80,6 @@ void GLGraphicsContext::preTerm()
|
||||
#ifndef LIBRETRO
|
||||
imguiDriver.reset();
|
||||
#endif
|
||||
instance = nullptr;
|
||||
}
|
||||
|
||||
void GLGraphicsContext::resetUIDriver()
|
||||
@@ -88,3 +97,16 @@ void GLGraphicsContext::setSwapInterval(int interval)
|
||||
gameSwapInterval = interval;
|
||||
gameSwapIntervalChanged = true;
|
||||
}
|
||||
|
||||
void GLGraphicsContext::Create(void *window, void *display)
|
||||
{
|
||||
#if defined(LIBRETRO)
|
||||
LibretroGraphicsContext::Create(window, display);
|
||||
#elif defined(TARGET_IPHONE)
|
||||
OSXGraphicsContext::Create(window, display);
|
||||
#elif defined(USE_SDL)
|
||||
SDLGLGraphicsContext::Create(window, display);
|
||||
#elif defined(__ANDROID__) || defined(SUPPORT_X11)
|
||||
EGLGraphicsContext::Create(window, display);
|
||||
#endif
|
||||
}
|
||||
+39
-24
@@ -22,8 +22,37 @@
|
||||
#include "types.h"
|
||||
#include "context.h"
|
||||
|
||||
#if defined(USE_OPENGL) && !defined(LIBRETRO) && !defined(TARGET_IPHONE)
|
||||
#include <glad/gl.h>
|
||||
#if defined(TARGET_IPHONE)
|
||||
#include <OpenGLES/ES3/gl.h>
|
||||
#include <OpenGLES/ES3/glext.h>
|
||||
|
||||
#elif defined(LIBRETRO)
|
||||
#include <libretro.h>
|
||||
#include <glsm/glsm.h>
|
||||
#include <glsm/glsmsym.h>
|
||||
|
||||
#ifndef GL_MAJOR_VERSION
|
||||
#define GL_MAJOR_VERSION 0x821B
|
||||
#endif
|
||||
#ifndef GL_MINOR_VERSION
|
||||
#define GL_MINOR_VERSION 0x821C
|
||||
#endif
|
||||
|
||||
#ifndef GL_DEBUG_SEVERITY_NOTIFICATION
|
||||
#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
|
||||
#endif
|
||||
#ifndef GL_DEBUG_SEVERITY_HIGH
|
||||
#define GL_DEBUG_SEVERITY_HIGH 0x9146
|
||||
#endif
|
||||
#ifndef GL_DEBUG_SEVERITY_MEDIUM
|
||||
#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
|
||||
#endif
|
||||
#ifndef GL_DEBUG_SEVERITY_LOW
|
||||
#define GL_DEBUG_SEVERITY_LOW 0x9148
|
||||
#endif
|
||||
|
||||
#elif defined(USE_OPENGL)
|
||||
#include <glad/gl.h>
|
||||
#endif
|
||||
|
||||
#ifdef TEST_AUTOMATION
|
||||
@@ -35,6 +64,7 @@ static inline void do_swap_automation() {}
|
||||
class GLGraphicsContext : public GraphicsContext
|
||||
{
|
||||
public:
|
||||
virtual void swap() = 0;
|
||||
int getMajorVersion() const {
|
||||
return majorVersion;
|
||||
}
|
||||
@@ -63,7 +93,14 @@ public:
|
||||
}
|
||||
void setSwapInterval(int interval) override;
|
||||
|
||||
static GLGraphicsContext *Instance() {
|
||||
return static_cast<GLGraphicsContext*>(GraphicsContext::Instance());
|
||||
}
|
||||
static void Create(void *window, void *display = nullptr);
|
||||
|
||||
protected:
|
||||
GLGraphicsContext(void *window, void *display)
|
||||
: GraphicsContext(window, display) {}
|
||||
void postInit();
|
||||
void preTerm();
|
||||
void findGLVersion();
|
||||
@@ -79,25 +116,3 @@ private:
|
||||
std::string driverVersion;
|
||||
bool amd = false;
|
||||
};
|
||||
|
||||
#if defined(LIBRETRO)
|
||||
|
||||
#include "libretro.h"
|
||||
|
||||
#elif defined(TARGET_IPHONE)
|
||||
|
||||
#include "osx.h"
|
||||
|
||||
#elif defined(USE_SDL)
|
||||
|
||||
#include "sdl.h"
|
||||
|
||||
#elif defined(__ANDROID__) || defined(SUPPORT_X11)
|
||||
|
||||
#include "egl.h"
|
||||
|
||||
#else
|
||||
|
||||
#error Unsupported window system
|
||||
|
||||
#endif
|
||||
+13
-36
@@ -18,49 +18,26 @@
|
||||
*/
|
||||
#pragma once
|
||||
#if defined(LIBRETRO) && (defined(HAVE_OPENGL) || defined(HAVE_OPENGLES))
|
||||
#if defined(TARGET_IPHONE) //apple-specific ogles3 headers
|
||||
#include <OpenGLES/ES3/gl.h>
|
||||
#include <OpenGLES/ES3/glext.h>
|
||||
#endif
|
||||
#include "gl_context.h"
|
||||
#include <libretro.h>
|
||||
#include <glsm/glsm.h>
|
||||
#include <glsm/glsmsym.h>
|
||||
|
||||
#ifndef GL_MAJOR_VERSION
|
||||
#define GL_MAJOR_VERSION 0x821B
|
||||
#endif
|
||||
#ifndef GL_MINOR_VERSION
|
||||
#define GL_MINOR_VERSION 0x821C
|
||||
#endif
|
||||
|
||||
#ifndef GL_DEBUG_SEVERITY_NOTIFICATION
|
||||
#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
|
||||
#endif
|
||||
#ifndef GL_DEBUG_SEVERITY_HIGH
|
||||
#define GL_DEBUG_SEVERITY_HIGH 0x9146
|
||||
#endif
|
||||
#ifndef GL_DEBUG_SEVERITY_MEDIUM
|
||||
#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
|
||||
#endif
|
||||
#ifndef GL_DEBUG_SEVERITY_LOW
|
||||
#define GL_DEBUG_SEVERITY_LOW 0x9148
|
||||
#endif
|
||||
|
||||
class LibretroGraphicsContext : public GLGraphicsContext
|
||||
{
|
||||
public:
|
||||
bool init() {
|
||||
postInit();
|
||||
return true;
|
||||
}
|
||||
|
||||
void term() override {
|
||||
~LibretroGraphicsContext() {
|
||||
preTerm();
|
||||
}
|
||||
|
||||
void swap() {}
|
||||
};
|
||||
void swap() override {}
|
||||
|
||||
extern LibretroGraphicsContext theGLContext;
|
||||
static void Create(void *window, void *display) {
|
||||
new LibretroGraphicsContext(window, display);
|
||||
}
|
||||
|
||||
private:
|
||||
LibretroGraphicsContext(void *window, void *display)
|
||||
: GLGraphicsContext(window, display)
|
||||
{
|
||||
postInit();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
+14
-3
@@ -19,12 +19,23 @@
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#if defined(TARGET_IPHONE) && !defined(LIBRETRO)
|
||||
#include "gl_context.h"
|
||||
#include "osx.h"
|
||||
|
||||
OSXGraphicsContext theGLContext;
|
||||
void OSXGraphicsContext::Create(void *window, void *display) {
|
||||
new OSXGraphicsContext();
|
||||
}
|
||||
|
||||
void OSXGraphicsContext::swap()
|
||||
OSXGraphicsContext::OSXGraphicsContext()
|
||||
: GLGraphicsContext(nullptr, nullptr)
|
||||
{
|
||||
postInit();
|
||||
}
|
||||
|
||||
OSXGraphicsContext::~OSXGraphicsContext() {
|
||||
preTerm();
|
||||
}
|
||||
|
||||
void OSXGraphicsContext::swap() {
|
||||
do_swap_automation();
|
||||
}
|
||||
|
||||
|
||||
+6
-7
@@ -21,16 +21,15 @@
|
||||
#pragma once
|
||||
#if defined(TARGET_IPHONE)
|
||||
#include "gl_context.h"
|
||||
#include <OpenGLES/ES3/gl.h>
|
||||
#include <OpenGLES/ES3/glext.h>
|
||||
|
||||
class OSXGraphicsContext : public GLGraphicsContext
|
||||
{
|
||||
public:
|
||||
bool init() { postInit(); return true; }
|
||||
void term() override { preTerm(); }
|
||||
void swap();
|
||||
};
|
||||
~OSXGraphicsContext();
|
||||
void swap() override;
|
||||
static void Create(void *window = nullptr, void *display = nullptr);
|
||||
|
||||
extern OSXGraphicsContext theGLContext;
|
||||
private:
|
||||
OSXGraphicsContext();
|
||||
};
|
||||
#endif
|
||||
+15
-3
@@ -19,7 +19,7 @@
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#if defined(USE_SDL)
|
||||
#include "gl_context.h"
|
||||
#include "sdl.h"
|
||||
#include "ui/gui.h"
|
||||
#include "sdl/sdl.h"
|
||||
#include "cfg/option.h"
|
||||
@@ -27,11 +27,19 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
SDLGLGraphicsContext theGLContext;
|
||||
SDLGLGraphicsContext::SDLGLGraphicsContext(void *window, void *display)
|
||||
: GLGraphicsContext(window, display)
|
||||
{
|
||||
if (!init())
|
||||
throw FlycastException("OpenGL initialization failed");
|
||||
}
|
||||
|
||||
SDLGLGraphicsContext::~SDLGLGraphicsContext() {
|
||||
term();
|
||||
}
|
||||
|
||||
bool SDLGLGraphicsContext::init()
|
||||
{
|
||||
instance = this;
|
||||
#ifdef GLES
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
@@ -167,5 +175,9 @@ void SDLGLGraphicsContext::term()
|
||||
}
|
||||
}
|
||||
|
||||
void SDLGLGraphicsContext::Create(void *window, void *display) {
|
||||
new SDLGLGraphicsContext(window, display);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+6
-5
@@ -26,15 +26,16 @@
|
||||
class SDLGLGraphicsContext : public GLGraphicsContext
|
||||
{
|
||||
public:
|
||||
bool init();
|
||||
void term() override;
|
||||
void swap();
|
||||
~SDLGLGraphicsContext();
|
||||
void swap() override;
|
||||
static void Create(void *window, void *display);
|
||||
|
||||
private:
|
||||
SDLGLGraphicsContext(void *window, void *display);
|
||||
bool init();
|
||||
void term();
|
||||
void changeGLSwapInterval();
|
||||
|
||||
SDL_GLContext glcontext = nullptr;
|
||||
bool swapOnVSync = false;
|
||||
};
|
||||
|
||||
extern SDLGLGraphicsContext theGLContext;
|
||||
+32
-28
@@ -28,54 +28,59 @@
|
||||
#include "rend/dx11/dx11context.h"
|
||||
#ifdef USE_VULKAN
|
||||
#include "rend/vulkan/vulkan_context.h"
|
||||
|
||||
VulkanContext theVulkanContext;
|
||||
#endif
|
||||
|
||||
GraphicsContext *GraphicsContext::instance;
|
||||
|
||||
void initRenderApi(void *window, void *display)
|
||||
{
|
||||
#ifdef USE_VULKAN
|
||||
if (isVulkan(config::RendererType))
|
||||
{
|
||||
theVulkanContext.setWindow(window, display);
|
||||
if (theVulkanContext.init())
|
||||
try {
|
||||
VulkanContext::Create(window, display);
|
||||
return;
|
||||
// Fall back to OpenGL
|
||||
WARN_LOG(RENDERER, "Vulkan init failed. Falling back to OpenGL.");
|
||||
config::RendererType = RenderType::OpenGL;
|
||||
} catch (const std::exception& e) {
|
||||
// Fall back to OpenGL
|
||||
WARN_LOG(RENDERER, "Vulkan init failed. Falling back to OpenGL (%s)", e.what());
|
||||
config::RendererType = RenderType::OpenGL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_DX11
|
||||
bool dx11Failed = false;
|
||||
if (config::RendererType == RenderType::DirectX11 || config::RendererType == RenderType::DirectX11_OIT)
|
||||
{
|
||||
theDX11Context.setWindow(window, display);
|
||||
if (theDX11Context.init())
|
||||
try {
|
||||
DX11Context::Create(window, display);
|
||||
return;
|
||||
dx11Failed = true;
|
||||
WARN_LOG(RENDERER, "DirectX 11 init failed. Falling back to DirectX 9.");
|
||||
config::RendererType = RenderType::DirectX9;
|
||||
} catch (const std::exception& e) {
|
||||
dx11Failed = true;
|
||||
WARN_LOG(RENDERER, "DirectX 11 init failed. Falling back to DirectX 9 (%s)", e.what());
|
||||
config::RendererType = RenderType::DirectX9;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_DX9
|
||||
if (config::RendererType == RenderType::DirectX9)
|
||||
{
|
||||
theDXContext.setWindow(window, display);
|
||||
if (theDXContext.init())
|
||||
try {
|
||||
DXContext::Create(window, display);
|
||||
return;
|
||||
// Fall back to OpenGL
|
||||
WARN_LOG(RENDERER, "DirectX 9 init failed. Falling back to OpenGL.");
|
||||
config::RendererType = RenderType::OpenGL;
|
||||
} catch (const std::exception& e) {
|
||||
// Fall back to OpenGL
|
||||
WARN_LOG(RENDERER, "DirectX 9 init failed. Falling back to OpenGL (%s)", e.what());
|
||||
config::RendererType = RenderType::OpenGL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_OPENGL
|
||||
if (!isOpenGL(config::RendererType))
|
||||
config::RendererType = RenderType::OpenGL;
|
||||
theGLContext.setWindow(window, display);
|
||||
if (theGLContext.init())
|
||||
try {
|
||||
GLGraphicsContext::Create(window, display);
|
||||
return;
|
||||
} catch (const std::exception& e) {
|
||||
WARN_LOG(RENDERER, "OpenGL init failed: %s", e.what());
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_DX11
|
||||
if (!dx11Failed)
|
||||
@@ -83,19 +88,18 @@ void initRenderApi(void *window, void *display)
|
||||
// Try dx11 as a last resort if it hasn't been tried before
|
||||
WARN_LOG(RENDERER, "OpenGL init failed. Trying DirectX 11.");
|
||||
config::RendererType = RenderType::DirectX11;
|
||||
theDX11Context.setWindow(window, display);
|
||||
if (theDX11Context.init())
|
||||
try {
|
||||
DX11Context::Create(window, display);
|
||||
return;
|
||||
} catch (const std::exception& e) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
throw FlycastException(i18n::T("Cannot initialize the graphics API"));
|
||||
}
|
||||
|
||||
void termRenderApi()
|
||||
{
|
||||
if (GraphicsContext::Instance() != nullptr)
|
||||
GraphicsContext::Instance()->term();
|
||||
verify(GraphicsContext::Instance() == nullptr);
|
||||
void termRenderApi() {
|
||||
GraphicsContext::Term();
|
||||
}
|
||||
|
||||
void switchRenderApi()
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
|
||||
#include <glsm/glsm.h>
|
||||
#include "wsi/gl_context.h"
|
||||
#include "wsi/libretro.h"
|
||||
#endif
|
||||
#ifdef HAVE_VULKAN
|
||||
#include "rend/vulkan/vulkan_context.h"
|
||||
@@ -1369,7 +1369,13 @@ static void context_reset()
|
||||
glsm_ctl(GLSM_CTL_STATE_CONTEXT_RESET, NULL);
|
||||
glsm_ctl(GLSM_CTL_STATE_SETUP, NULL);
|
||||
rend_term_renderer();
|
||||
theGLContext.init();
|
||||
GraphicsContext::Term();
|
||||
try {
|
||||
GLGraphicsContext::Create(nullptr, nullptr);
|
||||
} catch (const std::exception& e) {
|
||||
ERROR_LOG(RENDERER, "%s", e.what());
|
||||
return;
|
||||
}
|
||||
rend_init_renderer();
|
||||
#ifdef HAVE_OIT
|
||||
if (!perPixelChecked)
|
||||
@@ -1382,6 +1388,7 @@ static void context_destroy()
|
||||
gl_ctx_resetting = true;
|
||||
rend_term_renderer();
|
||||
glsm_ctl(GLSM_CTL_STATE_CONTEXT_DESTROY, NULL);
|
||||
GraphicsContext::Term();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1946,8 +1953,6 @@ static void remove_extension(char *buf, const char *path, size_t size)
|
||||
}
|
||||
|
||||
#ifdef HAVE_VULKAN
|
||||
static VulkanContext theVulkanContext;
|
||||
|
||||
static void retro_vk_context_reset()
|
||||
{
|
||||
NOTICE_LOG(RENDERER, "retro_vk_context_reset");
|
||||
@@ -1957,8 +1962,12 @@ static void retro_vk_context_reset()
|
||||
ERROR_LOG(RENDERER, "Get Vulkan HW interface failed");
|
||||
return;
|
||||
}
|
||||
if (!theVulkanContext.init((retro_hw_render_interface_vulkan *)vulkan))
|
||||
try {
|
||||
VulkanContext::Create((retro_hw_render_interface_vulkan *)vulkan);
|
||||
} catch (const std::exception& e) {
|
||||
ERROR_LOG(RENDERER, "%s", e.what());
|
||||
return;
|
||||
}
|
||||
rend_term_renderer();
|
||||
rend_init_renderer();
|
||||
if (!perPixelChecked)
|
||||
@@ -1969,7 +1978,7 @@ static void retro_vk_context_destroy()
|
||||
{
|
||||
NOTICE_LOG(RENDERER, "retro_vk_context_destroy");
|
||||
rend_term_renderer();
|
||||
theVulkanContext.term();
|
||||
GraphicsContext::Term();
|
||||
}
|
||||
|
||||
static bool set_vulkan_hw_render()
|
||||
@@ -2091,9 +2100,14 @@ static void dx11_context_reset()
|
||||
return;
|
||||
}
|
||||
rend_term_renderer();
|
||||
theDX11Context.term();
|
||||
GraphicsContext::Term();
|
||||
|
||||
theDX11Context.init(hw_render->device, hw_render->context, hw_render->D3DCompile, hw_render->featureLevel);
|
||||
try {
|
||||
DX11Context::Create(hw_render->device, hw_render->context, hw_render->D3DCompile, hw_render->featureLevel);
|
||||
} catch (const std::exception& e) {
|
||||
ERROR_LOG(RENDERER, "%s", e.what());
|
||||
return;
|
||||
}
|
||||
if (config::RendererType == RenderType::OpenGL_OIT || config::RendererType == RenderType::Vulkan_OIT)
|
||||
config::RendererType = RenderType::DirectX11_OIT;
|
||||
else if (config::RendererType != RenderType::DirectX11_OIT)
|
||||
@@ -2107,7 +2121,7 @@ static void dx11_context_destroy()
|
||||
{
|
||||
NOTICE_LOG(RENDERER, "DX11 context destroyed");
|
||||
rend_term_renderer();
|
||||
theDX11Context.term();
|
||||
GraphicsContext::Term();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in new issue
Block a user