1 /* 2 * Copyright 2019 Google LLC 3 * SPDX-License-Identifier: MIT 4 * 5 * based in part on anv and radv which are: 6 * Copyright 2015 Intel Corporation 7 * Copyright 2016 Red Hat. 8 * Copyright 2016 Bas Nieuwenhuizen 9 */ 10 11 #ifndef VN_INSTANCE_H 12 #define VN_INSTANCE_H 13 14 #include "vn_common.h" 15 16 #include "venus-protocol/vn_protocol_driver_defines.h" 17 18 #include "vn_cs.h" 19 #include "vn_renderer.h" 20 #include "vn_ring.h" 21 22 /* require and request at least Vulkan 1.1 at both instance and device levels 23 */ 24 #define VN_MIN_RENDERER_VERSION VK_API_VERSION_1_1 25 26 /* max advertised version at both instance and device levels */ 27 #ifdef ANDROID 28 #define VN_MAX_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION) 29 #else 30 #define VN_MAX_API_VERSION VK_MAKE_VERSION(1, 2, VK_HEADER_VERSION) 31 #endif 32 33 struct vn_instance { 34 struct vn_instance_base base; 35 36 struct driOptionCache dri_options; 37 struct driOptionCache available_dri_options; 38 39 struct vn_renderer *renderer; 40 struct vn_renderer_info renderer_info; 41 42 /* XXX staged features to be merged to core venus protocol */ 43 VkVenusExperimentalFeatures100000MESA experimental; 44 45 struct { 46 mtx_t mutex; 47 struct vn_renderer_shmem *shmem; 48 struct vn_ring ring; 49 uint64_t id; 50 51 struct vn_cs_encoder upload; 52 uint32_t command_dropped; 53 54 /* to synchronize renderer/ring */ 55 mtx_t roundtrip_mutex; 56 uint32_t roundtrip_next; 57 } ring; 58 59 struct { 60 struct vn_renderer_shmem *shmem; 61 size_t size; 62 size_t used; 63 void *ptr; 64 } reply; 65 66 /* Between the driver and the app, VN_MAX_API_VERSION is what we advertise 67 * and base.base.app_info.api_version is what the app requests. 68 * 69 * Between the driver and the renderer, renderer_api_version is the api 70 * version we request internally, which can be higher than 71 * base.base.app_info.api_version. renderer_version is the instance 72 * version we can use internally. 73 */ 74 uint32_t renderer_api_version; 75 uint32_t renderer_version; 76 77 struct { 78 mtx_t mutex; 79 bool initialized; 80 81 struct vn_physical_device *devices; 82 uint32_t device_count; 83 VkPhysicalDeviceGroupProperties *groups; 84 uint32_t group_count; 85 } physical_device; 86 }; 87 VK_DEFINE_HANDLE_CASTS(vn_instance, 88 base.base.base, 89 VkInstance, 90 VK_OBJECT_TYPE_INSTANCE) 91 92 VkResult 93 vn_instance_submit_roundtrip(struct vn_instance *instance, 94 uint32_t *roundtrip_seqno); 95 96 void 97 vn_instance_wait_roundtrip(struct vn_instance *instance, 98 uint32_t roundtrip_seqno); 99 100 static inline void 101 vn_instance_roundtrip(struct vn_instance *instance) 102 { 103 uint32_t roundtrip_seqno; 104 if (vn_instance_submit_roundtrip(instance, &roundtrip_seqno) == VK_SUCCESS) 105 vn_instance_wait_roundtrip(instance, roundtrip_seqno); 106 } 107 108 VkResult 109 vn_instance_ring_submit(struct vn_instance *instance, 110 const struct vn_cs_encoder *cs); 111 112 struct vn_instance_submit_command { 113 /* empty command implies errors */ 114 struct vn_cs_encoder command; 115 struct vn_cs_encoder_buffer buffer; 116 /* non-zero implies waiting */ 117 size_t reply_size; 118 119 /* when reply_size is non-zero, NULL can be returned on errors */ 120 struct vn_renderer_shmem *reply_shmem; 121 struct vn_cs_decoder reply; 122 }; 123 124 static inline struct vn_cs_encoder * 125 vn_instance_submit_command_init(struct vn_instance *instance, 126 struct vn_instance_submit_command *submit, 127 void *cmd_data, 128 size_t cmd_size, 129 size_t reply_size) 130 { 131 submit->buffer = VN_CS_ENCODER_BUFFER_INITIALIZER(cmd_data); 132 submit->command = VN_CS_ENCODER_INITIALIZER(&submit->buffer, cmd_size); 133 134 submit->reply_size = reply_size; 135 submit->reply_shmem = NULL; 136 137 return &submit->command; 138 } 139 140 void 141 vn_instance_submit_command(struct vn_instance *instance, 142 struct vn_instance_submit_command *submit); 143 144 static inline struct vn_cs_decoder * 145 vn_instance_get_command_reply(struct vn_instance *instance, 146 struct vn_instance_submit_command *submit) 147 { 148 return submit->reply_shmem ? &submit->reply : NULL; 149 } 150 151 static inline void 152 vn_instance_free_command_reply(struct vn_instance *instance, 153 struct vn_instance_submit_command *submit) 154 { 155 assert(submit->reply_shmem); 156 vn_renderer_shmem_unref(instance->renderer, submit->reply_shmem); 157 } 158 159 #endif /* VN_INSTANCE_H */ 160