GLTexture: Add validation for empty slots before drawing

This is to have better error detection in debug builds.
This is not a replacement for a full check like in renderdoc but it
might catch some issues early on.
This commit is contained in:
Clément Foucault 2020-09-04 22:19:36 +02:00
parent 541de201fe
commit 7d4adbdfab
4 changed files with 35 additions and 1 deletions

View File

@ -93,6 +93,11 @@ class ShaderInterface {
return input_lookup(inputs_ + attr_len_ + ubo_len_, uniform_len_, name);
}
inline const ShaderInput *texture_get(const int binding) const
{
return input_lookup(inputs_ + attr_len_ + ubo_len_, uniform_len_, binding);
}
inline const char *input_name_get(const ShaderInput *input) const
{
return name_buffer_ + input->name_offset;

View File

@ -186,7 +186,12 @@ void check_gl_resources(const char *info)
uint16_t ubo_needed = interface->enabled_ubo_mask_;
ubo_needed &= ~ctx->bound_ubo_slots;
if (ubo_needed == 0) {
/* NOTE: This only check binding. To be valid, the bound texture needs to
* be the same format/target the shader expects. */
uint64_t tex_needed = interface->enabled_tex_mask_;
tex_needed &= ~ctx->state_manager_active_get()->bound_texture_slots();
if (ubo_needed == 0 && tex_needed == 0) {
return;
}
@ -200,6 +205,17 @@ void check_gl_resources(const char *info)
debug_callback(0, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, 0, msg, NULL);
}
}
for (int i = 0; tex_needed != 0; i++, tex_needed >>= 1) {
if ((tex_needed & 1) != 0) {
const ShaderInput *tex_input = interface->texture_get(i);
const char *tex_name = interface->input_name_get(tex_input);
const char *sh_name = ctx->shader->name_get();
char msg[256];
SNPRINTF(msg, "Missing Texture bind at slot %d : %s > %s : %s", i, sh_name, tex_name, info);
debug_callback(0, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, 0, msg, NULL);
}
}
}
void raise_gl_error(const char *msg)

View File

@ -503,6 +503,17 @@ void GLStateManager::texture_bind_apply(void)
}
}
uint64_t GLStateManager::bound_texture_slots(void)
{
uint64_t bound_slots = 0;
for (int i = 0; i < ARRAY_SIZE(textures_); i++) {
if (textures_[i] != 0) {
bound_slots |= 1 << i;
}
}
return bound_slots;
}
/** \} */
} // namespace blender::gpu

View File

@ -74,6 +74,8 @@ class GLStateManager : public GPUStateManager {
void texture_unbind(Texture *tex) override;
void texture_unbind_all(void) override;
uint64_t bound_texture_slots(void);
private:
static void set_write_mask(const eGPUWriteMask value);
static void set_depth_test(const eGPUDepthTest value);