Skip to content

Commit

Permalink
Misc: Correctness fixes for OpenGL
Browse files Browse the repository at this point in the history
GLES2 fallback should be functional again.
  • Loading branch information
stenzek committed Jan 30, 2023
1 parent a30bc94 commit 14cf865
Show file tree
Hide file tree
Showing 18 changed files with 145 additions and 125 deletions.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -53,7 +53,7 @@ Other features include:

## System Requirements
- A CPU faster than a potato. But it needs to be x86_64, AArch32/armv7, or AArch64/ARMv8, otherwise you won't get a recompiler and it'll be slow.
- For the hardware renderers, a GPU capable of OpenGL 3.1/OpenGL ES 3.0/Direct3D 11 Feature Level 10.0 (or Vulkan 1.0) and above. So, basically anything made in the last 10 years or so.
- For the hardware renderers, a GPU capable of OpenGL 3.1/OpenGL ES 3.1/Direct3D 11 Feature Level 10.0 (or Vulkan 1.0) and above. So, basically anything made in the last 10 years or so.
- SDL, XInput or DInput compatible game controller (e.g. XB360/XBOne). DualShock 3 users on Windows will need to install the official DualShock 3 drivers included as part of PlayStation Now.

## Downloading and running
Expand Down
15 changes: 9 additions & 6 deletions src/common/gl/texture.cpp
Expand Up @@ -118,6 +118,9 @@ bool GL::Texture::Create(u32 width, u32 height, u32 layers, u32 levels, u32 samp
else
glTexImage2DMultisample(target, samples, gl_internal_format, width, height, GL_FALSE);
}

glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels);
}
else
{
Expand Down Expand Up @@ -148,8 +151,12 @@ bool GL::Texture::Create(u32 width, u32 height, u32 layers, u32 levels, u32 samp
glTexImage2D(target, i, gl_internal_format, width, height, 0, gl_format, gl_type, data);
}

glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels);
// This doesn't exist on GLES2.
if (!GLAD_GL_ES_VERSION_2_0 || GLAD_GL_ES_VERSION_3_0)
{
glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels);
}
}

glTexParameteri(target, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST);
Expand All @@ -161,10 +168,6 @@ bool GL::Texture::Create(u32 width, u32 height, u32 layers, u32 levels, u32 samp
glTexParameteri(target, GL_TEXTURE_WRAP_R, wrap ? GL_REPEAT : GL_CLAMP_TO_EDGE);
}

// This doesn't exist on GLES2.
if (!GLAD_GL_ES_VERSION_2_0 || GLAD_GL_ES_VERSION_3_0)
glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, 1);

