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 "Image/BsPixelUtil.h"
8#include "Image/BsTexture.h"
9
10namespace bs { namespace ct
11{
12 /** @addtogroup RenderBeast
13 * @{
14 */
15
16 class GpuResourcePool;
17 struct POOLED_RENDER_TEXTURE_DESC;
18 struct POOLED_STORAGE_BUFFER_DESC;
19
20 /** Contains data about a single render texture in the GPU resource pool. */
21 struct BS_CORE_EXPORT PooledRenderTexture
22 {
23 PooledRenderTexture(GpuResourcePool* pool);
24 ~PooledRenderTexture();
25
26 SPtr<Texture> texture;
27 SPtr<RenderTexture> renderTexture;
28
29 private:
30 friend class GpuResourcePool;
31
32 GpuResourcePool* mPool;
33 bool mIsFree = false;
34 };
35
36 /** Contains data about a single storage buffer in the GPU resource pool. */
37 struct BS_CORE_EXPORT PooledStorageBuffer
38 {
39 PooledStorageBuffer(GpuResourcePool* pool);
40 ~PooledStorageBuffer();
41
42 SPtr<GpuBuffer> buffer;
43
44 private:
45 friend class GpuResourcePool;
46
47 GpuResourcePool* mPool;
48 bool mIsFree = false;
49 };
50
51 /**
52 * Contains a pool of textures and buffers meant to accommodate reuse of such resources for the main purpose of using
53 * them as write targets on the GPU.
54 */
55 class BS_CORE_EXPORT GpuResourcePool : public Module<GpuResourcePool>
56 {
57 public:
58 ~GpuResourcePool();
59
60 /**
61 * Attempts to find the unused render texture with the specified parameters in the pool, or creates a new texture
62 * otherwise. When done with the texture make sure to call release(const POOLED_RENDER_TEXTURE_DESC&).
63 *
64 * @param[in] desc Descriptor structure that describes what kind of texture to retrieve.
65 */
66 SPtr<PooledRenderTexture> get(const POOLED_RENDER_TEXTURE_DESC& desc);
67
68 /**
69 * Attempts to find the unused storage buffer with the specified parameters in the pool, or creates a new buffer
70 * otherwise. When done with the buffer make sure to call release(const POOLED_STORAGE_BUFFER_DESC&).
71 *
72 * @param[in] desc Descriptor structure that describes what kind of buffer to retrieve.
73 */
74 SPtr<PooledStorageBuffer> get(const POOLED_STORAGE_BUFFER_DESC& desc);
75
76 /**
77 * Releases a texture previously allocated with get(const POOLED_RENDER_TEXTURE_DESC&). The texture is returned to
78 * the pool so that it may be reused later.
79 *
80 * @note
81 * The texture will be removed from the pool if the last reference to it is deleted. Normally you would call
82 * release(const POOLED_RENDER_TEXTURE_DESC&) but keep a reference if you plan on using it later on.
83 */
84 void release(const SPtr<PooledRenderTexture>& texture);
85
86 /**
87 * Releases a buffer previously allocated with get(const POOLED_STORAGE_BUFFER_DESC&). The buffer is returned to the
88 * pool so that it may be reused later.
89 *
90 * @note
91 * The buffer will be removed from the pool if the last reference to it is deleted. Normally you would call
92 * release(const POOLED_STORAGE_BUFFER_DESC&) but keep a reference if you plan on using it later on.
93 */
94 void release(const SPtr<PooledStorageBuffer>& buffer);
95
96 private:
97 friend struct PooledRenderTexture;
98 friend struct PooledStorageBuffer;
99
100 /** Registers a newly created render texture in the pool. */
101 void _registerTexture(const SPtr<PooledRenderTexture>& texture);
102
103 /** Unregisters a created render texture in the pool. */
104 void _unregisterTexture(PooledRenderTexture* texture);
105
106 /** Registers a newly created storage buffer in the pool. */
107 void _registerBuffer(const SPtr<PooledStorageBuffer>& buffer);
108
109 /** Unregisters a created storage buffer in the pool. */
110 void _unregisterBuffer(PooledStorageBuffer* buffer);
111
112 /**
113 * Checks does the provided texture match the parameters.
114 *
115 * @param[in] desc Descriptor structure that describes what kind of texture to match.
116 * @return True if the texture matches the descriptor, false otherwise.
117 */
118 static bool matches(const SPtr<Texture>& texture, const POOLED_RENDER_TEXTURE_DESC& desc);
119
120 /**
121 * Checks does the provided buffer match the parameters.
122 *
123 * @param[in] desc Descriptor structure that describes what kind of buffer to match.
124 * @return True if the buffer matches the descriptor, false otherwise.
125 */
126 static bool matches(const SPtr<GpuBuffer>& buffer, const POOLED_STORAGE_BUFFER_DESC& desc);
127
128 Map<PooledRenderTexture*, std::weak_ptr<PooledRenderTexture>> mTextures;
129 Map<PooledStorageBuffer*, std::weak_ptr<PooledStorageBuffer>> mBuffers;
130 };
131
132 /** Structure used for creating a new pooled render texture. */
133 struct BS_CORE_EXPORT POOLED_RENDER_TEXTURE_DESC
134 {
135 public:
136 POOLED_RENDER_TEXTURE_DESC() {}
137
138 /**
139 * Creates a descriptor for a two dimensional render texture.
140 *
141 * @param[in] format Pixel format used by the texture surface.
142 * @param[in] width Width of the render texture, in pixels.
143 * @param[in] height Height of the render texture, in pixels.
144 * @param[in] usage Usage flags that control in which way is the texture going to be used.
145 * @param[in] samples If higher than 1, texture containing multiple samples per pixel is created.
146 * @param[in] hwGamma Should the written pixels be gamma corrected.
147 * @param[in] arraySize Number of textures in a texture array. Specify 1 for no array.
148 * @param[in] mipCount Number of mip levels, excluding the root mip level.
149 * @return Descriptor that is accepted by RenderTexturePool.
150 */
151 static POOLED_RENDER_TEXTURE_DESC create2D(PixelFormat format, UINT32 width, UINT32 height,
152 INT32 usage = TU_STATIC, UINT32 samples = 0, bool hwGamma = false, UINT32 arraySize = 1, UINT32 mipCount = 0);
153
154 /**
155 * Creates a descriptor for a three dimensional render texture.
156 *
157 * @param[in] format Pixel format used by the texture surface.
158 * @param[in] width Width of the render texture, in pixels.
159 * @param[in] height Height of the render texture, in pixels.
160 * @param[in] depth Depth of the render texture, in pixels.
161 * @param[in] usage Usage flags that control in which way is the texture going to be used.
162 * @return Descriptor that is accepted by RenderTexturePool.
163 */
164 static POOLED_RENDER_TEXTURE_DESC create3D(PixelFormat format, UINT32 width, UINT32 height, UINT32 depth,
165 INT32 usage = TU_STATIC);
166
167 /**
168 * Creates a descriptor for a cube render texture.
169 *
170 * @param[in] format Pixel format used by the texture surface.
171 * @param[in] width Width of the render texture, in pixels.
172 * @param[in] height Height of the render texture, in pixels.
173 * @param[in] usage Usage flags that control in which way is the texture going to be used.
174 * @param[in] arraySize Number of textures in a texture array. Specify 1 for no array.
175 * @return Descriptor that is accepted by RenderTexturePool.
176 */
177 static POOLED_RENDER_TEXTURE_DESC createCube(PixelFormat format, UINT32 width, UINT32 height,
178 INT32 usage = TU_STATIC, UINT32 arraySize = 1);
179
180 private:
181 friend class GpuResourcePool;
182
183 UINT32 width;
184 UINT32 height;
185 UINT32 depth;
186 UINT32 numSamples;
187 PixelFormat format;
188 TextureUsage flag;
189 TextureType type;
190 bool hwGamma;
191 UINT32 arraySize;
192 UINT32 numMipLevels;
193 };
194
195 /** Structure used for describing a pooled storage buffer. */
196 struct BS_CORE_EXPORT POOLED_STORAGE_BUFFER_DESC
197 {
198 public:
199 POOLED_STORAGE_BUFFER_DESC() {}
200
201 /**
202 * Creates a descriptor for a storage buffer containing primitive data types.
203 *
204 * @param[in] format Format of individual buffer entries.
205 * @param[in] numElements Number of elements in the buffer.
206 * @param[in] usage Usage flag hinting the driver how is buffer going to be used.
207 */
208 static POOLED_STORAGE_BUFFER_DESC createStandard(GpuBufferFormat format, UINT32 numElements,
209 GpuBufferUsage usage = GBU_LOADSTORE);
210
211 /**
212 * Creates a descriptor for a storage buffer containing structures.
213 *
214 * @param[in] elementSize Size of a single structure in the buffer.
215 * @param[in] numElements Number of elements in the buffer.
216 * @param[in] usage Usage flag hinting the driver how is buffer going to be used.
217 */
218 static POOLED_STORAGE_BUFFER_DESC createStructured(UINT32 elementSize, UINT32 numElements,
219 GpuBufferUsage usage = GBU_LOADSTORE);
220
221 private:
222 friend class GpuResourcePool;
223
224 GpuBufferType type;
225 GpuBufferFormat format;
226 GpuBufferUsage usage;
227 UINT32 numElements;
228 UINT32 elementSize;
229 };
230
231 /** @} */
232}}