aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/video_core/renderer_opengl/renderer_opengl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl/renderer_opengl.cpp')
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp61
1 files changed, 47 insertions, 14 deletions
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 71ceb021..16cf92e2 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -53,6 +53,7 @@ static std::array<GLfloat, 3*2> MakeOrthographicMatrix(const float width, const
/// RendererOpenGL constructor
RendererOpenGL::RendererOpenGL() {
+ hw_rasterizer.reset(new RasterizerOpenGL());
resolution_width = std::max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth);
resolution_height = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight;
}
@@ -63,7 +64,9 @@ RendererOpenGL::~RendererOpenGL() {
/// Swap buffers (render frame)
void RendererOpenGL::SwapBuffers() {
- render_window->MakeCurrent();
+ // Maintain the rasterizer's state as a priority
+ OpenGLState prev_state = OpenGLState::GetCurState();
+ state.Apply();
for(int i : {0, 1}) {
const auto& framebuffer = GPU::g_regs.framebuffer_config[i];
@@ -110,7 +113,19 @@ void RendererOpenGL::SwapBuffers() {
render_window->PollEvents();
render_window->SwapBuffers();
+ prev_state.Apply();
+
profiler.BeginFrame();
+
+ bool hw_renderer_enabled = VideoCore::g_hw_renderer_enabled;
+ if (Settings::values.use_hw_renderer != hw_renderer_enabled) {
+ // TODO: Save new setting value to config file for next startup
+ Settings::values.use_hw_renderer = hw_renderer_enabled;
+
+ if (Settings::values.use_hw_renderer) {
+ hw_rasterizer->Reset();
+ }
+ }
}
/**
@@ -139,7 +154,11 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig&
// only allows rows to have a memory alignement of 4.
ASSERT(pixel_stride % 4 == 0);
- glBindTexture(GL_TEXTURE_2D, texture.handle);
+ state.texture_units[0].enabled_2d = true;
+ state.texture_units[0].texture_2d = texture.handle;
+ state.Apply();
+
+ glActiveTexture(GL_TEXTURE0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)pixel_stride);
// Update existing texture
@@ -151,7 +170,6 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig&
texture.gl_format, texture.gl_type, framebuffer_data);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glBindTexture(GL_TEXTURE_2D, 0);
}
/**
@@ -161,13 +179,15 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig&
*/
void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b,
const TextureInfo& texture) {
- glBindTexture(GL_TEXTURE_2D, texture.handle);
+ state.texture_units[0].enabled_2d = true;
+ state.texture_units[0].texture_2d = texture.handle;
+ state.Apply();
+ glActiveTexture(GL_TEXTURE0);
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);
- glBindTexture(GL_TEXTURE_2D, 0);
}
/**
@@ -175,7 +195,6 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color
*/
void RendererOpenGL::InitOpenGLObjects() {
glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue, 0.0f);
- glDisable(GL_DEPTH_TEST);
// Link shaders and get variable locations
program_id = ShaderUtil::LoadShaders(GLShaders::g_vertex_shader, GLShaders::g_fragment_shader);
@@ -189,10 +208,12 @@ void RendererOpenGL::InitOpenGLObjects() {
// Generate VAO
glGenVertexArrays(1, &vertex_array_handle);
- glBindVertexArray(vertex_array_handle);
+
+ state.draw.vertex_array = vertex_array_handle;
+ state.draw.vertex_buffer = vertex_buffer_handle;
+ state.Apply();
// Attach vertex data to VAO
- glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_handle);
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));
@@ -206,14 +227,19 @@ void RendererOpenGL::InitOpenGLObjects() {
// Allocation of storage is deferred until the first frame, when we
// know the framebuffer size.
- glBindTexture(GL_TEXTURE_2D, texture.handle);
+ state.texture_units[0].enabled_2d = true;
+ state.texture_units[0].texture_2d = texture.handle;
+ state.Apply();
+
+ glActiveTexture(GL_TEXTURE0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
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_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
- glBindTexture(GL_TEXTURE_2D, 0);
+
+ hw_rasterizer->InitObjects();
}
void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
@@ -264,7 +290,11 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
UNIMPLEMENTED();
}
- glBindTexture(GL_TEXTURE_2D, texture.handle);
+ state.texture_units[0].enabled_2d = true;
+ state.texture_units[0].texture_2d = texture.handle;
+ state.Apply();
+
+ glActiveTexture(GL_TEXTURE0);
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0,
texture.gl_format, texture.gl_type, nullptr);
}
@@ -280,8 +310,10 @@ void RendererOpenGL::DrawSingleScreenRotated(const TextureInfo& texture, float x
ScreenRectVertex(x+w, y+h, 0.f, 1.f),
};
- glBindTexture(GL_TEXTURE_2D, texture.handle);
- glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_handle);
+ state.texture_units[0].enabled_2d = true;
+ state.texture_units[0].texture_2d = texture.handle;
+ state.Apply();
+
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices.data());
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
@@ -295,7 +327,8 @@ void RendererOpenGL::DrawScreens() {
glViewport(0, 0, layout.width, layout.height);
glClear(GL_COLOR_BUFFER_BIT);
- glUseProgram(program_id);
+ state.draw.shader_program = program_id;
+ state.Apply();
// Set projection matrix
std::array<GLfloat, 3 * 2> ortho_matrix = MakeOrthographicMatrix((float)layout.width,