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