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_renderer_util.h" 21#include "vn_ring.h" 22 23/* require and request at least Vulkan 1.1 at both instance and device levels 24 */ 25#define VN_MIN_RENDERER_VERSION VK_API_VERSION_1_1 26 27/* max advertised version at both instance and device levels */ 28#ifdef ANDROID 29#define VN_MAX_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION) 30#else 31#define VN_MAX_API_VERSION VK_MAKE_VERSION(1, 2, VK_HEADER_VERSION) 32#endif 33 34struct vn_instance { 35 struct vn_instance_base base; 36 37 struct driOptionCache dri_options; 38 struct driOptionCache available_dri_options; 39 40 struct vn_renderer *renderer; 41 42 struct vn_renderer_shmem_pool reply_shmem_pool; 43 44 /* XXX staged features to be merged to core venus protocol */ 45 VkVenusExperimentalFeatures100000MESA experimental; 46 47 struct { 48 mtx_t mutex; 49 struct vn_renderer_shmem *shmem; 50 struct vn_ring ring; 51 uint64_t id; 52 53 struct vn_cs_encoder upload; 54 uint32_t command_dropped; 55 56 /* to synchronize renderer/ring */ 57 mtx_t roundtrip_mutex; 58 uint32_t roundtrip_next; 59 } ring; 60 61 /* Between the driver and the app, VN_MAX_API_VERSION is what we advertise 62 * and base.base.app_info.api_version is what the app requests. 63 * 64 * Between the driver and the renderer, renderer_api_version is the api 65 * version we request internally, which can be higher than 66 * base.base.app_info.api_version. renderer_version is the instance 67 * version we can use internally. 68 */ 69 uint32_t renderer_api_version; 70 uint32_t renderer_version; 71 72 /* for VN_CS_ENCODER_STORAGE_SHMEM_POOL */ 73 struct { 74 mtx_t mutex; 75 struct vn_renderer_shmem_pool pool; 76 } cs_shmem; 77 78 struct { 79 mtx_t mutex; 80 bool initialized; 81 82 struct vn_physical_device *devices; 83 uint32_t device_count; 84 VkPhysicalDeviceGroupProperties *groups; 85 uint32_t group_count; 86 } physical_device; 87}; 88VK_DEFINE_HANDLE_CASTS(vn_instance, 89 base.base.base, 90 VkInstance, 91 VK_OBJECT_TYPE_INSTANCE) 92 93VkResult 94vn_instance_submit_roundtrip(struct vn_instance *instance, 95 uint32_t *roundtrip_seqno); 96 97void 98vn_instance_wait_roundtrip(struct vn_instance *instance, 99 uint32_t roundtrip_seqno); 100 101static inline void 102vn_instance_roundtrip(struct vn_instance *instance) 103{ 104 uint32_t roundtrip_seqno; 105 if (vn_instance_submit_roundtrip(instance, &roundtrip_seqno) == VK_SUCCESS) 106 vn_instance_wait_roundtrip(instance, roundtrip_seqno); 107} 108 109VkResult 110vn_instance_ring_submit(struct vn_instance *instance, 111 const struct vn_cs_encoder *cs); 112 113static inline void 114vn_instance_ring_wait(struct vn_instance *instance) 115{ 116 struct vn_ring *ring = &instance->ring.ring; 117 vn_ring_wait_all(ring); 118} 119 120struct vn_instance_submit_command { 121 /* empty command implies errors */ 122 struct vn_cs_encoder command; 123 struct vn_cs_encoder_buffer buffer; 124 /* non-zero implies waiting */ 125 size_t reply_size; 126 127 /* when reply_size is non-zero, NULL can be returned on errors */ 128 struct vn_renderer_shmem *reply_shmem; 129 struct vn_cs_decoder reply; 130}; 131 132static inline struct vn_cs_encoder * 133vn_instance_submit_command_init(struct vn_instance *instance, 134 struct vn_instance_submit_command *submit, 135 void *cmd_data, 136 size_t cmd_size, 137 size_t reply_size) 138{ 139 submit->buffer = VN_CS_ENCODER_BUFFER_INITIALIZER(cmd_data); 140 submit->command = VN_CS_ENCODER_INITIALIZER(&submit->buffer, cmd_size); 141 142 submit->reply_size = reply_size; 143 submit->reply_shmem = NULL; 144 145 return &submit->command; 146} 147 148void 149vn_instance_submit_command(struct vn_instance *instance, 150 struct vn_instance_submit_command *submit); 151 152static inline struct vn_cs_decoder * 153vn_instance_get_command_reply(struct vn_instance *instance, 154 struct vn_instance_submit_command *submit) 155{ 156 return submit->reply_shmem ? &submit->reply : NULL; 157} 158 159static inline void 160vn_instance_free_command_reply(struct vn_instance *instance, 161 struct vn_instance_submit_command *submit) 162{ 163 assert(submit->reply_shmem); 164 vn_renderer_shmem_unref(instance->renderer, submit->reply_shmem); 165} 166 167static inline struct vn_renderer_shmem * 168vn_instance_cs_shmem_alloc(struct vn_instance *instance, 169 size_t size, 170 size_t *out_offset) 171{ 172 struct vn_renderer_shmem *shmem; 173 174 mtx_lock(&instance->cs_shmem.mutex); 175 shmem = vn_renderer_shmem_pool_alloc( 176 instance->renderer, &instance->cs_shmem.pool, size, out_offset); 177 mtx_unlock(&instance->cs_shmem.mutex); 178 179 return shmem; 180} 181 182#endif /* VN_INSTANCE_H */ 183