Use BufferSubData instead of MapBufferRange in HTML5 platform
WebGL does not support MapBufferRange or UnmapBuffer. Also used in non-ES platforms where an extra-copy is avoided.
This commit is contained in:
parent
0a80ceaf02
commit
92e7c8daf0
|
@ -1428,7 +1428,16 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
|
|||
if (particles->draw_order == VS::PARTICLES_DRAW_ORDER_VIEW_DEPTH && particles->particle_valid_histories[1]) {
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffer_histories[1]); //modify the buffer, this was used 2 frames ago so it should be good enough for flushing
|
||||
RasterizerGLES3Particle *particle_array = (RasterizerGLES3Particle *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 24 * sizeof(float), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
|
||||
RasterizerGLES3Particle *particle_array;
|
||||
#ifndef __EMSCRIPTEN__
|
||||
particle_array = static_cast<RasterizerGLES3Particle *>(glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 24 * sizeof(float), GL_MAP_READ_BIT | GL_MAP_WRITE_BIT));
|
||||
#else
|
||||
PoolVector<RasterizerGLES3Particle> particle_vector;
|
||||
particle_vector.resize(particles->amount);
|
||||
PoolVector<RasterizerGLES3Particle>::Write w = particle_vector.write();
|
||||
particle_array = w.ptr();
|
||||
glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(RasterizerGLES3Particle), particle_array);
|
||||
#endif
|
||||
|
||||
SortArray<RasterizerGLES3Particle, RasterizerGLES3ParticleSort> sorter;
|
||||
|
||||
|
@ -1440,7 +1449,17 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
|
|||
|
||||
sorter.sort(particle_array, particles->amount);
|
||||
|
||||
#ifndef __EMSCRIPTEN__
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
#else
|
||||
w = PoolVector<RasterizerGLES3Particle>::Write();
|
||||
particle_array = NULL;
|
||||
{
|
||||
PoolVector<RasterizerGLES3Particle>::Read r = particle_vector.read();
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(RasterizerGLES3Particle), r.ptr());
|
||||
}
|
||||
particle_vector = PoolVector<RasterizerGLES3Particle>();
|
||||
#endif
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) {
|
||||
glBindVertexArray(s->instancing_array_wireframe_id); // use the wireframe instancing array ID
|
||||
|
|
|
@ -101,6 +101,28 @@
|
|||
#define _EXT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
|
||||
#define _EXT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten/emscripten.h>
|
||||
|
||||
void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data) {
|
||||
|
||||
/* clang-format off */
|
||||
EM_ASM({
|
||||
GLctx.getBufferSubData($0, $1, HEAPU8, $2, $3);
|
||||
}, target, offset, data, size);
|
||||
/* clang-format on */
|
||||
}
|
||||
|
||||
void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) {
|
||||
|
||||
/* clang-format off */
|
||||
EM_ASM({
|
||||
GLctx.bufferSubData($0, $1, HEAPU8, $2, $3);
|
||||
}, target, offset, data, size);
|
||||
/* clang-format on */
|
||||
}
|
||||
#endif
|
||||
|
||||
void glTexStorage2DCustom(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type) {
|
||||
|
||||
#ifdef GLES_OVER_GL
|
||||
|
@ -3494,21 +3516,26 @@ PoolVector<uint8_t> RasterizerStorageGLES3::mesh_surface_get_array(RID p_mesh, i
|
|||
|
||||
Surface *surface = mesh->surfaces[p_surface];
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
|
||||
void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, surface->array_byte_size, GL_MAP_READ_BIT);
|
||||
|
||||
ERR_FAIL_COND_V(!data, PoolVector<uint8_t>());
|
||||
|
||||
PoolVector<uint8_t> ret;
|
||||
ret.resize(surface->array_byte_size);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
|
||||
|
||||
#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
|
||||
{
|
||||
PoolVector<uint8_t>::Write w = ret.write();
|
||||
glGetBufferSubData(GL_ARRAY_BUFFER, 0, surface->array_byte_size, w.ptr());
|
||||
}
|
||||
#else
|
||||
void *data = glMapBufferRange(GL_ARRAY_BUFFER, 0, surface->array_byte_size, GL_MAP_READ_BIT);
|
||||
ERR_FAIL_NULL_V(data, PoolVector<uint8_t>());
|
||||
{
|
||||
|
||||
PoolVector<uint8_t>::Write w = ret.write();
|
||||
copymem(w.ptr(), data, surface->array_byte_size);
|
||||
}
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -3521,22 +3548,26 @@ PoolVector<uint8_t> RasterizerStorageGLES3::mesh_surface_get_index_array(RID p_m
|
|||
|
||||
ERR_FAIL_COND_V(surface->index_array_len == 0, PoolVector<uint8_t>());
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
|
||||
void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, GL_MAP_READ_BIT);
|
||||
|
||||
ERR_FAIL_COND_V(!data, PoolVector<uint8_t>());
|
||||
|
||||
PoolVector<uint8_t> ret;
|
||||
ret.resize(surface->index_array_byte_size);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
|
||||
|
||||
#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
|
||||
{
|
||||
PoolVector<uint8_t>::Write w = ret.write();
|
||||
glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, w.ptr());
|
||||
}
|
||||
#else
|
||||
void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, surface->index_array_byte_size, GL_MAP_READ_BIT);
|
||||
ERR_FAIL_NULL_V(data, PoolVector<uint8_t>());
|
||||
{
|
||||
|
||||
PoolVector<uint8_t>::Write w = ret.write();
|
||||
copymem(w.ptr(), data, surface->index_array_byte_size);
|
||||
}
|
||||
|
||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -3577,23 +3608,26 @@ Vector<PoolVector<uint8_t> > RasterizerStorageGLES3::mesh_surface_get_blend_shap
|
|||
|
||||
for (int i = 0; i < mesh->surfaces[p_surface]->blend_shapes.size(); i++) {
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->surfaces[p_surface]->blend_shapes[i].vertex_id);
|
||||
void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, GL_MAP_READ_BIT);
|
||||
|
||||
ERR_FAIL_COND_V(!data, Vector<PoolVector<uint8_t> >());
|
||||
|
||||
PoolVector<uint8_t> ret;
|
||||
ret.resize(mesh->surfaces[p_surface]->array_byte_size);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->surfaces[p_surface]->blend_shapes[i].vertex_id);
|
||||
|
||||
#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
|
||||
{
|
||||
PoolVector<uint8_t>::Write w = ret.write();
|
||||
glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, w.ptr());
|
||||
}
|
||||
#else
|
||||
void *data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->surfaces[p_surface]->array_byte_size, GL_MAP_READ_BIT);
|
||||
ERR_FAIL_COND_V(!data, Vector<PoolVector<uint8_t> >());
|
||||
{
|
||||
|
||||
PoolVector<uint8_t>::Write w = ret.write();
|
||||
copymem(w.ptr(), data, mesh->surfaces[p_surface]->array_byte_size);
|
||||
}
|
||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||
#endif
|
||||
|
||||
bsarr.push_back(ret);
|
||||
|
||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||
}
|
||||
|
||||
return bsarr;
|
||||
|
@ -6001,9 +6035,21 @@ AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
|
|||
const Particles *particles = particles_owner.getornull(p_particles);
|
||||
ERR_FAIL_COND_V(!particles, AABB());
|
||||
|
||||
const float *data;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]);
|
||||
|
||||
float *data = (float *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, GL_MAP_READ_BIT);
|
||||
#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
|
||||
PoolVector<uint8_t> vector;
|
||||
vector.resize(particles->amount * 16 * 6);
|
||||
{
|
||||
PoolVector<uint8_t>::Write w = vector.write();
|
||||
glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, w.ptr());
|
||||
}
|
||||
PoolVector<uint8_t>::Read r = vector.read();
|
||||
data = reinterpret_cast<const float *>(r.ptr());
|
||||
#else
|
||||
data = (float *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, GL_MAP_READ_BIT);
|
||||
#endif
|
||||
AABB aabb;
|
||||
|
||||
Transform inv = particles->emission_transform.affine_inverse();
|
||||
|
@ -6020,7 +6066,13 @@ AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
|
|||
aabb.expand_to(pos);
|
||||
}
|
||||
|
||||
#if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__)
|
||||
r = PoolVector<uint8_t>::Read();
|
||||
vector = PoolVector<uint8_t>();
|
||||
#else
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
float longest_axis = 0;
|
||||
|
|
|
@ -43,6 +43,12 @@
|
|||
#include "shaders/cubemap_filter.glsl.gen.h"
|
||||
#include "shaders/particles.glsl.gen.h"
|
||||
|
||||
// WebGL 2.0 has no MapBufferRange/UnmapBuffer, but offers a non-ES style BufferSubData API instead.
|
||||
#ifdef __EMSCRIPTEN__
|
||||
void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);
|
||||
void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
|
||||
#endif
|
||||
|
||||
class RasterizerCanvasGLES3;
|
||||
class RasterizerSceneGLES3;
|
||||
|
||||
|
|
Loading…
Reference in New Issue