summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-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
return std::memcmp(this, &rhs, Size()) == 0;
}
-GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_cache_,
- BufferCache& buffer_cache_, Tegra::MemoryManager& gpu_memory_,
- Tegra::Engines::Maxwell3D& maxwell3d_,
- ProgramManager& program_manager_, StateTracker& state_tracker_,
- ShaderWorker* thread_worker,
- VideoCore::ShaderNotify* shader_notify,
- std::array<std::string, 5> sources,
- const std::array<const Shader::Info*, 5>& infos,
- const VideoCommon::TransformFeedbackState* xfb_state)
- : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, gpu_memory{gpu_memory_},
- maxwell3d{maxwell3d_}, program_manager{program_manager_}, state_tracker{state_tracker_} {
+GraphicsPipeline::GraphicsPipeline(
+ const Device& device, TextureCache& texture_cache_, BufferCache& buffer_cache_,
+ Tegra::MemoryManager& gpu_memory_, Tegra::Engines::Maxwell3D& maxwell3d_,
+ ProgramManager& program_manager_, StateTracker& state_tracker_, ShaderWorker* thread_worker,
+ VideoCore::ShaderNotify* shader_notify, std::array<std::string, 5> sources,
+ const std::array<const Shader::Info*, 5>& infos, const GraphicsPipelineKey& key_)
+ : texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
+ gpu_memory{gpu_memory_}, maxwell3d{maxwell3d_}, program_manager{program_manager_},
+ state_tracker{state_tracker_}, key{key_} {
if (shader_notify) {
shader_notify->MarkShaderBuilding();
}
@@ -241,10 +239,10 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c
writes_global_memory &= !use_storage_buffers;
configure_func = ConfigureFunc(stage_infos, enabled_stages_mask);
- if (assembly_shaders && xfb_state) {
- GenerateTransformFeedbackState(*xfb_state);
+ if (assembly_shaders && key.xfb_enabled) {
+ GenerateTransformFeedbackState();
}
- auto func{[this, device, sources, shader_notify, xfb_state](ShaderContext::Context*) mutable {
+ auto func{[this, device, sources, shader_notify](ShaderContext::Context*) mutable {
if (!device.UseAssemblyShaders()) {
program.handle = glCreateProgram();
}
@@ -505,15 +503,14 @@ void GraphicsPipeline::ConfigureTransformFeedbackImpl() const {
xfb_streams.data(), GL_INTERLEAVED_ATTRIBS);
}
-void GraphicsPipeline::GenerateTransformFeedbackState(
- const VideoCommon::TransformFeedbackState& xfb_state) {
+void GraphicsPipeline::GenerateTransformFeedbackState() {
// TODO(Rodrigo): Inject SKIP_COMPONENTS*_NV when required. An unimplemented message will signal
// when this is required.
GLint* cursor{xfb_attribs.data()};
GLint* current_stream{xfb_streams.data()};
for (size_t feedback = 0; feedback < Maxwell::NumTransformFeedbackBuffers; ++feedback) {
- const auto& layout = xfb_state.layouts[feedback];
+ const auto& layout = key.xfb_state.layouts[feedback];
UNIMPLEMENTED_IF_MSG(layout.stride != layout.varying_count * 4, "Stride padding");
if (layout.varying_count == 0) {
continue;
@@ -528,7 +525,7 @@ void GraphicsPipeline::GenerateTransformFeedbackState(
}
++current_stream;
- const auto& locations = xfb_state.varyings[feedback];
+ const auto& locations = key.xfb_state.varyings[feedback];
std::optional<u8> current_index;
for (u32 offset = 0; offset < layout.varying_count; ++offset) {
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:
ShaderWorker* thread_worker, VideoCore::ShaderNotify* shader_notify,
std::array<std::string, 5> sources,
const std::array<const Shader::Info*, 5>& infos,
- const VideoCommon::TransformFeedbackState* xfb_state);
+ const GraphicsPipelineKey& key_);
void Configure(bool is_indexed) {
configure_func(this, is_indexed);
@@ -85,6 +85,10 @@ public:
}
}
+ [[nodiscard]] const GraphicsPipelineKey& Key() const noexcept {
+ return key;
+ }
+
[[nodiscard]] bool WritesGlobalMemory() const noexcept {
return writes_global_memory;
}
@@ -106,7 +110,7 @@ private:
void ConfigureTransformFeedbackImpl() const;
- void GenerateTransformFeedbackState(const VideoCommon::TransformFeedbackState& xfb_state);
+ void GenerateTransformFeedbackState();
TextureCache& texture_cache;
BufferCache& buffer_cache;
@@ -114,6 +118,7 @@ private:
Tegra::Engines::Maxwell3D& maxwell3d;
ProgramManager& program_manager;
StateTracker& state_tracker;
+ const GraphicsPipelineKey key;
void (*configure_func)(GraphicsPipeline*, bool){};
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,
GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() {
if (!RefreshStages(graphics_key.unique_hashes)) {
+ current_pipeline = nullptr;
return nullptr;
}
const auto& regs{maxwell3d.regs};
@@ -313,15 +314,23 @@ GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() {
if (graphics_key.xfb_enabled) {
SetXfbState(graphics_key.xfb_state, regs);
}
+ if (current_pipeline && graphics_key == current_pipeline->Key()) {
+ return current_pipeline->IsBuilt() ? current_pipeline : nullptr;
+ }
+ return CurrentGraphicsPipelineSlowPath();
+}
+
+GraphicsPipeline* ShaderCache::CurrentGraphicsPipelineSlowPath() {
const auto [pair, is_new]{graphics_cache.try_emplace(graphics_key)};
- auto& program{pair->second};
+ auto& pipeline{pair->second};
if (is_new) {
- program = CreateGraphicsPipeline();
+ pipeline = CreateGraphicsPipeline();
}
- if (!program || !program->IsBuilt()) {
+ current_pipeline = pipeline.get();
+ if (!pipeline || !pipeline->IsBuilt()) {
return nullptr;
}
- return program.get();
+ return pipeline.get();
}
ComputePipeline* ShaderCache::CurrentComputePipeline() {
@@ -432,8 +441,7 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
auto* const thread_worker{build_in_parallel ? workers.get() : nullptr};
return std::make_unique<GraphicsPipeline>(device, texture_cache, buffer_cache, gpu_memory,
maxwell3d, program_manager, state_tracker,
- thread_worker, &shader_notify, sources, infos,
- key.xfb_enabled != 0 ? &key.xfb_state : nullptr);
+ thread_worker, &shader_notify, sources, infos, key);
} catch (Shader::Exception& exception) {
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:
[[nodiscard]] ComputePipeline* CurrentComputePipeline();
private:
+ GraphicsPipeline* CurrentGraphicsPipelineSlowPath();
+
std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline();
std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline(
@@ -75,9 +77,10 @@ private:
ProgramManager& program_manager;
StateTracker& state_tracker;
VideoCore::ShaderNotify& shader_notify;
+ const bool use_asynchronous_shaders;
GraphicsPipelineKey graphics_key{};
- const bool use_asynchronous_shaders;
+ GraphicsPipeline* current_pipeline{};
ShaderContext::ShaderPools main_pools;
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:
BufferCache& buffer_cache;
TextureCache& texture_cache;
VideoCore::ShaderNotify& shader_notify;
+ bool use_asynchronous_shaders{};
GraphicsPipelineCacheKey graphics_key{};
GraphicsPipeline* current_pipeline{};
- bool use_asynchronous_shaders{};
-
std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<ComputePipeline>> compute_cache;
std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<GraphicsPipeline>> graphics_cache;