display: Support extracting only subset of SSBO

This commit is contained in:
rdb 2025-12-31 20:10:19 +01:00
parent b806035c40
commit 86b1304588
7 changed files with 29 additions and 12 deletions

View File

@ -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;

View File

@ -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);

View File

@ -774,7 +774,8 @@ release_shader_buffers(const pvector<BufferContext *> &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;
}

View File

@ -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<BufferContext *> &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();

View File

@ -7766,14 +7766,21 @@ release_shader_buffers(const pvector<BufferContext *> &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;

View File

@ -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<BufferContext *> &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

View File

@ -301,7 +301,7 @@ def test_glsl_uimage(gsg):
def test_glsl_ssbo(gsg):
from struct import pack, unpack
num1 = pack('<i', 1234567)
num2 = pack('<i', -1234567)
num2 = pack('<ii', -1234567, 867451)
buffer1 = core.ShaderBuffer("buffer1", num1, core.GeomEnums.UH_static)
buffer2 = core.ShaderBuffer("buffer2", num2, core.GeomEnums.UH_static)
@ -311,11 +311,13 @@ def test_glsl_ssbo(gsg):
};
layout(std430, binding=1) buffer buffer2 {
int value2;
int value3;
};
"""
code = """
assert(value1 == 1234567);
assert(value2 == -1234567);
assert(value3 == 867451);
value1 = 98765;
value2 = 5343525;
"""
@ -328,7 +330,10 @@ def test_glsl_ssbo(gsg):
assert unpack('<i', data1[:4]) == (98765, )
data2 = gsg.get_engine().extract_shader_buffer_data(buffer2, gsg)
assert unpack('<i', data2[:4]) == (5343525, )
assert unpack('<ii', data2[:8]) == (5343525, 867451)
data3 = gsg.get_engine().extract_shader_buffer_data(buffer2, gsg, 4, 8)
assert unpack('<i', data3[:4]) == (867451, )
def test_glsl_int(gsg):