【问题标题】:android vulkan vertex shader can't get all input dataandroid vulkan顶点着色器无法获取所有输入数据
【发布时间】:2020-05-29 10:16:29
【问题描述】:

我的顶点数据是这样定义的:

struct Vertex{
    glm::vec4 pos;
    glm::vec2 texcoord;
    glm::vec2 texcoordex;
    float alpha;
    float idx;
};

我的问题是: 顶点缓冲区已读取所有数据,但顶点着色器仅获取第一个 pos 作为输入,其他为 0.0f

顶点着色器输入

layout (location = 0) in vec4 pos;
layout (location = 1) in vec2 attr;
layout (location = 2) in vec2 attrex;
layout (location = 3) in float alph;
layout (location = 4) in float id;

一些代码sn-ps

VkVertexInputBindingDescription vertex_input_bindings{
.binding = 0,
.stride = sizeof(Vertex),
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
};

VkVertexInputAttributeDescription vertex_input_attributes[5]{
{
.binding = 0,
.location = 0,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof(Vertex, pos),
},
{
.binding = 0,
.location = 1,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = offsetof(Vertex, texcoord),
},
{
.binding = 0,
.location = 2,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = offsetof(Vertex, texcoordex),
},
{
.binding = 0,
.location = 3,
.format = VK_FORMAT_R32_SFLOAT,
.offset = offsetof(Vertex, alpha),
},
{
.binding = 0,
.location = 4,
.format = VK_FORMAT_R32_SFLOAT,
.offset = offsetof(Vertex, idx),
}};

VkPipelineVertexInputStateCreateInfo vertexInputInfo{
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.pNext = nullptr,
.vertexBindingDescriptionCount = 1,
.pVertexBindingDescriptions = &vertex_input_bindings,
.vertexAttributeDescriptionCount = 5,
.pVertexAttributeDescriptions = vertex_input_attributes,
};

VkDeviceSize offset = 0;
vkCmdBindVertexBuffers(render.cmdBuffer_[bufferIndex], 0, 1, &buffers.vertexBuf_, &offset);

我该如何解决这个问题?感谢您的帮助。


更新


我通过捕获帧从 Renderdoc 获得一些信息。结果显示顶点着色器没有输出正确的数据。(顶点着色器是通过的。) 但是 Renderdoc 显示顶点缓冲区有正确的数据。 同时,顶点着色器的输出每次运行都会变化,并且永远不会正确。 是同步问题吗?错误可能在哪里。

vertex shader data from Renderdoc

// Draw one frame
bool VulkanDrawFrame(void) {
    uint32_t nextIndex;
    // Get the framebuffer index we should draw in
    CALL_VK(vkAcquireNextImageKHR(device.device_, swapchain.swapchain_,
                                  UINT64_MAX, render.semaphore_, VK_NULL_HANDLE,
                                  &nextIndex));
    CALL_VK(vkResetFences(device.device_, 1, &render.fence_));

    VkPipelineStageFlags waitStageMask =
        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    VkSubmitInfo submit_info = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
                                .pNext = nullptr,
                                .waitSemaphoreCount = 1,
                                .pWaitSemaphores = &render.semaphore_,
                                .pWaitDstStageMask = &waitStageMask,
                                .commandBufferCount = 1,
                                .pCommandBuffers = &render.cmdBuffer_[nextIndex],
                                .signalSemaphoreCount = 0,
                                .pSignalSemaphores = nullptr};
    CALL_VK(vkQueueSubmit(device.queue_, 1, &submit_info, render.fence_));
    CALL_VK(
        vkWaitForFences(device.device_, 1, &render.fence_, VK_TRUE, 100000000));

    LOGI("Drawing frames......");

    VkResult result;
    VkPresentInfoKHR presentInfo{
        .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
        .pNext = nullptr,
        .swapchainCount = 1,
        .pSwapchains = &swapchain.swapchain_,
        .pImageIndices = &nextIndex,
        .waitSemaphoreCount = 0,
        .pWaitSemaphores = nullptr,
        .pResults = &result,
        };
    vkQueuePresentKHR(device.queue_, &presentInfo);
    return true;
}


    // Create the pipeline
    VkGraphicsPipelineCreateInfo pipelineCreateInfo{
        .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
        .pNext = nullptr,
        .flags = 0,
        .stageCount = 2,
        .pStages = shaderStages,
        .pVertexInputState = &vertexInputInfo,
        .pInputAssemblyState = &inputAssemblyInfo,
        .pTessellationState = nullptr,
        .pViewportState = &viewportInfo,
        .pRasterizationState = &rasterInfo,
        .pMultisampleState = &multisampleInfo,
        .pDepthStencilState = nullptr,
        .pColorBlendState = &colorBlendInfo,
        .pDynamicState = &dynamicStateInfo,
        .layout = gfxPipeline.layout_,
        .renderPass = render.renderPass_,
        .subpass = 0,
        .basePipelineHandle = VK_NULL_HANDLE,
        .basePipelineIndex = 0,
    };

  VkResult pipelineResult = vkCreateGraphicsPipelines(
      device.device_, gfxPipeline.cache_, 1, &pipelineCreateInfo, nullptr,
      &gfxPipeline.pipeline_);

【问题讨论】:

  • 通过VK_LAYER_LUNARG_api_dump 层验证 Vulkan 是否看到了您认为它看到的内容。由于您的代码是某种摘录,因此我看不到例如你正确使用vertexInputInfo;它引用的数组的生命周期必须一直延伸到调用vkCreateGPipelines 的点。否则代码对我来说似乎没问题;可能总是同步问题。
  • 感谢您的回答。我更新了问题并提供了更多细节。我通过捕获帧从 Renderdoc 获得了一些信息。结果显示顶点着色器没有输出正确的数据。(顶点着色器是通过的。)但是Renderdoc显示顶点缓冲区有正确的数据。同时,顶点着色器的输出每次运行都会变化,并且永远不会正确。是同步问题吗?错误可能在哪里。
  • 从更新的代码中我仍然看不出这是否是内存问题。你确定VkVertexInputAttributeDescriptions 在调用vkCreateGraphicsPipelines 时没有被销毁吗?
  • 感谢您的帮助,我已经解决了这个问题。驱动程序优化无用的输入。我删除了与它们有关的操作以简化调试,因此驱动程序发现它们无用。
  • 啊,有道理。那么请在这里做一个正式的回答,以便对其他人有用。

标签: glsl shader vulkan


【解决方案1】:

我已经解决了这个问题。 驱动程序优化无用的输入。我删除了与它们有关的操作以简化调试,因此驱动程序发现它们无用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 2017-09-19
    • 2012-06-28
    • 1970-01-01
    • 2017-12-14
    • 2017-05-08
    相关资源
    最近更新 更多