1 /* 2 * Copyright 2022 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef skgpu_graphite_VulkanResourceProvider_DEFINED 9 #define skgpu_graphite_VulkanResourceProvider_DEFINED 10 11 #include "src/gpu/graphite/ResourceProvider.h" 12 13 #include "include/gpu/vk/VulkanTypes.h" 14 #include "src/core/SkLRUCache.h" 15 #include "src/core/SkTHash.h" 16 #include "src/gpu/graphite/DescriptorData.h" 17 18 #ifdef SK_BUILD_FOR_ANDROID 19 extern "C" { 20 typedef struct AHardwareBuffer AHardwareBuffer; 21 } 22 #endif 23 24 namespace skgpu::graphite { 25 26 class VulkanCommandBuffer; 27 class VulkanDescriptorSet; 28 class VulkanFramebuffer; 29 class VulkanGraphicsPipeline; 30 class VulkanRenderPass; 31 class VulkanSharedContext; 32 class VulkanYcbcrConversion; 33 34 class VulkanResourceProvider final : public ResourceProvider { 35 public: 36 static constexpr size_t kIntrinsicConstantSize = sizeof(float) * 4; 37 static constexpr size_t kLoadMSAAVertexBufferSize = sizeof(float) * 8; // 4 points of 2 floats 38 39 VulkanResourceProvider(SharedContext* sharedContext, 40 SingleOwner*, 41 uint32_t recorderID, 42 size_t resourceBudget, 43 sk_sp<Buffer> intrinsicConstantUniformBuffer, 44 sk_sp<Buffer> loadMSAAVertexBuffer); 45 46 ~VulkanResourceProvider() override; 47 48 sk_sp<Buffer> refIntrinsicConstantBuffer() const; 49 50 const Buffer* loadMSAAVertexBuffer() const; 51 52 sk_sp<VulkanYcbcrConversion> findOrCreateCompatibleYcbcrConversion( 53 const VulkanYcbcrConversionInfo& ycbcrInfo) const; 54 55 private: 56 const VulkanSharedContext* vulkanSharedContext() const; 57 58 sk_sp<GraphicsPipeline> createGraphicsPipeline(const RuntimeEffectDictionary*, 59 const GraphicsPipelineDesc&, 60 const RenderPassDesc&) override; 61 sk_sp<ComputePipeline> createComputePipeline(const ComputePipelineDesc&) override; 62 63 sk_sp<Texture> createTexture(SkISize, 64 const TextureInfo&, 65 skgpu::Budgeted) override; 66 sk_sp<Texture> onCreateWrappedTexture(const BackendTexture&) override; 67 sk_sp<Buffer> createBuffer(size_t size, BufferType type, AccessPattern) override; 68 sk_sp<Sampler> createSampler(const SamplerDesc&) override; 69 70 sk_sp<VulkanFramebuffer> createFramebuffer( 71 const VulkanSharedContext*, 72 const skia_private::TArray<VkImageView>& attachmentViews, 73 const VulkanRenderPass&, 74 const int width, 75 const int height); 76 77 BackendTexture onCreateBackendTexture(SkISize dimensions, const TextureInfo&) override; 78 #ifdef SK_BUILD_FOR_ANDROID 79 BackendTexture onCreateBackendTexture(AHardwareBuffer*, 80 bool isRenderable, 81 bool isProtectedContent, 82 SkISize dimensions, 83 bool fromAndroidWindow) const override; 84 #endif 85 void onDeleteBackendTexture(const BackendTexture&) override; 86 87 sk_sp<VulkanDescriptorSet> findOrCreateDescriptorSet(SkSpan<DescriptorData>); 88 89 sk_sp<VulkanDescriptorSet> findOrCreateUniformBuffersDescriptorSet( 90 SkSpan<DescriptorData> requestedDescriptors, 91 SkSpan<BindUniformBufferInfo> bindUniformBufferInfo); 92 93 sk_sp<VulkanGraphicsPipeline> findOrCreateLoadMSAAPipeline(const RenderPassDesc&); 94 95 // Find or create a compatible (needed when creating a framebuffer and graphics pipeline) or 96 // full (needed when beginning a render pass from the command buffer) RenderPass. 97 sk_sp<VulkanRenderPass> findOrCreateRenderPass(const RenderPassDesc&, bool compatibleOnly); 98 99 // Use a predetermined RenderPass key for finding/creating a RenderPass to avoid recreating it 100 sk_sp<VulkanRenderPass> findOrCreateRenderPassWithKnownKey( 101 const RenderPassDesc&, bool compatibleOnly, const GraphiteResourceKey& rpKey); 102 103 VkPipelineCache pipelineCache(); 104 105 friend class VulkanCommandBuffer; 106 VkPipelineCache fPipelineCache = VK_NULL_HANDLE; 107 108 // Each render pass will need buffer space to record rtAdjust information. To minimize costly 109 // allocation calls and searching of the resource cache, we find & store a uniform buffer upon 110 // resource provider creation. This way, render passes across all command buffers can simply 111 // update the value within this buffer as needed. 112 sk_sp<Buffer> fIntrinsicUniformBuffer; 113 // Similary, use a shared buffer b/w all renderpasses to store vertices for loading MSAA from 114 // resolve. 115 sk_sp<Buffer> fLoadMSAAVertexBuffer; 116 117 // The first value of the pair is a renderpass key. Graphics pipeline keys contain extra 118 // information that we do not need for identifying unique pipelines. 119 skia_private::TArray<std::pair<GraphiteResourceKey, 120 sk_sp<VulkanGraphicsPipeline>>> fLoadMSAAPipelines; 121 // All of the following attributes are the same between all msaa load pipelines, so they only 122 // need to be created once and can then be stored. 123 VkShaderModule fMSAALoadVertShaderModule = VK_NULL_HANDLE; 124 VkShaderModule fMSAALoadFragShaderModule = VK_NULL_HANDLE; 125 VkPipelineShaderStageCreateInfo fMSAALoadShaderStageInfo[2]; 126 VkPipelineLayout fMSAALoadPipelineLayout = VK_NULL_HANDLE; 127 128 struct UniqueKeyHash { operatorUniqueKeyHash129 uint32_t operator()(const skgpu::UniqueKey& key) const { return key.hash(); } 130 }; 131 using DescriptorSetCache = SkLRUCache<UniqueKey, sk_sp<VulkanDescriptorSet>, UniqueKeyHash>; 132 DescriptorSetCache fUniformBufferDescSetCache; 133 }; 134 135 } // namespace skgpu::graphite 136 137 #endif // skgpu_graphite_VulkanResourceProvider_DEFINED 138