GPUShaderCreateInfo: Add manual validation of bindpoints

Some drivers/glsl compilers will not warn about multiple resources using
the same binding, creating silent errors.

This patch checks for this case and outputs a descriptive error message if
a particular createInfo merge error is founds.

Other validation can be added later.
This commit is contained in:
Clément Foucault
2022-01-24 13:23:50 +01:00
parent 7708a848c9
commit e774f2c901
2 changed files with 66 additions and 0 deletions

View File

@@ -72,6 +72,8 @@ void ShaderCreateInfo::finalize()
pass_resources_.extend(info.pass_resources_);
typedef_sources_.extend(info.typedef_sources_);
validate(info);
if (info.local_group_size_[0] != 0) {
BLI_assert(local_group_size_[0] == 0);
for (int i = 0; i < 3; i++) {
@@ -100,6 +102,67 @@ void ShaderCreateInfo::finalize()
}
}
void ShaderCreateInfo::validate(const ShaderCreateInfo &other_info)
{
{
/* Check same bindpoints usage in OGL. */
Set<int> images, samplers, ubos, ssbos;
auto register_resource = [&](const Resource &res) -> bool {
switch (res.bind_type) {
case Resource::BindType::UNIFORM_BUFFER:
return images.add(res.slot);
case Resource::BindType::STORAGE_BUFFER:
return samplers.add(res.slot);
case Resource::BindType::SAMPLER:
return ubos.add(res.slot);
case Resource::BindType::IMAGE:
return ssbos.add(res.slot);
default:
return false;
}
};
auto print_error_msg = [&](const Resource &res) {
std::cerr << name_ << ": Validation failed : Overlapping ";
switch (res.bind_type) {
case Resource::BindType::UNIFORM_BUFFER:
std::cerr << "Uniform Buffer " << res.uniformbuf.name;
break;
case Resource::BindType::STORAGE_BUFFER:
std::cerr << "Storage Buffer " << res.storagebuf.name;
break;
case Resource::BindType::SAMPLER:
std::cerr << "Sampler " << res.sampler.name;
break;
case Resource::BindType::IMAGE:
std::cerr << "Image " << res.image.name;
break;
default:
std::cerr << "Unknown Type";
break;
}
std::cerr << " (" << res.slot << ") while merging " << other_info.name_ << std::endl;
};
for (auto &res : batch_resources_) {
if (register_resource(res) == false) {
print_error_msg(res);
}
}
for (auto &res : pass_resources_) {
if (register_resource(res) == false) {
print_error_msg(res);
}
}
}
{
/* TODO(fclem) Push constant validation. */
}
}
} // namespace blender::gpu::shader
using namespace blender::gpu::shader;

View File

@@ -597,6 +597,9 @@ struct ShaderCreateInfo {
/* WARNING: Recursive. */
void finalize();
/** Error detection that some backend compilers do not complain about. */
void validate(const ShaderCreateInfo &other_info);
/** \} */
};