#ifndef EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_RECOMPILER_SRTWALKER_H_ #define EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_RECOMPILER_SRTWALKER_H_ #include "graphics/shader/recompiler/ir/ShaderIR.h" #include namespace Libs::Graphics::ShaderRecompiler::IR { class Value; using SrtMemoryReader = bool (*)(void* userdata, uint64_t address, std::span values); struct SrtRuntime { std::span user_data; uint64_t shader_base = 0; SrtMemoryReader read_memory = nullptr; void* userdata = nullptr; SrtMemoryReader read_specialization_memory = nullptr; std::span workgroup_counts; }; class SrtReadCapture { public: SrtReadCapture(SrtRuntime source, std::vector>& ranges): m_source(source), m_ranges(ranges) {} SrtRuntime ObservedRuntime(); private: static bool ReadStrict(void* userdata, uint64_t address, std::span values); static bool ReadOrdinary(void* userdata, uint64_t address, std::span values); SrtRuntime m_source; std::vector>& m_ranges; }; // Retained reads no longer need the guest instruction PC. A clean read evaluates // its address and bounds through the strict reader as well as the final DWORD. struct SrtReadFlags { uint32_t index = 0; uint32_t clean = 0; }; enum class RuntimeValueType { Any, Integer, ImmutableInteger }; bool ValidateRuntimeValue(const ResourcePlan& program, Value value, RuntimeValueType type = RuntimeValueType::Any); // Uses the strict reader for values that affect shader specialization. SrtRuntime CleanRuntime(SrtRuntime runtime); // One memoized evaluation session shared by the entire shader resource refresh. class SrtWalker { public: SrtWalker(const ResourcePlan& program, const SrtRuntime& runtime, SrtWalker* clean_evaluator = nullptr, Value active_mask = {}); ~SrtWalker(); SrtWalker(const SrtWalker&) = delete; SrtWalker& operator=(const SrtWalker&) = delete; bool Evaluate(Value value, uint32_t& result); bool EvaluateDescriptor(uint32_t source, DescriptorValue& result); // Refreshes reachable scalar reads and active descriptor sources in one walk. bool RefreshFlatBuffer(std::vector& flat); private: static ResourcePlan::EvaluationContext& AcquireContext(const ResourcePlan& program); static float Float32(uint64_t bits); bool EvaluateWide(Value value, uint64_t& result); bool Arg(const Inst& inst, size_t index, uint64_t& result); bool EvaluatePhi(const Inst& inst, uint64_t& result); bool EvaluateExtract(const Inst& inst, uint64_t& result); bool EvaluateRawRead(const Inst& inst, uint64_t& result); bool EvaluateInst(const Inst& inst, uint64_t& result); const ResourcePlan& m_program; SrtRuntime m_runtime; SrtWalker* m_clean_evaluator = nullptr; Value m_active_mask; ResourcePlan::EvaluationContext& m_context; }; } // namespace Libs::Graphics::ShaderRecompiler::IR #endif /* EMULATOR_INCLUDE_EMULATOR_GRAPHICS_SHADER_RECOMPILER_SRTWALKER_H_ */