shader: derive immutable resource policy once per plan

This commit is contained in:
nmzik
2026-09-28 17:25:25 +04:00
parent 34a3eb6b58
commit c8baa7b909
2 changed files with 11 additions and 14 deletions
+2 -1
View File
@@ -549,7 +549,7 @@ struct ResourcePlan {
std::vector<SrtRead> srt_reads; std::vector<SrtRead> srt_reads;
std::vector<uint8_t> clean_flat_slots; std::vector<uint8_t> clean_flat_slots;
bool requires_specialization_memory = false; bool requires_specialization_memory = false;
bool has_address_writes = false; bool capture_specialization_reads = false;
bool srt_plan_complete = false; bool srt_plan_complete = false;
bool resource_tracking_complete = false; bool resource_tracking_complete = false;
ShaderInfo info; ShaderInfo info;
@@ -588,6 +588,7 @@ struct Program: ResourcePlan {
// Typed memory and export instructions reference shader-local metadata by dense index. // Typed memory and export instructions reference shader-local metadata by dense index.
// Decoder-only details (such as NSA register numbers) have already become IR operands. // Decoder-only details (such as NSA register numbers) have already become IR operands.
std::vector<ExportInfo> export_info; std::vector<ExportInfo> export_info;
bool has_address_writes = false;
bool shader_info_complete = false; bool shader_info_complete = false;
BindingLayout bindings; BindingLayout bindings;
bool binding_layout_complete = false; bool binding_layout_complete = false;
@@ -865,7 +865,6 @@ ResourcePlan ExtractResourcePlan(const Program& program) {
plan.memory_info = program.memory_info; plan.memory_info = program.memory_info;
plan.srt_plan_complete = program.srt_plan_complete; plan.srt_plan_complete = program.srt_plan_complete;
plan.resource_tracking_complete = program.resource_tracking_complete; plan.resource_tracking_complete = program.resource_tracking_complete;
plan.has_address_writes = program.has_address_writes;
std::unordered_map<const Inst*, Inst*> cloned; std::unordered_map<const Inst*, Inst*> cloned;
std::function<Value(Value)> Clone = [&](Value value) -> Value { std::function<Value(Value)> Clone = [&](Value value) -> Value {
@@ -924,17 +923,25 @@ ResourcePlan ExtractResourcePlan(const Program& program) {
plan.uniform_fill.values[i] = Clone(plan.uniform_fill.values[i]); plan.uniform_fill.values[i] = Clone(plan.uniform_fill.values[i]);
} }
plan.clean_flat_slots.resize(plan.srt_reads.size()); plan.clean_flat_slots.resize(plan.srt_reads.size());
bool masked_image = false;
for (const auto& image: plan.info.images) { for (const auto& image: plan.info.images) {
const auto* source = Source(plan, image.source); const auto* source = Source(plan, image.source);
if (source == nullptr || !source->indirect_image.has_value()) { if (source == nullptr || !source->indirect_image.has_value()) {
continue; continue;
} }
plan.requires_specialization_memory = true; plan.requires_specialization_memory = true;
masked_image |= !source->indirect_image->selector_mask.IsEmpty();
MarkCleanFlatSlots(plan, Source(plan, source->indirect_image->material_source), MarkCleanFlatSlots(plan, Source(plan, source->indirect_image->material_source),
plan.clean_flat_slots, source->indirect_image->selector_mask); plan.clean_flat_slots, source->indirect_image->selector_mask);
MarkCleanFlatSlots(plan, Source(plan, source->indirect_image->table_source), MarkCleanFlatSlots(plan, Source(plan, source->indirect_image->table_source),
plan.clean_flat_slots); plan.clean_flat_slots);
} }
if (masked_image) {
plan.resource_tracking_complete &= !program.has_address_writes &&
!std::ranges::any_of(plan.info.images, &ImageResource::written);
plan.capture_specialization_reads =
std::ranges::any_of(plan.info.buffers, &BufferResource::written);
}
return plan; return plan;
} }
@@ -944,18 +951,7 @@ bool MaterializeResources(const ResourcePlan& program, const SrtRuntime& runtime
(program.requires_specialization_memory && runtime.read_specialization_memory == nullptr)) { (program.requires_specialization_memory && runtime.read_specialization_memory == nullptr)) {
return false; return false;
} }
const bool masked_image = std::ranges::any_of(program.info.images, [&](const auto& image) { const bool capture_reads = program.capture_specialization_reads;
const auto* source = Source(program, image.source);
return source != nullptr && source->indirect_image.has_value() &&
!source->indirect_image->selector_mask.IsEmpty();
});
if (masked_image &&
(program.has_address_writes ||
std::ranges::any_of(program.info.images, &ImageResource::written))) {
return false;
}
const bool capture_reads = masked_image &&
std::ranges::any_of(program.info.buffers, &BufferResource::written);
auto& reads = program.specialization_reads; auto& reads = program.specialization_reads;
ReadCapture capture {runtime, reads}; ReadCapture capture {runtime, reads};
SrtRuntime observed = runtime; SrtRuntime observed = runtime;