Reduce glBufferSubData calls in legacy renderer
This is part of effort to make more efficient use of the API for devices with poor drivers. This eliminates multiple calls to glBufferSubData per update.
This commit is contained in:
parent
c2290dbedd
commit
74c460fb67
@ -446,8 +446,21 @@ void RasterizerCanvasBaseGLES2::_draw_polygon(const int *p_indices, int p_index_
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
|
||||
|
||||
// precalculate the buffer size ahead of time instead of making multiple glBufferSubData calls
|
||||
uint32_t total_buffer_size = sizeof(Vector2) * p_vertex_count;
|
||||
if (!p_singlecolor && p_colors) {
|
||||
total_buffer_size += sizeof(Color) * p_vertex_count;
|
||||
}
|
||||
if (p_uvs) {
|
||||
total_buffer_size += sizeof(Vector2) * p_vertex_count;
|
||||
}
|
||||
if (p_weights && p_bones) {
|
||||
total_buffer_size += sizeof(float) * 4 * p_vertex_count; // weights
|
||||
total_buffer_size += sizeof(int) * 4 * p_vertex_count; // bones
|
||||
}
|
||||
|
||||
uint32_t buffer_ofs = 0;
|
||||
storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, sizeof(Vector2) * p_vertex_count, p_vertices);
|
||||
storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, total_buffer_size, p_vertices);
|
||||
|
||||
glEnableVertexAttribArray(VS::ARRAY_VERTEX);
|
||||
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL);
|
||||
@ -461,14 +474,12 @@ void RasterizerCanvasBaseGLES2::_draw_polygon(const int *p_indices, int p_index_
|
||||
glDisableVertexAttribArray(VS::ARRAY_COLOR);
|
||||
glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
|
||||
} else {
|
||||
glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors);
|
||||
glEnableVertexAttribArray(VS::ARRAY_COLOR);
|
||||
glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
|
||||
buffer_ofs += sizeof(Color) * p_vertex_count;
|
||||
}
|
||||
|
||||
if (p_uvs) {
|
||||
glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs);
|
||||
glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
|
||||
glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
|
||||
buffer_ofs += sizeof(Vector2) * p_vertex_count;
|
||||
@ -477,12 +488,10 @@ void RasterizerCanvasBaseGLES2::_draw_polygon(const int *p_indices, int p_index_
|
||||
}
|
||||
|
||||
if (p_weights && p_bones) {
|
||||
glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(float) * 4 * p_vertex_count, p_weights);
|
||||
glEnableVertexAttribArray(VS::ARRAY_WEIGHTS);
|
||||
glVertexAttribPointer(VS::ARRAY_WEIGHTS, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs));
|
||||
buffer_ofs += sizeof(float) * 4 * p_vertex_count;
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(int) * 4 * p_vertex_count, p_bones);
|
||||
glEnableVertexAttribArray(VS::ARRAY_BONES);
|
||||
glVertexAttribPointer(VS::ARRAY_BONES, 4, GL_UNSIGNED_INT, GL_FALSE, sizeof(int) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs));
|
||||
buffer_ofs += sizeof(int) * 4 * p_vertex_count;
|
||||
@ -516,8 +525,17 @@ void RasterizerCanvasBaseGLES2::_draw_generic(GLuint p_primitive, int p_vertex_c
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
|
||||
|
||||
// precalculate the buffer size ahead of time instead of making multiple glBufferSubData calls
|
||||
uint32_t total_buffer_size = sizeof(Vector2) * p_vertex_count;
|
||||
if (!p_singlecolor && p_colors) {
|
||||
total_buffer_size += sizeof(Color) * p_vertex_count;
|
||||
}
|
||||
if (p_uvs) {
|
||||
total_buffer_size += sizeof(Vector2) * p_vertex_count;
|
||||
}
|
||||
|
||||
uint32_t buffer_ofs = 0;
|
||||
storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, sizeof(Vector2) * p_vertex_count, p_vertices);
|
||||
storage->buffer_orphan_and_upload(data.polygon_buffer_size, 0, total_buffer_size, p_vertices);
|
||||
|
||||
glEnableVertexAttribArray(VS::ARRAY_VERTEX);
|
||||
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL);
|
||||
@ -531,14 +549,12 @@ void RasterizerCanvasBaseGLES2::_draw_generic(GLuint p_primitive, int p_vertex_c
|
||||
glDisableVertexAttribArray(VS::ARRAY_COLOR);
|
||||
glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
|
||||
} else {
|
||||
glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors);
|
||||
glEnableVertexAttribArray(VS::ARRAY_COLOR);
|
||||
glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
|
||||
buffer_ofs += sizeof(Color) * p_vertex_count;
|
||||
}
|
||||
|
||||
if (p_uvs) {
|
||||
glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs);
|
||||
glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
|
||||
glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
|
||||
} else {
|
||||
|
@ -3788,14 +3788,17 @@ void RasterizerStorageGLES2::_update_skeleton_transform_buffer(const PoolVector<
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, resources.skeleton_transform_buffer);
|
||||
|
||||
uint32_t buffer_size = p_size * sizeof(float);
|
||||
|
||||
if (p_size > resources.skeleton_transform_buffer_size) {
|
||||
// new requested buffer is bigger, so resizing the GPU buffer
|
||||
|
||||
resources.skeleton_transform_buffer_size = p_size;
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, p_size * sizeof(float), p_data.read().ptr(), GL_DYNAMIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, buffer_size, p_data.read().ptr(), GL_DYNAMIC_DRAW);
|
||||
} else {
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, p_size * sizeof(float), p_data.read().ptr());
|
||||
// this may not be best, it could be better to use glBufferData in both cases.
|
||||
buffer_orphan_and_upload(resources.skeleton_transform_buffer_size, 0, buffer_size, p_data.read().ptr());
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
@ -348,8 +348,21 @@ void RasterizerCanvasBaseGLES3::_draw_polygon(const int *p_indices, int p_index_
|
||||
glBindVertexArray(data.polygon_buffer_pointer_array);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
|
||||
|
||||
// precalculate the buffer size ahead of time instead of making multiple glBufferSubData calls
|
||||
uint32_t total_buffer_size = sizeof(Vector2) * p_vertex_count;
|
||||
if (!p_singlecolor && p_colors) {
|
||||
total_buffer_size += sizeof(Color) * p_vertex_count;
|
||||
}
|
||||
if (p_uvs) {
|
||||
total_buffer_size += sizeof(Vector2) * p_vertex_count;
|
||||
}
|
||||
if (p_weights && p_bones) {
|
||||
total_buffer_size += sizeof(int) * 4 * p_vertex_count; // bones
|
||||
total_buffer_size += sizeof(float) * 4 * p_vertex_count; // weights
|
||||
}
|
||||
|
||||
uint32_t buffer_ofs = 0;
|
||||
storage->buffer_orphan_and_upload(data.polygon_buffer_size, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_vertices);
|
||||
storage->buffer_orphan_and_upload(data.polygon_buffer_size, buffer_ofs, total_buffer_size, p_vertices);
|
||||
|
||||
glEnableVertexAttribArray(VS::ARRAY_VERTEX);
|
||||
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
|
||||
@ -368,7 +381,6 @@ void RasterizerCanvasBaseGLES3::_draw_polygon(const int *p_indices, int p_index_
|
||||
glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
|
||||
} else {
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors);
|
||||
glEnableVertexAttribArray(VS::ARRAY_COLOR);
|
||||
glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
|
||||
buffer_ofs += sizeof(Color) * p_vertex_count;
|
||||
@ -380,7 +392,6 @@ void RasterizerCanvasBaseGLES3::_draw_polygon(const int *p_indices, int p_index_
|
||||
|
||||
if (p_uvs) {
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs);
|
||||
glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
|
||||
glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
|
||||
buffer_ofs += sizeof(Vector2) * p_vertex_count;
|
||||
@ -395,13 +406,11 @@ void RasterizerCanvasBaseGLES3::_draw_polygon(const int *p_indices, int p_index_
|
||||
|
||||
if (p_bones && p_weights) {
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(int) * 4 * p_vertex_count, p_bones);
|
||||
glEnableVertexAttribArray(VS::ARRAY_BONES);
|
||||
//glVertexAttribPointer(VS::ARRAY_BONES, 4, GL_UNSIGNED_INT, false, sizeof(int) * 4, ((uint8_t *)0) + buffer_ofs);
|
||||
glVertexAttribIPointer(VS::ARRAY_BONES, 4, GL_UNSIGNED_INT, sizeof(int) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs));
|
||||
buffer_ofs += sizeof(int) * 4 * p_vertex_count;
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(float) * 4 * p_vertex_count, p_weights);
|
||||
glEnableVertexAttribArray(VS::ARRAY_WEIGHTS);
|
||||
glVertexAttribPointer(VS::ARRAY_WEIGHTS, 4, GL_FLOAT, false, sizeof(float) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs));
|
||||
buffer_ofs += sizeof(float) * 4 * p_vertex_count;
|
||||
@ -439,9 +448,18 @@ void RasterizerCanvasBaseGLES3::_draw_generic(GLuint p_primitive, int p_vertex_c
|
||||
glBindVertexArray(data.polygon_buffer_pointer_array);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
|
||||
|
||||
// precalculate the buffer size ahead of time instead of making multiple glBufferSubData calls
|
||||
uint32_t total_buffer_size = sizeof(Vector2) * p_vertex_count;
|
||||
if (!p_singlecolor && p_colors) {
|
||||
total_buffer_size += sizeof(Color) * p_vertex_count;
|
||||
}
|
||||
if (p_uvs) {
|
||||
total_buffer_size += sizeof(Vector2) * p_vertex_count;
|
||||
}
|
||||
|
||||
//vertex
|
||||
uint32_t buffer_ofs = 0;
|
||||
storage->buffer_orphan_and_upload(data.polygon_buffer_size, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_vertices);
|
||||
storage->buffer_orphan_and_upload(data.polygon_buffer_size, buffer_ofs, total_buffer_size, p_vertices);
|
||||
|
||||
glEnableVertexAttribArray(VS::ARRAY_VERTEX);
|
||||
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
|
||||
@ -457,7 +475,6 @@ void RasterizerCanvasBaseGLES3::_draw_generic(GLuint p_primitive, int p_vertex_c
|
||||
glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
|
||||
} else {
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors);
|
||||
glEnableVertexAttribArray(VS::ARRAY_COLOR);
|
||||
glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
|
||||
buffer_ofs += sizeof(Color) * p_vertex_count;
|
||||
@ -465,7 +482,6 @@ void RasterizerCanvasBaseGLES3::_draw_generic(GLuint p_primitive, int p_vertex_c
|
||||
|
||||
if (p_uvs) {
|
||||
|
||||
glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs);
|
||||
glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
|
||||
glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
|
||||
buffer_ofs += sizeof(Vector2) * p_vertex_count;
|
||||
|
@ -5085,7 +5085,8 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() {
|
||||
if (multimesh->size && multimesh->dirty_data) {
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, multimesh->data.size() * sizeof(float), multimesh->data.ptr());
|
||||
uint32_t buffer_size = multimesh->data.size() * sizeof(float);
|
||||
glBufferData(GL_ARRAY_BUFFER, buffer_size, multimesh->data.ptr(), GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user