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
8namespace bs
9{
10 class HardwareBuffer;
11
12 /** @addtogroup RenderAPI
13 * @{
14 */
15
16 /**
17 * Represents a GPU parameter block buffer. Parameter block buffers are bound to GPU programs which then fetch
18 * parameters from those buffers.
19 *
20 * Writing or reading from this buffer will translate directly to API calls that update the GPU.
21 *
22 * @note Sim thread only.
23 */
24 class BS_CORE_EXPORT GpuParamBlockBuffer : public CoreObject
25 {
26 public:
27 GpuParamBlockBuffer(UINT32 size, GpuBufferUsage usage);
28 virtual ~GpuParamBlockBuffer();
29
30 /**
31 * Write some data to the specified offset in the buffer.
32 *
33 * @note All values are in bytes. Actual hardware buffer update is delayed until rendering.
34 */
35 void write(UINT32 offset, const void* data, UINT32 size);
36
37 /**
38 * Read some data from the specified offset in the buffer.
39 *
40 * @note All values are in bytes. This reads from the cached CPU buffer and not from the GPU.
41 */
42 void read(UINT32 offset, void* data, UINT32 size);
43
44 /**
45 * Clear specified section of the buffer to zero.
46 *
47 * @note All values are in bytes. Actual hardware buffer update is delayed until rendering.
48 */
49 void zeroOut(UINT32 offset, UINT32 size);
50
51 /** Returns internal cached data of the buffer. */
52 const UINT8* getCachedData() const { return mCachedData; }
53
54 /** Returns the size of the buffer in bytes. */
55 UINT32 getSize() const { return mSize; }
56
57 /** Retrieves a core implementation of a GPU param block buffer usable only from the core thread. */
58 SPtr<ct::GpuParamBlockBuffer> getCore() const;
59
60 /** @copydoc HardwareBufferManager::createGpuParamBlockBuffer */
61 static SPtr<GpuParamBlockBuffer> create(UINT32 size, GpuBufferUsage usage = GBU_DYNAMIC);
62
63 protected:
64 /** @copydoc CoreObject::createCore */
65 SPtr<ct::CoreObject> createCore() const override;
66
67 /** @copydoc CoreObject::syncToCore */
68 CoreSyncData syncToCore(FrameAlloc* allocator) override;
69
70 GpuBufferUsage mUsage;
71 UINT32 mSize;
72 UINT8* mCachedData;
73 };
74
75 /** @} */
76
77 namespace ct
78 {
79 /** @addtogroup RenderAPI-Internal
80 * @{
81 */
82
83 /**
84 * Core thread version of a bs::GpuParamBlockBuffer.
85 *
86 * @note Core thread only.
87 */
88 class BS_CORE_EXPORT GpuParamBlockBuffer : public CoreObject
89 {
90 public:
91 GpuParamBlockBuffer(UINT32 size, GpuBufferUsage usage, GpuDeviceFlags deviceMask);
92 virtual ~GpuParamBlockBuffer();
93
94 /**
95 * Writes all of the specified data to the buffer. Data size must be the same size as the buffer.
96 *
97 * @param[in] data Data to write. Must match the size of the buffer.
98 * @param[in] queueIdx Device queue to perform the write operation on. See @ref queuesDoc.
99 */
100 void writeToGPU(const UINT8* data, UINT32 queueIdx = 0);
101
102 /**
103 * Flushes any cached data into the actual GPU buffer.
104 *
105 * @param[in] queueIdx Device queue to perform the write operation on. See @ref queuesDoc.
106 */
107 void flushToGPU(UINT32 queueIdx = 0);
108
109 /**
110 * Write some data to the specified offset in the buffer.
111 *
112 * @note All values are in bytes. Actual hardware buffer update is delayed until rendering or until
113 * flushToGPU() is called.
114 */
115 void write(UINT32 offset, const void* data, UINT32 size);
116
117 /**
118 * Read some data from the specified offset in the buffer.
119 *
120 * @note All values are in bytes. This reads from the cached CPU buffer and not directly from the GPU.
121 */
122 void read(UINT32 offset, void* data, UINT32 size);
123
124 /**
125 * Clear specified section of the buffer to zero.
126 *
127 * @note All values are in bytes. Actual hardware buffer update is delayed until rendering or until
128 * flushToGPU() is called.
129 */
130 void zeroOut(UINT32 offset, UINT32 size);
131
132 /** Returns the size of the buffer in bytes. */
133 UINT32 getSize() const { return mSize; }
134
135 /** @copydoc HardwareBufferManager::createGpuParamBlockBuffer */
136 static SPtr<GpuParamBlockBuffer> create(UINT32 size, GpuBufferUsage usage = GBU_DYNAMIC,
137 GpuDeviceFlags deviceMask = GDF_DEFAULT);
138
139 protected:
140 friend class HardwareBufferManager;
141
142 /** @copydoc CoreObject::syncToCore */
143 void syncToCore(const CoreSyncData& data) override;
144
145 /** @copydoc CoreObject::initialize */
146 void initialize() override;
147
148 HardwareBuffer* mBuffer;
149
150 GpuBufferUsage mUsage;
151 UINT32 mSize;
152
153 UINT8* mCachedData;
154 bool mGPUBufferDirty;
155 };
156
157 /** @} */
158 }
159}