diff options
Diffstat (limited to 'source/blender/draw')
18 files changed, 300 insertions, 0 deletions
diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.cc b/source/blender/draw/engines/eevee_next/eevee_instance.cc index 8005b27c30e..a0bdf70e254 100644 --- a/source/blender/draw/engines/eevee_next/eevee_instance.cc +++ b/source/blender/draw/engines/eevee_next/eevee_instance.cc @@ -106,6 +106,8 @@ void Instance::begin_sync() gpencil_engine_enabled = false; + scene_sync(); + depth_of_field.sync(); motion_blur.sync(); hiz_buffer.sync(); @@ -115,6 +117,21 @@ void Instance::begin_sync() film.sync(); } +void Instance::scene_sync() +{ + SceneHandle &sc_handle = sync.sync_scene(scene); + + sc_handle.reset_recalc_flag(); + + /* This refers specifically to the Scene camera that can be accessed + * via View Layer Attribute nodes, rather than the actual render camera. */ + if (scene->camera != nullptr) { + ObjectHandle &ob_handle = sync.sync_object(scene->camera); + + ob_handle.reset_recalc_flag(); + } +} + void Instance::object_sync(Object *ob) { const bool is_renderable_type = ELEM(ob->type, OB_CURVES, OB_GPENCIL, OB_MESH, OB_LAMP); diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.hh b/source/blender/draw/engines/eevee_next/eevee_instance.hh index c8eecbd812d..bc610cd0642 100644 --- a/source/blender/draw/engines/eevee_next/eevee_instance.hh +++ b/source/blender/draw/engines/eevee_next/eevee_instance.hh @@ -162,6 +162,7 @@ class Instance { void render_sample(); void render_read_result(RenderLayer *render_layer, const char *view_name); + void scene_sync(); void mesh_sync(Object *ob, ObjectHandle &ob_handle); void update_eval_members(); diff --git a/source/blender/draw/engines/eevee_next/eevee_material.cc b/source/blender/draw/engines/eevee_next/eevee_material.cc index b63002df2e3..d190a1f17a3 100644 --- a/source/blender/draw/engines/eevee_next/eevee_material.cc +++ b/source/blender/draw/engines/eevee_next/eevee_material.cc @@ -187,6 +187,8 @@ MaterialPass MaterialModule::material_pass_get(Object *ob, /* Returned material should be ready to be drawn. */ BLI_assert(GPU_material_status(matpass.gpumat) == GPU_MAT_SUCCESS); + inst_.manager->register_layer_attributes(matpass.gpumat); + if (GPU_material_recalc_flag_get(matpass.gpumat)) { inst_.sampling.reset(); } @@ -217,6 +219,9 @@ MaterialPass MaterialModule::material_pass_get(Object *ob, matpass.sub_pass = &shader_sub->sub(GPU_material_get_name(matpass.gpumat)); matpass.sub_pass->material_set(*inst_.manager, matpass.gpumat); } + else { + matpass.sub_pass = nullptr; + } } return matpass; diff --git a/source/blender/draw/engines/eevee_next/eevee_sync.cc b/source/blender/draw/engines/eevee_next/eevee_sync.cc index f2daba48d7a..08cda6f47cf 100644 --- a/source/blender/draw/engines/eevee_next/eevee_sync.cc +++ b/source/blender/draw/engines/eevee_next/eevee_sync.cc @@ -68,6 +68,20 @@ WorldHandle &SyncModule::sync_world(::World *world) return eevee_dd; } +SceneHandle &SyncModule::sync_scene(::Scene *scene) +{ + DrawEngineType *owner = (DrawEngineType *)&DRW_engine_viewport_eevee_next_type; + struct DrawData *dd = DRW_drawdata_ensure( + (ID *)scene, owner, sizeof(eevee::SceneHandle), draw_data_init_cb, nullptr); + SceneHandle &eevee_dd = *reinterpret_cast<SceneHandle *>(dd); + + const int recalc_flags = ID_RECALC_ALL; + if ((eevee_dd.recalc & recalc_flags) != 0) { + inst_.sampling.reset(); + } + return eevee_dd; +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/engines/eevee_next/eevee_sync.hh b/source/blender/draw/engines/eevee_next/eevee_sync.hh index ab883ce44c2..eda0342c4b6 100644 --- a/source/blender/draw/engines/eevee_next/eevee_sync.hh +++ b/source/blender/draw/engines/eevee_next/eevee_sync.hh @@ -139,6 +139,15 @@ struct WorldHandle : public DrawData { } }; +struct SceneHandle : public DrawData { + void reset_recalc_flag() + { + if (recalc != 0) { + recalc = 0; + } + } +}; + class SyncModule { private: Instance &inst_; @@ -149,6 +158,7 @@ class SyncModule { ObjectHandle &sync_object(Object *ob); WorldHandle &sync_world(::World *world); + SceneHandle &sync_scene(::Scene *scene); void sync_mesh(Object *ob, ObjectHandle &ob_handle, diff --git a/source/blender/draw/engines/eevee_next/eevee_world.cc b/source/blender/draw/engines/eevee_next/eevee_world.cc index 313c0bda42e..37f90570028 100644 --- a/source/blender/draw/engines/eevee_next/eevee_world.cc +++ b/source/blender/draw/engines/eevee_next/eevee_world.cc @@ -87,6 +87,9 @@ void World::sync() default_tree.nodetree_get(bl_world); GPUMaterial *gpumat = inst_.shaders.world_shader_get(bl_world, ntree); + + inst_.manager->register_layer_attributes(gpumat); + inst_.pipelines.world.sync(gpumat); } diff --git a/source/blender/draw/intern/draw_defines.h b/source/blender/draw/intern/draw_defines.h index f5976ddd34e..57035717bd7 100644 --- a/source/blender/draw/intern/draw_defines.h +++ b/source/blender/draw/intern/draw_defines.h @@ -15,6 +15,8 @@ #define DRW_VIEW_CULLING_UBO_SLOT 1 #define DRW_CLIPPING_UBO_SLOT 2 +#define DRW_LAYER_ATTR_UBO_SLOT 3 + #define DRW_RESOURCE_ID_SLOT 11 #define DRW_OBJ_MAT_SLOT 10 #define DRW_OBJ_INFOS_SLOT 9 diff --git a/source/blender/draw/intern/draw_instance_data.c b/source/blender/draw/intern/draw_instance_data.c index a56883ce304..b44c1364af9 100644 --- a/source/blender/draw/intern/draw_instance_data.c +++ b/source/blender/draw/intern/draw_instance_data.c @@ -622,6 +622,62 @@ void drw_uniform_attrs_pool_update(GHash *table, } } +GPUUniformBuf *drw_ensure_layer_attribute_buffer() +{ + DRWData *data = DST.vmempool; + + if (data->vlattrs_ubo_ready && data->vlattrs_ubo != NULL) { + return data->vlattrs_ubo; + } + + /* Allocate the buffer data. */ + const int buf_size = DRW_RESOURCE_CHUNK_LEN; + + if (data->vlattrs_buf == NULL) { + data->vlattrs_buf = MEM_calloc_arrayN( + buf_size, sizeof(LayerAttribute), "View Layer Attr Data"); + } + + /* Look up attributes. + * + * Mirrors code in draw_resource.cc and cycles/blender/shader.cpp. + */ + LayerAttribute *buffer = data->vlattrs_buf; + int count = 0; + + LISTBASE_FOREACH (GPULayerAttr *, attr, &data->vlattrs_name_list) { + float value[4]; + + if (BKE_view_layer_find_rgba_attribute( + DST.draw_ctx.scene, DST.draw_ctx.view_layer, attr->name, value)) { + LayerAttribute *item = &buffer[count++]; + + memcpy(item->data, value, sizeof(item->data)); + item->hash_code = attr->hash_code; + + /* Check if the buffer is full just in case. */ + if (count >= buf_size) { + break; + } + } + } + + buffer[0].buffer_length = count; + + /* Update or create the UBO object. */ + if (data->vlattrs_ubo != NULL) { + GPU_uniformbuf_update(data->vlattrs_ubo, buffer); + } + else { + data->vlattrs_ubo = GPU_uniformbuf_create_ex( + sizeof(*buffer) * buf_size, buffer, "View Layer Attributes"); + } + + data->vlattrs_ubo_ready = true; + + return data->vlattrs_ubo; +} + DRWSparseUniformBuf *DRW_uniform_attrs_pool_find_ubo(GHash *table, const struct GPUUniformAttrList *key) { diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 6dfd434d5c7..28abbc6ab71 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -378,6 +378,8 @@ DRWData *DRW_viewport_data_create(void) drw_data->views = BLI_memblock_create(sizeof(DRWView)); drw_data->images = BLI_memblock_create(sizeof(GPUTexture *)); drw_data->obattrs_ubo_pool = DRW_uniform_attrs_pool_new(); + drw_data->vlattrs_name_cache = BLI_ghash_new( + BLI_ghashutil_inthash_p_simple, BLI_ghashutil_intcmp, "View Layer Attribute names"); { uint chunk_len = sizeof(DRWObjectMatrix) * DRW_RESOURCE_CHUNK_LEN; drw_data->obmats = BLI_memblock_create_ex(sizeof(DRWObjectMatrix), chunk_len); @@ -413,9 +415,23 @@ static void draw_texture_release(DRWData *drw_data) } } +static void draw_prune_vlattrs(DRWData *drw_data) +{ + drw_data->vlattrs_ubo_ready = false; + + /* Forget known attributes after they are unused for a few frames. */ + LISTBASE_FOREACH_MUTABLE (GPULayerAttr *, attr, &drw_data->vlattrs_name_list) { + if (++attr->users > 10) { + BLI_ghash_remove(drw_data->vlattrs_name_cache, (void *)attr->hash_code, NULL, NULL); + BLI_freelinkN(&drw_data->vlattrs_name_list, attr); + } + } +} + static void drw_viewport_data_reset(DRWData *drw_data) { draw_texture_release(drw_data); + draw_prune_vlattrs(drw_data); BLI_memblock_clear(drw_data->commands, NULL); BLI_memblock_clear(drw_data->commands_small, NULL); @@ -451,6 +467,12 @@ void DRW_viewport_data_free(DRWData *drw_data) BLI_memblock_destroy(drw_data->passes, NULL); BLI_memblock_destroy(drw_data->images, NULL); DRW_uniform_attrs_pool_free(drw_data->obattrs_ubo_pool); + BLI_ghash_free(drw_data->vlattrs_name_cache, NULL, NULL); + BLI_freelistN(&drw_data->vlattrs_name_list); + if (drw_data->vlattrs_ubo) { + GPU_uniformbuf_free(drw_data->vlattrs_ubo); + MEM_freeN(drw_data->vlattrs_buf); + } DRW_instance_data_list_free(drw_data->idatalist); DRW_texture_pool_free(drw_data->texture_pool); for (int i = 0; i < 2; i++) { @@ -811,6 +833,7 @@ static bool id_type_can_have_drawdata(const short id_type) /* has DrawData */ case ID_OB: case ID_WO: + case ID_SCE: return true; /* no DrawData */ diff --git a/source/blender/draw/intern/draw_manager.cc b/source/blender/draw/intern/draw_manager.cc index 169d86b2ea1..c644cadd18c 100644 --- a/source/blender/draw/intern/draw_manager.cc +++ b/source/blender/draw/intern/draw_manager.cc @@ -35,6 +35,7 @@ void Manager::begin_sync() } acquired_textures.clear(); + layer_attributes.clear(); #ifdef DEBUG /* Detect uninitialized data. */ @@ -52,14 +53,46 @@ void Manager::begin_sync() resource_handle(float4x4::identity()); } +void Manager::sync_layer_attributes() +{ + /* Sort the attribute IDs - the shaders use binary search. */ + Vector<uint32_t> id_list; + + id_list.reserve(layer_attributes.size()); + + for (uint32_t id : layer_attributes.keys()) { + id_list.append(id); + } + + std::sort(id_list.begin(), id_list.end()); + + /* Look up the attributes. */ + int count = 0, size = layer_attributes_buf.end() - layer_attributes_buf.begin(); + + for (uint32_t id : id_list) { + if (layer_attributes_buf[count].sync( + DST.draw_ctx.scene, DST.draw_ctx.view_layer, layer_attributes.lookup(id))) { + /* Check if the buffer is full. */ + if (++count == size) { + break; + } + } + } + + layer_attributes_buf[0].buffer_length = count; +} + void Manager::end_sync() { GPU_debug_group_begin("Manager.end_sync"); + sync_layer_attributes(); + matrix_buf.push_update(); bounds_buf.push_update(); infos_buf.push_update(); attributes_buf.push_update(); + layer_attributes_buf.push_update(); attributes_buf_legacy.push_update(); /* Useful for debugging the following resource finalize. But will trigger the drawing of the GPU @@ -100,6 +133,7 @@ void Manager::resource_bind() GPU_storagebuf_bind(matrix_buf, DRW_OBJ_MAT_SLOT); GPU_storagebuf_bind(infos_buf, DRW_OBJ_INFOS_SLOT); GPU_storagebuf_bind(attributes_buf, DRW_OBJ_ATTR_SLOT); + GPU_uniformbuf_bind(layer_attributes_buf, DRW_LAYER_ATTR_UBO_SLOT); /* 2 is the hardcoded location of the uniform attr UBO. */ /* TODO(@fclem): Remove this workaround. */ GPU_uniformbuf_bind(attributes_buf_legacy, 2); diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index 6b5a2cc4f6f..ce316a31cf9 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -335,6 +335,7 @@ typedef enum { DRW_UNIFORM_BLOCK_OBMATS, DRW_UNIFORM_BLOCK_OBINFOS, DRW_UNIFORM_BLOCK_OBATTRS, + DRW_UNIFORM_BLOCK_VLATTRS, DRW_UNIFORM_RESOURCE_CHUNK, DRW_UNIFORM_RESOURCE_ID, /** Legacy / Fallback */ @@ -527,6 +528,11 @@ typedef struct DRWData { struct GPUUniformBuf **matrices_ubo; struct GPUUniformBuf **obinfos_ubo; struct GHash *obattrs_ubo_pool; + struct GHash *vlattrs_name_cache; + struct ListBase vlattrs_name_list; + struct LayerAttribute *vlattrs_buf; + struct GPUUniformBuf *vlattrs_ubo; + bool vlattrs_ubo_ready; uint ubo_len; /** Per draw-call volume object data. */ void *volume_grids_ubos; /* VolumeUniformBufPool */ @@ -691,6 +697,8 @@ void drw_uniform_attrs_pool_update(struct GHash *table, struct Object *dupli_parent, struct DupliObject *dupli_source); +GPUUniformBuf *drw_ensure_layer_attribute_buffer(); + double *drw_engine_data_cache_time_get(GPUViewport *viewport); void *drw_engine_data_engine_data_create(GPUViewport *viewport, void *engine_type); void *drw_engine_data_engine_data_get(GPUViewport *viewport, void *engine_handle); diff --git a/source/blender/draw/intern/draw_manager.hh b/source/blender/draw/intern/draw_manager.hh index fbd3d28d3f4..0a865179cee 100644 --- a/source/blender/draw/intern/draw_manager.hh +++ b/source/blender/draw/intern/draw_manager.hh @@ -44,6 +44,7 @@ class Manager { using ObjectBoundsBuf = StorageArrayBuffer<ObjectBounds, 128>; using ObjectInfosBuf = StorageArrayBuffer<ObjectInfos, 128>; using ObjectAttributeBuf = StorageArrayBuffer<ObjectAttribute, 128>; + using LayerAttributeBuf = UniformArrayBuffer<LayerAttribute, 512>; /** * TODO(@fclem): Remove once we get rid of old EEVEE code-base. * `DRW_RESOURCE_CHUNK_LEN = 512`. @@ -87,6 +88,16 @@ class Manager { ObjectAttributeLegacyBuf attributes_buf_legacy; /** + * Table of all View Layer attributes required by shaders, used to populate the buffer below. + */ + Map<uint32_t, GPULayerAttr> layer_attributes; + + /** + * Buffer of layer attribute values, indexed and sorted by the hash. + */ + LayerAttributeBuf layer_attributes_buf; + + /** * List of textures coming from Image data-blocks. * They need to be reference-counted in order to avoid being freed in another thread. */ @@ -131,6 +142,11 @@ class Manager { Span<GPUMaterial *> materials); /** + * Collect necessary View Layer attributes. + */ + void register_layer_attributes(GPUMaterial *material); + + /** * Submit a pass for drawing. All resource reference will be dereferenced and commands will be * sent to GPU. */ @@ -169,6 +185,9 @@ class Manager { void debug_bind(); void resource_bind(); + + private: + void sync_layer_attributes(); }; inline ResourceHandle Manager::resource_handle(const ObjectRef ref) @@ -229,6 +248,19 @@ inline void Manager::extract_object_attributes(ResourceHandle handle, } } +inline void Manager::register_layer_attributes(GPUMaterial *material) +{ + const ListBase *attr_list = GPU_material_layer_attributes(material); + + if (attr_list != nullptr) { + LISTBASE_FOREACH (const GPULayerAttr *, attr, attr_list) { + /** Since layer attributes are global to the whole render pass, + * this only collects a table of their names. */ + layer_attributes.add(attr->hash_code, *attr); + } + } +} + } // namespace blender::draw /* TODO(@fclem): This is for testing. The manager should be passed to the engine through the diff --git a/source/blender/draw/intern/draw_manager_data.cc b/source/blender/draw/intern/draw_manager_data.cc index 06677344132..030b13177f1 100644 --- a/source/blender/draw/intern/draw_manager_data.cc +++ b/source/blender/draw/intern/draw_manager_data.cc @@ -1840,6 +1840,13 @@ void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, GPUMaterial *mater grp, loc, DRW_UNIFORM_BLOCK_OBATTRS, uattrs, GPU_SAMPLER_DEFAULT, 0, 1); grp->uniform_attrs = uattrs; } + + if (GPU_material_layer_attributes(material) != NULL) { + int loc = GPU_shader_get_uniform_block_binding(grp->shader, + GPU_LAYER_ATTRIBUTE_UBO_BLOCK_NAME); + drw_shgroup_uniform_create_ex( + grp, loc, DRW_UNIFORM_BLOCK_VLATTRS, nullptr, GPU_SAMPLER_DEFAULT, 0, 1); + } } GPUVertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttrFormat attrs[], diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 3627b0fbf10..8b1b35b5f03 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -44,6 +44,7 @@ typedef struct DRWCommandsState { int obmats_loc; int obinfos_loc; int obattrs_loc; + int vlattrs_loc; int baseinst_loc; int chunkid_loc; int resourceid_loc; @@ -682,6 +683,10 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup, uni->uniform_attrs); DRW_sparse_uniform_buffer_bind(state->obattrs_ubo, 0, uni->location); break; + case DRW_UNIFORM_BLOCK_VLATTRS: + state->vlattrs_loc = uni->location; + GPU_uniformbuf_bind(drw_ensure_layer_attribute_buffer(), uni->location); + break; case DRW_UNIFORM_RESOURCE_CHUNK: state->chunkid_loc = uni->location; GPU_shader_uniform_int(shgroup->shader, uni->location, 0); @@ -960,6 +965,9 @@ static void draw_call_batching_finish(DRWShadingGroup *shgroup, DRWCommandsState if (state->obattrs_loc != -1) { DRW_sparse_uniform_buffer_unbind(state->obattrs_ubo, state->resource_chunk); } + if (state->vlattrs_loc != -1) { + GPU_uniformbuf_unbind(DST.vmempool->vlattrs_ubo); + } } static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) @@ -970,6 +978,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) .obmats_loc = -1, .obinfos_loc = -1, .obattrs_loc = -1, + .vlattrs_loc = -1, .baseinst_loc = -1, .chunkid_loc = -1, .resourceid_loc = -1, diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index 04a9f3fdd2d..8b287e116bc 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -237,6 +237,42 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred) WM_jobs_start(wm, wm_job); } +static void drw_register_shader_vlattrs(GPUMaterial *mat) +{ + const ListBase *attrs = GPU_material_layer_attributes(mat); + + if (!attrs) { + return; + } + + GHash *hash = DST.vmempool->vlattrs_name_cache; + ListBase *list = &DST.vmempool->vlattrs_name_list; + + LISTBASE_FOREACH (GPULayerAttr *, attr, attrs) { + GPULayerAttr **p_val; + + /* Add to the table and list if newly seen. */ + if (!BLI_ghash_ensure_p(hash, (void *)attr->hash_code, (void ***)&p_val)) { + DST.vmempool->vlattrs_ubo_ready = false; + + GPULayerAttr *new_link = *p_val = MEM_dupallocN(attr); + + /* Insert into the list ensuring sorted order. */ + GPULayerAttr *link = list->first; + + while (link && link->hash_code <= attr->hash_code) { + link = link->next; + } + + new_link->prev = new_link->next = NULL; + BLI_insertlinkbefore(list, link, new_link); + } + + /* Reset the unused frames counter. */ + (*p_val)->users = 0; + } +} + void DRW_deferred_shader_remove(GPUMaterial *mat) { LISTBASE_FOREACH (wmWindowManager *, wm, &G_MAIN->wm) { @@ -382,6 +418,9 @@ GPUMaterial *DRW_shader_from_world(World *wo, false, callback, thunk); + + drw_register_shader_vlattrs(mat); + if (DRW_state_is_image_render()) { /* Do not deferred if doing render. */ deferred = false; @@ -411,6 +450,8 @@ GPUMaterial *DRW_shader_from_material(Material *ma, callback, thunk); + drw_register_shader_vlattrs(mat); + if (DRW_state_is_image_render()) { /* Do not deferred if doing render. */ deferred = false; diff --git a/source/blender/draw/intern/draw_resource.cc b/source/blender/draw/intern/draw_resource.cc index f57058190fb..c1f83c3a5ae 100644 --- a/source/blender/draw/intern/draw_resource.cc +++ b/source/blender/draw/intern/draw_resource.cc @@ -38,3 +38,16 @@ bool ObjectAttribute::sync(const blender::draw::ObjectRef &ref, const GPUUniform } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name LayerAttributes + * \{ */ + +bool LayerAttribute::sync(Scene *scene, ViewLayer *layer, const GPULayerAttr &attr) +{ + hash_code = attr.hash_code; + + return BKE_view_layer_find_rgba_attribute(scene, layer, attr.name, &data.x); +} + +/** \} */ diff --git a/source/blender/draw/intern/draw_shader_shared.h b/source/blender/draw/intern/draw_shader_shared.h index 37899e36d8a..75a7e28fa75 100644 --- a/source/blender/draw/intern/draw_shader_shared.h +++ b/source/blender/draw/intern/draw_shader_shared.h @@ -15,6 +15,7 @@ typedef struct ObjectBounds ObjectBounds; typedef struct VolumeInfos VolumeInfos; typedef struct CurvesInfos CurvesInfos; typedef struct ObjectAttribute ObjectAttribute; +typedef struct LayerAttribute LayerAttribute; typedef struct DrawCommand DrawCommand; typedef struct DispatchCommand DispatchCommand; typedef struct DRWDebugPrintBuffer DRWDebugPrintBuffer; @@ -24,8 +25,10 @@ typedef struct DRWDebugDrawBuffer DRWDebugDrawBuffer; # ifdef __cplusplus /* C++ only forward declarations. */ struct Object; +struct ViewLayer; struct ID; struct GPUUniformAttr; +struct GPULayerAttr; namespace blender::draw { @@ -192,6 +195,20 @@ struct ObjectAttribute { * C++ compiler gives us the same size. */ BLI_STATIC_ASSERT_ALIGN(ObjectAttribute, 20) +#pragma pack(push, 4) +struct LayerAttribute { + float4 data; + uint hash_code; + uint buffer_length; /* Only in the first record. */ + uint _pad1, _pad2; + +#if !defined(GPU_SHADER) && defined(__cplusplus) + bool sync(Scene *scene, ViewLayer *layer, const GPULayerAttr &attr); +#endif +}; +#pragma pack(pop) +BLI_STATIC_ASSERT_ALIGN(LayerAttribute, 32) + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/intern/shaders/draw_object_infos_info.hh b/source/blender/draw/intern/shaders/draw_object_infos_info.hh index ad0426e6d3f..33634fb5fcb 100644 --- a/source/blender/draw/intern/shaders/draw_object_infos_info.hh +++ b/source/blender/draw/intern/shaders/draw_object_infos_info.hh @@ -19,6 +19,14 @@ GPU_SHADER_CREATE_INFO(draw_curves_infos) .typedef_source("draw_shader_shared.h") .uniform_buf(3, "CurvesInfos", "drw_curves", Frequency::BATCH); +GPU_SHADER_CREATE_INFO(draw_layer_attributes) + .typedef_source("draw_shader_shared.h") + .define("VLATTR_LIB") + .uniform_buf(DRW_LAYER_ATTR_UBO_SLOT, + "LayerAttribute", + "drw_layer_attrs[DRW_RESOURCE_CHUNK_LEN]", + Frequency::BATCH); + GPU_SHADER_CREATE_INFO(draw_object_infos_new) .typedef_source("draw_shader_shared.h") .define("OBINFO_LIB") |