gl_shader_manager: Cleanup and consolidate uniform handling.

This commit is contained in:
bunnei 2018-04-07 23:45:09 -04:00
parent 35aca0bf1f
commit 51f37f5061
2 changed files with 24 additions and 26 deletions

View file

@ -10,8 +10,8 @@
namespace GLShader { namespace GLShader {
namespace Impl { namespace Impl {
void SetShaderUniformBlockBinding(GLuint shader, const char* name, UniformBindings binding, void SetShaderUniformBlockBinding(GLuint shader, const char* name,
size_t expected_size) { Maxwell3D::Regs::ShaderStage binding, size_t expected_size) {
GLuint ub_index = glGetUniformBlockIndex(shader, name); GLuint ub_index = glGetUniformBlockIndex(shader, name);
if (ub_index != GL_INVALID_INDEX) { if (ub_index != GL_INVALID_INDEX) {
GLint ub_size = 0; GLint ub_size = 0;
@ -24,7 +24,12 @@ void SetShaderUniformBlockBinding(GLuint shader, const char* name, UniformBindin
} }
void SetShaderUniformBlockBindings(GLuint shader) { void SetShaderUniformBlockBindings(GLuint shader) {
SetShaderUniformBlockBinding(shader, "vs_config", UniformBindings::VS, sizeof(VSUniformData)); SetShaderUniformBlockBinding(shader, "vs_config", Maxwell3D::Regs::ShaderStage::Vertex,
sizeof(MaxwellUniformData));
SetShaderUniformBlockBinding(shader, "gs_config", Maxwell3D::Regs::ShaderStage::Geometry,
sizeof(MaxwellUniformData));
SetShaderUniformBlockBinding(shader, "fs_config", Maxwell3D::Regs::ShaderStage::Fragment,
sizeof(MaxwellUniformData));
} }
void SetShaderSamplerBindings(GLuint shader) { void SetShaderSamplerBindings(GLuint shader) {
@ -40,7 +45,13 @@ void SetShaderSamplerBindings(GLuint shader) {
} // namespace Impl } // namespace Impl
void MaxwellUniformData::SetFromRegs() { void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage) {
const auto& memory_manager = Core::System().GetInstance().GPU().memory_manager;
for (unsigned index = 0; index < shader_stage.const_buffers.size(); ++index) {
const auto& const_buffer = shader_stage.const_buffers[index];
const VAddr vaddr = memory_manager->PhysicalToVirtualAddress(const_buffer.address);
Memory::ReadBlock(vaddr, const_buffers[index].data(), sizeof(ConstBuffer));
}
} }
} // namespace GLShader } // namespace GLShader

View file

@ -14,40 +14,27 @@
namespace GLShader { namespace GLShader {
using Tegra::Engines::Maxwell3D;
namespace Impl { namespace Impl {
void SetShaderUniformBlockBindings(GLuint shader); void SetShaderUniformBlockBindings(GLuint shader);
void SetShaderSamplerBindings(GLuint shader); void SetShaderSamplerBindings(GLuint shader);
} // namespace Impl } // namespace Impl
enum class UniformBindings : GLuint { Common, VS, GS, FS };
/// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned /// Uniform structure for the Uniform Buffer Object, all vectors must be 16-byte aligned
// NOTE: Always keep a vec4 at the end. The GL spec is not clear wether the alignment at // NOTE: Always keep a vec4 at the end. The GL spec is not clear wether the alignment at
// the end of a uniform block is included in UNIFORM_BLOCK_DATA_SIZE or not. // 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. // Not following that rule will cause problems on some AMD drivers.
struct MaxwellUniformData { struct MaxwellUniformData {
void SetFromRegs(); void SetFromRegs(const Maxwell3D::State::ShaderStageInfo& shader_stage);
using ConstBuffer = std::array<GLvec4, 4>; using ConstBuffer = std::array<GLvec4, 4>;
using Regs = Tegra::Engines::Maxwell3D::Regs; alignas(16) std::array<ConstBuffer, Maxwell3D::Regs::MaxConstBuffers> const_buffers;
alignas(16) std::array<ConstBuffer, Regs::MaxConstBuffers> const_buffers;
}; };
static_assert(sizeof(MaxwellUniformData) == 1024, "MaxwellUniformData structure size is incorrect");
static_assert(sizeof(MaxwellUniformData) < 16384, static_assert(sizeof(MaxwellUniformData) < 16384,
"MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec");
struct VSUniformData {
MaxwellUniformData uniforms;
};
static_assert(sizeof(VSUniformData) < 16384,
"VSUniformData structure must be less than 16kb as per the OpenGL spec");
struct FSUniformData {
MaxwellUniformData uniforms;
};
static_assert(sizeof(FSUniformData) < 16384,
"VSUniformData structure must be less than 16kb as per the OpenGL spec");
class OGLShaderStage { class OGLShaderStage {
public: public:
OGLShaderStage() = default; OGLShaderStage() = default;
@ -113,14 +100,14 @@ public:
current.vs = vertex_shaders.Get(config, setup); current.vs = vertex_shaders.Get(config, setup);
} }
void UseTrivialGeometryShader() {
current.gs = 0;
}
void UseProgrammableFragmentShader(const MaxwellFSConfig& config, const ShaderSetup setup) { void UseProgrammableFragmentShader(const MaxwellFSConfig& config, const ShaderSetup setup) {
current.fs = fragment_shaders.Get(config, setup); current.fs = fragment_shaders.Get(config, setup);
} }
void UseTrivialGeometryShader() {
current.gs = 0;
}
void ApplyTo(OpenGLState& state) { void ApplyTo(OpenGLState& state) {
// Workaround for AMD bug // Workaround for AMD bug
glUseProgramStages(pipeline.handle, glUseProgramStages(pipeline.handle,