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: 4099d6641a6d0652e2165bc0080fcf49b25e6500 (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
/* SPDX-License-Identifier: GPL-2.0-or-later
 * Copyright 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;
  /** True if buffer only contains restart indices. */
  bool is_empty_ = 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,
            uint min_index,
            uint max_index,
            GPUPrimType prim_type,
            bool uses_restart_indices);
  void init_subrange(IndexBuf *elem_src, uint start, uint length);
  void init_build_on_device(uint index_len);

  /* Returns render index count (not precise). */
  uint32_t index_len_get() const
  {
    /* Return 0 to bypass drawing for index buffers full of restart indices.
     * They can lead to graphical glitches on some systems. (See T96892) */
    return is_empty_ ? 0 : index_len_;
  }
  uint32_t index_start_get() const
  {
    return index_start_;
  }
  uint32_t index_base_get() const
  {
    return index_base_;
  }
  /* Return size in byte of the drawable data buffer range. Actual buffer size might be bigger. */
  size_t size_get() const
  {
    return index_len_ * to_bytesize(index_type_);
  };

  bool is_init() const
  {
    return is_init_;
  };

  virtual void upload_data() = 0;

  virtual void bind_as_ssbo(uint binding) = 0;

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

  virtual void update_sub(uint start, uint len, const void *data) = 0;

 private:
  inline void squeeze_indices_short(uint min_idx,
                                    uint max_idx,
                                    GPUPrimType prim_type,
                                    bool clamp_indices_in_range);
  inline uint index_range(uint *r_min, uint *r_max);
  virtual void strip_restart_indices() = 0;
};

/* 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