Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/hydra/render_buffer.cpp')
-rw-r--r--intern/cycles/hydra/render_buffer.cpp276
1 files changed, 276 insertions, 0 deletions
diff --git a/intern/cycles/hydra/render_buffer.cpp b/intern/cycles/hydra/render_buffer.cpp
new file mode 100644
index 00000000000..4867def0624
--- /dev/null
+++ b/intern/cycles/hydra/render_buffer.cpp
@@ -0,0 +1,276 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2022 NVIDIA Corporation
+ * Copyright 2022 Blender Foundation */
+
+#include "hydra/render_buffer.h"
+#include "hydra/session.h"
+#include "util/half.h"
+
+#include <pxr/base/gf/vec3i.h>
+#include <pxr/base/gf/vec4f.h>
+
+HDCYCLES_NAMESPACE_OPEN_SCOPE
+
+HdCyclesRenderBuffer::HdCyclesRenderBuffer(const SdfPath &bprimId) : HdRenderBuffer(bprimId)
+{
+}
+
+HdCyclesRenderBuffer::~HdCyclesRenderBuffer()
+{
+}
+
+void HdCyclesRenderBuffer::Finalize(HdRenderParam *renderParam)
+{
+ // Remove this render buffer from AOV bindings
+ // This ensures that 'OutputDriver' does not attempt to write to it anymore
+ static_cast<HdCyclesSession *>(renderParam)->RemoveAovBinding(this);
+
+ HdRenderBuffer::Finalize(renderParam);
+}
+
+bool HdCyclesRenderBuffer::Allocate(const GfVec3i &dimensions, HdFormat format, bool multiSampled)
+{
+ if (dimensions[2] != 1) {
+ TF_RUNTIME_ERROR("HdCyclesRenderBuffer::Allocate called with dimensions that are not 2D.");
+ return false;
+ }
+
+ const size_t oldSize = _data.size();
+ const size_t newSize = dimensions[0] * dimensions[1] * HdDataSizeOfFormat(format);
+ if (oldSize == newSize) {
+ return true;
+ }
+
+ if (IsMapped()) {
+ TF_RUNTIME_ERROR("HdCyclesRenderBuffer::Allocate called while buffer is mapped.");
+ return false;
+ }
+
+ _width = dimensions[0];
+ _height = dimensions[1];
+ _format = format;
+
+ _data.resize(newSize);
+
+ return true;
+}
+
+void HdCyclesRenderBuffer::_Deallocate()
+{
+ _width = 0u;
+ _height = 0u;
+ _format = HdFormatInvalid;
+
+ _data.clear();
+ _data.shrink_to_fit();
+
+ _resource = VtValue();
+}
+
+void *HdCyclesRenderBuffer::Map()
+{
+ // Mapping is not implemented when a resource is set
+ if (!_resource.IsEmpty()) {
+ return nullptr;
+ }
+
+ ++_mapped;
+
+ return _data.data();
+}
+
+void HdCyclesRenderBuffer::Unmap()
+{
+ --_mapped;
+}
+
+bool HdCyclesRenderBuffer::IsMapped() const
+{
+ return _mapped != 0;
+}
+
+void HdCyclesRenderBuffer::Resolve()
+{
+}
+
+bool HdCyclesRenderBuffer::IsConverged() const
+{
+ return _converged;
+}
+
+void HdCyclesRenderBuffer::SetConverged(bool converged)
+{
+ _converged = converged;
+}
+
+VtValue HdCyclesRenderBuffer::GetResource(bool multiSampled) const
+{
+ TF_UNUSED(multiSampled);
+
+ return _resource;
+}
+
+void HdCyclesRenderBuffer::SetResource(const VtValue &resource)
+{
+ _resource = resource;
+}
+
+namespace {
+
+struct SimpleConversion {
+ static float convert(float value)
+ {
+ return value;
+ }
+};
+struct IdConversion {
+ static int32_t convert(float value)
+ {
+ return static_cast<int32_t>(value) - 1;
+ }
+};
+struct UInt8Conversion {
+ static uint8_t convert(float value)
+ {
+ return static_cast<uint8_t>(value * 255.f);
+ }
+};
+struct SInt8Conversion {
+ static int8_t convert(float value)
+ {
+ return static_cast<int8_t>(value * 127.f);
+ }
+};
+struct HalfConversion {
+ static half convert(float value)
+ {
+ return float_to_half_image(value);
+ }
+};
+
+template<typename SrcT, typename DstT, typename Convertor = SimpleConversion>
+void writePixels(const SrcT *srcPtr,
+ const GfVec2i &srcSize,
+ int srcChannelCount,
+ DstT *dstPtr,
+ const GfVec2i &dstSize,
+ int dstChannelCount,
+ const Convertor &convertor = {})
+{
+ const auto writeSize = GfVec2i(GfMin(srcSize[0], dstSize[0]), GfMin(srcSize[1], dstSize[1]));
+ const auto writeChannelCount = GfMin(srcChannelCount, dstChannelCount);
+
+ for (int y = 0; y < writeSize[1]; ++y) {
+ for (int x = 0; x < writeSize[0]; ++x) {
+ for (int c = 0; c < writeChannelCount; ++c) {
+ dstPtr[x * dstChannelCount + c] = convertor.convert(srcPtr[x * srcChannelCount + c]);
+ }
+ }
+ srcPtr += srcSize[0] * srcChannelCount;
+ dstPtr += dstSize[0] * dstChannelCount;
+ }
+}
+
+} // namespace
+
+void HdCyclesRenderBuffer::WritePixels(const float *srcPixels,
+ const PXR_NS::GfVec2i &srcOffset,
+ const GfVec2i &srcDims,
+ int srcChannels,
+ bool isId)
+{
+ uint8_t *dstPixels = _data.data();
+
+ const size_t formatSize = HdDataSizeOfFormat(_format);
+ dstPixels += srcOffset[1] * (formatSize * _width) + srcOffset[0] * formatSize;
+
+ switch (_format) {
+ case HdFormatUNorm8:
+ case HdFormatUNorm8Vec2:
+ case HdFormatUNorm8Vec3:
+ case HdFormatUNorm8Vec4:
+ writePixels(srcPixels,
+ srcDims,
+ srcChannels,
+ dstPixels,
+ GfVec2i(_width, _height),
+ 1 + (_format - HdFormatUNorm8),
+ UInt8Conversion());
+ break;
+
+ case HdFormatSNorm8:
+ case HdFormatSNorm8Vec2:
+ case HdFormatSNorm8Vec3:
+ case HdFormatSNorm8Vec4:
+ writePixels(srcPixels,
+ srcDims,
+ srcChannels,
+ dstPixels,
+ GfVec2i(_width, _height),
+ 1 + (_format - HdFormatSNorm8),
+ SInt8Conversion());
+ break;
+
+ case HdFormatFloat16:
+ case HdFormatFloat16Vec2:
+ case HdFormatFloat16Vec3:
+ case HdFormatFloat16Vec4:
+ writePixels(srcPixels,
+ srcDims,
+ srcChannels,
+ reinterpret_cast<half *>(dstPixels),
+ GfVec2i(_width, _height),
+ 1 + (_format - HdFormatFloat16),
+ HalfConversion());
+ break;
+
+ case HdFormatFloat32:
+ case HdFormatFloat32Vec2:
+ case HdFormatFloat32Vec3:
+ case HdFormatFloat32Vec4:
+ writePixels(srcPixels,
+ srcDims,
+ srcChannels,
+ reinterpret_cast<float *>(dstPixels),
+ GfVec2i(_width, _height),
+ 1 + (_format - HdFormatFloat32));
+ break;
+
+ case HdFormatInt32:
+ // Special case for ID AOVs (see 'HdCyclesMesh::Sync')
+ if (isId) {
+ writePixels(srcPixels,
+ srcDims,
+ srcChannels,
+ reinterpret_cast<int *>(dstPixels),
+ GfVec2i(_width, _height),
+ 1,
+ IdConversion());
+ }
+ else {
+ writePixels(srcPixels,
+ srcDims,
+ srcChannels,
+ reinterpret_cast<int *>(dstPixels),
+ GfVec2i(_width, _height),
+ 1);
+ }
+ break;
+ case HdFormatInt32Vec2:
+ case HdFormatInt32Vec3:
+ case HdFormatInt32Vec4:
+ writePixels(srcPixels,
+ srcDims,
+ srcChannels,
+ reinterpret_cast<int *>(dstPixels),
+ GfVec2i(_width, _height),
+ 1 + (_format - HdFormatInt32));
+ break;
+
+ default:
+ TF_RUNTIME_ERROR("HdCyclesRenderBuffer::WritePixels called with unsupported format.");
+ break;
+ }
+}
+
+HDCYCLES_NAMESPACE_CLOSE_SCOPE