1fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall/* 2fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall * Copyright 2016 The Android Open Source Project 3fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall * 4fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall * Licensed under the Apache License, Version 2.0 (the "License"); 5fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall * you may not use this file except in compliance with the License. 6fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall * You may obtain a copy of the License at 7fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall * 8fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall * http://www.apache.org/licenses/LICENSE-2.0 9fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall * 10fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall * Unless required by applicable law or agreed to in writing, software 11fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall * distributed under the License is distributed on an "AS IS" BASIS, 12fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall * See the License for the specific language governing permissions and 14fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall * limitations under the License. 15fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall */ 16fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall 17fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall#include "GpuService.h" 18fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall 19fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall#include <binder/Parcel.h> 208b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall#include <utils/String8.h> 218b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall#include <vkjson.h> 22fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall 23fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hallnamespace android { 24fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall 25fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall// ---------------------------------------------------------------------------- 26fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall 27fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hallclass BpGpuService : public BpInterface<IGpuService> 28fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall{ 29fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hallpublic: 30fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall BpGpuService(const sp<IBinder>& impl) : BpInterface<IGpuService>(impl) {} 31fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall}; 32fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall 33fc038bd8fc77998a436d43027919f4500c4291e6Jesse HallIMPLEMENT_META_INTERFACE(GpuService, "android.ui.IGpuService"); 34fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall 35fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hallstatus_t BnGpuService::onTransact(uint32_t code, const Parcel& data, 36fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall Parcel* reply, uint32_t flags) 37fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall{ 38fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall switch (code) { 39fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall case SHELL_COMMAND_TRANSACTION: { 40fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall int in = data.readFileDescriptor(); 41fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall int out = data.readFileDescriptor(); 42fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall int err = data.readFileDescriptor(); 43fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall int argc = data.readInt32(); 44fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall Vector<String16> args; 45fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall for (int i = 0; i < argc && data.dataAvail() > 0; i++) { 46fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall args.add(data.readString16()); 47fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall } 48fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall return shellCommand(in, out, err, args); 49fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall } 50fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall 51fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall default: 52fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall return BBinder::onTransact(code, data, reply, flags); 53fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall } 54fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall} 55fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall 56fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall// ---------------------------------------------------------------------------- 57fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall 588b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hallnamespace { 598b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall status_t cmd_help(int out); 608b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall status_t cmd_vkjson(int out, int err); 618b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall} 628b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 63fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hallconst char* const GpuService::SERVICE_NAME = "gpu"; 64fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall 65fc038bd8fc77998a436d43027919f4500c4291e6Jesse HallGpuService::GpuService() {} 66fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall 678b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hallstatus_t GpuService::shellCommand(int /*in*/, int out, int err, 688b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall Vector<String16>& args) 69fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall{ 708b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall ALOGV("GpuService::shellCommand"); 718b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall for (size_t i = 0, n = args.size(); i < n; i++) 728b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall ALOGV(" arg[%zu]: '%s'", i, String8(args[i]).string()); 738b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 748b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall if (args[0] == String16("vkjson")) 758b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall return cmd_vkjson(out, err); 768b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall else if (args[0] == String16("help")) 778b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall return cmd_help(out); 788b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 798b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall return NO_ERROR; 808b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall} 818b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 828b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall// ---------------------------------------------------------------------------- 838b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 848b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hallnamespace { 858b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 868b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hallstatus_t cmd_help(int out) { 878b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall FILE* outs = fdopen(out, "w"); 888b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall if (!outs) { 898b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall ALOGE("vkjson: failed to create out stream: %s (%d)", strerror(errno), 908b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall errno); 918b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall return BAD_VALUE; 928b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall } 938b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall fprintf(outs, 948b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall "GPU Service commands:\n" 958b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall " vkjson dump Vulkan device capabilities as JSON\n"); 968b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall fclose(outs); 97fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall return NO_ERROR; 98fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall} 99fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall 1008b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse HallVkResult vkjsonPrint(FILE* out, FILE* err) { 1018b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall VkResult result; 1028b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 1038b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall const VkApplicationInfo app_info = { 1048b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall VK_STRUCTURE_TYPE_APPLICATION_INFO, nullptr, 1058b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall "vkjson", 1, /* app name, version */ 1068b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall "", 0, /* engine name, version */ 1072676338dd692b7d1e1c276d82e6b0492db53ab2eJesse Hall VK_API_VERSION_1_0 1088b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall }; 1098b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall const VkInstanceCreateInfo instance_info = { 1108b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, nullptr, 1118b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 0, /* flags */ 1128b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall &app_info, 1138b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 0, nullptr, /* layers */ 1148b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 0, nullptr, /* extensions */ 1158b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall }; 1168b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall VkInstance instance; 1178b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall result = vkCreateInstance(&instance_info, nullptr, &instance); 1188b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall if (result != VK_SUCCESS) { 1198b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall fprintf(err, "vkCreateInstance failed: %d\n", result); 1208b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall return result; 1218b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall } 1228b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 1238b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall uint32_t ngpu = 0; 1248b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall result = vkEnumeratePhysicalDevices(instance, &ngpu, nullptr); 1258b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall if (result != VK_SUCCESS) { 1268b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall fprintf(err, "vkEnumeratePhysicalDevices failed: %d\n", result); 1278b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall return result; 1288b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall } 1298b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall std::vector<VkPhysicalDevice> gpus(ngpu, VK_NULL_HANDLE); 1308b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall result = vkEnumeratePhysicalDevices(instance, &ngpu, gpus.data()); 1318b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall if (result != VK_SUCCESS) { 1328b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall fprintf(err, "vkEnumeratePhysicalDevices failed: %d\n", result); 1338b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall return result; 1348b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall } 1358b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 1368b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall for (size_t i = 0, n = gpus.size(); i < n; i++) { 1378b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall auto props = VkJsonGetAllProperties(gpus[i]); 1388b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall std::string json = VkJsonAllPropertiesToJson(props); 1398b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall fwrite(json.data(), 1, json.size(), out); 1408b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall if (i < n - 1) 1418b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall fputc(',', out); 1428b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall fputc('\n', out); 1438b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall } 1448b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 1458b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall vkDestroyInstance(instance, nullptr); 1468b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 1478b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall return VK_SUCCESS; 1488b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall} 1498b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 1508b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hallstatus_t cmd_vkjson(int out, int err) { 1518b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall int errnum; 1528b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall FILE* outs = fdopen(out, "w"); 1538b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall if (!outs) { 1548b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall errnum = errno; 1558b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall ALOGE("vkjson: failed to create output stream: %s", strerror(errnum)); 1568b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall return -errnum; 1578b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall } 1588b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall FILE* errs = fdopen(err, "w"); 1598b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall if (!errs) { 1608b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall errnum = errno; 1618b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall ALOGE("vkjson: failed to create error stream: %s", strerror(errnum)); 1628b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall fclose(outs); 1638b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall return -errnum; 1648b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall } 1658b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall fprintf(outs, "[\n"); 1668b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall VkResult result = vkjsonPrint(outs, errs); 1678b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall fprintf(outs, "]\n"); 1688b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall fclose(errs); 1698b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall fclose(outs); 1708b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall return result >= 0 ? NO_ERROR : UNKNOWN_ERROR; 1718b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall} 1728b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 1738b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall} // anonymous namespace 1748b0d55e3652e68e9e2b0f4314c1eaeadc49cc2d0Jesse Hall 175fc038bd8fc77998a436d43027919f4500c4291e6Jesse Hall} // namespace android 176