1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "Utility/BsModule.h"
7#include "RenderAPI/BsVertexBuffer.h"
8#include "RenderAPI/BsIndexBuffer.h"
9#include "RenderAPI/BsVertexDeclaration.h"
10
11namespace bs
12{
13 struct GPU_BUFFER_DESC;
14 struct GPU_PARAMS_DESC;
15
16 /** @addtogroup RenderAPI-Internal
17 * @{
18 */
19
20 /**
21 * Handles creation of various hardware buffers.
22 *
23 * @note Sim thread only.
24 */
25 class BS_CORE_EXPORT HardwareBufferManager : public Module<HardwareBufferManager>
26 {
27 public:
28 HardwareBufferManager() = default;
29 virtual ~HardwareBufferManager() = default;
30
31 /**
32 * Creates a new vertex buffer used for holding number of vertices and other per-vertex data. Buffer can be bound
33 * to the pipeline and its data can be passed to the active vertex GPU program.
34 *
35 * @param[in] desc Description of the buffer to create.
36 */
37 SPtr<VertexBuffer> createVertexBuffer(const VERTEX_BUFFER_DESC& desc);
38
39 /**
40 * Creates a new index buffer that holds indices referencing vertices in a vertex buffer. Indices are interpreted
41 * by the pipeline and vertices are drawn in the order specified in the index buffer.
42 *
43 * @param[in] desc Description of the buffer to create.
44 */
45 SPtr<IndexBuffer> createIndexBuffer(const INDEX_BUFFER_DESC& desc);
46
47 /**
48 * Creates an GPU parameter block that you can use for setting parameters for GPU programs. Parameter blocks may be
49 * used for sharing parameter data between multiple GPU programs, requiring you to update only one buffer for all of
50 * them, potentially improving performance.
51 *
52 * @param[in] size Size of the parameter buffer in bytes.
53 * @param[in] usage Usage that tells the hardware how will be buffer be used.
54 */
55 SPtr<GpuParamBlockBuffer> createGpuParamBlockBuffer(UINT32 size, GpuBufferUsage usage = GBU_DYNAMIC);
56
57 /**
58 * Creates a generic buffer that can be passed as a parameter to a GPU program. This type of buffer can hold various
59 * type of data and can be used for various purposes. See GpuBufferType for explanation of different buffer types.
60 *
61 * @param[in] desc Description of the buffer to create.
62 */
63 SPtr<GpuBuffer> createGpuBuffer(const GPU_BUFFER_DESC& desc);
64
65 /**
66 * Creates a new vertex declaration from a list of vertex elements.
67 *
68 * @param[in] desc Description of the object to create.
69 */
70 SPtr<VertexDeclaration> createVertexDeclaration(const SPtr<VertexDataDesc>& desc);
71
72 /** @copydoc GpuParams::create(const SPtr<GpuPipelineParamInfo>&) */
73 SPtr<GpuParams> createGpuParams(const SPtr<GpuPipelineParamInfo>& paramInfo);
74 };
75
76 namespace ct
77 {
78
79 /**
80 * Handles creation of various hardware buffers.
81 *
82 * @note Core thread only.
83 */
84 class BS_CORE_EXPORT HardwareBufferManager : public Module<HardwareBufferManager>
85 {
86 public:
87 virtual ~HardwareBufferManager() { }
88
89 /**
90 * @copydoc bs::HardwareBufferManager::createVertexBuffer
91 * @param[in] deviceMask Mask that determines on which GPU devices should the object be created on.
92 */
93 SPtr<VertexBuffer> createVertexBuffer(const VERTEX_BUFFER_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
94
95 /**
96 * @copydoc bs::HardwareBufferManager::createIndexBuffer
97 * @param[in] deviceMask Mask that determines on which GPU devices should the object be created on.
98 */
99 SPtr<IndexBuffer> createIndexBuffer(const INDEX_BUFFER_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
100
101 /**
102 * @copydoc bs::HardwareBufferManager::createVertexDeclaration
103 * @param[in] deviceMask Mask that determines on which GPU devices should the object be created on.
104 */
105 SPtr<VertexDeclaration> createVertexDeclaration(const SPtr<VertexDataDesc>& desc,
106 GpuDeviceFlags deviceMask = GDF_DEFAULT);
107
108 /**
109 * Creates a new vertex declaration from a list of vertex elements.
110 *
111 * @param[in] elements List of elements to initialize the declaration with.
112 * @param[in] deviceMask Mask that determines on which GPU devices should the object be created on.
113 */
114 SPtr<VertexDeclaration> createVertexDeclaration(const Vector<VertexElement>& elements,
115 GpuDeviceFlags deviceMask = GDF_DEFAULT);
116
117 /**
118 * @copydoc bs::HardwareBufferManager::createGpuParamBlockBuffer
119 * @param[in] deviceMask Mask that determines on which GPU devices should the object be created on.
120 */
121 SPtr<GpuParamBlockBuffer> createGpuParamBlockBuffer(UINT32 size,
122 GpuBufferUsage usage = GBU_DYNAMIC, GpuDeviceFlags deviceMask = GDF_DEFAULT);
123
124 /**
125 * @copydoc bs::HardwareBufferManager::createGpuBuffer
126 * @param[in] deviceMask Mask that determines on which GPU devices should the object be created on.
127 */
128 SPtr<GpuBuffer> createGpuBuffer(const GPU_BUFFER_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
129
130 /** @copydoc GpuBuffer::create(const GPU_BUFFER_DESC&, SPtr<HardwareBuffer>) */
131 SPtr<GpuBuffer> createGpuBuffer(const GPU_BUFFER_DESC& desc, SPtr<HardwareBuffer> underlyingBuffer);
132
133 /** @copydoc GpuParams::create(const SPtr<GpuPipelineParamInfo>&, GpuDeviceFlags) */
134 SPtr<GpuParams> createGpuParams(const SPtr<GpuPipelineParamInfo>& paramInfo,
135 GpuDeviceFlags deviceMask = GDF_DEFAULT);
136 protected:
137 friend class bs::IndexBuffer;
138 friend class IndexBuffer;
139 friend class bs::VertexBuffer;
140 friend class VertexBuffer;
141 friend class bs::VertexDeclaration;
142 friend class bs::GpuParamBlockBuffer;
143 friend class bs::GpuBuffer;
144 friend class GpuBuffer;
145
146 /** Key for use in the vertex declaration map. */
147 struct VertexDeclarationKey
148 {
149 VertexDeclarationKey(const Vector<VertexElement>& elements);
150
151 class HashFunction
152 {
153 public:
154 size_t operator()(const VertexDeclarationKey& key) const;
155 };
156
157 class EqualFunction
158 {
159 public:
160 bool operator()(const VertexDeclarationKey& lhs, const VertexDeclarationKey& rhs) const;
161 };
162
163 Vector<VertexElement> elements;
164 };
165
166 /** @copydoc createVertexBuffer */
167 virtual SPtr<VertexBuffer> createVertexBufferInternal(const VERTEX_BUFFER_DESC& desc,
168 GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
169
170 /** @copydoc createIndexBuffer */
171 virtual SPtr<IndexBuffer> createIndexBufferInternal(const INDEX_BUFFER_DESC& desc,
172 GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
173
174 /** @copydoc createGpuParamBlockBuffer */
175 virtual SPtr<GpuParamBlockBuffer> createGpuParamBlockBufferInternal(UINT32 size,
176 GpuBufferUsage usage = GBU_DYNAMIC, GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
177
178 /** @copydoc createGpuBuffer(const GPU_BUFFER_DESC&, GpuDeviceFlags) */
179 virtual SPtr<GpuBuffer> createGpuBufferInternal(const GPU_BUFFER_DESC& desc,
180 GpuDeviceFlags deviceMask = GDF_DEFAULT) = 0;
181
182 /** @copydoc createGpuBuffer(const GPU_BUFFER_DESC&, SPtr<HardwareBuffer>) */
183 virtual SPtr<GpuBuffer> createGpuBufferInternal(const GPU_BUFFER_DESC& desc,
184 SPtr<HardwareBuffer> underlyingBuffer) = 0;
185
186 /** @copydoc createVertexDeclaration(const Vector<VertexElement>&, GpuDeviceFlags) */
187 virtual SPtr<VertexDeclaration> createVertexDeclarationInternal(const Vector<VertexElement>& elements,
188 GpuDeviceFlags deviceMask = GDF_DEFAULT);
189
190 /** @copydoc createGpuParams */
191 virtual SPtr<GpuParams> createGpuParamsInternal(const SPtr<GpuPipelineParamInfo>& paramInfo,
192 GpuDeviceFlags deviceMask = GDF_DEFAULT);
193
194 typedef UnorderedMap<VertexDeclarationKey, SPtr<VertexDeclaration>,
195 VertexDeclarationKey::HashFunction, VertexDeclarationKey::EqualFunction> DeclarationMap;
196
197 DeclarationMap mCachedDeclarations;
198 };
199 }
200
201 /** @} */
202}