From: Mikko Rasa Date: Fri, 29 Dec 2023 08:21:21 +0000 (+0200) Subject: Generate storage offsets for default block uniforms internally X-Git-Url: https://git.tdb.fi/?a=commitdiff_plain;h=15a53289882c39b9490d75e9f3ed970afc0bf9cd;p=libs%2Fgl.git Generate storage offsets for default block uniforms internally Intel drivers treat locations as abstract identifiers, so a 4×4 matrix only consumes a single location. --- diff --git a/source/backends/opengl/pipelinestate_backend.cpp b/source/backends/opengl/pipelinestate_backend.cpp index 51be6151..90cbc994 100644 --- a/source/backends/opengl/pipelinestate_backend.cpp +++ b/source/backends/opengl/pipelinestate_backend.cpp @@ -133,7 +133,7 @@ void OpenGLPipelineState::apply() const { const char *data = static_cast(r.block->get_data_pointer()); for(const Program::UniformCall &call: self.shprog->uniform_calls) - call.func(call.location, call.size, data+call.location*16); + call.func(call.location, call.size, data+call.offset); } } else if(r.type==PipelineState::STORAGE_BLOCK) diff --git a/source/backends/opengl/program_backend.cpp b/source/backends/opengl/program_backend.cpp index 994373f3..ecf6de07 100644 --- a/source/backends/opengl/program_backend.cpp +++ b/source/backends/opengl/program_backend.cpp @@ -361,11 +361,13 @@ void OpenGLProgram::query_uniforms() ReflectData::BlockInfo &default_block = rd.blocks.emplace_back(); + size_t offset = 0; for(ReflectData::UniformInfo &u: rd.uniforms) if(!u.block) { u.location = glGetUniformLocation(id, u.name.c_str()); u.block = &default_block; + u.offset = offset; u.array_stride = get_type_size(u.type); if(is_matrix(u.type)) u.matrix_stride = get_type_size(get_matrix_column_type(u.type)); @@ -373,8 +375,11 @@ void OpenGLProgram::query_uniforms() if(is_image(u.type) && u.location>=0) glGetUniformiv(id, u.location, &u.binding); + + offset += u.array_size*get_type_size(u.type); } + default_block.data_size = offset; default_block.sort_uniforms(); default_block.update_layout_hash(); } @@ -558,14 +563,8 @@ void OpenGLProgram::finalize_uniforms() func = &uniform_matrix_wrapper; if(func) - uniform_calls.emplace_back(u->location, u->array_size, func); + uniform_calls.emplace_back(u->location, u->array_size, u->offset, func); } - - if(i->data_size<=0) - { - const ReflectData::UniformInfo &last = *i->uniforms.back(); - i->data_size = last.location*16+last.array_size*get_type_size(last.type); - } } } diff --git a/source/backends/opengl/program_backend.h b/source/backends/opengl/program_backend.h index 1b383f82..52f30524 100644 --- a/source/backends/opengl/program_backend.h +++ b/source/backends/opengl/program_backend.h @@ -36,9 +36,10 @@ protected: unsigned location; unsigned size; + unsigned offset; FuncPtr func; - UniformCall(unsigned l, unsigned s, FuncPtr f): location(l), size(s), func(f) { } + UniformCall(unsigned l, unsigned s, unsigned o, FuncPtr f): location(l), size(s), offset(o), func(f) { } }; unsigned id = 0; diff --git a/source/core/reflectdata.h b/source/core/reflectdata.h index 4b0cbd2c..1fc60d28 100644 --- a/source/core/reflectdata.h +++ b/source/core/reflectdata.h @@ -29,11 +29,8 @@ struct ReflectData { std::string name; const BlockInfo *block = nullptr; - union - { - int location = -1; - unsigned offset; - }; + int location = -1; + unsigned offset = 0; unsigned array_size = 0; unsigned array_stride = 0; unsigned matrix_stride = 0; diff --git a/source/core/uniformblock.cpp b/source/core/uniformblock.cpp index b4af61a2..3f0497d5 100644 --- a/source/core/uniformblock.cpp +++ b/source/core/uniformblock.cpp @@ -21,40 +21,30 @@ void UniformBlock::store(const ReflectData::UniformInfo &info, size_t array_size { array_size = min(array_size, max(info.array_size, 1U)); - size_t store_offset; - bool packed; - if(info.block->bind_point==ReflectData::DEFAULT_BLOCK) + bool packed = true; + if(info.block->bind_point!=ReflectData::DEFAULT_BLOCK) { - if(info.location<0) - return; - - store_offset = info.location*16; - packed = true; - } - else - { - store_offset = info.offset; if(array_size!=1 && info.array_stride!=get_type_size(info.type)) packed = false; else if(is_matrix(info.type)) packed = (info.matrix_stride==get_type_size(get_matrix_column_type(info.type))); - else - packed = true; } + else if(info.location<0) + return; - char *store_ptr = data.data()+store_offset; + char *store_ptr = data.data()+info.offset; const char *value_ptr = static_cast(value); if(packed) { size_t value_size = array_size*get_type_size(info.type); - check_store_range(store_offset, value_size); + check_store_range(info.offset, value_size); copy(value_ptr, value_ptr+value_size, store_ptr); } else if(is_matrix(info.type)) { unsigned col_size = get_type_size(get_matrix_column_type(info.type)); unsigned cols = get_type_size(info.type)/col_size; - check_store_range(store_offset, (array_size-1)*info.array_stride+(cols-1)*info.matrix_stride+col_size); + check_store_range(info.offset, (array_size-1)*info.array_stride+(cols-1)*info.matrix_stride+col_size); for(unsigned i=0; i