Blender  V2.93
gpu_texture_private.hh
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2020 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #pragma once
25 
26 #include "BLI_assert.h"
27 
28 #include "GPU_vertex_buffer.h"
29 
31 
32 namespace blender {
33 namespace gpu {
34 
35 typedef enum eGPUTextureFormatFlag {
36  GPU_FORMAT_DEPTH = (1 << 0),
37  GPU_FORMAT_STENCIL = (1 << 1),
38  GPU_FORMAT_INTEGER = (1 << 2),
39  GPU_FORMAT_FLOAT = (1 << 3),
41 
44 
46 
47 typedef enum eGPUTextureType {
48  GPU_TEXTURE_1D = (1 << 0),
49  GPU_TEXTURE_2D = (1 << 1),
50  GPU_TEXTURE_3D = (1 << 2),
51  GPU_TEXTURE_CUBE = (1 << 3),
52  GPU_TEXTURE_ARRAY = (1 << 4),
53  GPU_TEXTURE_BUFFER = (1 << 5),
54 
59 
61 
62 #ifdef DEBUG
63 # define DEBUG_NAME_LEN 64
64 #else
65 # define DEBUG_NAME_LEN 8
66 #endif
67 
68 /* Maximum number of FBOs a texture can be attached to. */
69 #define GPU_TEX_MAX_FBO_ATTACHED 16
70 
75 class Texture {
76  public:
80  int refcount = 1;
82  int src_w = 0, src_h = 0;
83 
84  protected:
85  /* ---- Texture format (immutable after init). ---- */
87  int w_, h_, d_;
94 
96  /* TODO(fclem): Should become immutable and the need for mipmaps should be specified upfront. */
97  int mipmaps_ = -1;
99  int mip_min_ = 0, mip_max_ = 0;
100 
103 
107 
108  public:
109  Texture(const char *name);
110  virtual ~Texture();
111 
112  /* Return true on success. */
113  bool init_1D(int w, int layers, eGPUTextureFormat format);
114  bool init_2D(int w, int h, int layers, eGPUTextureFormat format);
115  bool init_3D(int w, int h, int d, eGPUTextureFormat format);
116  bool init_cubemap(int w, int layers, eGPUTextureFormat format);
118 
119  virtual void generate_mipmap(void) = 0;
120  virtual void copy_to(Texture *tex) = 0;
121  virtual void clear(eGPUDataFormat format, const void *data) = 0;
122  virtual void swizzle_set(const char swizzle_mask[4]) = 0;
123  virtual void mip_range_set(int min, int max) = 0;
124  virtual void *read(int mip, eGPUDataFormat format) = 0;
125 
127  void detach_from(FrameBuffer *fb);
128  void update(eGPUDataFormat format, const void *data);
129 
130  virtual void update_sub(
131  int mip, int offset[3], int extent[3], eGPUDataFormat format, const void *data) = 0;
132 
133  /* TODO(fclem): Legacy. Should be removed at some point. */
134  virtual uint gl_bindcode_get(void) const = 0;
135 
136  int width_get(void) const
137  {
138  return w_;
139  }
140  int height_get(void) const
141  {
142  return h_;
143  }
144  int depth_get(void) const
145  {
146  return d_;
147  }
148 
149  void mip_size_get(int mip, int r_size[3]) const
150  {
151  /* TODO assert if lvl is below the limit of 1px in each dimension. */
152  int div = 1 << mip;
153  r_size[0] = max_ii(1, w_ / div);
154 
155  if (type_ == GPU_TEXTURE_1D_ARRAY) {
156  r_size[1] = h_;
157  }
158  else if (h_ > 0) {
159  r_size[1] = max_ii(1, h_ / div);
160  }
161 
163  r_size[2] = d_;
164  }
165  else if (d_ > 0) {
166  r_size[2] = max_ii(1, d_ / div);
167  }
168  }
169 
170  int mip_width_get(int mip) const
171  {
172  return max_ii(1, w_ / (1 << mip));
173  }
174  int mip_height_get(int mip) const
175  {
176  return (type_ == GPU_TEXTURE_1D_ARRAY) ? h_ : max_ii(1, h_ / (1 << mip));
177  }
178  int mip_depth_get(int mip) const
179  {
180  return (type_ & (GPU_TEXTURE_ARRAY | GPU_TEXTURE_CUBE)) ? d_ : max_ii(1, d_ / (1 << mip));
181  }
182 
183  /* Return number of dimension taking the array type into account. */
184  int dimensions_count(void) const
185  {
186  const int array = (type_ & GPU_TEXTURE_ARRAY) ? 1 : 0;
187  switch (type_ & ~GPU_TEXTURE_ARRAY) {
188  case GPU_TEXTURE_BUFFER:
189  return 1;
190  case GPU_TEXTURE_1D:
191  return 1 + array;
192  case GPU_TEXTURE_2D:
193  return 2 + array;
194  case GPU_TEXTURE_CUBE:
195  case GPU_TEXTURE_3D:
196  default:
197  return 3;
198  }
199  }
200  /* Return number of array layer (or face layer) for texture array or 1 for the others. */
201  int layer_count(void) const
202  {
203  switch (type_) {
205  return h_;
208  return d_;
209  default:
210  return 1;
211  }
212  }
213 
215  {
216  return format_;
217  }
219  {
220  return format_flag_;
221  }
223  {
224  return type_;
225  }
227  {
228  switch (format_) {
232  BLI_assert(slot == 0);
236  BLI_assert(slot == 0);
238  default:
239  return GPU_FB_COLOR_ATTACHMENT0 + slot;
240  }
241  }
242 
243  protected:
244  virtual bool init_internal(void) = 0;
245  virtual bool init_internal(GPUVertBuf *vbo) = 0;
246 };
247 
248 /* Syntactic sugar. */
249 static inline GPUTexture *wrap(Texture *vert)
250 {
251  return reinterpret_cast<GPUTexture *>(vert);
252 }
253 static inline Texture *unwrap(GPUTexture *vert)
254 {
255  return reinterpret_cast<Texture *>(vert);
256 }
257 static inline const Texture *unwrap(const GPUTexture *vert)
258 {
259  return reinterpret_cast<const Texture *>(vert);
260 }
261 
262 #undef DEBUG_NAME_LEN
263 
265 {
266  switch (format) {
267  case GPU_RGBA32F:
268  return 32;
269  case GPU_RG32F:
270  case GPU_RGBA16F:
271  case GPU_RGBA16:
272  return 16;
273  case GPU_RGB16F:
274  return 12;
275  case GPU_DEPTH32F_STENCIL8: /* 32-bit depth, 8 bits stencil, and 24 unused bits. */
276  return 8;
277  case GPU_RG16F:
278  case GPU_RG16I:
279  case GPU_RG16UI:
280  case GPU_RG16:
283  case GPU_RGBA8UI:
284  case GPU_RGBA8:
285  case GPU_SRGB8_A8:
286  case GPU_RGB10_A2:
287  case GPU_R11F_G11F_B10F:
288  case GPU_R32F:
289  case GPU_R32UI:
290  case GPU_R32I:
291  return 4;
293  return 3;
295  case GPU_R16F:
296  case GPU_R16UI:
297  case GPU_R16I:
298  case GPU_RG8:
299  case GPU_R16:
300  return 2;
301  case GPU_R8:
302  case GPU_R8UI:
303  return 1;
304  case GPU_SRGB8_A8_DXT1:
305  case GPU_SRGB8_A8_DXT3:
306  case GPU_SRGB8_A8_DXT5:
307  case GPU_RGBA8_DXT1:
308  case GPU_RGBA8_DXT3:
309  case GPU_RGBA8_DXT5:
310  return 1; /* Incorrect but actual size is fractional. */
311  default:
312  BLI_assert(!"Texture format incorrect or unsupported\n");
313  return 0;
314  }
315 }
316 
317 inline size_t to_block_size(eGPUTextureFormat data_type)
318 {
319  switch (data_type) {
320  case GPU_SRGB8_A8_DXT1:
321  case GPU_RGBA8_DXT1:
322  return 8;
323  case GPU_SRGB8_A8_DXT3:
324  case GPU_SRGB8_A8_DXT5:
325  case GPU_RGBA8_DXT3:
326  case GPU_RGBA8_DXT5:
327  return 16;
328  default:
329  BLI_assert(!"Texture format is not a compressed format\n");
330  return 0;
331  }
332 }
333 
335 {
336  switch (format) {
340  return GPU_FORMAT_DEPTH;
344  case GPU_R8UI:
345  case GPU_RG16I:
346  case GPU_R16I:
347  case GPU_RG16UI:
348  case GPU_R16UI:
349  case GPU_R32UI:
350  return GPU_FORMAT_INTEGER;
351  case GPU_SRGB8_A8_DXT1:
352  case GPU_SRGB8_A8_DXT3:
353  case GPU_SRGB8_A8_DXT5:
354  case GPU_RGBA8_DXT1:
355  case GPU_RGBA8_DXT3:
356  case GPU_RGBA8_DXT5:
357  return GPU_FORMAT_COMPRESSED;
358  default:
359  return GPU_FORMAT_FLOAT;
360  }
361 }
362 
364 {
365  switch (format) {
366  case GPU_RGBA8:
367  case GPU_RGBA8UI:
368  case GPU_RGBA16F:
369  case GPU_RGBA16:
370  case GPU_RGBA32F:
371  case GPU_SRGB8_A8:
372  case GPU_RGB10_A2:
373  return 4;
374  case GPU_RGB16F:
375  case GPU_R11F_G11F_B10F:
376  return 3;
377  case GPU_RG8:
378  case GPU_RG16:
379  case GPU_RG16F:
380  case GPU_RG16I:
381  case GPU_RG16UI:
382  case GPU_RG32F:
383  return 2;
384  default:
385  return 1;
386  }
387 }
388 
389 inline size_t to_bytesize(eGPUDataFormat data_format)
390 {
391  switch (data_format) {
392  case GPU_DATA_UBYTE:
393  return 1;
394  case GPU_DATA_FLOAT:
395  case GPU_DATA_INT:
396  case GPU_DATA_UINT:
397  return 4;
398  case GPU_DATA_UINT_24_8:
401  return 4;
402  default:
403  BLI_assert(!"Data format incorrect or unsupported\n");
404  return 0;
405  }
406 }
407 
408 inline size_t to_bytesize(eGPUTextureFormat tex_format, eGPUDataFormat data_format)
409 {
410  return to_component_len(tex_format) * to_bytesize(data_format);
411 }
412 
413 /* Definitely not complete, edit according to the gl specification. */
414 inline bool validate_data_format(eGPUTextureFormat tex_format, eGPUDataFormat data_format)
415 {
416  switch (tex_format) {
420  return data_format == GPU_DATA_FLOAT;
423  return data_format == GPU_DATA_UINT_24_8;
424  case GPU_R8UI:
425  case GPU_R16UI:
426  case GPU_RG16UI:
427  case GPU_R32UI:
428  return data_format == GPU_DATA_UINT;
429  case GPU_RG16I:
430  case GPU_R16I:
431  return data_format == GPU_DATA_INT;
432  case GPU_R8:
433  case GPU_RG8:
434  case GPU_RGBA8:
435  case GPU_RGBA8UI:
436  case GPU_SRGB8_A8:
437  return ELEM(data_format, GPU_DATA_UBYTE, GPU_DATA_FLOAT);
438  case GPU_RGB10_A2:
439  return ELEM(data_format, GPU_DATA_2_10_10_10_REV, GPU_DATA_FLOAT);
440  case GPU_R11F_G11F_B10F:
441  return ELEM(data_format, GPU_DATA_10_11_11_REV, GPU_DATA_FLOAT);
442  default:
443  return data_format == GPU_DATA_FLOAT;
444  }
445 }
446 
447 /* Definitely not complete, edit according to the gl specification. */
449 {
450  switch (tex_format) {
454  return GPU_DATA_FLOAT;
457  return GPU_DATA_UINT_24_8;
458  case GPU_R8UI:
459  case GPU_R16UI:
460  case GPU_RG16UI:
461  case GPU_R32UI:
462  return GPU_DATA_UINT;
463  case GPU_RG16I:
464  case GPU_R16I:
465  return GPU_DATA_INT;
466  case GPU_R8:
467  case GPU_RG8:
468  case GPU_RGBA8:
469  case GPU_RGBA8UI:
470  case GPU_SRGB8_A8:
471  return GPU_DATA_UBYTE;
472  case GPU_RGB10_A2:
474  case GPU_R11F_G11F_B10F:
475  return GPU_DATA_10_11_11_REV;
476  default:
477  return GPU_DATA_FLOAT;
478  }
479 }
480 
482 {
483  switch (tex_format) {
487  return GPU_DEPTH_BIT;
491  default:
492  return GPU_COLOR_BIT;
493  }
494 }
495 
497 {
498  if (format->attr_len > 1 || format->attr_len == 0) {
499  BLI_assert(!"Incorrect vertex format for buffer texture");
500  return GPU_DEPTH_COMPONENT24;
501  }
502  switch (format->attrs[0].comp_len) {
503  case 1:
504  switch (format->attrs[0].comp_type) {
505  case GPU_COMP_I8:
506  return GPU_R8I;
507  case GPU_COMP_U8:
508  return GPU_R8UI;
509  case GPU_COMP_I16:
510  return GPU_R16I;
511  case GPU_COMP_U16:
512  return GPU_R16UI;
513  case GPU_COMP_I32:
514  return GPU_R32I;
515  case GPU_COMP_U32:
516  return GPU_R32UI;
517  case GPU_COMP_F32:
518  return GPU_R32F;
519  default:
520  break;
521  }
522  break;
523  case 2:
524  switch (format->attrs[0].comp_type) {
525  case GPU_COMP_I8:
526  return GPU_RG8I;
527  case GPU_COMP_U8:
528  return GPU_RG8UI;
529  case GPU_COMP_I16:
530  return GPU_RG16I;
531  case GPU_COMP_U16:
532  return GPU_RG16UI;
533  case GPU_COMP_I32:
534  return GPU_RG32I;
535  case GPU_COMP_U32:
536  return GPU_RG32UI;
537  case GPU_COMP_F32:
538  return GPU_RG32F;
539  default:
540  break;
541  }
542  break;
543  case 3:
544  /* Not supported until GL 4.0 */
545  break;
546  case 4:
547  switch (format->attrs[0].comp_type) {
548  case GPU_COMP_I8:
549  return GPU_RGBA8I;
550  case GPU_COMP_U8:
551  return GPU_RGBA8UI;
552  case GPU_COMP_I16:
553  return GPU_RGBA16I;
554  case GPU_COMP_U16:
555  /* Note: Checking the fetch mode to select the right GPU texture format. This can be
556  * added to other formats as well. */
557  switch (format->attrs[0].fetch_mode) {
558  case GPU_FETCH_INT:
559  return GPU_RGBA16UI;
561  return GPU_RGBA16;
563  return GPU_RGBA16F;
564  case GPU_FETCH_FLOAT:
565  return GPU_RGBA16F;
566  }
567  case GPU_COMP_I32:
568  return GPU_RGBA32I;
569  case GPU_COMP_U32:
570  return GPU_RGBA32UI;
571  case GPU_COMP_F32:
572  return GPU_RGBA32F;
573  default:
574  break;
575  }
576  break;
577  default:
578  break;
579  }
580  BLI_assert(!"Unsupported vertex format for buffer texture");
581  return GPU_DEPTH_COMPONENT24;
582 }
583 
584 } // namespace gpu
585 } // namespace blender
#define BLI_assert(a)
Definition: BLI_assert.h:58
MINLINE int max_ii(int a, int b)
unsigned int uint
Definition: BLI_sys_types.h:83
#define ENUM_OPERATORS(_type, _max)
#define ELEM(...)
eGPUFrameBufferBits
@ GPU_DEPTH_BIT
@ GPU_STENCIL_BIT
@ GPU_COLOR_BIT
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
eGPUSamplerState
Definition: GPU_texture.h:40
@ GPU_SAMPLER_DEFAULT
Definition: GPU_texture.h:41
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
eGPUDataFormat
Definition: GPU_texture.h:171
@ GPU_DATA_UINT_24_8
Definition: GPU_texture.h:176
@ GPU_DATA_INT
Definition: GPU_texture.h:173
@ GPU_DATA_10_11_11_REV
Definition: GPU_texture.h:177
@ GPU_DATA_UBYTE
Definition: GPU_texture.h:175
@ GPU_DATA_UINT
Definition: GPU_texture.h:174
@ GPU_DATA_2_10_10_10_REV
Definition: GPU_texture.h:178
@ GPU_DATA_FLOAT
Definition: GPU_texture.h:172
eGPUTextureFormat
Definition: GPU_texture.h:84
@ GPU_R16UI
Definition: GPU_texture.h:112
@ GPU_RG16F
Definition: GPU_texture.h:104
@ GPU_DEPTH32F_STENCIL8
Definition: GPU_texture.h:120
@ GPU_R32F
Definition: GPU_texture.h:111
@ GPU_R16I
Definition: GPU_texture.h:113
@ GPU_SRGB8_A8
Definition: GPU_texture.h:122
@ GPU_DEPTH24_STENCIL8
Definition: GPU_texture.h:121
@ GPU_RGB10_A2
Definition: GPU_texture.h:118
@ GPU_R32I
Definition: GPU_texture.h:110
@ GPU_RG8UI
Definition: GPU_texture.h:96
@ GPU_R16F
Definition: GPU_texture.h:114
@ GPU_SRGB8_A8_DXT5
Definition: GPU_texture.h:152
@ GPU_RG8I
Definition: GPU_texture.h:97
@ GPU_RG16I
Definition: GPU_texture.h:103
@ GPU_RG32UI
Definition: GPU_texture.h:99
@ GPU_RGBA32F
Definition: GPU_texture.h:91
@ GPU_RGBA16F
Definition: GPU_texture.h:94
@ GPU_RG8
Definition: GPU_texture.h:98
@ GPU_RG32I
Definition: GPU_texture.h:100
@ GPU_SRGB8_A8_DXT1
Definition: GPU_texture.h:150
@ GPU_RG16
Definition: GPU_texture.h:105
@ GPU_RGBA32UI
Definition: GPU_texture.h:89
@ GPU_R8I
Definition: GPU_texture.h:107
@ GPU_R16
Definition: GPU_texture.h:115
@ GPU_RG16UI
Definition: GPU_texture.h:102
@ GPU_RGBA8I
Definition: GPU_texture.h:87
@ GPU_RGBA8_DXT1
Definition: GPU_texture.h:153
@ GPU_RGBA8UI
Definition: GPU_texture.h:86
@ GPU_RGBA16UI
Definition: GPU_texture.h:92
@ GPU_RGBA16I
Definition: GPU_texture.h:93
@ GPU_R8UI
Definition: GPU_texture.h:106
@ GPU_RGBA16
Definition: GPU_texture.h:95
@ GPU_SRGB8_A8_DXT3
Definition: GPU_texture.h:151
@ GPU_RGBA8_DXT3
Definition: GPU_texture.h:154
@ GPU_RG32F
Definition: GPU_texture.h:101
@ GPU_R8
Definition: GPU_texture.h:108
@ GPU_DEPTH_COMPONENT24
Definition: GPU_texture.h:167
@ GPU_RGB16F
Definition: GPU_texture.h:128
@ GPU_R32UI
Definition: GPU_texture.h:109
@ GPU_RGBA32I
Definition: GPU_texture.h:90
@ GPU_RGBA8_DXT5
Definition: GPU_texture.h:155
@ GPU_DEPTH_COMPONENT32F
Definition: GPU_texture.h:166
@ GPU_DEPTH_COMPONENT16
Definition: GPU_texture.h:168
@ GPU_R11F_G11F_B10F
Definition: GPU_texture.h:119
@ GPU_RGBA8
Definition: GPU_texture.h:88
struct GPUVertBuf GPUVertBuf
@ GPU_FETCH_FLOAT
@ GPU_FETCH_INT_TO_FLOAT_UNIT
@ GPU_FETCH_INT
@ GPU_FETCH_INT_TO_FLOAT
@ GPU_COMP_U16
@ GPU_COMP_F32
@ GPU_COMP_I32
@ GPU_COMP_I8
@ GPU_COMP_U32
@ GPU_COMP_I16
@ GPU_COMP_U8
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
bool init_3D(int w, int h, int d, eGPUTextureFormat format)
Definition: gpu_texture.cc:93
eGPUTextureFormatFlag format_flag_get(void) const
virtual void mip_range_set(int min, int max)=0
bool init_1D(int w, int layers, eGPUTextureFormat format)
Definition: gpu_texture.cc:65
virtual bool init_internal(GPUVertBuf *vbo)=0
virtual bool init_internal(void)=0
void attach_to(FrameBuffer *fb, GPUAttachmentType type)
Definition: gpu_texture.cc:142
int mip_width_get(int mip) const
eGPUTextureFormat format_
int mip_depth_get(int mip) const
bool init_cubemap(int w, int layers, eGPUTextureFormat format)
Definition: gpu_texture.cc:107
eGPUTextureType type_get(void) const
eGPUTextureFormatFlag format_flag_
void update(eGPUDataFormat format, const void *data)
Definition: gpu_texture.cc:166
char name_[DEBUG_NAME_LEN]
FrameBuffer * fb_[GPU_TEX_MAX_FBO_ATTACHED]
bool init_2D(int w, int h, int layers, eGPUTextureFormat format)
Definition: gpu_texture.cc:79
virtual void swizzle_set(const char swizzle_mask[4])=0
bool init_buffer(GPUVertBuf *vbo, eGPUTextureFormat format)
Definition: gpu_texture.cc:121
GPUAttachmentType fb_attachment_[GPU_TEX_MAX_FBO_ATTACHED]
GPUAttachmentType attachment_type(int slot) const
virtual void generate_mipmap(void)=0
eGPUSamplerState sampler_state
int mip_height_get(int mip) const
eGPUTextureFormat format_get(void) const
virtual void clear(eGPUDataFormat format, const void *data)=0
int dimensions_count(void) const
virtual void * read(int mip, eGPUDataFormat format)=0
virtual void update_sub(int mip, int offset[3], int extent[3], eGPUDataFormat format, const void *data)=0
void mip_size_get(int mip, int r_size[3]) const
virtual void copy_to(Texture *tex)=0
virtual uint gl_bindcode_get(void) const =0
Texture(const char *name)
Definition: gpu_texture.cc:42
void detach_from(FrameBuffer *fb)
Definition: gpu_texture.cc:154
@ GPU_FB_DEPTH_STENCIL_ATTACHMENT
@ GPU_FB_COLOR_ATTACHMENT0
@ GPU_FB_DEPTH_ATTACHMENT
#define DEBUG_NAME_LEN
#define GPU_TEX_MAX_FBO_ATTACHED
BLI_INLINE float fb(float length, float L)
format
Definition: logImageCore.h:47
bool validate_data_format(eGPUTextureFormat tex_format, eGPUDataFormat data_format)
size_t to_block_size(eGPUTextureFormat data_type)
static GPUContext * wrap(Context *ctx)
static Context * unwrap(GPUContext *ctx)
eGPUFrameBufferBits to_framebuffer_bits(eGPUTextureFormat tex_format)
eGPUDataFormat to_data_format(eGPUTextureFormat tex_format)
static eGPUTextureFormat to_texture_format(const GPUVertFormat *format)
eGPUTextureFormatFlag to_format_flag(eGPUTextureFormat format)
static size_t to_bytesize(GPUIndexBufType type)
int to_component_len(eGPUTextureFormat format)
#define min(a, b)
Definition: sort.c:51
float max