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/output_driver.cpp')
-rw-r--r--intern/cycles/hydra/output_driver.cpp78
1 files changed, 78 insertions, 0 deletions
diff --git a/intern/cycles/hydra/output_driver.cpp b/intern/cycles/hydra/output_driver.cpp
new file mode 100644
index 00000000000..c5f64ac1c18
--- /dev/null
+++ b/intern/cycles/hydra/output_driver.cpp
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2022 NVIDIA Corporation
+ * Copyright 2022 Blender Foundation */
+
+#include "hydra/output_driver.h"
+#include "hydra/render_buffer.h"
+#include "hydra/session.h"
+
+HDCYCLES_NAMESPACE_OPEN_SCOPE
+
+HdCyclesOutputDriver::HdCyclesOutputDriver(HdCyclesSession *renderParam)
+ : _renderParam(renderParam)
+{
+}
+
+void HdCyclesOutputDriver::write_render_tile(const Tile &tile)
+{
+ update_render_tile(tile);
+
+ // Update convergence state of all render buffers
+ for (const HdRenderPassAovBinding &aovBinding : _renderParam->GetAovBindings()) {
+ if (const auto renderBuffer = static_cast<HdCyclesRenderBuffer *>(aovBinding.renderBuffer)) {
+ renderBuffer->SetConverged(true);
+ }
+ }
+}
+
+bool HdCyclesOutputDriver::update_render_tile(const Tile &tile)
+{
+ std::vector<float> pixels;
+
+ for (const HdRenderPassAovBinding &aovBinding : _renderParam->GetAovBindings()) {
+ if (aovBinding == _renderParam->GetDisplayAovBinding()) {
+ continue; // Display AOV binding is already updated by Cycles display driver
+ }
+
+ if (const auto renderBuffer = static_cast<HdCyclesRenderBuffer *>(aovBinding.renderBuffer)) {
+ const HdFormat format = renderBuffer->GetFormat();
+ if (format == HdFormatInvalid) {
+ continue; // Skip invalid AOV bindings
+ }
+
+ const size_t channels = HdGetComponentCount(format);
+ // Avoid extra copy by mapping render buffer directly when dimensions/format match the tile
+ if (tile.offset.x == 0 && tile.offset.y == 0 && tile.size.x == renderBuffer->GetWidth() &&
+ tile.size.y == renderBuffer->GetHeight() &&
+ (format >= HdFormatFloat32 && format <= HdFormatFloat32Vec4)) {
+ float *const data = static_cast<float *>(renderBuffer->Map());
+ TF_VERIFY(tile.get_pass_pixels(aovBinding.aovName.GetString(), channels, data));
+ renderBuffer->Unmap();
+ }
+ else {
+ pixels.resize(channels * tile.size.x * tile.size.y);
+ if (tile.get_pass_pixels(aovBinding.aovName.GetString(), channels, pixels.data())) {
+ const bool isId = aovBinding.aovName == HdAovTokens->primId ||
+ aovBinding.aovName == HdAovTokens->elementId ||
+ aovBinding.aovName == HdAovTokens->instanceId;
+
+ renderBuffer->WritePixels(pixels.data(),
+ GfVec2i(tile.offset.x, tile.offset.y),
+ GfVec2i(tile.size.x, tile.size.y),
+ channels,
+ isId);
+ }
+ else {
+ // Do not warn on missing elementId, which is a standard AOV but is not implememted
+ if (aovBinding.aovName != HdAovTokens->elementId) {
+ TF_RUNTIME_ERROR("Could not find pass for AOV '%s'", aovBinding.aovName.GetText());
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+HDCYCLES_NAMESPACE_CLOSE_SCOPE