Blender V5.0
gl_vertex_array.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2016 by Mike Erwin. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
11
12#include "gl_batch.hh"
13#include "gl_context.hh"
14#include "gl_index_buffer.hh"
15#include "gl_storage_buffer.hh"
16#include "gl_vertex_buffer.hh"
17
18#include "gl_vertex_array.hh"
19
20namespace blender::gpu {
21
22/* -------------------------------------------------------------------- */
25
27static uint16_t vbo_bind(const ShaderInterface *interface,
28 const GPUVertFormat *format,
29 uint v_first,
30 uint v_len,
31 const bool use_instancing)
32{
33 uint16_t enabled_attrib = 0;
34 const uint attr_len = format->attr_len;
35 uint stride = format->stride;
36 uint offset = 0;
37 GLuint divisor = (use_instancing) ? 1 : 0;
38
39 for (uint a_idx = 0; a_idx < attr_len; a_idx++) {
40 const GPUVertAttr *a = &format->attrs[a_idx];
41
42 if (format->deinterleaved) {
43 offset += ((a_idx == 0) ? 0 : format->attrs[a_idx - 1].type.size()) * v_len;
44 stride = a->type.size();
45 }
46 else {
47 offset = a->offset;
48 }
49
50 /* This is in fact an offset in memory. */
51 const GLvoid *pointer = (const GLubyte *)intptr_t(offset + v_first * stride);
52 const GLenum type = to_gl(a->type.comp_type());
53
54 for (uint n_idx = 0; n_idx < a->name_len; n_idx++) {
55 const char *name = GPU_vertformat_attr_name_get(format, a, n_idx);
56 const ShaderInput *input = interface->attr_get(name);
57
58 if (input == nullptr || input->location == -1) {
59 continue;
60 }
61
62 enabled_attrib |= (1 << input->location);
63
64 glEnableVertexAttribArray(input->location);
65 glVertexAttribDivisor(input->location, divisor);
66
67 switch (a->type.fetch_mode()) {
68 case GPU_FETCH_FLOAT:
70 glVertexAttribPointer(
71 input->location, a->type.comp_len(), type, GL_TRUE, stride, pointer);
72 break;
73 case GPU_FETCH_INT:
74 glVertexAttribIPointer(input->location, a->type.comp_len(), type, stride, pointer);
75 break;
76 }
77 }
78 }
79 return enabled_attrib;
80}
81
82void GLVertArray::update_bindings(const GLuint vao,
83 const Batch *batch_, /* Should be GLBatch. */
85{
86 const GLBatch *batch = static_cast<const GLBatch *>(batch_);
87 uint16_t attr_mask = interface->enabled_attr_mask_;
88
89 glBindVertexArray(vao);
90
91 /* Reverse order so first VBO'S have more prevalence (in term of attribute override). */
92 for (int v = GPU_BATCH_VBO_MAX_LEN - 1; v > -1; v--) {
93 GLVertBuf *vbo = batch->verts_(v);
94 if (vbo) {
95 vbo->bind();
96 attr_mask &= ~vbo_bind(interface, &vbo->format, 0, vbo->vertex_len, false);
97 }
98 }
99
100 if (attr_mask != 0) {
101 for (uint16_t mask = 1, a = 0; a < 16; a++, mask <<= 1) {
102 if (attr_mask & mask) {
103 GLContext *ctx = GLContext::get();
104 /* This replaces glVertexAttrib4f(a, 0.0f, 0.0f, 0.0f, 1.0f); with a more modern style.
105 * Fix issues for some drivers (see #75069). */
106 glBindVertexBuffer(a, ctx->default_attr_vbo_, intptr_t(0), intptr_t(0));
107 glEnableVertexAttribArray(a);
108 glVertexAttribFormat(a, 4, GL_FLOAT, GL_FALSE, 0);
109 glVertexAttribBinding(a, a);
110 }
111 }
112 }
113
114 if (batch->elem) {
115 /* Binds the index buffer. This state is also saved in the VAO. */
116 static_cast<GLIndexBuf *>(batch->elem)->bind();
117 }
118}
119
120void GLVertArray::update_bindings(const GLuint vao,
121 const uint v_first,
122 const GPUVertFormat *format,
124{
125 glBindVertexArray(vao);
126
127 vbo_bind(interface, format, v_first, 0, false);
128}
129
131
132} // namespace blender::gpu
unsigned int uint
static constexpr int GPU_BATCH_VBO_MAX_LEN
Definition GPU_batch.hh:33
BLI_INLINE const char * GPU_vertformat_attr_name_get(const GPUVertFormat *format, const GPUVertAttr *attr, uint n_idx)
@ GPU_FETCH_FLOAT
@ GPU_FETCH_INT_TO_FLOAT_UNIT
@ GPU_FETCH_INT
ATTR_WARN_UNUSED_RESULT const BMVert * v
static GLContext * get()
struct @021025263243242147216143265077100330027142264337::@225245033123204053237120173316075113304004012000 batch
#define input
format
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void update_bindings(const GLuint vao, const Batch *batch, const ShaderInterface *interface)
static uint16_t vbo_bind(const ShaderInterface *interface, const GPUVertFormat *format, uint v_first, uint v_len, const bool use_instancing)
static GLenum to_gl(const GPUAttachmentType type)
const char * name
GPUVertFetchMode fetch_mode() const
GPUVertCompType comp_type() const
struct GPUVertAttr::Type type