17ec681f3Smrg/*
27ec681f3Smrg * Copyright 2019 Google LLC
37ec681f3Smrg * SPDX-License-Identifier: MIT
47ec681f3Smrg *
57ec681f3Smrg * based in part on anv and radv which are:
67ec681f3Smrg * Copyright © 2015 Intel Corporation
77ec681f3Smrg * Copyright © 2016 Red Hat.
87ec681f3Smrg * Copyright © 2016 Bas Nieuwenhuizen
97ec681f3Smrg */
107ec681f3Smrg
117ec681f3Smrg#ifndef VN_INSTANCE_H
127ec681f3Smrg#define VN_INSTANCE_H
137ec681f3Smrg
147ec681f3Smrg#include "vn_common.h"
157ec681f3Smrg
167ec681f3Smrg#include "venus-protocol/vn_protocol_driver_defines.h"
177ec681f3Smrg
187ec681f3Smrg#include "vn_cs.h"
197ec681f3Smrg#include "vn_renderer.h"
207ec681f3Smrg#include "vn_ring.h"
217ec681f3Smrg
227ec681f3Smrg/* require and request at least Vulkan 1.1 at both instance and device levels
237ec681f3Smrg */
247ec681f3Smrg#define VN_MIN_RENDERER_VERSION VK_API_VERSION_1_1
257ec681f3Smrg
267ec681f3Smrg/* max advertised version at both instance and device levels */
277ec681f3Smrg#ifdef ANDROID
287ec681f3Smrg#define VN_MAX_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION)
297ec681f3Smrg#else
307ec681f3Smrg#define VN_MAX_API_VERSION VK_MAKE_VERSION(1, 2, VK_HEADER_VERSION)
317ec681f3Smrg#endif
327ec681f3Smrg
337ec681f3Smrgstruct vn_instance {
347ec681f3Smrg   struct vn_instance_base base;
357ec681f3Smrg
367ec681f3Smrg   struct driOptionCache dri_options;
377ec681f3Smrg   struct driOptionCache available_dri_options;
387ec681f3Smrg
397ec681f3Smrg   struct vn_renderer *renderer;
407ec681f3Smrg   struct vn_renderer_info renderer_info;
417ec681f3Smrg
427ec681f3Smrg   /* XXX staged features to be merged to core venus protocol */
437ec681f3Smrg   VkVenusExperimentalFeatures100000MESA experimental;
447ec681f3Smrg
457ec681f3Smrg   struct {
467ec681f3Smrg      mtx_t mutex;
477ec681f3Smrg      struct vn_renderer_shmem *shmem;
487ec681f3Smrg      struct vn_ring ring;
497ec681f3Smrg      uint64_t id;
507ec681f3Smrg
517ec681f3Smrg      struct vn_cs_encoder upload;
527ec681f3Smrg      uint32_t command_dropped;
537ec681f3Smrg
547ec681f3Smrg      /* to synchronize renderer/ring */
557ec681f3Smrg      mtx_t roundtrip_mutex;
567ec681f3Smrg      uint32_t roundtrip_next;
577ec681f3Smrg   } ring;
587ec681f3Smrg
597ec681f3Smrg   struct {
607ec681f3Smrg      struct vn_renderer_shmem *shmem;
617ec681f3Smrg      size_t size;
627ec681f3Smrg      size_t used;
637ec681f3Smrg      void *ptr;
647ec681f3Smrg   } reply;
657ec681f3Smrg
667ec681f3Smrg   /* Between the driver and the app, VN_MAX_API_VERSION is what we advertise
677ec681f3Smrg    * and base.base.app_info.api_version is what the app requests.
687ec681f3Smrg    *
697ec681f3Smrg    * Between the driver and the renderer, renderer_api_version is the api
707ec681f3Smrg    * version we request internally, which can be higher than
717ec681f3Smrg    * base.base.app_info.api_version.  renderer_version is the instance
727ec681f3Smrg    * version we can use internally.
737ec681f3Smrg    */
747ec681f3Smrg   uint32_t renderer_api_version;
757ec681f3Smrg   uint32_t renderer_version;
767ec681f3Smrg
777ec681f3Smrg   struct {
787ec681f3Smrg      mtx_t mutex;
797ec681f3Smrg      bool initialized;
807ec681f3Smrg
817ec681f3Smrg      struct vn_physical_device *devices;
827ec681f3Smrg      uint32_t device_count;
837ec681f3Smrg      VkPhysicalDeviceGroupProperties *groups;
847ec681f3Smrg      uint32_t group_count;
857ec681f3Smrg   } physical_device;
867ec681f3Smrg};
877ec681f3SmrgVK_DEFINE_HANDLE_CASTS(vn_instance,
887ec681f3Smrg                       base.base.base,
897ec681f3Smrg                       VkInstance,
907ec681f3Smrg                       VK_OBJECT_TYPE_INSTANCE)
917ec681f3Smrg
927ec681f3SmrgVkResult
937ec681f3Smrgvn_instance_submit_roundtrip(struct vn_instance *instance,
947ec681f3Smrg                             uint32_t *roundtrip_seqno);
957ec681f3Smrg
967ec681f3Smrgvoid
977ec681f3Smrgvn_instance_wait_roundtrip(struct vn_instance *instance,
987ec681f3Smrg                           uint32_t roundtrip_seqno);
997ec681f3Smrg
1007ec681f3Smrgstatic inline void
1017ec681f3Smrgvn_instance_roundtrip(struct vn_instance *instance)
1027ec681f3Smrg{
1037ec681f3Smrg   uint32_t roundtrip_seqno;
1047ec681f3Smrg   if (vn_instance_submit_roundtrip(instance, &roundtrip_seqno) == VK_SUCCESS)
1057ec681f3Smrg      vn_instance_wait_roundtrip(instance, roundtrip_seqno);
1067ec681f3Smrg}
1077ec681f3Smrg
1087ec681f3SmrgVkResult
1097ec681f3Smrgvn_instance_ring_submit(struct vn_instance *instance,
1107ec681f3Smrg                        const struct vn_cs_encoder *cs);
1117ec681f3Smrg
1127ec681f3Smrgstruct vn_instance_submit_command {
1137ec681f3Smrg   /* empty command implies errors */
1147ec681f3Smrg   struct vn_cs_encoder command;
1157ec681f3Smrg   struct vn_cs_encoder_buffer buffer;
1167ec681f3Smrg   /* non-zero implies waiting */
1177ec681f3Smrg   size_t reply_size;
1187ec681f3Smrg
1197ec681f3Smrg   /* when reply_size is non-zero, NULL can be returned on errors */
1207ec681f3Smrg   struct vn_renderer_shmem *reply_shmem;
1217ec681f3Smrg   struct vn_cs_decoder reply;
1227ec681f3Smrg};
1237ec681f3Smrg
1247ec681f3Smrgstatic inline struct vn_cs_encoder *
1257ec681f3Smrgvn_instance_submit_command_init(struct vn_instance *instance,
1267ec681f3Smrg                                struct vn_instance_submit_command *submit,
1277ec681f3Smrg                                void *cmd_data,
1287ec681f3Smrg                                size_t cmd_size,
1297ec681f3Smrg                                size_t reply_size)
1307ec681f3Smrg{
1317ec681f3Smrg   submit->buffer = VN_CS_ENCODER_BUFFER_INITIALIZER(cmd_data);
1327ec681f3Smrg   submit->command = VN_CS_ENCODER_INITIALIZER(&submit->buffer, cmd_size);
1337ec681f3Smrg
1347ec681f3Smrg   submit->reply_size = reply_size;
1357ec681f3Smrg   submit->reply_shmem = NULL;
1367ec681f3Smrg
1377ec681f3Smrg   return &submit->command;
1387ec681f3Smrg}
1397ec681f3Smrg
1407ec681f3Smrgvoid
1417ec681f3Smrgvn_instance_submit_command(struct vn_instance *instance,
1427ec681f3Smrg                           struct vn_instance_submit_command *submit);
1437ec681f3Smrg
1447ec681f3Smrgstatic inline struct vn_cs_decoder *
1457ec681f3Smrgvn_instance_get_command_reply(struct vn_instance *instance,
1467ec681f3Smrg                              struct vn_instance_submit_command *submit)
1477ec681f3Smrg{
1487ec681f3Smrg   return submit->reply_shmem ? &submit->reply : NULL;
1497ec681f3Smrg}
1507ec681f3Smrg
1517ec681f3Smrgstatic inline void
1527ec681f3Smrgvn_instance_free_command_reply(struct vn_instance *instance,
1537ec681f3Smrg                               struct vn_instance_submit_command *submit)
1547ec681f3Smrg{
1557ec681f3Smrg   assert(submit->reply_shmem);
1567ec681f3Smrg   vn_renderer_shmem_unref(instance->renderer, submit->reply_shmem);
1577ec681f3Smrg}
1587ec681f3Smrg
1597ec681f3Smrg#endif /* VN_INSTANCE_H */
160