From c8baa7b9090d552d78ddb5ed587c91dbf8b28919 Mon Sep 17 00:00:00 2001 From: nmzik Date: Mon, 28 Sep 2026 17:25:25 +0400 Subject: [PATCH] shader: derive immutable resource policy once per plan --- src/graphics/shader/recompiler/ir/ShaderIR.h | 3 ++- .../ir/passes/ResourceMaterialization.cpp | 22 ++++++++----------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/graphics/shader/recompiler/ir/ShaderIR.h b/src/graphics/shader/recompiler/ir/ShaderIR.h index 65dd66328..7380672f3 100644 --- a/src/graphics/shader/recompiler/ir/ShaderIR.h +++ b/src/graphics/shader/recompiler/ir/ShaderIR.h @@ -549,7 +549,7 @@ struct ResourcePlan { std::vector srt_reads; std::vector clean_flat_slots; bool requires_specialization_memory = false; - bool has_address_writes = false; + bool capture_specialization_reads = false; bool srt_plan_complete = false; bool resource_tracking_complete = false; ShaderInfo info; @@ -588,6 +588,7 @@ struct Program: ResourcePlan { // 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. std::vector export_info; + bool has_address_writes = false; bool shader_info_complete = false; BindingLayout bindings; bool binding_layout_complete = false; diff --git a/src/graphics/shader/recompiler/ir/passes/ResourceMaterialization.cpp b/src/graphics/shader/recompiler/ir/passes/ResourceMaterialization.cpp index 57b30d2f4..418c4be3a 100644 --- a/src/graphics/shader/recompiler/ir/passes/ResourceMaterialization.cpp +++ b/src/graphics/shader/recompiler/ir/passes/ResourceMaterialization.cpp @@ -865,7 +865,6 @@ ResourcePlan ExtractResourcePlan(const Program& program) { plan.memory_info = program.memory_info; plan.srt_plan_complete = program.srt_plan_complete; plan.resource_tracking_complete = program.resource_tracking_complete; - plan.has_address_writes = program.has_address_writes; std::unordered_map cloned; std::function 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.clean_flat_slots.resize(plan.srt_reads.size()); + bool masked_image = false; for (const auto& image: plan.info.images) { const auto* source = Source(plan, image.source); if (source == nullptr || !source->indirect_image.has_value()) { continue; } plan.requires_specialization_memory = true; + masked_image |= !source->indirect_image->selector_mask.IsEmpty(); MarkCleanFlatSlots(plan, Source(plan, source->indirect_image->material_source), plan.clean_flat_slots, source->indirect_image->selector_mask); MarkCleanFlatSlots(plan, Source(plan, source->indirect_image->table_source), 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; } @@ -944,18 +951,7 @@ bool MaterializeResources(const ResourcePlan& program, const SrtRuntime& runtime (program.requires_specialization_memory && runtime.read_specialization_memory == nullptr)) { return false; } - const bool masked_image = std::ranges::any_of(program.info.images, [&](const auto& image) { - 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); + const bool capture_reads = program.capture_specialization_reads; auto& reads = program.specialization_reads; ReadCapture capture {runtime, reads}; SrtRuntime observed = runtime;