From c3d9e26cde7efc7a35de0b3801bd8508df958980 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Tue, 24 Jun 2025 13:10:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=BA=9B=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=E8=AF=B4=E6=98=8E=EF=BC=8C=E9=83=A8=E5=88=86=E6=9D=A5?= =?UTF-8?q?=E8=87=AAAI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- inc/hgl/component/Component.h | 11 +++++++++-- src/SceneGraph/Vulkan/VKMemory.cpp | 31 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/inc/hgl/component/Component.h b/inc/hgl/component/Component.h index c53f3d28..f8884a6f 100644 --- a/inc/hgl/component/Component.h +++ b/inc/hgl/component/Component.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include #include @@ -32,7 +32,6 @@ * RenderComponent是可渲染组件的基类,所有可渲染组件都从这里派生。 * * MeshComponent是静态网格组件,它是一个具体的RenderComponent实现。 -* */ #define COMPONENT_NAMESPACE hgl::graph @@ -65,6 +64,14 @@ public: using ComponentDataPtr=SharedPtr; +/** +* 为什么要ComponentData与Component分离? +* +* ComponentData是Component的一个数据载体,但它也仅仅代表数据。 +* 它不参与任何的逻辑、事件、更新、渲染操作,而且同一份数据可以被多个Component使用。 +* 同时,Component也可以在运行时更换ComponentData。 +*/ + /** * 基础组件
* 是一切组件的基类 diff --git a/src/SceneGraph/Vulkan/VKMemory.cpp b/src/SceneGraph/Vulkan/VKMemory.cpp index e2a23b5e..b1bb27f5 100644 --- a/src/SceneGraph/Vulkan/VKMemory.cpp +++ b/src/SceneGraph/Vulkan/VKMemory.cpp @@ -44,7 +44,38 @@ void *DeviceMemory::Map() void *result; if(vkMapMemory(device,memory,0,req.size,0,&result)==VK_SUCCESS) + { + /** 只要是MAP成功,那么数据就可以直接访问 + + 关键点 + 1. 如果你的内存类型是 HOST_VISIBLE 且 HOST_COHERENT + • 这类内存通常是“共享内存”(integrated GPU)或“staging buffer”(独立显卡+主机内存)。 + • 读取和写入都比较高效,类似普通RAM,但带宽和延迟可能略低于纯CPU内存。 + • 适合CPU直接读写。 + 2. 如果你的内存类型是 HOST_VISIBLE 但不是 HOST_COHERENT + • 你在写入后需要vkFlushMappedMemoryRanges,读取前需要vkInvalidateMappedMemoryRanges。 + • 否则CPU和GPU看到的数据可能不同步。 + • 读取时要注意同步,否则可能读到旧数据。 + 3. 如果你的内存类型是纯GPU本地内存(DEVICE_LOCAL,无HOST_VISIBLE) + • 你根本无法vkMapMemory,也无法直接读取。 + + 性能建议 + • 遍历读取通常比写入慢,因为数据可能在主板内存(staging buffer),而不是CPU缓存友好的区域。 + • 如果只是偶尔小范围读取,影响不大。 + • 如果频繁大范围遍历,建议: + • 尽量减少读取次数和数据量。 + • 考虑在上传前先在CPU内存准备好数据,必要时用临时buffer。 + • 如果数据已经上传到GPU且只在GPU用,避免CPU端读取。 + 典型用法 + • 上传数据:CPU写入staging buffer → flush → GPU拷贝到本地显存。 + • 读取数据:很少直接从映射内存读取,通常是GPU拷贝到staging buffer,再由CPU读取。 + 总结 + • 偶尔小量读取没问题,大范围频繁读取会有性能损失。 + • 建议只在必要时读取,并优先考虑数据在CPU端准备好后一次性上传。 + */ + return result; + } return(nullptr); }