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