mirror of https://github.com/auygun/kaliber.git
Hash uniform name strings
This commit is contained in:
parent
e509588f61
commit
c5171ffc03
|
@ -6,17 +6,15 @@
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
// Compile-time string hashing function.
|
|
||||||
template <size_t N>
|
template <size_t N>
|
||||||
constexpr inline size_t Hash(const char (&str)[N], size_t Len = N - 1) {
|
constexpr inline size_t KR2Hash(const char (&str)[N], size_t Len = N - 1) {
|
||||||
size_t hash_value = 0;
|
size_t hash_value = 0;
|
||||||
for (int i = 0; str[i] != '\0'; ++i)
|
for (int i = 0; str[i] != '\0'; ++i)
|
||||||
hash_value = str[i] + 31 * hash_value;
|
hash_value = str[i] + 31 * hash_value;
|
||||||
return hash_value;
|
return hash_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The same hashing function for run-time.
|
inline size_t KR2Hash(const std::string& str) {
|
||||||
inline size_t Hash(const std::string& str) {
|
|
||||||
size_t hash_value = 0;
|
size_t hash_value = 0;
|
||||||
for (std::string::value_type c : str)
|
for (std::string::value_type c : str)
|
||||||
hash_value = c + 31 * hash_value;
|
hash_value = c + 31 * hash_value;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
|
#include "base/hash.h"
|
||||||
#include "base/log.h"
|
#include "base/log.h"
|
||||||
#include "base/vecmath.h"
|
#include "base/vecmath.h"
|
||||||
#include "engine/asset/image.h"
|
#include "engine/asset/image.h"
|
||||||
|
@ -615,10 +616,11 @@ bool RendererOpenGL::BindAttributeLocation(GLuint id,
|
||||||
GLint RendererOpenGL::GetUniformLocation(
|
GLint RendererOpenGL::GetUniformLocation(
|
||||||
GLuint id,
|
GLuint id,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
std::vector<std::pair<std::string, GLuint>>& uniforms) {
|
std::vector<std::pair<size_t, GLuint>>& uniforms) {
|
||||||
// Check if we've encountered this uniform before.
|
// Check if we've encountered this uniform before.
|
||||||
|
auto hash = KR2Hash(name);
|
||||||
auto it = std::find_if(uniforms.begin(), uniforms.end(),
|
auto it = std::find_if(uniforms.begin(), uniforms.end(),
|
||||||
[&](auto& r) { return name == std::get<0>(r); });
|
[&](auto& r) { return hash == std::get<0>(r); });
|
||||||
GLint index;
|
GLint index;
|
||||||
if (it != uniforms.end()) {
|
if (it != uniforms.end()) {
|
||||||
// Yes, we already have the mapping.
|
// Yes, we already have the mapping.
|
||||||
|
@ -626,11 +628,16 @@ GLint RendererOpenGL::GetUniformLocation(
|
||||||
} else {
|
} else {
|
||||||
// No, ask the driver for the mapping and save it.
|
// No, ask the driver for the mapping and save it.
|
||||||
index = glGetUniformLocation(id, name.c_str());
|
index = glGetUniformLocation(id, name.c_str());
|
||||||
if (index >= 0)
|
if (index >= 0) {
|
||||||
uniforms.emplace_back(std::make_pair(name, index));
|
DCHECK(std::find_if(uniforms.begin(), uniforms.end(),
|
||||||
else
|
[&](auto& r) { return hash == std::get<0>(r); }) ==
|
||||||
|
uniforms.end())
|
||||||
|
<< "Hash collision";
|
||||||
|
uniforms.emplace_back(std::make_pair(hash, index));
|
||||||
|
} else {
|
||||||
LOG(0) << "Cannot find uniform " << name.c_str() << " (shader: " << id
|
LOG(0) << "Cannot find uniform " << name.c_str() << " (shader: " << id
|
||||||
<< ")";
|
<< ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,10 @@ class RendererOpenGL final : public Renderer {
|
||||||
|
|
||||||
struct ShaderOpenGL {
|
struct ShaderOpenGL {
|
||||||
GLuint id = 0;
|
GLuint id = 0;
|
||||||
std::vector<std::pair<std::string, GLuint>> uniforms;
|
std::vector<std::pair<size_t, // Uniform name hash
|
||||||
|
GLuint // Uniform index
|
||||||
|
>>
|
||||||
|
uniforms;
|
||||||
bool enable_depth_test = false;
|
bool enable_depth_test = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -139,10 +142,9 @@ class RendererOpenGL final : public Renderer {
|
||||||
std::vector<GeometryOpenGL::Element>& vertex_layout);
|
std::vector<GeometryOpenGL::Element>& vertex_layout);
|
||||||
GLuint CreateShader(const char* source, GLenum type);
|
GLuint CreateShader(const char* source, GLenum type);
|
||||||
bool BindAttributeLocation(GLuint id, const VertexDescription& vd);
|
bool BindAttributeLocation(GLuint id, const VertexDescription& vd);
|
||||||
GLint GetUniformLocation(
|
GLint GetUniformLocation(GLuint id,
|
||||||
GLuint id,
|
const std::string& name,
|
||||||
const std::string& name,
|
std::vector<std::pair<size_t, GLuint>>& uniforms);
|
||||||
std::vector<std::pair<std::string, GLuint>>& uniforms);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace eng
|
} // namespace eng
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "base/hash.h"
|
||||||
#include "base/log.h"
|
#include "base/log.h"
|
||||||
#include "base/vecmath.h"
|
#include "base/vecmath.h"
|
||||||
#include "engine/asset/image.h"
|
#include "engine/asset/image.h"
|
||||||
|
@ -1876,12 +1877,12 @@ bool RendererVulkan::CreatePipelineLayout(
|
||||||
|
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
for (uint32_t j = 0; j < pconstants_vertex[0]->member_count; j++) {
|
for (uint32_t j = 0; j < pconstants_vertex[0]->member_count; j++) {
|
||||||
DCHECK(std::find_if(shader.variables.begin(), shader.variables.end(),
|
DCHECK(std::find_if(
|
||||||
[&](auto& r) {
|
shader.variables.begin(), shader.variables.end(),
|
||||||
return pconstants_vertex[0]->members[j].name ==
|
[hash = KR2Hash(pconstants_vertex[0]->members[j].name)](
|
||||||
std::get<0>(r);
|
auto& r) { return hash == std::get<0>(r); }) ==
|
||||||
}) == shader.variables.end())
|
shader.variables.end())
|
||||||
<< "Duplicate uniform name";
|
<< "Hash collision";
|
||||||
|
|
||||||
DLOG(0) << __func__
|
DLOG(0) << __func__
|
||||||
<< " name: " << pconstants_vertex[0]->members[j].name
|
<< " name: " << pconstants_vertex[0]->members[j].name
|
||||||
|
@ -1890,7 +1891,7 @@ bool RendererVulkan::CreatePipelineLayout(
|
||||||
<< pconstants_vertex[0]->members[j].padded_size;
|
<< pconstants_vertex[0]->members[j].padded_size;
|
||||||
|
|
||||||
shader.variables.emplace_back(
|
shader.variables.emplace_back(
|
||||||
std::make_tuple(pconstants_vertex[0]->members[j].name,
|
std::make_tuple(KR2Hash(pconstants_vertex[0]->members[j].name),
|
||||||
pconstants_vertex[0]->members[j].size, offset));
|
pconstants_vertex[0]->members[j].size, offset));
|
||||||
offset += pconstants_vertex[0]->members[j].padded_size;
|
offset += pconstants_vertex[0]->members[j].padded_size;
|
||||||
}
|
}
|
||||||
|
@ -2040,8 +2041,9 @@ template <typename T>
|
||||||
bool RendererVulkan::SetUniformInternal(ShaderVulkan& shader,
|
bool RendererVulkan::SetUniformInternal(ShaderVulkan& shader,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
T val) {
|
T val) {
|
||||||
|
auto hash = KR2Hash(name);
|
||||||
auto it = std::find_if(shader.variables.begin(), shader.variables.end(),
|
auto it = std::find_if(shader.variables.begin(), shader.variables.end(),
|
||||||
[&](auto& r) { return name == std::get<0>(r); });
|
[&](auto& r) { return hash == std::get<0>(r); });
|
||||||
if (it == shader.variables.end()) {
|
if (it == shader.variables.end()) {
|
||||||
DLOG(0) << "No variable found with name " << name;
|
DLOG(0) << "No variable found with name " << name;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -106,7 +106,11 @@ class RendererVulkan final : public Renderer {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ShaderVulkan {
|
struct ShaderVulkan {
|
||||||
std::vector<std::tuple<std::string, size_t, size_t>> variables;
|
std::vector<std::tuple<size_t, // Variable name hash
|
||||||
|
size_t, // Variable size
|
||||||
|
size_t // Push constant offset
|
||||||
|
>>
|
||||||
|
variables;
|
||||||
std::unique_ptr<char[]> push_constants;
|
std::unique_ptr<char[]> push_constants;
|
||||||
size_t push_constants_size = 0;
|
size_t push_constants_size = 0;
|
||||||
std::vector<std::string> sampler_uniform_names;
|
std::vector<std::string> sampler_uniform_names;
|
||||||
|
|
Loading…
Reference in New Issue