GLenum error = glGetError();
if (error != GL_NO_ERROR)
{
Expand Down
40 changes: 19 additions & 21 deletions src/core/gpu_hw_d3d11.cpp
Expand Up @@ -14,18 +14,12 @@
#include "util/state_wrapper.h"
Log_SetChannel(GPU_HW_D3D11);

GPU_HW_D3D11::GPU_HW_D3D11() = default;
GPU_HW_D3D11::GPU_HW_D3D11(ID3D11Device* device, ID3D11DeviceContext* context) : m_device(device), m_context(context) {}

GPU_HW_D3D11::~GPU_HW_D3D11()
{
if (g_host_display)
{
g_host_display->ClearDisplayTexture();
ResetGraphicsAPIState();
}

if (m_context)
m_context->ClearState();
g_host_display->ClearDisplayTexture();
GPU_HW_D3D11::ResetGraphicsAPIState();

DestroyShaders();
DestroyStateObjects();
Expand All @@ -38,17 +32,6 @@ GPURenderer GPU_HW_D3D11::GetRendererType() const

bool GPU_HW_D3D11::Initialize()
{
if (!Host::AcquireHostDisplay(RenderAPI::D3D11))
{
Log_ErrorPrintf("Host render API is incompatible");
return false;
}

m_device = static_cast<ID3D11Device*>(g_host_display->GetDevice());
m_context = static_cast<ID3D11DeviceContext*>(g_host_display->GetContext());
if (!m_device || !m_context)
return false;

SetCapabilities();

if (!GPU_HW::Initialize())
Expand Down Expand Up @@ -1213,5 +1196,20 @@ void GPU_HW_D3D11::DownsampleFramebufferBoxFilter(D3D11::Texture& source, u32 le

std::unique_ptr<GPU> GPU::CreateHardwareD3D11Renderer()
{
return std::make_unique<GPU_HW_D3D11>();
if (!Host::AcquireHostDisplay(RenderAPI::D3D11))
{
Log_ErrorPrintf("Host render API is incompatible");
return nullptr;
}

ID3D11Device* device = static_cast<ID3D11Device*>(g_host_display->GetDevice());
ID3D11DeviceContext* context = static_cast<ID3D11DeviceContext*>(g_host_display->GetContext());
if (!device || !context)
return nullptr;

std::unique_ptr<GPU_HW_D3D11> gpu(std::make_unique<GPU_HW_D3D11>(device, context));
if (!gpu->Initialize())
return nullptr;

return gpu;
}
4 changes: 2 additions & 2 deletions src/core/gpu_hw_d3d11.h
Expand Up @@ -13,13 +13,13 @@
#include <tuple>
#include <wrl/client.h>

class GPU_HW_D3D11 : public GPU_HW
class GPU_HW_D3D11 final : public GPU_HW
{
public:
template<typename T>
using ComPtr = Microsoft::WRL::ComPtr<T>;

GPU_HW_D3D11();
GPU_HW_D3D11(ID3D11Device* device, ID3D11DeviceContext* context);
~GPU_HW_D3D11() override;

GPURenderer GetRendererType() const override;
Expand Down
25 changes: 13 additions & 12 deletions src/core/gpu_hw_d3d12.cpp
Expand Up @@ -21,11 +21,8 @@ GPU_HW_D3D12::GPU_HW_D3D12() = default;

GPU_HW_D3D12::~GPU_HW_D3D12()
{
if (g_host_display)
{
g_host_display->ClearDisplayTexture();
ResetGraphicsAPIState();
}
g_host_display->ClearDisplayTexture();
GPU_HW_D3D12::ResetGraphicsAPIState();

DestroyResources();
}
Expand All @@ -37,12 +34,6 @@ GPURenderer GPU_HW_D3D12::GetRendererType() const

bool GPU_HW_D3D12::Initialize()
{
if (!Host::AcquireHostDisplay(RenderAPI::D3D12))
{
Log_ErrorPrintf("Host render API is incompatible");
return false;
}

SetCapabilities();

if (!GPU_HW::Initialize())
Expand Down Expand Up @@ -1193,5 +1184,15 @@ void GPU_HW_D3D12::ClearDepthBuffer()

std::unique_ptr<GPU> GPU::CreateHardwareD3D12Renderer()
{
return std::make_unique<GPU_HW_D3D12>();
if (!Host::AcquireHostDisplay(RenderAPI::D3D12))
{
Log_ErrorPrintf("Host render API is incompatible");
return nullptr;
}

std::unique_ptr<GPU_HW_D3D12> gpu(std::make_unique<GPU_HW_D3D12>());
if (!gpu->Initialize())
return nullptr;

return gpu;
}
2 changes: 1 addition & 1 deletion src/core/gpu_hw_d3d12.h
Expand Up @@ -12,7 +12,7 @@
#include <memory>
#include <tuple>

class GPU_HW_D3D12 : public GPU_HW
class GPU_HW_D3D12 final : public GPU_HW
{
public:
template<typename T>
Expand Down
55 changes: 28 additions & 27 deletions src/core/gpu_hw_opengl.cpp
Expand Up @@ -28,11 +28,8 @@ GPU_HW_OpenGL::~GPU_HW_OpenGL()
if (m_texture_buffer_r16ui_texture != 0)
glDeleteTextures(1, &m_texture_buffer_r16ui_texture);

if (g_host_display)
{
g_host_display->ClearDisplayTexture();
ResetGraphicsAPIState();
}
g_host_display->ClearDisplayTexture();
GPU_HW_OpenGL::ResetGraphicsAPIState();

// One of our programs might've been bound.
GL::Program::ResetLastProgram();
Expand All @@ -46,27 +43,6 @@ GPURenderer GPU_HW_OpenGL::GetRendererType() const

bool GPU_HW_OpenGL::Initialize()
{
// Don't re-request GL when we already have GLES here...
const RenderAPI current_api = g_host_display ? g_host_display->GetRenderAPI() : RenderAPI::None;
if (current_api != RenderAPI::OpenGL && current_api != RenderAPI::OpenGLES &&
!Host::AcquireHostDisplay(RenderAPI::OpenGL))
{
Log_ErrorPrintf("Host render API type is incompatible");
return false;
}

const bool opengl_is_available = ((g_host_display->GetRenderAPI() == RenderAPI::OpenGL &&
(GLAD_GL_VERSION_3_0 || GLAD_GL_ARB_uniform_buffer_object)) ||
(g_host_display->GetRenderAPI() == RenderAPI::OpenGLES && GLAD_GL_ES_VERSION_3_0));
if (!opengl_is_available)
{
Host::AddOSDMessage(Host::TranslateStdString("OSDMessage",
"OpenGL renderer unavailable, your driver or hardware is not "
"recent enough. OpenGL 3.1 or OpenGL ES 3.0 is required."),
20.0f);
return false;
}

SetCapabilities();

if (!GPU_HW::Initialize())
Expand Down Expand Up @@ -1333,5 +1309,30 @@ void GPU_HW_OpenGL::DownsampleFramebufferBoxFilter(GL::Texture& source, u32 left

std::unique_ptr<GPU> GPU::CreateHardwareOpenGLRenderer()
{
return std::make_unique<GPU_HW_OpenGL>();
// Don't re-request GL when we already have GLES here...
const RenderAPI current_api = g_host_display ? g_host_display->GetRenderAPI() : RenderAPI::None;
if (current_api != RenderAPI::OpenGL && current_api != RenderAPI::OpenGLES &&
!Host::AcquireHostDisplay(RenderAPI::OpenGL))
{
Log_ErrorPrintf("Host render API type is incompatible");
return nullptr;
}

const bool opengl_is_available = ((g_host_display->GetRenderAPI() == RenderAPI::OpenGL &&
(GLAD_GL_VERSION_3_0 || GLAD_GL_ARB_uniform_buffer_object)) ||
(g_host_display->GetRenderAPI() == RenderAPI::OpenGLES && GLAD_GL_ES_VERSION_3_1));
if (!opengl_is_available)
{
Host::AddOSDMessage(Host::TranslateStdString("OSDMessage",
"OpenGL renderer unavailable, your driver or hardware is not "
"recent enough. OpenGL 3.1 or OpenGL ES 3.1 is required."),
20.0f);
return nullptr;
}

std::unique_ptr<GPU_HW_OpenGL> gpu(std::make_unique<GPU_HW_OpenGL>());
if (!gpu->Initialize())
return nullptr;

return gpu;
}
2 changes: 1 addition & 1 deletion src/core/gpu_hw_opengl.h
Expand Up @@ -13,7 +13,7 @@
#include <memory>
#include <tuple>

class GPU_HW_OpenGL : public GPU_HW
class GPU_HW_OpenGL final : public GPU_HW
{
public:
GPU_HW_OpenGL();
Expand Down
28 changes: 14 additions & 14 deletions src/core/gpu_hw_vulkan.cpp
Expand Up @@ -20,12 +20,8 @@ GPU_HW_Vulkan::GPU_HW_Vulkan() = default;

GPU_HW_Vulkan::~GPU_HW_Vulkan()
{
if (g_host_display)
{
g_host_display->ClearDisplayTexture();
ResetGraphicsAPIState();
}

g_host_display->ClearDisplayTexture();
GPU_HW_Vulkan::ResetGraphicsAPIState();
DestroyResources();
}

Expand All @@ -36,13 +32,6 @@ GPURenderer GPU_HW_Vulkan::GetRendererType() const

bool GPU_HW_Vulkan::Initialize()
{
if (!Host::AcquireHostDisplay(RenderAPI::Vulkan))
{
Log_ErrorPrintf("Host render API is incompatible");
return false;
}

Assert(g_vulkan_shader_cache);
SetCapabilities();

if (!GPU_HW::Initialize())
Expand Down Expand Up @@ -1993,5 +1982,16 @@ void GPU_HW_Vulkan::DownsampleFramebufferAdaptive(Vulkan::Texture& source, u32 l

std::unique_ptr<GPU> GPU::CreateHardwareVulkanRenderer()
{
return std::make_unique<GPU_HW_Vulkan>();
if (!Host::AcquireHostDisplay(RenderAPI::Vulkan))
{
Log_ErrorPrintf("Host render API is incompatible");
return nullptr;
}

Assert(g_vulkan_shader_cache);
std::unique_ptr<GPU_HW_Vulkan> gpu(std::make_unique<GPU_HW_Vulkan>());
if (!gpu->Initialize())
return nullptr;

return gpu;
}
2 changes: 1 addition & 1 deletion src/core/gpu_hw_vulkan.h
Expand Up @@ -11,7 +11,7 @@
#include <memory>
#include <tuple>

class GPU_HW_Vulkan : public GPU_HW
class GPU_HW_Vulkan final : public GPU_HW
{
public:
GPU_HW_Vulkan();
Expand Down

0 comments on commit 14cf865

Please sign in to comment.