summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/renderer_opengl.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp122
1 files changed, 71 insertions, 51 deletions
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 8410e0a64..3cabda8f9 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -89,8 +89,12 @@ struct ScreenRectVertex {
static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, const float height) {
std::array<GLfloat, 3 * 2> matrix;
- matrix[0] = 2.f / width; matrix[2] = 0.f; matrix[4] = -1.f;
- matrix[1] = 0.f; matrix[3] = -2.f / height; matrix[5] = 1.f;
+ matrix[0] = 2.f / width;
+ matrix[2] = 0.f;
+ matrix[4] = -1.f;
+ matrix[1] = 0.f;
+ matrix[3] = -2.f / height;
+ matrix[5] = 1.f;
// Last matrix row is implicitly assumed to be [0, 0, 1].
return matrix;
@@ -98,7 +102,7 @@ static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, cons
/// RendererOpenGL constructor
RendererOpenGL::RendererOpenGL() {
- resolution_width = std::max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth);
+ resolution_width = std::max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth);
resolution_height = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight;
}
@@ -116,13 +120,15 @@ void RendererOpenGL::SwapBuffers() {
const auto& framebuffer = GPU::g_regs.framebuffer_config[i];
// Main LCD (0): 0x1ED02204, Sub LCD (1): 0x1ED02A04
- u32 lcd_color_addr = (i == 0) ? LCD_REG_INDEX(color_fill_top) : LCD_REG_INDEX(color_fill_bottom);
+ u32 lcd_color_addr =
+ (i == 0) ? LCD_REG_INDEX(color_fill_top) : LCD_REG_INDEX(color_fill_bottom);
lcd_color_addr = HW::VADDR_LCD + 4 * lcd_color_addr;
LCD::Regs::ColorFill color_fill = {0};
LCD::Read(color_fill.raw, lcd_color_addr);
if (color_fill.is_enabled) {
- LoadColorToActiveGLTexture(color_fill.color_r, color_fill.color_g, color_fill.color_b, screen_infos[i].texture);
+ LoadColorToActiveGLTexture(color_fill.color_r, color_fill.color_g, color_fill.color_b,
+ screen_infos[i].texture);
// Resize the texture in case the framebuffer size has changed
screen_infos[i].texture.width = 1;
@@ -172,15 +178,14 @@ void RendererOpenGL::SwapBuffers() {
* Loads framebuffer from emulated memory into the active OpenGL texture.
*/
void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& framebuffer,
- ScreenInfo& screen_info) {
+ ScreenInfo& screen_info) {
- const PAddr framebuffer_addr = framebuffer.active_fb == 0 ?
- framebuffer.address_left1 : framebuffer.address_left2;
+ const PAddr framebuffer_addr =
+ framebuffer.active_fb == 0 ? framebuffer.address_left1 : framebuffer.address_left2;
LOG_TRACE(Render_OpenGL, "0x%08x bytes from 0x%08x(%dx%d), fmt %x",
- framebuffer.stride * framebuffer.height,
- framebuffer_addr, (int)framebuffer.width,
- (int)framebuffer.height, (int)framebuffer.format);
+ framebuffer.stride * framebuffer.height, framebuffer_addr, (int)framebuffer.width,
+ (int)framebuffer.height, (int)framebuffer.format);
int bpp = GPU::Regs::BytesPerPixel(framebuffer.color_format);
size_t pixel_stride = framebuffer.stride / bpp;
@@ -192,7 +197,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& fram
// only allows rows to have a memory alignement of 4.
ASSERT(pixel_stride % 4 == 0);
- if (!Rasterizer()->AccelerateDisplay(framebuffer, framebuffer_addr, static_cast<u32>(pixel_stride), screen_info)) {
+ if (!Rasterizer()->AccelerateDisplay(framebuffer, framebuffer_addr,
+ static_cast<u32>(pixel_stride), screen_info)) {
// Reset the screen info's display texture to its own permanent texture
screen_info.display_texture = screen_info.texture.resource.handle;
screen_info.display_texcoords = MathUtil::Rectangle<float>(0.f, 0.f, 1.f, 1.f);
@@ -208,12 +214,14 @@ void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& fram
glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)pixel_stride);
// Update existing texture
- // TODO: Test what happens on hardware when you change the framebuffer dimensions so that they
+ // TODO: Test what happens on hardware when you change the framebuffer dimensions so that
+ // they
// differ from the LCD resolution.
// TODO: Applications could theoretically crash Citra here by specifying too large
// framebuffer sizes. We should make sure that this cannot happen.
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, framebuffer.width, framebuffer.height,
- screen_info.texture.gl_format, screen_info.texture.gl_type, framebuffer_data);
+ screen_info.texture.gl_format, screen_info.texture.gl_type,
+ framebuffer_data);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
@@ -224,7 +232,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& fram
/**
* Fills active OpenGL texture with the given RGB color.
- * Since the color is solid, the texture can be 1x1 but will stretch across whatever it's rendered on.
+ * Since the color is solid, the texture can be 1x1 but will stretch across whatever it's rendered
+ * on.
* This has the added benefit of being *really fast*.
*/
void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b,
@@ -233,7 +242,7 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color
state.Apply();
glActiveTexture(GL_TEXTURE0);
- u8 framebuffer_data[3] = { color_r, color_g, color_b };
+ u8 framebuffer_data[3] = {color_r, color_g, color_b};
// Update existing texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, framebuffer_data);
@@ -246,7 +255,8 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color
* Initializes the OpenGL state and creates persistent objects.
*/
void RendererOpenGL::InitOpenGLObjects() {
- glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue, 0.0f);
+ glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue,
+ 0.0f);
// Link shaders and get variable locations
shader.Create(vertex_shader, fragment_shader);
@@ -270,8 +280,10 @@ void RendererOpenGL::InitOpenGLObjects() {
// Attach vertex data to VAO
glBufferData(GL_ARRAY_BUFFER, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW);
- glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, sizeof(ScreenRectVertex), (GLvoid*)offsetof(ScreenRectVertex, position));
- glVertexAttribPointer(attrib_tex_coord, 2, GL_FLOAT, GL_FALSE, sizeof(ScreenRectVertex), (GLvoid*)offsetof(ScreenRectVertex, tex_coord));
+ glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, sizeof(ScreenRectVertex),
+ (GLvoid*)offsetof(ScreenRectVertex, position));
+ glVertexAttribPointer(attrib_tex_coord, 2, GL_FLOAT, GL_FALSE, sizeof(ScreenRectVertex),
+ (GLvoid*)offsetof(ScreenRectVertex, tex_coord));
glEnableVertexAttribArray(attrib_position);
glEnableVertexAttribArray(attrib_tex_coord);
@@ -352,23 +364,25 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
glActiveTexture(GL_TEXTURE0);
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0,
- texture.gl_format, texture.gl_type, nullptr);
+ texture.gl_format, texture.gl_type, nullptr);
state.texture_units[0].texture_2d = 0;
state.Apply();
}
/**
- * Draws a single texture to the emulator window, rotating the texture to correct for the 3DS's LCD rotation.
+ * Draws a single texture to the emulator window, rotating the texture to correct for the 3DS's LCD
+ * rotation.
*/
-void RendererOpenGL::DrawSingleScreenRotated(const ScreenInfo& screen_info, float x, float y, float w, float h) {
+void RendererOpenGL::DrawSingleScreenRotated(const ScreenInfo& screen_info, float x, float y,
+ float w, float h) {
auto& texcoords = screen_info.display_texcoords;
std::array<ScreenRectVertex, 4> vertices = {{
- ScreenRectVertex(x, y, texcoords.bottom, texcoords.left),
- ScreenRectVertex(x+w, y, texcoords.bottom, texcoords.right),
- ScreenRectVertex(x, y+h, texcoords.top, texcoords.left),
- ScreenRectVertex(x+w, y+h, texcoords.top, texcoords.right),
+ ScreenRectVertex(x, y, texcoords.bottom, texcoords.left),
+ ScreenRectVertex(x + w, y, texcoords.bottom, texcoords.right),
+ ScreenRectVertex(x, y + h, texcoords.top, texcoords.left),
+ ScreenRectVertex(x + w, y + h, texcoords.top, texcoords.right),
}};
state.texture_units[0].texture_2d = screen_info.display_texture;
@@ -391,18 +405,20 @@ void RendererOpenGL::DrawScreens() {
glClear(GL_COLOR_BUFFER_BIT);
// Set projection matrix
- std::array<GLfloat, 3 * 2> ortho_matrix = MakeOrthographicMatrix((float)layout.width,
- (float)layout.height);
+ std::array<GLfloat, 3 * 2> ortho_matrix =
+ MakeOrthographicMatrix((float)layout.width, (float)layout.height);
glUniformMatrix3x2fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data());
// Bind texture in Texture Unit 0
glActiveTexture(GL_TEXTURE0);
glUniform1i(uniform_color_texture, 0);
- DrawSingleScreenRotated(screen_infos[0], (float)layout.top_screen.left, (float)layout.top_screen.top,
- (float)layout.top_screen.GetWidth(), (float)layout.top_screen.GetHeight());
- DrawSingleScreenRotated(screen_infos[1], (float)layout.bottom_screen.left,(float)layout.bottom_screen.top,
- (float)layout.bottom_screen.GetWidth(), (float)layout.bottom_screen.GetHeight());
+ DrawSingleScreenRotated(screen_infos[0], (float)layout.top_screen.left,
+ (float)layout.top_screen.top, (float)layout.top_screen.GetWidth(),
+ (float)layout.top_screen.GetHeight());
+ DrawSingleScreenRotated(screen_infos[1], (float)layout.bottom_screen.left,
+ (float)layout.bottom_screen.top, (float)layout.bottom_screen.GetWidth(),
+ (float)layout.bottom_screen.GetHeight());
m_current_frame++;
}
@@ -420,14 +436,16 @@ void RendererOpenGL::SetWindow(EmuWindow* window) {
}
static const char* GetSource(GLenum source) {
-#define RET(s) case GL_DEBUG_SOURCE_##s: return #s
+#define RET(s) \
+ case GL_DEBUG_SOURCE_##s: \
+ return #s
switch (source) {
- RET(API);
- RET(WINDOW_SYSTEM);
- RET(SHADER_COMPILER);
- RET(THIRD_PARTY);
- RET(APPLICATION);
- RET(OTHER);
+ RET(API);
+ RET(WINDOW_SYSTEM);
+ RET(SHADER_COMPILER);
+ RET(THIRD_PARTY);
+ RET(APPLICATION);
+ RET(OTHER);
default:
UNREACHABLE();
}
@@ -435,23 +453,25 @@ static const char* GetSource(GLenum source) {
}
static const char* GetType(GLenum type) {
-#define RET(t) case GL_DEBUG_TYPE_##t: return #t
+#define RET(t) \
+ case GL_DEBUG_TYPE_##t: \
+ return #t
switch (type) {
- RET(ERROR);
- RET(DEPRECATED_BEHAVIOR);
- RET(UNDEFINED_BEHAVIOR);
- RET(PORTABILITY);
- RET(PERFORMANCE);
- RET(OTHER);
- RET(MARKER);
+ RET(ERROR);
+ RET(DEPRECATED_BEHAVIOR);
+ RET(UNDEFINED_BEHAVIOR);
+ RET(PORTABILITY);
+ RET(PERFORMANCE);
+ RET(OTHER);
+ RET(MARKER);
default:
UNREACHABLE();
}
#undef RET
}
-static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
- const GLchar* message, const void* user_param) {
+static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity,
+ GLsizei length, const GLchar* message, const void* user_param) {
Log::Level level;
switch (severity) {
case GL_DEBUG_SEVERITY_HIGH:
@@ -465,8 +485,8 @@ static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum
level = Log::Level::Debug;
break;
}
- LOG_GENERIC(Log::Class::Render_OpenGL, level, "%s %s %d: %s",
- GetSource(source), GetType(type), id, message);
+ LOG_GENERIC(Log::Class::Render_OpenGL, level, "%s %s %d: %s", GetSource(source), GetType(type),
+ id, message);
}
/// Initialize the renderer