17ec681f3Smrg/*
27ec681f3Smrg * Copyright © 2019 Raspberry Pi
37ec681f3Smrg *
47ec681f3Smrg * based in part on anv driver which is:
57ec681f3Smrg * Copyright © 2015 Intel Corporation
67ec681f3Smrg *
77ec681f3Smrg * based in part on radv driver which is:
87ec681f3Smrg * Copyright © 2016 Red Hat.
97ec681f3Smrg * Copyright © 2016 Bas Nieuwenhuizen
107ec681f3Smrg *
117ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
127ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
137ec681f3Smrg * to deal in the Software without restriction, including without limitation
147ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
157ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
167ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
177ec681f3Smrg *
187ec681f3Smrg * The above copyright notice and this permission notice (including the next
197ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
207ec681f3Smrg * Software.
217ec681f3Smrg *
227ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
237ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
247ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
257ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
267ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
277ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
287ec681f3Smrg * IN THE SOFTWARE.
297ec681f3Smrg */
307ec681f3Smrg#ifndef V3DV_PRIVATE_H
317ec681f3Smrg#define V3DV_PRIVATE_H
327ec681f3Smrg
337ec681f3Smrg#include <stdio.h>
347ec681f3Smrg#include <string.h>
357ec681f3Smrg#include <vulkan/vulkan.h>
367ec681f3Smrg#include <vulkan/vk_icd.h>
377ec681f3Smrg#include <vk_enum_to_str.h>
387ec681f3Smrg
397ec681f3Smrg#include "vk_device.h"
407ec681f3Smrg#include "vk_instance.h"
417ec681f3Smrg#include "vk_image.h"
427ec681f3Smrg#include "vk_log.h"
437ec681f3Smrg#include "vk_physical_device.h"
447ec681f3Smrg#include "vk_shader_module.h"
457ec681f3Smrg#include "vk_util.h"
467ec681f3Smrg
477ec681f3Smrg#include "vk_command_buffer.h"
487ec681f3Smrg#include "vk_queue.h"
497ec681f3Smrg
507ec681f3Smrg#include <xf86drm.h>
517ec681f3Smrg
527ec681f3Smrg#ifdef HAVE_VALGRIND
537ec681f3Smrg#include <valgrind.h>
547ec681f3Smrg#include <memcheck.h>
557ec681f3Smrg#define VG(x) x
567ec681f3Smrg#else
577ec681f3Smrg#define VG(x) ((void)0)
587ec681f3Smrg#endif
597ec681f3Smrg
607ec681f3Smrg#include "v3dv_limits.h"
617ec681f3Smrg
627ec681f3Smrg#include "common/v3d_device_info.h"
637ec681f3Smrg#include "common/v3d_limits.h"
647ec681f3Smrg#include "common/v3d_tiling.h"
657ec681f3Smrg#include "common/v3d_util.h"
667ec681f3Smrg
677ec681f3Smrg#include "compiler/shader_enums.h"
687ec681f3Smrg#include "compiler/spirv/nir_spirv.h"
697ec681f3Smrg
707ec681f3Smrg#include "compiler/v3d_compiler.h"
717ec681f3Smrg
727ec681f3Smrg#include "vk_debug_report.h"
737ec681f3Smrg#include "util/set.h"
747ec681f3Smrg#include "util/hash_table.h"
757ec681f3Smrg#include "util/xmlconfig.h"
767ec681f3Smrg#include "u_atomic.h"
777ec681f3Smrg
787ec681f3Smrg#include "v3dv_entrypoints.h"
797ec681f3Smrg#include "v3dv_bo.h"
807ec681f3Smrg
817ec681f3Smrg#include "drm-uapi/v3d_drm.h"
827ec681f3Smrg
837ec681f3Smrg#include "vk_alloc.h"
847ec681f3Smrg#include "simulator/v3d_simulator.h"
857ec681f3Smrg
867ec681f3Smrg#include "v3dv_cl.h"
877ec681f3Smrg
887ec681f3Smrg#include "wsi_common.h"
897ec681f3Smrg
907ec681f3Smrg/* A non-fatal assert.  Useful for debugging. */
917ec681f3Smrg#ifdef DEBUG
927ec681f3Smrg#define v3dv_assert(x) ({ \
937ec681f3Smrg   if (unlikely(!(x))) \
947ec681f3Smrg      fprintf(stderr, "%s:%d ASSERT: %s", __FILE__, __LINE__, #x); \
957ec681f3Smrg})
967ec681f3Smrg#else
977ec681f3Smrg#define v3dv_assert(x)
987ec681f3Smrg#endif
997ec681f3Smrg
1007ec681f3Smrg#define perf_debug(...) do {                       \
1017ec681f3Smrg   if (unlikely(V3D_DEBUG & V3D_DEBUG_PERF))       \
1027ec681f3Smrg      fprintf(stderr, __VA_ARGS__);                \
1037ec681f3Smrg} while (0)
1047ec681f3Smrg
1057ec681f3Smrgstruct v3dv_instance;
1067ec681f3Smrg
1077ec681f3Smrg#ifdef USE_V3D_SIMULATOR
1087ec681f3Smrg#define using_v3d_simulator true
1097ec681f3Smrg#else
1107ec681f3Smrg#define using_v3d_simulator false
1117ec681f3Smrg#endif
1127ec681f3Smrg
1137ec681f3Smrgstruct v3d_simulator_file;
1147ec681f3Smrg
1157ec681f3Smrg/* Minimum required by the Vulkan 1.1 spec */
1167ec681f3Smrg#define MAX_MEMORY_ALLOCATION_SIZE (1ull << 30)
1177ec681f3Smrg
1187ec681f3Smrgstruct v3dv_physical_device {
1197ec681f3Smrg   struct vk_physical_device vk;
1207ec681f3Smrg
1217ec681f3Smrg   char *name;
1227ec681f3Smrg   int32_t render_fd;
1237ec681f3Smrg   int32_t display_fd;
1247ec681f3Smrg   int32_t master_fd;
1257ec681f3Smrg
1267ec681f3Smrg   /* We need these because it is not clear how to detect
1277ec681f3Smrg    * valid devids in a portable way
1287ec681f3Smrg     */
1297ec681f3Smrg   bool has_primary;
1307ec681f3Smrg   bool has_render;
1317ec681f3Smrg
1327ec681f3Smrg   dev_t primary_devid;
1337ec681f3Smrg   dev_t render_devid;
1347ec681f3Smrg
1357ec681f3Smrg   uint8_t driver_build_sha1[20];
1367ec681f3Smrg   uint8_t pipeline_cache_uuid[VK_UUID_SIZE];
1377ec681f3Smrg   uint8_t device_uuid[VK_UUID_SIZE];
1387ec681f3Smrg   uint8_t driver_uuid[VK_UUID_SIZE];
1397ec681f3Smrg
1407ec681f3Smrg   struct disk_cache *disk_cache;
1417ec681f3Smrg
1427ec681f3Smrg   mtx_t mutex;
1437ec681f3Smrg
1447ec681f3Smrg   struct wsi_device wsi_device;
1457ec681f3Smrg
1467ec681f3Smrg   VkPhysicalDeviceMemoryProperties memory;
1477ec681f3Smrg
1487ec681f3Smrg   struct v3d_device_info devinfo;
1497ec681f3Smrg
1507ec681f3Smrg   struct v3d_simulator_file *sim_file;
1517ec681f3Smrg
1527ec681f3Smrg   const struct v3d_compiler *compiler;
1537ec681f3Smrg   uint32_t next_program_id;
1547ec681f3Smrg
1557ec681f3Smrg   struct {
1567ec681f3Smrg      bool merge_jobs;
1577ec681f3Smrg   } options;
1587ec681f3Smrg};
1597ec681f3Smrg
1607ec681f3SmrgVkResult v3dv_physical_device_acquire_display(struct v3dv_instance *instance,
1617ec681f3Smrg                                              struct v3dv_physical_device *pdevice,
1627ec681f3Smrg                                              VkIcdSurfaceBase *surface);
1637ec681f3Smrg
1647ec681f3SmrgVkResult v3dv_wsi_init(struct v3dv_physical_device *physical_device);
1657ec681f3Smrgvoid v3dv_wsi_finish(struct v3dv_physical_device *physical_device);
1667ec681f3Smrgstruct v3dv_image *v3dv_wsi_get_image_from_swapchain(VkSwapchainKHR swapchain,
1677ec681f3Smrg                                                     uint32_t index);
1687ec681f3Smrg
1697ec681f3Smrgvoid v3dv_meta_clear_init(struct v3dv_device *device);
1707ec681f3Smrgvoid v3dv_meta_clear_finish(struct v3dv_device *device);
1717ec681f3Smrg
1727ec681f3Smrgvoid v3dv_meta_blit_init(struct v3dv_device *device);
1737ec681f3Smrgvoid v3dv_meta_blit_finish(struct v3dv_device *device);
1747ec681f3Smrg
1757ec681f3Smrgvoid v3dv_meta_texel_buffer_copy_init(struct v3dv_device *device);
1767ec681f3Smrgvoid v3dv_meta_texel_buffer_copy_finish(struct v3dv_device *device);
1777ec681f3Smrg
1787ec681f3Smrgbool v3dv_meta_can_use_tlb(struct v3dv_image *image,
1797ec681f3Smrg                           const VkOffset3D *offset,
1807ec681f3Smrg                           VkFormat *compat_format);
1817ec681f3Smrg
1827ec681f3Smrgstruct v3dv_instance {
1837ec681f3Smrg   struct vk_instance vk;
1847ec681f3Smrg
1857ec681f3Smrg   int physicalDeviceCount;
1867ec681f3Smrg   struct v3dv_physical_device physicalDevice;
1877ec681f3Smrg
1887ec681f3Smrg   bool pipeline_cache_enabled;
1897ec681f3Smrg   bool default_pipeline_cache_enabled;
1907ec681f3Smrg};
1917ec681f3Smrg
1927ec681f3Smrg/* Tracks wait threads spawned from a single vkQueueSubmit call */
1937ec681f3Smrgstruct v3dv_queue_submit_wait_info {
1947ec681f3Smrg   /*  struct vk_object_base base; ?*/
1957ec681f3Smrg   struct list_head list_link;
1967ec681f3Smrg
1977ec681f3Smrg   struct v3dv_device *device;
1987ec681f3Smrg
1997ec681f3Smrg   /* List of wait threads spawned for any command buffers in a particular
2007ec681f3Smrg    * call to vkQueueSubmit.
2017ec681f3Smrg    */
2027ec681f3Smrg   uint32_t wait_thread_count;
2037ec681f3Smrg   struct {
2047ec681f3Smrg      pthread_t thread;
2057ec681f3Smrg      bool finished;
2067ec681f3Smrg   } wait_threads[16];
2077ec681f3Smrg
2087ec681f3Smrg   /* The master wait thread for the entire submit. This will wait for all
2097ec681f3Smrg    * other threads in this submit to complete  before processing signal
2107ec681f3Smrg    * semaphores and fences.
2117ec681f3Smrg    */
2127ec681f3Smrg   pthread_t master_wait_thread;
2137ec681f3Smrg
2147ec681f3Smrg   /* List of semaphores (and fence) to signal after all wait threads completed
2157ec681f3Smrg    * and all command buffer jobs in the submission have been sent to the GPU.
2167ec681f3Smrg    */
2177ec681f3Smrg   uint32_t signal_semaphore_count;
2187ec681f3Smrg   VkSemaphore *signal_semaphores;
2197ec681f3Smrg   VkFence fence;
2207ec681f3Smrg};
2217ec681f3Smrg
2227ec681f3Smrgstruct v3dv_queue {
2237ec681f3Smrg   struct vk_queue vk;
2247ec681f3Smrg
2257ec681f3Smrg   struct v3dv_device *device;
2267ec681f3Smrg
2277ec681f3Smrg   /* A list of active v3dv_queue_submit_wait_info */
2287ec681f3Smrg   struct list_head submit_wait_list;
2297ec681f3Smrg
2307ec681f3Smrg   /* A mutex to prevent concurrent access to the list of wait threads */
2317ec681f3Smrg   mtx_t mutex;
2327ec681f3Smrg
2337ec681f3Smrg   struct v3dv_job *noop_job;
2347ec681f3Smrg};
2357ec681f3Smrg
2367ec681f3Smrg#define V3DV_META_BLIT_CACHE_KEY_SIZE              (4 * sizeof(uint32_t))
2377ec681f3Smrg#define V3DV_META_TEXEL_BUFFER_COPY_CACHE_KEY_SIZE (3 * sizeof(uint32_t) + \
2387ec681f3Smrg                                                    sizeof(VkComponentMapping))
2397ec681f3Smrg
2407ec681f3Smrgstruct v3dv_meta_color_clear_pipeline {
2417ec681f3Smrg   VkPipeline pipeline;
2427ec681f3Smrg   VkRenderPass pass;
2437ec681f3Smrg   bool cached;
2447ec681f3Smrg   uint64_t key;
2457ec681f3Smrg};
2467ec681f3Smrg
2477ec681f3Smrgstruct v3dv_meta_depth_clear_pipeline {
2487ec681f3Smrg   VkPipeline pipeline;
2497ec681f3Smrg   uint64_t key;
2507ec681f3Smrg};
2517ec681f3Smrg
2527ec681f3Smrgstruct v3dv_meta_blit_pipeline {
2537ec681f3Smrg   VkPipeline pipeline;
2547ec681f3Smrg   VkRenderPass pass;
2557ec681f3Smrg   VkRenderPass pass_no_load;
2567ec681f3Smrg   uint8_t key[V3DV_META_BLIT_CACHE_KEY_SIZE];
2577ec681f3Smrg};
2587ec681f3Smrg
2597ec681f3Smrgstruct v3dv_meta_texel_buffer_copy_pipeline {
2607ec681f3Smrg   VkPipeline pipeline;
2617ec681f3Smrg   VkRenderPass pass;
2627ec681f3Smrg   VkRenderPass pass_no_load;
2637ec681f3Smrg   uint8_t key[V3DV_META_TEXEL_BUFFER_COPY_CACHE_KEY_SIZE];
2647ec681f3Smrg};
2657ec681f3Smrg
2667ec681f3Smrgstruct v3dv_pipeline_key {
2677ec681f3Smrg   bool robust_buffer_access;
2687ec681f3Smrg   uint8_t topology;
2697ec681f3Smrg   uint8_t logicop_func;
2707ec681f3Smrg   bool msaa;
2717ec681f3Smrg   bool sample_coverage;
2727ec681f3Smrg   bool sample_alpha_to_coverage;
2737ec681f3Smrg   bool sample_alpha_to_one;
2747ec681f3Smrg   uint8_t cbufs;
2757ec681f3Smrg   struct {
2767ec681f3Smrg      enum pipe_format format;
2777ec681f3Smrg      const uint8_t *swizzle;
2787ec681f3Smrg   } color_fmt[V3D_MAX_DRAW_BUFFERS];
2797ec681f3Smrg   uint8_t f32_color_rb;
2807ec681f3Smrg   uint32_t va_swap_rb_mask;
2817ec681f3Smrg   bool has_multiview;
2827ec681f3Smrg};
2837ec681f3Smrg
2847ec681f3Smrgstruct v3dv_pipeline_cache_stats {
2857ec681f3Smrg   uint32_t miss;
2867ec681f3Smrg   uint32_t hit;
2877ec681f3Smrg   uint32_t count;
2887ec681f3Smrg};
2897ec681f3Smrg
2907ec681f3Smrg/* Equivalent to gl_shader_stage, but including the coordinate shaders
2917ec681f3Smrg *
2927ec681f3Smrg * FIXME: perhaps move to common
2937ec681f3Smrg */
2947ec681f3Smrgenum broadcom_shader_stage {
2957ec681f3Smrg   BROADCOM_SHADER_VERTEX,
2967ec681f3Smrg   BROADCOM_SHADER_VERTEX_BIN,
2977ec681f3Smrg   BROADCOM_SHADER_GEOMETRY,
2987ec681f3Smrg   BROADCOM_SHADER_GEOMETRY_BIN,
2997ec681f3Smrg   BROADCOM_SHADER_FRAGMENT,
3007ec681f3Smrg   BROADCOM_SHADER_COMPUTE,
3017ec681f3Smrg};
3027ec681f3Smrg
3037ec681f3Smrg#define BROADCOM_SHADER_STAGES (BROADCOM_SHADER_COMPUTE + 1)
3047ec681f3Smrg
3057ec681f3Smrg/* Assumes that coordinate shaders will be custom-handled by the caller */
3067ec681f3Smrgstatic inline enum broadcom_shader_stage
3077ec681f3Smrggl_shader_stage_to_broadcom(gl_shader_stage stage)
3087ec681f3Smrg{
3097ec681f3Smrg   switch (stage) {
3107ec681f3Smrg   case MESA_SHADER_VERTEX:
3117ec681f3Smrg      return BROADCOM_SHADER_VERTEX;
3127ec681f3Smrg   case MESA_SHADER_GEOMETRY:
3137ec681f3Smrg      return BROADCOM_SHADER_GEOMETRY;
3147ec681f3Smrg   case MESA_SHADER_FRAGMENT:
3157ec681f3Smrg      return BROADCOM_SHADER_FRAGMENT;
3167ec681f3Smrg   case MESA_SHADER_COMPUTE:
3177ec681f3Smrg      return BROADCOM_SHADER_COMPUTE;
3187ec681f3Smrg   default:
3197ec681f3Smrg      unreachable("Unknown gl shader stage");
3207ec681f3Smrg   }
3217ec681f3Smrg}
3227ec681f3Smrg
3237ec681f3Smrgstatic inline gl_shader_stage
3247ec681f3Smrgbroadcom_shader_stage_to_gl(enum broadcom_shader_stage stage)
3257ec681f3Smrg{
3267ec681f3Smrg   switch (stage) {
3277ec681f3Smrg   case BROADCOM_SHADER_VERTEX:
3287ec681f3Smrg   case BROADCOM_SHADER_VERTEX_BIN:
3297ec681f3Smrg      return MESA_SHADER_VERTEX;
3307ec681f3Smrg   case BROADCOM_SHADER_GEOMETRY:
3317ec681f3Smrg   case BROADCOM_SHADER_GEOMETRY_BIN:
3327ec681f3Smrg      return MESA_SHADER_GEOMETRY;
3337ec681f3Smrg   case BROADCOM_SHADER_FRAGMENT:
3347ec681f3Smrg      return MESA_SHADER_FRAGMENT;
3357ec681f3Smrg   case BROADCOM_SHADER_COMPUTE:
3367ec681f3Smrg      return MESA_SHADER_COMPUTE;
3377ec681f3Smrg   default:
3387ec681f3Smrg      unreachable("Unknown broadcom shader stage");
3397ec681f3Smrg   }
3407ec681f3Smrg}
3417ec681f3Smrg
3427ec681f3Smrgstatic inline bool
3437ec681f3Smrgbroadcom_shader_stage_is_binning(enum broadcom_shader_stage stage)
3447ec681f3Smrg{
3457ec681f3Smrg   switch (stage) {
3467ec681f3Smrg   case BROADCOM_SHADER_VERTEX_BIN:
3477ec681f3Smrg   case BROADCOM_SHADER_GEOMETRY_BIN:
3487ec681f3Smrg      return true;
3497ec681f3Smrg   default:
3507ec681f3Smrg      return false;
3517ec681f3Smrg   }
3527ec681f3Smrg}
3537ec681f3Smrg
3547ec681f3Smrgstatic inline bool
3557ec681f3Smrgbroadcom_shader_stage_is_render_with_binning(enum broadcom_shader_stage stage)
3567ec681f3Smrg{
3577ec681f3Smrg   switch (stage) {
3587ec681f3Smrg   case BROADCOM_SHADER_VERTEX:
3597ec681f3Smrg   case BROADCOM_SHADER_GEOMETRY:
3607ec681f3Smrg      return true;
3617ec681f3Smrg   default:
3627ec681f3Smrg      return false;
3637ec681f3Smrg   }
3647ec681f3Smrg}
3657ec681f3Smrg
3667ec681f3Smrgstatic inline enum broadcom_shader_stage
3677ec681f3Smrgbroadcom_binning_shader_stage_for_render_stage(enum broadcom_shader_stage stage)
3687ec681f3Smrg{
3697ec681f3Smrg   switch (stage) {
3707ec681f3Smrg   case BROADCOM_SHADER_VERTEX:
3717ec681f3Smrg      return BROADCOM_SHADER_VERTEX_BIN;
3727ec681f3Smrg   case BROADCOM_SHADER_GEOMETRY:
3737ec681f3Smrg      return BROADCOM_SHADER_GEOMETRY_BIN;
3747ec681f3Smrg   default:
3757ec681f3Smrg      unreachable("Invalid shader stage");
3767ec681f3Smrg   }
3777ec681f3Smrg}
3787ec681f3Smrg
3797ec681f3Smrgstatic inline const char *
3807ec681f3Smrgbroadcom_shader_stage_name(enum broadcom_shader_stage stage)
3817ec681f3Smrg{
3827ec681f3Smrg   switch(stage) {
3837ec681f3Smrg   case BROADCOM_SHADER_VERTEX_BIN:
3847ec681f3Smrg      return "MESA_SHADER_VERTEX_BIN";
3857ec681f3Smrg   case BROADCOM_SHADER_GEOMETRY_BIN:
3867ec681f3Smrg      return "MESA_SHADER_GEOMETRY_BIN";
3877ec681f3Smrg   default:
3887ec681f3Smrg      return gl_shader_stage_name(broadcom_shader_stage_to_gl(stage));
3897ec681f3Smrg   }
3907ec681f3Smrg}
3917ec681f3Smrg
3927ec681f3Smrgstruct v3dv_pipeline_cache {
3937ec681f3Smrg   struct vk_object_base base;
3947ec681f3Smrg
3957ec681f3Smrg   struct v3dv_device *device;
3967ec681f3Smrg   mtx_t mutex;
3977ec681f3Smrg
3987ec681f3Smrg   struct hash_table *nir_cache;
3997ec681f3Smrg   struct v3dv_pipeline_cache_stats nir_stats;
4007ec681f3Smrg
4017ec681f3Smrg   struct hash_table *cache;
4027ec681f3Smrg   struct v3dv_pipeline_cache_stats stats;
4037ec681f3Smrg
4047ec681f3Smrg   /* For VK_EXT_pipeline_creation_cache_control. */
4057ec681f3Smrg   bool externally_synchronized;
4067ec681f3Smrg};
4077ec681f3Smrg
4087ec681f3Smrgstruct v3dv_device {
4097ec681f3Smrg   struct vk_device vk;
4107ec681f3Smrg
4117ec681f3Smrg   struct v3dv_instance *instance;
4127ec681f3Smrg   struct v3dv_physical_device *pdevice;
4137ec681f3Smrg
4147ec681f3Smrg   struct v3d_device_info devinfo;
4157ec681f3Smrg   struct v3dv_queue queue;
4167ec681f3Smrg
4177ec681f3Smrg   /* A sync object to track the last job submitted to the GPU. */
4187ec681f3Smrg   uint32_t last_job_sync;
4197ec681f3Smrg
4207ec681f3Smrg   /* A mutex to prevent concurrent access to last_job_sync from the queue */
4217ec681f3Smrg   mtx_t mutex;
4227ec681f3Smrg
4237ec681f3Smrg   /* Resources used for meta operations */
4247ec681f3Smrg   struct {
4257ec681f3Smrg      mtx_t mtx;
4267ec681f3Smrg      struct {
4277ec681f3Smrg         VkPipelineLayout p_layout;
4287ec681f3Smrg         struct hash_table *cache; /* v3dv_meta_color_clear_pipeline */
4297ec681f3Smrg      } color_clear;
4307ec681f3Smrg      struct {
4317ec681f3Smrg         VkPipelineLayout p_layout;
4327ec681f3Smrg         struct hash_table *cache; /* v3dv_meta_depth_clear_pipeline */
4337ec681f3Smrg      } depth_clear;
4347ec681f3Smrg      struct {
4357ec681f3Smrg         VkDescriptorSetLayout ds_layout;
4367ec681f3Smrg         VkPipelineLayout p_layout;
4377ec681f3Smrg         struct hash_table *cache[3]; /* v3dv_meta_blit_pipeline for 1d, 2d, 3d */
4387ec681f3Smrg      } blit;
4397ec681f3Smrg      struct {
4407ec681f3Smrg         VkDescriptorSetLayout ds_layout;
4417ec681f3Smrg         VkPipelineLayout p_layout;
4427ec681f3Smrg         struct hash_table *cache[3]; /* v3dv_meta_texel_buffer_copy_pipeline for 1d, 2d, 3d */
4437ec681f3Smrg      } texel_buffer_copy;
4447ec681f3Smrg   } meta;
4457ec681f3Smrg
4467ec681f3Smrg   struct v3dv_bo_cache {
4477ec681f3Smrg      /** List of struct v3d_bo freed, by age. */
4487ec681f3Smrg      struct list_head time_list;
4497ec681f3Smrg      /** List of struct v3d_bo freed, per size, by age. */
4507ec681f3Smrg      struct list_head *size_list;
4517ec681f3Smrg      uint32_t size_list_size;
4527ec681f3Smrg
4537ec681f3Smrg      mtx_t lock;
4547ec681f3Smrg
4557ec681f3Smrg      uint32_t cache_size;
4567ec681f3Smrg      uint32_t cache_count;
4577ec681f3Smrg      uint32_t max_cache_size;
4587ec681f3Smrg   } bo_cache;
4597ec681f3Smrg
4607ec681f3Smrg   uint32_t bo_size;
4617ec681f3Smrg   uint32_t bo_count;
4627ec681f3Smrg
4637ec681f3Smrg   struct v3dv_pipeline_cache default_pipeline_cache;
4647ec681f3Smrg
4657ec681f3Smrg   /* GL_SHADER_STATE_RECORD needs to speficy default attribute values. The
4667ec681f3Smrg    * following covers the most common case, that is all attributes format
4677ec681f3Smrg    * being float being float, allowing us to reuse the same BO for all
4687ec681f3Smrg    * pipelines matching this requirement. Pipelines that need integer
4697ec681f3Smrg    * attributes will create their own BO.
4707ec681f3Smrg    */
4717ec681f3Smrg   struct v3dv_bo *default_attribute_float;
4727ec681f3Smrg   VkPhysicalDeviceFeatures features;
4737ec681f3Smrg};
4747ec681f3Smrg
4757ec681f3Smrgstruct v3dv_device_memory {
4767ec681f3Smrg   struct vk_object_base base;
4777ec681f3Smrg
4787ec681f3Smrg   struct v3dv_bo *bo;
4797ec681f3Smrg   const VkMemoryType *type;
4807ec681f3Smrg   bool has_bo_ownership;
4817ec681f3Smrg   bool is_for_wsi;
4827ec681f3Smrg};
4837ec681f3Smrg
4847ec681f3Smrg#define V3D_OUTPUT_IMAGE_FORMAT_NO 255
4857ec681f3Smrg#define TEXTURE_DATA_FORMAT_NO     255
4867ec681f3Smrg
4877ec681f3Smrgstruct v3dv_format {
4887ec681f3Smrg   bool supported;
4897ec681f3Smrg
4907ec681f3Smrg   /* One of V3D33_OUTPUT_IMAGE_FORMAT_*, or OUTPUT_IMAGE_FORMAT_NO */
4917ec681f3Smrg   uint8_t rt_type;
4927ec681f3Smrg
4937ec681f3Smrg   /* One of V3D33_TEXTURE_DATA_FORMAT_*. */
4947ec681f3Smrg   uint8_t tex_type;
4957ec681f3Smrg
4967ec681f3Smrg   /* Swizzle to apply to the RGBA shader output for storing to the tile
4977ec681f3Smrg    * buffer, to the RGBA tile buffer to produce shader input (for
4987ec681f3Smrg    * blending), and for turning the rgba8888 texture sampler return
4997ec681f3Smrg    * value into shader rgba values.
5007ec681f3Smrg    */
5017ec681f3Smrg   uint8_t swizzle[4];
5027ec681f3Smrg
5037ec681f3Smrg   /* Whether the return value is 16F/I/UI or 32F/I/UI. */
5047ec681f3Smrg   uint8_t return_size;
5057ec681f3Smrg
5067ec681f3Smrg   /* If the format supports (linear) filtering when texturing. */
5077ec681f3Smrg   bool supports_filtering;
5087ec681f3Smrg};
5097ec681f3Smrg
5107ec681f3Smrgstruct v3d_resource_slice {
5117ec681f3Smrg   uint32_t offset;
5127ec681f3Smrg   uint32_t stride;
5137ec681f3Smrg   uint32_t padded_height;
5147ec681f3Smrg   /* Size of a single pane of the slice.  For 3D textures, there will be
5157ec681f3Smrg    * a number of panes equal to the minified, power-of-two-aligned
5167ec681f3Smrg    * depth.
5177ec681f3Smrg    */
5187ec681f3Smrg   uint32_t size;
5197ec681f3Smrg   uint8_t ub_pad;
5207ec681f3Smrg   enum v3d_tiling_mode tiling;
5217ec681f3Smrg   uint32_t padded_height_of_output_image_in_uif_blocks;
5227ec681f3Smrg};
5237ec681f3Smrg
5247ec681f3Smrgstruct v3dv_image {
5257ec681f3Smrg   struct vk_image vk;
5267ec681f3Smrg
5277ec681f3Smrg   const struct v3dv_format *format;
5287ec681f3Smrg   uint32_t cpp;
5297ec681f3Smrg   bool tiled;
5307ec681f3Smrg
5317ec681f3Smrg   struct v3d_resource_slice slices[V3D_MAX_MIP_LEVELS];
5327ec681f3Smrg   uint64_t size; /* Total size in bytes */
5337ec681f3Smrg   uint32_t cube_map_stride;
5347ec681f3Smrg
5357ec681f3Smrg   struct v3dv_device_memory *mem;
5367ec681f3Smrg   VkDeviceSize mem_offset;
5377ec681f3Smrg   uint32_t alignment;
5387ec681f3Smrg};
5397ec681f3Smrg
5407ec681f3SmrgVkImageViewType v3dv_image_type_to_view_type(VkImageType type);
5417ec681f3Smrg
5427ec681f3Smrg/* Pre-generating packets needs to consider changes in packet sizes across hw
5437ec681f3Smrg * versions. Keep things simple and allocate enough space for any supported
5447ec681f3Smrg * version. We ensure the size is large enough through static asserts.
5457ec681f3Smrg */
5467ec681f3Smrg#define V3DV_TEXTURE_SHADER_STATE_LENGTH 32
5477ec681f3Smrg#define V3DV_SAMPLER_STATE_LENGTH 24
5487ec681f3Smrg#define V3DV_BLEND_CFG_LENGTH 5
5497ec681f3Smrg#define V3DV_CFG_BITS_LENGTH 4
5507ec681f3Smrg#define V3DV_GL_SHADER_STATE_RECORD_LENGTH 36
5517ec681f3Smrg#define V3DV_VCM_CACHE_SIZE_LENGTH 2
5527ec681f3Smrg#define V3DV_GL_SHADER_STATE_ATTRIBUTE_RECORD_LENGTH 16
5537ec681f3Smrg#define V3DV_STENCIL_CFG_LENGTH 6
5547ec681f3Smrg
5557ec681f3Smrgstruct v3dv_image_view {
5567ec681f3Smrg   struct vk_image_view vk;
5577ec681f3Smrg
5587ec681f3Smrg   const struct v3dv_format *format;
5597ec681f3Smrg   bool swap_rb;
5607ec681f3Smrg   uint32_t internal_bpp;
5617ec681f3Smrg   uint32_t internal_type;
5627ec681f3Smrg   uint32_t offset;
5637ec681f3Smrg
5647ec681f3Smrg   /* Precomputed (composed from createinfo->components and formar swizzle)
5657ec681f3Smrg    * swizzles to pass in to the shader key.
5667ec681f3Smrg    *
5677ec681f3Smrg    * This could be also included on the descriptor bo, but the shader state
5687ec681f3Smrg    * packet doesn't need it on a bo, so we can just avoid a memory copy
5697ec681f3Smrg    */
5707ec681f3Smrg   uint8_t swizzle[4];
5717ec681f3Smrg
5727ec681f3Smrg   /* Prepacked TEXTURE_SHADER_STATE. It will be copied to the descriptor info
5737ec681f3Smrg    * during UpdateDescriptorSets.
5747ec681f3Smrg    *
5757ec681f3Smrg    * Empirical tests show that cube arrays need a different shader state
5767ec681f3Smrg    * depending on whether they are used with a sampler or not, so for these
5777ec681f3Smrg    * we generate two states and select the one to use based on the descriptor
5787ec681f3Smrg    * type.
5797ec681f3Smrg    */
5807ec681f3Smrg   uint8_t texture_shader_state[2][V3DV_TEXTURE_SHADER_STATE_LENGTH];
5817ec681f3Smrg};
5827ec681f3Smrg
5837ec681f3Smrguint32_t v3dv_layer_offset(const struct v3dv_image *image, uint32_t level, uint32_t layer);
5847ec681f3Smrg
5857ec681f3Smrgstruct v3dv_buffer {
5867ec681f3Smrg   struct vk_object_base base;
5877ec681f3Smrg
5887ec681f3Smrg   VkDeviceSize size;
5897ec681f3Smrg   VkBufferUsageFlags usage;
5907ec681f3Smrg   uint32_t alignment;
5917ec681f3Smrg
5927ec681f3Smrg   struct v3dv_device_memory *mem;
5937ec681f3Smrg   VkDeviceSize mem_offset;
5947ec681f3Smrg};
5957ec681f3Smrg
5967ec681f3Smrgstruct v3dv_buffer_view {
5977ec681f3Smrg   struct vk_object_base base;
5987ec681f3Smrg
5997ec681f3Smrg   struct v3dv_buffer *buffer;
6007ec681f3Smrg
6017ec681f3Smrg   VkFormat vk_format;
6027ec681f3Smrg   const struct v3dv_format *format;
6037ec681f3Smrg   uint32_t internal_bpp;
6047ec681f3Smrg   uint32_t internal_type;
6057ec681f3Smrg
6067ec681f3Smrg   uint32_t offset;
6077ec681f3Smrg   uint32_t size;
6087ec681f3Smrg   uint32_t num_elements;
6097ec681f3Smrg
6107ec681f3Smrg   /* Prepacked TEXTURE_SHADER_STATE. */
6117ec681f3Smrg   uint8_t texture_shader_state[V3DV_TEXTURE_SHADER_STATE_LENGTH];
6127ec681f3Smrg};
6137ec681f3Smrg
6147ec681f3Smrgstruct v3dv_subpass_attachment {
6157ec681f3Smrg   uint32_t attachment;
6167ec681f3Smrg   VkImageLayout layout;
6177ec681f3Smrg};
6187ec681f3Smrg
6197ec681f3Smrgstruct v3dv_subpass {
6207ec681f3Smrg   uint32_t input_count;
6217ec681f3Smrg   struct v3dv_subpass_attachment *input_attachments;
6227ec681f3Smrg
6237ec681f3Smrg   uint32_t color_count;
6247ec681f3Smrg   struct v3dv_subpass_attachment *color_attachments;
6257ec681f3Smrg   struct v3dv_subpass_attachment *resolve_attachments;
6267ec681f3Smrg
6277ec681f3Smrg   struct v3dv_subpass_attachment ds_attachment;
6287ec681f3Smrg
6297ec681f3Smrg   /* If we need to emit the clear of the depth/stencil attachment using a
6307ec681f3Smrg    * a draw call instead of using the TLB (GFXH-1461).
6317ec681f3Smrg    */
6327ec681f3Smrg   bool do_depth_clear_with_draw;
6337ec681f3Smrg   bool do_stencil_clear_with_draw;
6347ec681f3Smrg
6357ec681f3Smrg   /* Multiview */
6367ec681f3Smrg   uint32_t view_mask;
6377ec681f3Smrg};
6387ec681f3Smrg
6397ec681f3Smrgstruct v3dv_render_pass_attachment {
6407ec681f3Smrg   VkAttachmentDescription desc;
6417ec681f3Smrg
6427ec681f3Smrg   uint32_t first_subpass;
6437ec681f3Smrg   uint32_t last_subpass;
6447ec681f3Smrg
6457ec681f3Smrg   /* When multiview is enabled, we no longer care about when a particular
6467ec681f3Smrg    * attachment is first or last used in a render pass, since not all views
6477ec681f3Smrg    * in the attachment will meet that criteria. Instead, we need to track
6487ec681f3Smrg    * each individual view (layer) in each attachment and emit our stores,
6497ec681f3Smrg    * loads and clears accordingly.
6507ec681f3Smrg    */
6517ec681f3Smrg   struct {
6527ec681f3Smrg      uint32_t first_subpass;
6537ec681f3Smrg      uint32_t last_subpass;
6547ec681f3Smrg   } views[MAX_MULTIVIEW_VIEW_COUNT];
6557ec681f3Smrg
6567ec681f3Smrg   /* If this is a multismapled attachment that is going to be resolved,
6577ec681f3Smrg    * whether we can use the TLB resolve on store.
6587ec681f3Smrg    */
6597ec681f3Smrg   bool use_tlb_resolve;
6607ec681f3Smrg};
6617ec681f3Smrg
6627ec681f3Smrgstruct v3dv_render_pass {
6637ec681f3Smrg   struct vk_object_base base;
6647ec681f3Smrg
6657ec681f3Smrg   bool multiview_enabled;
6667ec681f3Smrg
6677ec681f3Smrg   uint32_t attachment_count;
6687ec681f3Smrg   struct v3dv_render_pass_attachment *attachments;
6697ec681f3Smrg
6707ec681f3Smrg   uint32_t subpass_count;
6717ec681f3Smrg   struct v3dv_subpass *subpasses;
6727ec681f3Smrg
6737ec681f3Smrg   struct v3dv_subpass_attachment *subpass_attachments;
6747ec681f3Smrg};
6757ec681f3Smrg
6767ec681f3Smrgstruct v3dv_framebuffer {
6777ec681f3Smrg   struct vk_object_base base;
6787ec681f3Smrg
6797ec681f3Smrg   uint32_t width;
6807ec681f3Smrg   uint32_t height;
6817ec681f3Smrg   uint32_t layers;
6827ec681f3Smrg
6837ec681f3Smrg   /* Typically, edge tiles in the framebuffer have padding depending on the
6847ec681f3Smrg    * underlying tiling layout. One consequnce of this is that when the
6857ec681f3Smrg    * framebuffer dimensions are not aligned to tile boundaries, tile stores
6867ec681f3Smrg    * would still write full tiles on the edges and write to the padded area.
6877ec681f3Smrg    * If the framebuffer is aliasing a smaller region of a larger image, then
6887ec681f3Smrg    * we need to be careful with this though, as we won't have padding on the
6897ec681f3Smrg    * edge tiles (which typically means that we need to load the tile buffer
6907ec681f3Smrg    * before we store).
6917ec681f3Smrg    */
6927ec681f3Smrg   bool has_edge_padding;
6937ec681f3Smrg
6947ec681f3Smrg   uint32_t attachment_count;
6957ec681f3Smrg   uint32_t color_attachment_count;
6967ec681f3Smrg   struct v3dv_image_view *attachments[0];
6977ec681f3Smrg};
6987ec681f3Smrg
6997ec681f3Smrgstruct v3dv_frame_tiling {
7007ec681f3Smrg   uint32_t width;
7017ec681f3Smrg   uint32_t height;
7027ec681f3Smrg   uint32_t layers;
7037ec681f3Smrg   uint32_t render_target_count;
7047ec681f3Smrg   uint32_t internal_bpp;
7057ec681f3Smrg   bool     msaa;
7067ec681f3Smrg   uint32_t tile_width;
7077ec681f3Smrg   uint32_t tile_height;
7087ec681f3Smrg   uint32_t draw_tiles_x;
7097ec681f3Smrg   uint32_t draw_tiles_y;
7107ec681f3Smrg   uint32_t supertile_width;
7117ec681f3Smrg   uint32_t supertile_height;
7127ec681f3Smrg   uint32_t frame_width_in_supertiles;
7137ec681f3Smrg   uint32_t frame_height_in_supertiles;
7147ec681f3Smrg};
7157ec681f3Smrg
7167ec681f3Smrgvoid v3dv_framebuffer_compute_internal_bpp_msaa(const struct v3dv_framebuffer *framebuffer,
7177ec681f3Smrg                                                const struct v3dv_subpass *subpass,
7187ec681f3Smrg                                                uint8_t *max_bpp, bool *msaa);
7197ec681f3Smrg
7207ec681f3Smrgbool v3dv_subpass_area_is_tile_aligned(struct v3dv_device *device,
7217ec681f3Smrg                                       const VkRect2D *area,
7227ec681f3Smrg                                       struct v3dv_framebuffer *fb,
7237ec681f3Smrg                                       struct v3dv_render_pass *pass,
7247ec681f3Smrg                                       uint32_t subpass_idx);
7257ec681f3Smrg
7267ec681f3Smrgstruct v3dv_cmd_pool {
7277ec681f3Smrg   struct vk_object_base base;
7287ec681f3Smrg
7297ec681f3Smrg   VkAllocationCallbacks alloc;
7307ec681f3Smrg   struct list_head cmd_buffers;
7317ec681f3Smrg};
7327ec681f3Smrg
7337ec681f3Smrgenum v3dv_cmd_buffer_status {
7347ec681f3Smrg   V3DV_CMD_BUFFER_STATUS_NEW           = 0,
7357ec681f3Smrg   V3DV_CMD_BUFFER_STATUS_INITIALIZED   = 1,
7367ec681f3Smrg   V3DV_CMD_BUFFER_STATUS_RECORDING     = 2,
7377ec681f3Smrg   V3DV_CMD_BUFFER_STATUS_EXECUTABLE    = 3
7387ec681f3Smrg};
7397ec681f3Smrg
7407ec681f3Smrgunion v3dv_clear_value {
7417ec681f3Smrg   uint32_t color[4];
7427ec681f3Smrg   struct {
7437ec681f3Smrg      float z;
7447ec681f3Smrg      uint8_t s;
7457ec681f3Smrg   };
7467ec681f3Smrg};
7477ec681f3Smrg
7487ec681f3Smrgstruct v3dv_cmd_buffer_attachment_state {
7497ec681f3Smrg   /* The original clear value as provided by the Vulkan API */
7507ec681f3Smrg   VkClearValue vk_clear_value;
7517ec681f3Smrg
7527ec681f3Smrg   /* The hardware clear value */
7537ec681f3Smrg   union v3dv_clear_value clear_value;
7547ec681f3Smrg};
7557ec681f3Smrg
7567ec681f3Smrgstruct v3dv_viewport_state {
7577ec681f3Smrg   uint32_t count;
7587ec681f3Smrg   VkViewport viewports[MAX_VIEWPORTS];
7597ec681f3Smrg   float translate[MAX_VIEWPORTS][3];
7607ec681f3Smrg   float scale[MAX_VIEWPORTS][3];
7617ec681f3Smrg};
7627ec681f3Smrg
7637ec681f3Smrgstruct v3dv_scissor_state {
7647ec681f3Smrg   uint32_t count;
7657ec681f3Smrg   VkRect2D scissors[MAX_SCISSORS];
7667ec681f3Smrg};
7677ec681f3Smrg
7687ec681f3Smrg/* Mostly a v3dv mapping of VkDynamicState, used to track which data as
7697ec681f3Smrg * defined as dynamic
7707ec681f3Smrg */
7717ec681f3Smrgenum v3dv_dynamic_state_bits {
7727ec681f3Smrg   V3DV_DYNAMIC_VIEWPORT                  = 1 << 0,
7737ec681f3Smrg   V3DV_DYNAMIC_SCISSOR                   = 1 << 1,
7747ec681f3Smrg   V3DV_DYNAMIC_STENCIL_COMPARE_MASK      = 1 << 2,
7757ec681f3Smrg   V3DV_DYNAMIC_STENCIL_WRITE_MASK        = 1 << 3,
7767ec681f3Smrg   V3DV_DYNAMIC_STENCIL_REFERENCE         = 1 << 4,
7777ec681f3Smrg   V3DV_DYNAMIC_BLEND_CONSTANTS           = 1 << 5,
7787ec681f3Smrg   V3DV_DYNAMIC_DEPTH_BIAS                = 1 << 6,
7797ec681f3Smrg   V3DV_DYNAMIC_LINE_WIDTH                = 1 << 7,
7807ec681f3Smrg   V3DV_DYNAMIC_COLOR_WRITE_ENABLE        = 1 << 8,
7817ec681f3Smrg   V3DV_DYNAMIC_ALL                       = (1 << 9) - 1,
7827ec681f3Smrg};
7837ec681f3Smrg
7847ec681f3Smrg/* Flags for dirty pipeline state.
7857ec681f3Smrg */
7867ec681f3Smrgenum v3dv_cmd_dirty_bits {
7877ec681f3Smrg   V3DV_CMD_DIRTY_VIEWPORT                  = 1 << 0,
7887ec681f3Smrg   V3DV_CMD_DIRTY_SCISSOR                   = 1 << 1,
7897ec681f3Smrg   V3DV_CMD_DIRTY_STENCIL_COMPARE_MASK      = 1 << 2,
7907ec681f3Smrg   V3DV_CMD_DIRTY_STENCIL_WRITE_MASK        = 1 << 3,
7917ec681f3Smrg   V3DV_CMD_DIRTY_STENCIL_REFERENCE         = 1 << 4,
7927ec681f3Smrg   V3DV_CMD_DIRTY_PIPELINE                  = 1 << 5,
7937ec681f3Smrg   V3DV_CMD_DIRTY_COMPUTE_PIPELINE          = 1 << 6,
7947ec681f3Smrg   V3DV_CMD_DIRTY_VERTEX_BUFFER             = 1 << 7,
7957ec681f3Smrg   V3DV_CMD_DIRTY_INDEX_BUFFER              = 1 << 8,
7967ec681f3Smrg   V3DV_CMD_DIRTY_DESCRIPTOR_SETS           = 1 << 9,
7977ec681f3Smrg   V3DV_CMD_DIRTY_COMPUTE_DESCRIPTOR_SETS   = 1 << 10,
7987ec681f3Smrg   V3DV_CMD_DIRTY_PUSH_CONSTANTS            = 1 << 11,
7997ec681f3Smrg   V3DV_CMD_DIRTY_BLEND_CONSTANTS           = 1 << 12,
8007ec681f3Smrg   V3DV_CMD_DIRTY_OCCLUSION_QUERY           = 1 << 13,
8017ec681f3Smrg   V3DV_CMD_DIRTY_DEPTH_BIAS                = 1 << 14,
8027ec681f3Smrg   V3DV_CMD_DIRTY_LINE_WIDTH                = 1 << 15,
8037ec681f3Smrg   V3DV_CMD_DIRTY_VIEW_INDEX                = 1 << 16,
8047ec681f3Smrg   V3DV_CMD_DIRTY_COLOR_WRITE_ENABLE        = 1 << 17,
8057ec681f3Smrg};
8067ec681f3Smrg
8077ec681f3Smrgstruct v3dv_dynamic_state {
8087ec681f3Smrg   /**
8097ec681f3Smrg    * Bitmask of (1 << VK_DYNAMIC_STATE_*).
8107ec681f3Smrg    * Defines the set of saved dynamic state.
8117ec681f3Smrg    */
8127ec681f3Smrg   uint32_t mask;
8137ec681f3Smrg
8147ec681f3Smrg   struct v3dv_viewport_state viewport;
8157ec681f3Smrg
8167ec681f3Smrg   struct v3dv_scissor_state scissor;
8177ec681f3Smrg
8187ec681f3Smrg   struct {
8197ec681f3Smrg      uint32_t front;
8207ec681f3Smrg      uint32_t back;
8217ec681f3Smrg   } stencil_compare_mask;
8227ec681f3Smrg
8237ec681f3Smrg   struct {
8247ec681f3Smrg      uint32_t front;
8257ec681f3Smrg      uint32_t back;
8267ec681f3Smrg   } stencil_write_mask;
8277ec681f3Smrg
8287ec681f3Smrg   struct {
8297ec681f3Smrg      uint32_t front;
8307ec681f3Smrg      uint32_t back;
8317ec681f3Smrg   } stencil_reference;
8327ec681f3Smrg
8337ec681f3Smrg   float blend_constants[4];
8347ec681f3Smrg
8357ec681f3Smrg   struct {
8367ec681f3Smrg      float constant_factor;
8377ec681f3Smrg      float depth_bias_clamp;
8387ec681f3Smrg      float slope_factor;
8397ec681f3Smrg   } depth_bias;
8407ec681f3Smrg
8417ec681f3Smrg   float line_width;
8427ec681f3Smrg
8437ec681f3Smrg   uint32_t color_write_enable;
8447ec681f3Smrg};
8457ec681f3Smrg
8467ec681f3Smrgextern const struct v3dv_dynamic_state default_dynamic_state;
8477ec681f3Smrg
8487ec681f3Smrgvoid v3dv_viewport_compute_xform(const VkViewport *viewport,
8497ec681f3Smrg                                 float scale[3],
8507ec681f3Smrg                                 float translate[3]);
8517ec681f3Smrg
8527ec681f3Smrgenum v3dv_ez_state {
8537ec681f3Smrg   V3D_EZ_UNDECIDED = 0,
8547ec681f3Smrg   V3D_EZ_GT_GE,
8557ec681f3Smrg   V3D_EZ_LT_LE,
8567ec681f3Smrg   V3D_EZ_DISABLED,
8577ec681f3Smrg};
8587ec681f3Smrg
8597ec681f3Smrgenum v3dv_job_type {
8607ec681f3Smrg   V3DV_JOB_TYPE_GPU_CL = 0,
8617ec681f3Smrg   V3DV_JOB_TYPE_GPU_CL_SECONDARY,
8627ec681f3Smrg   V3DV_JOB_TYPE_GPU_TFU,
8637ec681f3Smrg   V3DV_JOB_TYPE_GPU_CSD,
8647ec681f3Smrg   V3DV_JOB_TYPE_CPU_RESET_QUERIES,
8657ec681f3Smrg   V3DV_JOB_TYPE_CPU_END_QUERY,
8667ec681f3Smrg   V3DV_JOB_TYPE_CPU_COPY_QUERY_RESULTS,
8677ec681f3Smrg   V3DV_JOB_TYPE_CPU_SET_EVENT,
8687ec681f3Smrg   V3DV_JOB_TYPE_CPU_WAIT_EVENTS,
8697ec681f3Smrg   V3DV_JOB_TYPE_CPU_COPY_BUFFER_TO_IMAGE,
8707ec681f3Smrg   V3DV_JOB_TYPE_CPU_CSD_INDIRECT,
8717ec681f3Smrg   V3DV_JOB_TYPE_CPU_TIMESTAMP_QUERY,
8727ec681f3Smrg};
8737ec681f3Smrg
8747ec681f3Smrgstruct v3dv_reset_query_cpu_job_info {
8757ec681f3Smrg   struct v3dv_query_pool *pool;
8767ec681f3Smrg   uint32_t first;
8777ec681f3Smrg   uint32_t count;
8787ec681f3Smrg};
8797ec681f3Smrg
8807ec681f3Smrgstruct v3dv_end_query_cpu_job_info {
8817ec681f3Smrg   struct v3dv_query_pool *pool;
8827ec681f3Smrg   uint32_t query;
8837ec681f3Smrg
8847ec681f3Smrg   /* This is one unless multiview is used */
8857ec681f3Smrg   uint32_t count;
8867ec681f3Smrg};
8877ec681f3Smrg
8887ec681f3Smrgstruct v3dv_copy_query_results_cpu_job_info {
8897ec681f3Smrg   struct v3dv_query_pool *pool;
8907ec681f3Smrg   uint32_t first;
8917ec681f3Smrg   uint32_t count;
8927ec681f3Smrg   struct v3dv_buffer *dst;
8937ec681f3Smrg   uint32_t offset;
8947ec681f3Smrg   uint32_t stride;
8957ec681f3Smrg   VkQueryResultFlags flags;
8967ec681f3Smrg};
8977ec681f3Smrg
8987ec681f3Smrgstruct v3dv_event_set_cpu_job_info {
8997ec681f3Smrg   struct v3dv_event *event;
9007ec681f3Smrg   int state;
9017ec681f3Smrg};
9027ec681f3Smrg
9037ec681f3Smrgstruct v3dv_event_wait_cpu_job_info {
9047ec681f3Smrg   /* List of events to wait on */
9057ec681f3Smrg   uint32_t event_count;
9067ec681f3Smrg   struct v3dv_event **events;
9077ec681f3Smrg
9087ec681f3Smrg   /* Whether any postponed jobs after the wait should wait on semaphores */
9097ec681f3Smrg   bool sem_wait;
9107ec681f3Smrg};
9117ec681f3Smrg
9127ec681f3Smrgstruct v3dv_copy_buffer_to_image_cpu_job_info {
9137ec681f3Smrg   struct v3dv_image *image;
9147ec681f3Smrg   struct v3dv_buffer *buffer;
9157ec681f3Smrg   uint32_t buffer_offset;
9167ec681f3Smrg   uint32_t buffer_stride;
9177ec681f3Smrg   uint32_t buffer_layer_stride;
9187ec681f3Smrg   VkOffset3D image_offset;
9197ec681f3Smrg   VkExtent3D image_extent;
9207ec681f3Smrg   uint32_t mip_level;
9217ec681f3Smrg   uint32_t base_layer;
9227ec681f3Smrg   uint32_t layer_count;
9237ec681f3Smrg};
9247ec681f3Smrg
9257ec681f3Smrgstruct v3dv_csd_indirect_cpu_job_info {
9267ec681f3Smrg   struct v3dv_buffer *buffer;
9277ec681f3Smrg   uint32_t offset;
9287ec681f3Smrg   struct v3dv_job *csd_job;
9297ec681f3Smrg   uint32_t wg_size;
9307ec681f3Smrg   uint32_t *wg_uniform_offsets[3];
9317ec681f3Smrg   bool needs_wg_uniform_rewrite;
9327ec681f3Smrg};
9337ec681f3Smrg
9347ec681f3Smrgstruct v3dv_timestamp_query_cpu_job_info {
9357ec681f3Smrg   struct v3dv_query_pool *pool;
9367ec681f3Smrg   uint32_t query;
9377ec681f3Smrg
9387ec681f3Smrg   /* This is one unless multiview is used */
9397ec681f3Smrg   uint32_t count;
9407ec681f3Smrg};
9417ec681f3Smrg
9427ec681f3Smrgstruct v3dv_job {
9437ec681f3Smrg   struct list_head list_link;
9447ec681f3Smrg
9457ec681f3Smrg   /* We only create job clones when executing secondary command buffers into
9467ec681f3Smrg    * primaries. These clones don't make deep copies of the original object
9477ec681f3Smrg    * so we want to flag them to avoid freeing resources they don't own.
9487ec681f3Smrg    */
9497ec681f3Smrg   bool is_clone;
9507ec681f3Smrg
9517ec681f3Smrg   enum v3dv_job_type type;
9527ec681f3Smrg
9537ec681f3Smrg   struct v3dv_device *device;
9547ec681f3Smrg
9557ec681f3Smrg   struct v3dv_cmd_buffer *cmd_buffer;
9567ec681f3Smrg
9577ec681f3Smrg   struct v3dv_cl bcl;
9587ec681f3Smrg   struct v3dv_cl rcl;
9597ec681f3Smrg   struct v3dv_cl indirect;
9607ec681f3Smrg
9617ec681f3Smrg   /* Set of all BOs referenced by the job. This will be used for making
9627ec681f3Smrg    * the list of BOs that the kernel will need to have paged in to
9637ec681f3Smrg    * execute our job.
9647ec681f3Smrg    */
9657ec681f3Smrg   struct set *bos;
9667ec681f3Smrg   uint32_t bo_count;
9677ec681f3Smrg   uint64_t bo_handle_mask;
9687ec681f3Smrg
9697ec681f3Smrg   struct v3dv_bo *tile_alloc;
9707ec681f3Smrg   struct v3dv_bo *tile_state;
9717ec681f3Smrg
9727ec681f3Smrg   bool tmu_dirty_rcl;
9737ec681f3Smrg
9747ec681f3Smrg   uint32_t first_subpass;
9757ec681f3Smrg
9767ec681f3Smrg   /* When the current subpass is split into multiple jobs, this flag is set
9777ec681f3Smrg    * to true for any jobs after the first in the same subpass.
9787ec681f3Smrg    */
9797ec681f3Smrg   bool is_subpass_continue;
9807ec681f3Smrg
9817ec681f3Smrg   /* If this job is the last job emitted for a subpass. */
9827ec681f3Smrg   bool is_subpass_finish;
9837ec681f3Smrg
9847ec681f3Smrg   struct v3dv_frame_tiling frame_tiling;
9857ec681f3Smrg
9867ec681f3Smrg   enum v3dv_ez_state ez_state;
9877ec681f3Smrg   enum v3dv_ez_state first_ez_state;
9887ec681f3Smrg
9897ec681f3Smrg   /* If we have already decided if we need to disable Early Z/S completely
9907ec681f3Smrg    * for this job.
9917ec681f3Smrg    */
9927ec681f3Smrg   bool decided_global_ez_enable;
9937ec681f3Smrg
9947ec681f3Smrg   /* If this job has been configured to use early Z/S clear */
9957ec681f3Smrg   bool early_zs_clear;
9967ec681f3Smrg
9977ec681f3Smrg   /* Number of draw calls recorded into the job */
9987ec681f3Smrg   uint32_t draw_count;
9997ec681f3Smrg
10007ec681f3Smrg   /* A flag indicating whether we want to flush every draw separately. This
10017ec681f3Smrg    * can be used for debugging, or for cases where special circumstances
10027ec681f3Smrg    * require this behavior.
10037ec681f3Smrg    */
10047ec681f3Smrg   bool always_flush;
10057ec681f3Smrg
10067ec681f3Smrg   /* Whether we need to serialize this job in our command stream */
10077ec681f3Smrg   bool serialize;
10087ec681f3Smrg
10097ec681f3Smrg   /* If this is a CL job, whether we should sync before binning */
10107ec681f3Smrg   bool needs_bcl_sync;
10117ec681f3Smrg
10127ec681f3Smrg   /* Job specs for CPU jobs */
10137ec681f3Smrg   union {
10147ec681f3Smrg      struct v3dv_reset_query_cpu_job_info          query_reset;
10157ec681f3Smrg      struct v3dv_end_query_cpu_job_info            query_end;
10167ec681f3Smrg      struct v3dv_copy_query_results_cpu_job_info   query_copy_results;
10177ec681f3Smrg      struct v3dv_event_set_cpu_job_info            event_set;
10187ec681f3Smrg      struct v3dv_event_wait_cpu_job_info           event_wait;
10197ec681f3Smrg      struct v3dv_copy_buffer_to_image_cpu_job_info copy_buffer_to_image;
10207ec681f3Smrg      struct v3dv_csd_indirect_cpu_job_info         csd_indirect;
10217ec681f3Smrg      struct v3dv_timestamp_query_cpu_job_info      query_timestamp;
10227ec681f3Smrg   } cpu;
10237ec681f3Smrg
10247ec681f3Smrg   /* Job specs for TFU jobs */
10257ec681f3Smrg   struct drm_v3d_submit_tfu tfu;
10267ec681f3Smrg
10277ec681f3Smrg   /* Job specs for CSD jobs */
10287ec681f3Smrg   struct {
10297ec681f3Smrg      struct v3dv_bo *shared_memory;
10307ec681f3Smrg      uint32_t wg_count[3];
10317ec681f3Smrg      uint32_t wg_base[3];
10327ec681f3Smrg      struct drm_v3d_submit_csd submit;
10337ec681f3Smrg   } csd;
10347ec681f3Smrg};
10357ec681f3Smrg
10367ec681f3Smrgvoid v3dv_job_init(struct v3dv_job *job,
10377ec681f3Smrg                   enum v3dv_job_type type,
10387ec681f3Smrg                   struct v3dv_device *device,
10397ec681f3Smrg                   struct v3dv_cmd_buffer *cmd_buffer,
10407ec681f3Smrg                   int32_t subpass_idx);
10417ec681f3Smrgvoid v3dv_job_destroy(struct v3dv_job *job);
10427ec681f3Smrg
10437ec681f3Smrgvoid v3dv_job_add_bo(struct v3dv_job *job, struct v3dv_bo *bo);
10447ec681f3Smrgvoid v3dv_job_add_bo_unchecked(struct v3dv_job *job, struct v3dv_bo *bo);
10457ec681f3Smrg
10467ec681f3Smrgvoid v3dv_job_start_frame(struct v3dv_job *job,
10477ec681f3Smrg                          uint32_t width,
10487ec681f3Smrg                          uint32_t height,
10497ec681f3Smrg                          uint32_t layers,
10507ec681f3Smrg                          bool allocate_tile_state_for_all_layers,
10517ec681f3Smrg                          uint32_t render_target_count,
10527ec681f3Smrg                          uint8_t max_internal_bpp,
10537ec681f3Smrg                          bool msaa);
10547ec681f3Smrg
10557ec681f3Smrgstruct v3dv_job *
10567ec681f3Smrgv3dv_job_clone_in_cmd_buffer(struct v3dv_job *job,
10577ec681f3Smrg                             struct v3dv_cmd_buffer *cmd_buffer);
10587ec681f3Smrg
10597ec681f3Smrgstruct v3dv_job *v3dv_cmd_buffer_create_cpu_job(struct v3dv_device *device,
10607ec681f3Smrg                                                enum v3dv_job_type type,
10617ec681f3Smrg                                                struct v3dv_cmd_buffer *cmd_buffer,
10627ec681f3Smrg                                                uint32_t subpass_idx);
10637ec681f3Smrg
10647ec681f3Smrgvoid
10657ec681f3Smrgv3dv_cmd_buffer_ensure_array_state(struct v3dv_cmd_buffer *cmd_buffer,
10667ec681f3Smrg                                   uint32_t slot_size,
10677ec681f3Smrg                                   uint32_t used_count,
10687ec681f3Smrg                                   uint32_t *alloc_count,
10697ec681f3Smrg                                   void **ptr);
10707ec681f3Smrg
10717ec681f3Smrgvoid v3dv_cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer);
10727ec681f3Smrg
10737ec681f3Smrg/* FIXME: only used on v3dv_cmd_buffer and v3dvx_cmd_buffer, perhaps move to a
10747ec681f3Smrg * cmd_buffer specific header?
10757ec681f3Smrg */
10767ec681f3Smrgstruct v3dv_draw_info {
10777ec681f3Smrg   uint32_t vertex_count;
10787ec681f3Smrg   uint32_t instance_count;
10797ec681f3Smrg   uint32_t first_vertex;
10807ec681f3Smrg   uint32_t first_instance;
10817ec681f3Smrg};
10827ec681f3Smrg
10837ec681f3Smrgstruct v3dv_vertex_binding {
10847ec681f3Smrg   struct v3dv_buffer *buffer;
10857ec681f3Smrg   VkDeviceSize offset;
10867ec681f3Smrg};
10877ec681f3Smrg
10887ec681f3Smrgstruct v3dv_descriptor_state {
10897ec681f3Smrg   struct v3dv_descriptor_set *descriptor_sets[MAX_SETS];
10907ec681f3Smrg   uint32_t valid;
10917ec681f3Smrg   uint32_t dynamic_offsets[MAX_DYNAMIC_BUFFERS];
10927ec681f3Smrg};
10937ec681f3Smrg
10947ec681f3Smrgstruct v3dv_cmd_pipeline_state {
10957ec681f3Smrg   struct v3dv_pipeline *pipeline;
10967ec681f3Smrg
10977ec681f3Smrg   struct v3dv_descriptor_state descriptor_state;
10987ec681f3Smrg};
10997ec681f3Smrg
11007ec681f3Smrgstruct v3dv_cmd_buffer_state {
11017ec681f3Smrg   struct v3dv_render_pass *pass;
11027ec681f3Smrg   struct v3dv_framebuffer *framebuffer;
11037ec681f3Smrg   VkRect2D render_area;
11047ec681f3Smrg
11057ec681f3Smrg   /* Current job being recorded */
11067ec681f3Smrg   struct v3dv_job *job;
11077ec681f3Smrg
11087ec681f3Smrg   uint32_t subpass_idx;
11097ec681f3Smrg
11107ec681f3Smrg   struct v3dv_cmd_pipeline_state gfx;
11117ec681f3Smrg   struct v3dv_cmd_pipeline_state compute;
11127ec681f3Smrg
11137ec681f3Smrg   struct v3dv_dynamic_state dynamic;
11147ec681f3Smrg
11157ec681f3Smrg   uint32_t dirty;
11167ec681f3Smrg   VkShaderStageFlagBits dirty_descriptor_stages;
11177ec681f3Smrg   VkShaderStageFlagBits dirty_push_constants_stages;
11187ec681f3Smrg
11197ec681f3Smrg   /* Current clip window. We use this to check whether we have an active
11207ec681f3Smrg    * scissor, since in that case we can't use TLB clears and need to fallback
11217ec681f3Smrg    * to drawing rects.
11227ec681f3Smrg    */
11237ec681f3Smrg   VkRect2D clip_window;
11247ec681f3Smrg
11257ec681f3Smrg   /* Whether our render area is aligned to tile boundaries. If this is false
11267ec681f3Smrg    * then we have tiles that are only partially covered by the render area,
11277ec681f3Smrg    * and therefore, we need to be careful with our loads and stores so we don't
11287ec681f3Smrg    * modify pixels for the tile area that is not covered by the render area.
11297ec681f3Smrg    * This means, for example, that we can't use the TLB to clear, since that
11307ec681f3Smrg    * always clears full tiles.
11317ec681f3Smrg    */
11327ec681f3Smrg   bool tile_aligned_render_area;
11337ec681f3Smrg
11347ec681f3Smrg   uint32_t attachment_alloc_count;
11357ec681f3Smrg   struct v3dv_cmd_buffer_attachment_state *attachments;
11367ec681f3Smrg
11377ec681f3Smrg   struct v3dv_vertex_binding vertex_bindings[MAX_VBS];
11387ec681f3Smrg
11397ec681f3Smrg   struct {
11407ec681f3Smrg      VkBuffer buffer;
11417ec681f3Smrg      VkDeviceSize offset;
11427ec681f3Smrg      uint8_t index_size;
11437ec681f3Smrg   } index_buffer;
11447ec681f3Smrg
11457ec681f3Smrg   /* Current uniforms */
11467ec681f3Smrg   struct {
11477ec681f3Smrg      struct v3dv_cl_reloc vs_bin;
11487ec681f3Smrg      struct v3dv_cl_reloc vs;
11497ec681f3Smrg      struct v3dv_cl_reloc gs_bin;
11507ec681f3Smrg      struct v3dv_cl_reloc gs;
11517ec681f3Smrg      struct v3dv_cl_reloc fs;
11527ec681f3Smrg   } uniforms;
11537ec681f3Smrg
11547ec681f3Smrg   /* Current view index for multiview rendering */
11557ec681f3Smrg   uint32_t view_index;
11567ec681f3Smrg
11577ec681f3Smrg   /* Used to flag OOM conditions during command buffer recording */
11587ec681f3Smrg   bool oom;
11597ec681f3Smrg
11607ec681f3Smrg   /* Whether we have recorded a pipeline barrier that we still need to
11617ec681f3Smrg    * process.
11627ec681f3Smrg    */
11637ec681f3Smrg   bool has_barrier;
11647ec681f3Smrg   bool has_bcl_barrier;
11657ec681f3Smrg
11667ec681f3Smrg   /* Secondary command buffer state */
11677ec681f3Smrg   struct {
11687ec681f3Smrg      bool occlusion_query_enable;
11697ec681f3Smrg   } inheritance;
11707ec681f3Smrg
11717ec681f3Smrg   /* Command buffer state saved during a meta operation */
11727ec681f3Smrg   struct {
11737ec681f3Smrg      uint32_t subpass_idx;
11747ec681f3Smrg      VkRenderPass pass;
11757ec681f3Smrg      VkFramebuffer framebuffer;
11767ec681f3Smrg
11777ec681f3Smrg      uint32_t attachment_alloc_count;
11787ec681f3Smrg      uint32_t attachment_count;
11797ec681f3Smrg      struct v3dv_cmd_buffer_attachment_state *attachments;
11807ec681f3Smrg
11817ec681f3Smrg      bool tile_aligned_render_area;
11827ec681f3Smrg      VkRect2D render_area;
11837ec681f3Smrg
11847ec681f3Smrg      struct v3dv_dynamic_state dynamic;
11857ec681f3Smrg
11867ec681f3Smrg      struct v3dv_cmd_pipeline_state gfx;
11877ec681f3Smrg      bool has_descriptor_state;
11887ec681f3Smrg
11897ec681f3Smrg      uint32_t push_constants[MAX_PUSH_CONSTANTS_SIZE / 4];
11907ec681f3Smrg   } meta;
11917ec681f3Smrg
11927ec681f3Smrg   /* Command buffer state for queries */
11937ec681f3Smrg   struct {
11947ec681f3Smrg      /* A list of vkCmdQueryEnd commands recorded in the command buffer during
11957ec681f3Smrg       * a render pass. We queue these here and then schedule the corresponding
11967ec681f3Smrg       * CPU jobs for them at the time we finish the GPU job in which they have
11977ec681f3Smrg       * been recorded.
11987ec681f3Smrg       */
11997ec681f3Smrg      struct {
12007ec681f3Smrg         uint32_t used_count;
12017ec681f3Smrg         uint32_t alloc_count;
12027ec681f3Smrg         struct v3dv_end_query_cpu_job_info *states;
12037ec681f3Smrg      } end;
12047ec681f3Smrg
12057ec681f3Smrg      /* This BO is not NULL if we have an active query, that is, we have
12067ec681f3Smrg       * called vkCmdBeginQuery but not vkCmdEndQuery.
12077ec681f3Smrg       */
12087ec681f3Smrg      struct {
12097ec681f3Smrg         struct v3dv_bo *bo;
12107ec681f3Smrg         uint32_t offset;
12117ec681f3Smrg      } active_query;
12127ec681f3Smrg   } query;
12137ec681f3Smrg};
12147ec681f3Smrg
12157ec681f3Smrg/* The following struct represents the info from a descriptor that we store on
12167ec681f3Smrg * the host memory. They are mostly links to other existing vulkan objects,
12177ec681f3Smrg * like the image_view in order to access to swizzle info, or the buffer used
12187ec681f3Smrg * for a UBO/SSBO, for example.
12197ec681f3Smrg *
12207ec681f3Smrg * FIXME: revisit if makes sense to just move everything that would be needed
12217ec681f3Smrg * from a descriptor to the bo.
12227ec681f3Smrg */
12237ec681f3Smrgstruct v3dv_descriptor {
12247ec681f3Smrg   VkDescriptorType type;
12257ec681f3Smrg
12267ec681f3Smrg   union {
12277ec681f3Smrg      struct {
12287ec681f3Smrg         struct v3dv_image_view *image_view;
12297ec681f3Smrg         struct v3dv_sampler *sampler;
12307ec681f3Smrg      };
12317ec681f3Smrg
12327ec681f3Smrg      struct {
12337ec681f3Smrg         struct v3dv_buffer *buffer;
12347ec681f3Smrg         uint32_t offset;
12357ec681f3Smrg         uint32_t range;
12367ec681f3Smrg      };
12377ec681f3Smrg
12387ec681f3Smrg      struct v3dv_buffer_view *buffer_view;
12397ec681f3Smrg   };
12407ec681f3Smrg};
12417ec681f3Smrg
12427ec681f3Smrgstruct v3dv_query {
12437ec681f3Smrg   bool maybe_available;
12447ec681f3Smrg   union {
12457ec681f3Smrg      /* Used by GPU queries (occlusion) */
12467ec681f3Smrg      struct {
12477ec681f3Smrg         struct v3dv_bo *bo;
12487ec681f3Smrg         uint32_t offset;
12497ec681f3Smrg      };
12507ec681f3Smrg      /* Used by CPU queries (timestamp) */
12517ec681f3Smrg      uint64_t value;
12527ec681f3Smrg   };
12537ec681f3Smrg};
12547ec681f3Smrg
12557ec681f3Smrgstruct v3dv_query_pool {
12567ec681f3Smrg   struct vk_object_base base;
12577ec681f3Smrg
12587ec681f3Smrg   struct v3dv_bo *bo; /* Only used with GPU queries (occlusion) */
12597ec681f3Smrg
12607ec681f3Smrg   VkQueryType query_type;
12617ec681f3Smrg   uint32_t query_count;
12627ec681f3Smrg   struct v3dv_query *queries;
12637ec681f3Smrg};
12647ec681f3Smrg
12657ec681f3SmrgVkResult v3dv_get_query_pool_results_cpu(struct v3dv_device *device,
12667ec681f3Smrg                                         struct v3dv_query_pool *pool,
12677ec681f3Smrg                                         uint32_t first,
12687ec681f3Smrg                                         uint32_t count,
12697ec681f3Smrg                                         void *data,
12707ec681f3Smrg                                         VkDeviceSize stride,
12717ec681f3Smrg                                         VkQueryResultFlags flags);
12727ec681f3Smrg
12737ec681f3Smrgtypedef void (*v3dv_cmd_buffer_private_obj_destroy_cb)(VkDevice device,
12747ec681f3Smrg                                                       uint64_t pobj,
12757ec681f3Smrg                                                       VkAllocationCallbacks *alloc);
12767ec681f3Smrgstruct v3dv_cmd_buffer_private_obj {
12777ec681f3Smrg   struct list_head list_link;
12787ec681f3Smrg   uint64_t obj;
12797ec681f3Smrg   v3dv_cmd_buffer_private_obj_destroy_cb destroy_cb;
12807ec681f3Smrg};
12817ec681f3Smrg
12827ec681f3Smrgstruct v3dv_cmd_buffer {
12837ec681f3Smrg   struct vk_command_buffer vk;
12847ec681f3Smrg
12857ec681f3Smrg   struct v3dv_device *device;
12867ec681f3Smrg
12877ec681f3Smrg   struct v3dv_cmd_pool *pool;
12887ec681f3Smrg   struct list_head pool_link;
12897ec681f3Smrg
12907ec681f3Smrg   /* Used at submit time to link command buffers in the submission that have
12917ec681f3Smrg    * spawned wait threads, so we can then wait on all of them to complete
12927ec681f3Smrg    * before we process any signal sempahores or fences.
12937ec681f3Smrg    */
12947ec681f3Smrg   struct list_head list_link;
12957ec681f3Smrg
12967ec681f3Smrg   VkCommandBufferUsageFlags usage_flags;
12977ec681f3Smrg   VkCommandBufferLevel level;
12987ec681f3Smrg
12997ec681f3Smrg   enum v3dv_cmd_buffer_status status;
13007ec681f3Smrg
13017ec681f3Smrg   struct v3dv_cmd_buffer_state state;
13027ec681f3Smrg
13037ec681f3Smrg   /* FIXME: we have just one client-side and bo for the push constants,
13047ec681f3Smrg    * independently of the stageFlags in vkCmdPushConstants, and the
13057ec681f3Smrg    * pipelineBindPoint in vkCmdBindPipeline. We could probably do more stage
13067ec681f3Smrg    * tunning in the future if it makes sense.
13077ec681f3Smrg    */
13087ec681f3Smrg   uint32_t push_constants_data[MAX_PUSH_CONSTANTS_SIZE / 4];
13097ec681f3Smrg   struct v3dv_cl_reloc push_constants_resource;
13107ec681f3Smrg
13117ec681f3Smrg   /* Collection of Vulkan objects created internally by the driver (typically
13127ec681f3Smrg    * during recording of meta operations) that are part of the command buffer
13137ec681f3Smrg    * and should be destroyed with it.
13147ec681f3Smrg    */
13157ec681f3Smrg   struct list_head private_objs; /* v3dv_cmd_buffer_private_obj */
13167ec681f3Smrg
13177ec681f3Smrg   /* Per-command buffer resources for meta operations. */
13187ec681f3Smrg   struct {
13197ec681f3Smrg      struct {
13207ec681f3Smrg         /* The current descriptor pool for blit sources */
13217ec681f3Smrg         VkDescriptorPool dspool;
13227ec681f3Smrg      } blit;
13237ec681f3Smrg      struct {
13247ec681f3Smrg         /* The current descriptor pool for texel buffer copy sources */
13257ec681f3Smrg         VkDescriptorPool dspool;
13267ec681f3Smrg      } texel_buffer_copy;
13277ec681f3Smrg   } meta;
13287ec681f3Smrg
13297ec681f3Smrg   /* List of jobs in the command buffer. For primary command buffers it
13307ec681f3Smrg    * represents the jobs we want to submit to the GPU. For secondary command
13317ec681f3Smrg    * buffers it represents jobs that will be merged into a primary command
13327ec681f3Smrg    * buffer via vkCmdExecuteCommands.
13337ec681f3Smrg    */
13347ec681f3Smrg   struct list_head jobs;
13357ec681f3Smrg};
13367ec681f3Smrg
13377ec681f3Smrgstruct v3dv_job *v3dv_cmd_buffer_start_job(struct v3dv_cmd_buffer *cmd_buffer,
13387ec681f3Smrg                                           int32_t subpass_idx,
13397ec681f3Smrg                                           enum v3dv_job_type type);
13407ec681f3Smrgvoid v3dv_cmd_buffer_finish_job(struct v3dv_cmd_buffer *cmd_buffer);
13417ec681f3Smrg
13427ec681f3Smrgstruct v3dv_job *v3dv_cmd_buffer_subpass_start(struct v3dv_cmd_buffer *cmd_buffer,
13437ec681f3Smrg                                               uint32_t subpass_idx);
13447ec681f3Smrgstruct v3dv_job *v3dv_cmd_buffer_subpass_resume(struct v3dv_cmd_buffer *cmd_buffer,
13457ec681f3Smrg                                                uint32_t subpass_idx);
13467ec681f3Smrg
13477ec681f3Smrgvoid v3dv_cmd_buffer_subpass_finish(struct v3dv_cmd_buffer *cmd_buffer);
13487ec681f3Smrg
13497ec681f3Smrgvoid v3dv_cmd_buffer_meta_state_push(struct v3dv_cmd_buffer *cmd_buffer,
13507ec681f3Smrg                                     bool push_descriptor_state);
13517ec681f3Smrgvoid v3dv_cmd_buffer_meta_state_pop(struct v3dv_cmd_buffer *cmd_buffer,
13527ec681f3Smrg                                    uint32_t dirty_dynamic_state,
13537ec681f3Smrg                                    bool needs_subpass_resume);
13547ec681f3Smrg
13557ec681f3Smrgvoid v3dv_cmd_buffer_reset_queries(struct v3dv_cmd_buffer *cmd_buffer,
13567ec681f3Smrg                                   struct v3dv_query_pool *pool,
13577ec681f3Smrg                                   uint32_t first,
13587ec681f3Smrg                                   uint32_t count);
13597ec681f3Smrg
13607ec681f3Smrgvoid v3dv_cmd_buffer_begin_query(struct v3dv_cmd_buffer *cmd_buffer,
13617ec681f3Smrg                                 struct v3dv_query_pool *pool,
13627ec681f3Smrg                                 uint32_t query,
13637ec681f3Smrg                                 VkQueryControlFlags flags);
13647ec681f3Smrg
13657ec681f3Smrgvoid v3dv_cmd_buffer_end_query(struct v3dv_cmd_buffer *cmd_buffer,
13667ec681f3Smrg                               struct v3dv_query_pool *pool,
13677ec681f3Smrg                               uint32_t query);
13687ec681f3Smrg
13697ec681f3Smrgvoid v3dv_cmd_buffer_copy_query_results(struct v3dv_cmd_buffer *cmd_buffer,
13707ec681f3Smrg                                        struct v3dv_query_pool *pool,
13717ec681f3Smrg                                        uint32_t first,
13727ec681f3Smrg                                        uint32_t count,
13737ec681f3Smrg                                        struct v3dv_buffer *dst,
13747ec681f3Smrg                                        uint32_t offset,
13757ec681f3Smrg                                        uint32_t stride,
13767ec681f3Smrg                                        VkQueryResultFlags flags);
13777ec681f3Smrg
13787ec681f3Smrgvoid v3dv_cmd_buffer_add_tfu_job(struct v3dv_cmd_buffer *cmd_buffer,
13797ec681f3Smrg                                 struct drm_v3d_submit_tfu *tfu);
13807ec681f3Smrg
13817ec681f3Smrgvoid v3dv_cmd_buffer_rewrite_indirect_csd_job(struct v3dv_csd_indirect_cpu_job_info *info,
13827ec681f3Smrg                                              const uint32_t *wg_counts);
13837ec681f3Smrg
13847ec681f3Smrgvoid v3dv_cmd_buffer_add_private_obj(struct v3dv_cmd_buffer *cmd_buffer,
13857ec681f3Smrg                                     uint64_t obj,
13867ec681f3Smrg                                     v3dv_cmd_buffer_private_obj_destroy_cb destroy_cb);
13877ec681f3Smrg
13887ec681f3Smrgstruct v3dv_semaphore {
13897ec681f3Smrg   struct vk_object_base base;
13907ec681f3Smrg
13917ec681f3Smrg   /* A syncobject handle associated with this semaphore */
13927ec681f3Smrg   uint32_t sync;
13937ec681f3Smrg
13947ec681f3Smrg   /* A temporary syncobject handle produced from a vkImportSemaphoreFd. */
13957ec681f3Smrg   uint32_t temp_sync;
13967ec681f3Smrg};
13977ec681f3Smrg
13987ec681f3Smrgstruct v3dv_fence {
13997ec681f3Smrg   struct vk_object_base base;
14007ec681f3Smrg
14017ec681f3Smrg   /* A syncobject handle associated with this fence */
14027ec681f3Smrg   uint32_t sync;
14037ec681f3Smrg
14047ec681f3Smrg   /* A temporary syncobject handle produced from a vkImportFenceFd. */
14057ec681f3Smrg   uint32_t temp_sync;
14067ec681f3Smrg};
14077ec681f3Smrg
14087ec681f3Smrgstruct v3dv_event {
14097ec681f3Smrg   struct vk_object_base base;
14107ec681f3Smrg   int state;
14117ec681f3Smrg};
14127ec681f3Smrg
14137ec681f3Smrgstruct v3dv_shader_variant {
14147ec681f3Smrg   enum broadcom_shader_stage stage;
14157ec681f3Smrg
14167ec681f3Smrg   union {
14177ec681f3Smrg      struct v3d_prog_data *base;
14187ec681f3Smrg      struct v3d_vs_prog_data *vs;
14197ec681f3Smrg      struct v3d_gs_prog_data *gs;
14207ec681f3Smrg      struct v3d_fs_prog_data *fs;
14217ec681f3Smrg      struct v3d_compute_prog_data *cs;
14227ec681f3Smrg   } prog_data;
14237ec681f3Smrg
14247ec681f3Smrg   /* We explicitly save the prog_data_size as it would make easier to
14257ec681f3Smrg    * serialize
14267ec681f3Smrg    */
14277ec681f3Smrg   uint32_t prog_data_size;
14287ec681f3Smrg
14297ec681f3Smrg   /* The assembly for this variant will be uploaded to a BO shared with all
14307ec681f3Smrg    * other shader stages in that pipeline. This is the offset in that BO.
14317ec681f3Smrg    */
14327ec681f3Smrg   uint32_t assembly_offset;
14337ec681f3Smrg
14347ec681f3Smrg   /* Note: it is really likely that qpu_insts would be NULL, as it will be
14357ec681f3Smrg    * used only temporarily, to upload it to the shared bo, as we compile the
14367ec681f3Smrg    * different stages individually.
14377ec681f3Smrg    */
14387ec681f3Smrg   uint64_t *qpu_insts;
14397ec681f3Smrg   uint32_t qpu_insts_size;
14407ec681f3Smrg};
14417ec681f3Smrg
14427ec681f3Smrg/*
14437ec681f3Smrg * Per-stage info for each stage, useful so shader_module_compile_to_nir and
14447ec681f3Smrg * other methods doesn't have so many parameters.
14457ec681f3Smrg *
14467ec681f3Smrg * FIXME: for the case of the coordinate shader and the vertex shader, module,
14477ec681f3Smrg * entrypoint, spec_info and nir are the same. There are also info only
14487ec681f3Smrg * relevant to some stages. But seemed too much a hassle to create a new
14497ec681f3Smrg * struct only to handle that. Revisit if such kind of info starts to grow.
14507ec681f3Smrg */
14517ec681f3Smrgstruct v3dv_pipeline_stage {
14527ec681f3Smrg   struct v3dv_pipeline *pipeline;
14537ec681f3Smrg
14547ec681f3Smrg   enum broadcom_shader_stage stage;
14557ec681f3Smrg
14567ec681f3Smrg   const struct vk_shader_module *module;
14577ec681f3Smrg   const char *entrypoint;
14587ec681f3Smrg   const VkSpecializationInfo *spec_info;
14597ec681f3Smrg
14607ec681f3Smrg   nir_shader *nir;
14617ec681f3Smrg
14627ec681f3Smrg   /* The following is the combined hash of module+entrypoint+spec_info+nir */
14637ec681f3Smrg   unsigned char shader_sha1[20];
14647ec681f3Smrg
14657ec681f3Smrg   /** A name for this program, so you can track it in shader-db output. */
14667ec681f3Smrg   uint32_t program_id;
14677ec681f3Smrg
14687ec681f3Smrg   VkPipelineCreationFeedbackEXT feedback;
14697ec681f3Smrg};
14707ec681f3Smrg
14717ec681f3Smrg/* We are using the descriptor pool entry for two things:
14727ec681f3Smrg * * Track the allocated sets, so we can properly free it if needed
14737ec681f3Smrg * * Track the suballocated pool bo regions, so if some descriptor set is
14747ec681f3Smrg *   freed, the gap could be reallocated later.
14757ec681f3Smrg *
14767ec681f3Smrg * Those only make sense if the pool was not created with the flag
14777ec681f3Smrg * VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT
14787ec681f3Smrg */
14797ec681f3Smrgstruct v3dv_descriptor_pool_entry
14807ec681f3Smrg{
14817ec681f3Smrg   struct v3dv_descriptor_set *set;
14827ec681f3Smrg   /* Offset and size of the subregion allocated for this entry from the
14837ec681f3Smrg    * pool->bo
14847ec681f3Smrg    */
14857ec681f3Smrg   uint32_t offset;
14867ec681f3Smrg   uint32_t size;
14877ec681f3Smrg};
14887ec681f3Smrg
14897ec681f3Smrgstruct v3dv_descriptor_pool {
14907ec681f3Smrg   struct vk_object_base base;
14917ec681f3Smrg
14927ec681f3Smrg   /* If this descriptor pool has been allocated for the driver for internal
14937ec681f3Smrg    * use, typically to implement meta operations.
14947ec681f3Smrg    */
14957ec681f3Smrg   bool is_driver_internal;
14967ec681f3Smrg
14977ec681f3Smrg   struct v3dv_bo *bo;
14987ec681f3Smrg   /* Current offset at the descriptor bo. 0 means that we didn't use it for
14997ec681f3Smrg    * any descriptor. If the descriptor bo is NULL, current offset is
15007ec681f3Smrg    * meaningless
15017ec681f3Smrg    */
15027ec681f3Smrg   uint32_t current_offset;
15037ec681f3Smrg
15047ec681f3Smrg   /* If VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT is not set the
15057ec681f3Smrg    * descriptor sets are handled as a whole as pool memory and handled by the
15067ec681f3Smrg    * following pointers. If set, they are not used, and individually
15077ec681f3Smrg    * descriptor sets are allocated/freed.
15087ec681f3Smrg    */
15097ec681f3Smrg   uint8_t *host_memory_base;
15107ec681f3Smrg   uint8_t *host_memory_ptr;
15117ec681f3Smrg   uint8_t *host_memory_end;
15127ec681f3Smrg
15137ec681f3Smrg   uint32_t entry_count;
15147ec681f3Smrg   uint32_t max_entry_count;
15157ec681f3Smrg   struct v3dv_descriptor_pool_entry entries[0];
15167ec681f3Smrg};
15177ec681f3Smrg
15187ec681f3Smrgstruct v3dv_descriptor_set {
15197ec681f3Smrg   struct vk_object_base base;
15207ec681f3Smrg
15217ec681f3Smrg   struct v3dv_descriptor_pool *pool;
15227ec681f3Smrg
15237ec681f3Smrg   const struct v3dv_descriptor_set_layout *layout;
15247ec681f3Smrg
15257ec681f3Smrg   /* Offset relative to the descriptor pool bo for this set */
15267ec681f3Smrg   uint32_t base_offset;
15277ec681f3Smrg
15287ec681f3Smrg   /* The descriptors below can be indexed (set/binding) using the set_layout
15297ec681f3Smrg    */
15307ec681f3Smrg   struct v3dv_descriptor descriptors[0];
15317ec681f3Smrg};
15327ec681f3Smrg
15337ec681f3Smrgstruct v3dv_descriptor_set_binding_layout {
15347ec681f3Smrg   VkDescriptorType type;
15357ec681f3Smrg
15367ec681f3Smrg   /* Number of array elements in this binding */
15377ec681f3Smrg   uint32_t array_size;
15387ec681f3Smrg
15397ec681f3Smrg   /* Index into the flattend descriptor set */
15407ec681f3Smrg   uint32_t descriptor_index;
15417ec681f3Smrg
15427ec681f3Smrg   uint32_t dynamic_offset_count;
15437ec681f3Smrg   uint32_t dynamic_offset_index;
15447ec681f3Smrg
15457ec681f3Smrg   /* Offset into the descriptor set where this descriptor lives (final offset
15467ec681f3Smrg    * on the descriptor bo need to take into account set->base_offset)
15477ec681f3Smrg    */
15487ec681f3Smrg   uint32_t descriptor_offset;
15497ec681f3Smrg
15507ec681f3Smrg   /* Offset in the v3dv_descriptor_set_layout of the immutable samplers, or 0
15517ec681f3Smrg    * if there are no immutable samplers.
15527ec681f3Smrg    */
15537ec681f3Smrg   uint32_t immutable_samplers_offset;
15547ec681f3Smrg};
15557ec681f3Smrg
15567ec681f3Smrgstruct v3dv_descriptor_set_layout {
15577ec681f3Smrg   struct vk_object_base base;
15587ec681f3Smrg
15597ec681f3Smrg   VkDescriptorSetLayoutCreateFlags flags;
15607ec681f3Smrg
15617ec681f3Smrg   /* Number of bindings in this descriptor set */
15627ec681f3Smrg   uint32_t binding_count;
15637ec681f3Smrg
15647ec681f3Smrg   /* Total bo size needed for this descriptor set
15657ec681f3Smrg    */
15667ec681f3Smrg   uint32_t bo_size;
15677ec681f3Smrg
15687ec681f3Smrg   /* Shader stages affected by this descriptor set */
15697ec681f3Smrg   uint16_t shader_stages;
15707ec681f3Smrg
15717ec681f3Smrg   /* Number of descriptors in this descriptor set */
15727ec681f3Smrg   uint32_t descriptor_count;
15737ec681f3Smrg
15747ec681f3Smrg   /* Number of dynamic offsets used by this descriptor set */
15757ec681f3Smrg   uint16_t dynamic_offset_count;
15767ec681f3Smrg
15777ec681f3Smrg   /* Bindings in this descriptor set */
15787ec681f3Smrg   struct v3dv_descriptor_set_binding_layout binding[0];
15797ec681f3Smrg};
15807ec681f3Smrg
15817ec681f3Smrgstruct v3dv_pipeline_layout {
15827ec681f3Smrg   struct vk_object_base base;
15837ec681f3Smrg
15847ec681f3Smrg   struct {
15857ec681f3Smrg      struct v3dv_descriptor_set_layout *layout;
15867ec681f3Smrg      uint32_t dynamic_offset_start;
15877ec681f3Smrg   } set[MAX_SETS];
15887ec681f3Smrg
15897ec681f3Smrg   uint32_t num_sets;
15907ec681f3Smrg
15917ec681f3Smrg   /* Shader stages that are declared to use descriptors from this layout */
15927ec681f3Smrg   uint32_t shader_stages;
15937ec681f3Smrg
15947ec681f3Smrg   uint32_t dynamic_offset_count;
15957ec681f3Smrg   uint32_t push_constant_size;
15967ec681f3Smrg};
15977ec681f3Smrg
15987ec681f3Smrg/*
15997ec681f3Smrg * We are using descriptor maps for ubo/ssbo and texture/samplers, so we need
16007ec681f3Smrg * it to be big enough to include the max value for all of them.
16017ec681f3Smrg *
16027ec681f3Smrg * FIXME: one alternative would be to allocate the map as big as you need for
16037ec681f3Smrg * each descriptor type. That would means more individual allocations.
16047ec681f3Smrg */
16057ec681f3Smrg#define DESCRIPTOR_MAP_SIZE MAX3(V3D_MAX_TEXTURE_SAMPLERS, \
16067ec681f3Smrg                                 MAX_UNIFORM_BUFFERS,      \
16077ec681f3Smrg                                 MAX_STORAGE_BUFFERS)
16087ec681f3Smrg
16097ec681f3Smrg
16107ec681f3Smrgstruct v3dv_descriptor_map {
16117ec681f3Smrg   /* TODO: avoid fixed size array/justify the size */
16127ec681f3Smrg   unsigned num_desc; /* Number of descriptors  */
16137ec681f3Smrg   int set[DESCRIPTOR_MAP_SIZE];
16147ec681f3Smrg   int binding[DESCRIPTOR_MAP_SIZE];
16157ec681f3Smrg   int array_index[DESCRIPTOR_MAP_SIZE];
16167ec681f3Smrg   int array_size[DESCRIPTOR_MAP_SIZE];
16177ec681f3Smrg
16187ec681f3Smrg   /* NOTE: the following is only for sampler, but this is the easier place to
16197ec681f3Smrg    * put it.
16207ec681f3Smrg    */
16217ec681f3Smrg   uint8_t return_size[DESCRIPTOR_MAP_SIZE];
16227ec681f3Smrg};
16237ec681f3Smrg
16247ec681f3Smrgstruct v3dv_sampler {
16257ec681f3Smrg   struct vk_object_base base;
16267ec681f3Smrg
16277ec681f3Smrg   bool compare_enable;
16287ec681f3Smrg   bool unnormalized_coordinates;
16297ec681f3Smrg   bool clamp_to_transparent_black_border;
16307ec681f3Smrg
16317ec681f3Smrg   /* Prepacked SAMPLER_STATE, that is referenced as part of the tmu
16327ec681f3Smrg    * configuration. If needed it will be copied to the descriptor info during
16337ec681f3Smrg    * UpdateDescriptorSets
16347ec681f3Smrg    */
16357ec681f3Smrg   uint8_t sampler_state[V3DV_SAMPLER_STATE_LENGTH];
16367ec681f3Smrg};
16377ec681f3Smrg
16387ec681f3Smrgstruct v3dv_descriptor_template_entry {
16397ec681f3Smrg   /* The type of descriptor in this entry */
16407ec681f3Smrg   VkDescriptorType type;
16417ec681f3Smrg
16427ec681f3Smrg   /* Binding in the descriptor set */
16437ec681f3Smrg   uint32_t binding;
16447ec681f3Smrg
16457ec681f3Smrg   /* Offset at which to write into the descriptor set binding */
16467ec681f3Smrg   uint32_t array_element;
16477ec681f3Smrg
16487ec681f3Smrg   /* Number of elements to write into the descriptor set binding */
16497ec681f3Smrg   uint32_t array_count;
16507ec681f3Smrg
16517ec681f3Smrg   /* Offset into the user provided data */
16527ec681f3Smrg   size_t offset;
16537ec681f3Smrg
16547ec681f3Smrg   /* Stride between elements into the user provided data */
16557ec681f3Smrg   size_t stride;
16567ec681f3Smrg};
16577ec681f3Smrg
16587ec681f3Smrgstruct v3dv_descriptor_update_template {
16597ec681f3Smrg   struct vk_object_base base;
16607ec681f3Smrg
16617ec681f3Smrg   VkPipelineBindPoint bind_point;
16627ec681f3Smrg
16637ec681f3Smrg   /* The descriptor set this template corresponds to. This value is only
16647ec681f3Smrg    * valid if the template was created with the templateType
16657ec681f3Smrg    * VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET.
16667ec681f3Smrg    */
16677ec681f3Smrg   uint8_t set;
16687ec681f3Smrg
16697ec681f3Smrg   /* Number of entries in this template */
16707ec681f3Smrg   uint32_t entry_count;
16717ec681f3Smrg
16727ec681f3Smrg   /* Entries of the template */
16737ec681f3Smrg   struct v3dv_descriptor_template_entry entries[0];
16747ec681f3Smrg};
16757ec681f3Smrg
16767ec681f3Smrg
16777ec681f3Smrg/* We keep two special values for the sampler idx that represents exactly when a
16787ec681f3Smrg * sampler is not needed/provided. The main use is that even if we don't have
16797ec681f3Smrg * sampler, we still need to do the output unpacking (through
16807ec681f3Smrg * nir_lower_tex). The easier way to do this is to add those special "no
16817ec681f3Smrg * sampler" in the sampler_map, and then use the proper unpacking for that
16827ec681f3Smrg * case.
16837ec681f3Smrg *
16847ec681f3Smrg * We have one when we want a 16bit output size, and other when we want a
16857ec681f3Smrg * 32bit output size. We use the info coming from the RelaxedPrecision
16867ec681f3Smrg * decoration to decide between one and the other.
16877ec681f3Smrg */
16887ec681f3Smrg#define V3DV_NO_SAMPLER_16BIT_IDX 0
16897ec681f3Smrg#define V3DV_NO_SAMPLER_32BIT_IDX 1
16907ec681f3Smrg
16917ec681f3Smrg/*
16927ec681f3Smrg * Following two methods are using on the combined to/from texture/sampler
16937ec681f3Smrg * indices maps at v3dv_pipeline.
16947ec681f3Smrg */
16957ec681f3Smrgstatic inline uint32_t
16967ec681f3Smrgv3dv_pipeline_combined_index_key_create(uint32_t texture_index,
16977ec681f3Smrg                                        uint32_t sampler_index)
16987ec681f3Smrg{
16997ec681f3Smrg   return texture_index << 24 | sampler_index;
17007ec681f3Smrg}
17017ec681f3Smrg
17027ec681f3Smrgstatic inline void
17037ec681f3Smrgv3dv_pipeline_combined_index_key_unpack(uint32_t combined_index_key,
17047ec681f3Smrg                                        uint32_t *texture_index,
17057ec681f3Smrg                                        uint32_t *sampler_index)
17067ec681f3Smrg{
17077ec681f3Smrg   uint32_t texture = combined_index_key >> 24;
17087ec681f3Smrg   uint32_t sampler = combined_index_key & 0xffffff;
17097ec681f3Smrg
17107ec681f3Smrg   if (texture_index)
17117ec681f3Smrg      *texture_index = texture;
17127ec681f3Smrg
17137ec681f3Smrg   if (sampler_index)
17147ec681f3Smrg      *sampler_index = sampler;
17157ec681f3Smrg}
17167ec681f3Smrg
17177ec681f3Smrgstruct v3dv_descriptor_maps {
17187ec681f3Smrg   struct v3dv_descriptor_map ubo_map;
17197ec681f3Smrg   struct v3dv_descriptor_map ssbo_map;
17207ec681f3Smrg   struct v3dv_descriptor_map sampler_map;
17217ec681f3Smrg   struct v3dv_descriptor_map texture_map;
17227ec681f3Smrg};
17237ec681f3Smrg
17247ec681f3Smrg/* The structure represents data shared between different objects, like the
17257ec681f3Smrg * pipeline and the pipeline cache, so we ref count it to know when it should
17267ec681f3Smrg * be freed.
17277ec681f3Smrg */
17287ec681f3Smrgstruct v3dv_pipeline_shared_data {
17297ec681f3Smrg   uint32_t ref_cnt;
17307ec681f3Smrg
17317ec681f3Smrg   unsigned char sha1_key[20];
17327ec681f3Smrg
17337ec681f3Smrg   struct v3dv_descriptor_maps *maps[BROADCOM_SHADER_STAGES];
17347ec681f3Smrg   struct v3dv_shader_variant *variants[BROADCOM_SHADER_STAGES];
17357ec681f3Smrg
17367ec681f3Smrg   struct v3dv_bo *assembly_bo;
17377ec681f3Smrg};
17387ec681f3Smrg
17397ec681f3Smrgstruct v3dv_pipeline {
17407ec681f3Smrg   struct vk_object_base base;
17417ec681f3Smrg
17427ec681f3Smrg   struct v3dv_device *device;
17437ec681f3Smrg
17447ec681f3Smrg   VkShaderStageFlags active_stages;
17457ec681f3Smrg
17467ec681f3Smrg   struct v3dv_render_pass *pass;
17477ec681f3Smrg   struct v3dv_subpass *subpass;
17487ec681f3Smrg
17497ec681f3Smrg   /* Note: We can't use just a MESA_SHADER_STAGES array because we also need
17507ec681f3Smrg    * to track binning shaders. Note these will be freed once the pipeline
17517ec681f3Smrg    * has been compiled.
17527ec681f3Smrg    */
17537ec681f3Smrg   struct v3dv_pipeline_stage *vs;
17547ec681f3Smrg   struct v3dv_pipeline_stage *vs_bin;
17557ec681f3Smrg   struct v3dv_pipeline_stage *gs;
17567ec681f3Smrg   struct v3dv_pipeline_stage *gs_bin;
17577ec681f3Smrg   struct v3dv_pipeline_stage *fs;
17587ec681f3Smrg   struct v3dv_pipeline_stage *cs;
17597ec681f3Smrg
17607ec681f3Smrg   /* Flags for whether optional pipeline stages are present, for convenience */
17617ec681f3Smrg   bool has_gs;
17627ec681f3Smrg
17637ec681f3Smrg   /* Spilling memory requirements */
17647ec681f3Smrg   struct {
17657ec681f3Smrg      struct v3dv_bo *bo;
17667ec681f3Smrg      uint32_t size_per_thread;
17677ec681f3Smrg   } spill;
17687ec681f3Smrg
17697ec681f3Smrg   struct v3dv_dynamic_state dynamic_state;
17707ec681f3Smrg
17717ec681f3Smrg   struct v3dv_pipeline_layout *layout;
17727ec681f3Smrg
17737ec681f3Smrg   /* Whether this pipeline enables depth writes */
17747ec681f3Smrg   bool z_updates_enable;
17757ec681f3Smrg
17767ec681f3Smrg   enum v3dv_ez_state ez_state;
17777ec681f3Smrg
17787ec681f3Smrg   bool msaa;
17797ec681f3Smrg   bool sample_rate_shading;
17807ec681f3Smrg   uint32_t sample_mask;
17817ec681f3Smrg
17827ec681f3Smrg   bool primitive_restart;
17837ec681f3Smrg
17847ec681f3Smrg   /* Accessed by binding. So vb[binding]->stride is the stride of the vertex
17857ec681f3Smrg    * array with such binding
17867ec681f3Smrg    */
17877ec681f3Smrg   struct v3dv_pipeline_vertex_binding {
17887ec681f3Smrg      uint32_t stride;
17897ec681f3Smrg      uint32_t instance_divisor;
17907ec681f3Smrg   } vb[MAX_VBS];
17917ec681f3Smrg   uint32_t vb_count;
17927ec681f3Smrg
17937ec681f3Smrg   /* Note that a lot of info from VkVertexInputAttributeDescription is
17947ec681f3Smrg    * already prepacked, so here we are only storing those that need recheck
17957ec681f3Smrg    * later. The array must be indexed by driver location, since that is the
17967ec681f3Smrg    * order in which we need to emit the attributes.
17977ec681f3Smrg    */
17987ec681f3Smrg   struct v3dv_pipeline_vertex_attrib {
17997ec681f3Smrg      uint32_t binding;
18007ec681f3Smrg      uint32_t offset;
18017ec681f3Smrg      VkFormat vk_format;
18027ec681f3Smrg   } va[MAX_VERTEX_ATTRIBS];
18037ec681f3Smrg   uint32_t va_count;
18047ec681f3Smrg
18057ec681f3Smrg   enum pipe_prim_type topology;
18067ec681f3Smrg
18077ec681f3Smrg   struct v3dv_pipeline_shared_data *shared_data;
18087ec681f3Smrg
18097ec681f3Smrg   /* In general we can reuse v3dv_device->default_attribute_float, so note
18107ec681f3Smrg    * that the following can be NULL.
18117ec681f3Smrg    *
18127ec681f3Smrg    * FIXME: the content of this BO will be small, so it could be improved to
18137ec681f3Smrg    * be uploaded to a common BO. But as in most cases it will be NULL, it is
18147ec681f3Smrg    * not a priority.
18157ec681f3Smrg    */
18167ec681f3Smrg   struct v3dv_bo *default_attribute_values;
18177ec681f3Smrg
18187ec681f3Smrg   struct vpm_config vpm_cfg;
18197ec681f3Smrg   struct vpm_config vpm_cfg_bin;
18207ec681f3Smrg
18217ec681f3Smrg   /* If the pipeline should emit any of the stencil configuration packets */
18227ec681f3Smrg   bool emit_stencil_cfg[2];
18237ec681f3Smrg
18247ec681f3Smrg   /* Blend state */
18257ec681f3Smrg   struct {
18267ec681f3Smrg      /* Per-RT bit mask with blend enables */
18277ec681f3Smrg      uint8_t enables;
18287ec681f3Smrg      /* Per-RT prepacked blend config packets */
18297ec681f3Smrg      uint8_t cfg[V3D_MAX_DRAW_BUFFERS][V3DV_BLEND_CFG_LENGTH];
18307ec681f3Smrg      /* Flag indicating whether the blend factors in use require
18317ec681f3Smrg       * color constants.
18327ec681f3Smrg       */
18337ec681f3Smrg      bool needs_color_constants;
18347ec681f3Smrg      /* Mask with enabled color channels for each RT (4 bits per RT) */
18357ec681f3Smrg      uint32_t color_write_masks;
18367ec681f3Smrg   } blend;
18377ec681f3Smrg
18387ec681f3Smrg   /* Depth bias */
18397ec681f3Smrg   struct {
18407ec681f3Smrg      bool enabled;
18417ec681f3Smrg      bool is_z16;
18427ec681f3Smrg   } depth_bias;
18437ec681f3Smrg
18447ec681f3Smrg   /* Packets prepacked during pipeline creation
18457ec681f3Smrg    */
18467ec681f3Smrg   uint8_t cfg_bits[V3DV_CFG_BITS_LENGTH];
18477ec681f3Smrg   uint8_t shader_state_record[V3DV_GL_SHADER_STATE_RECORD_LENGTH];
18487ec681f3Smrg   uint8_t vcm_cache_size[V3DV_VCM_CACHE_SIZE_LENGTH];
18497ec681f3Smrg   uint8_t vertex_attrs[V3DV_GL_SHADER_STATE_ATTRIBUTE_RECORD_LENGTH *
18507ec681f3Smrg                        MAX_VERTEX_ATTRIBS];
18517ec681f3Smrg   uint8_t stencil_cfg[2][V3DV_STENCIL_CFG_LENGTH];
18527ec681f3Smrg};
18537ec681f3Smrg
18547ec681f3Smrgstatic inline VkPipelineBindPoint
18557ec681f3Smrgv3dv_pipeline_get_binding_point(struct v3dv_pipeline *pipeline)
18567ec681f3Smrg{
18577ec681f3Smrg   assert(pipeline->active_stages == VK_SHADER_STAGE_COMPUTE_BIT ||
18587ec681f3Smrg          !(pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT));
18597ec681f3Smrg   return pipeline->active_stages == VK_SHADER_STAGE_COMPUTE_BIT ?
18607ec681f3Smrg      VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS;
18617ec681f3Smrg}
18627ec681f3Smrg
18637ec681f3Smrgstatic inline struct v3dv_descriptor_state*
18647ec681f3Smrgv3dv_cmd_buffer_get_descriptor_state(struct v3dv_cmd_buffer *cmd_buffer,
18657ec681f3Smrg                                     struct v3dv_pipeline *pipeline)
18667ec681f3Smrg{
18677ec681f3Smrg   if (v3dv_pipeline_get_binding_point(pipeline) == VK_PIPELINE_BIND_POINT_COMPUTE)
18687ec681f3Smrg      return &cmd_buffer->state.compute.descriptor_state;
18697ec681f3Smrg   else
18707ec681f3Smrg      return &cmd_buffer->state.gfx.descriptor_state;
18717ec681f3Smrg}
18727ec681f3Smrg
18737ec681f3Smrgconst nir_shader_compiler_options *v3dv_pipeline_get_nir_options(void);
18747ec681f3Smrg
18757ec681f3Smrguint32_t v3dv_physical_device_vendor_id(struct v3dv_physical_device *dev);
18767ec681f3Smrguint32_t v3dv_physical_device_device_id(struct v3dv_physical_device *dev);
18777ec681f3Smrg
18787ec681f3Smrg#ifdef DEBUG
18797ec681f3Smrg#define v3dv_debug_ignored_stype(sType) \
18807ec681f3Smrg   fprintf(stderr, "%s: ignored VkStructureType %u:%s\n\n", __func__, (sType), vk_StructureType_to_str(sType))
18817ec681f3Smrg#else
18827ec681f3Smrg#define v3dv_debug_ignored_stype(sType)
18837ec681f3Smrg#endif
18847ec681f3Smrg
18857ec681f3Smrgconst uint8_t *v3dv_get_format_swizzle(struct v3dv_device *device, VkFormat f);
18867ec681f3Smrguint8_t v3dv_get_tex_return_size(const struct v3dv_format *vf, bool compare_enable);
18877ec681f3Smrgconst struct v3dv_format *
18887ec681f3Smrgv3dv_get_compatible_tfu_format(struct v3dv_device *device,
18897ec681f3Smrg                               uint32_t bpp, VkFormat *out_vk_format);
18907ec681f3Smrgbool v3dv_buffer_format_supports_features(struct v3dv_device *device,
18917ec681f3Smrg                                          VkFormat vk_format,
18927ec681f3Smrg                                          VkFormatFeatureFlags features);
18937ec681f3Smrg
18947ec681f3Smrgstruct v3dv_cl_reloc v3dv_write_uniforms(struct v3dv_cmd_buffer *cmd_buffer,
18957ec681f3Smrg                                         struct v3dv_pipeline *pipeline,
18967ec681f3Smrg                                         struct v3dv_shader_variant *variant);
18977ec681f3Smrg
18987ec681f3Smrgstruct v3dv_cl_reloc v3dv_write_uniforms_wg_offsets(struct v3dv_cmd_buffer *cmd_buffer,
18997ec681f3Smrg                                                    struct v3dv_pipeline *pipeline,
19007ec681f3Smrg                                                    struct v3dv_shader_variant *variant,
19017ec681f3Smrg                                                    uint32_t **wg_count_offsets);
19027ec681f3Smrg
19037ec681f3Smrgstruct v3dv_shader_variant *
19047ec681f3Smrgv3dv_get_shader_variant(struct v3dv_pipeline_stage *p_stage,
19057ec681f3Smrg                        struct v3dv_pipeline_cache *cache,
19067ec681f3Smrg                        struct v3d_key *key,
19077ec681f3Smrg                        size_t key_size,
19087ec681f3Smrg                        const VkAllocationCallbacks *pAllocator,
19097ec681f3Smrg                        VkResult *out_vk_result);
19107ec681f3Smrg
19117ec681f3Smrgstruct v3dv_shader_variant *
19127ec681f3Smrgv3dv_shader_variant_create(struct v3dv_device *device,
19137ec681f3Smrg                           enum broadcom_shader_stage stage,
19147ec681f3Smrg                           struct v3d_prog_data *prog_data,
19157ec681f3Smrg                           uint32_t prog_data_size,
19167ec681f3Smrg                           uint32_t assembly_offset,
19177ec681f3Smrg                           uint64_t *qpu_insts,
19187ec681f3Smrg                           uint32_t qpu_insts_size,
19197ec681f3Smrg                           VkResult *out_vk_result);
19207ec681f3Smrg
19217ec681f3Smrgvoid
19227ec681f3Smrgv3dv_shader_variant_destroy(struct v3dv_device *device,
19237ec681f3Smrg                            struct v3dv_shader_variant *variant);
19247ec681f3Smrg
19257ec681f3Smrgstatic inline void
19267ec681f3Smrgv3dv_pipeline_shared_data_ref(struct v3dv_pipeline_shared_data *shared_data)
19277ec681f3Smrg{
19287ec681f3Smrg   assert(shared_data && shared_data->ref_cnt >= 1);
19297ec681f3Smrg   p_atomic_inc(&shared_data->ref_cnt);
19307ec681f3Smrg}
19317ec681f3Smrg
19327ec681f3Smrgvoid
19337ec681f3Smrgv3dv_pipeline_shared_data_destroy(struct v3dv_device *device,
19347ec681f3Smrg                                  struct v3dv_pipeline_shared_data *shared_data);
19357ec681f3Smrg
19367ec681f3Smrgstatic inline void
19377ec681f3Smrgv3dv_pipeline_shared_data_unref(struct v3dv_device *device,
19387ec681f3Smrg                                struct v3dv_pipeline_shared_data *shared_data)
19397ec681f3Smrg{
19407ec681f3Smrg   assert(shared_data && shared_data->ref_cnt >= 1);
19417ec681f3Smrg   if (p_atomic_dec_zero(&shared_data->ref_cnt))
19427ec681f3Smrg      v3dv_pipeline_shared_data_destroy(device, shared_data);
19437ec681f3Smrg}
19447ec681f3Smrg
19457ec681f3Smrgstruct v3dv_descriptor *
19467ec681f3Smrgv3dv_descriptor_map_get_descriptor(struct v3dv_descriptor_state *descriptor_state,
19477ec681f3Smrg                                   struct v3dv_descriptor_map *map,
19487ec681f3Smrg                                   struct v3dv_pipeline_layout *pipeline_layout,
19497ec681f3Smrg                                   uint32_t index,
19507ec681f3Smrg                                   uint32_t *dynamic_offset);
19517ec681f3Smrg
19527ec681f3Smrgconst struct v3dv_sampler *
19537ec681f3Smrgv3dv_descriptor_map_get_sampler(struct v3dv_descriptor_state *descriptor_state,
19547ec681f3Smrg                                struct v3dv_descriptor_map *map,
19557ec681f3Smrg                                struct v3dv_pipeline_layout *pipeline_layout,
19567ec681f3Smrg                                uint32_t index);
19577ec681f3Smrg
19587ec681f3Smrgstruct v3dv_cl_reloc
19597ec681f3Smrgv3dv_descriptor_map_get_sampler_state(struct v3dv_device *device,
19607ec681f3Smrg                                      struct v3dv_descriptor_state *descriptor_state,
19617ec681f3Smrg                                      struct v3dv_descriptor_map *map,
19627ec681f3Smrg                                      struct v3dv_pipeline_layout *pipeline_layout,
19637ec681f3Smrg                                      uint32_t index);
19647ec681f3Smrg
19657ec681f3Smrgstruct v3dv_cl_reloc
19667ec681f3Smrgv3dv_descriptor_map_get_texture_shader_state(struct v3dv_device *device,
19677ec681f3Smrg                                             struct v3dv_descriptor_state *descriptor_state,
19687ec681f3Smrg                                             struct v3dv_descriptor_map *map,
19697ec681f3Smrg                                             struct v3dv_pipeline_layout *pipeline_layout,
19707ec681f3Smrg                                             uint32_t index);
19717ec681f3Smrg
19727ec681f3Smrgconst struct v3dv_format*
19737ec681f3Smrgv3dv_descriptor_map_get_texture_format(struct v3dv_descriptor_state *descriptor_state,
19747ec681f3Smrg                                       struct v3dv_descriptor_map *map,
19757ec681f3Smrg                                       struct v3dv_pipeline_layout *pipeline_layout,
19767ec681f3Smrg                                       uint32_t index,
19777ec681f3Smrg                                       VkFormat *out_vk_format);
19787ec681f3Smrg
19797ec681f3Smrgstruct v3dv_bo*
19807ec681f3Smrgv3dv_descriptor_map_get_texture_bo(struct v3dv_descriptor_state *descriptor_state,
19817ec681f3Smrg                                   struct v3dv_descriptor_map *map,
19827ec681f3Smrg                                   struct v3dv_pipeline_layout *pipeline_layout,
19837ec681f3Smrg                                   uint32_t index);
19847ec681f3Smrg
19857ec681f3Smrgstatic inline const struct v3dv_sampler *
19867ec681f3Smrgv3dv_immutable_samplers(const struct v3dv_descriptor_set_layout *set,
19877ec681f3Smrg                        const struct v3dv_descriptor_set_binding_layout *binding)
19887ec681f3Smrg{
19897ec681f3Smrg   assert(binding->immutable_samplers_offset);
19907ec681f3Smrg   return (const struct v3dv_sampler *) ((const char *) set + binding->immutable_samplers_offset);
19917ec681f3Smrg}
19927ec681f3Smrg
19937ec681f3Smrgvoid v3dv_pipeline_cache_init(struct v3dv_pipeline_cache *cache,
19947ec681f3Smrg                              struct v3dv_device *device,
19957ec681f3Smrg                              VkPipelineCacheCreateFlags,
19967ec681f3Smrg                              bool cache_enabled);
19977ec681f3Smrg
19987ec681f3Smrgvoid v3dv_pipeline_cache_finish(struct v3dv_pipeline_cache *cache);
19997ec681f3Smrg
20007ec681f3Smrgvoid v3dv_pipeline_cache_upload_nir(struct v3dv_pipeline *pipeline,
20017ec681f3Smrg                                    struct v3dv_pipeline_cache *cache,
20027ec681f3Smrg                                    nir_shader *nir,
20037ec681f3Smrg                                    unsigned char sha1_key[20]);
20047ec681f3Smrg
20057ec681f3Smrgnir_shader* v3dv_pipeline_cache_search_for_nir(struct v3dv_pipeline *pipeline,
20067ec681f3Smrg                                               struct v3dv_pipeline_cache *cache,
20077ec681f3Smrg                                               const nir_shader_compiler_options *nir_options,
20087ec681f3Smrg                                               unsigned char sha1_key[20]);
20097ec681f3Smrg
20107ec681f3Smrgstruct v3dv_pipeline_shared_data *
20117ec681f3Smrgv3dv_pipeline_cache_search_for_pipeline(struct v3dv_pipeline_cache *cache,
20127ec681f3Smrg                                        unsigned char sha1_key[20],
20137ec681f3Smrg                                        bool *cache_hit);
20147ec681f3Smrg
20157ec681f3Smrgvoid
20167ec681f3Smrgv3dv_pipeline_cache_upload_pipeline(struct v3dv_pipeline *pipeline,
20177ec681f3Smrg                                    struct v3dv_pipeline_cache *cache);
20187ec681f3Smrg
20197ec681f3Smrgstruct v3dv_bo *
20207ec681f3Smrgv3dv_pipeline_create_default_attribute_values(struct v3dv_device *device,
20217ec681f3Smrg                                              struct v3dv_pipeline *pipeline);
20227ec681f3Smrg
20237ec681f3Smrgvoid v3dv_shader_module_internal_init(struct v3dv_device *device,
20247ec681f3Smrg                                      struct vk_shader_module *module,
20257ec681f3Smrg                                      nir_shader *nir);
20267ec681f3Smrg
20277ec681f3Smrg#define V3DV_FROM_HANDLE(__v3dv_type, __name, __handle)			\
20287ec681f3Smrg   VK_FROM_HANDLE(__v3dv_type, __name, __handle)
20297ec681f3Smrg
20307ec681f3SmrgVK_DEFINE_HANDLE_CASTS(v3dv_cmd_buffer, vk.base, VkCommandBuffer,
20317ec681f3Smrg                       VK_OBJECT_TYPE_COMMAND_BUFFER)
20327ec681f3SmrgVK_DEFINE_HANDLE_CASTS(v3dv_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE)
20337ec681f3SmrgVK_DEFINE_HANDLE_CASTS(v3dv_instance, vk.base, VkInstance,
20347ec681f3Smrg                       VK_OBJECT_TYPE_INSTANCE)
20357ec681f3SmrgVK_DEFINE_HANDLE_CASTS(v3dv_physical_device, vk.base, VkPhysicalDevice,
20367ec681f3Smrg                       VK_OBJECT_TYPE_PHYSICAL_DEVICE)
20377ec681f3SmrgVK_DEFINE_HANDLE_CASTS(v3dv_queue, vk.base, VkQueue, VK_OBJECT_TYPE_QUEUE)
20387ec681f3Smrg
20397ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_cmd_pool, base, VkCommandPool,
20407ec681f3Smrg                               VK_OBJECT_TYPE_COMMAND_POOL)
20417ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_buffer, base, VkBuffer,
20427ec681f3Smrg                               VK_OBJECT_TYPE_BUFFER)
20437ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_buffer_view, base, VkBufferView,
20447ec681f3Smrg                               VK_OBJECT_TYPE_BUFFER_VIEW)
20457ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_device_memory, base, VkDeviceMemory,
20467ec681f3Smrg                               VK_OBJECT_TYPE_DEVICE_MEMORY)
20477ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_descriptor_pool, base, VkDescriptorPool,
20487ec681f3Smrg                               VK_OBJECT_TYPE_DESCRIPTOR_POOL)
20497ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_descriptor_set, base, VkDescriptorSet,
20507ec681f3Smrg                               VK_OBJECT_TYPE_DESCRIPTOR_SET)
20517ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_descriptor_set_layout, base,
20527ec681f3Smrg                               VkDescriptorSetLayout,
20537ec681f3Smrg                               VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
20547ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_descriptor_update_template, base,
20557ec681f3Smrg                               VkDescriptorUpdateTemplate,
20567ec681f3Smrg                               VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE)
20577ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_event, base, VkEvent, VK_OBJECT_TYPE_EVENT)
20587ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_fence, base, VkFence, VK_OBJECT_TYPE_FENCE)
20597ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_framebuffer, base, VkFramebuffer,
20607ec681f3Smrg                               VK_OBJECT_TYPE_FRAMEBUFFER)
20617ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_image, vk.base, VkImage,
20627ec681f3Smrg                               VK_OBJECT_TYPE_IMAGE)
20637ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_image_view, vk.base, VkImageView,
20647ec681f3Smrg                               VK_OBJECT_TYPE_IMAGE_VIEW)
20657ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_pipeline, base, VkPipeline,
20667ec681f3Smrg                               VK_OBJECT_TYPE_PIPELINE)
20677ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_pipeline_cache, base, VkPipelineCache,
20687ec681f3Smrg                               VK_OBJECT_TYPE_PIPELINE_CACHE)
20697ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_pipeline_layout, base, VkPipelineLayout,
20707ec681f3Smrg                               VK_OBJECT_TYPE_PIPELINE_LAYOUT)
20717ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_query_pool, base, VkQueryPool,
20727ec681f3Smrg                               VK_OBJECT_TYPE_QUERY_POOL)
20737ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_render_pass, base, VkRenderPass,
20747ec681f3Smrg                               VK_OBJECT_TYPE_RENDER_PASS)
20757ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_sampler, base, VkSampler,
20767ec681f3Smrg                               VK_OBJECT_TYPE_SAMPLER)
20777ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(v3dv_semaphore, base, VkSemaphore,
20787ec681f3Smrg                               VK_OBJECT_TYPE_SEMAPHORE)
20797ec681f3Smrg
20807ec681f3Smrgstatic inline int
20817ec681f3Smrgv3dv_ioctl(int fd, unsigned long request, void *arg)
20827ec681f3Smrg{
20837ec681f3Smrg   if (using_v3d_simulator)
20847ec681f3Smrg      return v3d_simulator_ioctl(fd, request, arg);
20857ec681f3Smrg   else
20867ec681f3Smrg      return drmIoctl(fd, request, arg);
20877ec681f3Smrg}
20887ec681f3Smrg
20897ec681f3Smrg/* Flags OOM conditions in command buffer state.
20907ec681f3Smrg *
20917ec681f3Smrg * Note: notice that no-op jobs don't have a command buffer reference.
20927ec681f3Smrg */
20937ec681f3Smrgstatic inline void
20947ec681f3Smrgv3dv_flag_oom(struct v3dv_cmd_buffer *cmd_buffer, struct v3dv_job *job)
20957ec681f3Smrg{
20967ec681f3Smrg   if (cmd_buffer) {
20977ec681f3Smrg      cmd_buffer->state.oom = true;
20987ec681f3Smrg   } else {
20997ec681f3Smrg      assert(job);
21007ec681f3Smrg      if (job->cmd_buffer)
21017ec681f3Smrg         job->cmd_buffer->state.oom = true;
21027ec681f3Smrg   }
21037ec681f3Smrg}
21047ec681f3Smrg
21057ec681f3Smrg#define v3dv_return_if_oom(_cmd_buffer, _job) do {                  \
21067ec681f3Smrg   const struct v3dv_cmd_buffer *__cmd_buffer = _cmd_buffer;        \
21077ec681f3Smrg   if (__cmd_buffer && __cmd_buffer->state.oom)                     \
21087ec681f3Smrg      return;                                                       \
21097ec681f3Smrg   const struct v3dv_job *__job = _job;                             \
21107ec681f3Smrg   if (__job && __job->cmd_buffer && __job->cmd_buffer->state.oom)  \
21117ec681f3Smrg      return;                                                       \
21127ec681f3Smrg} while(0)                                                          \
21137ec681f3Smrg
21147ec681f3Smrgstatic inline uint32_t
21157ec681f3Smrgu64_hash(const void *key)
21167ec681f3Smrg{
21177ec681f3Smrg   return _mesa_hash_data(key, sizeof(uint64_t));
21187ec681f3Smrg}
21197ec681f3Smrg
21207ec681f3Smrgstatic inline bool
21217ec681f3Smrgu64_compare(const void *key1, const void *key2)
21227ec681f3Smrg{
21237ec681f3Smrg   return memcmp(key1, key2, sizeof(uint64_t)) == 0;
21247ec681f3Smrg}
21257ec681f3Smrg
21267ec681f3Smrg/* Helper to call hw ver speficic functions */
21277ec681f3Smrg#define v3dv_X(device, thing) ({                      \
21287ec681f3Smrg   __typeof(&v3d42_##thing) v3d_X_thing;              \
21297ec681f3Smrg   switch (device->devinfo.ver) {                     \
21307ec681f3Smrg   case 42:                                           \
21317ec681f3Smrg      v3d_X_thing = &v3d42_##thing;                   \
21327ec681f3Smrg      break;                                          \
21337ec681f3Smrg   default:                                           \
21347ec681f3Smrg      unreachable("Unsupported hardware generation"); \
21357ec681f3Smrg   }                                                  \
21367ec681f3Smrg   v3d_X_thing;                                       \
21377ec681f3Smrg})
21387ec681f3Smrg
21397ec681f3Smrg
21407ec681f3Smrg/* v3d_macros from common requires v3dX and V3DX definitions. Below we need to
21417ec681f3Smrg * define v3dX for each version supported, because when we compile code that
21427ec681f3Smrg * is not version-specific, all version-specific macros need to be already
21437ec681f3Smrg * defined.
21447ec681f3Smrg */
21457ec681f3Smrg#ifdef v3dX
21467ec681f3Smrg#  include "v3dvx_private.h"
21477ec681f3Smrg#else
21487ec681f3Smrg#  define v3dX(x) v3d42_##x
21497ec681f3Smrg#  include "v3dvx_private.h"
21507ec681f3Smrg#  undef v3dX
21517ec681f3Smrg#endif
21527ec681f3Smrg
21537ec681f3Smrg#endif /* V3DV_PRIVATE_H */
2154