使用Vulkan在Android上安装MSAA的黑屏

时间:2017-10-26 17:48:27

标签: android vulkan

我在Android上安装MSAA时遇到问题。在任何经测试的台式机上(英特尔,NVIDIA),我得到一个正确的解析帧缓冲和渲染通道(我目前有一个空的渲染通道,我只清除背面颜色),屏幕渲染只是灰色(所需)但在Android上屏幕是黑色的。

我没有得到任何验证错误。代码只是"工作"但这对我来说似乎不对。

这是我的Renderpass代码:

VkSampleCountFlagBits sampleCount = GetMaxUsableSampleCount();

VkAttachmentDescription colorResolveAttachment = {};
colorResolveAttachment.format = mSwapchainImageFormat;
colorResolveAttachment.samples = sampleCount;
colorResolveAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
colorResolveAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorResolveAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorResolveAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorResolveAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
colorResolveAttachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

VkAttachmentDescription colorAttachment = {};
colorAttachment.format = mSwapchainImageFormat;
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
colorAttachment.loadOp = (mSamples != 0) ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_CLEAR;
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;

VkAttachmentDescription depthResolveAttachment = {};
depthResolveAttachment.format = mDepthImageFormat;
depthResolveAttachment.samples = sampleCount;
depthResolveAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
depthResolveAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depthResolveAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
depthResolveAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depthResolveAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
depthResolveAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

VkAttachmentDescription depthAttachment = {};
depthAttachment.format = mDepthImageFormat;
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
depthAttachment.loadOp = (mSamples != 0) ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_CLEAR;
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depthAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

VkAttachmentReference colorAttachmentRef = {};
colorAttachmentRef.attachment = 0;
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

VkAttachmentReference depthAttachmentRef = {};
depthAttachmentRef.attachment = (mSamples != 0) ? 2 : 1;
depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

VkAttachmentReference colorAttachmentResolveRef = {};
colorAttachmentResolveRef.attachment = 1;
colorAttachmentResolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

VkSubpassDescription subpass = {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachmentRef;
subpass.pDepthStencilAttachment = &depthAttachmentRef;
if(mSamples != 0)
{
    subpass.pResolveAttachments = &colorAttachmentResolveRef;
}

std::vector<VkSubpassDependency> dependencies;

if(mSamples != 0)
{
    std::array<VkSubpassDependency, 2> dependency;

    dependency[0].srcSubpass = VK_SUBPASS_EXTERNAL;
    dependency[0].dstSubpass = 0;
    dependency[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
    dependency[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    dependency[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
    dependency[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    dependency[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

    dependency[1].srcSubpass = 0;
    dependency[1].dstSubpass = VK_SUBPASS_EXTERNAL;
    dependency[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    dependency[1].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
    dependency[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
    dependency[1].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
    dependency[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;

    dependencies.push_back(dependency[0]);
    dependencies.push_back(dependency[1]);
}
else
{
    VkSubpassDependency dependency = {};
    dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
    dependency.dstSubpass = 0;
    dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    dependency.srcAccessMask = 0;
    dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
    dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;

    dependencies.push_back(dependency);
}

std::vector<VkAttachmentDescription> attachments;

if(mSamples != 0)
{
    attachments.push_back(colorResolveAttachment);
    attachments.push_back(colorAttachment);
    attachments.push_back(depthResolveAttachment);
    attachments.push_back(depthAttachment);
}
else
{
    attachments.push_back(colorAttachment);
    attachments.push_back(depthAttachment);
}

VkRenderPassCreateInfo renderPassInfo = {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
renderPassInfo.pAttachments = attachments.data();
renderPassInfo.subpassCount = 1;
renderPassInfo.pSubpasses = &subpass;
renderPassInfo.dependencyCount = static_cast<uint32_t>(dependencies.size());
renderPassInfo.pDependencies = dependencies.data();

if(vkCreateRenderPass(mDevice, &renderPassInfo, nullptr, &mRenderPass) != VK_SUCCESS)
{
    Console::FatalError("Failed to create render pass!");
    return false;
}

return true;

这是我的Freambuffer代码:

if(!CreateMultiSampleTargets())
    return false;

mSwapchainFramebuffers.resize(mSwapchainImageViews.size());

for(size_t i = 0u; i < mSwapchainImageViews.size(); i++)
{
    std::vector<VkImageView> attachments;

    if(mSamples != 0)
    {
        attachments.push_back(mMultiSampleColorImageView);
        attachments.push_back(mSwapchainImageViews[i]);
        attachments.push_back(mMultiSampleDepthImageView);
        attachments.push_back(mDepthImageView);
    }
    else
    {
        attachments.push_back(mSwapchainImageViews[i]);
        attachments.push_back(mDepthImageView);
    }

    VkFramebufferCreateInfo framebufferInfo = {};
    framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
    framebufferInfo.renderPass = mRenderPass;
    framebufferInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
    framebufferInfo.pAttachments = attachments.data();
    framebufferInfo.width = mSwapchainExtent.width;
    framebufferInfo.height = mSwapchainExtent.height;
    framebufferInfo.layers = 1;

    if(vkCreateFramebuffer(mDevice, &framebufferInfo, nullptr, &mSwapchainFramebuffers[i]) != VK_SUCCESS)
    {
        Console::FatalError("Failed to create framebuffer!");
        return false;
    }
}

我应该提一下,我的代码很大程度上基于:https://github.com/SaschaWillems/Vulkan/blob/master/multisampling/multisampling.cpp

1 个答案:

答案 0 :(得分:0)

解决方案是将我的Oneplus 3升级到android 8以获得更新的驱动程序版本,但不会发生此问题。我想这是一个驱动程序错误。