Skip to content

Commit 66098ce

Browse files
authored
Merge pull request #1690 from EdvinLndh/uniform_syntax_change
Update syntax of GlUniformBuffer to match that of GlUniformInput #1683
2 parents 380d2e9 + de212cb commit 66098ce

File tree

10 files changed

+190
-127
lines changed

10 files changed

+190
-127
lines changed

copying.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ _the openage authors_ are:
154154
| Haoyang Bi | AyiStar | ayistar à outlook dawt com |
155155
| Michael Seibt | RoboSchmied | github à roboschmie dawt de |
156156
| Nikhil Ghosh | NikhilGhosh75 | nghosh606 à gmail dawt com |
157+
| Edvin Lindholm | EdvinLndh | edvinlndh à gmail dawt com |
157158

158159
If you're a first-time committer, add yourself to the above list. This is not
159160
just for legal reasons, but also to keep an overview of all those nicknames.

libopenage/renderer/opengl/renderer.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,22 +86,21 @@ std::shared_ptr<RenderTarget> GlRenderer::get_display_target() {
8686

8787
std::shared_ptr<UniformBuffer> GlRenderer::add_uniform_buffer(resources::UniformBufferInfo const &info) {
8888
auto inputs = info.get_inputs();
89-
std::unordered_map<std::string, GlInBlockUniform> uniforms{};
89+
std::vector<GlInBlockUniform> uniforms{};
9090
size_t offset = 0;
9191
for (auto const &input : inputs) {
9292
auto type = GL_UBO_INPUT_TYPE.get(input.type);
9393
auto size = resources::UniformBufferInfo::get_size(input, info.get_layout());
9494

9595
// align offset to the size of the type
9696
offset += offset % size;
97-
98-
uniforms.emplace(
99-
std::make_pair(input.name,
100-
GlInBlockUniform{type,
101-
offset,
102-
resources::UniformBufferInfo::get_size(input, info.get_layout()),
103-
resources::UniformBufferInfo::get_stride_size(input.type, info.get_layout()),
104-
input.count}));
97+
uniforms.push_back(
98+
GlInBlockUniform{type,
99+
offset,
100+
resources::UniformBufferInfo::get_size(input, info.get_layout()),
101+
resources::UniformBufferInfo::get_stride_size(input.type, info.get_layout()),
102+
input.count,
103+
input.name});
105104

106105
offset += size;
107106
}

libopenage/renderer/opengl/shader_data.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <optional>
66
#include <string>
77
#include <unordered_map>
8+
#include <vector>
89

910
#include <epoxy/gl.h>
1011

@@ -61,6 +62,11 @@ struct GlInBlockUniform {
6162
* Only relevant for arrays. The number of elements in the array.
6263
*/
6364
size_t count;
65+
66+
/**
67+
* Name of the block uniform.
68+
*/
69+
std::string name;
6470
};
6571

6672
/**
@@ -78,7 +84,7 @@ struct GlUniformBlock {
7884
/**
7985
* Maps uniform names within this block to their descriptions.
8086
*/
81-
std::unordered_map<std::string, GlInBlockUniform> uniforms;
87+
std::vector<GlInBlockUniform> uniforms;
8288

8389
/**
8490
* The binding point assigned to this block.

libopenage/renderer/opengl/shader_program.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ GlShaderProgram::GlShaderProgram(const std::shared_ptr<GlContext> &context,
125125
std::vector<GLint> uniform_indices(val);
126126
glGetActiveUniformBlockiv(handle, i_unif_block, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, uniform_indices.data());
127127

128-
std::unordered_map<std::string, GlInBlockUniform> uniforms;
128+
std::vector<GlInBlockUniform> uniforms;
129129
for (GLuint const i_unif : uniform_indices) {
130130
in_block_unifs.insert(i_unif);
131131

@@ -152,14 +152,14 @@ GlShaderProgram::GlShaderProgram(const std::shared_ptr<GlContext> &context,
152152
// We do not need to handle sampler types here like in the uniform loop below,
153153
// because named blocks cannot contain samplers.
154154

155-
uniforms.insert(std::make_pair(
156-
name.data(),
155+
uniforms.push_back(
157156
GlInBlockUniform{
158157
type,
159158
size_t(offset),
160159
size_t(count) * GL_UNIFORM_TYPE_SIZE.get(type),
161160
size_t(stride),
162-
size_t(count)}));
161+
size_t(count),
162+
std::string(name.data())});
163163
}
164164

165165
// ENSURE(block_binding < caps.max_uniform_buffer_bindings,
@@ -257,10 +257,10 @@ GlShaderProgram::GlShaderProgram(const std::shared_ptr<GlContext> &context,
257257
for (auto const &pair : this->uniform_blocks) {
258258
log::log(MSG(dbg) << "(" << pair.second.index << ") " << pair.first
259259
<< " (size: " << pair.second.data_size << ") {");
260-
for (auto const &unif_pair : pair.second.uniforms) {
261-
log::log(MSG(dbg) << "\t+" << unif_pair.second.offset
262-
<< " " << unif_pair.first << ": "
263-
<< GLSL_TYPE_NAME.get(unif_pair.second.type));
260+
for (auto const &unif : pair.second.uniforms) {
261+
log::log(MSG(dbg) << "\t+" << unif.offset
262+
<< " " << unif.name << ": "
263+
<< GLSL_TYPE_NAME.get(unif.type));
264264
}
265265
log::log(MSG(dbg) << "}");
266266
}
@@ -478,9 +478,9 @@ void GlShaderProgram::bind_uniform_buffer(const char *block_name, std::shared_pt
478478
auto &block = this->uniform_blocks[block_name];
479479

480480
// Check if the uniform buffer matches the block definition
481-
for (auto const &pair : block.uniforms) {
482-
ENSURE(gl_buffer->has_uniform(pair.first.c_str()),
483-
"Uniform buffer does not contain uniform '" << pair.first << "' required by block " << block_name);
481+
for (auto const &unif : block.uniforms) {
482+
ENSURE(gl_buffer->has_uniform(unif.name.c_str()),
483+
"Uniform buffer does not contain uniform '" << unif.name << "' required by block " << block_name);
484484
}
485485

486486
block.binding_point = gl_buffer->get_binding_point();

libopenage/renderer/opengl/uniform_buffer.cpp

Lines changed: 59 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ namespace openage::renderer::opengl {
1616

1717
GlUniformBuffer::GlUniformBuffer(const std::shared_ptr<GlContext> &context,
1818
size_t size,
19-
std::unordered_map<std::string, GlInBlockUniform> uniforms,
19+
std::vector<GlInBlockUniform> uniforms,
2020
GLuint binding_point,
2121
GLenum usage) :
2222
GlSimpleObject(context,
@@ -33,6 +33,12 @@ GlUniformBuffer::GlUniformBuffer(const std::shared_ptr<GlContext> &context,
3333
this->bind();
3434
glBufferData(GL_UNIFORM_BUFFER, this->data_size, NULL, usage);
3535

36+
uniform_id_t unif_id = 0;
37+
for (auto &uniform : uniforms) {
38+
this->uniforms_by_name.insert(std::make_pair(uniform.name, unif_id));
39+
unif_id += 1;
40+
}
41+
3642
glBindBufferRange(GL_UNIFORM_BUFFER, this->binding_point, *this->handle, 0, this->data_size);
3743

3844
log::log(MSG(dbg) << "Created OpenGL uniform buffer (size: "
@@ -51,23 +57,35 @@ void GlUniformBuffer::set_binding_point(GLuint binding_point) {
5157

5258
void GlUniformBuffer::update_uniforms(std::shared_ptr<UniformBufferInput> const &unif_in) {
5359
auto glunif_in = std::dynamic_pointer_cast<GlUniformBufferInput>(unif_in);
54-
ENSURE(glunif_in->get_buffer() == this->shared_from_this(), "Uniform input passed to different buffer than it was created with.");
60+
ENSURE(glunif_in->get_buffer().get() == this, "Uniform input passed to different buffer than it was created with.");
5561

5662
this->bind();
5763

64+
const auto &update_offs = glunif_in->update_offs;
65+
const auto &used_uniforms = glunif_in->used_uniforms;
66+
const auto &uniforms = this->uniforms;
5867
uint8_t const *data = glunif_in->update_data.data();
59-
for (auto const &pair : glunif_in->update_offs) {
60-
uint8_t const *ptr = data + pair.second;
61-
auto unif_def = this->uniforms[pair.first];
62-
auto loc = unif_def.offset;
63-
auto size = unif_def.size;
68+
69+
size_t unif_count = used_uniforms.size();
70+
for (size_t i = 0; i < unif_count; ++i) {
71+
uniform_id_t unif_id = used_uniforms[i];
72+
auto offset = update_offs[unif_id];
73+
74+
uint8_t const *ptr = data + offset.offset;
75+
auto &unif = uniforms[unif_id];
76+
auto loc = unif.offset;
77+
auto size = unif.size;
6478

6579
glBufferSubData(GL_UNIFORM_BUFFER, loc, size, ptr);
6680
}
6781
}
6882

69-
bool GlUniformBuffer::has_uniform(const char *unif) {
70-
return this->uniforms.count(unif) != 0;
83+
const std::vector<GlInBlockUniform> &GlUniformBuffer::get_uniforms() const {
84+
return this->uniforms;
85+
}
86+
87+
bool GlUniformBuffer::has_uniform(const char *name) {
88+
return this->uniforms_by_name.contains(name);
7189
}
7290

7391
void GlUniformBuffer::bind() const {
@@ -80,14 +98,14 @@ std::shared_ptr<UniformBufferInput> GlUniformBuffer::new_unif_in() {
8098
return in;
8199
}
82100

83-
void GlUniformBuffer::set_unif(std::shared_ptr<UniformBufferInput> const &in, const char *unif, void const *val, GLenum type) {
84-
auto unif_in = std::dynamic_pointer_cast<GlUniformBufferInput>(in);
101+
void GlUniformBuffer::set_unif(UniformBufferInput &in, const char *unif, void const *val, GLenum type) {
102+
auto &unif_in = dynamic_cast<GlUniformBufferInput &>(in);
85103

86-
auto uniform = this->uniforms.find(unif);
87-
ENSURE(uniform != std::end(this->uniforms),
88-
"Tried to set uniform " << unif << " that does not exist in the shader program.");
104+
auto unif_id = this->uniforms_by_name.find(unif)->second;
105+
ENSURE(unif_id < this->uniforms.size(),
106+
"Tried to set uniform with invalid ID " << unif_id);
89107

90-
auto const &unif_data = uniform->second;
108+
auto const &unif_data = this->uniforms[unif_id];
91109

92110
ENSURE(type == unif_data.type,
93111
"Tried to set uniform " << unif << " to a value of the wrong type.");
@@ -96,83 +114,80 @@ void GlUniformBuffer::set_unif(std::shared_ptr<UniformBufferInput> const &in, co
96114
ENSURE(size == unif_data.size,
97115
"Tried to set uniform " << unif << " to a value of the wrong size.");
98116

99-
auto update_off = unif_in->update_offs.find(unif);
100-
if (update_off != std::end(unif_in->update_offs)) [[likely]] { // always used after the uniform value is written once
101-
// already wrote to this uniform since last upload
102-
size_t off = update_off->second;
103-
memcpy(unif_in->update_data.data() + off, val, size);
104-
}
105-
else {
106-
// first time writing to this uniform since last upload, so
107-
// extend the buffer before storing the uniform value
108-
size_t prev_size = unif_in->update_data.size();
109-
unif_in->update_data.resize(prev_size + size);
110-
memcpy(unif_in->update_data.data() + prev_size, val, size);
111-
unif_in->update_offs.emplace(unif, prev_size);
117+
auto &update_off = unif_in.update_offs[unif_id];
118+
auto offset = update_off.offset;
119+
memcpy(unif_in.update_data.data() + offset, val, size);
120+
if (not update_off.used) [[unlikely]] { // only true if the uniform value was not set before
121+
auto lower_bound = std::lower_bound(
122+
std::begin(unif_in.used_uniforms),
123+
std::end(unif_in.used_uniforms),
124+
unif_id);
125+
unif_in.used_uniforms.insert(lower_bound, unif_id);
126+
update_off.used = true;
112127
}
113128
}
114129

115-
void GlUniformBuffer::set_i32(std::shared_ptr<UniformBufferInput> const &in, const char *unif, int32_t val) {
130+
void GlUniformBuffer::set_i32(UniformBufferInput &in, const char *unif, int32_t val) {
116131
this->set_unif(in, unif, &val, GL_INT);
117132
}
118133

119-
void GlUniformBuffer::set_u32(std::shared_ptr<UniformBufferInput> const &in, const char *unif, uint32_t val) {
134+
void GlUniformBuffer::set_u32(UniformBufferInput &in, const char *unif, uint32_t val) {
120135
this->set_unif(in, unif, &val, GL_UNSIGNED_INT);
121136
}
122137

123-
void GlUniformBuffer::set_f32(std::shared_ptr<UniformBufferInput> const &in, const char *unif, float val) {
138+
void GlUniformBuffer::set_f32(UniformBufferInput &in, const char *unif, float val) {
124139
this->set_unif(in, unif, &val, GL_FLOAT);
125140
}
126141

127-
void GlUniformBuffer::set_f64(std::shared_ptr<UniformBufferInput> const &in, const char *unif, double val) {
142+
void GlUniformBuffer::set_f64(UniformBufferInput &in, const char *unif, double val) {
128143
this->set_unif(in, unif, &val, GL_DOUBLE);
129144
}
130145

131-
void GlUniformBuffer::set_bool(std::shared_ptr<UniformBufferInput> const &in, const char *unif, bool val) {
146+
void GlUniformBuffer::set_bool(UniformBufferInput &in, const char *unif, bool val) {
132147
this->set_unif(in, unif, &val, GL_BOOL);
133148
}
134149

135-
void GlUniformBuffer::set_v2f32(std::shared_ptr<UniformBufferInput> const &in, const char *unif, Eigen::Vector2f const &val) {
150+
void GlUniformBuffer::set_v2f32(UniformBufferInput &in, const char *unif, Eigen::Vector2f const &val) {
136151
this->set_unif(in, unif, val.data(), GL_FLOAT_VEC2);
137152
}
138153

139-
void GlUniformBuffer::set_v3f32(std::shared_ptr<UniformBufferInput> const &in, const char *unif, Eigen::Vector3f const &val) {
154+
void GlUniformBuffer::set_v3f32(UniformBufferInput &in, const char *unif, Eigen::Vector3f const &val) {
140155
this->set_unif(in, unif, val.data(), GL_FLOAT_VEC3);
141156
}
142157

143-
void GlUniformBuffer::set_v4f32(std::shared_ptr<UniformBufferInput> const &in, const char *unif, Eigen::Vector4f const &val) {
158+
void GlUniformBuffer::set_v4f32(UniformBufferInput &in, const char *unif, Eigen::Vector4f const &val) {
144159
this->set_unif(in, unif, val.data(), GL_FLOAT_VEC4);
145160
}
146161

147-
void GlUniformBuffer::set_v2i32(std::shared_ptr<UniformBufferInput> const &in, const char *unif, Eigen::Vector2i const &val) {
162+
void GlUniformBuffer::set_v2i32(UniformBufferInput &in, const char *unif, Eigen::Vector2i const &val) {
148163
this->set_unif(in, unif, val.data(), GL_INT_VEC2);
149164
}
150165

151-
void GlUniformBuffer::set_v3i32(std::shared_ptr<UniformBufferInput> const &in, const char *unif, Eigen::Vector3i const &val) {
166+
void GlUniformBuffer::set_v3i32(UniformBufferInput &in, const char *unif, Eigen::Vector3i const &val) {
152167
this->set_unif(in, unif, val.data(), GL_INT_VEC3);
153168
}
154169

155-
void GlUniformBuffer::set_v4i32(std::shared_ptr<UniformBufferInput> const &in, const char *unif, Eigen::Vector4i const &val) {
170+
void GlUniformBuffer::set_v4i32(UniformBufferInput &in, const char *unif, Eigen::Vector4i const &val) {
156171
this->set_unif(in, unif, val.data(), GL_INT_VEC4);
157172
}
158173

159-
void GlUniformBuffer::set_v2ui32(std::shared_ptr<UniformBufferInput> const &in, const char *unif, Eigen::Vector2<uint32_t> const &val) {
174+
void GlUniformBuffer::set_v2ui32(UniformBufferInput &in, const char *unif, Eigen::Vector2<uint32_t> const &val) {
160175
this->set_unif(in, unif, val.data(), GL_UNSIGNED_INT_VEC2);
161176
}
162177

163-
void GlUniformBuffer::set_v3ui32(std::shared_ptr<UniformBufferInput> const &in, const char *unif, Eigen::Vector3<uint32_t> const &val) {
178+
void GlUniformBuffer::set_v3ui32(UniformBufferInput &in, const char *unif, Eigen::Vector3<uint32_t> const &val) {
164179
this->set_unif(in, unif, val.data(), GL_UNSIGNED_INT_VEC3);
165180
}
166181

167-
void GlUniformBuffer::set_v4ui32(std::shared_ptr<UniformBufferInput> const &in, const char *unif, Eigen::Vector4<uint32_t> const &val) {
182+
void GlUniformBuffer::set_v4ui32(UniformBufferInput &in, const char *unif, Eigen::Vector4<uint32_t> const &val) {
168183
this->set_unif(in, unif, val.data(), GL_UNSIGNED_INT_VEC4);
169184
}
170185

171-
void GlUniformBuffer::set_m4f32(std::shared_ptr<UniformBufferInput> const &in, const char *unif, Eigen::Matrix4f const &val) {
186+
void GlUniformBuffer::set_m4f32(UniformBufferInput &in, const char *unif, Eigen::Matrix4f const &val) {
172187
this->set_unif(in, unif, val.data(), GL_FLOAT_MAT4);
173188
}
174189

175-
void GlUniformBuffer::set_tex(std::shared_ptr<UniformBufferInput> const &in, const char *unif, std::shared_ptr<Texture2d> const &val) {
190+
void GlUniformBuffer::set_tex(UniformBufferInput &in, const char *unif, std::shared_ptr<Texture2d> const &val) {
176191
auto tex = std::dynamic_pointer_cast<GlTexture2d>(val);
177192
GLuint handle = tex->get_handle();
178193
this->set_unif(in, unif, &handle, GL_SAMPLER_2D);

0 commit comments

Comments
 (0)