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

gpu_index_buffer_private.hh « intern « gpu « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 358258604bfe9dcc4af936d1390a773d09ffb538 (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
/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * The Original Code is Copyright (C) 2020 Blender Foundation.
 * All rights reserved.
 */

/** \file
 * \ingroup gpu
 */

#pragma once

#include "BLI_assert.h"

#include "GPU_index_buffer.h"

#define GPU_TRACK_INDEX_RANGE 1

namespace blender::gpu {

typedef enum {
  GPU_INDEX_U16,
  GPU_INDEX_U32,
} GPUIndexBufType;

static inline size_t to_bytesize(GPUIndexBufType type)
{
  return (type == GPU_INDEX_U32) ? sizeof(uint32_t) : sizeof(uint16_t);
}

/**
 * Base class which is then specialized for each implementation (GL, VK, ...).
 *
 * \note #IndexBuf does not hold any #GPUPrimType.
 * This is because it can be interpreted differently by multiple batches.
 */
class IndexBuf {
 protected:
  /** Type of indices used inside this buffer. */
  GPUIndexBufType index_type_ = GPU_INDEX_U32;
  /** Offset in this buffer to the first index to render. Is 0 if not a subrange.  */
  uint32_t index_start_ = 0;
  /** Number of indices to render. */
  uint32_t index_len_ = 0;
  /** Base index: Added to all indices after fetching. Allows index compression. */
  uint32_t index_base_ = 0;
  /** Bookkeeping. */
  bool is_init_ = false;
  /** Is this object only a reference to a subrange of another IndexBuf. */
  bool is_subrange_ = false;

  union {
    /** Mapped buffer data. non-NULL indicates not yet sent to VRAM. */
    void *data_ = nullptr;
    /** If is_subrange is true, this is the source index buffer. */
    IndexBuf *src_;
  };

 public:
  IndexBuf(){};
  virtual ~IndexBuf();

  void init(uint indices_len, uint32_t *indices);
  void init_subrange(IndexBuf *elem_src, uint start, uint length);
  void init_build_on_device(uint index_len);

  uint32_t index_len_get(void) const
  {
    return index_len_;
  }
  /* Return size in byte of the drawable data buffer range. Actual buffer size might be bigger. */
  size_t size_get(void) const
  {
    return index_len_ * to_bytesize(index_type_);
  };

  bool is_init(void) const
  {
    return is_init_;
  };

  virtual void bind_as_ssbo(uint binding) = 0;

  virtual const uint32_t *read() const = 0;
  uint32_t *unmap(const uint32_t *mapped_memory) const;

 private:
  inline void squeeze_indices_short(uint min_idx, uint max_idx);
  inline uint index_range(uint *r_min, uint *r_max);
};

/* Syntactic sugar. */
static inline GPUIndexBuf *wrap(IndexBuf *indexbuf)
{
  return reinterpret_cast<GPUIndexBuf *>(indexbuf);
}
static inline IndexBuf *unwrap(GPUIndexBuf *indexbuf)
{
  return reinterpret_cast<IndexBuf *>(indexbuf);
}
static inline const IndexBuf *unwrap(const GPUIndexBuf *indexbuf)
{
  return reinterpret_cast<const IndexBuf *>(indexbuf);
}

static inline int indices_per_primitive(GPUPrimType prim_type)
{
  switch (prim_type) {
    case GPU_PRIM_POINTS:
      return 1;
    case GPU_PRIM_LINES:
      return 2;
    case GPU_PRIM_TRIS:
      return 3;
    case GPU_PRIM_LINES_ADJ:
      return 4;
    default:
      return -1;
  }
}

}  // namespace blender::gpu