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

gpu_framebuffer_private.hh « intern « gpu « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: cb7fd62445c9f51f4f5567098700b35a4c372bf8 (plain)
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/* SPDX-License-Identifier: GPL-2.0-or-later
 * Copyright 2020 Blender Foundation. All rights reserved. */

/** \file
 * \ingroup gpu
 *
 * Private frame buffer API.
 */

#pragma once

#include "BLI_math_vector.h"
#include "BLI_span.hh"

#include "MEM_guardedalloc.h"

#include "GPU_framebuffer.h"

struct GPUTexture;

typedef enum GPUAttachmentType : int {
  GPU_FB_DEPTH_ATTACHMENT = 0,
  GPU_FB_DEPTH_STENCIL_ATTACHMENT,
  GPU_FB_COLOR_ATTACHMENT0,
  GPU_FB_COLOR_ATTACHMENT1,
  GPU_FB_COLOR_ATTACHMENT2,
  GPU_FB_COLOR_ATTACHMENT3,
  GPU_FB_COLOR_ATTACHMENT4,
  GPU_FB_COLOR_ATTACHMENT5,
  GPU_FB_COLOR_ATTACHMENT6,
  GPU_FB_COLOR_ATTACHMENT7,
  /* Number of maximum output slots. */
  /* Keep in mind that GL max is GL_MAX_DRAW_BUFFERS and is at least 8, corresponding to
   * the maximum number of COLOR attachments specified by glDrawBuffers. */
  GPU_FB_MAX_ATTACHMENT,

} GPUAttachmentType;

#define GPU_FB_MAX_COLOR_ATTACHMENT (GPU_FB_MAX_ATTACHMENT - GPU_FB_COLOR_ATTACHMENT0)

inline constexpr GPUAttachmentType operator-(GPUAttachmentType a, int b)
{
  return static_cast<GPUAttachmentType>(int(a) - b);
}

inline constexpr GPUAttachmentType operator+(GPUAttachmentType a, int b)
{
  return static_cast<GPUAttachmentType>(int(a) + b);
}

inline GPUAttachmentType &operator++(GPUAttachmentType &a)
{
  a = a + 1;
  return a;
}

inline GPUAttachmentType &operator--(GPUAttachmentType &a)
{
  a = a - 1;
  return a;
}

namespace blender {
namespace gpu {

#ifdef DEBUG
#  define DEBUG_NAME_LEN 64
#else
#  define DEBUG_NAME_LEN 16
#endif

class FrameBuffer {
 protected:
  /** Set of texture attachments to render to. DEPTH and DEPTH_STENCIL are mutually exclusive. */
  GPUAttachment attachments_[GPU_FB_MAX_ATTACHMENT];
  /** Is true if internal representation need to be updated. */
  bool dirty_attachments_ = true;
  /** Size of attachment textures. */
  int width_ = 0, height_ = 0;
  /** Debug name. */
  char name_[DEBUG_NAME_LEN];
  /** Frame-buffer state. */
  int viewport_[4] = {0};
  int scissor_[4] = {0};
  bool scissor_test_ = false;
  bool dirty_state_ = true;

#ifndef GPU_NO_USE_PY_REFERENCES
 public:
  /**
   * Reference of a pointer that needs to be cleaned when deallocating the frame-buffer.
   * Points to #BPyGPUFrameBuffer.fb
   */
  void **py_ref = nullptr;
#endif

 public:
  FrameBuffer(const char *name);
  virtual ~FrameBuffer();

  virtual void bind(bool enabled_srgb) = 0;
  virtual bool check(char err_out[256]) = 0;
  virtual void clear(eGPUFrameBufferBits buffers,
                     const float clear_col[4],
                     float clear_depth,
                     uint clear_stencil) = 0;
  virtual void clear_multi(const float (*clear_col)[4]) = 0;
  virtual void clear_attachment(GPUAttachmentType type,
                                eGPUDataFormat data_format,
                                const void *clear_value) = 0;

  virtual void attachment_set_loadstore_op(GPUAttachmentType type,
                                           eGPULoadOp load_action,
                                           eGPUStoreOp store_action) = 0;

  virtual void read(eGPUFrameBufferBits planes,
                    eGPUDataFormat format,
                    const int area[4],
                    int channel_len,
                    int slot,
                    void *r_data) = 0;

  virtual void blit_to(eGPUFrameBufferBits planes,
                       int src_slot,
                       FrameBuffer *dst,
                       int dst_slot,
                       int dst_offset_x,
                       int dst_offset_y) = 0;

  void load_store_config_array(const GPULoadStore *load_store_actions, uint actions_len);

  void attachment_set(GPUAttachmentType type, const GPUAttachment &new_attachment);
  void attachment_remove(GPUAttachmentType type);

  void recursive_downsample(int max_lvl,
                            void (*callback)(void *userData, int level),
                            void *userData);
  uint get_bits_per_pixel();

  inline void size_set(int width, int height)
  {
    width_ = width;
    height_ = height;
    dirty_state_ = true;
  }

  inline void viewport_set(const int viewport[4])
  {
    if (!equals_v4v4_int(viewport_, viewport)) {
      copy_v4_v4_int(viewport_, viewport);
      dirty_state_ = true;
    }
  }

  inline void scissor_set(const int scissor[4])
  {
    if (!equals_v4v4_int(scissor_, scissor)) {
      copy_v4_v4_int(scissor_, scissor);
      dirty_state_ = true;
    }
  }

  inline void scissor_test_set(bool test)
  {
    scissor_test_ = test;
  }

  inline void viewport_get(int r_viewport[4]) const
  {
    copy_v4_v4_int(r_viewport, viewport_);
  }

  inline void scissor_get(int r_scissor[4]) const
  {
    copy_v4_v4_int(r_scissor, scissor_);
  }

  inline bool scissor_test_get() const
  {
    return scissor_test_;
  }

  inline void viewport_reset()
  {
    int viewport_rect[4] = {0, 0, width_, height_};
    viewport_set(viewport_rect);
  }

  inline void scissor_reset()
  {
    int scissor_rect[4] = {0, 0, width_, height_};
    scissor_set(scissor_rect);
  }

  inline GPUTexture *depth_tex() const
  {
    if (attachments_[GPU_FB_DEPTH_ATTACHMENT].tex) {
      return attachments_[GPU_FB_DEPTH_ATTACHMENT].tex;
    }
    return attachments_[GPU_FB_DEPTH_STENCIL_ATTACHMENT].tex;
  };

  inline GPUTexture *color_tex(int slot) const
  {
    return attachments_[GPU_FB_COLOR_ATTACHMENT0 + slot].tex;
  };

  inline const char *const name_get() const
  {
    return name_;
  };
};

/* Syntactic sugar. */
static inline GPUFrameBuffer *wrap(FrameBuffer *vert)
{
  return reinterpret_cast<GPUFrameBuffer *>(vert);
}
static inline FrameBuffer *unwrap(GPUFrameBuffer *vert)
{
  return reinterpret_cast<FrameBuffer *>(vert);
}
static inline const FrameBuffer *unwrap(const GPUFrameBuffer *vert)
{
  return reinterpret_cast<const FrameBuffer *>(vert);
}

#undef DEBUG_NAME_LEN

}  // namespace gpu
}  // namespace blender