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 "CoreThread/BsCoreObject.h"
7#include "RenderAPI/BsHardwareBuffer.h"
8
9namespace bs
10{
11 /** @addtogroup RenderAPI
12 * @{
13 */
14
15 /** Descriptor structure used for initialization of a GpuBuffer. */
16 struct GPU_BUFFER_DESC
17 {
18 /** Number of elements in the buffer. */
19 UINT32 elementCount = 0;
20
21 /**
22 * Size of each individual element in the buffer, in bytes. Only needed if using non-standard buffer. If using
23 * standard buffers element size is calculated from format and this must be zero.
24 */
25 UINT32 elementSize = 0;
26
27 /** Type of the buffer. Determines how is buffer seen by the GPU program and in what ways can it be used. */
28 GpuBufferType type = GBT_STANDARD;
29
30 /** Format if the data in the buffer. Only relevant for standard buffers, must be BF_UNKNOWN otherwise. */
31 GpuBufferFormat format = BF_32X4F;
32
33 /** Usage that tells the hardware how will be buffer be used. */
34 GpuBufferUsage usage = GBU_STATIC;
35 };
36
37 /**
38 * Information about a GpuBuffer. Allows core and non-core versions of GpuBuffer to share the same structure for
39 * properties.
40 */
41 class BS_CORE_EXPORT GpuBufferProperties
42 {
43 public:
44 GpuBufferProperties(const GPU_BUFFER_DESC& desc);
45
46 /**
47 * Returns the type of the GPU buffer. Type determines which kind of views (if any) can be created for the buffer,
48 * and how is data read or modified in it.
49 */
50 GpuBufferType getType() const { return mDesc.type; }
51
52 /** Returns format used by the buffer. Only relevant for standard buffers. */
53 GpuBufferFormat getFormat() const { return mDesc.format; }
54
55 /** Returns buffer usage which determines how are planning on updating the buffer contents. */
56 GpuBufferUsage getUsage() const { return mDesc.usage; }
57
58 /** Returns number of elements in the buffer. */
59 UINT32 getElementCount() const { return mDesc.elementCount; }
60
61 /** Returns size of a single element in the buffer in bytes. */
62 UINT32 getElementSize() const { return mDesc.elementSize; }
63
64 protected:
65 friend class GpuBuffer;
66
67 GPU_BUFFER_DESC mDesc;
68 };
69
70 /**
71 * Handles a generic GPU buffer that you may use for storing any kind of sequential data you wish to be accessible to
72 * the GPU.
73 *
74 * @note Sim thread only.
75 */
76 class BS_CORE_EXPORT GpuBuffer : public CoreObject
77 {
78 public:
79 virtual ~GpuBuffer() = default;
80
81 /** Returns properties describing the buffer. */
82 const GpuBufferProperties& getProperties() const { return mProperties; }
83
84 /** Retrieves a core implementation of a GPU buffer usable only from the core thread. */
85 SPtr<ct::GpuBuffer> getCore() const;
86
87 /** Returns the size of a single element in the buffer, of the provided format, in bytes. */
88 static UINT32 getFormatSize(GpuBufferFormat format);
89
90 /** @copydoc HardwareBufferManager::createGpuBuffer */
91 static SPtr<GpuBuffer> create(const GPU_BUFFER_DESC& desc);
92
93 protected:
94 friend class HardwareBufferManager;
95
96 GpuBuffer(const GPU_BUFFER_DESC& desc);
97
98 /** @copydoc CoreObject::createCore */
99 SPtr<ct::CoreObject> createCore() const override;
100
101 GpuBufferProperties mProperties;
102 };
103
104 /** @} */
105
106 namespace ct
107 {
108 /** @addtogroup RenderAPI-Internal
109 * @{
110 */
111
112 /**
113 * Core thread version of a bs::GpuBuffer.
114 *
115 * @note Core thread only.
116 */
117 class BS_CORE_EXPORT GpuBuffer : public CoreObject, public HardwareBuffer
118 {
119 public:
120 virtual ~GpuBuffer();
121
122 /** Returns properties describing the buffer. */
123 const GpuBufferProperties& getProperties() const { return mProperties; }
124
125 /** @copydoc HardwareBuffer::readData */
126 void readData(UINT32 offset, UINT32 length, void* dest, UINT32 deviceIdx = 0, UINT32 queueIdx = 0) override;
127
128 /** @copydoc HardwareBuffer::writeData */
129 void writeData(UINT32 offset, UINT32 length, const void* source,
130 BufferWriteType writeFlags = BWT_NORMAL, UINT32 queueIdx = 0) override;
131
132 /** @copydoc HardwareBuffer::copyData */
133 void copyData(HardwareBuffer& srcBuffer, UINT32 srcOffset, UINT32 dstOffset, UINT32 length,
134 bool discardWholeBuffer = false, const SPtr<CommandBuffer>& commandBuffer = nullptr) override;
135
136 /**
137 * Returns a view of this buffer with specified format/type.
138 *
139 * @param[in] type Type of buffer to view the contents as. Only supported values are GBT_STANDARD and
140 * GBT_STRUCTURED.
141 * @param[in] format Format of the data in the buffer. Size of the underlying buffer must be divisible by
142 * the size of an individual element of this format. Must be BF_UNKNOWN if buffer type
143 * is GBT_STRUCTURED.
144 * @param[in] elementSize Size of the individual element in the buffer. Size of the underlying buffer must be
145 * divisible by this size. Must be 0 if buffer type is GBT_STANDARD (element size gets
146 * deduced from format).
147 * @return New view of the buffer, using the provided format and type.
148 */
149 SPtr<GpuBuffer> getView(GpuBufferType type, GpuBufferFormat format, UINT32 elementSize = 0);
150
151 /** @copydoc bs::HardwareBufferManager::createGpuBuffer */
152 static SPtr<GpuBuffer> create(const GPU_BUFFER_DESC& desc, GpuDeviceFlags deviceMask = GDF_DEFAULT);
153
154 /**
155 * Creates a view of an existing hardware buffer. No internal buffer will be allocated and the provided buffer
156 * will be used for all internal operations instead. Information provided in @p desc (such as element size and
157 * count) must match the provided @p underlyingBuffer.
158 */
159 static SPtr<GpuBuffer> create(const GPU_BUFFER_DESC& desc, SPtr<HardwareBuffer> underlyingBuffer);
160 protected:
161 friend class HardwareBufferManager;
162
163 GpuBuffer(const GPU_BUFFER_DESC& desc, GpuDeviceFlags deviceMask);
164 GpuBuffer(const GPU_BUFFER_DESC& desc, SPtr<HardwareBuffer> underlyingBuffer);
165
166 /** @copydoc HardwareBuffer::map */
167 void* map(UINT32 offset, UINT32 length, GpuLockOptions options, UINT32 deviceIdx = 0, UINT32 queueIdx = 0) override;
168
169 /** @copydoc HardwareBuffer::unmap */
170 void unmap() override;
171
172 /** @copydoc CoreObject::initialize */
173 void initialize() override;
174
175 GpuBufferProperties mProperties;
176
177 HardwareBuffer* mBuffer = nullptr;
178 SPtr<HardwareBuffer> mSharedBuffer;
179 bool mIsExternalBuffer = false;
180
181 typedef void(*Deleter)(HardwareBuffer*);
182 Deleter mBufferDeleter = nullptr;
183 };
184
185 /** @} */
186 }
187}
188