void GrVkProgram::writeSamplers(const GrVkGpu* gpu, const SkTArray<const GrTextureAccess*>& textureBindings) { SkASSERT(fNumSamplers == textureBindings.count()); for (int i = 0; i < textureBindings.count(); ++i) { fSamplers.push(GrVkSampler::Create(gpu, *textureBindings[i])); GrVkTexture* texture = static_cast<GrVkTexture*>(textureBindings[i]->getTexture()); const GrVkImage::Resource* textureResource = texture->resource(); textureResource->ref(); fTextures.push(textureResource); const GrVkImageView* textureView = texture->textureView(); textureView->ref(); fTextureViews.push(textureView); // Change texture layout so it can be read in shader VkImageLayout layout = texture->currentLayout(); VkPipelineStageFlags srcStageMask = GrVkMemory::LayoutToPipelineStageFlags(layout); VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT; VkAccessFlags srcAccessMask = GrVkMemory::LayoutToSrcAccessMask(layout); VkAccessFlags dstAccessMask = VK_ACCESS_SHADER_READ_BIT; texture->setImageLayout(gpu, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, srcAccessMask, dstAccessMask, srcStageMask, dstStageMask, false); VkDescriptorImageInfo imageInfo; memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo)); imageInfo.sampler = fSamplers[i]->sampler(); imageInfo.imageView = texture->textureView()->imageView(); imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; VkWriteDescriptorSet writeInfo; memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet)); writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writeInfo.pNext = nullptr; writeInfo.dstSet = fDescriptorSets[GrVkUniformHandler::kSamplerDescSet]; writeInfo.dstBinding = i; writeInfo.dstArrayElement = 0; writeInfo.descriptorCount = 1; writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; writeInfo.pImageInfo = &imageInfo; writeInfo.pBufferInfo = nullptr; writeInfo.pTexelBufferView = nullptr; GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(), 1, &writeInfo, 0, nullptr)); } }
DEF_GPUTEST_FOR_VULKAN_CONTEXT(VkImageLayoutTest, reporter, ctxInfo) { GrContext* context = ctxInfo.grContext(); GrVkGpu* gpu = static_cast<GrVkGpu*>(context->contextPriv().getGpu()); GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(nullptr, 1, 1, kRGBA_8888_GrPixelConfig, false, GrMipMapped::kNo); REPORTER_ASSERT(reporter, backendTex.isValid()); GrVkImageInfo info; REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); VkImageLayout initLayout = info.fImageLayout; // Verify that setting that layout via a copy of a backendTexture is reflected in all the // backendTextures. GrBackendTexture backendTexCopy = backendTex; REPORTER_ASSERT(reporter, backendTexCopy.getVkImageInfo(&info)); REPORTER_ASSERT(reporter, initLayout == info.fImageLayout); backendTexCopy.setVkImageLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == info.fImageLayout); REPORTER_ASSERT(reporter, backendTexCopy.getVkImageInfo(&info)); REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == info.fImageLayout); // Setting back the layout since we didn't actually change it backendTex.setVkImageLayout(initLayout); sk_sp<SkImage> wrappedImage = SkImage::MakeFromTexture(context, backendTex, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr); REPORTER_ASSERT(reporter, wrappedImage.get()); sk_sp<GrTextureProxy> texProxy = as_IB(wrappedImage)->asTextureProxyRef(); REPORTER_ASSERT(reporter, texProxy.get()); REPORTER_ASSERT(reporter, texProxy->priv().isInstantiated()); GrTexture* texture = texProxy->priv().peekTexture(); REPORTER_ASSERT(reporter, texture); // Verify that modifying the layout via the GrVkTexture is reflected in the GrBackendTexture GrVkTexture* vkTexture = static_cast<GrVkTexture*>(texture); REPORTER_ASSERT(reporter, initLayout == vkTexture->currentLayout()); vkTexture->updateImageLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == info.fImageLayout); GrBackendTexture backendTexImage = wrappedImage->getBackendTexture(false); REPORTER_ASSERT(reporter, backendTexImage.getVkImageInfo(&info)); REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == info.fImageLayout); // Verify that modifying the layout via the GrBackendTexutre is reflected in the GrVkTexture backendTexImage.setVkImageLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == vkTexture->currentLayout()); #ifdef SK_SUPPORT_LEGACY_BACKEND_OBJECTS // Verify that modifying the layout via the old textureHandle sitll works in is reflected in the // GrVkTexture and GrBackendTexture. GrVkImageInfo* backendInfo = (GrVkImageInfo*)wrappedImage->getTextureHandle(false); REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == backendInfo->fImageLayout); backendInfo->updateImageLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL); REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == vkTexture->currentLayout()); REPORTER_ASSERT(reporter, backendTexImage.getVkImageInfo(&info)); REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == info.fImageLayout); #endif vkTexture->updateImageLayout(initLayout); REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); REPORTER_ASSERT(reporter, initLayout == info.fImageLayout); REPORTER_ASSERT(reporter, backendTexCopy.getVkImageInfo(&info)); REPORTER_ASSERT(reporter, initLayout == info.fImageLayout); REPORTER_ASSERT(reporter, backendTexImage.getVkImageInfo(&info)); REPORTER_ASSERT(reporter, initLayout == info.fImageLayout); // Check that we can do things like assigning the backend texture to invalid one, assign an // invalid one, assin a backend texture to inself etc. Success here is that we don't hit any of // our ref counting asserts. REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(backendTex, backendTexCopy)); GrBackendTexture invalidTexture; REPORTER_ASSERT(reporter, !invalidTexture.isValid()); REPORTER_ASSERT(reporter, !GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTexCopy)); backendTexCopy = invalidTexture; REPORTER_ASSERT(reporter, !backendTexCopy.isValid()); REPORTER_ASSERT(reporter, !GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTexCopy)); invalidTexture = backendTex; REPORTER_ASSERT(reporter, invalidTexture.isValid()); REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(invalidTexture, backendTex)); invalidTexture = static_cast<decltype(invalidTexture)&>(invalidTexture); REPORTER_ASSERT(reporter, invalidTexture.isValid()); REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(invalidTexture, invalidTexture)); gpu->deleteTestingOnlyBackendTexture(backendTex); }