void GrVkRenderTarget::getAttachmentsDescriptor( GrVkRenderPass::AttachmentsDescriptor* desc, GrVkRenderPass::AttachmentFlags* attachmentFlags) const { int colorSamples = this->numColorSamples(); VkFormat colorFormat; GrPixelConfigToVkFormat(this->config(), &colorFormat); desc->fColor.fFormat = colorFormat; desc->fColor.fSamples = colorSamples ? colorSamples : 1; *attachmentFlags = GrVkRenderPass::kColor_AttachmentFlag; uint32_t attachmentCount = 1; if (colorSamples > 0) { desc->fResolve.fFormat = colorFormat; desc->fResolve.fSamples = 1; *attachmentFlags |= GrVkRenderPass::kResolve_AttachmentFlag; ++attachmentCount; } const GrStencilAttachment* stencil = this->renderTargetPriv().getStencilAttachment(); if (stencil) { const GrVkStencilAttachment* vkStencil = static_cast<const GrVkStencilAttachment*>(stencil); desc->fStencil.fFormat = vkStencil->vkFormat(); desc->fStencil.fSamples = vkStencil->numSamples() ? vkStencil->numSamples() : 1; // Currently in vulkan stencil and color attachments must all have same number of samples SkASSERT(desc->fColor.fSamples == desc->fStencil.fSamples); *attachmentFlags |= GrVkRenderPass::kStencil_AttachmentFlag; ++attachmentCount; } desc->fAttachmentCount = attachmentCount; }
bool GrVkTextureRenderTarget::updateForMipmap(GrVkGpu* gpu, const GrVkImageInfo& newInfo) { VkFormat pixelFormat; GrPixelConfigToVkFormat(this->config(), &pixelFormat); if (this->numStencilSamples() > 1) { const GrVkImageView* resolveAttachmentView = GrVkImageView::Create(gpu, newInfo.fImage, pixelFormat, GrVkImageView::kColor_Type, newInfo.fLevelCount); if (!resolveAttachmentView) { return false; } fResolveAttachmentView->unref(gpu); fResolveAttachmentView = resolveAttachmentView; } else { const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, newInfo.fImage, pixelFormat, GrVkImageView::kColor_Type, 1); if (!colorAttachmentView) { return false; } fColorAttachmentView->unref(gpu); fColorAttachmentView = colorAttachmentView; } this->createFramebuffer(gpu); return true; }
void GrVkCaps::initConfigTable(const GrVkInterface* interface, VkPhysicalDevice physDev) { for (int i = 0; i < kGrPixelConfigCnt; ++i) { VkFormat format; if (GrPixelConfigToVkFormat(static_cast<GrPixelConfig>(i), &format)) { fConfigTable[i].init(interface, physDev, format); } } }
GrVkTextureRenderTarget* GrVkTextureRenderTarget::Create(GrVkGpu* gpu, const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle, VkFormat format, const GrVkImage::Resource* imageResource) { VkImage image = imageResource->fImage; // Create the texture ImageView const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, format, GrVkImageView::kColor_Type); if (!imageView) { return nullptr; } VkFormat pixelFormat; GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat); VkImage colorImage; // create msaa surface if necessary const GrVkImage::Resource* msaaImageResource = nullptr; const GrVkImageView* resolveAttachmentView = nullptr; if (desc.fSampleCnt) { GrVkImage::ImageDesc msImageDesc; msImageDesc.fImageType = VK_IMAGE_TYPE_2D; msImageDesc.fFormat = pixelFormat; msImageDesc.fWidth = desc.fWidth; msImageDesc.fHeight = desc.fHeight; msImageDesc.fLevels = 1; msImageDesc.fSamples = desc.fSampleCnt; msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL; msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; msaaImageResource = GrVkImage::CreateResource(gpu, msImageDesc); if (!msaaImageResource) { imageView->unref(gpu); return nullptr; } // Set color attachment image colorImage = msaaImageResource->fImage; // Create resolve attachment view if necessary. // If the format matches, this is the same as the texture imageView. if (pixelFormat == format) { resolveAttachmentView = imageView; resolveAttachmentView->ref(); } else { resolveAttachmentView = GrVkImageView::Create(gpu, image, pixelFormat, GrVkImageView::kColor_Type); if (!resolveAttachmentView) { msaaImageResource->unref(gpu); imageView->unref(gpu); return nullptr; } } } else { // Set color attachment image colorImage = imageResource->fImage; } const GrVkImageView* colorAttachmentView; // Get color attachment view. // If the format matches and there's no multisampling, // this is the same as the texture imageView if (pixelFormat == format && !resolveAttachmentView) { colorAttachmentView = imageView; colorAttachmentView->ref(); } else { colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat, GrVkImageView::kColor_Type); if (!colorAttachmentView) { if (msaaImageResource) { resolveAttachmentView->unref(gpu); msaaImageResource->unref(gpu); } imageView->unref(gpu); return nullptr; } } GrVkTextureRenderTarget* texRT; if (msaaImageResource) { texRT = new GrVkTextureRenderTarget(gpu, desc, lifeCycle, imageResource, imageView, msaaImageResource, colorAttachmentView, resolveAttachmentView); msaaImageResource->unref(gpu); } else { texRT = new GrVkTextureRenderTarget(gpu, desc, lifeCycle, imageResource, imageView, colorAttachmentView); } return texRT; }
GrVkRenderTarget* GrVkRenderTarget::Create(GrVkGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc, const GrVkImageInfo& info, GrBackendObjectOwnership ownership) { SkASSERT(1 == info.fLevelCount); VkFormat pixelFormat; GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat); VkImage colorImage; // create msaa surface if necessary GrVkImageInfo msInfo; const GrVkImageView* resolveAttachmentView = nullptr; if (desc.fSampleCnt > 1) { GrVkImage::ImageDesc msImageDesc; msImageDesc.fImageType = VK_IMAGE_TYPE_2D; msImageDesc.fFormat = pixelFormat; msImageDesc.fWidth = desc.fWidth; msImageDesc.fHeight = desc.fHeight; msImageDesc.fLevels = 1; msImageDesc.fSamples = desc.fSampleCnt; msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL; msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; if (!GrVkImage::InitImageInfo(gpu, msImageDesc, &msInfo)) { return nullptr; } // Set color attachment image colorImage = msInfo.fImage; // Create Resolve attachment view resolveAttachmentView = GrVkImageView::Create(gpu, info.fImage, pixelFormat, GrVkImageView::kColor_Type, 1); if (!resolveAttachmentView) { GrVkImage::DestroyImageInfo(gpu, &msInfo); return nullptr; } } else { // Set color attachment image colorImage = info.fImage; } // Get color attachment view const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat, GrVkImageView::kColor_Type, 1); if (!colorAttachmentView) { if (desc.fSampleCnt > 1) { resolveAttachmentView->unref(gpu); GrVkImage::DestroyImageInfo(gpu, &msInfo); } return nullptr; } GrVkRenderTarget* texRT; if (desc.fSampleCnt > 1) { texRT = new GrVkRenderTarget(gpu, budgeted, desc, info, msInfo, colorAttachmentView, resolveAttachmentView, ownership); } else { texRT = new GrVkRenderTarget(gpu, budgeted, desc, info, colorAttachmentView, ownership); } return texRT; }
sk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::Make(GrVkGpu* gpu, const GrSurfaceDesc& desc, const GrVkImageInfo& info, sk_sp<GrVkImageLayout> layout, GrMipMapsStatus mipMapsStatus, SkBudgeted budgeted, GrBackendObjectOwnership ownership, bool isWrapped) { VkImage image = info.fImage; // Create the texture ImageView const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, info.fFormat, GrVkImageView::kColor_Type, info.fLevelCount); if (!imageView) { return nullptr; } VkFormat pixelFormat; GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat); VkImage colorImage; // create msaa surface if necessary GrVkImageInfo msInfo; sk_sp<GrVkImageLayout> msLayout; const GrVkImageView* resolveAttachmentView = nullptr; if (desc.fSampleCnt > 1) { GrVkImage::ImageDesc msImageDesc; msImageDesc.fImageType = VK_IMAGE_TYPE_2D; msImageDesc.fFormat = pixelFormat; msImageDesc.fWidth = desc.fWidth; msImageDesc.fHeight = desc.fHeight; msImageDesc.fLevels = 1; msImageDesc.fSamples = desc.fSampleCnt; msImageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL; msImageDesc.fUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT; msImageDesc.fMemProps = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; if (!GrVkImage::InitImageInfo(gpu, msImageDesc, &msInfo)) { imageView->unref(gpu); return nullptr; } // Set color attachment image colorImage = msInfo.fImage; // Create resolve attachment view. resolveAttachmentView = GrVkImageView::Create(gpu, image, pixelFormat, GrVkImageView::kColor_Type, info.fLevelCount); if (!resolveAttachmentView) { GrVkImage::DestroyImageInfo(gpu, &msInfo); imageView->unref(gpu); return nullptr; } msLayout.reset(new GrVkImageLayout(msInfo.fImageLayout)); } else { // Set color attachment image colorImage = info.fImage; } const GrVkImageView* colorAttachmentView = GrVkImageView::Create(gpu, colorImage, pixelFormat, GrVkImageView::kColor_Type, 1); if (!colorAttachmentView) { if (desc.fSampleCnt > 1) { resolveAttachmentView->unref(gpu); GrVkImage::DestroyImageInfo(gpu, &msInfo); } imageView->unref(gpu); return nullptr; } sk_sp<GrVkTextureRenderTarget> texRT; if (desc.fSampleCnt > 1) { if (!isWrapped) { texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget( gpu, budgeted, desc, info, std::move(layout), imageView, msInfo, std::move(msLayout), colorAttachmentView, resolveAttachmentView, mipMapsStatus, ownership)); } else { texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget( gpu, desc, info, std::move(layout), imageView, msInfo, std::move(msLayout), colorAttachmentView, resolveAttachmentView, mipMapsStatus, ownership)); } } else { if (!isWrapped) { texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget( gpu, budgeted, desc, info, std::move(layout), imageView, colorAttachmentView, mipMapsStatus, ownership)); } else { texRT = sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget( gpu, desc, info, std::move(layout), imageView, colorAttachmentView, mipMapsStatus, ownership)); } } return texRT; }