mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-05-05 05:25:43 -04:00
GL: Improve error handling with texture creation
This commit is contained in:
parent
05e6d4c401
commit
6f78fea159
@ -5,32 +5,96 @@ Log_SetChannel(GL);
|
|||||||
|
|
||||||
namespace GL {
|
namespace GL {
|
||||||
|
|
||||||
Texture::Texture(u32 width, u32 height, GLenum format, GLenum type, const void* data /* = nullptr */,
|
Texture::Texture() = default;
|
||||||
bool linear_filter /* = false */, bool create_framebuffer /* = false */)
|
|
||||||
: m_width(width), m_height(height)
|
Texture::Texture(Texture&& moved)
|
||||||
|
: m_id(moved.m_id), m_width(moved.m_width), m_height(moved.m_height), m_fbo_id(moved.m_fbo_id)
|
||||||
{
|
{
|
||||||
glGenTextures(1, &m_id);
|
moved.m_id = 0;
|
||||||
glBindTexture(GL_TEXTURE_2D, m_id);
|
moved.m_width = 0;
|
||||||
|
moved.m_height = 0;
|
||||||
|
moved.m_fbo_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture::~Texture()
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Texture::Create(u32 width, u32 height, GLenum format, GLenum type, const void* data, bool linear_filter)
|
||||||
|
{
|
||||||
|
glGetError();
|
||||||
|
|
||||||
|
GLuint id;
|
||||||
|
glGenTextures(1, &id);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type, data);
|
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type, data);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear_filter ? GL_LINEAR : GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||||
|
|
||||||
if (create_framebuffer)
|
if (glGetError() != GL_NO_ERROR)
|
||||||
{
|
{
|
||||||
glGenFramebuffers(1, &m_fbo_id);
|
glDeleteTextures(1, &id);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_id);
|
return false;
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_id, 0);
|
|
||||||
Assert(glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsValid())
|
||||||
|
Destroy();
|
||||||
|
|
||||||
|
m_id = id;
|
||||||
|
m_width = width;
|
||||||
|
m_height = height;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::~Texture()
|
void Texture::SetLinearFilter(bool enabled)
|
||||||
{
|
{
|
||||||
|
Bind();
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, enabled ? GL_LINEAR : GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, enabled ? GL_LINEAR : GL_NEAREST);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Texture::CreateFramebuffer()
|
||||||
|
{
|
||||||
|
if (!IsValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
glGetError();
|
||||||
|
|
||||||
|
GLuint fbo_id;
|
||||||
|
glGenFramebuffers(1, &fbo_id);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
|
||||||
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_id, 0);
|
||||||
|
if (glGetError() != GL_NO_ERROR || glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
{
|
||||||
|
glDeleteFramebuffers(1, &fbo_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_fbo_id != 0)
|
if (m_fbo_id != 0)
|
||||||
glDeleteFramebuffers(1, &m_fbo_id);
|
glDeleteFramebuffers(1, &m_fbo_id);
|
||||||
|
|
||||||
|
m_fbo_id = fbo_id;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::Destroy()
|
||||||
|
{
|
||||||
|
if (m_fbo_id != 0)
|
||||||
|
{
|
||||||
|
glDeleteFramebuffers(1, &m_fbo_id);
|
||||||
|
m_fbo_id = 0;
|
||||||
|
}
|
||||||
|
if (m_id != 0)
|
||||||
|
{
|
||||||
glDeleteTextures(1, &m_id);
|
glDeleteTextures(1, &m_id);
|
||||||
|
m_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_width = 0;
|
||||||
|
m_height = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::Bind()
|
void Texture::Bind()
|
||||||
@ -49,4 +113,20 @@ void Texture::Unbind()
|
|||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Texture& Texture::operator=(Texture&& moved)
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
|
||||||
|
m_id = moved.m_id;
|
||||||
|
m_width = moved.m_width;
|
||||||
|
m_height = moved.m_height;
|
||||||
|
m_fbo_id = moved.m_fbo_id;
|
||||||
|
|
||||||
|
moved.m_id = 0;
|
||||||
|
moved.m_width = 0;
|
||||||
|
moved.m_height = 0;
|
||||||
|
moved.m_fbo_id = 0;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace GL
|
} // namespace GL
|
@ -1,15 +1,24 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <glad.h>
|
|
||||||
#include "../types.h"
|
#include "../types.h"
|
||||||
|
#include <glad.h>
|
||||||
|
|
||||||
namespace GL {
|
namespace GL {
|
||||||
class Texture
|
class Texture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Texture(u32 width, u32 height, GLenum format, GLenum type, const void* data = nullptr, bool linear_filter = false,
|
Texture();
|
||||||
bool create_framebuffer = false);
|
Texture(Texture&& moved);
|
||||||
~Texture();
|
~Texture();
|
||||||
|
|
||||||
|
bool Create(u32 width, u32 height, GLenum format, GLenum type, const void* data = nullptr,
|
||||||
|
bool linear_filter = false);
|
||||||
|
bool CreateFramebuffer();
|
||||||
|
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
|
void SetLinearFilter(bool enabled);
|
||||||
|
|
||||||
|
bool IsValid() const { return m_id != 0; }
|
||||||
GLuint GetGLId() const { return m_id; }
|
GLuint GetGLId() const { return m_id; }
|
||||||
u32 GetWidth() const { return m_width; }
|
u32 GetWidth() const { return m_width; }
|
||||||
u32 GetHeight() const { return m_height; }
|
u32 GetHeight() const { return m_height; }
|
||||||
@ -21,10 +30,14 @@ public:
|
|||||||
|
|
||||||
static void Unbind();
|
static void Unbind();
|
||||||
|
|
||||||
|
Texture& operator=(const Texture& copy) = delete;
|
||||||
|
Texture& operator=(Texture&& moved);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLuint m_id;
|
|
||||||
u32 m_width;
|
GLuint m_id = 0;
|
||||||
u32 m_height;
|
u32 m_width = 0;
|
||||||
|
u32 m_height = 0;
|
||||||
|
|
||||||
GLuint m_fbo_id = 0;
|
GLuint m_fbo_id = 0;
|
||||||
};
|
};
|
||||||
|
@ -41,16 +41,39 @@ bool GPU_HW_OpenGL::Initialize(HostDisplay* host_display, System* system, DMA* d
|
|||||||
if (!GPU_HW::Initialize(host_display, system, dma, interrupt_controller, timers))
|
if (!GPU_HW::Initialize(host_display, system, dma, interrupt_controller, timers))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CreateFramebuffer();
|
if (!CreateFramebuffer())
|
||||||
CreateVertexBuffer();
|
{
|
||||||
CreateUniformBuffer();
|
Log_ErrorPrintf("Failed to create framebuffer");
|
||||||
CreateTextureBuffer();
|
|
||||||
if (!CompilePrograms())
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture->GetGLId())), 0, 0,
|
if (!CreateVertexBuffer())
|
||||||
m_display_texture->GetWidth(), m_display_texture->GetHeight(),
|
{
|
||||||
m_display_texture->GetWidth(), m_display_texture->GetHeight(), 1.0f);
|
Log_ErrorPrintf("Failed to create vertex buffer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CreateUniformBuffer())
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("Failed to create uniform buffer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CreateTextureBuffer())
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("Failed to create texture buffer");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CompilePrograms())
|
||||||
|
{
|
||||||
|
Log_ErrorPrintf("Failed to compile programs");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture.GetGLId())), 0, 0,
|
||||||
|
m_display_texture.GetWidth(), m_display_texture.GetHeight(),
|
||||||
|
m_display_texture.GetWidth(), m_display_texture.GetHeight(), 1.0f);
|
||||||
RestoreGraphicsAPIState();
|
RestoreGraphicsAPIState();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -76,8 +99,8 @@ void GPU_HW_OpenGL::ResetGraphicsAPIState()
|
|||||||
|
|
||||||
void GPU_HW_OpenGL::RestoreGraphicsAPIState()
|
void GPU_HW_OpenGL::RestoreGraphicsAPIState()
|
||||||
{
|
{
|
||||||
m_vram_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_vram_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
glViewport(0, 0, m_vram_texture->GetWidth(), m_vram_texture->GetHeight());
|
glViewport(0, 0, m_vram_texture.GetWidth(), m_vram_texture.GetHeight());
|
||||||
|
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
@ -162,47 +185,50 @@ void GPU_HW_OpenGL::SetCapabilities(HostDisplay* host_display)
|
|||||||
Log_WarningPrintf("Dual-source blending is not supported, this may break some mask effects.");
|
Log_WarningPrintf("Dual-source blending is not supported, this may break some mask effects.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL::CreateFramebuffer()
|
bool GPU_HW_OpenGL::CreateFramebuffer()
|
||||||
{
|
{
|
||||||
// save old vram texture/fbo, in case we're changing scale
|
// save old vram texture/fbo, in case we're changing scale
|
||||||
auto old_vram_texture = std::move(m_vram_texture);
|
GL::Texture old_vram_texture = std::move(m_vram_texture);
|
||||||
DestroyFramebuffer();
|
|
||||||
|
|
||||||
// scale vram size to internal resolution
|
// scale vram size to internal resolution
|
||||||
const u32 texture_width = VRAM_WIDTH * m_resolution_scale;
|
const u32 texture_width = VRAM_WIDTH * m_resolution_scale;
|
||||||
const u32 texture_height = VRAM_HEIGHT * m_resolution_scale;
|
const u32 texture_height = VRAM_HEIGHT * m_resolution_scale;
|
||||||
|
|
||||||
m_vram_texture =
|
if (!m_vram_texture.Create(texture_width, texture_height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false) ||
|
||||||
std::make_unique<GL::Texture>(texture_width, texture_height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false, true);
|
!m_vram_texture.CreateFramebuffer())
|
||||||
|
|
||||||
// do we need to restore the framebuffer after a size change?
|
|
||||||
if (old_vram_texture)
|
|
||||||
{
|
{
|
||||||
const bool linear_filter = old_vram_texture->GetWidth() > m_vram_texture->GetWidth();
|
return false;
|
||||||
Log_DevPrintf("Scaling %ux%u VRAM texture to %ux%u using %s filter", old_vram_texture->GetWidth(),
|
|
||||||
old_vram_texture->GetHeight(), m_vram_texture->GetWidth(), m_vram_texture->GetHeight(),
|
|
||||||
linear_filter ? "linear" : "nearest");
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
|
||||||
old_vram_texture->BindFramebuffer(GL_READ_FRAMEBUFFER);
|
|
||||||
glBlitFramebuffer(0, 0, old_vram_texture->GetWidth(), old_vram_texture->GetHeight(), 0, 0,
|
|
||||||
m_vram_texture->GetWidth(), m_vram_texture->GetHeight(), GL_COLOR_BUFFER_BIT,
|
|
||||||
linear_filter ? GL_LINEAR : GL_NEAREST);
|
|
||||||
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
old_vram_texture.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vram_read_texture =
|
// do we need to restore the framebuffer after a size change?
|
||||||
std::make_unique<GL::Texture>(texture_width, texture_height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false, true);
|
if (old_vram_texture.IsValid())
|
||||||
|
{
|
||||||
|
const bool linear_filter = old_vram_texture.GetWidth() > m_vram_texture.GetWidth();
|
||||||
|
Log_DevPrintf("Scaling %ux%u VRAM texture to %ux%u using %s filter", old_vram_texture.GetWidth(),
|
||||||
|
old_vram_texture.GetHeight(), m_vram_texture.GetWidth(), m_vram_texture.GetHeight(),
|
||||||
|
linear_filter ? "linear" : "nearest");
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
old_vram_texture.BindFramebuffer(GL_READ_FRAMEBUFFER);
|
||||||
|
glBlitFramebuffer(0, 0, old_vram_texture.GetWidth(), old_vram_texture.GetHeight(), 0, 0, m_vram_texture.GetWidth(),
|
||||||
|
m_vram_texture.GetHeight(), GL_COLOR_BUFFER_BIT, linear_filter ? GL_LINEAR : GL_NEAREST);
|
||||||
|
|
||||||
m_vram_encoding_texture =
|
glEnable(GL_SCISSOR_TEST);
|
||||||
std::make_unique<GL::Texture>(VRAM_WIDTH, VRAM_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false, true);
|
old_vram_texture.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
m_display_texture =
|
if (!m_vram_read_texture.Create(texture_width, texture_height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false) ||
|
||||||
std::make_unique<GL::Texture>(texture_width, texture_height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false, true);
|
!m_vram_read_texture.CreateFramebuffer() ||
|
||||||
|
!m_vram_encoding_texture.Create(VRAM_WIDTH, VRAM_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false) ||
|
||||||
|
!m_vram_encoding_texture.CreateFramebuffer() ||
|
||||||
|
!m_display_texture.Create(texture_width, texture_height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false) ||
|
||||||
|
!m_display_texture.CreateFramebuffer())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_vram_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_vram_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
SetFullVRAMDirtyRectangle();
|
SetFullVRAMDirtyRectangle();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL::ClearFramebuffer()
|
void GPU_HW_OpenGL::ClearFramebuffer()
|
||||||
@ -214,19 +240,11 @@ void GPU_HW_OpenGL::ClearFramebuffer()
|
|||||||
SetFullVRAMDirtyRectangle();
|
SetFullVRAMDirtyRectangle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL::DestroyFramebuffer()
|
bool GPU_HW_OpenGL::CreateVertexBuffer()
|
||||||
{
|
|
||||||
m_vram_read_texture.reset();
|
|
||||||
m_vram_texture.reset();
|
|
||||||
m_vram_encoding_texture.reset();
|
|
||||||
m_display_texture.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GPU_HW_OpenGL::CreateVertexBuffer()
|
|
||||||
{
|
{
|
||||||
m_vertex_stream_buffer = GL::StreamBuffer::Create(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE);
|
m_vertex_stream_buffer = GL::StreamBuffer::Create(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE);
|
||||||
if (!m_vertex_stream_buffer)
|
if (!m_vertex_stream_buffer)
|
||||||
Panic("Failed to create vertex streaming buffer");
|
return false;
|
||||||
|
|
||||||
m_vertex_stream_buffer->Bind();
|
m_vertex_stream_buffer->Bind();
|
||||||
|
|
||||||
@ -244,21 +262,24 @@ void GPU_HW_OpenGL::CreateVertexBuffer()
|
|||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
glGenVertexArrays(1, &m_attributeless_vao_id);
|
glGenVertexArrays(1, &m_attributeless_vao_id);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL::CreateUniformBuffer()
|
bool GPU_HW_OpenGL::CreateUniformBuffer()
|
||||||
{
|
{
|
||||||
m_uniform_stream_buffer = GL::StreamBuffer::Create(GL_UNIFORM_BUFFER, UNIFORM_BUFFER_SIZE);
|
m_uniform_stream_buffer = GL::StreamBuffer::Create(GL_UNIFORM_BUFFER, UNIFORM_BUFFER_SIZE);
|
||||||
if (!m_uniform_stream_buffer)
|
if (!m_uniform_stream_buffer)
|
||||||
Panic("Failed to create uniform buffer");
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL::CreateTextureBuffer()
|
bool GPU_HW_OpenGL::CreateTextureBuffer()
|
||||||
{
|
{
|
||||||
// We use the pixel unpack buffer here because we share it with CPU-decoded VRAM writes.
|
// We use the pixel unpack buffer here because we share it with CPU-decoded VRAM writes.
|
||||||
m_texture_stream_buffer = GL::StreamBuffer::Create(GL_PIXEL_UNPACK_BUFFER, VRAM_UPDATE_TEXTURE_BUFFER_SIZE);
|
m_texture_stream_buffer = GL::StreamBuffer::Create(GL_PIXEL_UNPACK_BUFFER, VRAM_UPDATE_TEXTURE_BUFFER_SIZE);
|
||||||
if (!m_texture_stream_buffer)
|
if (!m_texture_stream_buffer)
|
||||||
Panic("Failed to create texture stream buffer");
|
return false;
|
||||||
|
|
||||||
if (m_max_texture_buffer_size > 0)
|
if (m_max_texture_buffer_size > 0)
|
||||||
{
|
{
|
||||||
@ -268,6 +289,7 @@ void GPU_HW_OpenGL::CreateTextureBuffer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_texture_stream_buffer->Unbind();
|
m_texture_stream_buffer->Unbind();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GPU_HW_OpenGL::CompilePrograms()
|
bool GPU_HW_OpenGL::CompilePrograms()
|
||||||
@ -396,7 +418,7 @@ void GPU_HW_OpenGL::SetDrawState(BatchRenderMode render_mode)
|
|||||||
prog.Bind();
|
prog.Bind();
|
||||||
|
|
||||||
if (m_batch.texture_mode != TextureMode::Disabled)
|
if (m_batch.texture_mode != TextureMode::Disabled)
|
||||||
m_vram_read_texture->Bind();
|
m_vram_read_texture.Bind();
|
||||||
|
|
||||||
if (m_batch.transparency_mode == TransparencyMode::Disabled || render_mode == BatchRenderMode::OnlyOpaque)
|
if (m_batch.transparency_mode == TransparencyMode::Disabled || render_mode == BatchRenderMode::OnlyOpaque)
|
||||||
{
|
{
|
||||||
@ -433,7 +455,7 @@ void GPU_HW_OpenGL::SetScissorFromDrawingArea()
|
|||||||
const int width = right - left;
|
const int width = right - left;
|
||||||
const int height = bottom - top;
|
const int height = bottom - top;
|
||||||
const int x = left;
|
const int x = left;
|
||||||
const int y = m_vram_texture->GetHeight() - bottom;
|
const int y = m_vram_texture.GetHeight() - bottom;
|
||||||
|
|
||||||
Log_DebugPrintf("SetScissor: (%d-%d, %d-%d)", x, x + width, y, y + height);
|
Log_DebugPrintf("SetScissor: (%d-%d, %d-%d)", x, x + width, y, y + height);
|
||||||
glScissor(x, y, width, height);
|
glScissor(x, y, width, height);
|
||||||
@ -456,10 +478,10 @@ void GPU_HW_OpenGL::UpdateDisplay()
|
|||||||
|
|
||||||
if (m_system->GetSettings().debugging.show_vram)
|
if (m_system->GetSettings().debugging.show_vram)
|
||||||
{
|
{
|
||||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture->GetGLId())), 0,
|
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture.GetGLId())), 0,
|
||||||
m_vram_texture->GetHeight(), m_vram_texture->GetWidth(),
|
m_vram_texture.GetHeight(), m_vram_texture.GetWidth(),
|
||||||
-static_cast<s32>(m_vram_texture->GetHeight()), m_vram_texture->GetWidth(),
|
-static_cast<s32>(m_vram_texture.GetHeight()), m_vram_texture.GetWidth(),
|
||||||
m_vram_texture->GetHeight(), 1.0f);
|
m_vram_texture.GetHeight(), 1.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -479,17 +501,17 @@ void GPU_HW_OpenGL::UpdateDisplay()
|
|||||||
}
|
}
|
||||||
else if (!m_GPUSTAT.display_area_color_depth_24 && !interlaced)
|
else if (!m_GPUSTAT.display_area_color_depth_24 && !interlaced)
|
||||||
{
|
{
|
||||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture->GetGLId())),
|
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture.GetGLId())),
|
||||||
scaled_vram_offset_x, m_vram_texture->GetHeight() - scaled_vram_offset_y,
|
scaled_vram_offset_x, m_vram_texture.GetHeight() - scaled_vram_offset_y,
|
||||||
scaled_display_width, -static_cast<s32>(scaled_display_height),
|
scaled_display_width, -static_cast<s32>(scaled_display_height),
|
||||||
m_vram_texture->GetWidth(), m_vram_texture->GetHeight(),
|
m_vram_texture.GetWidth(), m_vram_texture.GetHeight(),
|
||||||
m_crtc_state.display_aspect_ratio);
|
m_crtc_state.display_aspect_ratio);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const u32 flipped_vram_offset_y = VRAM_HEIGHT - vram_offset_y - display_height;
|
const u32 flipped_vram_offset_y = VRAM_HEIGHT - vram_offset_y - display_height;
|
||||||
const u32 scaled_flipped_vram_offset_y =
|
const u32 scaled_flipped_vram_offset_y =
|
||||||
m_vram_texture->GetHeight() - scaled_vram_offset_y - scaled_display_height;
|
m_vram_texture.GetHeight() - scaled_vram_offset_y - scaled_display_height;
|
||||||
const u32 field_offset = BoolToUInt8(interlaced && m_GPUSTAT.interlaced_field);
|
const u32 field_offset = BoolToUInt8(interlaced && m_GPUSTAT.interlaced_field);
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
@ -504,15 +526,15 @@ void GPU_HW_OpenGL::UpdateDisplay()
|
|||||||
{
|
{
|
||||||
const u32 copy_width = std::min<u32>((display_width * 3) / 2, VRAM_WIDTH - vram_offset_x);
|
const u32 copy_width = std::min<u32>((display_width * 3) / 2, VRAM_WIDTH - vram_offset_x);
|
||||||
const u32 scaled_copy_width = copy_width * m_resolution_scale;
|
const u32 scaled_copy_width = copy_width * m_resolution_scale;
|
||||||
m_vram_encoding_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_vram_encoding_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
m_vram_texture->BindFramebuffer(GL_READ_FRAMEBUFFER);
|
m_vram_texture.BindFramebuffer(GL_READ_FRAMEBUFFER);
|
||||||
glBlitFramebuffer(scaled_vram_offset_x, scaled_flipped_vram_offset_y, scaled_vram_offset_x + scaled_copy_width,
|
glBlitFramebuffer(scaled_vram_offset_x, scaled_flipped_vram_offset_y, scaled_vram_offset_x + scaled_copy_width,
|
||||||
scaled_flipped_vram_offset_y + scaled_display_height, vram_offset_x, flipped_vram_offset_y,
|
scaled_flipped_vram_offset_y + scaled_display_height, vram_offset_x, flipped_vram_offset_y,
|
||||||
vram_offset_x + copy_width, flipped_vram_offset_y + display_height, GL_COLOR_BUFFER_BIT,
|
vram_offset_x + copy_width, flipped_vram_offset_y + display_height, GL_COLOR_BUFFER_BIT,
|
||||||
GL_NEAREST);
|
GL_NEAREST);
|
||||||
|
|
||||||
m_display_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_display_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
m_vram_encoding_texture->Bind();
|
m_vram_encoding_texture.Bind();
|
||||||
|
|
||||||
glViewport(0, field_offset, display_width, display_height);
|
glViewport(0, field_offset, display_width, display_height);
|
||||||
|
|
||||||
@ -522,15 +544,15 @@ void GPU_HW_OpenGL::UpdateDisplay()
|
|||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
|
||||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_texture->GetGLId())),
|
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_texture.GetGLId())),
|
||||||
0, display_height, display_width, -static_cast<s32>(display_height),
|
0, display_height, display_width, -static_cast<s32>(display_height),
|
||||||
m_display_texture->GetWidth(), m_display_texture->GetHeight(),
|
m_display_texture.GetWidth(), m_display_texture.GetHeight(),
|
||||||
m_crtc_state.display_aspect_ratio);
|
m_crtc_state.display_aspect_ratio);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_display_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_display_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
m_vram_texture->Bind();
|
m_vram_texture.Bind();
|
||||||
|
|
||||||
glViewport(0, field_offset, scaled_display_width, scaled_display_height);
|
glViewport(0, field_offset, scaled_display_width, scaled_display_height);
|
||||||
|
|
||||||
@ -540,15 +562,15 @@ void GPU_HW_OpenGL::UpdateDisplay()
|
|||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
|
||||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_texture->GetGLId())),
|
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_texture.GetGLId())),
|
||||||
0, scaled_display_height, scaled_display_width,
|
0, scaled_display_height, scaled_display_width,
|
||||||
-static_cast<s32>(scaled_display_height), m_display_texture->GetWidth(),
|
-static_cast<s32>(scaled_display_height), m_display_texture.GetWidth(),
|
||||||
m_display_texture->GetHeight(), m_crtc_state.display_aspect_ratio);
|
m_display_texture.GetHeight(), m_crtc_state.display_aspect_ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore state
|
// restore state
|
||||||
m_vram_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_vram_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
glViewport(0, 0, m_vram_texture->GetWidth(), m_vram_texture->GetHeight());
|
glViewport(0, 0, m_vram_texture.GetWidth(), m_vram_texture.GetHeight());
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -564,8 +586,8 @@ void GPU_HW_OpenGL::ReadVRAM(u32 x, u32 y, u32 width, u32 height)
|
|||||||
// Encode the 24-bit texture as 16-bit.
|
// Encode the 24-bit texture as 16-bit.
|
||||||
const u32 uniforms[4] = {copy_rect.left, VRAM_HEIGHT - copy_rect.top - copy_rect.GetHeight(), copy_rect.GetWidth(),
|
const u32 uniforms[4] = {copy_rect.left, VRAM_HEIGHT - copy_rect.top - copy_rect.GetHeight(), copy_rect.GetWidth(),
|
||||||
copy_rect.GetHeight()};
|
copy_rect.GetHeight()};
|
||||||
m_vram_encoding_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_vram_encoding_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
m_vram_texture->Bind();
|
m_vram_texture.Bind();
|
||||||
m_vram_read_program.Bind();
|
m_vram_read_program.Bind();
|
||||||
UploadUniformBlock(uniforms, sizeof(uniforms));
|
UploadUniformBlock(uniforms, sizeof(uniforms));
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
@ -574,7 +596,7 @@ void GPU_HW_OpenGL::ReadVRAM(u32 x, u32 y, u32 width, u32 height)
|
|||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
|
||||||
// Readback encoded texture.
|
// Readback encoded texture.
|
||||||
m_vram_encoding_texture->BindFramebuffer(GL_READ_FRAMEBUFFER);
|
m_vram_encoding_texture.BindFramebuffer(GL_READ_FRAMEBUFFER);
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 2);
|
glPixelStorei(GL_PACK_ALIGNMENT, 2);
|
||||||
glPixelStorei(GL_PACK_ROW_LENGTH, VRAM_WIDTH / 2);
|
glPixelStorei(GL_PACK_ROW_LENGTH, VRAM_WIDTH / 2);
|
||||||
glReadPixels(0, 0, encoded_width, encoded_height, GL_RGBA, GL_UNSIGNED_BYTE,
|
glReadPixels(0, 0, encoded_width, encoded_height, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||||
@ -594,7 +616,7 @@ void GPU_HW_OpenGL::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
|||||||
width *= m_resolution_scale;
|
width *= m_resolution_scale;
|
||||||
height *= m_resolution_scale;
|
height *= m_resolution_scale;
|
||||||
|
|
||||||
glScissor(x, m_vram_texture->GetHeight() - y - height, width, height);
|
glScissor(x, m_vram_texture.GetHeight() - y - height, width, height);
|
||||||
|
|
||||||
// drop precision unless true colour is enabled
|
// drop precision unless true colour is enabled
|
||||||
if (!m_true_color)
|
if (!m_true_color)
|
||||||
@ -635,7 +657,7 @@ void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void*
|
|||||||
const u32 scaled_height = height * m_resolution_scale;
|
const u32 scaled_height = height * m_resolution_scale;
|
||||||
const u32 scaled_x = x * m_resolution_scale;
|
const u32 scaled_x = x * m_resolution_scale;
|
||||||
const u32 scaled_y = y * m_resolution_scale;
|
const u32 scaled_y = y * m_resolution_scale;
|
||||||
const u32 scaled_flipped_y = m_vram_texture->GetHeight() - scaled_y - scaled_height;
|
const u32 scaled_flipped_y = m_vram_texture.GetHeight() - scaled_y - scaled_height;
|
||||||
glViewport(scaled_x, scaled_flipped_y, scaled_width, scaled_height);
|
glViewport(scaled_x, scaled_flipped_y, scaled_width, scaled_height);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
@ -679,9 +701,9 @@ void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void*
|
|||||||
|
|
||||||
// have to write to the 1x texture first
|
// have to write to the 1x texture first
|
||||||
if (m_resolution_scale > 1)
|
if (m_resolution_scale > 1)
|
||||||
m_vram_encoding_texture->Bind();
|
m_vram_encoding_texture.Bind();
|
||||||
else
|
else
|
||||||
m_vram_texture->Bind();
|
m_vram_texture.Bind();
|
||||||
|
|
||||||
// lower-left origin flip happens here
|
// lower-left origin flip happens here
|
||||||
const u32 flipped_y = VRAM_HEIGHT - y - height;
|
const u32 flipped_y = VRAM_HEIGHT - y - height;
|
||||||
@ -698,9 +720,9 @@ void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void*
|
|||||||
const u32 scaled_height = height * m_resolution_scale;
|
const u32 scaled_height = height * m_resolution_scale;
|
||||||
const u32 scaled_x = x * m_resolution_scale;
|
const u32 scaled_x = x * m_resolution_scale;
|
||||||
const u32 scaled_y = y * m_resolution_scale;
|
const u32 scaled_y = y * m_resolution_scale;
|
||||||
const u32 scaled_flipped_y = m_vram_texture->GetHeight() - scaled_y - scaled_height;
|
const u32 scaled_flipped_y = m_vram_texture.GetHeight() - scaled_y - scaled_height;
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
m_vram_encoding_texture->BindFramebuffer(GL_READ_FRAMEBUFFER);
|
m_vram_encoding_texture.BindFramebuffer(GL_READ_FRAMEBUFFER);
|
||||||
glBlitFramebuffer(x, flipped_y, x + width, flipped_y + height, scaled_x, scaled_flipped_y,
|
glBlitFramebuffer(x, flipped_y, x + width, flipped_y + height, scaled_x, scaled_flipped_y,
|
||||||
scaled_x + scaled_width, scaled_flipped_y + scaled_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
scaled_x + scaled_width, scaled_flipped_y + scaled_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
@ -720,23 +742,23 @@ void GPU_HW_OpenGL::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 wid
|
|||||||
height *= m_resolution_scale;
|
height *= m_resolution_scale;
|
||||||
|
|
||||||
// lower-left origin flip
|
// lower-left origin flip
|
||||||
src_y = m_vram_texture->GetHeight() - src_y - height;
|
src_y = m_vram_texture.GetHeight() - src_y - height;
|
||||||
dst_y = m_vram_texture->GetHeight() - dst_y - height;
|
dst_y = m_vram_texture.GetHeight() - dst_y - height;
|
||||||
|
|
||||||
if (GLAD_GL_VERSION_4_3)
|
if (GLAD_GL_VERSION_4_3)
|
||||||
{
|
{
|
||||||
glCopyImageSubData(m_vram_texture->GetGLId(), GL_TEXTURE_2D, 0, src_x, src_y, 0, m_vram_texture->GetGLId(),
|
glCopyImageSubData(m_vram_texture.GetGLId(), GL_TEXTURE_2D, 0, src_x, src_y, 0, m_vram_texture.GetGLId(),
|
||||||
GL_TEXTURE_2D, 0, dst_x, dst_y, 0, width, height, 1);
|
GL_TEXTURE_2D, 0, dst_x, dst_y, 0, width, height, 1);
|
||||||
}
|
}
|
||||||
else if (GLAD_GL_EXT_copy_image)
|
else if (GLAD_GL_EXT_copy_image)
|
||||||
{
|
{
|
||||||
glCopyImageSubDataEXT(m_vram_texture->GetGLId(), GL_TEXTURE_2D, 0, src_x, src_y, 0, m_vram_texture->GetGLId(),
|
glCopyImageSubDataEXT(m_vram_texture.GetGLId(), GL_TEXTURE_2D, 0, src_x, src_y, 0, m_vram_texture.GetGLId(),
|
||||||
GL_TEXTURE_2D, 0, dst_x, dst_y, 0, width, height, 1);
|
GL_TEXTURE_2D, 0, dst_x, dst_y, 0, width, height, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
m_vram_texture->BindFramebuffer(GL_READ_FRAMEBUFFER);
|
m_vram_texture.BindFramebuffer(GL_READ_FRAMEBUFFER);
|
||||||
glBlitFramebuffer(src_x, src_y, src_x + width, src_y + height, dst_x, dst_y, dst_x + width, dst_y + height,
|
glBlitFramebuffer(src_x, src_y, src_x + width, src_y + height, dst_x, dst_y, dst_x + width, dst_y + height,
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
@ -749,26 +771,26 @@ void GPU_HW_OpenGL::UpdateVRAMReadTexture()
|
|||||||
const u32 width = scaled_rect.GetWidth();
|
const u32 width = scaled_rect.GetWidth();
|
||||||
const u32 height = scaled_rect.GetHeight();
|
const u32 height = scaled_rect.GetHeight();
|
||||||
const u32 x = scaled_rect.left;
|
const u32 x = scaled_rect.left;
|
||||||
const u32 y = m_vram_texture->GetHeight() - scaled_rect.top - height;
|
const u32 y = m_vram_texture.GetHeight() - scaled_rect.top - height;
|
||||||
|
|
||||||
if (GLAD_GL_VERSION_4_3)
|
if (GLAD_GL_VERSION_4_3)
|
||||||
{
|
{
|
||||||
glCopyImageSubData(m_vram_texture->GetGLId(), GL_TEXTURE_2D, 0, x, y, 0, m_vram_read_texture->GetGLId(),
|
glCopyImageSubData(m_vram_texture.GetGLId(), GL_TEXTURE_2D, 0, x, y, 0, m_vram_read_texture.GetGLId(),
|
||||||
GL_TEXTURE_2D, 0, x, y, 0, width, height, 1);
|
GL_TEXTURE_2D, 0, x, y, 0, width, height, 1);
|
||||||
}
|
}
|
||||||
else if (GLAD_GL_EXT_copy_image)
|
else if (GLAD_GL_EXT_copy_image)
|
||||||
{
|
{
|
||||||
glCopyImageSubDataEXT(m_vram_texture->GetGLId(), GL_TEXTURE_2D, 0, x, y, 0, m_vram_read_texture->GetGLId(),
|
glCopyImageSubDataEXT(m_vram_texture.GetGLId(), GL_TEXTURE_2D, 0, x, y, 0, m_vram_read_texture.GetGLId(),
|
||||||
GL_TEXTURE_2D, 0, x, y, 0, width, height, 1);
|
GL_TEXTURE_2D, 0, x, y, 0, width, height, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_vram_read_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_vram_read_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
m_vram_texture->BindFramebuffer(GL_READ_FRAMEBUFFER);
|
m_vram_texture.BindFramebuffer(GL_READ_FRAMEBUFFER);
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
glBlitFramebuffer(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
glBlitFramebuffer(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
m_vram_texture->BindFramebuffer(GL_FRAMEBUFFER);
|
m_vram_texture.BindFramebuffer(GL_FRAMEBUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_renderer_stats.num_vram_read_texture_updates++;
|
m_renderer_stats.num_vram_read_texture_updates++;
|
||||||
|
@ -46,13 +46,12 @@ private:
|
|||||||
std::tuple<s32, s32> ConvertToFramebufferCoordinates(s32 x, s32 y);
|
std::tuple<s32, s32> ConvertToFramebufferCoordinates(s32 x, s32 y);
|
||||||
|
|
||||||
void SetCapabilities(HostDisplay* host_display);
|
void SetCapabilities(HostDisplay* host_display);
|
||||||
void CreateFramebuffer();
|
bool CreateFramebuffer();
|
||||||
void ClearFramebuffer();
|
void ClearFramebuffer();
|
||||||
void DestroyFramebuffer();
|
|
||||||
|
|
||||||
void CreateVertexBuffer();
|
bool CreateVertexBuffer();
|
||||||
void CreateUniformBuffer();
|
bool CreateUniformBuffer();
|
||||||
void CreateTextureBuffer();
|
bool CreateTextureBuffer();
|
||||||
|
|
||||||
bool CompilePrograms();
|
bool CompilePrograms();
|
||||||
void SetDrawState(BatchRenderMode render_mode);
|
void SetDrawState(BatchRenderMode render_mode);
|
||||||
@ -60,10 +59,10 @@ private:
|
|||||||
void UploadUniformBlock(const void* data, u32 data_size);
|
void UploadUniformBlock(const void* data, u32 data_size);
|
||||||
|
|
||||||
// downsample texture - used for readbacks at >1xIR.
|
// downsample texture - used for readbacks at >1xIR.
|
||||||
std::unique_ptr<GL::Texture> m_vram_texture;
|
GL::Texture m_vram_texture;
|
||||||
std::unique_ptr<GL::Texture> m_vram_read_texture;
|
GL::Texture m_vram_read_texture;
|
||||||
std::unique_ptr<GL::Texture> m_vram_encoding_texture;
|
GL::Texture m_vram_encoding_texture;
|
||||||
std::unique_ptr<GL::Texture> m_display_texture;
|
GL::Texture m_display_texture;
|
||||||
|
|
||||||
std::unique_ptr<GL::StreamBuffer> m_vertex_stream_buffer;
|
std::unique_ptr<GL::StreamBuffer> m_vertex_stream_buffer;
|
||||||
GLuint m_vao_id = 0;
|
GLuint m_vao_id = 0;
|
||||||
|
@ -33,13 +33,21 @@ bool GPU_HW_OpenGL_ES::Initialize(HostDisplay* host_display, System* system, DMA
|
|||||||
if (!GPU_HW::Initialize(host_display, system, dma, interrupt_controller, timers))
|
if (!GPU_HW::Initialize(host_display, system, dma, interrupt_controller, timers))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CreateFramebuffer();
|
if (!CreateFramebuffer())
|
||||||
if (!CompilePrograms())
|
{
|
||||||
|
Log_ErrorPrintf("Failed to create framebuffer");
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture->GetGLId())), 0, 0,
|
if (!CompilePrograms())
|
||||||
m_display_texture->GetWidth(), m_display_texture->GetHeight(),
|
{
|
||||||
m_display_texture->GetWidth(), m_display_texture->GetHeight(), 1.0f);
|
Log_ErrorPrintf("Failed to compile programs");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture.GetGLId())), 0, 0,
|
||||||
|
m_display_texture.GetWidth(), m_display_texture.GetHeight(),
|
||||||
|
m_display_texture.GetWidth(), m_display_texture.GetHeight(), 1.0f);
|
||||||
RestoreGraphicsAPIState();
|
RestoreGraphicsAPIState();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -69,8 +77,8 @@ void GPU_HW_OpenGL_ES::ResetGraphicsAPIState()
|
|||||||
|
|
||||||
void GPU_HW_OpenGL_ES::RestoreGraphicsAPIState()
|
void GPU_HW_OpenGL_ES::RestoreGraphicsAPIState()
|
||||||
{
|
{
|
||||||
m_vram_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_vram_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
glViewport(0, 0, m_vram_texture->GetWidth(), m_vram_texture->GetHeight());
|
glViewport(0, 0, m_vram_texture.GetWidth(), m_vram_texture.GetHeight());
|
||||||
|
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
@ -127,47 +135,50 @@ void GPU_HW_OpenGL_ES::SetCapabilities(HostDisplay* host_display)
|
|||||||
m_supports_dual_source_blend = false;
|
m_supports_dual_source_blend = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL_ES::CreateFramebuffer()
|
bool GPU_HW_OpenGL_ES::CreateFramebuffer()
|
||||||
{
|
{
|
||||||
// save old vram texture/fbo, in case we're changing scale
|
// save old vram texture/fbo, in case we're changing scale
|
||||||
auto old_vram_texture = std::move(m_vram_texture);
|
GL::Texture old_vram_texture = std::move(m_vram_texture);
|
||||||
DestroyFramebuffer();
|
|
||||||
|
|
||||||
// scale vram size to internal resolution
|
// scale vram size to internal resolution
|
||||||
const u32 texture_width = VRAM_WIDTH * m_resolution_scale;
|
const u32 texture_width = VRAM_WIDTH * m_resolution_scale;
|
||||||
const u32 texture_height = VRAM_HEIGHT * m_resolution_scale;
|
const u32 texture_height = VRAM_HEIGHT * m_resolution_scale;
|
||||||
|
|
||||||
m_vram_texture =
|
if (!m_vram_texture.Create(texture_width, texture_height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false) ||
|
||||||
std::make_unique<GL::Texture>(texture_width, texture_height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false, true);
|
!m_vram_texture.CreateFramebuffer())
|
||||||
|
|
||||||
// do we need to restore the framebuffer after a size change?
|
|
||||||
if (old_vram_texture)
|
|
||||||
{
|
{
|
||||||
const bool linear_filter = old_vram_texture->GetWidth() > m_vram_texture->GetWidth();
|
return false;
|
||||||
Log_DevPrintf("Scaling %ux%u VRAM texture to %ux%u using %s filter", old_vram_texture->GetWidth(),
|
|
||||||
old_vram_texture->GetHeight(), m_vram_texture->GetWidth(), m_vram_texture->GetHeight(),
|
|
||||||
linear_filter ? "linear" : "nearest");
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
|
||||||
old_vram_texture->BindFramebuffer(GL_READ_FRAMEBUFFER);
|
|
||||||
glBlitFramebuffer(0, 0, old_vram_texture->GetWidth(), old_vram_texture->GetHeight(), 0, 0,
|
|
||||||
m_vram_texture->GetWidth(), m_vram_texture->GetHeight(), GL_COLOR_BUFFER_BIT,
|
|
||||||
linear_filter ? GL_LINEAR : GL_NEAREST);
|
|
||||||
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
old_vram_texture.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vram_read_texture =
|
// do we need to restore the framebuffer after a size change?
|
||||||
std::make_unique<GL::Texture>(texture_width, texture_height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false, true);
|
if (old_vram_texture.IsValid())
|
||||||
|
{
|
||||||
|
const bool linear_filter = old_vram_texture.GetWidth() > m_vram_texture.GetWidth();
|
||||||
|
Log_DevPrintf("Scaling %ux%u VRAM texture to %ux%u using %s filter", old_vram_texture.GetWidth(),
|
||||||
|
old_vram_texture.GetHeight(), m_vram_texture.GetWidth(), m_vram_texture.GetHeight(),
|
||||||
|
linear_filter ? "linear" : "nearest");
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
old_vram_texture.BindFramebuffer(GL_READ_FRAMEBUFFER);
|
||||||
|
glBlitFramebuffer(0, 0, old_vram_texture.GetWidth(), old_vram_texture.GetHeight(), 0, 0, m_vram_texture.GetWidth(),
|
||||||
|
m_vram_texture.GetHeight(), GL_COLOR_BUFFER_BIT, linear_filter ? GL_LINEAR : GL_NEAREST);
|
||||||
|
|
||||||
m_vram_encoding_texture =
|
glEnable(GL_SCISSOR_TEST);
|
||||||
std::make_unique<GL::Texture>(VRAM_WIDTH, VRAM_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false, true);
|
old_vram_texture.Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
m_display_texture =
|
if (!m_vram_read_texture.Create(texture_width, texture_height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false) ||
|
||||||
std::make_unique<GL::Texture>(texture_width, texture_height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false, true);
|
!m_vram_read_texture.CreateFramebuffer() ||
|
||||||
|
!m_vram_encoding_texture.Create(VRAM_WIDTH, VRAM_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false) ||
|
||||||
|
!m_vram_encoding_texture.CreateFramebuffer() ||
|
||||||
|
!m_display_texture.Create(texture_width, texture_height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, false) ||
|
||||||
|
!m_display_texture.CreateFramebuffer())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_vram_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_vram_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
SetFullVRAMDirtyRectangle();
|
SetFullVRAMDirtyRectangle();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL_ES::ClearFramebuffer()
|
void GPU_HW_OpenGL_ES::ClearFramebuffer()
|
||||||
@ -179,14 +190,6 @@ void GPU_HW_OpenGL_ES::ClearFramebuffer()
|
|||||||
SetFullVRAMDirtyRectangle();
|
SetFullVRAMDirtyRectangle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GPU_HW_OpenGL_ES::DestroyFramebuffer()
|
|
||||||
{
|
|
||||||
m_vram_read_texture.reset();
|
|
||||||
m_vram_texture.reset();
|
|
||||||
m_vram_encoding_texture.reset();
|
|
||||||
m_display_texture.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GPU_HW_OpenGL_ES::CompilePrograms()
|
bool GPU_HW_OpenGL_ES::CompilePrograms()
|
||||||
{
|
{
|
||||||
GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_true_color, m_texture_filtering,
|
GPU_HW_ShaderGen shadergen(m_host_display->GetRenderAPI(), m_resolution_scale, m_true_color, m_texture_filtering,
|
||||||
@ -290,7 +293,7 @@ void GPU_HW_OpenGL_ES::SetDrawState(BatchRenderMode render_mode)
|
|||||||
prog.Bind();
|
prog.Bind();
|
||||||
|
|
||||||
if (m_batch.texture_mode != TextureMode::Disabled)
|
if (m_batch.texture_mode != TextureMode::Disabled)
|
||||||
m_vram_read_texture->Bind();
|
m_vram_read_texture.Bind();
|
||||||
|
|
||||||
if (m_batch.transparency_mode == TransparencyMode::Disabled || render_mode == BatchRenderMode::OnlyOpaque)
|
if (m_batch.transparency_mode == TransparencyMode::Disabled || render_mode == BatchRenderMode::OnlyOpaque)
|
||||||
{
|
{
|
||||||
@ -332,7 +335,7 @@ void GPU_HW_OpenGL_ES::SetScissorFromDrawingArea()
|
|||||||
const int width = right - left;
|
const int width = right - left;
|
||||||
const int height = bottom - top;
|
const int height = bottom - top;
|
||||||
const int x = left;
|
const int x = left;
|
||||||
const int y = m_vram_texture->GetHeight() - bottom;
|
const int y = m_vram_texture.GetHeight() - bottom;
|
||||||
|
|
||||||
Log_DebugPrintf("SetScissor: (%d-%d, %d-%d)", x, x + width, y, y + height);
|
Log_DebugPrintf("SetScissor: (%d-%d, %d-%d)", x, x + width, y, y + height);
|
||||||
glScissor(x, y, width, height);
|
glScissor(x, y, width, height);
|
||||||
@ -344,10 +347,10 @@ void GPU_HW_OpenGL_ES::UpdateDisplay()
|
|||||||
|
|
||||||
if (m_system->GetSettings().debugging.show_vram)
|
if (m_system->GetSettings().debugging.show_vram)
|
||||||
{
|
{
|
||||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture->GetGLId())), 0,
|
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture.GetGLId())), 0,
|
||||||
m_vram_texture->GetHeight(), m_vram_texture->GetWidth(),
|
m_vram_texture.GetHeight(), m_vram_texture.GetWidth(),
|
||||||
-static_cast<s32>(m_vram_texture->GetHeight()), m_vram_texture->GetWidth(),
|
-static_cast<s32>(m_vram_texture.GetHeight()), m_vram_texture.GetWidth(),
|
||||||
m_vram_texture->GetHeight(), 1.0f);
|
m_vram_texture.GetHeight(), 1.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -367,17 +370,17 @@ void GPU_HW_OpenGL_ES::UpdateDisplay()
|
|||||||
}
|
}
|
||||||
else if (!m_GPUSTAT.display_area_color_depth_24 && !interlaced)
|
else if (!m_GPUSTAT.display_area_color_depth_24 && !interlaced)
|
||||||
{
|
{
|
||||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture->GetGLId())),
|
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_vram_texture.GetGLId())),
|
||||||
scaled_vram_offset_x, m_vram_texture->GetHeight() - scaled_vram_offset_y,
|
scaled_vram_offset_x, m_vram_texture.GetHeight() - scaled_vram_offset_y,
|
||||||
scaled_display_width, -static_cast<s32>(scaled_display_height),
|
scaled_display_width, -static_cast<s32>(scaled_display_height),
|
||||||
m_vram_texture->GetWidth(), m_vram_texture->GetHeight(),
|
m_vram_texture.GetWidth(), m_vram_texture.GetHeight(),
|
||||||
m_crtc_state.display_aspect_ratio);
|
m_crtc_state.display_aspect_ratio);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const u32 flipped_vram_offset_y = VRAM_HEIGHT - vram_offset_y - display_height;
|
const u32 flipped_vram_offset_y = VRAM_HEIGHT - vram_offset_y - display_height;
|
||||||
const u32 scaled_flipped_vram_offset_y =
|
const u32 scaled_flipped_vram_offset_y =
|
||||||
m_vram_texture->GetHeight() - scaled_vram_offset_y - scaled_display_height;
|
m_vram_texture.GetHeight() - scaled_vram_offset_y - scaled_display_height;
|
||||||
const u32 field_offset = BoolToUInt8(interlaced && m_GPUSTAT.interlaced_field);
|
const u32 field_offset = BoolToUInt8(interlaced && m_GPUSTAT.interlaced_field);
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
@ -392,15 +395,15 @@ void GPU_HW_OpenGL_ES::UpdateDisplay()
|
|||||||
{
|
{
|
||||||
const u32 copy_width = std::min<u32>((display_width * 3) / 2, VRAM_WIDTH - vram_offset_x);
|
const u32 copy_width = std::min<u32>((display_width * 3) / 2, VRAM_WIDTH - vram_offset_x);
|
||||||
const u32 scaled_copy_width = copy_width * m_resolution_scale;
|
const u32 scaled_copy_width = copy_width * m_resolution_scale;
|
||||||
m_vram_encoding_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_vram_encoding_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
m_vram_texture->BindFramebuffer(GL_READ_FRAMEBUFFER);
|
m_vram_texture.BindFramebuffer(GL_READ_FRAMEBUFFER);
|
||||||
glBlitFramebuffer(scaled_vram_offset_x, scaled_flipped_vram_offset_y, scaled_vram_offset_x + scaled_copy_width,
|
glBlitFramebuffer(scaled_vram_offset_x, scaled_flipped_vram_offset_y, scaled_vram_offset_x + scaled_copy_width,
|
||||||
scaled_flipped_vram_offset_y + scaled_display_height, vram_offset_x, flipped_vram_offset_y,
|
scaled_flipped_vram_offset_y + scaled_display_height, vram_offset_x, flipped_vram_offset_y,
|
||||||
vram_offset_x + copy_width, flipped_vram_offset_y + display_height, GL_COLOR_BUFFER_BIT,
|
vram_offset_x + copy_width, flipped_vram_offset_y + display_height, GL_COLOR_BUFFER_BIT,
|
||||||
GL_NEAREST);
|
GL_NEAREST);
|
||||||
|
|
||||||
m_display_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_display_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
m_vram_encoding_texture->Bind();
|
m_vram_encoding_texture.Bind();
|
||||||
|
|
||||||
glViewport(0, field_offset, display_width, display_height);
|
glViewport(0, field_offset, display_width, display_height);
|
||||||
|
|
||||||
@ -410,15 +413,15 @@ void GPU_HW_OpenGL_ES::UpdateDisplay()
|
|||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
|
||||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_texture->GetGLId())),
|
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_texture.GetGLId())),
|
||||||
0, display_height, display_width, -static_cast<s32>(display_height),
|
0, display_height, display_width, -static_cast<s32>(display_height),
|
||||||
m_display_texture->GetWidth(), m_display_texture->GetHeight(),
|
m_display_texture.GetWidth(), m_display_texture.GetHeight(),
|
||||||
m_crtc_state.display_aspect_ratio);
|
m_crtc_state.display_aspect_ratio);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_display_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_display_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
m_vram_texture->Bind();
|
m_vram_texture.Bind();
|
||||||
|
|
||||||
glViewport(0, field_offset, scaled_display_width, scaled_display_height);
|
glViewport(0, field_offset, scaled_display_width, scaled_display_height);
|
||||||
|
|
||||||
@ -428,15 +431,15 @@ void GPU_HW_OpenGL_ES::UpdateDisplay()
|
|||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
|
||||||
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_texture->GetGLId())),
|
m_host_display->SetDisplayTexture(reinterpret_cast<void*>(static_cast<uintptr_t>(m_display_texture.GetGLId())),
|
||||||
0, scaled_display_height, scaled_display_width,
|
0, scaled_display_height, scaled_display_width,
|
||||||
-static_cast<s32>(scaled_display_height), m_display_texture->GetWidth(),
|
-static_cast<s32>(scaled_display_height), m_display_texture.GetWidth(),
|
||||||
m_display_texture->GetHeight(), m_crtc_state.display_aspect_ratio);
|
m_display_texture.GetHeight(), m_crtc_state.display_aspect_ratio);
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore state
|
// restore state
|
||||||
m_vram_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_vram_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
glViewport(0, 0, m_vram_texture->GetWidth(), m_vram_texture->GetHeight());
|
glViewport(0, 0, m_vram_texture.GetWidth(), m_vram_texture.GetHeight());
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -450,8 +453,8 @@ void GPU_HW_OpenGL_ES::ReadVRAM(u32 x, u32 y, u32 width, u32 height)
|
|||||||
const u32 encoded_height = copy_rect.GetHeight();
|
const u32 encoded_height = copy_rect.GetHeight();
|
||||||
|
|
||||||
// Encode the 24-bit texture as 16-bit.
|
// Encode the 24-bit texture as 16-bit.
|
||||||
m_vram_encoding_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_vram_encoding_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
m_vram_texture->Bind();
|
m_vram_texture.Bind();
|
||||||
m_vram_read_program.Bind();
|
m_vram_read_program.Bind();
|
||||||
m_vram_read_program.Uniform2i(0, copy_rect.left, VRAM_HEIGHT - copy_rect.top - copy_rect.GetHeight());
|
m_vram_read_program.Uniform2i(0, copy_rect.left, VRAM_HEIGHT - copy_rect.top - copy_rect.GetHeight());
|
||||||
m_vram_read_program.Uniform2i(1, copy_rect.GetWidth(), copy_rect.GetHeight());
|
m_vram_read_program.Uniform2i(1, copy_rect.GetWidth(), copy_rect.GetHeight());
|
||||||
@ -461,7 +464,7 @@ void GPU_HW_OpenGL_ES::ReadVRAM(u32 x, u32 y, u32 width, u32 height)
|
|||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
|
||||||
// Readback encoded texture.
|
// Readback encoded texture.
|
||||||
m_vram_encoding_texture->BindFramebuffer(GL_READ_FRAMEBUFFER);
|
m_vram_encoding_texture.BindFramebuffer(GL_READ_FRAMEBUFFER);
|
||||||
glPixelStorei(GL_PACK_ALIGNMENT, 2);
|
glPixelStorei(GL_PACK_ALIGNMENT, 2);
|
||||||
glPixelStorei(GL_PACK_ROW_LENGTH, VRAM_WIDTH / 2);
|
glPixelStorei(GL_PACK_ROW_LENGTH, VRAM_WIDTH / 2);
|
||||||
glReadPixels(0, 0, encoded_width, encoded_height, GL_RGBA, GL_UNSIGNED_BYTE,
|
glReadPixels(0, 0, encoded_width, encoded_height, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||||
@ -481,7 +484,7 @@ void GPU_HW_OpenGL_ES::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
|
|||||||
width *= m_resolution_scale;
|
width *= m_resolution_scale;
|
||||||
height *= m_resolution_scale;
|
height *= m_resolution_scale;
|
||||||
|
|
||||||
glScissor(x, m_vram_texture->GetHeight() - y - height, width, height);
|
glScissor(x, m_vram_texture.GetHeight() - y - height, width, height);
|
||||||
|
|
||||||
// drop precision unless true colour is enabled
|
// drop precision unless true colour is enabled
|
||||||
if (!m_true_color)
|
if (!m_true_color)
|
||||||
@ -533,9 +536,9 @@ void GPU_HW_OpenGL_ES::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const voi
|
|||||||
|
|
||||||
// have to write to the 1x texture first
|
// have to write to the 1x texture first
|
||||||
if (m_resolution_scale > 1)
|
if (m_resolution_scale > 1)
|
||||||
m_vram_encoding_texture->Bind();
|
m_vram_encoding_texture.Bind();
|
||||||
else
|
else
|
||||||
m_vram_texture->Bind();
|
m_vram_texture.Bind();
|
||||||
|
|
||||||
// lower-left origin flip happens here
|
// lower-left origin flip happens here
|
||||||
const u32 flipped_y = VRAM_HEIGHT - y - height;
|
const u32 flipped_y = VRAM_HEIGHT - y - height;
|
||||||
@ -550,9 +553,9 @@ void GPU_HW_OpenGL_ES::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const voi
|
|||||||
const u32 scaled_height = height * m_resolution_scale;
|
const u32 scaled_height = height * m_resolution_scale;
|
||||||
const u32 scaled_x = x * m_resolution_scale;
|
const u32 scaled_x = x * m_resolution_scale;
|
||||||
const u32 scaled_y = y * m_resolution_scale;
|
const u32 scaled_y = y * m_resolution_scale;
|
||||||
const u32 scaled_flipped_y = m_vram_texture->GetHeight() - scaled_y - scaled_height;
|
const u32 scaled_flipped_y = m_vram_texture.GetHeight() - scaled_y - scaled_height;
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
m_vram_encoding_texture->BindFramebuffer(GL_READ_FRAMEBUFFER);
|
m_vram_encoding_texture.BindFramebuffer(GL_READ_FRAMEBUFFER);
|
||||||
glBlitFramebuffer(x, flipped_y, x + width, flipped_y + height, scaled_x, scaled_flipped_y, scaled_x + scaled_width,
|
glBlitFramebuffer(x, flipped_y, x + width, flipped_y + height, scaled_x, scaled_flipped_y, scaled_x + scaled_width,
|
||||||
scaled_flipped_y + scaled_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
scaled_flipped_y + scaled_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
@ -571,18 +574,18 @@ void GPU_HW_OpenGL_ES::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32
|
|||||||
height *= m_resolution_scale;
|
height *= m_resolution_scale;
|
||||||
|
|
||||||
// lower-left origin flip
|
// lower-left origin flip
|
||||||
src_y = m_vram_texture->GetHeight() - src_y - height;
|
src_y = m_vram_texture.GetHeight() - src_y - height;
|
||||||
dst_y = m_vram_texture->GetHeight() - dst_y - height;
|
dst_y = m_vram_texture.GetHeight() - dst_y - height;
|
||||||
|
|
||||||
if (GLAD_GL_EXT_copy_image)
|
if (GLAD_GL_EXT_copy_image)
|
||||||
{
|
{
|
||||||
glCopyImageSubDataEXT(m_vram_texture->GetGLId(), GL_TEXTURE_2D, 0, src_x, src_y, 0, m_vram_texture->GetGLId(),
|
glCopyImageSubDataEXT(m_vram_texture.GetGLId(), GL_TEXTURE_2D, 0, src_x, src_y, 0, m_vram_texture.GetGLId(),
|
||||||
GL_TEXTURE_2D, 0, dst_x, dst_y, 0, width, height, 1);
|
GL_TEXTURE_2D, 0, dst_x, dst_y, 0, width, height, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
m_vram_texture->BindFramebuffer(GL_READ_FRAMEBUFFER);
|
m_vram_texture.BindFramebuffer(GL_READ_FRAMEBUFFER);
|
||||||
glBlitFramebuffer(src_x, src_y, src_x + width, src_y + height, dst_x, dst_y, dst_x + width, dst_y + height,
|
glBlitFramebuffer(src_x, src_y, src_x + width, src_y + height, dst_x, dst_y, dst_x + width, dst_y + height,
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
@ -595,21 +598,21 @@ void GPU_HW_OpenGL_ES::UpdateVRAMReadTexture()
|
|||||||
const u32 width = scaled_rect.GetWidth();
|
const u32 width = scaled_rect.GetWidth();
|
||||||
const u32 height = scaled_rect.GetHeight();
|
const u32 height = scaled_rect.GetHeight();
|
||||||
const u32 x = scaled_rect.left;
|
const u32 x = scaled_rect.left;
|
||||||
const u32 y = m_vram_texture->GetHeight() - scaled_rect.top - height;
|
const u32 y = m_vram_texture.GetHeight() - scaled_rect.top - height;
|
||||||
|
|
||||||
if (GLAD_GL_EXT_copy_image)
|
if (GLAD_GL_EXT_copy_image)
|
||||||
{
|
{
|
||||||
glCopyImageSubDataEXT(m_vram_texture->GetGLId(), GL_TEXTURE_2D, 0, x, y, 0, m_vram_read_texture->GetGLId(),
|
glCopyImageSubDataEXT(m_vram_texture.GetGLId(), GL_TEXTURE_2D, 0, x, y, 0, m_vram_read_texture.GetGLId(),
|
||||||
GL_TEXTURE_2D, 0, x, y, 0, width, height, 1);
|
GL_TEXTURE_2D, 0, x, y, 0, width, height, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_vram_read_texture->BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
m_vram_read_texture.BindFramebuffer(GL_DRAW_FRAMEBUFFER);
|
||||||
m_vram_texture->BindFramebuffer(GL_READ_FRAMEBUFFER);
|
m_vram_texture.BindFramebuffer(GL_READ_FRAMEBUFFER);
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
glBlitFramebuffer(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
glBlitFramebuffer(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
m_vram_texture->BindFramebuffer(GL_FRAMEBUFFER);
|
m_vram_texture.BindFramebuffer(GL_FRAMEBUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_renderer_stats.num_vram_read_texture_updates++;
|
m_renderer_stats.num_vram_read_texture_updates++;
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include "glad.h"
|
#include "glad.h"
|
||||||
#include "gpu_hw.h"
|
#include "gpu_hw.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <memory>
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
class GPU_HW_OpenGL_ES : public GPU_HW
|
class GPU_HW_OpenGL_ES : public GPU_HW
|
||||||
@ -46,9 +45,8 @@ private:
|
|||||||
std::tuple<s32, s32> ConvertToFramebufferCoordinates(s32 x, s32 y);
|
std::tuple<s32, s32> ConvertToFramebufferCoordinates(s32 x, s32 y);
|
||||||
|
|
||||||
void SetCapabilities(HostDisplay* host_display);
|
void SetCapabilities(HostDisplay* host_display);
|
||||||
void CreateFramebuffer();
|
bool CreateFramebuffer();
|
||||||
void ClearFramebuffer();
|
void ClearFramebuffer();
|
||||||
void DestroyFramebuffer();
|
|
||||||
|
|
||||||
bool CompilePrograms();
|
bool CompilePrograms();
|
||||||
void SetVertexPointers();
|
void SetVertexPointers();
|
||||||
@ -56,10 +54,10 @@ private:
|
|||||||
void SetScissorFromDrawingArea();
|
void SetScissorFromDrawingArea();
|
||||||
|
|
||||||
// downsample texture - used for readbacks at >1xIR.
|
// downsample texture - used for readbacks at >1xIR.
|
||||||
std::unique_ptr<GL::Texture> m_vram_texture;
|
GL::Texture m_vram_texture;
|
||||||
std::unique_ptr<GL::Texture> m_vram_read_texture;
|
GL::Texture m_vram_read_texture;
|
||||||
std::unique_ptr<GL::Texture> m_vram_encoding_texture;
|
GL::Texture m_vram_encoding_texture;
|
||||||
std::unique_ptr<GL::Texture> m_display_texture;
|
GL::Texture m_display_texture;
|
||||||
|
|
||||||
std::vector<BatchVertex> m_vertex_buffer;
|
std::vector<BatchVertex> m_vertex_buffer;
|
||||||
|
|
||||||
|
@ -339,8 +339,8 @@ void main()
|
|||||||
|
|
||||||
glGenVertexArrays(1, &m_display_vao);
|
glGenVertexArrays(1, &m_display_vao);
|
||||||
|
|
||||||
m_app_icon_texture =
|
if (!m_app_icon_texture.Create(APP_ICON_WIDTH, APP_ICON_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, APP_ICON_DATA, true))
|
||||||
std::make_unique<GL::Texture>(APP_ICON_WIDTH, APP_ICON_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, APP_ICON_DATA, true);
|
return false;
|
||||||
|
|
||||||
// samplers
|
// samplers
|
||||||
glGenSamplers(1, &m_display_nearest_sampler);
|
glGenSamplers(1, &m_display_nearest_sampler);
|
||||||
|
@ -52,7 +52,7 @@ private:
|
|||||||
int m_window_width = 0;
|
int m_window_width = 0;
|
||||||
int m_window_height = 0;
|
int m_window_height = 0;
|
||||||
|
|
||||||
std::unique_ptr<GL::Texture> m_app_icon_texture = nullptr;
|
GL::Texture m_app_icon_texture;
|
||||||
|
|
||||||
GL::Program m_display_program;
|
GL::Program m_display_program;
|
||||||
GLuint m_display_vao = 0;
|
GLuint m_display_vao = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user