Skip to content

Commit

Permalink
renderer: Refer to uniforms by ID in level 1 renderer.
Browse files Browse the repository at this point in the history
  • Loading branch information
heinezen committed Aug 27, 2023
1 parent 3545ff7 commit 197fe32
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 21 deletions.
3 changes: 3 additions & 0 deletions libopenage/renderer/opengl/shader_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace openage::renderer::opengl {
* Represents a uniform in the default (shader) block, i.e. not within a named block.
*/
struct GlUniform {
/**
* Data type of the uniform for setting with glUniform.
*/
GLenum type;

/**
Expand Down
32 changes: 20 additions & 12 deletions libopenage/renderer/opengl/shader_program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,17 +201,21 @@ GlShaderProgram::GlShaderProgram(const std::shared_ptr<GlContext> &context,
GLuint loc = glGetUniformLocation(handle, name.data());

this->uniforms.insert(std::make_pair(
name.data(),
i_unif,
GlUniform{
type,
loc}));

this->uniforms_by_name.insert(std::make_pair(
name.data(),
i_unif));

if (type == GL_SAMPLER_2D) {
ENSURE(tex_unit < caps.max_texture_slots,
"Tried to create an OpenGL shader that uses more texture sampler uniforms "
<< "than there are texture unit slots (" << caps.max_texture_slots << " available).");

this->texunits_per_unifs.insert(std::make_pair(name.data(), tex_unit));
this->texunits_per_unifs.insert(std::make_pair(i_unif, tex_unit));

tex_unit += 1;
}
Expand Down Expand Up @@ -421,8 +425,12 @@ std::shared_ptr<UniformInput> GlShaderProgram::new_unif_in() {
return in;
}

uniform_id_t GlShaderProgram::get_uniform_id(const char *name) {
return this->uniforms_by_name.at(name);
}

bool GlShaderProgram::has_uniform(const char *name) {
return this->uniforms.count(name) == 1;
return this->uniforms_by_name.contains(name);
}

void GlShaderProgram::bind_uniform_buffer(const char *block_name, std::shared_ptr<UniformBuffer> const &buffer) {
Expand All @@ -441,18 +449,18 @@ void GlShaderProgram::bind_uniform_buffer(const char *block_name, std::shared_pt
void GlShaderProgram::set_unif(std::shared_ptr<UniformInput> const &in, const char *unif, void const *val, GLenum type) {
auto unif_in = std::dynamic_pointer_cast<GlUniformInput>(in);

auto uniform = this->uniforms.find(unif);
ENSURE(uniform != std::end(this->uniforms),
"Tried to set uniform " << unif << " that does not exist in the shader program.");
auto uniform_id = this->uniforms_by_name.find(unif);
ENSURE(uniform_id != std::end(this->uniforms_by_name),
"Tried to set uniform '" << unif << "' that does not exist in the shader program.");

auto const &unif_data = uniform->second;
auto const &unif_info = this->uniforms.at(uniform_id->second);

ENSURE(type == unif_data.type,
"Tried to set uniform " << unif << " to a value of the wrong type.");
ENSURE(type == unif_info.type,
"Tried to set uniform '" << unif << "' to a value of the wrong type.");

size_t size = GL_SHADER_TYPE_SIZE.get(unif_data.type);
size_t size = GL_SHADER_TYPE_SIZE.get(unif_info.type);

auto update_off = unif_in->update_offs.find(unif);
auto update_off = unif_in->update_offs.find(uniform_id->second);
if (update_off != std::end(unif_in->update_offs)) [[likely]] { // always used after the uniform value is written once
// already wrote to this uniform since last upload
size_t off = update_off->second;
Expand All @@ -464,7 +472,7 @@ void GlShaderProgram::set_unif(std::shared_ptr<UniformInput> const &in, const ch
size_t prev_size = unif_in->update_data.size();
unif_in->update_data.resize(prev_size + size);
memcpy(unif_in->update_data.data() + prev_size, val, size);
unif_in->update_offs.emplace(unif, prev_size);
unif_in->update_offs.emplace(uniform_id->second, prev_size);
}
}

Expand Down
14 changes: 10 additions & 4 deletions libopenage/renderer/opengl/shader_program.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ class GlShaderProgram final : public ShaderProgram
*/
const GlUniformBlock &get_uniform_block(const char *block_name) const;

bool has_uniform(const char *) override;
uniform_id_t get_uniform_id(const char *name) override;

bool has_uniform(const char *name) override;

/**
* Binds a uniform block in the shader program to the same binding point as
Expand Down Expand Up @@ -100,9 +102,12 @@ class GlShaderProgram final : public ShaderProgram
private:
void set_unif(std::shared_ptr<UniformInput> const &, const char *, void const *, GLenum);

/// Maps uniform names to their descriptions. Contains only
/// Maps uniform IDs to their descriptions. Contains only
/// uniforms in the default block, i.e. not within named blocks.
std::unordered_map<std::string, GlUniform> uniforms;
std::unordered_map<uniform_id_t, GlUniform> uniforms;

/// Maps uniform names to their ID.
std::unordered_map<std::string, uniform_id_t> uniforms_by_name;

/// Maps uniform block names to their descriptions.
std::unordered_map<std::string, GlUniformBlock> uniform_blocks;
Expand All @@ -111,7 +116,8 @@ class GlShaderProgram final : public ShaderProgram
std::unordered_map<std::string, GlVertexAttrib> attribs;

/// Maps sampler uniform names to their assigned texture units.
std::unordered_map<std::string, GLuint> texunits_per_unifs;
std::unordered_map<uniform_id_t, GLuint> texunits_per_unifs;

/// Maps texture units to the texture handles that are currently bound to them.
std::unordered_map<GLuint, GLuint> textures_per_texunits;

Expand Down
5 changes: 2 additions & 3 deletions libopenage/renderer/opengl/uniform_input.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

namespace openage {
namespace renderer {

class ShaderProgram;
class UniformBuffer;

Expand All @@ -30,11 +29,11 @@ class GlUniformInput final : public UniformInput {
* We store uniform updates lazily. They are only actually uploaded to GPU
* when a draw call is made.
*
* \p update_offs maps the uniform names to where their
* \p update_offs maps the uniform IDs to where their
* value is in \p update_data in terms of a byte-wise offset. This is only a partial
* valuation, so not all uniforms have to be present here.
*/
std::unordered_map<std::string, size_t> update_offs;
std::unordered_map<uint32_t, size_t> update_offs;

/**
* Buffer containing untyped uniform update data.
Expand Down
15 changes: 13 additions & 2 deletions libopenage/renderer/shader_program.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,31 @@ namespace renderer {
class Texture2d;
class UniformBuffer;

using uniform_id_t = uint32_t;

class ShaderProgram : public std::enable_shared_from_this<ShaderProgram> {
friend UniformInput;

public:
virtual ~ShaderProgram() = default;

/**
* Get the ID of a uniform variable in the shader program.
*
* @param unif Name of the uniform.
*
* @return ID of the uniform in the shader.
*/
virtual uniform_id_t get_uniform_id(const char *name) = 0;

/**
* Check whether the shader program contains a uniform variable with the given ID.
*
* @param unif ID of the uniform.
* @param unif Name of the uniform.
*
* @return true if the shader program contains the uniform, false otherwise.
*/
virtual bool has_uniform(const char *unif) = 0;
virtual bool has_uniform(const char *name) = 0;

/**
* Binds a uniform block in the shader program to the same binding point as
Expand Down

0 comments on commit 197fe32

Please sign in to comment.