Avoid heap allocation when compacting materialized shader images

This commit is contained in:
nmzik
2026-09-21 19:57:09 +04:00
parent 7c9e18e73b
commit 4b074cf9e9
@@ -357,16 +357,23 @@ struct SamplerPlan {
}; };
struct ImageRemap { struct ImageRemap {
explicit ImageRemap(const ResourceSpecialization& specialization) { explicit ImageRemap(const ResourceSpecialization& specialization)
for (const auto& image: specialization.images) { : source_count(static_cast<uint32_t>(specialization.images.size())) {
indices.push_back(image.fmask ? UINT32_MAX : count++); EXIT_IF(specialization.images.size() > indices.size());
for (uint32_t index = 0; index < source_count; index++) {
indices[index] = specialization.images[index].fmask ? UINT32_MAX : count++;
} }
} }
uint32_t operator[](uint32_t index) const {
EXIT_IF(index >= source_count);
return indices[index];
}
template <typename T> template <typename T>
void Apply(std::vector<T>& images) const { void Apply(std::vector<T>& images) const {
EXIT_IF(images.size() != indices.size()); EXIT_IF(images.size() != source_count);
for (uint32_t index = 0; index < indices.size(); index++) { for (uint32_t index = 0; index < source_count; index++) {
if (indices[index] != UINT32_MAX && indices[index] != index) { if (indices[index] != UINT32_MAX && indices[index] != index) {
images[indices[index]] = std::move(images[index]); images[indices[index]] = std::move(images[index]);
} }
@@ -374,8 +381,10 @@ struct ImageRemap {
images.resize(count); images.resize(count);
} }
std::vector<uint32_t> indices; private:
uint32_t count = 0; std::array<uint32_t, ShaderInfo::MaxImages> indices;
uint32_t source_count;
uint32_t count = 0;
}; };
template <typename Images> template <typename Images>
@@ -1075,29 +1084,29 @@ void ApplyResourceSpecialization(Program& program, const ResourceSpecialization&
for (auto* block: program.blocks) { for (auto* block: program.blocks) {
for (auto& inst: *block) { for (auto& inst: *block) {
if (inst.GetOpcode() == ValueOpcode::GetImageResource) { if (inst.GetOpcode() == ValueOpcode::GetImageResource) {
inst.SetFlags(image_remap.indices.at(inst.Flags<uint32_t>())); inst.SetFlags(image_remap[inst.Flags<uint32_t>()]);
} }
} }
} }
for (auto& memory: memory_info) { for (auto& memory: memory_info) {
if (memory.kind == ResourceKind::Image && !memory.planning_only) { if (memory.kind == ResourceKind::Image && !memory.planning_only) {
memory.resource = image_remap.indices.at(memory.resource); memory.resource = image_remap[memory.resource];
} }
} }
for (auto& buffer: buffers) { for (auto& buffer: buffers) {
if (buffer.image_alias != BufferResource::NoImageAlias) { if (buffer.image_alias != BufferResource::NoImageAlias) {
buffer.image_alias = image_remap.indices.at(buffer.image_alias); buffer.image_alias = image_remap[buffer.image_alias];
} }
} }
for (auto& pair: sampled_pairs) { for (auto& pair: sampled_pairs) {
pair.image = image_remap.indices.at(pair.image); pair.image = image_remap[pair.image];
} }
for (auto& image: images) { for (auto& image: images) {
if (image.indirect_root != ImageResource::NoIndirectImage) { if (image.indirect_root != ImageResource::NoIndirectImage) {
image.indirect_root = image_remap.indices.at(image.indirect_root); image.indirect_root = image_remap[image.indirect_root];
} }
for (auto& resource: image.indirect_resources) { for (auto& resource: image.indirect_resources) {
resource = image_remap.indices.at(resource); resource = image_remap[resource];
} }
} }
image_remap.Apply(images); image_remap.Apply(images);