1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2020 Google LLC 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkImage.h" 9cb93a386Sopenharmony_ci#include "include/gpu/GrBackendSurface.h" 10cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 11cb93a386Sopenharmony_ci#include "include/gpu/vk/GrVkTypes.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h" 14cb93a386Sopenharmony_ci#include "src/gpu/GrTextureProxy.h" 15cb93a386Sopenharmony_ci#include "src/image/SkImage_Base.h" 16cb93a386Sopenharmony_ci#include "tests/Test.h" 17cb93a386Sopenharmony_ci#include "tools/gpu/ProxyUtils.h" 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci#ifdef SK_VULKAN 20cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkGpu.h" 21cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkTexture.h" 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_VULKAN_CONTEXT(VkBackendSurfaceMutableStateTest, reporter, ctxInfo) { 24cb93a386Sopenharmony_ci auto dContext = ctxInfo.directContext(); 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ci GrBackendFormat format = GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8A8_UNORM); 27cb93a386Sopenharmony_ci GrBackendTexture backendTex = dContext->createBackendTexture( 28cb93a386Sopenharmony_ci 32, 32, format, GrMipmapped::kNo, GrRenderable::kNo, GrProtected::kNo); 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTex.isValid()); 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci GrVkImageInfo info; 33cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); 34cb93a386Sopenharmony_ci VkImageLayout initLayout = info.fImageLayout; 35cb93a386Sopenharmony_ci uint32_t initQueue = info.fCurrentQueueFamily; 36cb93a386Sopenharmony_ci GrBackendSurfaceMutableState initState(initLayout, initQueue); 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ci // Verify that setting that state via a copy of a backendTexture is reflected in all the 39cb93a386Sopenharmony_ci // backendTextures. 40cb93a386Sopenharmony_ci GrBackendTexture backendTexCopy = backendTex; 41cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTexCopy.getVkImageInfo(&info)); 42cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, initLayout == info.fImageLayout); 43cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, initQueue == info.fCurrentQueueFamily); 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ci GrBackendSurfaceMutableState newState(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 46cb93a386Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED); 47cb93a386Sopenharmony_ci backendTexCopy.setMutableState(newState); 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); 50cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == info.fImageLayout); 51cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, VK_QUEUE_FAMILY_IGNORED == info.fCurrentQueueFamily); 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTexCopy.getVkImageInfo(&info)); 54cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == info.fImageLayout); 55cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, VK_QUEUE_FAMILY_IGNORED == info.fCurrentQueueFamily); 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_ci // Setting back to the init state since we didn't actually change it 58cb93a386Sopenharmony_ci backendTex.setMutableState(initState); 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_ci sk_sp<SkImage> wrappedImage = SkImage::MakeFromTexture(dContext, backendTex, 61cb93a386Sopenharmony_ci kTopLeft_GrSurfaceOrigin, 62cb93a386Sopenharmony_ci kRGBA_8888_SkColorType, 63cb93a386Sopenharmony_ci kPremul_SkAlphaType, nullptr); 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci GrSurfaceProxy* proxy = sk_gpu_test::GetTextureImageProxy(wrappedImage.get(), dContext); 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, proxy); 68cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, proxy->isInstantiated()); 69cb93a386Sopenharmony_ci GrTexture* texture = proxy->peekTexture(); 70cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, texture); 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_ci // Verify that modifying the layout via the GrVkTexture is reflected in the GrBackendTexture 73cb93a386Sopenharmony_ci GrVkImage* vkTexture = static_cast<GrVkTexture*>(texture)->textureImage(); 74cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, initLayout == vkTexture->currentLayout()); 75cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, initQueue == vkTexture->currentQueueFamilyIndex()); 76cb93a386Sopenharmony_ci vkTexture->updateImageLayout(VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); 79cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == info.fImageLayout); 80cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, initQueue == info.fCurrentQueueFamily); 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci GrBackendTexture backendTexImage = wrappedImage->getBackendTexture(false); 83cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTexImage.getVkImageInfo(&info)); 84cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == info.fImageLayout); 85cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, initQueue == info.fCurrentQueueFamily); 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_ci // Verify that modifying the layout via the GrBackendTexutre is reflected in the GrVkTexture 88cb93a386Sopenharmony_ci backendTexImage.setMutableState(newState); 89cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 90cb93a386Sopenharmony_ci VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == vkTexture->currentLayout()); 91cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, VK_QUEUE_FAMILY_IGNORED == info.fCurrentQueueFamily); 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ci vkTexture->setQueueFamilyIndex(initQueue); 94cb93a386Sopenharmony_ci vkTexture->updateImageLayout(initLayout); 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); 97cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, initLayout == info.fImageLayout); 98cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, initQueue == info.fCurrentQueueFamily); 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTexCopy.getVkImageInfo(&info)); 101cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, initLayout == info.fImageLayout); 102cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, initQueue == info.fCurrentQueueFamily); 103cb93a386Sopenharmony_ci 104cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTexImage.getVkImageInfo(&info)); 105cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, initLayout == info.fImageLayout); 106cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, initQueue == info.fCurrentQueueFamily); 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_ci // Test using the setBackendTextureStateAPI. Unlike the previous test this will actually add 109cb93a386Sopenharmony_ci // real transitions to the image so we need to be careful about doing actual valid transitions. 110cb93a386Sopenharmony_ci GrVkGpu* gpu = static_cast<GrVkGpu*>(dContext->priv().getGpu()); 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci GrBackendSurfaceMutableState previousState; 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci dContext->setBackendTextureState(backendTex, newState, &previousState); 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); 117cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == info.fImageLayout); 118cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, gpu->queueIndex() == info.fCurrentQueueFamily); 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, previousState.isValid()); 121cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, previousState.backend() == GrBackendApi::kVulkan); 122cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, previousState.getVkImageLayout() == initLayout); 123cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, previousState.getQueueFamilyIndex() == initQueue); 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_ci // Make sure passing in VK_IMAGE_LAYOUT_UNDEFINED does not change the layout 126cb93a386Sopenharmony_ci GrBackendSurfaceMutableState noopState(VK_IMAGE_LAYOUT_UNDEFINED, VK_QUEUE_FAMILY_IGNORED); 127cb93a386Sopenharmony_ci dContext->setBackendTextureState(backendTex, noopState, &previousState); 128cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); 129cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == info.fImageLayout); 130cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, gpu->queueIndex() == info.fCurrentQueueFamily); 131cb93a386Sopenharmony_ci 132cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, previousState.isValid()); 133cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, previousState.backend() == GrBackendApi::kVulkan); 134cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 135cb93a386Sopenharmony_ci previousState.getVkImageLayout() == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 136cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, previousState.getQueueFamilyIndex() == gpu->queueIndex()); 137cb93a386Sopenharmony_ci 138cb93a386Sopenharmony_ci // To test queue transitions, we don't have any other valid queue available so instead we try 139cb93a386Sopenharmony_ci // to transition to external queue. 140cb93a386Sopenharmony_ci if (gpu->vkCaps().supportsExternalMemory()) { 141cb93a386Sopenharmony_ci GrBackendSurfaceMutableState externalState(VK_IMAGE_LAYOUT_GENERAL, 142cb93a386Sopenharmony_ci VK_QUEUE_FAMILY_EXTERNAL); 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_ci dContext->setBackendTextureState(backendTex, externalState, &previousState); 145cb93a386Sopenharmony_ci 146cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); 147cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_GENERAL == info.fImageLayout); 148cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, VK_QUEUE_FAMILY_EXTERNAL == info.fCurrentQueueFamily); 149cb93a386Sopenharmony_ci 150cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, previousState.isValid()); 151cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, previousState.backend() == GrBackendApi::kVulkan); 152cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, 153cb93a386Sopenharmony_ci previousState.getVkImageLayout() == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 154cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, previousState.getQueueFamilyIndex() == gpu->queueIndex()); 155cb93a386Sopenharmony_ci 156cb93a386Sopenharmony_ci dContext->submit(); 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_ci // Go back to the initial queue. Also we should stay in VK_IMAGE_LAYOUT_GENERAL since we 159cb93a386Sopenharmony_ci // are passing in VK_IMAGE_LAYOUT_UNDEFINED 160cb93a386Sopenharmony_ci GrBackendSurfaceMutableState externalState2(VK_IMAGE_LAYOUT_UNDEFINED, initQueue); 161cb93a386Sopenharmony_ci dContext->setBackendTextureState(backendTex, externalState2, &previousState); 162cb93a386Sopenharmony_ci 163cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, backendTex.getVkImageInfo(&info)); 164cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, VK_IMAGE_LAYOUT_GENERAL == info.fImageLayout); 165cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, gpu->queueIndex() == info.fCurrentQueueFamily); 166cb93a386Sopenharmony_ci 167cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, previousState.isValid()); 168cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, previousState.backend() == GrBackendApi::kVulkan); 169cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, previousState.getVkImageLayout() == VK_IMAGE_LAYOUT_GENERAL); 170cb93a386Sopenharmony_ci REPORTER_ASSERT(reporter, previousState.getQueueFamilyIndex() == VK_QUEUE_FAMILY_EXTERNAL); 171cb93a386Sopenharmony_ci } 172cb93a386Sopenharmony_ci 173cb93a386Sopenharmony_ci // We must submit this work before we try to delete the backend texture. 174cb93a386Sopenharmony_ci dContext->submit(true); 175cb93a386Sopenharmony_ci 176cb93a386Sopenharmony_ci dContext->deleteBackendTexture(backendTex); 177cb93a386Sopenharmony_ci} 178cb93a386Sopenharmony_ci 179cb93a386Sopenharmony_ci#endif 180