• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
34 struct 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 };
88 VK_DEFINE_HANDLE_CASTS(vn_instance,
89                        base.base.base,
90                        VkInstance,
91                        VK_OBJECT_TYPE_INSTANCE)
92 
93 VkResult
94 vn_instance_submit_roundtrip(struct vn_instance *instance,
95                              uint32_t *roundtrip_seqno);
96 
97 void
98 vn_instance_wait_roundtrip(struct vn_instance *instance,
99                            uint32_t roundtrip_seqno);
100 
101 static inline void
vn_instance_roundtrip(struct vn_instance * instance)102 vn_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 
109 VkResult
110 vn_instance_ring_submit(struct vn_instance *instance,
111                         const struct vn_cs_encoder *cs);
112 
113 static inline void
vn_instance_ring_wait(struct vn_instance * instance)114 vn_instance_ring_wait(struct vn_instance *instance)
115 {
116    struct vn_ring *ring = &instance->ring.ring;
117    vn_ring_wait_all(ring);
118 }
119 
120 struct 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 
132 static inline struct vn_cs_encoder *
vn_instance_submit_command_init(struct vn_instance * instance,struct vn_instance_submit_command * submit,void * cmd_data,size_t cmd_size,size_t reply_size)133 vn_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 
148 void
149 vn_instance_submit_command(struct vn_instance *instance,
150                            struct vn_instance_submit_command *submit);
151 
152 static inline struct vn_cs_decoder *
vn_instance_get_command_reply(struct vn_instance * instance,struct vn_instance_submit_command * submit)153 vn_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 
159 static inline void
vn_instance_free_command_reply(struct vn_instance * instance,struct vn_instance_submit_command * submit)160 vn_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 
167 static inline struct vn_renderer_shmem *
vn_instance_cs_shmem_alloc(struct vn_instance * instance,size_t size,size_t * out_offset)168 vn_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