summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp28
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h5
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.cpp16
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h17
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp32
-rw-r--r--src/video_core/renderer_opengl/gl_state.h12
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp37
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h7
9 files changed, 62 insertions, 94 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index b826146fb..84c4d110c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -99,14 +99,11 @@ void oglEnablei(GLenum cap, bool state, GLuint index) {
} // Anonymous namespace
RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
- ScreenInfo& info)
+ ScreenInfo& info, GLShader::ProgramManager& program_manager)
: RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device},
shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, system{system},
- screen_info{info}, buffer_cache{*this, system, device, STREAM_BUFFER_SIZE} {
- shader_program_manager = std::make_unique<GLShader::ProgramManager>();
- state.draw.shader_program = 0;
- state.Apply();
-
+ screen_info{info}, program_manager{program_manager}, buffer_cache{*this, system, device,
+ STREAM_BUFFER_SIZE} {
CheckExtensions();
}
@@ -228,10 +225,10 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
if (!gpu.regs.IsShaderConfigEnabled(index)) {
switch (program) {
case Maxwell::ShaderProgram::Geometry:
- shader_program_manager->UseTrivialGeometryShader();
+ program_manager.UseGeometryShader(0);
break;
case Maxwell::ShaderProgram::Fragment:
- shader_program_manager->UseTrivialFragmentShader();
+ program_manager.UseFragmentShader(0);
break;
default:
break;
@@ -262,13 +259,13 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
switch (program) {
case Maxwell::ShaderProgram::VertexA:
case Maxwell::ShaderProgram::VertexB:
- shader_program_manager->UseProgrammableVertexShader(program_handle);
+ program_manager.UseVertexShader(program_handle);
break;
case Maxwell::ShaderProgram::Geometry:
- shader_program_manager->UseProgrammableGeometryShader(program_handle);
+ program_manager.UseGeometryShader(program_handle);
break;
case Maxwell::ShaderProgram::Fragment:
- shader_program_manager->UseProgrammableFragmentShader(program_handle);
+ program_manager.UseFragmentShader(program_handle);
break;
default:
UNIMPLEMENTED_MSG("Unimplemented shader index={}, enable={}, offset=0x{:08X}", index,
@@ -550,7 +547,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
bind_ubo_pushbuffer.Bind();
bind_ssbo_pushbuffer.Bind();
- shader_program_manager->ApplyTo(state);
+ program_manager.Update();
state.Apply();
if (texture_cache.TextureBarrier()) {
@@ -613,8 +610,8 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
const ProgramVariant variant(launch_desc.block_dim_x, launch_desc.block_dim_y,
launch_desc.block_dim_z, launch_desc.shared_alloc,
launch_desc.local_pos_alloc);
- state.draw.shader_program = kernel->GetHandle(variant);
- state.draw.program_pipeline = 0;
+ glUseProgramStages(program_manager.GetHandle(), GL_COMPUTE_SHADER_BIT,
+ kernel->GetHandle(variant));
const std::size_t buffer_size =
Tegra::Engines::KeplerCompute::NumConstBuffers *
@@ -632,9 +629,6 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
bind_ubo_pushbuffer.Bind();
bind_ssbo_pushbuffer.Bind();
- state.ApplyShaderProgram();
- state.ApplyProgramPipeline();
-
glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z);
++num_queued_commands;
}
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index de21a3511..b8158c152 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -55,7 +55,7 @@ struct DrawParameters;
class RasterizerOpenGL : public VideoCore::RasterizerAccelerated {
public:
explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
- ScreenInfo& info);
+ ScreenInfo& info, GLShader::ProgramManager& program_manager);
~RasterizerOpenGL() override;
void Draw(bool is_indexed, bool is_instanced) override;
@@ -218,8 +218,7 @@ private:
Core::System& system;
ScreenInfo& screen_info;
-
- std::unique_ptr<GLShader::ProgramManager> shader_program_manager;
+ GLShader::ProgramManager& program_manager;
static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
OGLBufferCache buffer_cache;
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp
index 21ea6fde4..404fd6556 100644
--- a/src/video_core/renderer_opengl/gl_resource_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_resource_manager.cpp
@@ -123,7 +123,6 @@ void OGLProgram::Release() {
MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
glDeleteProgram(handle);
- OpenGLState::GetCurState().ResetProgram(handle).Apply();
handle = 0;
}
@@ -141,7 +140,6 @@ void OGLPipeline::Release() {
MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
glDeleteProgramPipelines(1, &handle);
- OpenGLState::GetCurState().ResetPipeline(handle).Apply();
handle = 0;
}
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp
index 75d3fac04..15f3cd066 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp
@@ -10,27 +10,21 @@ namespace OpenGL::GLShader {
using Tegra::Engines::Maxwell3D;
-ProgramManager::ProgramManager() {
- pipeline.Create();
-}
-
ProgramManager::~ProgramManager() = default;
-void ProgramManager::ApplyTo(OpenGLState& state) {
- UpdatePipeline();
- state.draw.shader_program = 0;
- state.draw.program_pipeline = pipeline.handle;
+void ProgramManager::Create() {
+ pipeline.Create();
}
-void ProgramManager::UpdatePipeline() {
+void ProgramManager::Update() {
// Avoid updating the pipeline when values have no changed
if (old_state == current_state) {
return;
}
// Workaround for AMD bug
- constexpr GLenum all_used_stages{GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT |
- GL_FRAGMENT_SHADER_BIT};
+ static constexpr GLenum all_used_stages{GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT |
+ GL_FRAGMENT_SHADER_BIT};
glUseProgramStages(pipeline.handle, all_used_stages, 0);
glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, current_state.vertex_shader);
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index 478c165ce..db23a27e8 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -29,25 +29,26 @@ static_assert(sizeof(MaxwellUniformData) < 16384,
class ProgramManager {
public:
- explicit ProgramManager();
~ProgramManager();
- void ApplyTo(OpenGLState& state);
+ void Create();
- void UseProgrammableVertexShader(GLuint program) {
+ void Update();
+
+ void UseVertexShader(GLuint program) {
current_state.vertex_shader = program;
}
- void UseProgrammableGeometryShader(GLuint program) {
+ void UseGeometryShader(GLuint program) {
current_state.geometry_shader = program;
}
- void UseProgrammableFragmentShader(GLuint program) {
+ void UseFragmentShader(GLuint program) {
current_state.fragment_shader = program;
}
- void UseTrivialGeometryShader() {
- current_state.geometry_shader = 0;
+ GLuint GetHandle() const {
+ return pipeline.handle;
}
void UseTrivialFragmentShader() {
@@ -70,8 +71,6 @@ private:
GLuint geometry_shader{};
};
- void UpdatePipeline();
-
OGLPipeline pipeline;
PipelineState current_state;
PipelineState old_state;
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index be4ca6bf0..e8a23d41d 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -85,36 +85,6 @@ void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) {
OpenGLState::OpenGLState() = default;
-void OpenGLState::ApplyShaderProgram() {
- if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) {
- glUseProgram(draw.shader_program);
- }
-}
-
-void OpenGLState::ApplyProgramPipeline() {
- if (UpdateValue(cur_state.draw.program_pipeline, draw.program_pipeline)) {
- glBindProgramPipeline(draw.program_pipeline);
- }
-}
-
-void OpenGLState::Apply() {
- MICROPROFILE_SCOPE(OpenGL_State);
- ApplyShaderProgram();
- ApplyProgramPipeline();
-}
-
-OpenGLState& OpenGLState::ResetProgram(GLuint handle) {
- if (draw.shader_program == handle) {
- draw.shader_program = 0;
- }
- return *this;
-}
-
-OpenGLState& OpenGLState::ResetPipeline(GLuint handle) {
- if (draw.program_pipeline == handle) {
- draw.program_pipeline = 0;
- }
- return *this;
-}
+void OpenGLState::Apply() {}
} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index c9a839736..f62e2e2e1 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -13,11 +13,6 @@ namespace OpenGL {
class OpenGLState {
public:
- struct {
- GLuint shader_program = 0; // GL_CURRENT_PROGRAM
- GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING
- } draw;
-
OpenGLState();
/// Get the currently active OpenGL state
@@ -28,13 +23,6 @@ public:
/// Apply this state as the current OpenGL state
void Apply();
- void ApplyShaderProgram();
- void ApplyProgramPipeline();
-
- /// Resets any references to the given resource
- OpenGLState& ResetProgram(GLuint handle);
- OpenGLState& ResetPipeline(GLuint handle);
-
private:
static OpenGLState cur_state;
};
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index da4b4bf34..ace3aec88 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -20,6 +20,7 @@
#include "core/telemetry_session.h"
#include "video_core/morton.h"
#include "video_core/renderer_opengl/gl_rasterizer.h"
+#include "video_core/renderer_opengl/gl_shader_manager.h"
#include "video_core/renderer_opengl/renderer_opengl.h"
namespace OpenGL {
@@ -158,9 +159,13 @@ public:
namespace {
-constexpr char vertex_shader[] = R"(
+constexpr char VERTEX_SHADER[] = R"(
#version 430 core
+out gl_PerVertex {
+ vec4 gl_Position;
+};
+
layout (location = 0) in vec2 vert_position;
layout (location = 1) in vec2 vert_tex_coord;
layout (location = 0) out vec2 frag_tex_coord;
@@ -181,7 +186,7 @@ void main() {
}
)";
-constexpr char fragment_shader[] = R"(
+constexpr char FRAGMENT_SHADER[] = R"(
#version 430 core
layout (location = 0) in vec2 frag_tex_coord;
@@ -426,10 +431,19 @@ void RendererOpenGL::InitOpenGLObjects() {
glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue,
0.0f);
- // Link shaders and get variable locations
- shader.CreateFromSource(vertex_shader, nullptr, fragment_shader);
- state.draw.shader_program = shader.handle;
- state.Apply();
+ // Create shader programs
+ OGLShader vertex_shader;
+ vertex_shader.Create(VERTEX_SHADER, GL_VERTEX_SHADER);
+
+ OGLShader fragment_shader;
+ fragment_shader.Create(FRAGMENT_SHADER, GL_FRAGMENT_SHADER);
+
+ vertex_program.Create(true, false, vertex_shader.handle);
+ fragment_program.Create(true, false, fragment_shader.handle);
+
+ // Create program pipeline
+ program_manager.Create();
+ glBindProgramPipeline(program_manager.GetHandle());
// Generate VBO handle for drawing
vertex_buffer.Create();
@@ -468,7 +482,8 @@ void RendererOpenGL::CreateRasterizer() {
if (rasterizer) {
return;
}
- rasterizer = std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info);
+ rasterizer =
+ std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info, program_manager);
}
void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
@@ -517,7 +532,8 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
// Set projection matrix
const std::array ortho_matrix =
MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height));
- glUniformMatrix3x2fv(ModelViewMatrixLocation, 1, GL_FALSE, ortho_matrix.data());
+ glProgramUniformMatrix3x2fv(vertex_program.handle, ModelViewMatrixLocation, 1, GL_FALSE,
+ std::data(ortho_matrix));
const auto& texcoords = screen_info.display_texcoords;
auto left = texcoords.left;
@@ -562,6 +578,11 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
state.Apply();
// TODO: Signal state tracker about these changes
+ program_manager.UseVertexShader(vertex_program.handle);
+ program_manager.UseGeometryShader(0);
+ program_manager.UseFragmentShader(fragment_program.handle);
+ program_manager.Update();
+
glEnable(GL_CULL_FACE);
if (screen_info.display_srgb) {
glEnable(GL_FRAMEBUFFER_SRGB);
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 42a2141d8..f1225269f 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -10,6 +10,7 @@
#include "common/math_util.h"
#include "video_core/renderer_base.h"
#include "video_core/renderer_opengl/gl_resource_manager.h"
+#include "video_core/renderer_opengl/gl_shader_manager.h"
#include "video_core/renderer_opengl/gl_state.h"
namespace Core {
@@ -95,12 +96,16 @@ private:
// OpenGL object IDs
OGLBuffer vertex_buffer;
- OGLProgram shader;
+ OGLProgram vertex_program;
+ OGLProgram fragment_program;
OGLFramebuffer screenshot_framebuffer;
/// Display information for Switch screen
ScreenInfo screen_info;
+ /// Global dummy shader pipeline
+ GLShader::ProgramManager program_manager;
+
/// OpenGL framebuffer data
std::vector<u8> gl_framebuffer_data;