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; }
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(); }
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; }