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 #include "src/gpu/graphite/vk/VulkanGraphicsPipeline.h" 13 14 #include "include/gpu/vk/VulkanTypes.h" 15 #include "src/core/SkLRUCache.h" 16 #include "src/core/SkTHash.h" 17 #include "src/gpu/graphite/DescriptorData.h" 18 19 #ifdef SK_BUILD_FOR_ANDROID 20 extern "C" { 21 typedef struct AHardwareBuffer AHardwareBuffer; 22 } 23 #endif 24 25 namespace skgpu::graphite { 26 27 class VulkanCommandBuffer; 28 class VulkanDescriptorSet; 29 class VulkanFramebuffer; 30 class VulkanGraphicsPipeline; 31 class VulkanRenderPass; 32 class VulkanSharedContext; 33 class VulkanTexture; 34 class VulkanYcbcrConversion; 35 36 class VulkanResourceProvider final : public ResourceProvider { 37 public: 38 static constexpr size_t kIntrinsicConstantSize = sizeof(float) * 8; // float4 + 2xfloat2 39 // Intrinsic constant rtAdjust value is needed by the vertex shader. Dst copy bounds are needed 40 // in the frag shader. 41 static constexpr VkShaderStageFlagBits kIntrinsicConstantStageFlags = 42 VkShaderStageFlagBits(VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT); 43 44 static constexpr size_t kLoadMSAAPushConstantSize = sizeof(float) * 4; 45 static constexpr VkShaderStageFlagBits kLoadMSAAPushConstantStageFlags = 46 VK_SHADER_STAGE_VERTEX_BIT; 47 48 49 using UniformBindGroupKey = FixedSizeKey<2 * VulkanGraphicsPipeline::kNumUniformBuffers>; 50 51 VulkanResourceProvider(SharedContext* sharedContext, 52 SingleOwner*, 53 uint32_t recorderID, 54 size_t resourceBudget); 55 56 ~VulkanResourceProvider() override; 57 58 sk_sp<VulkanYcbcrConversion> findOrCreateCompatibleYcbcrConversion( 59 const VulkanYcbcrConversionInfo& ycbcrInfo) const; 60 61 private: 62 const VulkanSharedContext* vulkanSharedContext() const; 63 64 sk_sp<GraphicsPipeline> createGraphicsPipeline(const RuntimeEffectDictionary*, 65 const UniqueKey&, 66 const GraphicsPipelineDesc&, 67 const RenderPassDesc&, 68 SkEnumBitMask<PipelineCreationFlags>, 69 uint32_t compilationID) override; 70 sk_sp<ComputePipeline> createComputePipeline(const ComputePipelineDesc&) override; 71 72 sk_sp<Texture> createTexture(SkISize, const TextureInfo&) override; 73 sk_sp<Texture> onCreateWrappedTexture(const BackendTexture&) override; 74 sk_sp<Buffer> createBuffer(size_t size, BufferType type, AccessPattern) override; 75 sk_sp<Sampler> createSampler(const SamplerDesc&) override; 76 77 sk_sp<VulkanFramebuffer> createFramebuffer( 78 const VulkanSharedContext*, 79 VulkanTexture* colorTexture, 80 VulkanTexture* resolveTexture, 81 VulkanTexture* depthStencilTexture, 82 const RenderPassDesc& renderPassDesc, 83 const VulkanRenderPass&, 84 const int width, 85 const int height); 86 87 BackendTexture onCreateBackendTexture(SkISize dimensions, const TextureInfo&) override; 88 #ifdef SK_BUILD_FOR_ANDROID 89 BackendTexture onCreateBackendTexture(AHardwareBuffer*, 90 bool isRenderable, 91 bool isProtectedContent, 92 SkISize dimensions, 93 bool fromAndroidWindow) const override; 94 #endif 95 void onDeleteBackendTexture(const BackendTexture&) override; 96 97 sk_sp<VulkanDescriptorSet> findOrCreateDescriptorSet(SkSpan<DescriptorData>); 98 99 sk_sp<VulkanDescriptorSet> findOrCreateUniformBuffersDescriptorSet( 100 SkSpan<DescriptorData> requestedDescriptors, 101 SkSpan<BindBufferInfo> bindUniformBufferInfo); 102 103 sk_sp<VulkanGraphicsPipeline> findOrCreateLoadMSAAPipeline(const RenderPassDesc&); 104 105 // Find or create a compatible (needed when creating a framebuffer and graphics pipeline) or 106 // full (needed when beginning a render pass from the command buffer) RenderPass. 107 sk_sp<VulkanRenderPass> findOrCreateRenderPass(const RenderPassDesc&, bool compatibleOnly); 108 109 // Use a predetermined RenderPass key for finding/creating a RenderPass to avoid recreating it 110 sk_sp<VulkanRenderPass> findOrCreateRenderPassWithKnownKey( 111 const RenderPassDesc&, bool compatibleOnly, const GraphiteResourceKey& rpKey); 112 113 VkPipelineCache pipelineCache(); mockPushConstantPipelineLayout()114 VkPipelineLayout mockPushConstantPipelineLayout() const { 115 return fMockPushConstantPipelineLayout; 116 } 117 118 friend class VulkanCommandBuffer; 119 friend class VulkanGraphicsPipeline; 120 VkPipelineCache fPipelineCache = VK_NULL_HANDLE; 121 122 // Create and store a pipeline layout that has compatible push constant parameters with other 123 // real pipeline layouts that can be reused across command buffers. 124 VkPipelineLayout fMockPushConstantPipelineLayout; 125 126 // The first value of the pair is a renderpass key. Graphics pipeline keys contain extra 127 // information that we do not need for identifying unique pipelines. 128 skia_private::TArray<std::pair<GraphiteResourceKey, 129 sk_sp<VulkanGraphicsPipeline>>> fLoadMSAAPipelines; 130 // All of the following attributes are the same between all msaa load pipelines, so they only 131 // need to be created once and can then be stored. 132 VkShaderModule fMSAALoadVertShaderModule = VK_NULL_HANDLE; 133 VkShaderModule fMSAALoadFragShaderModule = VK_NULL_HANDLE; 134 VkPipelineShaderStageCreateInfo fMSAALoadShaderStageInfo[2]; 135 VkPipelineLayout fMSAALoadPipelineLayout = VK_NULL_HANDLE; 136 137 SkLRUCache<UniformBindGroupKey, sk_sp<VulkanDescriptorSet>, 138 UniformBindGroupKey::Hash> fUniformBufferDescSetCache; 139 }; 140 141 } // namespace skgpu::graphite 142 143 #endif // skgpu_graphite_VulkanResourceProvider_DEFINED 144