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