diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-28 14:50:32 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-28 14:50:32 -0400 |
| commit | 0a692577b5c7d63a252d5099e39c088a117e7818 (patch) | |
| tree | 7f43d6c71851d77ef8f844744dab17e60dfb2c5d /src/video_core/shader_cache.cpp | |
| parent | 8f59920970674c47dcce8866d3e0659ef91a81b4 (diff) | |
Jump-table programs end at their self-branch; aligned wide zero stores
- With a BRX the jump targets live in a constant buffer, so capture and
lowering keep going past EXITs to the compiler's closing branch-to-self
(a title 1 compute program jumped to 0xae0, just past the first EXIT).
- 128-bit stores of RZ use R248-R251 (Eden wants 4-aligned data registers).
- The rejected-program cache covers environment construction, where native
programs are lowered (it never applied before), and logs the stage slot.
Title 1 reaches its title screen with the ground drawn.
Diffstat (limited to 'src/video_core/shader_cache.cpp')
| -rw-r--r-- | src/video_core/shader_cache.cpp | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/src/video_core/shader_cache.cpp b/src/video_core/shader_cache.cpp index 15c1adb7c9..da5417be02 100644 --- a/src/video_core/shader_cache.cpp +++ b/src/video_core/shader_cache.cpp @@ -81,10 +81,13 @@ bool ShaderCache::RefreshStages(std::array<u64, 6>& unique_hashes) try { const ShaderInfo* shader_info{TryGet(*cpu_shader_addr)}; if (!shader_info) { const u32 start_address{native ? 0 : shader_config.offset}; - GraphicsEnvironment env{*maxwell3d, *gpu_memory, program, native ? shader_addr : base_addr, start_address}; try { + // Native programs are lowered while the environment is built. + RethrowIfRejected(*cpu_shader_addr); + GraphicsEnvironment env{*maxwell3d, *gpu_memory, program, native ? shader_addr : base_addr, start_address}; shader_info = MakeShaderInfo(env, *cpu_shader_addr); } catch (const Shader::Exception&) { + RememberRejection(*cpu_shader_addr); // Once per program: which stage slot it is bound to, its header and the slot's // registers (to tell how a pipeline with task/mesh programs is set up). static std::unordered_set<GPUVAddr> described; @@ -145,8 +148,26 @@ const ShaderInfo* ShaderCache::ComputeShader() { if (const ShaderInfo* const shader = TryGet(*cpu_shader_addr)) { return shader; } - ComputeEnvironment env{*kepler_compute, *gpu_memory, program_base, qmd.program_start}; - return MakeShaderInfo(env, *cpu_shader_addr); + try { + RethrowIfRejected(*cpu_shader_addr); + ComputeEnvironment env{*kepler_compute, *gpu_memory, program_base, qmd.program_start}; + return MakeShaderInfo(env, *cpu_shader_addr); + } catch (const Shader::Exception&) { + RememberRejection(*cpu_shader_addr); + throw; + } +} + +void ShaderCache::RethrowIfRejected(VAddr addr) { + std::scoped_lock lock{rejected_mutex}; + if (const auto it = rejected_native.find(addr); it != rejected_native.end()) { + std::rethrow_exception(it->second); + } +} + +void ShaderCache::RememberRejection(VAddr addr) { + std::scoped_lock lock{rejected_mutex}; + rejected_native.emplace(addr, std::current_exception()); } void ShaderCache::GetGraphicsEnvironments(GraphicsEnvironments& result, @@ -290,22 +311,8 @@ ShaderCache::Entry* ShaderCache::NewEntry(VAddr addr, VAddr addr_end, ShaderInfo } const ShaderInfo* ShaderCache::MakeShaderInfo(GenericEnvironment& env, VAddr cpu_addr) { - { - std::scoped_lock lock{rejected_mutex}; - if (const auto it = rejected_native.find(cpu_addr); it != rejected_native.end()) { - std::rethrow_exception(it->second); - } - } auto info = std::make_unique<ShaderInfo>(); - std::optional<u64> analyzed; - try { - analyzed = env.Analyze(); - } catch (const Shader::Exception&) { - std::scoped_lock lock{rejected_mutex}; - rejected_native.emplace(cpu_addr, std::current_exception()); - throw; - } - if (const std::optional<u64> cached_hash{analyzed}) { + if (const std::optional<u64> cached_hash{env.Analyze()}) { info->unique_hash = *cached_hash; info->size_bytes = env.CachedSizeBytes(); } else { |
