Pyrogenesis  trunk
ShaderProgram.h
Go to the documentation of this file.
1 /* Copyright (C) 2023 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef INCLUDED_RENDERER_BACKEND_VULKAN_SHADERPROGRAM
19 #define INCLUDED_RENDERER_BACKEND_VULKAN_SHADERPROGRAM
20 
23 
24 #include <array>
25 #include <cstddef>
26 #include <glad/vulkan.h>
27 #include <memory>
28 #include <unordered_map>
29 #include <vector>
30 
31 class CShaderDefines;
32 class CStr;
33 
34 namespace Renderer
35 {
36 
37 namespace Backend
38 {
39 
40 namespace Vulkan
41 {
42 
43 class CDevice;
44 
46 {
47 public:
49  : m_Device(device), m_Attributes(attributes.begin(), attributes.end())
50  {
51  static uint32_t m_LastAvailableUID = 1;
52  m_UID = m_LastAvailableUID++;
53  for (const SVertexAttributeFormat& attribute : m_Attributes)
54  {
55  ENSURE(attribute.format != Format::UNDEFINED);
56  ENSURE(attribute.stride > 0);
57  }
58  }
59 
60  ~CVertexInputLayout() override = default;
61 
62  IDevice* GetDevice() override;
63 
64  const std::vector<SVertexAttributeFormat>& GetAttributes() const noexcept { return m_Attributes; }
65 
66  using UID = uint32_t;
67  UID GetUID() const { return m_UID; }
68 
69 private:
70  CDevice* m_Device = nullptr;
71 
72  UID m_UID = 0;
73 
74  std::vector<SVertexAttributeFormat> m_Attributes;
75 };
76 
77 class CShaderProgram final : public IShaderProgram
78 {
79 public:
80  ~CShaderProgram() override;
81 
82  IDevice* GetDevice() override;
83 
84  int32_t GetBindingSlot(const CStrIntern name) const override;
85 
86  std::vector<VfsPath> GetFileDependencies() const override;
87 
88  uint32_t GetStreamLocation(const VertexAttributeStream stream) const;
89 
90  const std::vector<VkPipelineShaderStageCreateInfo>& GetStages() const { return m_Stages; }
91 
92  void Bind();
93  void Unbind();
94  void PreDraw(VkCommandBuffer commandBuffer);
95 
96  VkPipelineLayout GetPipelineLayout() const { return m_PipelineLayout; }
97  VkPipelineBindPoint GetPipelineBindPoint() const { return VK_PIPELINE_BIND_POINT_GRAPHICS; }
98 
99  void SetUniform(
100  const int32_t bindingSlot,
101  const float value);
102  void SetUniform(
103  const int32_t bindingSlot,
104  const float valueX, const float valueY);
105  void SetUniform(
106  const int32_t bindingSlot,
107  const float valueX, const float valueY,
108  const float valueZ);
109  void SetUniform(
110  const int32_t bindingSlot,
111  const float valueX, const float valueY,
112  const float valueZ, const float valueW);
113  void SetUniform(
114  const int32_t bindingSlot, PS::span<const float> values);
115  void SetTexture(const int32_t bindingSlot, CTexture* texture);
116 
117  // TODO: rename to something related to buffer.
118  bool IsMaterialConstantsDataOutdated() const { return m_MaterialConstantsDataOutdated; }
119  void UpdateMaterialConstantsData() { m_MaterialConstantsDataOutdated = false; }
120  std::byte* GetMaterialConstantsData() const { return m_MaterialConstantsData.get(); }
121  uint32_t GetMaterialConstantsDataSize() const { return m_MaterialConstantsDataSize; }
122 
123 private:
124  friend class CDevice;
125 
126  CShaderProgram();
127 
128  std::pair<std::byte*, uint32_t> GetUniformData(
129  const int32_t bindingSlot, const uint32_t dataSize);
130 
131  static std::unique_ptr<CShaderProgram> Create(
132  CDevice* device, const CStr& name, const CShaderDefines& defines);
133 
134  void UpdateActiveDescriptorSet(
135  VkCommandBuffer commandBuffer);
136 
137  CDevice* m_Device = nullptr;
138 
139  std::vector<VkShaderModule> m_ShaderModules;
140  std::vector<VkPipelineShaderStageCreateInfo> m_Stages;
141  VkPipelineLayout m_PipelineLayout = VK_NULL_HANDLE;
142 
143  std::vector<VfsPath> m_FileDependencies;
144 
146  {
150  VkShaderStageFlags stageFlags;
151  };
152  struct Uniform
153  {
157  };
158  std::unique_ptr<std::byte[]> m_MaterialConstantsData;
159  uint32_t m_MaterialConstantsDataSize = 0;
160  bool m_MaterialConstantsDataOutdated = false;
161  std::array<std::byte, 128> m_PushConstantData;
162  uint32_t m_PushConstantDataMask = 0;
163  std::array<VkShaderStageFlags, 32> m_PushConstantDataFlags;
164  std::vector<PushConstant> m_PushConstants;
165  std::vector<Uniform> m_Uniforms;
166  std::unordered_map<CStrIntern, uint32_t> m_UniformMapping;
167  std::unordered_map<CStrIntern, uint32_t> m_PushConstantMapping;
168 
169  uint32_t m_TexturesDescriptorSetSize = 0;
170  bool m_BoundTexturesOutdated = false;
171 
172  VkDescriptorSetLayout m_TexturesDescriptorSetLayout = VK_NULL_HANDLE;
173  std::vector<CTexture*> m_BoundTextures;
174  std::vector<CTexture::UID> m_BoundTexturesUID;
175  VkDescriptorSet m_ActiveTexturesDescriptorSet = VK_NULL_HANDLE;
176  std::unordered_map<CStrIntern, uint32_t> m_TextureMapping;
177 
178  std::unordered_map<VertexAttributeStream, uint32_t> m_StreamLocations;
179 };
180 
181 } // namespace Vulkan
182 
183 } // namespace Backend
184 
185 } // namespace Renderer
186 
187 #endif // INCLUDED_RENDERER_BACKEND_VULKAN_SHADERPROGRAM
VkPipelineBindPoint GetPipelineBindPoint() const
Definition: ShaderProgram.h:97
uint32_t offset
Definition: ShaderProgram.h:155
uint32_t offset
Definition: ShaderProgram.h:148
const std::vector< VkPipelineShaderStageCreateInfo > & GetStages() const
Definition: ShaderProgram.h:90
Definition: ShaderProgram.h:45
IVertexInputLayout stores precompiled list of vertex attributes.
Definition: IShaderProgram.h:73
std::vector< SVertexAttributeFormat > m_Attributes
Definition: ShaderProgram.h:74
Definition: Texture.h:39
Definition: Device.h:59
std::unordered_map< VertexAttributeStream, uint32_t > m_StreamLocations
Definition: ShaderProgram.h:178
std::unordered_map< CStrIntern, uint32_t > m_TextureMapping
Definition: ShaderProgram.h:176
VertexAttributeStream
Definition: IShaderProgram.h:32
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
Definition: debug.h:290
uint32_t size
Definition: ShaderProgram.h:149
CVertexInputLayout(CDevice *device, const PS::span< const SVertexAttributeFormat > attributes)
Definition: ShaderProgram.h:48
IDevice * GetDevice() override
Definition: ShaderProgram.cpp:132
std::byte * GetMaterialConstantsData() const
Definition: ShaderProgram.h:120
Interned 8-bit strings.
Definition: CStrIntern.h:37
std::unordered_map< CStrIntern, uint32_t > m_UniformMapping
Definition: ShaderProgram.h:166
std::vector< VfsPath > m_FileDependencies
Definition: ShaderProgram.h:143
const std::vector< SVertexAttributeFormat > & GetAttributes() const noexcept
Definition: ShaderProgram.h:64
void UpdateMaterialConstantsData()
Definition: ShaderProgram.h:119
CDevice * m_Device
Definition: ShaderProgram.h:70
Definition: IDevice.h:47
VkShaderStageFlags stageFlags
Definition: ShaderProgram.h:150
std::vector< CTexture * > m_BoundTextures
Definition: ShaderProgram.h:173
std::array< std::byte, 128 > m_PushConstantData
Definition: ShaderProgram.h:161
std::vector< VkShaderModule > m_ShaderModules
Definition: ShaderProgram.h:139
std::vector< CTexture::UID > m_BoundTexturesUID
Definition: ShaderProgram.h:174
VkPipelineLayout GetPipelineLayout() const
Definition: ShaderProgram.h:96
IShaderProgram is a container for multiple shaders of different types.
Definition: IShaderProgram.h:80
Backend
Definition: Backend.h:27
Represents a mapping of name strings to value strings, for use with #if and #ifdef and similar condit...
Definition: ShaderDefines.h:146
std::array< VkShaderStageFlags, 32 > m_PushConstantDataFlags
Definition: ShaderProgram.h:163
unsigned int uint32_t
Definition: wposix_types.h:53
Definition: VideoMode.h:28
std::unique_ptr< std::byte[]> m_MaterialConstantsData
Definition: ShaderProgram.h:158
Definition: IShaderProgram.h:53
uint32_t GetMaterialConstantsDataSize() const
Definition: ShaderProgram.h:121
std::vector< Uniform > m_Uniforms
Definition: ShaderProgram.h:165
Definition: ShaderProgram.h:77
UID m_UID
Definition: ShaderProgram.h:72
CStrIntern name
Definition: ShaderProgram.h:154
uint32_t UID
Definition: ShaderProgram.h:66
std::vector< PushConstant > m_PushConstants
Definition: ShaderProgram.h:164
UID GetUID() const
Definition: ShaderProgram.h:67
CStrIntern name
Definition: ShaderProgram.h:147
std::vector< VkPipelineShaderStageCreateInfo > m_Stages
Definition: ShaderProgram.h:140
uint32_t size
Definition: ShaderProgram.h:156
std::unordered_map< CStrIntern, uint32_t > m_PushConstantMapping
Definition: ShaderProgram.h:167
Simplifed version of std::span (C++20) as we don&#39;t support the original one yet.
Definition: Span.h:36
bool IsMaterialConstantsDataOutdated() const
Definition: ShaderProgram.h:118