| Index: src/gpu/vk/GrVkGpu.cpp
|
| diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
|
| index 926e423b6e3016b13fa999b100520e0abcb398bf..f01c2e45e51bd22d27e5992172e788f1a657357c 100644
|
| --- a/src/gpu/vk/GrVkGpu.cpp
|
| +++ b/src/gpu/vk/GrVkGpu.cpp
|
| @@ -40,10 +40,6 @@
|
| #define VK_CALL_RET(RET, X) GR_VK_CALL_RET(this->vkInterface(), RET, X)
|
| #define VK_CALL_ERRCHECK(X) GR_VK_CALL_ERRCHECK(this->vkInterface(), X)
|
|
|
| -////////////////////////////////////////////////////////////////////////////////
|
| -// Stuff used to set up a GrVkGpu secrectly for now.
|
| -
|
| -
|
| #ifdef ENABLE_VK_LAYERS
|
| VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(
|
| VkDebugReportFlagsEXT flags,
|
| @@ -65,272 +61,37 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(
|
| }
|
| return VK_FALSE;
|
| }
|
| -
|
| -const char* kEnabledLayerNames[] = {
|
| - // elements of VK_LAYER_LUNARG_standard_validation
|
| - "VK_LAYER_LUNARG_threading",
|
| - "VK_LAYER_LUNARG_param_checker",
|
| - "VK_LAYER_LUNARG_device_limits",
|
| - "VK_LAYER_LUNARG_object_tracker",
|
| - "VK_LAYER_LUNARG_image",
|
| - "VK_LAYER_LUNARG_mem_tracker",
|
| - "VK_LAYER_LUNARG_draw_state",
|
| - "VK_LAYER_LUNARG_swapchain",
|
| - "VK_LAYER_GOOGLE_unique_objects",
|
| - // not included in standard_validation
|
| - //"VK_LAYER_LUNARG_api_dump",
|
| -};
|
| -const char* kEnabledInstanceExtensionNames[] = {
|
| - VK_EXT_DEBUG_REPORT_EXTENSION_NAME
|
| -};
|
| -
|
| -bool verify_instance_layers() {
|
| - // make sure we can actually use the extensions and layers above
|
| - uint32_t extensionCount;
|
| - VkResult res = vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
|
| - if (VK_SUCCESS != res) {
|
| - return false;
|
| - }
|
| - VkExtensionProperties* extensions = new VkExtensionProperties[extensionCount];
|
| - res = vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions);
|
| - if (VK_SUCCESS != res) {
|
| - return false;
|
| - }
|
| - int instanceExtensionsFound = 0;
|
| - for (uint32_t j = 0; j < ARRAYSIZE(kEnabledInstanceExtensionNames); ++j) {
|
| - for (uint32_t i = 0; i < extensionCount; ++i) {
|
| - if (!strncmp(extensions[i].extensionName, kEnabledInstanceExtensionNames[j],
|
| - strlen(kEnabledInstanceExtensionNames[j]))) {
|
| - ++instanceExtensionsFound;
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - delete[] extensions;
|
| -
|
| - uint32_t layerCount;
|
| - res = vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
|
| - if (VK_SUCCESS != res) {
|
| - return false;
|
| - }
|
| - VkLayerProperties* layers = new VkLayerProperties[layerCount];
|
| - res = vkEnumerateInstanceLayerProperties(&layerCount, layers);
|
| - if (VK_SUCCESS != res) {
|
| - return false;
|
| - }
|
| - int instanceLayersFound = 0;
|
| - for (uint32_t j = 0; j < ARRAYSIZE(kEnabledLayerNames); ++j) {
|
| - for (uint32_t i = 0; i < layerCount; ++i) {
|
| - if (!strncmp(layers[i].layerName, kEnabledLayerNames[j],
|
| - strlen(kEnabledLayerNames[j]))) {
|
| - ++instanceLayersFound;
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - delete[] layers;
|
| -
|
| - return instanceExtensionsFound == ARRAYSIZE(kEnabledInstanceExtensionNames) &&
|
| - instanceLayersFound == ARRAYSIZE(kEnabledLayerNames);
|
| -}
|
| -
|
| -bool verify_device_layers(VkPhysicalDevice physDev) {
|
| - uint32_t layerCount;
|
| - VkResult res = vkEnumerateDeviceLayerProperties(physDev, &layerCount, nullptr);
|
| - if (VK_SUCCESS != res) {
|
| - return false;
|
| - }
|
| - VkLayerProperties* layers = new VkLayerProperties[layerCount];
|
| - res = vkEnumerateDeviceLayerProperties(physDev, &layerCount, layers);
|
| - if (VK_SUCCESS != res) {
|
| - return false;
|
| - }
|
| - int deviceLayersFound = 0;
|
| - for (uint32_t j = 0; j < ARRAYSIZE(kEnabledLayerNames); ++j) {
|
| - for (uint32_t i = 0; i < layerCount; ++i) {
|
| - if (!strncmp(layers[i].layerName, kEnabledLayerNames[j],
|
| - strlen(kEnabledLayerNames[j]))) {
|
| - ++deviceLayersFound;
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - delete[] layers;
|
| -
|
| - return deviceLayersFound == ARRAYSIZE(kEnabledLayerNames);
|
| -}
|
| #endif
|
|
|
| -// For now the VkGpuCreate is using the same signature as GL. This is mostly for ease of
|
| -// hiding this code from offical skia. In the end the VkGpuCreate will not take a GrBackendContext
|
| -// and mostly likely would take an optional device and queues to use.
|
| -GrGpu* vk_gpu_create(GrBackendContext backendContext, const GrContextOptions& options,
|
| - GrContext* context) {
|
| - // Below is Vulkan setup code that normal would be done by a client, but will do here for now
|
| - // for testing purposes.
|
| - VkPhysicalDevice physDev;
|
| - VkDevice device;
|
| - VkInstance inst;
|
| - VkResult err;
|
| -
|
| - const VkApplicationInfo app_info = {
|
| - VK_STRUCTURE_TYPE_APPLICATION_INFO, // sType
|
| - nullptr, // pNext
|
| - "vktest", // pApplicationName
|
| - 0, // applicationVersion
|
| - "vktest", // pEngineName
|
| - 0, // engineVerison
|
| - kGrVkMinimumVersion, // apiVersion
|
| - };
|
| -
|
| - const char** enabledLayerNames = nullptr;
|
| - int enabledLayerCount = 0;
|
| - const char** enabledInstanceExtensionNames = nullptr;
|
| - int enabledInstanceExtensionCount = 0;
|
| -#ifdef ENABLE_VK_LAYERS
|
| - if (verify_instance_layers()) {
|
| - enabledLayerNames = kEnabledLayerNames;
|
| - enabledLayerCount = ARRAYSIZE(kEnabledLayerNames);
|
| - enabledInstanceExtensionNames = kEnabledInstanceExtensionNames;
|
| - enabledInstanceExtensionCount = ARRAYSIZE(kEnabledInstanceExtensionNames);
|
| - }
|
| -#endif
|
| -
|
| - const VkInstanceCreateInfo instance_create = {
|
| - VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
|
| - nullptr, // pNext
|
| - 0, // flags
|
| - &app_info, // pApplicationInfo
|
| - enabledLayerCount, // enabledLayerNameCount
|
| - enabledLayerNames, // ppEnabledLayerNames
|
| - enabledInstanceExtensionCount, // enabledExtensionNameCount
|
| - enabledInstanceExtensionNames, // ppEnabledExtensionNames
|
| - };
|
| -
|
| - err = vkCreateInstance(&instance_create, nullptr, &inst);
|
| - if (err < 0) {
|
| - SkDebugf("vkCreateInstanced failed: %d\n", err);
|
| - SkFAIL("failing");
|
| - }
|
| -
|
| - uint32_t gpuCount;
|
| - err = vkEnumeratePhysicalDevices(inst, &gpuCount, nullptr);
|
| - if (err) {
|
| - SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err);
|
| - SkFAIL("failing");
|
| - }
|
| - SkASSERT(gpuCount > 0);
|
| - // Just returning the first physical device instead of getting the whole array.
|
| - gpuCount = 1;
|
| - err = vkEnumeratePhysicalDevices(inst, &gpuCount, &physDev);
|
| - if (err) {
|
| - SkDebugf("vkEnumeratePhysicalDevices failed: %d\n", err);
|
| - SkFAIL("failing");
|
| - }
|
| -
|
| - // query to get the initial queue props size
|
| - uint32_t queueCount;
|
| - vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, nullptr);
|
| - SkASSERT(queueCount >= 1);
|
| -
|
| - SkAutoMalloc queuePropsAlloc(queueCount * sizeof(VkQueueFamilyProperties));
|
| - // now get the actual queue props
|
| - VkQueueFamilyProperties* queueProps = (VkQueueFamilyProperties*)queuePropsAlloc.get();
|
| -
|
| - vkGetPhysicalDeviceQueueFamilyProperties(physDev, &queueCount, queueProps);
|
| -
|
| - // iterate to find the graphics queue
|
| - uint32_t graphicsQueueIndex = -1;
|
| - for (uint32_t i = 0; i < queueCount; i++) {
|
| - if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
|
| - graphicsQueueIndex = i;
|
| - break;
|
| +GrGpu* GrVkGpu::Create(GrBackendContext backendContext, const GrContextOptions& options,
|
| + GrContext* context) {
|
| + SkAutoTUnref<const GrVkBackendContext> vkBackendContext(
|
| + reinterpret_cast<const GrVkBackendContext*>(backendContext));
|
| + if (!vkBackendContext) {
|
| + vkBackendContext.reset(GrVkBackendContext::Create());
|
| + if (!vkBackendContext) {
|
| + return nullptr;
|
| }
|
| - }
|
| - SkASSERT(graphicsQueueIndex < queueCount);
|
| -
|
| -#ifdef ENABLE_VK_LAYERS
|
| - // unlikely that the device will have different layers than the instance, but good to check
|
| - if (!verify_device_layers(physDev)) {
|
| - enabledLayerNames = nullptr;
|
| - enabledLayerCount = 0;
|
| - }
|
| -#endif
|
| -
|
| - float queuePriorities[1] = { 0.0 };
|
| - const VkDeviceQueueCreateInfo queueInfo = {
|
| - VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
|
| - nullptr, // pNext
|
| - 0, // VkDeviceQueueCreateFlags
|
| - 0, // queueFamilyIndex
|
| - 1, // queueCount
|
| - queuePriorities, // pQueuePriorities
|
| - };
|
| - const VkDeviceCreateInfo deviceInfo = {
|
| - VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
|
| - nullptr, // pNext
|
| - 0, // VkDeviceCreateFlags
|
| - 1, // queueCreateInfoCount
|
| - &queueInfo, // pQueueCreateInfos
|
| - enabledLayerCount, // layerCount
|
| - enabledLayerNames, // ppEnabledLayerNames
|
| - 0, // extensionCount
|
| - nullptr, // ppEnabledExtensionNames
|
| - nullptr // ppEnabledFeatures
|
| - };
|
| -
|
| - err = vkCreateDevice(physDev, &deviceInfo, nullptr, &device);
|
| - if (err) {
|
| - SkDebugf("CreateDevice failed: %d\n", err);
|
| - SkFAIL("failing");
|
| - }
|
| -
|
| - VkQueue queue;
|
| - vkGetDeviceQueue(device, graphicsQueueIndex, 0, &queue);
|
| -
|
| - const VkCommandPoolCreateInfo cmdPoolInfo = {
|
| - VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType
|
| - nullptr, // pNext
|
| - 0, // CmdPoolCreateFlags
|
| - graphicsQueueIndex, // queueFamilyIndex
|
| - };
|
| -
|
| - VkCommandPool cmdPool;
|
| - err = vkCreateCommandPool(device, &cmdPoolInfo, nullptr, &cmdPool);
|
| - if (err) {
|
| - SkDebugf("CreateCommandPool failed: %d\n", err);
|
| - SkFAIL("failing");
|
| + } else {
|
| + vkBackendContext->ref();
|
| }
|
|
|
| - return new GrVkGpu(context, options, physDev, device, queue, cmdPool, inst);
|
| + return new GrVkGpu(context, options, vkBackendContext);
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|
| -GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
|
| - VkPhysicalDevice physDev, VkDevice device, VkQueue queue, VkCommandPool cmdPool,
|
| - VkInstance inst)
|
| +GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
|
| + const GrVkBackendContext* backendCtx)
|
| : INHERITED(context)
|
| - , fDevice(device)
|
| - , fQueue(queue)
|
| - , fCmdPool(cmdPool)
|
| - , fResourceProvider(this)
|
| - , fVkInstance(inst) {
|
| - fInterface.reset(GrVkCreateInterface(fVkInstance));
|
| - fCompiler = shaderc_compiler_initialize();
|
| -
|
| - fVkCaps.reset(new GrVkCaps(options, fInterface, physDev));
|
| - fCaps.reset(SkRef(fVkCaps.get()));
|
| -
|
| - fResourceProvider.init();
|
| -
|
| - fCurrentCmdBuffer = fResourceProvider.createCommandBuffer();
|
| - SkASSERT(fCurrentCmdBuffer);
|
| - fCurrentCmdBuffer->begin(this);
|
| - VK_CALL(GetPhysicalDeviceMemoryProperties(physDev, &fPhysDevMemProps));
|
| + , fVkInstance(backendCtx->fInstance)
|
| + , fDevice(backendCtx->fDevice)
|
| + , fQueue(backendCtx->fQueue)
|
| + , fResourceProvider(this) {
|
| + fBackendContext.reset(backendCtx);
|
|
|
| #ifdef ENABLE_VK_LAYERS
|
| - if (fInterface->hasInstanceExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
|
| + if (this->vkInterface()->hasInstanceExtension(VK_EXT_DEBUG_REPORT_EXTENSION_NAME)) {
|
| /* Setup callback creation information */
|
| VkDebugReportCallbackCreateInfoEXT callbackCreateInfo;
|
| callbackCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
|
| @@ -344,14 +105,35 @@ GrVkGpu::GrVkGpu(GrContext* context, const GrContextOptions& options,
|
| callbackCreateInfo.pUserData = nullptr;
|
|
|
| /* Register the callback */
|
| - GR_VK_CALL_ERRCHECK(fInterface, CreateDebugReportCallbackEXT(inst, &callbackCreateInfo,
|
| - nullptr, &fCallback));
|
| + GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateDebugReportCallbackEXT(fVkInstance,
|
| + &callbackCreateInfo, nullptr, &fCallback));
|
| }
|
| #endif
|
| +
|
| + fCompiler = shaderc_compiler_initialize();
|
| +
|
| + fVkCaps.reset(new GrVkCaps(options, this->vkInterface(), backendCtx->fPhysicalDevice));
|
| + fCaps.reset(SkRef(fVkCaps.get()));
|
| +
|
| + VK_CALL(GetPhysicalDeviceMemoryProperties(backendCtx->fPhysicalDevice, &fPhysDevMemProps));
|
| +
|
| + const VkCommandPoolCreateInfo cmdPoolInfo = {
|
| + VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType
|
| + nullptr, // pNext
|
| + VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // CmdPoolCreateFlags
|
| + backendCtx->fQueueFamilyIndex, // queueFamilyIndex
|
| + };
|
| + GR_VK_CALL_ERRCHECK(this->vkInterface(), CreateCommandPool(fDevice, &cmdPoolInfo, nullptr,
|
| + &fCmdPool));
|
| +
|
| + // must call this after creating the CommandPool
|
| + fResourceProvider.init();
|
| + fCurrentCmdBuffer = fResourceProvider.createCommandBuffer();
|
| + SkASSERT(fCurrentCmdBuffer);
|
| + fCurrentCmdBuffer->begin(this);
|
| }
|
|
|
| GrVkGpu::~GrVkGpu() {
|
| - shaderc_compiler_release(fCompiler);
|
| fCurrentCmdBuffer->end(this);
|
| fCurrentCmdBuffer->unref(this);
|
|
|
| @@ -364,13 +146,13 @@ GrVkGpu::~GrVkGpu() {
|
| // must call this just before we destroy the VkDevice
|
| fResourceProvider.destroyResources();
|
|
|
| -#ifdef SK_DEBUG
|
| + VK_CALL(DestroyCommandPool(fDevice, fCmdPool, nullptr));
|
| +
|
| + shaderc_compiler_release(fCompiler);
|
| +
|
| +#ifdef ENABLE_VK_LAYERS
|
| VK_CALL(DestroyDebugReportCallbackEXT(fVkInstance, fCallback, nullptr));
|
| #endif
|
| -
|
| - VK_CALL(DestroyCommandPool(fDevice, fCmdPool, nullptr));
|
| - VK_CALL(DestroyDevice(fDevice, nullptr));
|
| - VK_CALL(DestroyInstance(fVkInstance, nullptr));
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|