diff options
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 19 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 5 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 16 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_resource_manager.cpp | 111 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_resource_manager.h | 110 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 13 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/pica_to_gl.h | 29 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 19 |
8 files changed, 155 insertions, 167 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 518f7933..2db845da 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -2,10 +2,15 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <cstring> +#include <memory> + #include "common/color.h" +#include "common/math_util.h" -#include "core/settings.h" #include "core/hw/gpu.h" +#include "core/memory.h" +#include "core/settings.h" #include "video_core/pica.h" #include "video_core/utils.h" @@ -16,8 +21,6 @@ #include "generated/gl_3_2_core.h" -#include <memory> - static bool IsPassThroughTevStage(const Pica::Regs::TevStageConfig& stage) { return (stage.color_op == Pica::Regs::TevStageConfig::Operation::Replace && stage.alpha_op == Pica::Regs::TevStageConfig::Operation::Replace && @@ -813,12 +816,16 @@ void RasterizerOpenGL::ReloadColorBuffer() { } void RasterizerOpenGL::ReloadDepthBuffer() { + PAddr depth_buffer_addr = Pica::g_state.regs.framebuffer.GetDepthBufferPhysicalAddress(); + + if (depth_buffer_addr == 0) + return; + // TODO: Appears to work, but double-check endianness of depth values and order of depth-stencil - u8* depth_buffer = Memory::GetPhysicalPointer(Pica::g_state.regs.framebuffer.GetDepthBufferPhysicalAddress()); + u8* depth_buffer = Memory::GetPhysicalPointer(depth_buffer_addr); - if (depth_buffer == nullptr) { + if (depth_buffer == nullptr) return; - } u32 bytes_per_pixel = Pica::Regs::BytesPerDepthPixel(fb_depth_texture.format); diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index d7d422b1..ae7b26fc 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -4,7 +4,12 @@ #pragma once +#include <vector> + +#include "common/common_types.h" + #include "video_core/hwrasterizer_base.h" +#include "video_core/vertex_shader.h" #include "gl_state.h" #include "gl_rasterizer_cache.h" diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 2e4110a8..dc3ffdf2 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -31,12 +31,18 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned text state.texture_units[texture_unit].texture_2d = new_texture->texture.handle; state.Apply(); - // TODO: Need to choose filters that correspond to PICA once register is declared - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, PicaToGL::TextureFilterMode(config.config.mag_filter)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, PicaToGL::TextureFilterMode(config.config.min_filter)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, PicaToGL::WrapMode(config.config.wrap_s)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, PicaToGL::WrapMode(config.config.wrap_t)); + GLenum wrap_s = PicaToGL::WrapMode(config.config.wrap_s); + GLenum wrap_t = PicaToGL::WrapMode(config.config.wrap_t); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t); + + if (wrap_s == GL_CLAMP_TO_BORDER || wrap_t == GL_CLAMP_TO_BORDER) { + auto border_color = PicaToGL::ColorRGBA8((u8*)&config.config.border_color.r); + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color.data()); + } const auto info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format); diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp deleted file mode 100644 index 8f4ae28a..00000000 --- a/src/video_core/renderer_opengl/gl_resource_manager.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2015 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "video_core/renderer_opengl/gl_resource_manager.h" -#include "video_core/renderer_opengl/gl_shader_util.h" - -// Textures -OGLTexture::OGLTexture() : handle(0) { -} - -OGLTexture::~OGLTexture() { - Release(); -} - -void OGLTexture::Create() { - if (handle != 0) { - return; - } - - glGenTextures(1, &handle); -} - -void OGLTexture::Release() { - glDeleteTextures(1, &handle); - handle = 0; -} - -// Shaders -OGLShader::OGLShader() : handle(0) { -} - -OGLShader::~OGLShader() { - Release(); -} - -void OGLShader::Create(const char* vert_shader, const char* frag_shader) { - if (handle != 0) { - return; - } - - handle = ShaderUtil::LoadShaders(vert_shader, frag_shader); -} - -void OGLShader::Release() { - glDeleteProgram(handle); - handle = 0; -} - -// Buffer objects -OGLBuffer::OGLBuffer() : handle(0) { -} - -OGLBuffer::~OGLBuffer() { - Release(); -} - -void OGLBuffer::Create() { - if (handle != 0) { - return; - } - - glGenBuffers(1, &handle); -} - -void OGLBuffer::Release() { - glDeleteBuffers(1, &handle); - handle = 0; -} - -// Vertex array objects -OGLVertexArray::OGLVertexArray() : handle(0) { -} - -OGLVertexArray::~OGLVertexArray() { - Release(); -} - -void OGLVertexArray::Create() { - if (handle != 0) { - return; - } - - glGenVertexArrays(1, &handle); -} - -void OGLVertexArray::Release() { - glDeleteVertexArrays(1, &handle); - handle = 0; -} - -// Framebuffers -OGLFramebuffer::OGLFramebuffer() : handle(0) { -} - -OGLFramebuffer::~OGLFramebuffer() { - Release(); -} - -void OGLFramebuffer::Create() { - if (handle != 0) { - return; - } - - glGenFramebuffers(1, &handle); -} - -void OGLFramebuffer::Release() { - glDeleteFramebuffers(1, &handle); - handle = 0; -} diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h index 975720d0..6f9dc012 100644 --- a/src/video_core/renderer_opengl/gl_resource_manager.h +++ b/src/video_core/renderer_opengl/gl_resource_manager.h @@ -4,76 +4,124 @@ #pragma once +#include <utility> + #include "common/common_types.h" -#include "generated/gl_3_2_core.h" +#include "video_core/renderer_opengl/generated/gl_3_2_core.h" +#include "video_core/renderer_opengl/gl_shader_util.h" -class OGLTexture : public NonCopyable { +class OGLTexture : private NonCopyable { public: - OGLTexture(); - ~OGLTexture(); + OGLTexture() = default; + OGLTexture(OGLTexture&& o) { std::swap(handle, o.handle); } + ~OGLTexture() { Release(); } + OGLTexture& operator=(OGLTexture&& o) { std::swap(handle, o.handle); return *this; } /// Creates a new internal OpenGL resource and stores the handle - void Create(); + void Create() { + if (handle != 0) return; + glGenTextures(1, &handle); + } /// Deletes the internal OpenGL resource - void Release(); + void Release() { + if (handle == 0) return; + glDeleteTextures(1, &handle); + handle = 0; + } - GLuint handle; + GLuint handle = 0; }; -class OGLShader : public NonCopyable { +class OGLShader : private NonCopyable { public: - OGLShader(); - ~OGLShader(); + OGLShader() = default; + OGLShader(OGLShader&& o) { std::swap(handle, o.handle); } + ~OGLShader() { Release(); } + OGLShader& operator=(OGLShader&& o) { std::swap(handle, o.handle); return *this; } /// Creates a new internal OpenGL resource and stores the handle - void Create(const char* vert_shader, const char* frag_shader); + void Create(const char* vert_shader, const char* frag_shader) { + if (handle != 0) return; + handle = ShaderUtil::LoadShaders(vert_shader, frag_shader); + } /// Deletes the internal OpenGL resource - void Release(); + void Release() { + if (handle == 0) return; + glDeleteProgram(handle); + handle = 0; + } - GLuint handle; + GLuint handle = 0; }; -class OGLBuffer : public NonCopyable { +class OGLBuffer : private NonCopyable { public: - OGLBuffer(); - ~OGLBuffer(); + OGLBuffer() = default; + OGLBuffer(OGLBuffer&& o) { std::swap(handle, o.handle); } + ~OGLBuffer() { Release(); } + OGLBuffer& operator=(OGLBuffer&& o) { std::swap(handle, o.handle); return *this; } /// Creates a new internal OpenGL resource and stores the handle - void Create(); + void Create() { + if (handle != 0) return; + glGenBuffers(1, &handle); + } /// Deletes the internal OpenGL resource - void Release(); + void Release() { + if (handle == 0) return; + glDeleteBuffers(1, &handle); + handle = 0; + } - GLuint handle; + GLuint handle = 0; }; -class OGLVertexArray : public NonCopyable { +class OGLVertexArray : private NonCopyable { public: - OGLVertexArray(); - ~OGLVertexArray(); + OGLVertexArray() = default; + OGLVertexArray(OGLVertexArray&& o) { std::swap(handle, o.handle); } + ~OGLVertexArray() { Release(); } + OGLVertexArray& operator=(OGLVertexArray&& o) { std::swap(handle, o.handle); return *this; } /// Creates a new internal OpenGL resource and stores the handle - void Create(); + void Create() { + if (handle != 0) return; + glGenVertexArrays(1, &handle); + } /// Deletes the internal OpenGL resource - void Release(); + void Release() { + if (handle == 0) return; + glDeleteVertexArrays(1, &handle); + handle = 0; + } - GLuint handle; + GLuint handle = 0; }; -class OGLFramebuffer : public NonCopyable { +class OGLFramebuffer : private NonCopyable { public: - OGLFramebuffer(); - ~OGLFramebuffer(); + OGLFramebuffer() = default; + OGLFramebuffer(OGLFramebuffer&& o) { std::swap(handle, o.handle); } + ~OGLFramebuffer() { Release(); } + OGLFramebuffer& operator=(OGLFramebuffer&& o) { std::swap(handle, o.handle); return *this; } /// Creates a new internal OpenGL resource and stores the handle - void Create(); + void Create() { + if (handle != 0) return; + glGenFramebuffers(1, &handle); + } /// Deletes the internal OpenGL resource - void Release(); + void Release() { + if (handle == 0) return; + glDeleteFramebuffers(1, &handle); + handle = 0; + } - GLuint handle; + GLuint handle = 0; }; diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 3526e16d..9efc1533 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -147,20 +147,17 @@ void OpenGLState::Apply() { // Textures for (unsigned texture_index = 0; texture_index < ARRAY_SIZE(texture_units); ++texture_index) { - if (texture_units[texture_index].enabled_2d != cur_state.texture_units[texture_index].enabled_2d) { + if (texture_units[texture_index].enabled_2d != cur_state.texture_units[texture_index].enabled_2d || + texture_units[texture_index].texture_2d != cur_state.texture_units[texture_index].texture_2d) { + glActiveTexture(GL_TEXTURE0 + texture_index); if (texture_units[texture_index].enabled_2d) { - glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texture_units[texture_index].texture_2d); } else { - glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); } } - - if (texture_units[texture_index].texture_2d != cur_state.texture_units[texture_index].texture_2d) { - glActiveTexture(GL_TEXTURE0 + texture_index); - glBindTexture(GL_TEXTURE_2D, texture_units[texture_index].texture_2d); - } } // Framebuffer diff --git a/src/video_core/renderer_opengl/pica_to_gl.h b/src/video_core/renderer_opengl/pica_to_gl.h index e566f9f7..3b562da8 100644 --- a/src/video_core/renderer_opengl/pica_to_gl.h +++ b/src/video_core/renderer_opengl/pica_to_gl.h @@ -12,10 +12,37 @@ namespace PicaToGL { +inline GLenum TextureFilterMode(Pica::Regs::TextureConfig::TextureFilter mode) { + static const GLenum filter_mode_table[] = { + GL_NEAREST, // TextureFilter::Nearest + GL_LINEAR // TextureFilter::Linear + }; + + // Range check table for input + if (mode >= ARRAY_SIZE(filter_mode_table)) { + LOG_CRITICAL(Render_OpenGL, "Unknown texture filtering mode %d", mode); + UNREACHABLE(); + + return GL_LINEAR; + } + + GLenum gl_mode = filter_mode_table[mode]; + + // Check for dummy values indicating an unknown mode + if (gl_mode == 0) { + LOG_CRITICAL(Render_OpenGL, "Unknown texture filtering mode %d", mode); + UNIMPLEMENTED(); + + return GL_LINEAR; + } + + return gl_mode; +} + inline GLenum WrapMode(Pica::Regs::TextureConfig::WrapMode mode) { static const GLenum wrap_mode_table[] = { GL_CLAMP_TO_EDGE, // WrapMode::ClampToEdge - 0, // Unknown + GL_CLAMP_TO_BORDER,// WrapMode::ClampToBorder GL_REPEAT, // WrapMode::Repeat GL_MIRRORED_REPEAT // WrapMode::MirroredRepeat }; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 3399ca12..96e12839 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -2,22 +2,27 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <algorithm> +#include <cstddef> +#include <cstdlib> + +#include "common/assert.h" +#include "common/emu_window.h" +#include "common/logging/log.h" +#include "common/profiler_reporting.h" + #include "core/hw/gpu.h" #include "core/hw/hw.h" #include "core/hw/lcd.h" #include "core/memory.h" #include "core/settings.h" -#include "common/emu_window.h" -#include "common/logging/log.h" -#include "common/profiler_reporting.h" - #include "video_core/video_core.h" #include "video_core/renderer_opengl/renderer_opengl.h" #include "video_core/renderer_opengl/gl_shader_util.h" #include "video_core/renderer_opengl/gl_shaders.h" -#include <algorithm> +#include "video_core/debug_utils/debug_utils.h" /** * Vertex structure that the drawn screen rectangles are composed of. @@ -126,6 +131,10 @@ void RendererOpenGL::SwapBuffers() { hw_rasterizer->Reset(); } } + + if (Pica::g_debug_context && Pica::g_debug_context->recorder) { + Pica::g_debug_context->recorder->FrameFinished(); + } } /** |