fixed Textures/Samplers potentially using incorrect registers

This commit is contained in:
Noel 2022-05-28 09:32:05 -07:00
parent 0628e0dce5
commit 410adbfe12
4 changed files with 69 additions and 125 deletions

View File

@ -257,12 +257,15 @@ namespace Blah
// The Shader type the Uniform is a part of // The Shader type the Uniform is a part of
ShaderType shader; ShaderType shader;
// Texture / Sampler register index, which shaders can manually assign
int register_index = 0;
// Some rendering APIs have uniform buffers. The `buffer_index` // Some rendering APIs have uniform buffers. The `buffer_index`
// specifies which buffer the uniform belongs to // specifies which buffer the uniform belongs to
int buffer_index; int buffer_index = 0;
// Array length of the Uniform (ex. a vec2[4] would be 4) // Array length of the Uniform (ex. a vec2[4] would be 4)
int array_length; int array_length = 0;
}; };
// Supported Vertex value types // Supported Vertex value types
@ -550,25 +553,25 @@ namespace Blah
void set_texture(const char* name, const TextureRef& texture, int array_index = 0); void set_texture(const char* name, const TextureRef& texture, int array_index = 0);
// Sets the texture // Sets the texture
void set_texture(int slot, const TextureRef& texture, int array_index = 0); void set_texture(int register_index, const TextureRef& texture);
// Gets the texture, or an empty reference if invalid // Gets the texture, or an empty reference if invalid
TextureRef get_texture(const char* name, int array_index = 0) const; TextureRef get_texture(const char* name, int array_index = 0) const;
// Gets the texture, or an empty reference if invalid // Gets the texture, or an empty reference if invalid
TextureRef get_texture(int slot, int array_index = 0) const; TextureRef get_texture(int register_index) const;
// Sets the sampler // Sets the sampler
void set_sampler(const char* name, const TextureSampler& sampler, int array_index = 0); void set_sampler(const char* name, const TextureSampler& sampler, int array_index = 0);
// Sets the sampler // Sets the sampler
void set_sampler(int slot, const TextureSampler& sampler, int array_index = 0); void set_sampler(int register_index, const TextureSampler& sampler);
// Gets the sampler // Gets the sampler
TextureSampler get_sampler(const char* name, int array_index = 0) const; TextureSampler get_sampler(const char* name, int array_index = 0) const;
// Gets the sampler // Gets the sampler
TextureSampler get_sampler(int slot, int array_index = 0) const; TextureSampler get_sampler(int register_index) const;
// Sets the value. `length` is the total number of floats to set // Sets the value. `length` is the total number of floats to set
// For example if the uniform is a float2[4], a total of 8 float values // For example if the uniform is a float2[4], a total of 8 float values

View File

