Esempio n. 1
0
angle::Result ImageVk::orphan(const gl::Context *context, egl::ImageSibling *sibling)
{
    if (sibling == mState.source)
    {
        if (egl::IsTextureTarget(mState.target))
        {
            TextureVk *textureVk = GetImplAs<TextureVk>(GetAs<gl::Texture>(mState.source));
            ASSERT(mImage == &textureVk->getImage());
            textureVk->releaseOwnershipOfImage(context);
            mOwnsImage = true;
        }
        else if (egl::IsRenderbufferTarget(mState.target))
        {
            RenderbufferVk *renderbufferVk =
                GetImplAs<RenderbufferVk>(GetAs<gl::Renderbuffer>(mState.source));
            ASSERT(mImage == renderbufferVk->getImage());
            renderbufferVk->releaseOwnershipOfImage(context);
            mOwnsImage = true;
        }
        else
        {
            ANGLE_VK_UNREACHABLE(vk::GetImpl(context));
            return angle::Result::Stop;
        }
    }

    // Grab a fence from the releasing context to know when the image is no longer used
    ASSERT(mContext != nullptr);
    ContextVk *contextVk = vk::GetImpl(mContext);

    // Flush the context to make sure the fence has been submitted.
    ANGLE_TRY(contextVk->flushImpl(nullptr));

    vk::Shared<vk::Fence> fence = contextVk->getLastSubmittedFence();
    if (fence.isReferenced())
    {
        mImageLastUseFences.push_back(std::move(fence));
    }

    return angle::Result::Continue;
}
Esempio n. 2
0
egl::Error ImageVk::initialize(const egl::Display *display)
{
    if (egl::IsTextureTarget(mState.target))
    {
        TextureVk *textureVk = GetImplAs<TextureVk>(GetAs<gl::Texture>(mState.source));

        // Make sure the texture has created its backing storage
        ASSERT(mContext != nullptr);
        ContextVk *contextVk = vk::GetImpl(mContext);
        ANGLE_TRY(ResultToEGL(textureVk->ensureImageInitialized(contextVk)));

        mImage = &textureVk->getImage();

        // The staging buffer for a texture source should already be initialized

        mOwnsImage = false;

        mImageTextureType = mState.imageIndex.getType();
        mImageLevel       = mState.imageIndex.getLevelIndex();
        mImageLayer       = mState.imageIndex.hasLayer() ? mState.imageIndex.getLayerIndex() : 0;
    }
    else
    {
        RendererVk *renderer = nullptr;
        if (egl::IsRenderbufferTarget(mState.target))
        {
            RenderbufferVk *renderbufferVk =
                GetImplAs<RenderbufferVk>(GetAs<gl::Renderbuffer>(mState.source));
            mImage = renderbufferVk->getImage();

            ASSERT(mContext != nullptr);
            renderer = vk::GetImpl(mContext)->getRenderer();
            ;
        }
        else if (egl::IsExternalImageTarget(mState.target))
        {
            const ExternalImageSiblingVk *externalImageSibling =
                GetImplAs<ExternalImageSiblingVk>(GetAs<egl::ExternalImageSibling>(mState.source));
            mImage = externalImageSibling->getImage();

            ASSERT(mContext == nullptr);
            renderer = vk::GetImpl(display)->getRenderer();
        }
        else
        {
            UNREACHABLE();
            return egl::EglBadAccess();
        }

        // Make sure a staging buffer is ready to use to upload data
        mImage->initStagingBuffer(renderer, mImage->getFormat());

        mOwnsImage = false;

        mImageTextureType = gl::TextureType::_2D;
        mImageLevel       = 0;
        mImageLayer       = 0;
    }

    return egl::NoError();
}
Esempio n. 3
0
void ProgramVk::updateTexturesDescriptorSet(ContextVk *contextVk)
{
    if (mState.getSamplerBindings().empty() || !mDirtyTextures)
    {
        return;
    }

    VkDescriptorSet descriptorSet = mDescriptorSets.back();

    // TODO(jmadill): Don't hard-code the texture limit.
    ShaderTextureArray<VkDescriptorImageInfo> descriptorImageInfo;
    ShaderTextureArray<VkWriteDescriptorSet> writeDescriptorInfo;
    uint32_t imageCount = 0;

    const gl::State &glState     = contextVk->getGLState();
    const auto &completeTextures = glState.getCompleteTextureCache();

    for (const auto &samplerBinding : mState.getSamplerBindings())
    {
        ASSERT(!samplerBinding.unreferenced);

        // TODO(jmadill): Sampler arrays
        ASSERT(samplerBinding.boundTextureUnits.size() == 1);

        GLuint textureUnit         = samplerBinding.boundTextureUnits[0];
        const gl::Texture *texture = completeTextures[textureUnit];

        // TODO(jmadill): Incomplete textures handling.
        ASSERT(texture);

        TextureVk *textureVk   = vk::GetImpl(texture);
        const vk::Image &image = textureVk->getImage();

        VkDescriptorImageInfo &imageInfo = descriptorImageInfo[imageCount];

        imageInfo.sampler     = textureVk->getSampler().getHandle();
        imageInfo.imageView   = textureVk->getImageView().getHandle();
        imageInfo.imageLayout = image.getCurrentLayout();

        auto &writeInfo = writeDescriptorInfo[imageCount];

        writeInfo.sType            = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
        writeInfo.pNext            = nullptr;
        writeInfo.dstSet           = descriptorSet;
        writeInfo.dstBinding       = imageCount;
        writeInfo.dstArrayElement  = 0;
        writeInfo.descriptorCount  = 1;
        writeInfo.descriptorType   = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
        writeInfo.pImageInfo       = &imageInfo;
        writeInfo.pBufferInfo      = nullptr;
        writeInfo.pTexelBufferView = nullptr;

        imageCount++;
    }

    VkDevice device = contextVk->getDevice();

    ASSERT(imageCount > 0);
    vkUpdateDescriptorSets(device, imageCount, writeDescriptorInfo.data(), 0, nullptr);

    mDirtyTextures = false;
}