Blender V4.3
hydra/output_driver.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
8#include "hydra/session.h"
9
11
13 : _renderParam(renderParam)
14{
15}
16
17void HdCyclesOutputDriver::write_render_tile(const Tile &tile)
18{
19 update_render_tile(tile);
20
21 // Update convergence state of all render buffers
22 for (const HdRenderPassAovBinding &aovBinding : _renderParam->GetAovBindings()) {
23 if (const auto renderBuffer = static_cast<HdCyclesRenderBuffer *>(aovBinding.renderBuffer)) {
24 renderBuffer->SetConverged(true);
25 }
26 }
27}
28
29bool HdCyclesOutputDriver::update_render_tile(const Tile &tile)
30{
31 std::vector<float> pixels;
32
33 for (const HdRenderPassAovBinding &aovBinding : _renderParam->GetAovBindings()) {
34 if (const auto renderBuffer = static_cast<HdCyclesRenderBuffer *>(aovBinding.renderBuffer)) {
35 if (aovBinding == _renderParam->GetDisplayAovBinding() && renderBuffer->IsResourceUsed()) {
36 continue; // Display AOV binding is already updated by Cycles display driver
37 }
38
39 const HdFormat format = renderBuffer->GetFormat();
40 if (format == HdFormatInvalid) {
41 continue; // Skip invalid AOV bindings
42 }
43
44 const size_t channels = HdGetComponentCount(format);
45 // Avoid extra copy by mapping render buffer directly when dimensions/format match the tile
46 if (tile.offset.x == 0 && tile.offset.y == 0 && tile.size.x == renderBuffer->GetWidth() &&
47 tile.size.y == renderBuffer->GetHeight() &&
48 (format >= HdFormatFloat32 && format <= HdFormatFloat32Vec4))
49 {
50 float *const data = static_cast<float *>(renderBuffer->Map());
51 TF_VERIFY(tile.get_pass_pixels(aovBinding.aovName.GetString(), channels, data));
52 renderBuffer->Unmap();
53 }
54 else {
55 pixels.resize(channels * tile.size.x * tile.size.y);
56 if (tile.get_pass_pixels(aovBinding.aovName.GetString(), channels, pixels.data())) {
57 const bool isId = aovBinding.aovName == HdAovTokens->primId ||
58 aovBinding.aovName == HdAovTokens->elementId ||
59 aovBinding.aovName == HdAovTokens->instanceId;
60 renderBuffer->Map();
61 renderBuffer->WritePixels(pixels.data(),
62 GfVec2i(tile.offset.x, tile.offset.y),
63 GfVec2i(tile.size.x, tile.size.y),
64 channels,
65 isId);
66 renderBuffer->Unmap();
67 }
68 else {
69 // Do not warn on missing elementId, which is a standard AOV but is not implememted
70 if (aovBinding.aovName != HdAovTokens->elementId) {
71 TF_RUNTIME_ERROR("Could not find pass for AOV '%s'", aovBinding.aovName.GetText());
72 }
73 }
74 }
75 }
76 }
77
78 return true;
79}
80
HdCyclesOutputDriver(HdCyclesSession *renderParam)
PXR_NS::HdRenderPassAovBinding GetDisplayAovBinding() const
#define HDCYCLES_NAMESPACE_CLOSE_SCOPE
ccl_global const KernelWorkTile * tile
format