diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index 474f8e2934..8cb83e5a03 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -1145,15 +1145,16 @@ extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg) { * * This is mainly useful for debugging. It is a very slow call because it * introduces a pipeline stall both of Panda's pipeline and the graphics - * pipeline. + * pipeline. This is even when only a small amount of data is downloaded. * * The return value is empty if some kind of error occurred. */ vector_uchar GraphicsEngine:: -extract_shader_buffer_data(ShaderBuffer *buffer, GraphicsStateGuardian *gsg) { +extract_shader_buffer_data(ShaderBuffer *buffer, GraphicsStateGuardian *gsg, + size_t start, size_t size) { return run_on_draw_thread([=] () { vector_uchar data; - if (!gsg->extract_shader_buffer_data(buffer, data)) { + if (!gsg->extract_shader_buffer_data(buffer, data, start, size)) { data.clear(); } return data; diff --git a/panda/src/display/graphicsEngine.h b/panda/src/display/graphicsEngine.h index 88874f8e50..bd19d8d265 100644 --- a/panda/src/display/graphicsEngine.h +++ b/panda/src/display/graphicsEngine.h @@ -115,7 +115,8 @@ PUBLISHED: BLOCKING void flip_frame(); bool extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg); - vector_uchar extract_shader_buffer_data(ShaderBuffer *buffer, GraphicsStateGuardian *gsg); + vector_uchar extract_shader_buffer_data(ShaderBuffer *buffer, GraphicsStateGuardian *gsg, + size_t start = 0, size_t size = (size_t)-1); void dispatch_compute(const LVecBase3i &work_groups, const RenderState *state, GraphicsStateGuardian *gsg); diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 16518d79b4..19fe696d04 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -774,7 +774,8 @@ release_shader_buffers(const pvector &contexts) { * current contents synchronously. */ bool GraphicsStateGuardian:: -extract_shader_buffer_data(ShaderBuffer *buffer, vector_uchar &data) { +extract_shader_buffer_data(ShaderBuffer *buffer, vector_uchar &data, + size_t start, size_t size) { return false; } diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 9cb390f88c..8e9775b25d 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -326,7 +326,8 @@ public: virtual BufferContext *prepare_shader_buffer(ShaderBuffer *data); virtual void release_shader_buffer(BufferContext *ibc); virtual void release_shader_buffers(const pvector &contexts); - virtual bool extract_shader_buffer_data(ShaderBuffer *buffer, vector_uchar &data); + virtual bool extract_shader_buffer_data(ShaderBuffer *buffer, vector_uchar &data, + size_t start = 0, size_t size = (size_t)-1); virtual void begin_occlusion_query(); virtual PT(OcclusionQueryContext) end_occlusion_query(); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 034b5e5434..abf6f4cd0a 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -7766,14 +7766,21 @@ release_shader_buffers(const pvector &contexts) { * current contents synchronously. */ bool CLP(GraphicsStateGuardian):: -extract_shader_buffer_data(ShaderBuffer *buffer, vector_uchar &data) { +extract_shader_buffer_data(ShaderBuffer *buffer, vector_uchar &data, + size_t start, size_t size) { BufferContext *bc = buffer->prepare_now(get_prepared_objects(), this); if (bc == nullptr || !bc->is_of_type(CLP(BufferContext)::get_class_type())) { return false; } CLP(BufferContext) *gbc = DCAST(CLP(BufferContext), bc); - data.resize(buffer->get_data_size_bytes()); + size_t total_size = buffer->get_data_size_bytes(); + if (start >= total_size) { + data.clear(); + return true; + } + + data.resize(std::min(total_size - start, size)); if (_glMemoryBarrier != nullptr) { _glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); @@ -7781,7 +7788,7 @@ extract_shader_buffer_data(ShaderBuffer *buffer, vector_uchar &data) { _glBindBuffer(GL_SHADER_STORAGE_BUFFER, gbc->_index); - _glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, data.size(), &data[0]); + _glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, start, data.size(), &data[0]); _glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); _current_sbuffer_index = 0; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index a489599672..a037ba27df 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -399,7 +399,8 @@ public: CLP(BufferContext) *apply_shader_buffer(GLuint base, ShaderBuffer *buffer); virtual void release_shader_buffer(BufferContext *bc); virtual void release_shader_buffers(const pvector &contexts); - virtual bool extract_shader_buffer_data(ShaderBuffer *buffer, vector_uchar &data); + virtual bool extract_shader_buffer_data(ShaderBuffer *buffer, vector_uchar &data, + size_t start, size_t size); #endif #ifndef OPENGLES diff --git a/tests/display/test_glsl_shader.py b/tests/display/test_glsl_shader.py index d6dd9ff5a5..3e0a3bc7be 100644 --- a/tests/display/test_glsl_shader.py +++ b/tests/display/test_glsl_shader.py @@ -301,7 +301,7 @@ def test_glsl_uimage(gsg): def test_glsl_ssbo(gsg): from struct import pack, unpack num1 = pack('