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]) {
|
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
|
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;
|
SortArray<RasterizerGLES3Particle, RasterizerGLES3ParticleSort> sorter;
|
||||||
|
|
||||||
|
@ -1440,7 +1449,17 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
|
||||||
|
|
||||||
sorter.sort(particle_array, particles->amount);
|
sorter.sort(particle_array, particles->amount);
|
||||||
|
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
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
|
#ifdef DEBUG_ENABLED
|
||||||
if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) {
|
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
|
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_SIGNED_FLOAT 0x8E8E
|
||||||
#define _EXT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
|
#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) {
|
void glTexStorage2DCustom(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type) {
|
||||||
|
|
||||||
#ifdef GLES_OVER_GL
|
#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];
|
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;
|
PoolVector<uint8_t> ret;
|
||||||
ret.resize(surface->array_byte_size);
|
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();
|
PoolVector<uint8_t>::Write w = ret.write();
|
||||||
copymem(w.ptr(), data, surface->array_byte_size);
|
copymem(w.ptr(), data, surface->array_byte_size);
|
||||||
}
|
}
|
||||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
return ret;
|
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>());
|
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;
|
PoolVector<uint8_t> ret;
|
||||||
ret.resize(surface->index_array_byte_size);
|
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();
|
PoolVector<uint8_t>::Write w = ret.write();
|
||||||
copymem(w.ptr(), data, surface->index_array_byte_size);
|
copymem(w.ptr(), data, surface->index_array_byte_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
return ret;
|
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++) {
|
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;
|
PoolVector<uint8_t> ret;
|
||||||
ret.resize(mesh->surfaces[p_surface]->array_byte_size);
|
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();
|
PoolVector<uint8_t>::Write w = ret.write();
|
||||||
copymem(w.ptr(), data, mesh->surfaces[p_surface]->array_byte_size);
|
copymem(w.ptr(), data, mesh->surfaces[p_surface]->array_byte_size);
|
||||||
}
|
}
|
||||||
|
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
||||||
|
#endif
|
||||||
|
|
||||||
bsarr.push_back(ret);
|
bsarr.push_back(ret);
|
||||||
|
|
||||||
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return bsarr;
|
return bsarr;
|
||||||
|
@ -6001,9 +6035,21 @@ AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
|
||||||
const Particles *particles = particles_owner.getornull(p_particles);
|
const Particles *particles = particles_owner.getornull(p_particles);
|
||||||
ERR_FAIL_COND_V(!particles, AABB());
|
ERR_FAIL_COND_V(!particles, AABB());
|
||||||
|
|
||||||
|
const float *data;
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]);
|
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;
|
AABB aabb;
|
||||||
|
|
||||||
Transform inv = particles->emission_transform.affine_inverse();
|
Transform inv = particles->emission_transform.affine_inverse();
|
||||||
|
@ -6020,7 +6066,13 @@ AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
|
||||||
aabb.expand_to(pos);
|
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);
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
#endif
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
float longest_axis = 0;
|
float longest_axis = 0;
|
||||||
|
|
|
@ -43,6 +43,12 @@
|
||||||
#include "shaders/cubemap_filter.glsl.gen.h"
|
#include "shaders/cubemap_filter.glsl.gen.h"
|
||||||
#include "shaders/particles.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 RasterizerCanvasGLES3;
|
||||||
class RasterizerSceneGLES3;
|
class RasterizerSceneGLES3;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue