summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp33
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.h9
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp20
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h5
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.h3
5 files changed, 41 insertions, 29 deletions
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index 6b62fa1da..92974ba08 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -184,17 +184,15 @@ bool GraphicsPipelineKey::operator==(const GraphicsPipelineKey& rhs) const noexc
184 return std::memcmp(this, &rhs, Size()) == 0; 184 return std::memcmp(this, &rhs, Size()) == 0;
185} 185}
186 186
187GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_cache_, 187GraphicsPipeline::GraphicsPipeline(
188 BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_, 188 const Device& device, TextureCache& texture_cache_, BufferCache& buffer_cache_,
189 Tegra::Engines::Maxwell3D& maxwell3d_, 189 Tegra::MemoryManager& gpu_memory_, Tegra::Engines::Maxwell3D& maxwell3d_,
190 ProgramManager& program_manager_, StateTracker& state_tracker_, 190 ProgramManager& program_manager_, StateTracker& state_tracker_, ShaderWorker* thread_worker,
191 ShaderWorker* thread_worker, 191 VideoCore::ShaderNotify* shader_notify, std::array<std::string, 5> sources,
192 VideoCore::ShaderNotify* shader_notify, 192 const std::array<const Shader::Info*, 5>& infos, const GraphicsPipelineKey& key_)
193 std::array<std::string, 5> sources, 193 : texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
194 const std::array<const Shader::Info*, 5>& infos, 194 gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, program_manager{program_manager_},
195 const VideoCommon::TransformFeedbackState* xfb_state) 195 state_tracker{state_tracker_}, key{key_} {
196 : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_},
197 maxwell3d{maxwell3d_}, program_manager{program_manager_}, state_tracker{state_tracker_} {
198 if (shader_notify) { 196 if (shader_notify) {
199 shader_notify->MarkShaderBuilding(); 197 shader_notify->MarkShaderBuilding();
200 } 198 }
@@ -241,10 +239,10 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c
241 writes_global_memory &= !use_storage_buffers; 239 writes_global_memory &= !use_storage_buffers;
242 configure_func = ConfigureFunc(stage_infos, enabled_stages_mask); 240 configure_func = ConfigureFunc(stage_infos, enabled_stages_mask);
243 241
244 if (assembly_shaders && xfb_state) { 242 if (assembly_shaders && key.xfb_enabled) {
245 GenerateTransformFeedbackState(*xfb_state); 243 GenerateTransformFeedbackState();
246 } 244 }
247 auto func{[this, device, sources, shader_notify, xfb_state](ShaderContext::Context*) mutable { 245 auto func{[this, device, sources, shader_notify](ShaderContext::Context*) mutable {
248 if (!device.UseAssemblyShaders()) { 246 if (!device.UseAssemblyShaders()) {
249 program.handle = glCreateProgram(); 247 program.handle = glCreateProgram();
250 } 248 }
@@ -505,15 +503,14 @@ void GraphicsPipeline::ConfigureTransformFeedbackImpl() const {
505 xfb_streams.data(), GL_INTERLEAVED_ATTRIBS); 503 xfb_streams.data(), GL_INTERLEAVED_ATTRIBS);
506} 504}
507 505
508void GraphicsPipeline::GenerateTransformFeedbackState( 506void GraphicsPipeline::GenerateTransformFeedbackState() {
509 const VideoCommon::TransformFeedbackState& xfb_state) {
510 // TODO(Rodrigo): Inject SKIP_COMPONENTS*_NV when required. An unimplemented message will signal 507 // TODO(Rodrigo): Inject SKIP_COMPONENTS*_NV when required. An unimplemented message will signal
511 // when this is required. 508 // when this is required.
512 GLint* cursor{xfb_attribs.data()}; 509 GLint* cursor{xfb_attribs.data()};
513 GLint* current_stream{xfb_streams.data()}; 510 GLint* current_stream{xfb_streams.data()};
514 511
515 for (size_t feedback = 0; feedback < Maxwell::NumTransformFeedbackBuffers; ++feedback) { 512 for (size_t feedback = 0; feedback < Maxwell::NumTransformFeedbackBuffers; ++feedback) {
516 const auto& layout = xfb_state.layouts[feedback]; 513 const auto& layout = key.xfb_state.layouts[feedback];
517 UNIMPLEMENTED_IF_MSG(layout.stride != layout.varying_count * 4, "Stride padding"); 514 UNIMPLEMENTED_IF_MSG(layout.stride != layout.varying_count * 4, "Stride padding");
518 if (layout.varying_count == 0) { 515 if (layout.varying_count == 0) {
519 continue; 516 continue;
@@ -528,7 +525,7 @@ void GraphicsPipeline::GenerateTransformFeedbackState(
528 } 525 }
529 ++current_stream; 526 ++current_stream;
530 527
531 const auto& locations = xfb_state.varyings[feedback]; 528 const auto& locations = key.xfb_state.varyings[feedback];
532 std::optional<u8> current_index; 529 std::optional<u8> current_index;
533 for (u32 offset = 0; offset < layout.varying_count; ++offset) { 530 for (u32 offset = 0; offset < layout.varying_count; ++offset) {
534 const u8 location = locations[offset]; 531 const u8 location = locations[offset];
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.h b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
index a3546daa8..a033d4a95 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.h
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
@@ -73,7 +73,7 @@ public:
73 ShaderWorker* thread_worker, VideoCore::ShaderNotify* shader_notify, 73 ShaderWorker* thread_worker, VideoCore::ShaderNotify* shader_notify,
74 std::array<std::string, 5> sources, 74 std::array<std::string, 5> sources,
75 const std::array<const Shader::Info*, 5>& infos, 75 const std::array<const Shader::Info*, 5>& infos,
76 const VideoCommon::TransformFeedbackState* xfb_state); 76 const GraphicsPipelineKey& key_);
77 77
78 void Configure(bool is_indexed) { 78 void Configure(bool is_indexed) {
79 configure_func(this, is_indexed); 79 configure_func(this, is_indexed);
@@ -85,6 +85,10 @@ public:
85 } 85 }
86 } 86 }
87 87
88 [[nodiscard]] const GraphicsPipelineKey& Key() const noexcept {
89 return key;
90 }
91
88 [[nodiscard]] bool WritesGlobalMemory() const noexcept { 92 [[nodiscard]] bool WritesGlobalMemory() const noexcept {
89 return writes_global_memory; 93 return writes_global_memory;
90 } 94 }
@@ -106,7 +110,7 @@ private:
106 110
107 void ConfigureTransformFeedbackImpl() const; 111 void ConfigureTransformFeedbackImpl() const;
108 112
109 void GenerateTransformFeedbackState(const VideoCommon::TransformFeedbackState& xfb_state); 113 void GenerateTransformFeedbackState();
110 114
111 TextureCache& texture_cache; 115 TextureCache& texture_cache;
112 BufferCache& buffer_cache; 116 BufferCache& buffer_cache;
@@ -114,6 +118,7 @@ private:
114 Tegra::Engines::Maxwell3D& maxwell3d; 118 Tegra::Engines::Maxwell3D& maxwell3d;
115 ProgramManager& program_manager; 119 ProgramManager& program_manager;
116 StateTracker& state_tracker; 120 StateTracker& state_tracker;
121 const GraphicsPipelineKey key;
117 122
118 void (*configure_func)(GraphicsPipeline*, bool){}; 123 void (*configure_func)(GraphicsPipeline*, bool){};
119 124
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 8aaadccc4..c36b0d8cf 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -298,6 +298,7 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
298 298
299GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() { 299GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() {
300 if (!RefreshStages(graphics_key.unique_hashes)) { 300 if (!RefreshStages(graphics_key.unique_hashes)) {
301 current_pipeline = nullptr;
301 return nullptr; 302 return nullptr;
302 } 303 }
303 const auto& regs{maxwell3d.regs}; 304 const auto& regs{maxwell3d.regs};
@@ -313,15 +314,23 @@ GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() {
313 if (graphics_key.xfb_enabled) { 314 if (graphics_key.xfb_enabled) {
314 SetXfbState(graphics_key.xfb_state, regs); 315 SetXfbState(graphics_key.xfb_state, regs);
315 } 316 }
317 if (current_pipeline && graphics_key == current_pipeline->Key()) {
318 return current_pipeline->IsBuilt() ? current_pipeline : nullptr;
319 }
320 return CurrentGraphicsPipelineSlowPath();
321}
322
323GraphicsPipeline* ShaderCache::CurrentGraphicsPipelineSlowPath() {
316 const auto [pair, is_new]{graphics_cache.try_emplace(graphics_key)}; 324 const auto [pair, is_new]{graphics_cache.try_emplace(graphics_key)};
317 auto& program{pair->second}; 325 auto& pipeline{pair->second};
318 if (is_new) { 326 if (is_new) {
319 program = CreateGraphicsPipeline(); 327 pipeline = CreateGraphicsPipeline();
320 } 328 }
321 if (!program || !program->IsBuilt()) { 329 current_pipeline = pipeline.get();
330 if (!pipeline || !pipeline->IsBuilt()) {
322 return nullptr; 331 return nullptr;
323 } 332 }
324 return program.get(); 333 return pipeline.get();
325} 334}
326 335
327ComputePipeline* ShaderCache::CurrentComputePipeline() { 336ComputePipeline* ShaderCache::CurrentComputePipeline() {
@@ -432,8 +441,7 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
432 auto* const thread_worker{build_in_parallel ? workers.get() : nullptr}; 441 auto* const thread_worker{build_in_parallel ? workers.get() : nullptr};
433 return std::make_unique<GraphicsPipeline>(device, texture_cache, buffer_cache, gpu_memory, 442 return std::make_unique<GraphicsPipeline>(device, texture_cache, buffer_cache, gpu_memory,
434 maxwell3d, program_manager, state_tracker, 443 maxwell3d, program_manager, state_tracker,
435 thread_worker, &shader_notify, sources, infos, 444 thread_worker, &shader_notify, sources, infos, key);
436 key.xfb_enabled != 0 ? &key.xfb_state : nullptr);
437 445
438} catch (Shader::Exception& exception) { 446} catch (Shader::Exception& exception) {
439 LOG_ERROR(Render_OpenGL, "{}", exception.what()); 447 LOG_ERROR(Render_OpenGL, "{}", exception.what());
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h
index ff5707119..16873fcec 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_cache.h
@@ -53,6 +53,8 @@ public:
53 [[nodiscard]] ComputePipeline* CurrentComputePipeline(); 53 [[nodiscard]] ComputePipeline* CurrentComputePipeline();
54 54
55private: 55private:
56 GraphicsPipeline* CurrentGraphicsPipelineSlowPath();
57
56 std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline(); 58 std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline();
57 59
58 std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline( 60 std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline(
@@ -75,9 +77,10 @@ private:
75 ProgramManager& program_manager; 77 ProgramManager& program_manager;
76 StateTracker& state_tracker; 78 StateTracker& state_tracker;
77 VideoCore::ShaderNotify& shader_notify; 79 VideoCore::ShaderNotify& shader_notify;
80 const bool use_asynchronous_shaders;
78 81
79 GraphicsPipelineKey graphics_key{}; 82 GraphicsPipelineKey graphics_key{};
80 const bool use_asynchronous_shaders; 83 GraphicsPipeline* current_pipeline{};
81 84
82 ShaderContext::ShaderPools main_pools; 85 ShaderContext::ShaderPools main_pools;
83 std::unordered_map<GraphicsPipelineKey, std::unique_ptr<GraphicsPipeline>> graphics_cache; 86 std::unordered_map<GraphicsPipelineKey, std::unique_ptr<GraphicsPipeline>> graphics_cache;
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
index 42da2960b..efe5a7ed8 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
@@ -146,12 +146,11 @@ private:
146 BufferCache& buffer_cache; 146 BufferCache& buffer_cache;
147 TextureCache& texture_cache; 147 TextureCache& texture_cache;
148 VideoCore::ShaderNotify& shader_notify; 148 VideoCore::ShaderNotify& shader_notify;
149 bool use_asynchronous_shaders{};
149 150
150 GraphicsPipelineCacheKey graphics_key{}; 151 GraphicsPipelineCacheKey graphics_key{};
151 GraphicsPipeline* current_pipeline{}; 152 GraphicsPipeline* current_pipeline{};
152 153
153 bool use_asynchronous_shaders{};
154
155 std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<ComputePipeline>> compute_cache; 154 std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<ComputePipeline>> compute_cache;
156 std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<GraphicsPipeline>> graphics_cache; 155 std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<GraphicsPipeline>> graphics_cache;
157 156