blob: 7581574d1c424a4333da5902802958174e0ccaf9 [file] [log] [blame]
/*
* Copyright 2025 Rive
*/
#pragma once
#include "rive/renderer/async_pipeline_manager.hpp"
#include "draw_pipeline_vulkan.hpp"
#include "render_pass_vulkan.hpp"
namespace rive::gpu
{
class PipelineManagerVulkan : public AsyncPipelineManager<DrawPipelineVulkan>
{
using Super = AsyncPipelineManager<DrawPipelineVulkan>;
public:
PipelineManagerVulkan(rcp<VulkanContext>,
ShaderCompilationMode,
VkImageView nullTextureView);
~PipelineManagerVulkan();
RenderPassVulkan& getRenderPassSynchronous(InterlockMode,
RenderPassOptionsVulkan,
VkFormat,
LoadAction);
DrawPipelineLayoutVulkan& getDrawPipelineLayoutSynchronous(
InterlockMode,
RenderPassOptionsVulkan);
uint32_t vendorID() const
{
return m_vk->physicalDeviceProperties().vendorID;
}
VkFormat atlasFormat() const { return m_atlasFormat; }
VulkanContext* vulkanContext() const { return m_vk.get(); }
VkDescriptorSetLayout perFlushDescriptorSetLayout() const
{
return m_perFlushDescriptorSetLayout;
}
VkDescriptorSetLayout perDrawDescriptorSetLayout() const
{
return m_perDrawDescriptorSetLayout;
}
VkDescriptorSetLayout immutableSamplerDescriptorSetLayout() const
{
return m_immutableSamplerDescriptorSetLayout;
}
VkDescriptorSetLayout emptyDescriptorSetLayout() const
{
return m_emptyDescriptorSetLayout;
}
VkSampler linearSampler() const { return m_linearSampler; }
VkSampler imageSampler(uint32_t i) const { return m_imageSamplers[i]; }
VkDescriptorSet nullImageDescriptorSet() const
{
return m_nullImageDescriptorSet;
}
VkDescriptorSet immutableSamplerDescriptorSet() const
{
return m_immutableSamplerDescriptorSet;
}
enum class PLSBackingType : bool
{
inputAttachment,
storageTexture,
};
PLSBackingType plsBackingType(gpu::InterlockMode interlockMode)
{
if (interlockMode == gpu::InterlockMode::clockwise)
{
assert(m_vk->features.fragmentShaderPixelInterlock);
return PLSBackingType::storageTexture;
}
return PLSBackingType::inputAttachment;
}
private:
virtual std::unique_ptr<DrawShaderVulkan> createVertexShader(
DrawType drawType,
ShaderFeatures shaderFeatures,
InterlockMode interlockMode) override;
virtual std::unique_ptr<DrawShaderVulkan> createFragmentShader(
DrawType drawType,
ShaderFeatures shaderFeatures,
InterlockMode interlockMode,
ShaderMiscFlags miscFlags) override;
virtual std::unique_ptr<DrawPipelineVulkan> createPipeline(
PipelineCreateType createType,
uint64_t key,
const PipelineProps& props) override;
virtual PipelineStatus getPipelineStatus(
const DrawPipelineVulkan&) const override;
virtual void clearCacheInternal() override;
std::unordered_map<uint32_t, std::unique_ptr<DrawPipelineLayoutVulkan>>
m_drawPipelineLayouts;
std::unordered_map<uint32_t, std::unique_ptr<RenderPassVulkan>>
m_renderPasses;
rcp<VulkanContext> m_vk;
VkFormat m_atlasFormat;
// Samplers.
VkSampler m_linearSampler;
VkSampler m_imageSamplers[ImageSampler::MAX_SAMPLER_PERMUTATIONS];
// With the exception of PLS texture bindings, which differ by interlock
// mode, all other shaders use the same shared descriptor set layouts.
VkDescriptorSetLayout m_perFlushDescriptorSetLayout;
VkDescriptorSetLayout m_perDrawDescriptorSetLayout;
VkDescriptorSetLayout m_immutableSamplerDescriptorSetLayout;
VkDescriptorSetLayout m_emptyDescriptorSetLayout; // For when a set isn't
// used by a shader.
VkDescriptorPool m_staticDescriptorPool; // For descriptorSets that never
// change between frames.
VkDescriptorSet m_nullImageDescriptorSet;
VkDescriptorSet m_immutableSamplerDescriptorSet; // Empty since samplers are
// immutable, but also
// required by Vulkan.
};
} // namespace rive::gpu