summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_compute_pipeline.cpp19
-rw-r--r--src/video_core/renderer_opengl/gl_compute_pipeline.h16
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp28
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.h16
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp1
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp11
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp17
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.h28
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp8
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp2
-rw-r--r--src/video_core/texture_cache/texture_cache.h12
11 files changed, 87 insertions, 71 deletions
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
index 1f0f156ed..26b51f442 100644
--- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
@@ -28,12 +28,11 @@ bool ComputePipelineKey::operator==(const ComputePipelineKey& rhs) const noexcep
28} 28}
29 29
30ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cache_, 30ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cache_,
31 BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, 31 BufferCache& buffer_cache_, ProgramManager& program_manager_,
32 Tegra::Engines::KeplerCompute& kepler_compute_, 32 const Shader::Info& info_, std::string code,
33 ProgramManager& program_manager_, const Shader::Info& info_, 33 std::vector<u32> code_v)
34 std::string code, std::vector<u32> code_v) 34 : texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
35 : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_}, 35 program_manager{program_manager_}, info{info_} {
36 kepler_compute{kepler_compute_}, program_manager{program_manager_}, info{info_} {
37 switch (device.GetShaderBackend()) { 36 switch (device.GetShaderBackend()) {
38 case Settings::ShaderBackend::GLSL: 37 case Settings::ShaderBackend::GLSL:
39 source_program = CreateProgram(code, GL_COMPUTE_SHADER); 38 source_program = CreateProgram(code, GL_COMPUTE_SHADER);
@@ -86,7 +85,7 @@ void ComputePipeline::Configure() {
86 GLsizei texture_binding{}; 85 GLsizei texture_binding{};
87 GLsizei image_binding{}; 86 GLsizei image_binding{};
88 87
89 const auto& qmd{kepler_compute.launch_description}; 88 const auto& qmd{kepler_compute->launch_description};
90 const auto& cbufs{qmd.const_buffer_config}; 89 const auto& cbufs{qmd.const_buffer_config};
91 const bool via_header_index{qmd.linked_tsc != 0}; 90 const bool via_header_index{qmd.linked_tsc != 0};
92 const auto read_handle{[&](const auto& desc, u32 index) { 91 const auto read_handle{[&](const auto& desc, u32 index) {
@@ -101,12 +100,12 @@ void ComputePipeline::Configure() {
101 const u32 secondary_offset{desc.secondary_cbuf_offset + index_offset}; 100 const u32 secondary_offset{desc.secondary_cbuf_offset + index_offset};
102 const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].Address() + 101 const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].Address() +
103 secondary_offset}; 102 secondary_offset};
104 const u32 lhs_raw{gpu_memory.Read<u32>(addr)}; 103 const u32 lhs_raw{gpu_memory->Read<u32>(addr)};
105 const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr)}; 104 const u32 rhs_raw{gpu_memory->Read<u32>(separate_addr)};
106 return TexturePair(lhs_raw | rhs_raw, via_header_index); 105 return TexturePair(lhs_raw | rhs_raw, via_header_index);
107 } 106 }
108 } 107 }
109 return TexturePair(gpu_memory.Read<u32>(addr), via_header_index); 108 return TexturePair(gpu_memory->Read<u32>(addr), via_header_index);
110 }}; 109 }};
111 const auto add_image{[&](const auto& desc, bool blacklist) { 110 const auto add_image{[&](const auto& desc, bool blacklist) {
112 for (u32 index = 0; index < desc.count; ++index) { 111 for (u32 index = 0; index < desc.count; ++index) {
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.h b/src/video_core/renderer_opengl/gl_compute_pipeline.h
index 723f27f11..6534dec32 100644
--- a/src/video_core/renderer_opengl/gl_compute_pipeline.h
+++ b/src/video_core/renderer_opengl/gl_compute_pipeline.h
@@ -49,10 +49,8 @@ static_assert(std::is_trivially_constructible_v<ComputePipelineKey>);
49class ComputePipeline { 49class ComputePipeline {
50public: 50public:
51 explicit ComputePipeline(const Device& device, TextureCache& texture_cache_, 51 explicit ComputePipeline(const Device& device, TextureCache& texture_cache_,
52 BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, 52 BufferCache& buffer_cache_, ProgramManager& program_manager_,
53 Tegra::Engines::KeplerCompute& kepler_compute_, 53 const Shader::Info& info_, std::string code, std::vector<u32> code_v);
54 ProgramManager& program_manager_, const Shader::Info& info_,
55 std::string code, std::vector<u32> code_v);
56 54
57 void Configure(); 55 void Configure();
58 56
@@ -60,11 +58,17 @@ public:
60 return writes_global_memory; 58 return writes_global_memory;
61 } 59 }
62 60
61 void SetEngine(Tegra::Engines::KeplerCompute* kepler_compute_,
62 Tegra::MemoryManager* gpu_memory_) {
63 kepler_compute = kepler_compute_;
64 gpu_memory = gpu_memory_;
65 }
66
63private: 67private:
64 TextureCache& texture_cache; 68 TextureCache& texture_cache;
65 BufferCache& buffer_cache; 69 BufferCache& buffer_cache;
66 Tegra::MemoryManager& gpu_memory; 70 Tegra::MemoryManager* gpu_memory;
67 Tegra::Engines::KeplerCompute& kepler_compute; 71 Tegra::Engines::KeplerCompute* kepler_compute;
68 ProgramManager& program_manager; 72 ProgramManager& program_manager;
69 73
70 Shader::Info info; 74 Shader::Info info;
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index 67eae369d..c877d7792 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -169,15 +169,15 @@ ConfigureFuncPtr ConfigureFunc(const std::array<Shader::Info, 5>& infos, u32 ena
169} 169}
170} // Anonymous namespace 170} // Anonymous namespace
171 171
172GraphicsPipeline::GraphicsPipeline( 172GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_cache_,
173 const Device& device, TextureCache& texture_cache_, BufferCache& buffer_cache_, 173 BufferCache& buffer_cache_, ProgramManager& program_manager_,
174 Tegra::MemoryManager& gpu_memory_, Tegra::Engines::Maxwell3D& maxwell3d_, 174 StateTracker& state_tracker_, ShaderWorker* thread_worker,
175 ProgramManager& program_manager_, StateTracker& state_tracker_, ShaderWorker* thread_worker, 175 VideoCore::ShaderNotify* shader_notify,
176 VideoCore::ShaderNotify* shader_notify, std::array<std::string, 5> sources, 176 std::array<std::string, 5> sources,
177 std::array<std::vector<u32>, 5> sources_spirv, const std::array<const Shader::Info*, 5>& infos, 177 std::array<std::vector<u32>, 5> sources_spirv,
178 const GraphicsPipelineKey& key_) 178 const std::array<const Shader::Info*, 5>& infos,
179 : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, 179 const GraphicsPipelineKey& key_)
180 gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, program_manager{program_manager_}, 180 : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, program_manager{program_manager_},
181 state_tracker{state_tracker_}, key{key_} { 181 state_tracker{state_tracker_}, key{key_} {
182 if (shader_notify) { 182 if (shader_notify) {
183 shader_notify->MarkShaderBuilding(); 183 shader_notify->MarkShaderBuilding();
@@ -285,7 +285,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
285 buffer_cache.runtime.SetBaseStorageBindings(base_storage_bindings); 285 buffer_cache.runtime.SetBaseStorageBindings(base_storage_bindings);
286 buffer_cache.runtime.SetEnableStorageBuffers(use_storage_buffers); 286 buffer_cache.runtime.SetEnableStorageBuffers(use_storage_buffers);
287 287
288 const auto& regs{maxwell3d.regs}; 288 const auto& regs{maxwell3d->regs};
289 const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; 289 const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex};
290 const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE { 290 const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE {
291 const Shader::Info& info{stage_infos[stage]}; 291 const Shader::Info& info{stage_infos[stage]};
@@ -299,7 +299,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
299 ++ssbo_index; 299 ++ssbo_index;
300 } 300 }
301 } 301 }
302 const auto& cbufs{maxwell3d.state.shader_stages[stage].const_buffers}; 302 const auto& cbufs{maxwell3d->state.shader_stages[stage].const_buffers};
303 const auto read_handle{[&](const auto& desc, u32 index) { 303 const auto read_handle{[&](const auto& desc, u32 index) {
304 ASSERT(cbufs[desc.cbuf_index].enabled); 304 ASSERT(cbufs[desc.cbuf_index].enabled);
305 const u32 index_offset{index << desc.size_shift}; 305 const u32 index_offset{index << desc.size_shift};
@@ -312,13 +312,13 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
312 const u32 second_offset{desc.secondary_cbuf_offset + index_offset}; 312 const u32 second_offset{desc.secondary_cbuf_offset + index_offset};
313 const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address + 313 const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address +
314 second_offset}; 314 second_offset};
315 const u32 lhs_raw{gpu_memory.Read<u32>(addr)}; 315 const u32 lhs_raw{gpu_memory->Read<u32>(addr)};
316 const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr)}; 316 const u32 rhs_raw{gpu_memory->Read<u32>(separate_addr)};
317 const u32 raw{lhs_raw | rhs_raw}; 317 const u32 raw{lhs_raw | rhs_raw};
318 return TexturePair(raw, via_header_index); 318 return TexturePair(raw, via_header_index);
319 } 319 }
320 } 320 }
321 return TexturePair(gpu_memory.Read<u32>(addr), via_header_index); 321 return TexturePair(gpu_memory->Read<u32>(addr), via_header_index);
322 }}; 322 }};
323 const auto add_image{[&](const auto& desc, bool blacklist) LAMBDA_FORCEINLINE { 323 const auto add_image{[&](const auto& desc, bool blacklist) LAMBDA_FORCEINLINE {
324 for (u32 index = 0; index < desc.count; ++index) { 324 for (u32 index = 0; index < desc.count; ++index) {
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.h b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
index 4ec15b966..a0f0e63cb 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.h
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
@@ -71,10 +71,9 @@ static_assert(std::is_trivially_constructible_v<GraphicsPipelineKey>);
71class GraphicsPipeline { 71class GraphicsPipeline {
72public: 72public:
73 explicit GraphicsPipeline(const Device& device, TextureCache& texture_cache_, 73 explicit GraphicsPipeline(const Device& device, TextureCache& texture_cache_,
74 BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, 74 BufferCache& buffer_cache_, ProgramManager& program_manager_,
75 Tegra::Engines::Maxwell3D& maxwell3d_, 75 StateTracker& state_tracker_, ShaderWorker* thread_worker,
76 ProgramManager& program_manager_, StateTracker& state_tracker_, 76 VideoCore::ShaderNotify* shader_notify,
77 ShaderWorker* thread_worker, VideoCore::ShaderNotify* shader_notify,
78 std::array<std::string, 5> sources, 77 std::array<std::string, 5> sources,
79 std::array<std::vector<u32>, 5> sources_spirv, 78 std::array<std::vector<u32>, 5> sources_spirv,
80 const std::array<const Shader::Info*, 5>& infos, 79 const std::array<const Shader::Info*, 5>& infos,
@@ -107,6 +106,11 @@ public:
107 }; 106 };
108 } 107 }
109 108
109 void SetEngine(Tegra::Engines::Maxwell3D* maxwell3d_, Tegra::MemoryManager* gpu_memory_) {
110 maxwell3d = maxwell3d_;
111 gpu_memory = gpu_memory_;
112 }
113
110private: 114private:
111 template <typename Spec> 115 template <typename Spec>
112 void ConfigureImpl(bool is_indexed); 116 void ConfigureImpl(bool is_indexed);
@@ -119,8 +123,8 @@ private:
119 123
120 TextureCache& texture_cache; 124 TextureCache& texture_cache;
121 BufferCache& buffer_cache; 125 BufferCache& buffer_cache;
122 Tegra::MemoryManager& gpu_memory; 126 Tegra::MemoryManager* gpu_memory;
123 Tegra::Engines::Maxwell3D& maxwell3d; 127 Tegra::Engines::Maxwell3D* maxwell3d;
124 ProgramManager& program_manager; 128 ProgramManager& program_manager;
125 StateTracker& state_tracker; 129 StateTracker& state_tracker;
126 const GraphicsPipelineKey key; 130 const GraphicsPipelineKey key;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 8cfa0013f..4eb9bd116 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -216,6 +216,7 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
216 return; 216 return;
217 } 217 }
218 std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex}; 218 std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
219 pipeline->SetEngine(maxwell3d, gpu_memory);
219 pipeline->Configure(is_indexed); 220 pipeline->Configure(is_indexed);
220 221
221 SyncState(); 222 SyncState();
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 494581d0d..5a29a41d2 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -477,9 +477,9 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
477 previous_program = &program; 477 previous_program = &program;
478 } 478 }
479 auto* const thread_worker{build_in_parallel ? workers.get() : nullptr}; 479 auto* const thread_worker{build_in_parallel ? workers.get() : nullptr};
480 return std::make_unique<GraphicsPipeline>( 480 return std::make_unique<GraphicsPipeline>(device, texture_cache, buffer_cache, program_manager,
481 device, texture_cache, buffer_cache, *gpu_memory, *maxwell3d, program_manager, 481 state_tracker, thread_worker, &shader_notify, sources,
482 state_tracker, thread_worker, &shader_notify, sources, sources_spirv, infos, key); 482 sources_spirv, infos, key);
483 483
484} catch (Shader::Exception& exception) { 484} catch (Shader::Exception& exception) {
485 LOG_ERROR(Render_OpenGL, "{}", exception.what()); 485 LOG_ERROR(Render_OpenGL, "{}", exception.what());
@@ -533,9 +533,8 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
533 break; 533 break;
534 } 534 }
535 535
536 return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, *gpu_memory, 536 return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, program_manager,
537 *kepler_compute, program_manager, program.info, code, 537 program.info, code, code_spirv);
538 code_spirv);
539} catch (Shader::Exception& exception) { 538} catch (Shader::Exception& exception) {
540 LOG_ERROR(Render_OpenGL, "{}", exception.what()); 539 LOG_ERROR(Render_OpenGL, "{}", exception.what());
541 return nullptr; 540 return nullptr;
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index 5aca8f038..1e993185f 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -215,15 +215,14 @@ ConfigureFuncPtr ConfigureFunc(const std::array<vk::ShaderModule, NUM_STAGES>& m
215} // Anonymous namespace 215} // Anonymous namespace
216 216
217GraphicsPipeline::GraphicsPipeline( 217GraphicsPipeline::GraphicsPipeline(
218 Tegra::Engines::Maxwell3D& maxwell3d_, Tegra::MemoryManager& gpu_memory_, Scheduler& scheduler_, 218 Scheduler& scheduler_, BufferCache& buffer_cache_, TextureCache& texture_cache_,
219 BufferCache& buffer_cache_, TextureCache& texture_cache_,
220 VideoCore::ShaderNotify* shader_notify, const Device& device_, DescriptorPool& descriptor_pool, 219 VideoCore::ShaderNotify* shader_notify, const Device& device_, DescriptorPool& descriptor_pool,
221 UpdateDescriptorQueue& update_descriptor_queue_, Common::ThreadWorker* worker_thread, 220 UpdateDescriptorQueue& update_descriptor_queue_, Common::ThreadWorker* worker_thread,
222 PipelineStatistics* pipeline_statistics, RenderPassCache& render_pass_cache, 221 PipelineStatistics* pipeline_statistics, RenderPassCache& render_pass_cache,
223 const GraphicsPipelineCacheKey& key_, std::array<vk::ShaderModule, NUM_STAGES> stages, 222 const GraphicsPipelineCacheKey& key_, std::array<vk::ShaderModule, NUM_STAGES> stages,
224 const std::array<const Shader::Info*, NUM_STAGES>& infos) 223 const std::array<const Shader::Info*, NUM_STAGES>& infos)
225 : key{key_}, maxwell3d{maxwell3d_}, gpu_memory{gpu_memory_}, device{device_}, 224 : key{key_}, device{device_}, texture_cache{texture_cache_},
226 texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, scheduler{scheduler_}, 225 buffer_cache{buffer_cache_}, scheduler{scheduler_},
227 update_descriptor_queue{update_descriptor_queue_}, spv_modules{std::move(stages)} { 226 update_descriptor_queue{update_descriptor_queue_}, spv_modules{std::move(stages)} {
228 if (shader_notify) { 227 if (shader_notify) {
229 shader_notify->MarkShaderBuilding(); 228 shader_notify->MarkShaderBuilding();
@@ -288,7 +287,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
288 287
289 buffer_cache.SetUniformBuffersState(enabled_uniform_buffer_masks, &uniform_buffer_sizes); 288 buffer_cache.SetUniformBuffersState(enabled_uniform_buffer_masks, &uniform_buffer_sizes);
290 289
291 const auto& regs{maxwell3d.regs}; 290 const auto& regs{maxwell3d->regs};
292 const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex}; 291 const bool via_header_index{regs.sampler_index == Maxwell::SamplerIndex::ViaHeaderIndex};
293 const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE { 292 const auto config_stage{[&](size_t stage) LAMBDA_FORCEINLINE {
294 const Shader::Info& info{stage_infos[stage]}; 293 const Shader::Info& info{stage_infos[stage]};
@@ -302,7 +301,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
302 ++ssbo_index; 301 ++ssbo_index;
303 } 302 }
304 } 303 }
305 const auto& cbufs{maxwell3d.state.shader_stages[stage].const_buffers}; 304 const auto& cbufs{maxwell3d->state.shader_stages[stage].const_buffers};
306 const auto read_handle{[&](const auto& desc, u32 index) { 305 const auto read_handle{[&](const auto& desc, u32 index) {
307 ASSERT(cbufs[desc.cbuf_index].enabled); 306 ASSERT(cbufs[desc.cbuf_index].enabled);
308 const u32 index_offset{index << desc.size_shift}; 307 const u32 index_offset{index << desc.size_shift};
@@ -315,13 +314,13 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
315 const u32 second_offset{desc.secondary_cbuf_offset + index_offset}; 314 const u32 second_offset{desc.secondary_cbuf_offset + index_offset};
316 const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address + 315 const GPUVAddr separate_addr{cbufs[desc.secondary_cbuf_index].address +
317 second_offset}; 316 second_offset};
318 const u32 lhs_raw{gpu_memory.Read<u32>(addr)}; 317 const u32 lhs_raw{gpu_memory->Read<u32>(addr)};
319 const u32 rhs_raw{gpu_memory.Read<u32>(separate_addr)}; 318 const u32 rhs_raw{gpu_memory->Read<u32>(separate_addr)};
320 const u32 raw{lhs_raw | rhs_raw}; 319 const u32 raw{lhs_raw | rhs_raw};
321 return TexturePair(raw, via_header_index); 320 return TexturePair(raw, via_header_index);
322 } 321 }
323 } 322 }
324 return TexturePair(gpu_memory.Read<u32>(addr), via_header_index); 323 return TexturePair(gpu_memory->Read<u32>(addr), via_header_index);
325 }}; 324 }};
326 const auto add_image{[&](const auto& desc, bool blacklist) LAMBDA_FORCEINLINE { 325 const auto add_image{[&](const auto& desc, bool blacklist) LAMBDA_FORCEINLINE {
327 for (u32 index = 0; index < desc.count; ++index) { 326 for (u32 index = 0; index < desc.count; ++index) {
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h
index e8949a9ab..85602592b 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h
@@ -69,15 +69,16 @@ class GraphicsPipeline {
69 static constexpr size_t NUM_STAGES = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage; 69 static constexpr size_t NUM_STAGES = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage;
70 70
71public: 71public:
72 explicit GraphicsPipeline( 72 explicit GraphicsPipeline(Scheduler& scheduler, BufferCache& buffer_cache,
73 Tegra::Engines::Maxwell3D& maxwell3d, Tegra::MemoryManager& gpu_memory, 73 TextureCache& texture_cache, VideoCore::ShaderNotify* shader_notify,
74 Scheduler& scheduler, BufferCache& buffer_cache, TextureCache& texture_cache, 74 const Device& device, DescriptorPool& descriptor_pool,
75 VideoCore::ShaderNotify* shader_notify, const Device& device, 75 UpdateDescriptorQueue& update_descriptor_queue,
76 DescriptorPool& descriptor_pool, UpdateDescriptorQueue& update_descriptor_queue, 76 Common::ThreadWorker* worker_thread,
77 Common::ThreadWorker* worker_thread, PipelineStatistics* pipeline_statistics, 77 PipelineStatistics* pipeline_statistics,
78 RenderPassCache& render_pass_cache, const GraphicsPipelineCacheKey& key, 78 RenderPassCache& render_pass_cache,
79 std::array<vk::ShaderModule, NUM_STAGES> stages, 79 const GraphicsPipelineCacheKey& key,
80 const std::array<const Shader::Info*, NUM_STAGES>& infos); 80 std::array<vk::ShaderModule, NUM_STAGES> stages,
81 const std::array<const Shader::Info*, NUM_STAGES>& infos);
81 82
82 GraphicsPipeline& operator=(GraphicsPipeline&&) noexcept = delete; 83 GraphicsPipeline& operator=(GraphicsPipeline&&) noexcept = delete;
83 GraphicsPipeline(GraphicsPipeline&&) noexcept = delete; 84 GraphicsPipeline(GraphicsPipeline&&) noexcept = delete;
@@ -109,6 +110,11 @@ public:
109 return [](GraphicsPipeline* pl, bool is_indexed) { pl->ConfigureImpl<Spec>(is_indexed); }; 110 return [](GraphicsPipeline* pl, bool is_indexed) { pl->ConfigureImpl<Spec>(is_indexed); };
110 } 111 }
111 112
113 void SetEngine(Tegra::Engines::Maxwell3D* maxwell3d_, Tegra::MemoryManager* gpu_memory_) {
114 maxwell3d = maxwell3d_;
115 gpu_memory = gpu_memory_;
116 }
117
112private: 118private:
113 template <typename Spec> 119 template <typename Spec>
114 void ConfigureImpl(bool is_indexed); 120 void ConfigureImpl(bool is_indexed);
@@ -120,8 +126,8 @@ private:
120 void Validate(); 126 void Validate();
121 127
122 const GraphicsPipelineCacheKey key; 128 const GraphicsPipelineCacheKey key;
123 Tegra::Engines::Maxwell3D& maxwell3d; 129 Tegra::Engines::Maxwell3D* maxwell3d;
124 Tegra::MemoryManager& gpu_memory; 130 Tegra::MemoryManager* gpu_memory;
125 const Device& device; 131 const Device& device;
126 TextureCache& texture_cache; 132 TextureCache& texture_cache;
127 BufferCache& buffer_cache; 133 BufferCache& buffer_cache;
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index b1e0b96c4..732e7b6f2 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -555,10 +555,10 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
555 previous_stage = &program; 555 previous_stage = &program;
556 } 556 }
557 Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr}; 557 Common::ThreadWorker* const thread_worker{build_in_parallel ? &workers : nullptr};
558 return std::make_unique<GraphicsPipeline>( 558 return std::make_unique<GraphicsPipeline>(scheduler, buffer_cache, texture_cache,
559 *maxwell3d, *gpu_memory, scheduler, buffer_cache, texture_cache, &shader_notify, device, 559 &shader_notify, device, descriptor_pool,
560 descriptor_pool, update_descriptor_queue, thread_worker, statistics, render_pass_cache, key, 560 update_descriptor_queue, thread_worker, statistics,
561 std::move(modules), infos); 561 render_pass_cache, key, std::move(modules), infos);
562 562
563} catch (const Shader::Exception& exception) { 563} catch (const Shader::Exception& exception) {
564 LOG_ERROR(Render_Vulkan, "{}", exception.what()); 564 LOG_ERROR(Render_Vulkan, "{}", exception.what());
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index bf750452f..7e0805544 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -190,6 +190,8 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) {
190 return; 190 return;
191 } 191 }
192 std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex}; 192 std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
193 // update engine as channel may be different.
194 pipeline->SetEngine(maxwell3d, gpu_memory);
193 pipeline->Configure(is_indexed); 195 pipeline->Configure(is_indexed);
194 196
195 BeginTransformFeedback(); 197 BeginTransformFeedback();
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 2731aead0..e8b0b0a3b 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -885,12 +885,14 @@ void TextureCache<P>::InvalidateScale(Image& image) {
885 } 885 }
886 image.image_view_ids.clear(); 886 image.image_view_ids.clear();
887 image.image_view_infos.clear(); 887 image.image_view_infos.clear();
888 if constexpr (ENABLE_VALIDATION) { 888 for (auto& this_state : channel_storage) {
889 std::ranges::fill(state->graphics_image_view_ids, CORRUPT_ID); 889 if constexpr (ENABLE_VALIDATION) {
890 std::ranges::fill(state->compute_image_view_ids, CORRUPT_ID); 890 std::ranges::fill(this_state.graphics_image_view_ids, CORRUPT_ID);
891 std::ranges::fill(this_state.compute_image_view_ids, CORRUPT_ID);
892 }
893 this_state.graphics_image_table.Invalidate();
894 this_state.compute_image_table.Invalidate();
891 } 895 }
892 state->graphics_image_table.Invalidate();
893 state->compute_image_table.Invalidate();
894 has_deleted_images = true; 896 has_deleted_images = true;
895} 897}
896 898