1 // Copyright 2018 The Dawn Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef DAWNNATIVE_VULKAN_RENDERPASSCACHE_H_ 16 #define DAWNNATIVE_VULKAN_RENDERPASSCACHE_H_ 17 18 #include "common/Constants.h" 19 #include "common/ityp_array.h" 20 #include "common/ityp_bitset.h" 21 #include "common/vulkan_platform.h" 22 #include "dawn_native/Error.h" 23 #include "dawn_native/IntegerTypes.h" 24 #include "dawn_native/dawn_platform.h" 25 26 #include <array> 27 #include <bitset> 28 #include <mutex> 29 #include <unordered_map> 30 31 namespace dawn_native { namespace vulkan { 32 33 class Device; 34 35 // This is a key to query the RenderPassCache, it can be sparse meaning that only the 36 // information for bits set in colorMask or hasDepthStencil need to be provided and the rest can 37 // be uninintialized. 38 struct RenderPassCacheQuery { 39 // Use these helpers to build the query, they make sure all relevant data is initialized and 40 // masks set. 41 void SetColor(ColorAttachmentIndex index, 42 wgpu::TextureFormat format, 43 wgpu::LoadOp loadOp, 44 wgpu::StoreOp storeOp, 45 bool hasResolveTarget); 46 void SetDepthStencil(wgpu::TextureFormat format, 47 wgpu::LoadOp depthLoadOp, 48 wgpu::StoreOp depthStoreOp, 49 wgpu::LoadOp stencilLoadOp, 50 wgpu::StoreOp stencilStoreOp, 51 bool readOnly); 52 void SetSampleCount(uint32_t sampleCount); 53 54 ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments> colorMask; 55 ityp::bitset<ColorAttachmentIndex, kMaxColorAttachments> resolveTargetMask; 56 ityp::array<ColorAttachmentIndex, wgpu::TextureFormat, kMaxColorAttachments> colorFormats; 57 ityp::array<ColorAttachmentIndex, wgpu::LoadOp, kMaxColorAttachments> colorLoadOp; 58 ityp::array<ColorAttachmentIndex, wgpu::StoreOp, kMaxColorAttachments> colorStoreOp; 59 60 bool hasDepthStencil = false; 61 wgpu::TextureFormat depthStencilFormat; 62 wgpu::LoadOp depthLoadOp; 63 wgpu::StoreOp depthStoreOp; 64 wgpu::LoadOp stencilLoadOp; 65 wgpu::StoreOp stencilStoreOp; 66 bool readOnlyDepthStencil; 67 68 uint32_t sampleCount; 69 }; 70 71 // Caches VkRenderPasses so that we don't create duplicate ones for every RenderPipeline or 72 // render pass. We always arrange the order of attachments in "color-depthstencil-resolve" order 73 // when creating render pass and framebuffer so that we can always make sure the order of 74 // attachments in the rendering pipeline matches the one of the framebuffer. 75 // All the operations on RenderPassCache are guaranteed to be thread-safe. 76 // TODO(cwallez@chromium.org): Make it an LRU cache somehow? 77 class RenderPassCache { 78 public: 79 RenderPassCache(Device* device); 80 ~RenderPassCache(); 81 82 ResultOrError<VkRenderPass> GetRenderPass(const RenderPassCacheQuery& query); 83 84 private: 85 // Does the actual VkRenderPass creation on a cache miss. 86 ResultOrError<VkRenderPass> CreateRenderPassForQuery( 87 const RenderPassCacheQuery& query) const; 88 89 // Implements the functors necessary for to use RenderPassCacheQueries as unordered_map 90 // keys. 91 struct CacheFuncs { 92 size_t operator()(const RenderPassCacheQuery& query) const; 93 bool operator()(const RenderPassCacheQuery& a, const RenderPassCacheQuery& b) const; 94 }; 95 using Cache = 96 std::unordered_map<RenderPassCacheQuery, VkRenderPass, CacheFuncs, CacheFuncs>; 97 98 Device* mDevice = nullptr; 99 100 std::mutex mMutex; 101 Cache mCache; 102 }; 103 104 }} // namespace dawn_native::vulkan 105 106 #endif // DAWNNATIVE_VULKAN_RENDERPASSCACHE_H_ 107