通过工厂方法创建结构体的成员会失去价值

问题描述 投票:0回答:1

我希望我能够尽可能清楚地解释我的问题。我正在开发一个使用 Vulkan 的 Rust 应用程序。

我在创建图形管道时遇到了一些麻烦。我发现了这个问题,但我不知道发生了什么以及为什么发生。

首先让我展示一下什么是有效的。为了创建图形管道,我需要创建一个名为

PipelineViewportStateCreateInfo
的东西。然后我用这个结构(以及其他一些结构)来创建一个
GraphicsPipelineCreateInfo

swapchain_extent 的

width
height
属性分别设置为 1600 和 1200。

    let viewports = [Viewport::builder()
        .x(0.0)
        .y(0.0)
        .width(swapchain_extent.width as f32)
        .height(swapchain_extent.height as f32)
        .min_depth(0.0)
        .max_depth(0.0)
        .build()];

    let scissors = [Rect2D::builder()
        .offset(Offset2D::builder().x(0).y(0).build())
        .extent(swapchain_extent)
        .build()];

    let viewport_state_create_info = PipelineViewportStateCreateInfo::builder()
        .scissors(&scissors)
        .viewports(&viewports)
        .build();

    let graphics_pipeline_create_infos = [GraphicsPipelineCreateInfo::builder()
        .viewport_state(&viewport_state_create_info)
        .build()];

这一切都很完美。

为了使我的代码更加结构化,我创建了一个辅助函数来负责创建

PipelineViewPortStateCreateInfo
:

fn create_viewport_state_create_info(extent: Extent2D) -> PipelineViewportStateCreateInfo {
    let viewports = [Viewport::builder()
        .x(0.0)
        .y(0.0)
        .width(extent.width as f32)
        .height(extent.height as f32)
        .min_depth(0.0)
        .max_depth(0.0)
        .build()];

    let scissors = [Rect2D::builder()
        .offset(Offset2D::builder().x(0).y(0).build())
        .extent(extent)
        .build()];

    PipelineViewportStateCreateInfo::builder()
        .viewports(&viewports)
        .scissors(&scissors)
        .build()
}

我从我的其他函数中调用它,如下所示:

    let viewport_state_create_info = create_viewport_state_create_info(swapchain_extent);

    let graphics_pipeline_create_infos = [GraphicsPipelineCreateInfo::builder()
        .viewport_state(&viewport_state_create_info)
        .build()];

我没有发现这段代码有问题。然而,当我运行此代码时,Vulkan 验证层向我抛出此错误:

VALIDATION [VUID-VkViewport-width-01770 (-1542042715)]: Validation Error: [ VUID-VkViewport-width-01770 ] | MessageID = 0xa4164ba5 | vkCreateGraphicsPipelines(): pCreateInfos[0].pViewportState->pViewports[0].width (0.000000) is not greater than 0.0. The Vulkan spec states: width must be greater than 0.0

即使

swapchain_extent.width
设置为 1600。

在调试器中我看到它确实是1600,但是当我进入

GraphicsPipelineCreateInfoBuilder
的构建功能时,宽度和高度突然变成0.0🤔

这是范围界定问题吗?如果是的话,编译器不是应该保护我免受它的侵害吗?

rust struct scope vulkan ash
1个回答
0
投票

是的,您的假设是正确的。这是一个范围界定问题。

问题在于

PipelineViewportStateCreateInfo
保留指向
viewports
scissors
的指针(而不是引用)。然而,当
create_viewport_state_create_info()
返回时,
viewports
scissors
都会被丢弃。所以
PipelineViewportStateCreateInfo
中的指针现在无效了。

编译器无法捕捉到这一点的原因。是因为当调用

build()
时,它返回一个不再引用任何生命周期的
PipelineViewportStateCreateInfo
。理论上可以。然而,
ask
只是镜像了
VkPipelineViewportStateCreateInfo
的定义。

(docs.rs当前已关闭,因此我无法链接到参考文献,稍后我将在其启动时更新答案)

© www.soinside.com 2019 - 2024. All rights reserved.