Compare commits
1 Commits
master
...
pipelinede
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a20d3f6799 |
@@ -248,10 +248,12 @@ GraphicsPipeline::GraphicsPipeline(
|
|||||||
GuestDescriptorQueue& guest_descriptor_queue_, Common::ThreadWorker* worker_thread,
|
GuestDescriptorQueue& guest_descriptor_queue_, Common::ThreadWorker* worker_thread,
|
||||||
PipelineStatistics* pipeline_statistics, RenderPassCache& render_pass_cache,
|
PipelineStatistics* pipeline_statistics, RenderPassCache& render_pass_cache,
|
||||||
const GraphicsPipelineCacheKey& key_, std::array<vk::ShaderModule, NUM_STAGES> stages,
|
const GraphicsPipelineCacheKey& key_, std::array<vk::ShaderModule, NUM_STAGES> stages,
|
||||||
const std::array<const Shader::Info*, NUM_STAGES>& infos)
|
const std::array<const Shader::Info*, NUM_STAGES>& infos,
|
||||||
: key{key_}, device{device_}, texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
|
GraphicsPipeline* base_pipeline_)
|
||||||
pipeline_cache(pipeline_cache_), scheduler{scheduler_},
|
: key{key_}, base_pipeline{base_pipeline_}, allow_derivatives{base_pipeline_ == nullptr},
|
||||||
guest_descriptor_queue{guest_descriptor_queue_}, spv_modules{std::move(stages)} {
|
device{device_}, texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
|
||||||
|
pipeline_cache(pipeline_cache_), scheduler{scheduler_},
|
||||||
|
guest_descriptor_queue{guest_descriptor_queue_}, spv_modules{std::move(stages)} {
|
||||||
if (shader_notify) {
|
if (shader_notify) {
|
||||||
shader_notify->MarkShaderBuilding();
|
shader_notify->MarkShaderBuilding();
|
||||||
}
|
}
|
||||||
@@ -935,6 +937,18 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||||||
if (device.IsKhrPipelineExecutablePropertiesEnabled() && Settings::values.renderer_debug.GetValue()) {
|
if (device.IsKhrPipelineExecutablePropertiesEnabled() && Settings::values.renderer_debug.GetValue()) {
|
||||||
flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
|
flags |= VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR;
|
||||||
}
|
}
|
||||||
|
VkPipeline base_handle = VK_NULL_HANDLE;
|
||||||
|
|
||||||
|
// First pipeline in a "cluster" allows derivatives
|
||||||
|
if (allow_derivatives) {
|
||||||
|
flags |= VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Children mark themselves as derivatives when base is already built
|
||||||
|
if (base_pipeline != nullptr && base_pipeline->IsBuilt()) {
|
||||||
|
flags |= VK_PIPELINE_CREATE_DERIVATIVE_BIT;
|
||||||
|
base_handle = *base_pipeline->pipeline;
|
||||||
|
}
|
||||||
|
|
||||||
pipeline = device.GetLogical().CreateGraphicsPipeline(
|
pipeline = device.GetLogical().CreateGraphicsPipeline(
|
||||||
{
|
{
|
||||||
@@ -955,8 +969,8 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||||||
.layout = *pipeline_layout,
|
.layout = *pipeline_layout,
|
||||||
.renderPass = render_pass,
|
.renderPass = render_pass,
|
||||||
.subpass = 0,
|
.subpass = 0,
|
||||||
.basePipelineHandle = nullptr,
|
.basePipelineHandle = base_handle,
|
||||||
.basePipelineIndex = 0,
|
.basePipelineIndex = -1,
|
||||||
},
|
},
|
||||||
*pipeline_cache);
|
*pipeline_cache);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,9 +79,14 @@ public:
|
|||||||
GuestDescriptorQueue& guest_descriptor_queue, Common::ThreadWorker* worker_thread,
|
GuestDescriptorQueue& guest_descriptor_queue, Common::ThreadWorker* worker_thread,
|
||||||
PipelineStatistics* pipeline_statistics, RenderPassCache& render_pass_cache,
|
PipelineStatistics* pipeline_statistics, RenderPassCache& render_pass_cache,
|
||||||
const GraphicsPipelineCacheKey& key, std::array<vk::ShaderModule, NUM_STAGES> stages,
|
const GraphicsPipelineCacheKey& key, std::array<vk::ShaderModule, NUM_STAGES> stages,
|
||||||
const std::array<const Shader::Info*, NUM_STAGES>& infos);
|
const std::array<const Shader::Info*, NUM_STAGES>& infos,
|
||||||
|
GraphicsPipeline* base_pipeline = nullptr);
|
||||||
|
|
||||||
|
|
||||||
bool HasDynamicVertexInput() const noexcept { return key.state.dynamic_vertex_input; }
|
bool HasDynamicVertexInput() const noexcept { return key.state.dynamic_vertex_input; }
|
||||||
|
[[nodiscard]] const GraphicsPipelineCacheKey& Key() const noexcept {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
GraphicsPipeline& operator=(GraphicsPipeline&&) noexcept = delete;
|
GraphicsPipeline& operator=(GraphicsPipeline&&) noexcept = delete;
|
||||||
GraphicsPipeline(GraphicsPipeline&&) noexcept = delete;
|
GraphicsPipeline(GraphicsPipeline&&) noexcept = delete;
|
||||||
|
|
||||||
@@ -129,6 +134,8 @@ private:
|
|||||||
void Validate();
|
void Validate();
|
||||||
|
|
||||||
const GraphicsPipelineCacheKey key;
|
const GraphicsPipelineCacheKey key;
|
||||||
|
GraphicsPipeline* base_pipeline = nullptr; // non-owning
|
||||||
|
bool allow_derivatives = false;
|
||||||
Tegra::Engines::Maxwell3D* maxwell3d;
|
Tegra::Engines::Maxwell3D* maxwell3d;
|
||||||
Tegra::MemoryManager* gpu_memory;
|
Tegra::MemoryManager* gpu_memory;
|
||||||
const Device& device;
|
const Device& device;
|
||||||
|
|||||||
@@ -575,8 +575,18 @@ GraphicsPipeline* PipelineCache::CurrentGraphicsPipelineSlowPath() {
|
|||||||
const auto [pair, is_new]{graphics_cache.try_emplace(graphics_key)};
|
const auto [pair, is_new]{graphics_cache.try_emplace(graphics_key)};
|
||||||
auto& pipeline{pair->second};
|
auto& pipeline{pair->second};
|
||||||
if (is_new) {
|
if (is_new) {
|
||||||
pipeline = CreateGraphicsPipeline();
|
GraphicsPipeline* base = nullptr;
|
||||||
|
|
||||||
|
// Use the current pipeline as a base if shaders match
|
||||||
|
if (current_pipeline) {
|
||||||
|
const auto& base_key = current_pipeline->Key();
|
||||||
|
if (base_key.unique_hashes == graphics_key.unique_hashes) {
|
||||||
|
base = current_pipeline;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
pipeline = CreateGraphicsPipeline(base);
|
||||||
|
}
|
||||||
|
|
||||||
if (!pipeline) {
|
if (!pipeline) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -607,7 +617,7 @@ GraphicsPipeline* PipelineCache::BuiltPipeline(GraphicsPipeline* pipeline) const
|
|||||||
std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
||||||
ShaderPools& pools, const GraphicsPipelineCacheKey& key,
|
ShaderPools& pools, const GraphicsPipelineCacheKey& key,
|
||||||
std::span<Shader::Environment* const> envs, PipelineStatistics* statistics,
|
std::span<Shader::Environment* const> envs, PipelineStatistics* statistics,
|
||||||
bool build_in_parallel) try {
|
bool build_in_parallel, GraphicsPipeline* base_pipeline) try {
|
||||||
auto hash = key.Hash();
|
auto hash = key.Hash();
|
||||||
LOG_INFO(Render_Vulkan, "0x{:016x}", hash);
|
LOG_INFO(Render_Vulkan, "0x{:016x}", hash);
|
||||||
size_t env_index{0};
|
size_t env_index{0};
|
||||||
@@ -686,7 +696,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
|||||||
return std::make_unique<GraphicsPipeline>(
|
return std::make_unique<GraphicsPipeline>(
|
||||||
scheduler, buffer_cache, texture_cache, vulkan_pipeline_cache, &shader_notify, device,
|
scheduler, buffer_cache, texture_cache, vulkan_pipeline_cache, &shader_notify, device,
|
||||||
descriptor_pool, guest_descriptor_queue, thread_worker, statistics, render_pass_cache, key,
|
descriptor_pool, guest_descriptor_queue, thread_worker, statistics, render_pass_cache, key,
|
||||||
std::move(modules), infos);
|
std::move(modules), infos, base_pipeline);
|
||||||
|
|
||||||
} catch (const Shader::Exception& exception) {
|
} catch (const Shader::Exception& exception) {
|
||||||
auto hash = key.Hash();
|
auto hash = key.Hash();
|
||||||
@@ -707,16 +717,23 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
|
std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
|
||||||
|
// Preserve old behaviour, no base pipeline
|
||||||
|
return CreateGraphicsPipeline(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
||||||
|
GraphicsPipeline* base_pipeline) {
|
||||||
GraphicsEnvironments environments;
|
GraphicsEnvironments environments;
|
||||||
GetGraphicsEnvironments(environments, graphics_key.unique_hashes);
|
GetGraphicsEnvironments(environments, graphics_key.unique_hashes);
|
||||||
|
|
||||||
main_pools.ReleaseContents();
|
main_pools.ReleaseContents();
|
||||||
auto pipeline{
|
auto pipeline{CreateGraphicsPipeline(main_pools, graphics_key, environments.Span(),
|
||||||
CreateGraphicsPipeline(main_pools, graphics_key, environments.Span(), nullptr, true)};
|
nullptr, true, base_pipeline)};
|
||||||
if (!pipeline || pipeline_cache_filename.empty()) {
|
if (!pipeline || pipeline_cache_filename.empty()) {
|
||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
serialization_thread.QueueWork([this, key = graphics_key, envs = std::move(environments.envs)] {
|
serialization_thread.QueueWork(
|
||||||
|
[this, key = graphics_key, envs = std::move(environments.envs)] {
|
||||||
boost::container::static_vector<const GenericEnvironment*, Maxwell::MaxShaderProgram>
|
boost::container::static_vector<const GenericEnvironment*, Maxwell::MaxShaderProgram>
|
||||||
env_ptrs;
|
env_ptrs;
|
||||||
for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
|
for (size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
|
||||||
|
|||||||
@@ -119,11 +119,12 @@ private:
|
|||||||
[[nodiscard]] GraphicsPipeline* BuiltPipeline(GraphicsPipeline* pipeline) const noexcept;
|
[[nodiscard]] GraphicsPipeline* BuiltPipeline(GraphicsPipeline* pipeline) const noexcept;
|
||||||
|
|
||||||
std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline();
|
std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline();
|
||||||
|
std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline(GraphicsPipeline* base_pipeline);
|
||||||
|
|
||||||
std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline(
|
std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline(
|
||||||
ShaderPools& pools, const GraphicsPipelineCacheKey& key,
|
ShaderPools& pools, const GraphicsPipelineCacheKey& key,
|
||||||
std::span<Shader::Environment* const> envs, PipelineStatistics* statistics,
|
std::span<Shader::Environment* const> envs, PipelineStatistics* statistics,
|
||||||
bool build_in_parallel);
|
bool build_in_parallel, GraphicsPipeline* base_pipeline = nullptr);
|
||||||
|
|
||||||
std::unique_ptr<ComputePipeline> CreateComputePipeline(const ComputePipelineCacheKey& key,
|
std::unique_ptr<ComputePipeline> CreateComputePipeline(const ComputePipelineCacheKey& key,
|
||||||
const ShaderInfo* shader);
|
const ShaderInfo* shader);
|
||||||
|
|||||||
Reference in New Issue
Block a user