Blender V5.0
render_buffer.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2022 NVIDIA Corporation
2 * SPDX-FileCopyrightText: 2022 Blender Foundation
3 *
4 * SPDX-License-Identifier: Apache-2.0 */
5
7#include "hydra/session.h"
8#include "util/half.h"
9
10#include <pxr/base/gf/vec3i.h>
11#include <pxr/base/gf/vec4f.h>
12
14
15HdCyclesRenderBuffer::HdCyclesRenderBuffer(const SdfPath &bprimId) : HdRenderBuffer(bprimId) {}
16
18
19void HdCyclesRenderBuffer::Finalize(HdRenderParam *renderParam)
20{
21 // Remove this render buffer from AOV bindings
22 // This ensures that 'OutputDriver' does not attempt to write to it anymore
23 static_cast<HdCyclesSession *>(renderParam)->RemoveAovBinding(this);
24
25 HdRenderBuffer::Finalize(renderParam);
26}
27
28bool HdCyclesRenderBuffer::Allocate(const GfVec3i &dimensions,
29 HdFormat format,
30 bool /*multiSampled*/)
31{
32 if (dimensions[2] != 1) {
33 TF_RUNTIME_ERROR("HdCyclesRenderBuffer::Allocate called with dimensions that are not 2D.");
34 return false;
35 }
36
37 const size_t oldSize = _dataSize;
38 const size_t newSize = dimensions[0] * dimensions[1] * HdDataSizeOfFormat(format);
39 if (oldSize == newSize) {
40 return true;
41 }
42
43 if (IsMapped()) {
44 TF_RUNTIME_ERROR("HdCyclesRenderBuffer::Allocate called while buffer is mapped.");
45 return false;
46 }
47
48 _width = dimensions[0];
49 _height = dimensions[1];
50 _format = format;
51 _dataSize = newSize;
52 _resourceUsed = false;
53
54 return true;
55}
56
57void HdCyclesRenderBuffer::_Deallocate()
58{
59 _width = 0u;
60 _height = 0u;
61 _format = HdFormatInvalid;
62
63 _data.clear();
64 _data.shrink_to_fit();
65 _dataSize = 0;
66
67 _resource = VtValue();
68}
69
71{
72 // Mapping is not implemented when a resource is set
73 if (!_resource.IsEmpty()) {
74 return nullptr;
75 }
76
77 if (_data.size() != _dataSize) {
78 _data.resize(_dataSize);
79 }
80
81 ++_mapped;
82
83 return _data.data();
84}
85
87{
88 --_mapped;
89}
90
92{
93 return _mapped != 0;
94}
95
97
99{
100 return _converged;
101}
102
104{
105 _converged = converged;
106}
107
109{
110 return _resourceUsed;
111}
112
113VtValue HdCyclesRenderBuffer::GetResource(bool multiSampled) const
114{
115 TF_UNUSED(multiSampled);
116
117 _resourceUsed = true;
118
119 return _resource;
120}
121
123{
124 _resource = resource;
125}
126
127namespace {
128
129struct SimpleConversion {
130 static float convert(const float value)
131 {
132 return value;
133 }
134};
135struct IdConversion {
136 static int32_t convert(const float value)
137 {
138 return static_cast<int32_t>(value) - 1;
139 }
140};
141struct UInt8Conversion {
142 static uint8_t convert(const float value)
143 {
144 return static_cast<uint8_t>(value * 255.f);
145 }
146};
147struct SInt8Conversion {
148 static int8_t convert(const float value)
149 {
150 return static_cast<int8_t>(value * 127.f);
151 }
152};
153struct HalfConversion {
154 static half convert(const float value)
155 {
156 return float_to_half_image(value);
157 }
158};
159
160template<typename SrcT, typename DstT, typename Convertor = SimpleConversion>
161void writePixels(const SrcT *srcPtr,
162 const GfVec2i &srcSize,
163 const int srcChannelCount,
164 DstT *dstPtr,
165 const GfVec2i &dstSize,
166 const int dstChannelCount,
167 const Convertor &convertor = {})
168{
169 const auto writeSize = GfVec2i(GfMin(srcSize[0], dstSize[0]), GfMin(srcSize[1], dstSize[1]));
170 const auto writeChannelCount = GfMin(srcChannelCount, dstChannelCount);
171
172 for (int y = 0; y < writeSize[1]; ++y) {
173 for (int x = 0; x < writeSize[0]; ++x) {
174 for (int c = 0; c < writeChannelCount; ++c) {
175 dstPtr[x * dstChannelCount + c] = convertor.convert(srcPtr[x * srcChannelCount + c]);
176 }
177 }
178 srcPtr += srcSize[0] * srcChannelCount;
179 dstPtr += dstSize[0] * dstChannelCount;
180 }
181}
182
183} // namespace
184
185void HdCyclesRenderBuffer::WritePixels(const float *srcPixels,
186 const PXR_NS::GfVec2i &srcOffset,
187 const GfVec2i &srcDims,
188 const int srcChannels,
189 bool isId)
190{
191 uint8_t *dstPixels = _data.data();
192
193 const size_t formatSize = HdDataSizeOfFormat(_format);
194 dstPixels += srcOffset[1] * (formatSize * _width) + srcOffset[0] * formatSize;
195
196 switch (_format) {
197 case HdFormatUNorm8:
198 case HdFormatUNorm8Vec2:
199 case HdFormatUNorm8Vec3:
200 case HdFormatUNorm8Vec4:
201 writePixels(srcPixels,
202 srcDims,
203 srcChannels,
204 dstPixels,
205 GfVec2i(_width, _height),
206 1 + (_format - HdFormatUNorm8),
207 UInt8Conversion());
208 break;
209
210 case HdFormatSNorm8:
211 case HdFormatSNorm8Vec2:
212 case HdFormatSNorm8Vec3:
213 case HdFormatSNorm8Vec4:
214 writePixels(srcPixels,
215 srcDims,
216 srcChannels,
217 dstPixels,
218 GfVec2i(_width, _height),
219 1 + (_format - HdFormatSNorm8),
220 SInt8Conversion());
221 break;
222
223 case HdFormatFloat16:
224 case HdFormatFloat16Vec2:
225 case HdFormatFloat16Vec3:
226 case HdFormatFloat16Vec4:
227 writePixels(srcPixels,
228 srcDims,
229 srcChannels,
230 reinterpret_cast<half *>(dstPixels),
231 GfVec2i(_width, _height),
232 1 + (_format - HdFormatFloat16),
233 HalfConversion());
234 break;
235
236 case HdFormatFloat32:
237 case HdFormatFloat32Vec2:
238 case HdFormatFloat32Vec3:
239 case HdFormatFloat32Vec4:
240 writePixels(srcPixels,
241 srcDims,
242 srcChannels,
243 reinterpret_cast<float *>(dstPixels),
244 GfVec2i(_width, _height),
245 1 + (_format - HdFormatFloat32));
246 break;
247
248 case HdFormatInt32:
249 // Special case for ID AOVs (see 'HdCyclesMesh::Sync')
250 if (isId) {
251 writePixels(srcPixels,
252 srcDims,
253 srcChannels,
254 reinterpret_cast<int *>(dstPixels),
255 GfVec2i(_width, _height),
256 1,
257 IdConversion());
258 }
259 else {
260 writePixels(srcPixels,
261 srcDims,
262 srcChannels,
263 reinterpret_cast<int *>(dstPixels),
264 GfVec2i(_width, _height),
265 1);
266 }
267 break;
268 case HdFormatInt32Vec2:
269 case HdFormatInt32Vec3:
270 case HdFormatInt32Vec4:
271 writePixels(srcPixels,
272 srcDims,
273 srcChannels,
274 reinterpret_cast<int *>(dstPixels),
275 GfVec2i(_width, _height),
276 1 + (_format - HdFormatInt32));
277 break;
278
279 default:
280 TF_RUNTIME_ERROR("HdCyclesRenderBuffer::WritePixels called with unsupported format.");
281 break;
282 }
283}
284
void WritePixels(const float *pixels, const PXR_NS::GfVec2i &offset, const PXR_NS::GfVec2i &dims, const int channels, bool isId=false)
bool IsConverged() const override
void Resolve() override
void SetConverged(bool converged)
HdCyclesRenderBuffer(const PXR_NS::SdfPath &bprimId)
bool IsResourceUsed() const
bool Allocate(const PXR_NS::GfVec3i &dimensions, PXR_NS::HdFormat format, bool multiSampled) override
~HdCyclesRenderBuffer() override
bool IsMapped() const override
void SetResource(const PXR_NS::VtValue &resource)
void Unmap() override
void * Map() override
void Finalize(PXR_NS::HdRenderParam *renderParam) override
PXR_NS::VtValue GetResource(bool multiSampled=false) const override
Definition half.h:41
#define resource
ccl_device_inline half float_to_half_image(const float f)
Definition half.h:70
#define HDCYCLES_NAMESPACE_CLOSE_SCOPE
format
void convert(SignedNormalized< StorageType > &dst, const F32 &src)