/* * Copyright (C) 2016 The Brenwill Workshop Ltd. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #include "ShellMVK.h" #include #include #include #include #include "Helpers.h" #include "Game.h" PosixTimer::PosixTimer() { _tsBase = mach_absolute_time(); mach_timebase_info_data_t timebase; mach_timebase_info(&timebase); _tsPeriod = (double)timebase.numer / (double)timebase.denom; } double PosixTimer::get() { return (double)(mach_absolute_time() - _tsBase) * _tsPeriod / 1e9; } ShellMVK::ShellMVK(Game& game) : Shell(game) { _timer = PosixTimer(); _current_time = _timer.get(); _profile_start_time = _current_time; _profile_present_count = 0; instance_extensions_.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME); init_vk(); } ShellMVK::~ShellMVK() { destroy_context(); cleanup_vk(); } PFN_vkGetInstanceProcAddr ShellMVK::load_vk() { return vkGetInstanceProcAddr; } bool ShellMVK::can_present(VkPhysicalDevice phy, uint32_t queue_family) { return true; } VkSurfaceKHR ShellMVK::create_surface(VkInstance instance) { VkSurfaceKHR surface; VkResult err; VkMetalSurfaceCreateInfoEXT surface_info; surface_info.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; surface_info.pNext = NULL; surface_info.flags = 0; surface_info.pLayer = _caMetalLayer; err = vkCreateMetalSurfaceEXT(instance, &surface_info, NULL, &surface); assert(!err); return surface; } void ShellMVK::update_and_draw() { acquire_back_buffer(); double t = _timer.get(); add_game_time(static_cast(t - _current_time)); present_back_buffer(); _current_time = t; _profile_present_count++; if (_current_time - _profile_start_time >= 5.0) { const double fps = _profile_present_count / (_current_time - _profile_start_time); std::stringstream ss; ss << _profile_present_count << " presents in " << _current_time - _profile_start_time << " seconds " << "(FPS: " << fps << ")"; log(LOG_INFO, ss.str().c_str()); _profile_start_time = _current_time; _profile_present_count = 0; } } void ShellMVK::run(void* caMetalLayer) { _caMetalLayer = caMetalLayer; // not retained create_context(); resize_swapchain(settings_.initial_width, settings_.initial_height); }