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 | #include "RenderAPI/BsGpuParamBlockBuffer.h" |
4 | #include "RenderAPI/BsHardwareBuffer.h" |
5 | #include "Managers/BsHardwareBufferManager.h" |
6 | #include "Profiling/BsRenderStats.h" |
7 | |
8 | namespace bs |
9 | { |
10 | GpuParamBlockBuffer::GpuParamBlockBuffer(UINT32 size, GpuBufferUsage usage) |
11 | :mUsage(usage), mSize(size), mCachedData(nullptr) |
12 | { |
13 | if (mSize > 0) |
14 | { |
15 | mCachedData = (UINT8*)bs_alloc(mSize); |
16 | memset(mCachedData, 0, mSize); |
17 | } |
18 | } |
19 | |
20 | GpuParamBlockBuffer::~GpuParamBlockBuffer() |
21 | { |
22 | if (mCachedData != nullptr) |
23 | bs_free(mCachedData); |
24 | } |
25 | |
26 | void GpuParamBlockBuffer::write(UINT32 offset, const void* data, UINT32 size) |
27 | { |
28 | #if BS_DEBUG_MODE |
29 | if ((offset + size) > mSize) |
30 | { |
31 | BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \ |
32 | "Available range: 0 .. " + toString(mSize) + ". " \ |
33 | "Wanted range: " + toString(offset) + " .. " + toString(offset + size) + "." ); |
34 | } |
35 | #endif |
36 | |
37 | memcpy(mCachedData + offset, data, size); |
38 | markCoreDirty(); |
39 | } |
40 | |
41 | void GpuParamBlockBuffer::read(UINT32 offset, void* data, UINT32 size) |
42 | { |
43 | #if BS_DEBUG_MODE |
44 | if ((offset + size) > mSize) |
45 | { |
46 | BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \ |
47 | "Available range: 0 .. " + toString(mSize) + ". " \ |
48 | "Wanted range: " + toString(offset) + " .. " + toString(offset + size) + "." ); |
49 | } |
50 | #endif |
51 | |
52 | memcpy(data, mCachedData + offset, size); |
53 | } |
54 | |
55 | void GpuParamBlockBuffer::zeroOut(UINT32 offset, UINT32 size) |
56 | { |
57 | #if BS_DEBUG_MODE |
58 | if ((offset + size) > mSize) |
59 | { |
60 | BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \ |
61 | "Available range: 0 .. " + toString(mSize) + ". " \ |
62 | "Wanted range: " + toString(offset) + " .. " + toString(offset + size) + "." ); |
63 | } |
64 | #endif |
65 | |
66 | memset(mCachedData + offset, 0, size); |
67 | markCoreDirty(); |
68 | } |
69 | |
70 | SPtr<ct::GpuParamBlockBuffer> GpuParamBlockBuffer::getCore() const |
71 | { |
72 | return std::static_pointer_cast<ct::GpuParamBlockBuffer>(mCoreSpecific); |
73 | } |
74 | |
75 | SPtr<ct::CoreObject> GpuParamBlockBuffer::createCore() const |
76 | { |
77 | return ct::HardwareBufferManager::instance().createGpuParamBlockBufferInternal(mSize, mUsage); |
78 | } |
79 | |
80 | CoreSyncData GpuParamBlockBuffer::syncToCore(FrameAlloc* allocator) |
81 | { |
82 | UINT8* buffer = allocator->alloc(mSize); |
83 | read(0, buffer, mSize); |
84 | |
85 | return CoreSyncData(buffer, mSize); |
86 | } |
87 | |
88 | SPtr<GpuParamBlockBuffer> GpuParamBlockBuffer::create(UINT32 size, GpuBufferUsage usage) |
89 | { |
90 | return HardwareBufferManager::instance().createGpuParamBlockBuffer(size, usage); |
91 | } |
92 | |
93 | namespace ct |
94 | { |
95 | GpuParamBlockBuffer::GpuParamBlockBuffer(UINT32 size, GpuBufferUsage usage, GpuDeviceFlags deviceMask) |
96 | :mUsage(usage), mSize(size), mCachedData(nullptr), mGPUBufferDirty(false) |
97 | { |
98 | if (mSize > 0) |
99 | { |
100 | mCachedData = (UINT8*)bs_alloc(mSize); |
101 | memset(mCachedData, 0, mSize); |
102 | } |
103 | } |
104 | |
105 | GpuParamBlockBuffer::~GpuParamBlockBuffer() |
106 | { |
107 | if (mCachedData != nullptr) |
108 | bs_free(mCachedData); |
109 | |
110 | BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_GpuParamBuffer); |
111 | } |
112 | |
113 | void GpuParamBlockBuffer::initialize() |
114 | { |
115 | BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_GpuParamBuffer); |
116 | |
117 | CoreObject::initialize(); |
118 | } |
119 | |
120 | void GpuParamBlockBuffer::write(UINT32 offset, const void* data, UINT32 size) |
121 | { |
122 | #if BS_DEBUG_MODE |
123 | if ((offset + size) > mSize) |
124 | { |
125 | BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \ |
126 | "Available range: 0 .. " + toString(mSize) + ". " \ |
127 | "Wanted range: " + toString(offset) + " .. " + toString(offset + size) + "." ); |
128 | } |
129 | #endif |
130 | |
131 | memcpy(mCachedData + offset, data, size); |
132 | mGPUBufferDirty = true; |
133 | } |
134 | |
135 | void GpuParamBlockBuffer::read(UINT32 offset, void* data, UINT32 size) |
136 | { |
137 | #if BS_DEBUG_MODE |
138 | if ((offset + size) > mSize) |
139 | { |
140 | BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \ |
141 | "Available range: 0 .. " + toString(mSize) + ". " \ |
142 | "Wanted range: " + toString(offset) + " .. " + toString(offset + size) + "." ); |
143 | } |
144 | #endif |
145 | |
146 | memcpy(data, mCachedData + offset, size); |
147 | } |
148 | |
149 | void GpuParamBlockBuffer::zeroOut(UINT32 offset, UINT32 size) |
150 | { |
151 | #if BS_DEBUG_MODE |
152 | if ((offset + size) > mSize) |
153 | { |
154 | BS_EXCEPT(InvalidParametersException, "Wanted range is out of buffer bounds. " \ |
155 | "Available range: 0 .. " + toString(mSize) + ". " \ |
156 | "Wanted range: " + toString(offset) + " .. " + toString(offset + size) + "." ); |
157 | } |
158 | #endif |
159 | |
160 | memset(mCachedData + offset, 0, size); |
161 | mGPUBufferDirty = true; |
162 | } |
163 | |
164 | void GpuParamBlockBuffer::flushToGPU(UINT32 queueIdx) |
165 | { |
166 | if (mGPUBufferDirty) |
167 | { |
168 | writeToGPU(mCachedData, queueIdx); |
169 | mGPUBufferDirty = false; |
170 | } |
171 | } |
172 | |
173 | void GpuParamBlockBuffer::writeToGPU(const UINT8* data, UINT32 queueIdx) |
174 | { |
175 | mBuffer->writeData(0, mSize, data, BWT_DISCARD, queueIdx); |
176 | |
177 | BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_GpuParamBuffer); |
178 | } |
179 | |
180 | void GpuParamBlockBuffer::syncToCore(const CoreSyncData& data) |
181 | { |
182 | assert(mSize == data.getBufferSize()); |
183 | |
184 | write(0, data.getBuffer(), data.getBufferSize()); |
185 | } |
186 | |
187 | SPtr<GpuParamBlockBuffer> GpuParamBlockBuffer::create(UINT32 size, GpuBufferUsage usage, GpuDeviceFlags deviceMask) |
188 | { |
189 | return HardwareBufferManager::instance().createGpuParamBlockBuffer(size, usage, deviceMask); |
190 | } |
191 | } |
192 | } |
193 | |