gl::Error RenderbufferVk::onDestroy(const gl::Context *context) { ContextVk *contextVk = vk::GetImpl(context); RendererVk *renderer = contextVk->getRenderer(); renderer->releaseResource(*this, &mImage); renderer->releaseResource(*this, &mDeviceMemory); renderer->releaseResource(*this, &mImageView); return gl::NoError(); }
gl::LinkResult ProgramVk::link(const gl::Context *glContext, const gl::ProgramLinkedResources &resources, gl::InfoLog &infoLog) { ContextVk *contextVk = vk::GetImpl(glContext); RendererVk *renderer = contextVk->getRenderer(); GlslangWrapper *glslangWrapper = renderer->getGlslangWrapper(); VkDevice device = renderer->getDevice(); reset(device); std::vector<uint32_t> vertexCode; std::vector<uint32_t> fragmentCode; bool linkSuccess = false; ANGLE_TRY_RESULT( glslangWrapper->linkProgram(glContext, mState, resources, &vertexCode, &fragmentCode), linkSuccess); if (!linkSuccess) { return false; } { VkShaderModuleCreateInfo vertexShaderInfo; vertexShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; vertexShaderInfo.pNext = nullptr; vertexShaderInfo.flags = 0; vertexShaderInfo.codeSize = vertexCode.size() * sizeof(uint32_t); vertexShaderInfo.pCode = vertexCode.data(); ANGLE_TRY(mLinkedVertexModule.init(device, vertexShaderInfo)); } { VkShaderModuleCreateInfo fragmentShaderInfo; fragmentShaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; fragmentShaderInfo.pNext = nullptr; fragmentShaderInfo.flags = 0; fragmentShaderInfo.codeSize = fragmentCode.size() * sizeof(uint32_t); fragmentShaderInfo.pCode = fragmentCode.data(); ANGLE_TRY(mLinkedFragmentModule.init(device, fragmentShaderInfo)); } ANGLE_TRY(initPipelineLayout(contextVk)); ANGLE_TRY(initDescriptorSets(contextVk)); ANGLE_TRY(initDefaultUniformBlocks(glContext)); return true; }
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; }
gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext) { ContextVk *contextVk = vk::GetImpl(glContext); VkDevice device = contextVk->getDevice(); // Process vertex and fragment uniforms into std140 packing. std::array<sh::BlockLayoutMap, 2> layoutMap; std::array<size_t, 2> requiredBufferSize = {{0, 0}}; for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex) { ANGLE_TRY(InitDefaultUniformBlock(glContext, device, GetShader(mState, shaderIndex), &mDefaultUniformBlocks[shaderIndex].storage, &layoutMap[shaderIndex], &requiredBufferSize[shaderIndex])); } // Init the default block layout info. const auto &locations = mState.getUniformLocations(); const auto &uniforms = mState.getUniforms(); for (size_t locationIndex = 0; locationIndex < locations.size(); ++locationIndex) { std::array<sh::BlockMemberInfo, 2> layoutInfo; const auto &location = locations[locationIndex]; if (location.used() && !location.ignored) { const auto &uniform = uniforms[location.index]; if (uniform.isSampler()) continue; std::string uniformName = uniform.name; if (uniform.isArray()) { uniformName += ArrayString(location.arrayIndex); } bool found = false; for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex) { auto it = layoutMap[shaderIndex].find(uniformName); if (it != layoutMap[shaderIndex].end()) { found = true; layoutInfo[shaderIndex] = it->second; } } ASSERT(found); } for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex) { mDefaultUniformBlocks[shaderIndex].uniformLayout.push_back(layoutInfo[shaderIndex]); } } bool anyDirty = false; bool allDirty = true; for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex) { if (requiredBufferSize[shaderIndex] > 0) { if (!mDefaultUniformBlocks[shaderIndex].uniformData.resize( requiredBufferSize[shaderIndex])) { return gl::OutOfMemory() << "Memory allocation failure."; } mDefaultUniformBlocks[shaderIndex].uniformData.fill(0); mDefaultUniformBlocks[shaderIndex].uniformsDirty = true; anyDirty = true; } else { allDirty = false; } } if (anyDirty) { // Initialize the "empty" uniform block if necessary. if (!allDirty) { VkBufferCreateInfo uniformBufferInfo; uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; uniformBufferInfo.pNext = nullptr; uniformBufferInfo.flags = 0; uniformBufferInfo.size = 1; uniformBufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; uniformBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; uniformBufferInfo.queueFamilyIndexCount = 0; uniformBufferInfo.pQueueFamilyIndices = nullptr; ANGLE_TRY(mEmptyUniformBlockStorage.buffer.init(device, uniformBufferInfo)); size_t requiredSize = 0; ANGLE_TRY(AllocateBufferMemory(contextVk, 1, &mEmptyUniformBlockStorage.buffer, &mEmptyUniformBlockStorage.memory, &requiredSize)); } ANGLE_TRY(updateDefaultUniformsDescriptorSet(contextVk)); } else { // If the program has no uniforms, note this in the offset. mDescriptorSetOffset = 1; } return gl::NoError(); }
gl::Error RenderbufferVk::setStorage(const gl::Context *context, GLenum internalformat, size_t width, size_t height) { ContextVk *contextVk = vk::GetImpl(context); RendererVk *renderer = contextVk->getRenderer(); const vk::Format &vkFormat = renderer->getFormat(internalformat); VkDevice device = renderer->getDevice(); VkImageUsageFlags usage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); VkImageCreateInfo imageInfo; imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageInfo.pNext = nullptr; imageInfo.flags = 0; imageInfo.imageType = VK_IMAGE_TYPE_2D; imageInfo.format = vkFormat.vkTextureFormat; imageInfo.extent.width = static_cast<uint32_t>(width); imageInfo.extent.height = static_cast<uint32_t>(height); imageInfo.extent.depth = 1; imageInfo.mipLevels = 1; imageInfo.arrayLayers = 1; imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL; imageInfo.usage = usage; imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; imageInfo.queueFamilyIndexCount = 0; imageInfo.pQueueFamilyIndices = nullptr; imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; ANGLE_TRY(mImage.init(device, imageInfo)); VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; ANGLE_TRY(vk::AllocateImageMemory(renderer, flags, &mImage, &mDeviceMemory, &mRequiredSize)); VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT; // Allocate ImageView. VkImageViewCreateInfo viewInfo; viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; viewInfo.pNext = nullptr; viewInfo.flags = 0; viewInfo.image = mImage.getHandle(); viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; viewInfo.format = vkFormat.vkTextureFormat; viewInfo.components.r = VK_COMPONENT_SWIZZLE_R; viewInfo.components.g = VK_COMPONENT_SWIZZLE_G; viewInfo.components.b = VK_COMPONENT_SWIZZLE_B; viewInfo.components.a = VK_COMPONENT_SWIZZLE_A; viewInfo.subresourceRange.aspectMask = aspect; viewInfo.subresourceRange.baseMipLevel = 0; viewInfo.subresourceRange.levelCount = 1; viewInfo.subresourceRange.baseArrayLayer = 0; viewInfo.subresourceRange.layerCount = 1; ANGLE_TRY(mImageView.init(device, viewInfo)); // Init RenderTarget. mRenderTarget.extents.width = static_cast<int>(width); mRenderTarget.extents.height = static_cast<int>(height); mRenderTarget.extents.depth = 1; mRenderTarget.format = &vkFormat; mRenderTarget.image = &mImage; mRenderTarget.imageView = &mImageView; mRenderTarget.resource = this; mRenderTarget.samples = VK_SAMPLE_COUNT_1_BIT; // TODO(jmadill): Multisample bits. return gl::NoError(); }