* Copyright 2022 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/core/SkAlphaType.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTypes.h"
#include "include/gpu/ganesh/GrDirectContext.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "include/gpu/ganesh/vk/GrVkDirectContext.h"
#include "include/gpu/vk/VulkanBackendContext.h"
#include "include/gpu/vk/VulkanExtensions.h"
#include "include/gpu/vk/VulkanMemoryAllocator.h"
#include "src/gpu/vk/vulkanmemoryallocator/VulkanMemoryAllocatorPriv.h"
#include "src/gpu/GpuTypesPriv.h"
#include "tools/gpu/vk/VkTestUtils.h"
#include <string.h>
#include <vulkan/vulkan_core.h>
#include <functional>
#include <memory>
#define ACQUIRE_INST_VK_PROC(name) \
do { \
fVk##name = reinterpret_cast<PFN_vk##name>(getProc("vk" #name, backendContext.fInstance, \
VK_NULL_HANDLE)); \
if (fVk##name == nullptr) { \
SkDebugf("Function ptr for vk%s could not be acquired\n", #name); \
return 1; \
} \
} while(false)
int main(int argc, char** argv) {
skgpu::VulkanBackendContext backendContext;
VkDebugReportCallbackEXT debugCallback;
std::unique_ptr<skgpu::VulkanExtensions> extensions(new skgpu::VulkanExtensions());
std::unique_ptr<VkPhysicalDeviceFeatures2> features(new VkPhysicalDeviceFeatures2);
{
PFN_vkGetInstanceProcAddr instProc;
if (!sk_gpu_test::LoadVkLibraryAndGetProcAddrFuncs(&instProc)) {
return 1;
}
memset(features.get(), 0, sizeof(VkPhysicalDeviceFeatures2));
features->sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
features->pNext = nullptr;
backendContext.fInstance = VK_NULL_HANDLE;
backendContext.fDevice = VK_NULL_HANDLE;
if (!sk_gpu_test::CreateVkBackendContext(instProc, &backendContext, extensions.get(),
features.get(), &debugCallback)) {
return 1;
}
}
auto getProc = backendContext.fGetProc;
PFN_vkDestroyInstance fVkDestroyInstance;
PFN_vkDestroyDebugReportCallbackEXT fVkDestroyDebugReportCallbackEXT = nullptr;
PFN_vkDestroyDevice fVkDestroyDevice;
ACQUIRE_INST_VK_PROC(DestroyInstance);
if (debugCallback != VK_NULL_HANDLE) {
ACQUIRE_INST_VK_PROC(DestroyDebugReportCallbackEXT);
}
ACQUIRE_INST_VK_PROC(DestroyDevice);
backendContext.fMemoryAllocator = skgpu::VulkanMemoryAllocators::Make(
backendContext, skgpu::ThreadSafe::kNo, std::nullopt);
sk_sp<GrDirectContext> context = GrDirectContexts::MakeVulkan(backendContext);
if (!context) {
fVkDestroyDevice(backendContext.fDevice, nullptr);
if (debugCallback != VK_NULL_HANDLE) {
fVkDestroyDebugReportCallbackEXT(backendContext.fInstance, debugCallback, nullptr);
}
fVkDestroyInstance(backendContext.fInstance, nullptr);
return 1;
}
SkImageInfo imageInfo = SkImageInfo::Make(16, 16, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
sk_sp<SkSurface> surface =
SkSurfaces::RenderTarget(context.get(), skgpu::Budgeted::kYes, imageInfo);
if (!surface) {
context.reset();
fVkDestroyDevice(backendContext.fDevice, nullptr);
if (debugCallback != VK_NULL_HANDLE) {
fVkDestroyDebugReportCallbackEXT(backendContext.fInstance, debugCallback, nullptr);
} fVkDestroyInstance(backendContext.fInstance, nullptr);
return 1;
}
surface->getCanvas()->clear(SK_ColorRED);
context->flush(surface.get());
context->submit();
surface.reset();
context.reset();
fVkDestroyDevice(backendContext.fDevice, nullptr);
if (debugCallback != VK_NULL_HANDLE) {
fVkDestroyDebugReportCallbackEXT(backendContext.fInstance, debugCallback, nullptr);
} fVkDestroyInstance(backendContext.fInstance, nullptr);
return 0;
}