feat: IBL 预积分 GPU compute 化 + 环境资产入 Assets 层(动态切换)

CPU 逐像素卷积(venice 4k 阻塞 7.36s)→ 4 个 compute shader 一次性
提交:equirect→cube / irradiance / prefilter×5mip / BRDF LUT。
Cubemap 瘦身为纯资源持有类,生成职责移交 IblGenerator;
环境经 AssetManager 缓存(EnvRef),Renderer::SetEnvironment
动态换绑(RenderPass::OnEnvironmentChanged 广播)。
调试视图 +4:EnvCube / Irradiance / Prefilter / BRDF LUT。

性能前后对比(RTX 5060 Laptop,venice_dawn_1_4k.hdr):
- 改造前 CPU:7.36 s(主线程阻塞)
- 改造后 GPU:HDR decode 127-134ms + 资源 22-35ms + compute 17-19ms
  ≈ 165-190ms(约 40×);Neutral 兜底 ~6ms
- 运行中动态切换环境同量级(ms 级 GPU,decode 占大头)

冒烟:两构建目录 0 警告;运行期 0 validation(含两次环境切换 +
调试视图 9-12 轮播自动化验证)。
This commit is contained in:
2026-09-24 13:23:59 +08:00
parent 705250df76
commit 1d690067bd
30 changed files with 1162 additions and 824 deletions
+27 -6
View File
@@ -25,10 +25,11 @@ namespace Engine
vk::DescriptorPool DescriptorManager::CreateChunk() const
{
std::array<vk::DescriptorPoolSize, 3> poolSizes = {
std::array<vk::DescriptorPoolSize, 4> poolSizes = {
vk::DescriptorPoolSize(vk::DescriptorType::eUniformBuffer, kChunkSets),
vk::DescriptorPoolSize(vk::DescriptorType::eCombinedImageSampler, kChunkSets),
vk::DescriptorPoolSize(vk::DescriptorType::eStorageBuffer, kChunkSets),
vk::DescriptorPoolSize(vk::DescriptorType::eStorageImage, kChunkSets),
};
vk::DescriptorPoolCreateInfo poolInfo;
@@ -133,6 +134,26 @@ namespace Engine
m_Device.GetDevice().updateDescriptorSets(write, {});
}
void DescriptorManager::UpdateStorageImage(const vk::DescriptorSet set,
const u32 binding,
const vk::ImageView view) const
{
// storage image 写(compute 输出):layout 必须 eGeneral
vk::DescriptorImageInfo imageInfo;
imageInfo.setImageView(view)
.setImageLayout(vk::ImageLayout::eGeneral);
vk::WriteDescriptorSet write;
write.setDstSet(set)
.setDstBinding(binding)
.setDstArrayElement(0)
.setDescriptorType(vk::DescriptorType::eStorageImage)
.setDescriptorCount(1)
.setImageInfo(imageInfo);
m_Device.GetDevice().updateDescriptorSets(write, {});
}
vk::PipelineLayout DescriptorManager::CreatePipelineLayout(vk::DescriptorSetLayout layout,
const u32 pushConstantSize) const
{
@@ -154,18 +175,18 @@ namespace Engine
}
vk::PipelineLayout DescriptorManager::CreatePipelineLayout(const std::vector<vk::DescriptorSetLayout>& layouts,
const u32 pushConstantSize) const
const u32 pushConstantSize,
const vk::ShaderStageFlags pushStages) const
{
vk::PipelineLayoutCreateInfo info;
info.setSetLayouts(layouts);
std::array<vk::PushConstantRange, 1> pushRanges;
if (pushConstantSize > 0) {
// 与 ShaderManager 一致:程序级 vertex|fragment 声明。
// 与 ShaderManager 一致:程序级声明(默认 vertex|fragment)。
// 注意 vkCmdPushConstants 的 stageFlags 必须覆盖 range 的
// 全部 stage(VUID-01796),因此 push 调用点也要带双 stage
pushRanges[0].setStageFlags(vk::ShaderStageFlagBits::eVertex |
vk::ShaderStageFlagBits::eFragment)
// 全部 stage(VUID-01796),因此 push 调用点也要带同样的 stage
pushRanges[0].setStageFlags(pushStages)
.setOffset(0)
.setSize(pushConstantSize);
info.setPushConstantRanges(pushRanges);