2018-04-07 11:12:38 +02:00
|
|
|
// Copyright 2018 yuzu Emulator Project
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <glad/glad.h>
|
2018-08-23 23:30:27 +02:00
|
|
|
|
2018-04-07 11:12:38 +02:00
|
|
|
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
|
|
|
#include "video_core/renderer_opengl/maxwell_to_gl.h"
|
|
|
|
|
2018-08-21 10:18:27 +02:00
|
|
|
namespace OpenGL::GLShader {
|
2018-04-07 11:12:38 +02:00
|
|
|
|
2018-04-15 00:50:06 +02:00
|
|
|
/// Number of OpenGL texture samplers that can be used in the fragment shader
|
|
|
|
static constexpr size_t NumTextureSamplers = 32;
|
|
|
|
|
2018-04-08 05:45:09 +02:00
|
|
|
using Tegra::Engines::Maxwell3D;
|
|
|
|
|
2018-04-07 11:12:38 +02:00
|
|
|
/// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned
|
2018-08-12 02:21:31 +02:00
|
|
|
// NOTE: Always keep a vec4 at the end. The GL spec is not clear whether the alignment at
|
2018-04-07 11:12:38 +02:00
|
|
|
// the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not.
|
|
|
|
// Not following that rule will cause problems on some AMD drivers.
|
|
|
|
struct MaxwellUniformData {
|
2018-04-08 05:45:09 +02:00
|
|
|
void SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage);
|
2018-04-18 22:42:40 +02:00
|
|
|
alignas(16) GLvec4 viewport_flip;
|
2018-08-12 02:21:31 +02:00
|
|
|
alignas(16) GLuvec4 instance_id;
|
2018-04-07 11:12:38 +02:00
|
|
|
};
|
2018-08-12 02:21:31 +02:00
|
|
|
static_assert(sizeof(MaxwellUniformData) == 32, "MaxwellUniformData structure size is incorrect");
|
2018-04-07 11:12:38 +02:00
|
|
|
static_assert(sizeof(MaxwellUniformData) < 16384,
|
|
|
|
"MaxwellUniformData structure must be less than 16kb as per the OpenGL spec");
|
|
|
|
|
|
|
|
class ProgramManager {
|
|
|
|
public:
|
|
|
|
ProgramManager() {
|
|
|
|
pipeline.Create();
|
|
|
|
}
|
|
|
|
|
2018-08-23 23:30:27 +02:00
|
|
|
void UseProgrammableVertexShader(GLuint program) {
|
|
|
|
vs = program;
|
2018-04-07 11:12:38 +02:00
|
|
|
}
|
|
|
|
|
2018-08-23 23:30:27 +02:00
|
|
|
void UseProgrammableFragmentShader(GLuint program) {
|
|
|
|
fs = program;
|
2018-04-15 21:14:57 +02:00
|
|
|
}
|
|
|
|
|
2018-04-08 05:45:09 +02:00
|
|
|
void UseTrivialGeometryShader() {
|
2018-08-23 23:30:27 +02:00
|
|
|
gs = 0;
|
2018-04-08 05:45:09 +02:00
|
|
|
}
|
|
|
|
|
2018-04-07 11:12:38 +02:00
|
|
|
void ApplyTo(OpenGLState& state) {
|
|
|
|
// Workaround for AMD bug
|
|
|
|
glUseProgramStages(pipeline.handle,
|
|
|
|
GL_VERTEX_SHADER_BIT | GL_GEOMETRY_SHADER_BIT | GL_FRAGMENT_SHADER_BIT,
|
|
|
|
0);
|
|
|
|
|
2018-08-23 23:30:27 +02:00
|
|
|
glUseProgramStages(pipeline.handle, GL_VERTEX_SHADER_BIT, vs);
|
|
|
|
glUseProgramStages(pipeline.handle, GL_GEOMETRY_SHADER_BIT, gs);
|
|
|
|
glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, fs);
|
2018-04-07 11:12:38 +02:00
|
|
|
state.draw.shader_program = 0;
|
|
|
|
state.draw.program_pipeline = pipeline.handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
OGLPipeline pipeline;
|
2018-08-23 23:30:27 +02:00
|
|
|
GLuint vs{}, fs{}, gs{};
|
2018-04-07 11:12:38 +02:00
|
|
|
};
|
|
|
|
|
2018-08-21 10:18:27 +02:00
|
|
|
} // namespace OpenGL::GLShader
|