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