Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
[Impeller] allow fixup UBO to have different offsets.
  • Loading branch information
jonahwilliams committed Jun 18, 2024
commit 8bab1df7b7472d61c6d4c441c0cb1cf3c4d8a39c
7 changes: 4 additions & 3 deletions impeller/compiler/reflector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,8 @@ std::shared_ptr<RuntimeStageData::Shader> Reflector::GenerateRuntimeStageData()

const auto& ubo = ubos[0];

size_t binding =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this is much nicer. The reflector reflects whats in the SPIRV instead of enforcing its own rules.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its still broken though :)

compiler_->get_decoration(ubo.id, spv::Decoration::DecorationBinding);
auto members = ReadStructMembers(ubo.type_id);
std::vector<uint8_t> struct_layout;
size_t float_count = 0;
Expand Down Expand Up @@ -410,9 +412,8 @@ std::shared_ptr<RuntimeStageData::Shader> Reflector::GenerateRuntimeStageData()
}
data->uniforms.emplace_back(UniformDescription{
.name = ubo.name,
.location = 64, // Magic constant that must match the descriptor set
// location for fragment programs.
.binding = 64,
.location = binding,
.binding = binding,
.type = spirv_cross::SPIRType::Struct,
.struct_layout = std::move(struct_layout),
.struct_float_count = float_count,
Expand Down
25 changes: 23 additions & 2 deletions impeller/runtime_stage/runtime_stage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,22 @@ RuntimeStage::RuntimeStage(const fb::RuntimeStage* runtime_stage,
entrypoint_ = runtime_stage->entrypoint()->str();

auto* uniforms = runtime_stage->uniforms();

// Note: image bindings are screwy and will always have the same offset.
// track the binding of the UBO to determine where the image bindings go.
// This is only guaranteed to give us the correct bindings if there is a
// single sampler2D.
std::optional<size_t> ubo_id;
if (uniforms) {
for (auto i = uniforms->begin(), end = uniforms->end(); i != end; i++) {
RuntimeUniformDescription desc;
desc.name = i->name()->str();
desc.location = i->location();
desc.binding = i->binding();
desc.type = ToType(i->type());
if (desc.type == kStruct) {
ubo_id = desc.location;
}
desc.dimensions = RuntimeUniformDimensions{
static_cast<size_t>(i->rows()), static_cast<size_t>(i->columns())};
desc.bit_width = i->bit_width();
Expand All @@ -105,7 +114,6 @@ RuntimeStage::RuntimeStage(const fb::RuntimeStage* runtime_stage,
desc.struct_layout.push_back(static_cast<uint8_t>(byte_type));
}
}
desc.binding = i->binding();
desc.struct_float_count = i->struct_float_count();
uniforms_.push_back(std::move(desc));
}
Expand All @@ -117,6 +125,20 @@ RuntimeStage::RuntimeStage(const fb::RuntimeStage* runtime_stage,
[payload = payload_](auto, auto) {} //
);

size_t binding = 64;
if (ubo_id.has_value() && ubo_id.value() == binding) {
binding++;
}
for (auto& uniform : uniforms_) {
if (uniform.type == kSampledImage) {
uniform.binding = binding;
binding++;
if (ubo_id.has_value() && ubo_id.value() == binding) {
binding++;
}
}
}

for (const auto& uniform : GetUniforms()) {
if (uniform.type == kStruct) {
descriptor_set_layouts_.push_back(DescriptorSetLayout{
Expand All @@ -132,7 +154,6 @@ RuntimeStage::RuntimeStage(const fb::RuntimeStage* runtime_stage,
});
}
}

is_valid_ = true;
}

Expand Down