File: SparseFB.h

package info (click to toggle)
ospray 3.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,048 kB
  • sloc: cpp: 80,569; ansic: 951; sh: 805; makefile: 170; python: 69
file content (137 lines) | stat: -rw-r--r-- 4,767 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright 2022 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "ISPCDevice.h"
#include "fb/FrameBuffer.h"
#include "fb/LocalFB.h"
#include "rkcommon/containers/AlignedVector.h"
#include "rkcommon/utility/ArrayView.h"
// ispc shared
#include "TileShared.h"
#include "fb/SparseFBShared.h"

namespace ospray {
/* The sparse framebuffer stores a subset of tiles of a larger framebuffer
 * to allow rendering tasks to directly write to this allocated tile memory,
 * rather than requiring on the fly allocation of tiles. The sparse framebuffer
 * is used as a component of a "parent" framebuffer that is responsible for
 * distributing the full image among different sparse framebuffers and
 * collecting the tiles from them into a complete image in some way.
 *
 * The sparse framebuffer doesn't store the entire image data and thus doesn't
 * support frame/tile operations or mapping.
 */
struct OSPRAY_SDK_INTERFACE SparseFrameBuffer
    : public AddStructShared<FrameBuffer, ispc::SparseFB>
{
  // Create a sparse framebuffer holding the tiles specified in tileIDs
  SparseFrameBuffer(api::ISPCDevice &device,
      const vec2i &size,
      ColorBufferFormat colorBufferFormat,
      const uint32 channels,
      const std::vector<uint32_t> &tileIDs);

  // Create a sparse framebuffer that stores no image tiles. Tiles can be added
  // to the empty sparse framebuffer by calling setTiles
  SparseFrameBuffer(api::ISPCDevice &device,
      const vec2i &size,
      ColorBufferFormat colorBufferFormat,
      const uint32 channels);

  // Return the number of render tasks in the x and y direction
  // This is the kernel launch dims to render the image
  virtual vec2i getNumRenderTasks() const override;

  virtual uint32_t getTotalRenderTasks() const override;

  virtual utility::ArrayView<uint32_t> getRenderTaskIDs(
      const float errorThreshold = 0.f, const uint32_t spp = 1) override;

  //! \brief common function to help printf-debugging
  /*! \detailed Every derived class should override this! */
  virtual std::string toString() const override;

  float taskError(const uint32_t taskID) const override;

  /* Set the error for a given task, used by the parent framebuffer managing the
   * sparse framebuffers to sync error computed over the entire image
   */
  void setTaskError(const uint32_t taskID, const float error);

  void beginFrame() override;

  devicert::AsyncEvent postProcess() override
  {
    // Do not run post-processing on sparse frame buffer
    return devicert::AsyncEvent();
  }

  // Mapping sparse framebuffers is not supported, will return null
  const void *mapBuffer(OSPFrameBufferChannel channel) override;

  void unmap(const void *mappedMem) override;

  void clear() override;

  size_t getNumTiles() const;

  const utility::ArrayView<Tile> getTiles();

  // Get a view of the device memory of the tiles
  const utility::ArrayView<Tile> getTilesDevice() const;

  const utility::ArrayView<uint32_t> getTileIDs();

  // Get the index of the tile in the tile ID and Tiles lists that this task
  // falls into
  uint32_t getTileIndexForTask(uint32_t taskID) const;

  /* Change the tiles stored in this SparseFrameBuffer, re-using the existing
   * storage. New tiles will be allocated if the size of the tileIDs passed
   * exceeds those currently stored in the SparseFrameBuffer
   */
  void setTiles(const std::vector<uint32_t> &tileIDs);

  // Return the image region for the tile
  box2i getTileRegion(uint32_t tileID) const;

  //// Data ////
 protected:
  // Get the position of a task in its tile
  vec2i getTaskPosInTile(const uint32_t taskID) const;

  uint32_t getNumTasksPerTile() const;

  api::ISPCDevice &device;

  // The tiles in this framebuffer
  BufferDeviceShadowedUq<Tile> tiles;
  // Track if we need to read back tiles to the host
  bool tilesDirty = false;

  // Variance data for the image, stored in tiled order with one RGBA value per
  // pixel, accumulates every other sample, for variance estimation
  BufferDeviceUq<vec4f> varianceBuffer;

  // Does this need to be USM at all?
  std::vector<uint32_t> tileIDs;

  // Total number of tiles that the framebuffer is divided into, including those
  // not owned by this sparsefb
  vec2i totalTiles;

  // Total number of render tasks that the framebuffer is divided into,
  // including those not owned by this sparsefb
  vec2i numRenderTasks{0};

  // holds error per task for each tile, stored in tiled order.
  // The SparseFB doesn't do its own error refinement since it doesn't have
  // access to error data for the entire framebuffer
  BufferSharedUq<float> taskErrorBuffer;

  BufferDeviceShadowedUq<uint32_t> renderTaskIDs;
  BufferDeviceShadowedUq<uint32_t> activeTaskIDs;
};
} // namespace ospray