Overte C++ Documentation
VKPipelineCache.h
1 // Created by dr Karol Suprynowicz on 2024/12/27.
2 // Based on work by by Bradley Austin Davis
3 // Copyright 2018 High Fidelity, Inc.
4 // Copyright 2023-2025 Overte e.V.
5 //
6 // Distributed under the Apache License, Version 2.0.
7 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
8 // SPDX-License-Identifier: Apache-2.0
9 //
10 
11 #pragma once
12 
13 // For hash_combine
14 #include <RegisteredMetaTypes.h>
15 
16 #include <gpu/Forward.h>
17 #include <gpu/Context.h>
18 
19 #include <vk/Config.h>
20 #include <vk/Context.h>
21 #include <vk/VulkanDebug.h>
22 #include <vulkan/vulkan_core.h>
23 
24 #include "VKForward.h"
25 
26 //define OVERTE_VK_PIPELINE_DEBUG
27 
28 template <>
29 struct std::hash<gpu::Element> {
30  size_t operator()(const gpu::Element& a) const { return std::hash<uint32_t>()(a.getRaw()); }
31 };
32 
33 template <>
34 struct std::hash<::VkImageLayout> {
35  size_t operator()(const VkImageLayout& a) const { return std::hash<uint32_t>()((uint32_t)a); }
36 };
37 
38 namespace gpu { namespace vk {
39 
40 inline size_t hashRenderPassPair(const std::pair<VkFormat,VkImageLayout>& a) {
41  size_t seed = 0;
42  hash_combine(seed, a.first);
43  hash_combine(seed, a.second);
44  return seed;
45 }
46 
47 template <typename Container>
48 struct RenderPassHash {
49  std::size_t operator()(const Container& c) const {
50  size_t seed = 0;
51  for (const auto& e : c) {
52  hash_combine(seed, hashRenderPassPair(e));
53  }
54  return seed;
55  }
56 };
57 
58 struct Cache {
59  struct Pipeline;
60  using BindingMap = std::unordered_map<uint32_t, VkShaderStageFlags>;
61  class PipelineLayout {
62  public:
63  VkPipeline pipeline{ VK_NULL_HANDLE };
64  VkPipelineLayout pipelineLayout{ VK_NULL_HANDLE };
65  VkDescriptorSetLayout uniformLayout{ };
66  VkDescriptorSetLayout textureLayout{ };
67  VkDescriptorSetLayout storageLayout{ };
68 
69  shader::Reflection vertexReflection;
70  shader::Reflection fragmentReflection;
71 
72  BindingMap uniformBindingMap;
73  BindingMap textureBindingMap;
74  BindingMap storageBindingMap;
75 #ifdef OVERTE_VK_PIPELINE_DEBUG
76  std::string vertexShader;
77  std::string fragmentShader;
78 #endif
79  private:
80  PipelineLayout() {};
81  friend struct Cache::Pipeline;
82  };
83  std::unordered_map<uint32_t, VkShaderModule> moduleMap;
84  std::unordered_map<std::string, PipelineLayout> pipelineMap;
85 
86  struct Pipeline {
87  using RenderpassKey = std::vector<std::pair<VkFormat, VkImageLayout>>;
88  using LocationMap = shader::Reflection::LocationMap;
89 
90  gpu::PipelineReference pipeline{ GPU_REFERENCE_INIT_VALUE };
91  std::shared_ptr<Shader> program;
92  gpu::FormatReference format{ GPU_REFERENCE_INIT_VALUE };
93  gpu::FramebufferReference framebuffer{ GPU_REFERENCE_INIT_VALUE };
94  gpu::Primitive primitiveTopology;
95 
96 
97  // VKTODO: maybe these should be moved from here to cache object?
98  std::unordered_map<RenderpassKey, VkRenderPass, RenderPassHash<std::vector<std::pair<VkFormat, VkImageLayout>>>> _renderPassMap; // VKTODO: make sure render passes are retrieved from here
99 
100  // These get set when stride gets set by setInputBuffer
101  std::array<Offset, MAX_NUM_INPUT_BUFFERS> _bufferStrides{ 0 };
102  std::bitset<MAX_NUM_INPUT_BUFFERS> _bufferStrideSet;
103 
104  void clearStrides() { _bufferStrideSet.reset(); }
105 
106  void setPipeline(const gpu::PipelinePointer& pipeline);
107 
108  void setVertexFormat(const gpu::Stream::FormatPointer& format);
109 
110  void setFramebuffer(const gpu::FramebufferPointer& framebuffer);
111 
112  static void updateBindingMap(BindingMap& bindingMap,
113  const LocationMap& locationMap,
114  VkShaderStageFlagBits shaderStage);
115 
116  static void setBindingMap(BindingMap& bindingMap, const LocationMap& vertexMap, const LocationMap& fragmentMap);
117 
118  static BindingMap getBindingMap(const LocationMap& vertexMap, const LocationMap& fragmentMap);
119 
120  // VKTODO: This needs to be used instead of getPipeline
121  // Returns structure containing pipeline layout and descriptor set layouts
122  PipelineLayout getPipelineAndDescriptorLayout(const vks::Context& context);
123 
124  RenderpassKey getRenderPassKey(gpu::Framebuffer* framebuffer, const vks::Context &context) const;
125 
126  VkRenderPass getRenderPass(const vks::Context& context);
127  static std::string getRenderpassKeyString(const RenderpassKey& renderpassKey);
128  std::string getStridesKey() const;
129  std::string getKey(const vks::Context& context) const;
130  } pipelineState;
131 
132  static VkStencilOpState getStencilOp(const gpu::State::StencilTest& stencil);
133 
134  VkShaderModule getShaderModule(const vks::Context& context, const shader::Source& source);
135 
136  const PipelineLayout& getPipeline(const vks::Context& context);
137 };
138 
139 } }
Definition: Format.h:295
Definition: gpu/src/gpu/Framebuffer.h:27