diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2022-09-01 15:46:17 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2022-09-02 20:37:15 +0300 |
commit | e48a6fcc6397e5a964f2096d937ac189f07ce999 (patch) | |
tree | 37f98d5dab5c869b7248fc65a35edfc1b618b531 /source/blender/draw/intern/draw_manager.hh | |
parent | 356460f5cf659ef071daa1267ab368b733b4133e (diff) |
DRW-Next: Add uniform attributes (object attributes) support
This replaces the direct shader uniform layout declaration by a linear
search through a global buffer.
Each instance has an attribute offset inside the global buffer and an
attribute count.
This removes any padding and tighly pack all uniform attributes inside
a single buffer.
This would also remove the limit of 8 attribute but it is kept because of
compatibility with the old system that is still used by the old draw
manager.
Diffstat (limited to 'source/blender/draw/intern/draw_manager.hh')
-rw-r--r-- | source/blender/draw/intern/draw_manager.hh | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/source/blender/draw/intern/draw_manager.hh b/source/blender/draw/intern/draw_manager.hh index 5f110b8bb6b..867b376702c 100644 --- a/source/blender/draw/intern/draw_manager.hh +++ b/source/blender/draw/intern/draw_manager.hh @@ -13,7 +13,9 @@ * \note It is currently work in progress and should replace the old global draw manager. */ +#include "BLI_listbase_wrapper.hh" #include "BLI_sys_types.h" +#include "GPU_material.h" #include "draw_resource.hh" #include "draw_view.hh" @@ -41,6 +43,9 @@ class Manager { using ObjectMatricesBuf = StorageArrayBuffer<ObjectMatrices, 128>; using ObjectBoundsBuf = StorageArrayBuffer<ObjectBounds, 128>; using ObjectInfosBuf = StorageArrayBuffer<ObjectInfos, 128>; + using ObjectAttributeBuf = StorageArrayBuffer<ObjectAttribute, 128>; + /** TODO(fclem): Remove once we get rid of old EEVEE codebase. DRW_RESOURCE_CHUNK_LEN = 512 */ + using ObjectAttributeLegacyBuf = UniformArrayBuffer<float4, 8 * 512>; public: struct SubmitDebugOutput { @@ -67,14 +72,25 @@ class Manager { ObjectBoundsBuf bounds_buf; ObjectInfosBuf infos_buf; + /** + * Object Attributes are reference by indirection data inside ObjectInfos. + * This is because attribute list is arbitrary. + */ + ObjectAttributeBuf attributes_buf; + /** TODO(fclem): Remove once we get rid of old EEVEE codebase. Only here to satisfy bindings. */ + ObjectAttributeLegacyBuf attributes_buf_legacy; + /** List of textures coming from Image data-blocks. They need to be refcounted in order to avoid * beeing freed in another thread. */ Vector<GPUTexture *> acquired_textures; private: + /** Number of resource handle recorded. */ uint resource_len_ = 0; - Object *object = nullptr; + /** Number of object attribute recorded. */ + uint attribute_len_ = 0; + Object *object = nullptr; Object *object_active = nullptr; public: @@ -104,7 +120,7 @@ class Manager { * Populate additional per resource data on demand. */ void extract_object_attributes(ResourceHandle handle, - Object &object, + const ObjectRef &ref, Span<GPUMaterial *> materials); /** @@ -145,6 +161,7 @@ class Manager { void end_sync(); void debug_bind(); + void resource_bind(); }; inline ResourceHandle Manager::resource_handle(const ObjectRef ref) @@ -175,13 +192,34 @@ inline ResourceHandle Manager::resource_handle(const float4x4 &model_matrix, } inline void Manager::extract_object_attributes(ResourceHandle handle, - Object &object, + const ObjectRef &ref, Span<GPUMaterial *> materials) { - /* TODO */ - (void)handle; - (void)object; - (void)materials; + ObjectInfos &infos = infos_buf.get_or_resize(handle.resource_index()); + infos.object_attrs_offset = attribute_len_; + + /* Simple cache solution to avoid duplicates. */ + Vector<uint32_t, 4> hash_cache; + + for (const GPUMaterial *mat : materials) { + const GPUUniformAttrList *attr_list = GPU_material_uniform_attributes(mat); + if (attr_list == nullptr) { + continue; + } + + LISTBASE_FOREACH (const GPUUniformAttr *, attr, &attr_list->list) { + /** WATCH: Linear Search. Avoid duplicate attributes across materials. */ + if ((mat != materials.first()) && (hash_cache.first_index_of_try(attr->hash_code) != -1)) { + /* Attribute has already been added to the attribute buffer by another material. */ + continue; + } + hash_cache.append(attr->hash_code); + if (attributes_buf.get_or_resize(attribute_len_).sync(ref, *attr)) { + infos.object_attrs_len++; + attribute_len_++; + } + } + } } } // namespace blender::draw |