【发布时间】:2022-10-21 00:23:36
【问题描述】:
由于在运行时不能创建新的着色器,所以在编译时就可以提前知道完整的着色器。每个着色器都必须引用一个用于渲染的“通道”。
为了避免在运行时出现帧峰值,我想在启动期间预先创建所有管道对象。要创建管道,必须知道输出数量和每个输出附件的格式——要么创建VkRenderPass,要么指定dynamic rendering feature 的输出。
但是,我还想使用frame graph concept(Yuriy O'Donnell 的演讲),它反过来构建了一个渲染通道图,其中包含输入输出规范和它们之间的依赖关系。有些通道是有条件地创建的(例如调试通道),有些通道可能会从图中删除(在“编译”它之后)。
此外,我需要支持“write on top”功能,因此在构建渲染通道期间无需指定新输出,我可以简单地说此通道的输出将使用前一个通道的输出 - 这是例如,对于添加 alpha 混合渲染很有用。
如何匹配代码的两个单独部分?换句话说,我怎么能在初始化期间定义所有渲染通道但也使用动态方法在每一帧构建帧图不重复我?
这就是我想要的避免(伪代码):
struct Pass1Def
{
output1 = ImageFormat::RGBA8;
output2 = ImageFormat::RGBA8;
// ...
outputs = // outputs in order (corresponds to location in shader)
};
void init()
{
for_each_shaders shader {
passDef = findPassDef(shader);
createPipeline(shader, passDef);
}
}
void render()
{
auto previousResource = someCondition ? passA.outputResource1 : passB.outputResource2;
graph.addPass(..., [&](PassBuilder& builder, Pass1Data& data) {
// error-prone: order of function calls matter (corresponds to location in shader)
// error-prone: use the same format defined in Pass1Def
data.outputResource1 = builder.create(... ImageFormat::RGBA8);
// error-prone: the format depends on the outputResource of a previous pass
// however the format must be (and was) specified in Pass1Def
data.outputResource2 = builder.write(previousResource);
});
}
【问题讨论】:
标签: graphics architecture vulkan