@ -256,15 +256,15 @@ Material::Material(const ShaderRef& shader)
if (uniform.type == UniformType::Texture2D) if (uniform.type == UniformType::Texture2D)
{ {
for (int i = 0; i < uniform.array_length; i++) if (m_textures.size() < uniform.register_index + uniform.array_length)
m_textures.push_back(TextureRef()); m_textures.resize(uniform.register_index + uniform.array_length);
continue; continue;
} }
if (uniform.type == UniformType::Sampler2D) if (uniform.type == UniformType::Sampler2D)
{ {
for (int i = 0; i < uniform.array_length; i++) if (m_samplers.size() < uniform.register_index + uniform.array_length)
m_samplers.push_back(TextureSampler()); m_samplers.resize(uniform.register_index + uniform.array_length);
continue; continue;
} }
@ -302,7 +302,6 @@ void Material::set_texture(const char* name, const TextureRef& texture, int inde
{ {
BLAH_ASSERT(m_shader, "Material Shader is invalid"); BLAH_ASSERT(m_shader, "Material Shader is invalid");
int offset = 0;
for (auto& uniform : m_shader->uniforms()) for (auto& uniform : m_shader->uniforms())
{ {
if (uniform.type != UniformType::Texture2D) if (uniform.type != UniformType::Texture2D)
@ -310,92 +309,60 @@ void Material::set_texture(const char* name, const TextureRef& texture, int inde
if (strcmp(uniform.name, name) == 0) if (strcmp(uniform.name, name) == 0)
{ {
m_textures[offset + index] = texture; if (uniform.register_index + index < m_textures.size())
return; {
} m_textures[uniform.register_index + index] = texture;
return;
offset += uniform.array_length; }
if (offset + index >= m_textures.size())
break; break;
}
} }
Log::warn("No Texture Uniform '%s' at index [%i] exists", name, index); Log::warn("No Texture Uniform '%s' at index [%i] exists", name, index);
} }
void Material::set_texture(int slot, const TextureRef& texture, int index) void Material::set_texture(int register_index, const TextureRef& texture)
{ {
BLAH_ASSERT(m_shader, "Material Shader is invalid"); BLAH_ASSERT(m_shader, "Material Shader is invalid");
int s = 0; if (register_index >= m_textures.size())
int offset = 0;
for (auto& uniform : m_shader->uniforms())
{ {
if (uniform.type != UniformType::Texture2D) Log::warn("Texture Register index [%i] is out of bounds", register_index);
continue; return;
if (s == slot)
{
if (index > uniform.array_length)
break;
m_textures[offset + index] = texture;
break;
}
offset += uniform.array_length;
s++;
} }
m_textures[register_index] = texture;
} }
TextureRef Material::get_texture(const char* name, int index) const TextureRef Material::get_texture(const char* name, int index) const
{ {
BLAH_ASSERT(m_shader, "Material Shader is invalid"); BLAH_ASSERT(m_shader, "Material Shader is invalid");
int offset = 0;
for (auto& uniform : m_shader->uniforms()) for (auto& uniform : m_shader->uniforms())
{ {
if (uniform.type != UniformType::Texture2D) if (uniform.type != UniformType::Texture2D)
continue; continue;
if (strcmp(uniform.name, name) == 0) if (strcmp(uniform.name, name) == 0)
return m_textures[offset + index]; {
if (uniform.register_index + index < m_textures.size())
offset += uniform.array_length; return m_textures[uniform.register_index + index];
if (offset + index >= m_textures.size())
break; break;
}
} }
Log::warn("No Texture Uniform '%s' at index [%i] exists", name, index); Log::warn("No Texture Uniform '%s' at index [%i] exists", name, index);
return TextureRef(); return TextureRef();
} }
TextureRef Material::get_texture(int slot, int index) const TextureRef Material::get_texture(int register_index) const
{ {
BLAH_ASSERT(m_shader, "Material Shader is invalid"); BLAH_ASSERT(m_shader, "Material Shader is invalid");
int s = 0; if (register_index < m_textures.size())
int offset = 0; return m_textures[register_index];
for (auto& uniform : m_shader->uniforms())
{
if (uniform.type != UniformType::Texture2D)
continue;
if (s == slot) Log::warn("No Texture Uniform at register index [%i]", register_index);
{
if (index > uniform.array_length)
break;
return m_textures[offset + index];
}
offset += uniform.array_length;
if (offset + index >= m_textures.size())
break;
s++;
}
Log::warn("No Texture Uniform ['%i'] at index [%i] exists", slot, index);
return TextureRef(); return TextureRef();
} }
@ -403,7 +370,6 @@ void Material::set_sampler(const char* name, const TextureSampler& sampler, int
{ {
BLAH_ASSERT(m_shader, "Material Shader is invalid"); BLAH_ASSERT(m_shader, "Material Shader is invalid");
int offset = 0;
for (auto& uniform : m_shader->uniforms()) for (auto& uniform : m_shader->uniforms())
{ {
if (uniform.type != UniformType::Sampler2D) if (uniform.type != UniformType::Sampler2D)
@ -411,92 +377,60 @@ void Material::set_sampler(const char* name, const TextureSampler& sampler, int
if (strcmp(uniform.name, name) == 0) if (strcmp(uniform.name, name) == 0)
{ {
m_samplers[offset + index] = sampler; if (uniform.register_index + index < m_samplers.size())
return; {
} m_samplers[uniform.register_index + index] = sampler;
return;
offset += uniform.array_length; }
if (offset + index >= m_samplers.size())
break; break;
}
} }
Log::warn("No Sampler Uniform '%s' at index [%i] exists", name, index); Log::warn("No Texture Sampler Uniform '%s' at index [%i] exists", name, index);
} }
void Material::set_sampler(int slot, const TextureSampler& sampler, int index) void Material::set_sampler(int register_index, const TextureSampler& sampler)
{ {
BLAH_ASSERT(m_shader, "Material Shader is invalid"); BLAH_ASSERT(m_shader, "Material Shader is invalid");
int s = 0; if (register_index >= m_samplers.size())
int offset = 0;
for (auto& uniform : m_shader->uniforms())
{ {
if (uniform.type != UniformType::Sampler2D) Log::warn("Texture Sampler Register index [%i] is out of bounds", register_index);
continue; return;
if (s == slot)
{
if (index > uniform.array_length)
break;
m_samplers[offset + index] = sampler;
break;
}
offset += uniform.array_length;
s++;
} }
m_samplers[register_index] = sampler;
} }
TextureSampler Material::get_sampler(const char* name, int index) const TextureSampler Material::get_sampler(const char* name, int index) const
{ {
BLAH_ASSERT(m_shader, "Material Shader is invalid"); BLAH_ASSERT(m_shader, "Material Shader is invalid");
int offset = 0;
for (auto& uniform : m_shader->uniforms()) for (auto& uniform : m_shader->uniforms())
{ {
if (uniform.type != UniformType::Sampler2D) if (uniform.type != UniformType::Sampler2D)
continue; continue;
if (strcmp(uniform.name, name) == 0) if (strcmp(uniform.name, name) == 0)
return m_samplers[offset + index]; {
if (uniform.register_index + index < m_samplers.size())
offset += uniform.array_length; return m_samplers[uniform.register_index + index];
if (offset + index >= m_samplers.size())
break; break;
}
} }
Log::warn("No Sampler Uniform '%s' at index [%i] exists", name, index); Log::warn("No Texture Sampler Uniform '%s' at index [%i] exists", name, index);
return TextureSampler(); return TextureSampler();
} }
TextureSampler Material::get_sampler(int slot, int index) const TextureSampler Material::get_sampler(int register_index) const
{ {
BLAH_ASSERT(m_shader, "Material Shader is invalid"); BLAH_ASSERT(m_shader, "Material Shader is invalid");
int s = 0; if (register_index < m_samplers.size())
int offset = 0; return m_samplers[register_index];
for (auto& uniform : m_shader->uniforms())
{
if (uniform.type != UniformType::Sampler2D)
continue;
if (s == slot) Log::warn("No Texture Sampler Uniform at register index [%i]", register_index);
{
if (index > uniform.array_length)
break;
return m_samplers[offset + index];
}
offset += uniform.array_length;
if (offset + index >= m_samplers.size())
break;
s++;
}
Log::warn("No Sampler Uniform ['%i'] at index [%i] exists", slot, index);
return TextureSampler(); return TextureSampler();
} }

View File

@ -1204,6 +1204,7 @@ namespace Blah
auto uniform = append_uniforms_to.expand(); auto uniform = append_uniforms_to.expand();
uniform->name = desc.Name; uniform->name = desc.Name;
uniform->shader = shader_type; uniform->shader = shader_type;
uniform->register_index = desc.BindPoint;
uniform->buffer_index = 0; uniform->buffer_index = 0;
uniform->array_length = max(1, desc.BindCount); uniform->array_length = max(1, desc.BindCount);
uniform->type = UniformType::Texture2D; uniform->type = UniformType::Texture2D;
@ -1213,6 +1214,7 @@ namespace Blah
auto uniform = append_uniforms_to.expand(); auto uniform = append_uniforms_to.expand();
uniform->name = desc.Name; uniform->name = desc.Name;
uniform->shader = shader_type; uniform->shader = shader_type;
uniform->register_index = desc.BindPoint;
uniform->buffer_index = 0; uniform->buffer_index = 0;
uniform->array_length = max(1, desc.BindCount); uniform->array_length = max(1, desc.BindCount);
uniform->type = UniformType::Sampler2D; uniform->type = UniformType::Sampler2D;
@ -1254,6 +1256,7 @@ namespace Blah
auto uniform = append_uniforms_to.expand(); auto uniform = append_uniforms_to.expand();
uniform->name = var_desc.Name; uniform->name = var_desc.Name;
uniform->shader = shader_type; uniform->shader = shader_type;
uniform->register_index = 0;
uniform->buffer_index = i; uniform->buffer_index = i;
uniform->array_length = max(1, type_desc.Elements); uniform->array_length = max(1, type_desc.Elements);
uniform->type = UniformType::None; uniform->type = UniformType::None;

View File

@ -894,6 +894,7 @@ namespace Blah
const int max_name_length = 256; const int max_name_length = 256;
GLint active_uniforms = 0; GLint active_uniforms = 0;
GLint sampler_uniforms = 0;
renderer->gl.GetProgramiv(id, GL_ACTIVE_UNIFORMS, &active_uniforms); renderer->gl.GetProgramiv(id, GL_ACTIVE_UNIFORMS, &active_uniforms);
for (int i = 0; i < active_uniforms; i++) for (int i = 0; i < active_uniforms; i++)
@ -921,6 +922,7 @@ namespace Blah
{ {
UniformInfo tex_uniform; UniformInfo tex_uniform;
tex_uniform.name = name; tex_uniform.name = name;
tex_uniform.register_index = sampler_uniforms;
tex_uniform.buffer_index = 0; tex_uniform.buffer_index = 0;
tex_uniform.array_length = size; tex_uniform.array_length = size;
tex_uniform.type = UniformType::Texture2D; tex_uniform.type = UniformType::Texture2D;
@ -930,18 +932,22 @@ namespace Blah
UniformInfo sampler_uniform; UniformInfo sampler_uniform;
sampler_uniform.name = String(name).append("_sampler"); sampler_uniform.name = String(name).append("_sampler");
sampler_uniform.register_index = sampler_uniforms;
sampler_uniform.buffer_index = 0; sampler_uniform.buffer_index = 0;
sampler_uniform.array_length = size; sampler_uniform.array_length = size;
sampler_uniform.type = UniformType::Sampler2D; sampler_uniform.type = UniformType::Sampler2D;
sampler_uniform.shader = ShaderType::Fragment; sampler_uniform.shader = ShaderType::Fragment;
uniform_locations.push_back(renderer->gl.GetUniformLocation(id, name)); uniform_locations.push_back(renderer->gl.GetUniformLocation(id, name));
m_uniforms.push_back(sampler_uniform); m_uniforms.push_back(sampler_uniform);
sampler_uniforms += size;
} }
else else
{ {
UniformInfo uniform; UniformInfo uniform;
uniform.name = name; uniform.name = name;
uniform.type = UniformType::None; uniform.type = UniformType::None;
uniform.register_index = 0;
uniform.buffer_index = 0; uniform.buffer_index = 0;
uniform.array_length = size; uniform.array_length = size;
uniform_locations.push_back(renderer->gl.GetUniformLocation(id, name)); uniform_locations.push_back(renderer->gl.GetUniformLocation(id, name));
@ -1297,7 +1303,6 @@ namespace Blah
renderer->gl.UseProgram(shader->gl_id()); renderer->gl.UseProgram(shader->gl_id());
int texture_slot = 0; int texture_slot = 0;
int gl_texture_slot = 0;
GLint texture_ids[64]; GLint texture_ids[64];
auto& uniforms = shader->uniforms(); auto& uniforms = shader->uniforms();
auto data = pass.material->data(); auto data = pass.material->data();
@ -1316,10 +1321,10 @@ namespace Blah
{ {
for (int n = 0; n < uniform.array_length; n++) for (int n = 0; n < uniform.array_length; n++)
{ {
auto tex = pass.material->get_texture(texture_slot, n); auto tex = pass.material->get_texture(texture_slot);
auto sampler = pass.material->get_sampler(texture_slot, n); auto sampler = pass.material->get_sampler(texture_slot);
renderer->gl.ActiveTexture(GL_TEXTURE0 + gl_texture_slot); renderer->gl.ActiveTexture(GL_TEXTURE0 + texture_slot);
if (!tex) if (!tex)
{ {
@ -1332,12 +1337,11 @@ namespace Blah
renderer->gl.BindTexture(GL_TEXTURE_2D, gl_tex->gl_id()); renderer->gl.BindTexture(GL_TEXTURE_2D, gl_tex->gl_id());
} }
texture_ids[n] = gl_texture_slot; texture_ids[n] = texture_slot;
gl_texture_slot++; texture_slot++;
} }
renderer->gl.Uniform1iv(location, (GLint)uniform.array_length, &texture_ids[0]); renderer->gl.Uniform1iv(location, (GLint)uniform.array_length, &texture_ids[0]);
texture_slot++;
continue; continue;
} }