101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2015 Intel Corporation
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2101e04c3fSmrg * IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg
2401e04c3fSmrg#ifndef ANV_PRIVATE_H
2501e04c3fSmrg#define ANV_PRIVATE_H
2601e04c3fSmrg
2701e04c3fSmrg#include <stdlib.h>
2801e04c3fSmrg#include <stdio.h>
2901e04c3fSmrg#include <stdbool.h>
3001e04c3fSmrg#include <pthread.h>
3101e04c3fSmrg#include <assert.h>
3201e04c3fSmrg#include <stdint.h>
339f464c52Smaya#include "drm-uapi/i915_drm.h"
3401e04c3fSmrg
3501e04c3fSmrg#ifdef HAVE_VALGRIND
3601e04c3fSmrg#include <valgrind.h>
3701e04c3fSmrg#include <memcheck.h>
3801e04c3fSmrg#define VG(x) x
3901e04c3fSmrg#ifndef NDEBUG
4001e04c3fSmrg#define __gen_validate_value(x) VALGRIND_CHECK_MEM_IS_DEFINED(&(x), sizeof(x))
4101e04c3fSmrg#endif
4201e04c3fSmrg#else
437ec681f3Smrg#define VG(x) ((void)0)
4401e04c3fSmrg#endif
4501e04c3fSmrg
467ec681f3Smrg#include "common/intel_clflush.h"
477ec681f3Smrg#include "common/intel_decoder.h"
487ec681f3Smrg#include "common/intel_gem.h"
497ec681f3Smrg#include "common/intel_l3_config.h"
507ec681f3Smrg#include "common/intel_measure.h"
517ec681f3Smrg#include "dev/intel_device_info.h"
5201e04c3fSmrg#include "blorp/blorp.h"
5301e04c3fSmrg#include "compiler/brw_compiler.h"
547ec681f3Smrg#include "compiler/brw_rt.h"
557ec681f3Smrg#include "util/bitset.h"
567ec681f3Smrg#include "util/bitscan.h"
5701e04c3fSmrg#include "util/macros.h"
5801e04c3fSmrg#include "util/hash_table.h"
5901e04c3fSmrg#include "util/list.h"
607ec681f3Smrg#include "util/sparse_array.h"
6101e04c3fSmrg#include "util/u_atomic.h"
6201e04c3fSmrg#include "util/u_vector.h"
6301e04c3fSmrg#include "util/u_math.h"
6401e04c3fSmrg#include "util/vma.h"
659f464c52Smaya#include "util/xmlconfig.h"
6601e04c3fSmrg#include "vk_alloc.h"
6701e04c3fSmrg#include "vk_debug_report.h"
687ec681f3Smrg#include "vk_device.h"
697ec681f3Smrg#include "vk_enum_defines.h"
707ec681f3Smrg#include "vk_image.h"
717ec681f3Smrg#include "vk_instance.h"
727ec681f3Smrg#include "vk_physical_device.h"
737ec681f3Smrg#include "vk_shader_module.h"
747ec681f3Smrg#include "vk_util.h"
757ec681f3Smrg#include "vk_command_buffer.h"
767ec681f3Smrg#include "vk_queue.h"
777ec681f3Smrg#include "vk_log.h"
7801e04c3fSmrg
7901e04c3fSmrg/* Pre-declarations needed for WSI entrypoints */
8001e04c3fSmrgstruct wl_surface;
8101e04c3fSmrgstruct wl_display;
8201e04c3fSmrgtypedef struct xcb_connection_t xcb_connection_t;
8301e04c3fSmrgtypedef uint32_t xcb_visualid_t;
8401e04c3fSmrgtypedef uint32_t xcb_window_t;
8501e04c3fSmrg
867ec681f3Smrgstruct anv_batch;
8701e04c3fSmrgstruct anv_buffer;
8801e04c3fSmrgstruct anv_buffer_view;
8901e04c3fSmrgstruct anv_image_view;
907ec681f3Smrgstruct anv_acceleration_structure;
9101e04c3fSmrgstruct anv_instance;
9201e04c3fSmrg
937ec681f3Smrgstruct intel_aux_map_context;
947ec681f3Smrgstruct intel_perf_config;
957ec681f3Smrgstruct intel_perf_counter_pass;
967ec681f3Smrgstruct intel_perf_query_result;
9701e04c3fSmrg
9801e04c3fSmrg#include <vulkan/vulkan.h>
9901e04c3fSmrg#include <vulkan/vk_icd.h>
10001e04c3fSmrg
1019f464c52Smaya#include "anv_android.h"
10201e04c3fSmrg#include "anv_entrypoints.h"
10301e04c3fSmrg#include "isl/isl.h"
10401e04c3fSmrg
1057ec681f3Smrg#include "dev/intel_debug.h"
1067ec681f3Smrg#undef MESA_LOG_TAG
1077ec681f3Smrg#define MESA_LOG_TAG "MESA-INTEL"
1087ec681f3Smrg#include "util/log.h"
10901e04c3fSmrg#include "wsi_common.h"
11001e04c3fSmrg
1117ec681f3Smrg#define NSEC_PER_SEC 1000000000ull
1127ec681f3Smrg
11301e04c3fSmrg/* anv Virtual Memory Layout
11401e04c3fSmrg * =========================
11501e04c3fSmrg *
11601e04c3fSmrg * When the anv driver is determining the virtual graphics addresses of memory
11701e04c3fSmrg * objects itself using the softpin mechanism, the following memory ranges
11801e04c3fSmrg * will be used.
11901e04c3fSmrg *
12001e04c3fSmrg * Three special considerations to notice:
12101e04c3fSmrg *
12201e04c3fSmrg * (1) the dynamic state pool is located within the same 4 GiB as the low
12301e04c3fSmrg * heap. This is to work around a VF cache issue described in a comment in
12401e04c3fSmrg * anv_physical_device_init_heaps.
12501e04c3fSmrg *
12601e04c3fSmrg * (2) the binding table pool is located at lower addresses than the surface
12701e04c3fSmrg * state pool, within a 4 GiB range. This allows surface state base addresses
12801e04c3fSmrg * to cover both binding tables (16 bit offsets) and surface states (32 bit
12901e04c3fSmrg * offsets).
13001e04c3fSmrg *
13101e04c3fSmrg * (3) the last 4 GiB of the address space is withheld from the high
13201e04c3fSmrg * heap. Various hardware units will read past the end of an object for
13301e04c3fSmrg * various reasons. This healthy margin prevents reads from wrapping around
13401e04c3fSmrg * 48-bit addresses.
13501e04c3fSmrg */
1367ec681f3Smrg#define GENERAL_STATE_POOL_MIN_ADDRESS     0x000000010000ULL /* 64 KiB */
1377ec681f3Smrg#define GENERAL_STATE_POOL_MAX_ADDRESS     0x00003fffffffULL
1387ec681f3Smrg#define LOW_HEAP_MIN_ADDRESS               0x000040000000ULL /* 1 GiB */
1397ec681f3Smrg#define LOW_HEAP_MAX_ADDRESS               0x00007fffffffULL
14001e04c3fSmrg#define DYNAMIC_STATE_POOL_MIN_ADDRESS     0x0000c0000000ULL /* 3 GiB */
14101e04c3fSmrg#define DYNAMIC_STATE_POOL_MAX_ADDRESS     0x0000ffffffffULL
14201e04c3fSmrg#define BINDING_TABLE_POOL_MIN_ADDRESS     0x000100000000ULL /* 4 GiB */
14301e04c3fSmrg#define BINDING_TABLE_POOL_MAX_ADDRESS     0x00013fffffffULL
14401e04c3fSmrg#define SURFACE_STATE_POOL_MIN_ADDRESS     0x000140000000ULL /* 5 GiB */
14501e04c3fSmrg#define SURFACE_STATE_POOL_MAX_ADDRESS     0x00017fffffffULL
14601e04c3fSmrg#define INSTRUCTION_STATE_POOL_MIN_ADDRESS 0x000180000000ULL /* 6 GiB */
14701e04c3fSmrg#define INSTRUCTION_STATE_POOL_MAX_ADDRESS 0x0001bfffffffULL
1487ec681f3Smrg#define CLIENT_VISIBLE_HEAP_MIN_ADDRESS    0x0001c0000000ULL /* 7 GiB */
1497ec681f3Smrg#define CLIENT_VISIBLE_HEAP_MAX_ADDRESS    0x0002bfffffffULL
1507ec681f3Smrg#define HIGH_HEAP_MIN_ADDRESS              0x0002c0000000ULL /* 11 GiB */
15101e04c3fSmrg
1527ec681f3Smrg#define GENERAL_STATE_POOL_SIZE     \
1537ec681f3Smrg   (GENERAL_STATE_POOL_MAX_ADDRESS - GENERAL_STATE_POOL_MIN_ADDRESS + 1)
15401e04c3fSmrg#define LOW_HEAP_SIZE               \
15501e04c3fSmrg   (LOW_HEAP_MAX_ADDRESS - LOW_HEAP_MIN_ADDRESS + 1)
15601e04c3fSmrg#define DYNAMIC_STATE_POOL_SIZE     \
15701e04c3fSmrg   (DYNAMIC_STATE_POOL_MAX_ADDRESS - DYNAMIC_STATE_POOL_MIN_ADDRESS + 1)
15801e04c3fSmrg#define BINDING_TABLE_POOL_SIZE     \
15901e04c3fSmrg   (BINDING_TABLE_POOL_MAX_ADDRESS - BINDING_TABLE_POOL_MIN_ADDRESS + 1)
16001e04c3fSmrg#define SURFACE_STATE_POOL_SIZE     \
16101e04c3fSmrg   (SURFACE_STATE_POOL_MAX_ADDRESS - SURFACE_STATE_POOL_MIN_ADDRESS + 1)
16201e04c3fSmrg#define INSTRUCTION_STATE_POOL_SIZE \
16301e04c3fSmrg   (INSTRUCTION_STATE_POOL_MAX_ADDRESS - INSTRUCTION_STATE_POOL_MIN_ADDRESS + 1)
1647ec681f3Smrg#define CLIENT_VISIBLE_HEAP_SIZE               \
1657ec681f3Smrg   (CLIENT_VISIBLE_HEAP_MAX_ADDRESS - CLIENT_VISIBLE_HEAP_MIN_ADDRESS + 1)
16601e04c3fSmrg
16701e04c3fSmrg/* Allowing different clear colors requires us to perform a depth resolve at
16801e04c3fSmrg * the end of certain render passes. This is because while slow clears store
16901e04c3fSmrg * the clear color in the HiZ buffer, fast clears (without a resolve) don't.
17001e04c3fSmrg * See the PRMs for examples describing when additional resolves would be
17101e04c3fSmrg * necessary. To enable fast clears without requiring extra resolves, we set
17201e04c3fSmrg * the clear value to a globally-defined one. We could allow different values
17301e04c3fSmrg * if the user doesn't expect coherent data during or after a render passes
17401e04c3fSmrg * (VK_ATTACHMENT_STORE_OP_DONT_CARE), but such users (aside from the CTS)
17501e04c3fSmrg * don't seem to exist yet. In almost all Vulkan applications tested thus far,
17601e04c3fSmrg * 1.0f seems to be the only value used. The only application that doesn't set
17701e04c3fSmrg * this value does so through the usage of an seemingly uninitialized clear
17801e04c3fSmrg * value.
17901e04c3fSmrg */
18001e04c3fSmrg#define ANV_HZ_FC_VAL 1.0f
18101e04c3fSmrg
18201e04c3fSmrg#define MAX_VBS         28
1839f464c52Smaya#define MAX_XFB_BUFFERS  4
1849f464c52Smaya#define MAX_XFB_STREAMS  4
18501e04c3fSmrg#define MAX_SETS         8
18601e04c3fSmrg#define MAX_RTS          8
18701e04c3fSmrg#define MAX_VIEWPORTS   16
18801e04c3fSmrg#define MAX_SCISSORS    16
18901e04c3fSmrg#define MAX_PUSH_CONSTANTS_SIZE 128
19001e04c3fSmrg#define MAX_DYNAMIC_BUFFERS 16
19101e04c3fSmrg#define MAX_IMAGES 64
19201e04c3fSmrg#define MAX_PUSH_DESCRIPTORS 32 /* Minimum requirement */
1939f464c52Smaya#define MAX_INLINE_UNIFORM_BLOCK_SIZE 4096
1949f464c52Smaya#define MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS 32
1957ec681f3Smrg/* We need 16 for UBO block reads to work and 32 for push UBOs. However, we
1967ec681f3Smrg * use 64 here to avoid cache issues. This could most likely bring it back to
1977ec681f3Smrg * 32 if we had different virtual addresses for the different views on a given
1987ec681f3Smrg * GEM object.
1997ec681f3Smrg */
2007ec681f3Smrg#define ANV_UBO_ALIGNMENT 64
2017ec681f3Smrg#define ANV_SSBO_ALIGNMENT 4
2027ec681f3Smrg#define ANV_SSBO_BOUNDS_CHECK_ALIGNMENT 4
2037ec681f3Smrg#define MAX_VIEWS_FOR_PRIMITIVE_REPLICATION 16
2047ec681f3Smrg#define MAX_SAMPLE_LOCATIONS 16
2059f464c52Smaya
2069f464c52Smaya/* From the Skylake PRM Vol. 7 "Binding Table Surface State Model":
2079f464c52Smaya *
2089f464c52Smaya *    "The surface state model is used when a Binding Table Index (specified
2099f464c52Smaya *    in the message descriptor) of less than 240 is specified. In this model,
2109f464c52Smaya *    the Binding Table Index is used to index into the binding table, and the
2119f464c52Smaya *    binding table entry contains a pointer to the SURFACE_STATE."
2129f464c52Smaya *
2139f464c52Smaya * Binding table values above 240 are used for various things in the hardware
2149f464c52Smaya * such as stateless, stateless with incoherent cache, SLM, and bindless.
2159f464c52Smaya */
2169f464c52Smaya#define MAX_BINDING_TABLE_SIZE 240
21701e04c3fSmrg
21801e04c3fSmrg/* The kernel relocation API has a limitation of a 32-bit delta value
21901e04c3fSmrg * applied to the address before it is written which, in spite of it being
22001e04c3fSmrg * unsigned, is treated as signed .  Because of the way that this maps to
22101e04c3fSmrg * the Vulkan API, we cannot handle an offset into a buffer that does not
22201e04c3fSmrg * fit into a signed 32 bits.  The only mechanism we have for dealing with
22301e04c3fSmrg * this at the moment is to limit all VkDeviceMemory objects to a maximum
22401e04c3fSmrg * of 2GB each.  The Vulkan spec allows us to do this:
22501e04c3fSmrg *
22601e04c3fSmrg *    "Some platforms may have a limit on the maximum size of a single
22701e04c3fSmrg *    allocation. For example, certain systems may fail to create
22801e04c3fSmrg *    allocations with a size greater than or equal to 4GB. Such a limit is
22901e04c3fSmrg *    implementation-dependent, and if such a failure occurs then the error
23001e04c3fSmrg *    VK_ERROR_OUT_OF_DEVICE_MEMORY should be returned."
23101e04c3fSmrg */
23201e04c3fSmrg#define MAX_MEMORY_ALLOCATION_SIZE (1ull << 31)
23301e04c3fSmrg
23401e04c3fSmrg#define ANV_SVGS_VB_INDEX    MAX_VBS
23501e04c3fSmrg#define ANV_DRAWID_VB_INDEX (MAX_VBS + 1)
23601e04c3fSmrg
2379f464c52Smaya/* We reserve this MI ALU register for the purpose of handling predication.
2389f464c52Smaya * Other code which uses the MI ALU should leave it alone.
2399f464c52Smaya */
2409f464c52Smaya#define ANV_PREDICATE_RESULT_REG 0x2678 /* MI_ALU_REG15 */
2419f464c52Smaya
2427ec681f3Smrg/* We reserve this MI ALU register to pass around an offset computed from
2437ec681f3Smrg * VkPerformanceQuerySubmitInfoKHR::counterPassIndex VK_KHR_performance_query.
2447ec681f3Smrg * Other code which uses the MI ALU should leave it alone.
2457ec681f3Smrg */
2467ec681f3Smrg#define ANV_PERF_QUERY_OFFSET_REG 0x2670 /* MI_ALU_REG14 */
2477ec681f3Smrg
2487ec681f3Smrg/* For gfx12 we set the streamout buffers using 4 separate commands
2497ec681f3Smrg * (3DSTATE_SO_BUFFER_INDEX_*) instead of 3DSTATE_SO_BUFFER. However the layout
2507ec681f3Smrg * of the 3DSTATE_SO_BUFFER_INDEX_* commands is identical to that of
2517ec681f3Smrg * 3DSTATE_SO_BUFFER apart from the SOBufferIndex field, so for now we use the
2527ec681f3Smrg * 3DSTATE_SO_BUFFER command, but change the 3DCommandSubOpcode.
2537ec681f3Smrg * SO_BUFFER_INDEX_0_CMD is actually the 3DCommandSubOpcode for
2547ec681f3Smrg * 3DSTATE_SO_BUFFER_INDEX_0.
2557ec681f3Smrg */
2567ec681f3Smrg#define SO_BUFFER_INDEX_0_CMD 0x60
25701e04c3fSmrg#define anv_printflike(a, b) __attribute__((__format__(__printf__, a, b)))
25801e04c3fSmrg
25901e04c3fSmrgstatic inline uint32_t
26001e04c3fSmrgalign_down_npot_u32(uint32_t v, uint32_t a)
26101e04c3fSmrg{
26201e04c3fSmrg   return v - (v % a);
26301e04c3fSmrg}
26401e04c3fSmrg
2657ec681f3Smrgstatic inline uint32_t
2667ec681f3Smrgalign_down_u32(uint32_t v, uint32_t a)
2677ec681f3Smrg{
2687ec681f3Smrg   assert(a != 0 && a == (a & -a));
2697ec681f3Smrg   return v & ~(a - 1);
2707ec681f3Smrg}
2717ec681f3Smrg
27201e04c3fSmrgstatic inline uint32_t
27301e04c3fSmrgalign_u32(uint32_t v, uint32_t a)
27401e04c3fSmrg{
27501e04c3fSmrg   assert(a != 0 && a == (a & -a));
2767ec681f3Smrg   return align_down_u32(v + a - 1, a);
27701e04c3fSmrg}
27801e04c3fSmrg
27901e04c3fSmrgstatic inline uint64_t
2807ec681f3Smrgalign_down_u64(uint64_t v, uint64_t a)
28101e04c3fSmrg{
28201e04c3fSmrg   assert(a != 0 && a == (a & -a));
2837ec681f3Smrg   return v & ~(a - 1);
2847ec681f3Smrg}
2857ec681f3Smrg
2867ec681f3Smrgstatic inline uint64_t
2877ec681f3Smrgalign_u64(uint64_t v, uint64_t a)
2887ec681f3Smrg{
2897ec681f3Smrg   return align_down_u64(v + a - 1, a);
29001e04c3fSmrg}
29101e04c3fSmrg
29201e04c3fSmrgstatic inline int32_t
29301e04c3fSmrgalign_i32(int32_t v, int32_t a)
29401e04c3fSmrg{
29501e04c3fSmrg   assert(a != 0 && a == (a & -a));
29601e04c3fSmrg   return (v + a - 1) & ~(a - 1);
29701e04c3fSmrg}
29801e04c3fSmrg
29901e04c3fSmrg/** Alignment must be a power of 2. */
30001e04c3fSmrgstatic inline bool
30101e04c3fSmrganv_is_aligned(uintmax_t n, uintmax_t a)
30201e04c3fSmrg{
30301e04c3fSmrg   assert(a == (a & -a));
30401e04c3fSmrg   return (n & (a - 1)) == 0;
30501e04c3fSmrg}
30601e04c3fSmrg
30701e04c3fSmrgstatic inline uint32_t
30801e04c3fSmrganv_minify(uint32_t n, uint32_t levels)
30901e04c3fSmrg{
31001e04c3fSmrg   if (unlikely(n == 0))
31101e04c3fSmrg      return 0;
31201e04c3fSmrg   else
31301e04c3fSmrg      return MAX2(n >> levels, 1);
31401e04c3fSmrg}
31501e04c3fSmrg
31601e04c3fSmrgstatic inline float
31701e04c3fSmrganv_clamp_f(float f, float min, float max)
31801e04c3fSmrg{
31901e04c3fSmrg   assert(min < max);
32001e04c3fSmrg
32101e04c3fSmrg   if (f > max)
32201e04c3fSmrg      return max;
32301e04c3fSmrg   else if (f < min)
32401e04c3fSmrg      return min;
32501e04c3fSmrg   else
32601e04c3fSmrg      return f;
32701e04c3fSmrg}
32801e04c3fSmrg
32901e04c3fSmrgstatic inline bool
33001e04c3fSmrganv_clear_mask(uint32_t *inout_mask, uint32_t clear_mask)
33101e04c3fSmrg{
33201e04c3fSmrg   if (*inout_mask & clear_mask) {
33301e04c3fSmrg      *inout_mask &= ~clear_mask;
33401e04c3fSmrg      return true;
33501e04c3fSmrg   } else {
33601e04c3fSmrg      return false;
33701e04c3fSmrg   }
33801e04c3fSmrg}
33901e04c3fSmrg
34001e04c3fSmrgstatic inline union isl_color_value
34101e04c3fSmrgvk_to_isl_color(VkClearColorValue color)
34201e04c3fSmrg{
34301e04c3fSmrg   return (union isl_color_value) {
34401e04c3fSmrg      .u32 = {
34501e04c3fSmrg         color.uint32[0],
34601e04c3fSmrg         color.uint32[1],
34701e04c3fSmrg         color.uint32[2],
34801e04c3fSmrg         color.uint32[3],
34901e04c3fSmrg      },
35001e04c3fSmrg   };
35101e04c3fSmrg}
35201e04c3fSmrg
3537ec681f3Smrgstatic inline void *anv_unpack_ptr(uintptr_t ptr, int bits, int *flags)
3547ec681f3Smrg{
3557ec681f3Smrg   uintptr_t mask = (1ull << bits) - 1;
3567ec681f3Smrg   *flags = ptr & mask;
3577ec681f3Smrg   return (void *) (ptr & ~mask);
3587ec681f3Smrg}
35901e04c3fSmrg
3607ec681f3Smrgstatic inline uintptr_t anv_pack_ptr(void *ptr, int bits, int flags)
3617ec681f3Smrg{
3627ec681f3Smrg   uintptr_t value = (uintptr_t) ptr;
3637ec681f3Smrg   uintptr_t mask = (1ull << bits) - 1;
3647ec681f3Smrg   return value | (mask & flags);
3657ec681f3Smrg}
36601e04c3fSmrg
36701e04c3fSmrg/**
36801e04c3fSmrg * Warn on ignored extension structs.
36901e04c3fSmrg *
37001e04c3fSmrg * The Vulkan spec requires us to ignore unsupported or unknown structs in
37101e04c3fSmrg * a pNext chain.  In debug mode, emitting warnings for ignored structs may
37201e04c3fSmrg * help us discover structs that we should not have ignored.
37301e04c3fSmrg *
37401e04c3fSmrg *
37501e04c3fSmrg * From the Vulkan 1.0.38 spec:
37601e04c3fSmrg *
37701e04c3fSmrg *    Any component of the implementation (the loader, any enabled layers,
37801e04c3fSmrg *    and drivers) must skip over, without processing (other than reading the
37901e04c3fSmrg *    sType and pNext members) any chained structures with sType values not
38001e04c3fSmrg *    defined by extensions supported by that component.
38101e04c3fSmrg */
38201e04c3fSmrg#define anv_debug_ignored_stype(sType) \
3837ec681f3Smrg   mesa_logd("%s: ignored VkStructureType %u\n", __func__, (sType))
38401e04c3fSmrg
3857ec681f3Smrgvoid __anv_perf_warn(struct anv_device *device,
3867ec681f3Smrg                     const struct vk_object_base *object,
3877ec681f3Smrg                     const char *file, int line, const char *format, ...)
3887ec681f3Smrg   anv_printflike(5, 6);
38901e04c3fSmrg
39001e04c3fSmrg/**
39101e04c3fSmrg * Print a FINISHME message, including its source location.
39201e04c3fSmrg */
39301e04c3fSmrg#define anv_finishme(format, ...) \
39401e04c3fSmrg   do { \
39501e04c3fSmrg      static bool reported = false; \
39601e04c3fSmrg      if (!reported) { \
3977ec681f3Smrg         mesa_logw("%s:%d: FINISHME: " format, __FILE__, __LINE__, \
39801e04c3fSmrg                    ##__VA_ARGS__); \
39901e04c3fSmrg         reported = true; \
40001e04c3fSmrg      } \
40101e04c3fSmrg   } while (0)
40201e04c3fSmrg
40301e04c3fSmrg/**
40401e04c3fSmrg * Print a perf warning message.  Set INTEL_DEBUG=perf to see these.
40501e04c3fSmrg */
4067ec681f3Smrg#define anv_perf_warn(objects_macro, format, ...)   \
40701e04c3fSmrg   do { \
40801e04c3fSmrg      static bool reported = false; \
4097ec681f3Smrg      if (!reported && INTEL_DEBUG(DEBUG_PERF)) { \
4107ec681f3Smrg         __vk_log(VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,      \
4117ec681f3Smrg                  VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,      \
4127ec681f3Smrg                  objects_macro, __FILE__, __LINE__,                    \
4137ec681f3Smrg                  format, ## __VA_ARGS__);                              \
41401e04c3fSmrg         reported = true; \
41501e04c3fSmrg      } \
41601e04c3fSmrg   } while (0)
41701e04c3fSmrg
41801e04c3fSmrg/* A non-fatal assert.  Useful for debugging. */
41901e04c3fSmrg#ifdef DEBUG
42001e04c3fSmrg#define anv_assert(x) ({ \
42101e04c3fSmrg   if (unlikely(!(x))) \
4227ec681f3Smrg      mesa_loge("%s:%d ASSERT: %s", __FILE__, __LINE__, #x); \
42301e04c3fSmrg})
42401e04c3fSmrg#else
42501e04c3fSmrg#define anv_assert(x)
42601e04c3fSmrg#endif
42701e04c3fSmrg
42801e04c3fSmrgstruct anv_bo {
4297ec681f3Smrg   const char *name;
4307ec681f3Smrg
43101e04c3fSmrg   uint32_t gem_handle;
43201e04c3fSmrg
4337ec681f3Smrg   uint32_t refcount;
4347ec681f3Smrg
43501e04c3fSmrg   /* Index into the current validation list.  This is used by the
43601e04c3fSmrg    * validation list building alrogithm to track which buffers are already
43701e04c3fSmrg    * in the validation list so that we can ensure uniqueness.
43801e04c3fSmrg    */
43901e04c3fSmrg   uint32_t index;
44001e04c3fSmrg
4417ec681f3Smrg   /* Index for use with util_sparse_array_free_list */
4427ec681f3Smrg   uint32_t free_index;
4437ec681f3Smrg
44401e04c3fSmrg   /* Last known offset.  This value is provided by the kernel when we
44501e04c3fSmrg    * execbuf and is used as the presumed offset for the next bunch of
44601e04c3fSmrg    * relocations.
44701e04c3fSmrg    */
44801e04c3fSmrg   uint64_t offset;
44901e04c3fSmrg
4507ec681f3Smrg   /** Size of the buffer not including implicit aux */
45101e04c3fSmrg   uint64_t size;
4527ec681f3Smrg
4537ec681f3Smrg   /* Map for internally mapped BOs.
4547ec681f3Smrg    *
4557ec681f3Smrg    * If ANV_BO_WRAPPER is set in flags, map points to the wrapped BO.
4567ec681f3Smrg    */
45701e04c3fSmrg   void *map;
45801e04c3fSmrg
4597ec681f3Smrg   /** Size of the implicit CCS range at the end of the buffer
4607ec681f3Smrg    *
4617ec681f3Smrg    * On Gfx12, CCS data is always a direct 1/256 scale-down.  A single 64K
4627ec681f3Smrg    * page of main surface data maps to a 256B chunk of CCS data and that
4637ec681f3Smrg    * mapping is provided on TGL-LP by the AUX table which maps virtual memory
4647ec681f3Smrg    * addresses in the main surface to virtual memory addresses for CCS data.
4657ec681f3Smrg    *
4667ec681f3Smrg    * Because we can't change these maps around easily and because Vulkan
4677ec681f3Smrg    * allows two VkImages to be bound to overlapping memory regions (as long
4687ec681f3Smrg    * as the app is careful), it's not feasible to make this mapping part of
4697ec681f3Smrg    * the image.  (On Gfx11 and earlier, the mapping was provided via
4707ec681f3Smrg    * RENDER_SURFACE_STATE so each image had its own main -> CCS mapping.)
4717ec681f3Smrg    * Instead, we attach the CCS data directly to the buffer object and setup
4727ec681f3Smrg    * the AUX table mapping at BO creation time.
4737ec681f3Smrg    *
4747ec681f3Smrg    * This field is for internal tracking use by the BO allocator only and
4757ec681f3Smrg    * should not be touched by other parts of the code.  If something wants to
4767ec681f3Smrg    * know if a BO has implicit CCS data, it should instead look at the
4777ec681f3Smrg    * has_implicit_ccs boolean below.
4787ec681f3Smrg    *
4797ec681f3Smrg    * This data is not included in maps of this buffer.
4807ec681f3Smrg    */
4817ec681f3Smrg   uint32_t _ccs_size;
4827ec681f3Smrg
48301e04c3fSmrg   /** Flags to pass to the kernel through drm_i915_exec_object2::flags */
48401e04c3fSmrg   uint32_t flags;
4857ec681f3Smrg
4867ec681f3Smrg   /** True if this BO may be shared with other processes */
4877ec681f3Smrg   bool is_external:1;
4887ec681f3Smrg
4897ec681f3Smrg   /** True if this BO is a wrapper
4907ec681f3Smrg    *
4917ec681f3Smrg    * When set to true, none of the fields in this BO are meaningful except
4927ec681f3Smrg    * for anv_bo::is_wrapper and anv_bo::map which points to the actual BO.
4937ec681f3Smrg    * See also anv_bo_unwrap().  Wrapper BOs are not allowed when use_softpin
4947ec681f3Smrg    * is set in the physical device.
4957ec681f3Smrg    */
4967ec681f3Smrg   bool is_wrapper:1;
4977ec681f3Smrg
4987ec681f3Smrg   /** See also ANV_BO_ALLOC_FIXED_ADDRESS */
4997ec681f3Smrg   bool has_fixed_address:1;
5007ec681f3Smrg
5017ec681f3Smrg   /** True if this BO wraps a host pointer */
5027ec681f3Smrg   bool from_host_ptr:1;
5037ec681f3Smrg
5047ec681f3Smrg   /** See also ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS */
5057ec681f3Smrg   bool has_client_visible_address:1;
5067ec681f3Smrg
5077ec681f3Smrg   /** True if this BO has implicit CCS data attached to it */
5087ec681f3Smrg   bool has_implicit_ccs:1;
50901e04c3fSmrg};
51001e04c3fSmrg
5117ec681f3Smrgstatic inline struct anv_bo *
5127ec681f3Smrganv_bo_ref(struct anv_bo *bo)
5137ec681f3Smrg{
5147ec681f3Smrg   p_atomic_inc(&bo->refcount);
5157ec681f3Smrg   return bo;
5167ec681f3Smrg}
5177ec681f3Smrg
5187ec681f3Smrgstatic inline struct anv_bo *
5197ec681f3Smrganv_bo_unwrap(struct anv_bo *bo)
52001e04c3fSmrg{
5217ec681f3Smrg   while (bo->is_wrapper)
5227ec681f3Smrg      bo = bo->map;
5237ec681f3Smrg   return bo;
52401e04c3fSmrg}
52501e04c3fSmrg
52601e04c3fSmrg/* Represents a lock-free linked list of "free" things.  This is used by
52701e04c3fSmrg * both the block pool and the state pools.  Unfortunately, in order to
52801e04c3fSmrg * solve the ABA problem, we can't use a single uint32_t head.
52901e04c3fSmrg */
53001e04c3fSmrgunion anv_free_list {
53101e04c3fSmrg   struct {
5329f464c52Smaya      uint32_t offset;
53301e04c3fSmrg
53401e04c3fSmrg      /* A simple count that is incremented every time the head changes. */
53501e04c3fSmrg      uint32_t count;
53601e04c3fSmrg   };
5377ec681f3Smrg   /* Make sure it's aligned to 64 bits. This will make atomic operations
5387ec681f3Smrg    * faster on 32 bit platforms.
5397ec681f3Smrg    */
5407ec681f3Smrg   uint64_t u64 __attribute__ ((aligned (8)));
54101e04c3fSmrg};
54201e04c3fSmrg
5439f464c52Smaya#define ANV_FREE_LIST_EMPTY ((union anv_free_list) { { UINT32_MAX, 0 } })
54401e04c3fSmrg
54501e04c3fSmrgstruct anv_block_state {
54601e04c3fSmrg   union {
54701e04c3fSmrg      struct {
54801e04c3fSmrg         uint32_t next;
54901e04c3fSmrg         uint32_t end;
55001e04c3fSmrg      };
5517ec681f3Smrg      /* Make sure it's aligned to 64 bits. This will make atomic operations
5527ec681f3Smrg       * faster on 32 bit platforms.
5537ec681f3Smrg       */
5547ec681f3Smrg      uint64_t u64 __attribute__ ((aligned (8)));
55501e04c3fSmrg   };
55601e04c3fSmrg};
55701e04c3fSmrg
5589f464c52Smaya#define anv_block_pool_foreach_bo(bo, pool)  \
5597ec681f3Smrg   for (struct anv_bo **_pp_bo = (pool)->bos, *bo; \
5607ec681f3Smrg        _pp_bo != &(pool)->bos[(pool)->nbos] && (bo = *_pp_bo, true); \
5617ec681f3Smrg        _pp_bo++)
5629f464c52Smaya
5639f464c52Smaya#define ANV_MAX_BLOCK_POOL_BOS 20
5649f464c52Smaya
56501e04c3fSmrgstruct anv_block_pool {
5667ec681f3Smrg   const char *name;
5677ec681f3Smrg
56801e04c3fSmrg   struct anv_device *device;
5697ec681f3Smrg   bool use_softpin;
57001e04c3fSmrg
5717ec681f3Smrg   /* Wrapper BO for use in relocation lists.  This BO is simply a wrapper
5727ec681f3Smrg    * around the actual BO so that we grow the pool after the wrapper BO has
5737ec681f3Smrg    * been put in a relocation list.  This is only used in the non-softpin
5747ec681f3Smrg    * case.
5757ec681f3Smrg    */
5767ec681f3Smrg   struct anv_bo wrapper_bo;
57701e04c3fSmrg
5787ec681f3Smrg   struct anv_bo *bos[ANV_MAX_BLOCK_POOL_BOS];
5799f464c52Smaya   struct anv_bo *bo;
5809f464c52Smaya   uint32_t nbos;
5819f464c52Smaya
5829f464c52Smaya   uint64_t size;
58301e04c3fSmrg
58401e04c3fSmrg   /* The address where the start of the pool is pinned. The various bos that
58501e04c3fSmrg    * are created as the pool grows will have addresses in the range
58601e04c3fSmrg    * [start_address, start_address + BLOCK_POOL_MEMFD_SIZE).
58701e04c3fSmrg    */
58801e04c3fSmrg   uint64_t start_address;
58901e04c3fSmrg
59001e04c3fSmrg   /* The offset from the start of the bo to the "center" of the block
59101e04c3fSmrg    * pool.  Pointers to allocated blocks are given by
59201e04c3fSmrg    * bo.map + center_bo_offset + offsets.
59301e04c3fSmrg    */
59401e04c3fSmrg   uint32_t center_bo_offset;
59501e04c3fSmrg
59601e04c3fSmrg   /* Current memory map of the block pool.  This pointer may or may not
59701e04c3fSmrg    * point to the actual beginning of the block pool memory.  If
59801e04c3fSmrg    * anv_block_pool_alloc_back has ever been called, then this pointer
59901e04c3fSmrg    * will point to the "center" position of the buffer and all offsets
60001e04c3fSmrg    * (negative or positive) given out by the block pool alloc functions
60101e04c3fSmrg    * will be valid relative to this pointer.
60201e04c3fSmrg    *
60301e04c3fSmrg    * In particular, map == bo.map + center_offset
6049f464c52Smaya    *
6059f464c52Smaya    * DO NOT access this pointer directly. Use anv_block_pool_map() instead,
6069f464c52Smaya    * since it will handle the softpin case as well, where this points to NULL.
60701e04c3fSmrg    */
60801e04c3fSmrg   void *map;
60901e04c3fSmrg   int fd;
61001e04c3fSmrg
61101e04c3fSmrg   /**
61201e04c3fSmrg    * Array of mmaps and gem handles owned by the block pool, reclaimed when
61301e04c3fSmrg    * the block pool is destroyed.
61401e04c3fSmrg    */
61501e04c3fSmrg   struct u_vector mmap_cleanups;
61601e04c3fSmrg
61701e04c3fSmrg   struct anv_block_state state;
61801e04c3fSmrg
61901e04c3fSmrg   struct anv_block_state back_state;
62001e04c3fSmrg};
62101e04c3fSmrg
62201e04c3fSmrg/* Block pools are backed by a fixed-size 1GB memfd */
62301e04c3fSmrg#define BLOCK_POOL_MEMFD_SIZE (1ul << 30)
62401e04c3fSmrg
62501e04c3fSmrg/* The center of the block pool is also the middle of the memfd.  This may
62601e04c3fSmrg * change in the future if we decide differently for some reason.
62701e04c3fSmrg */
62801e04c3fSmrg#define BLOCK_POOL_MEMFD_CENTER (BLOCK_POOL_MEMFD_SIZE / 2)
62901e04c3fSmrg
63001e04c3fSmrgstatic inline uint32_t
63101e04c3fSmrganv_block_pool_size(struct anv_block_pool *pool)
63201e04c3fSmrg{
63301e04c3fSmrg   return pool->state.end + pool->back_state.end;
63401e04c3fSmrg}
63501e04c3fSmrg
63601e04c3fSmrgstruct anv_state {
63701e04c3fSmrg   int32_t offset;
63801e04c3fSmrg   uint32_t alloc_size;
63901e04c3fSmrg   void *map;
6409f464c52Smaya   uint32_t idx;
64101e04c3fSmrg};
64201e04c3fSmrg
64301e04c3fSmrg#define ANV_STATE_NULL ((struct anv_state) { .alloc_size = 0 })
64401e04c3fSmrg
64501e04c3fSmrgstruct anv_fixed_size_state_pool {
64601e04c3fSmrg   union anv_free_list free_list;
64701e04c3fSmrg   struct anv_block_state block;
64801e04c3fSmrg};
64901e04c3fSmrg
65001e04c3fSmrg#define ANV_MIN_STATE_SIZE_LOG2 6
6517ec681f3Smrg#define ANV_MAX_STATE_SIZE_LOG2 21
65201e04c3fSmrg
65301e04c3fSmrg#define ANV_STATE_BUCKETS (ANV_MAX_STATE_SIZE_LOG2 - ANV_MIN_STATE_SIZE_LOG2 + 1)
65401e04c3fSmrg
6559f464c52Smayastruct anv_free_entry {
6569f464c52Smaya   uint32_t next;
6579f464c52Smaya   struct anv_state state;
6589f464c52Smaya};
6599f464c52Smaya
6609f464c52Smayastruct anv_state_table {
6619f464c52Smaya   struct anv_device *device;
6629f464c52Smaya   int fd;
6639f464c52Smaya   struct anv_free_entry *map;
6649f464c52Smaya   uint32_t size;
6659f464c52Smaya   struct anv_block_state state;
6669f464c52Smaya   struct u_vector cleanups;
6679f464c52Smaya};
6689f464c52Smaya
66901e04c3fSmrgstruct anv_state_pool {
67001e04c3fSmrg   struct anv_block_pool block_pool;
67101e04c3fSmrg
6727ec681f3Smrg   /* Offset into the relevant state base address where the state pool starts
6737ec681f3Smrg    * allocating memory.
6747ec681f3Smrg    */
6757ec681f3Smrg   int32_t start_offset;
6767ec681f3Smrg
6779f464c52Smaya   struct anv_state_table table;
6789f464c52Smaya
67901e04c3fSmrg   /* The size of blocks which will be allocated from the block pool */
68001e04c3fSmrg   uint32_t block_size;
68101e04c3fSmrg
68201e04c3fSmrg   /** Free list for "back" allocations */
68301e04c3fSmrg   union anv_free_list back_alloc_free_list;
68401e04c3fSmrg
68501e04c3fSmrg   struct anv_fixed_size_state_pool buckets[ANV_STATE_BUCKETS];
68601e04c3fSmrg};
68701e04c3fSmrg
6887ec681f3Smrgstruct anv_state_reserved_pool {
6897ec681f3Smrg   struct anv_state_pool *pool;
6907ec681f3Smrg   union anv_free_list reserved_blocks;
6917ec681f3Smrg   uint32_t count;
6927ec681f3Smrg};
69301e04c3fSmrg
69401e04c3fSmrgstruct anv_state_stream {
69501e04c3fSmrg   struct anv_state_pool *state_pool;
69601e04c3fSmrg
69701e04c3fSmrg   /* The size of blocks to allocate from the state pool */
69801e04c3fSmrg   uint32_t block_size;
69901e04c3fSmrg
70001e04c3fSmrg   /* Current block we're allocating from */
70101e04c3fSmrg   struct anv_state block;
70201e04c3fSmrg
70301e04c3fSmrg   /* Offset into the current block at which to allocate the next state */
70401e04c3fSmrg   uint32_t next;
70501e04c3fSmrg
70601e04c3fSmrg   /* List of all blocks allocated from this pool */
7077ec681f3Smrg   struct util_dynarray all_blocks;
70801e04c3fSmrg};
70901e04c3fSmrg
71001e04c3fSmrg/* The block_pool functions exported for testing only.  The block pool should
71101e04c3fSmrg * only be used via a state pool (see below).
71201e04c3fSmrg */
71301e04c3fSmrgVkResult anv_block_pool_init(struct anv_block_pool *pool,
71401e04c3fSmrg                             struct anv_device *device,
7157ec681f3Smrg                             const char *name,
71601e04c3fSmrg                             uint64_t start_address,
7177ec681f3Smrg                             uint32_t initial_size);
71801e04c3fSmrgvoid anv_block_pool_finish(struct anv_block_pool *pool);
71901e04c3fSmrgint32_t anv_block_pool_alloc(struct anv_block_pool *pool,
7209f464c52Smaya                             uint32_t block_size, uint32_t *padding);
72101e04c3fSmrgint32_t anv_block_pool_alloc_back(struct anv_block_pool *pool,
72201e04c3fSmrg                                  uint32_t block_size);
7237ec681f3Smrgvoid* anv_block_pool_map(struct anv_block_pool *pool, int32_t offset, uint32_t
7247ec681f3Smrgsize);
72501e04c3fSmrg
72601e04c3fSmrgVkResult anv_state_pool_init(struct anv_state_pool *pool,
72701e04c3fSmrg                             struct anv_device *device,
7287ec681f3Smrg                             const char *name,
7297ec681f3Smrg                             uint64_t base_address,
7307ec681f3Smrg                             int32_t start_offset,
7317ec681f3Smrg                             uint32_t block_size);
73201e04c3fSmrgvoid anv_state_pool_finish(struct anv_state_pool *pool);
73301e04c3fSmrgstruct anv_state anv_state_pool_alloc(struct anv_state_pool *pool,
73401e04c3fSmrg                                      uint32_t state_size, uint32_t alignment);
73501e04c3fSmrgstruct anv_state anv_state_pool_alloc_back(struct anv_state_pool *pool);
73601e04c3fSmrgvoid anv_state_pool_free(struct anv_state_pool *pool, struct anv_state state);
73701e04c3fSmrgvoid anv_state_stream_init(struct anv_state_stream *stream,
73801e04c3fSmrg                           struct anv_state_pool *state_pool,
73901e04c3fSmrg                           uint32_t block_size);
74001e04c3fSmrgvoid anv_state_stream_finish(struct anv_state_stream *stream);
74101e04c3fSmrgstruct anv_state anv_state_stream_alloc(struct anv_state_stream *stream,
74201e04c3fSmrg                                        uint32_t size, uint32_t alignment);
74301e04c3fSmrg
7447ec681f3Smrgvoid anv_state_reserved_pool_init(struct anv_state_reserved_pool *pool,
7457ec681f3Smrg                                      struct anv_state_pool *parent,
7467ec681f3Smrg                                      uint32_t count, uint32_t size,
7477ec681f3Smrg                                      uint32_t alignment);
7487ec681f3Smrgvoid anv_state_reserved_pool_finish(struct anv_state_reserved_pool *pool);
7497ec681f3Smrgstruct anv_state anv_state_reserved_pool_alloc(struct anv_state_reserved_pool *pool);
7507ec681f3Smrgvoid anv_state_reserved_pool_free(struct anv_state_reserved_pool *pool,
7517ec681f3Smrg                                  struct anv_state state);
7527ec681f3Smrg
7539f464c52SmayaVkResult anv_state_table_init(struct anv_state_table *table,
7549f464c52Smaya                             struct anv_device *device,
7559f464c52Smaya                             uint32_t initial_entries);
7569f464c52Smayavoid anv_state_table_finish(struct anv_state_table *table);
7579f464c52SmayaVkResult anv_state_table_add(struct anv_state_table *table, uint32_t *idx,
7589f464c52Smaya                             uint32_t count);
7599f464c52Smayavoid anv_free_list_push(union anv_free_list *list,
7609f464c52Smaya                        struct anv_state_table *table,
7619f464c52Smaya                        uint32_t idx, uint32_t count);
7629f464c52Smayastruct anv_state* anv_free_list_pop(union anv_free_list *list,
7639f464c52Smaya                                    struct anv_state_table *table);
7649f464c52Smaya
7659f464c52Smaya
7669f464c52Smayastatic inline struct anv_state *
7679f464c52Smayaanv_state_table_get(struct anv_state_table *table, uint32_t idx)
7689f464c52Smaya{
7699f464c52Smaya   return &table->map[idx].state;
7709f464c52Smaya}
77101e04c3fSmrg/**
77201e04c3fSmrg * Implements a pool of re-usable BOs.  The interface is identical to that
77301e04c3fSmrg * of block_pool except that each block is its own BO.
77401e04c3fSmrg */
77501e04c3fSmrgstruct anv_bo_pool {
7767ec681f3Smrg   const char *name;
77701e04c3fSmrg
7787ec681f3Smrg   struct anv_device *device;
77901e04c3fSmrg
7807ec681f3Smrg   struct util_sparse_array_free_list free_list[16];
78101e04c3fSmrg};
78201e04c3fSmrg
78301e04c3fSmrgvoid anv_bo_pool_init(struct anv_bo_pool *pool, struct anv_device *device,
7847ec681f3Smrg                      const char *name);
78501e04c3fSmrgvoid anv_bo_pool_finish(struct anv_bo_pool *pool);
7867ec681f3SmrgVkResult anv_bo_pool_alloc(struct anv_bo_pool *pool, uint32_t size,
7877ec681f3Smrg                           struct anv_bo **bo_out);
7887ec681f3Smrgvoid anv_bo_pool_free(struct anv_bo_pool *pool, struct anv_bo *bo);
78901e04c3fSmrg
79001e04c3fSmrgstruct anv_scratch_pool {
79101e04c3fSmrg   /* Indexed by Per-Thread Scratch Space number (the hardware value) and stage */
7927ec681f3Smrg   struct anv_bo *bos[16][MESA_SHADER_STAGES];
7937ec681f3Smrg   uint32_t surfs[16];
7947ec681f3Smrg   struct anv_state surf_states[16];
79501e04c3fSmrg};
79601e04c3fSmrg
79701e04c3fSmrgvoid anv_scratch_pool_init(struct anv_device *device,
79801e04c3fSmrg                           struct anv_scratch_pool *pool);
79901e04c3fSmrgvoid anv_scratch_pool_finish(struct anv_device *device,
80001e04c3fSmrg                             struct anv_scratch_pool *pool);
80101e04c3fSmrgstruct anv_bo *anv_scratch_pool_alloc(struct anv_device *device,
80201e04c3fSmrg                                      struct anv_scratch_pool *pool,
80301e04c3fSmrg                                      gl_shader_stage stage,
80401e04c3fSmrg                                      unsigned per_thread_scratch);
8057ec681f3Smrguint32_t anv_scratch_pool_get_surf(struct anv_device *device,
8067ec681f3Smrg                                   struct anv_scratch_pool *pool,
8077ec681f3Smrg                                   unsigned per_thread_scratch);
80801e04c3fSmrg
80901e04c3fSmrg/** Implements a BO cache that ensures a 1-1 mapping of GEM BOs to anv_bos */
81001e04c3fSmrgstruct anv_bo_cache {
8117ec681f3Smrg   struct util_sparse_array bo_map;
81201e04c3fSmrg   pthread_mutex_t mutex;
81301e04c3fSmrg};
81401e04c3fSmrg
8157ec681f3SmrgVkResult anv_bo_cache_init(struct anv_bo_cache *cache,
8167ec681f3Smrg                           struct anv_device *device);
81701e04c3fSmrgvoid anv_bo_cache_finish(struct anv_bo_cache *cache);
8187ec681f3Smrg
8197ec681f3Smrgstruct anv_queue_family {
8207ec681f3Smrg   /* Standard bits passed on to the client */
8217ec681f3Smrg   VkQueueFlags   queueFlags;
8227ec681f3Smrg   uint32_t       queueCount;
8237ec681f3Smrg
8247ec681f3Smrg   /* Driver internal information */
8257ec681f3Smrg   enum drm_i915_gem_engine_class engine_class;
8267ec681f3Smrg};
8277ec681f3Smrg
8287ec681f3Smrg#define ANV_MAX_QUEUE_FAMILIES 3
82901e04c3fSmrg
83001e04c3fSmrgstruct anv_memory_type {
83101e04c3fSmrg   /* Standard bits passed on to the client */
83201e04c3fSmrg   VkMemoryPropertyFlags   propertyFlags;
83301e04c3fSmrg   uint32_t                heapIndex;
83401e04c3fSmrg};
83501e04c3fSmrg
83601e04c3fSmrgstruct anv_memory_heap {
83701e04c3fSmrg   /* Standard bits passed on to the client */
83801e04c3fSmrg   VkDeviceSize      size;
83901e04c3fSmrg   VkMemoryHeapFlags flags;
84001e04c3fSmrg
8417ec681f3Smrg   /** Driver-internal book-keeping.
8427ec681f3Smrg    *
8437ec681f3Smrg    * Align it to 64 bits to make atomic operations faster on 32 bit platforms.
8447ec681f3Smrg    */
8457ec681f3Smrg   VkDeviceSize      used __attribute__ ((aligned (8)));
8467ec681f3Smrg
8477ec681f3Smrg   bool              is_local_mem;
8487ec681f3Smrg};
8497ec681f3Smrg
8507ec681f3Smrgstruct anv_memregion {
8517ec681f3Smrg   struct drm_i915_gem_memory_class_instance region;
8527ec681f3Smrg   uint64_t size;
8537ec681f3Smrg   uint64_t available;
85401e04c3fSmrg};
85501e04c3fSmrg
85601e04c3fSmrgstruct anv_physical_device {
8577ec681f3Smrg    struct vk_physical_device                   vk;
8587ec681f3Smrg
8597ec681f3Smrg    /* Link in anv_instance::physical_devices */
8607ec681f3Smrg    struct list_head                            link;
86101e04c3fSmrg
86201e04c3fSmrg    struct anv_instance *                       instance;
86301e04c3fSmrg    char                                        path[20];
86401e04c3fSmrg    struct {
86501e04c3fSmrg       uint16_t                                 domain;
86601e04c3fSmrg       uint8_t                                  bus;
86701e04c3fSmrg       uint8_t                                  device;
86801e04c3fSmrg       uint8_t                                  function;
86901e04c3fSmrg    }                                           pci_info;
8707ec681f3Smrg    struct intel_device_info                      info;
87101e04c3fSmrg    /** Amount of "GPU memory" we want to advertise
87201e04c3fSmrg     *
87301e04c3fSmrg     * Clearly, this value is bogus since Intel is a UMA architecture.  On
8747ec681f3Smrg     * gfx7 platforms, we are limited by GTT size unless we want to implement
87501e04c3fSmrg     * fine-grained tracking and GTT splitting.  On Broadwell and above we are
87601e04c3fSmrg     * practically unlimited.  However, we will never report more than 3/4 of
87701e04c3fSmrg     * the total system ram to try and avoid running out of RAM.
87801e04c3fSmrg     */
87901e04c3fSmrg    bool                                        supports_48bit_addresses;
88001e04c3fSmrg    struct brw_compiler *                       compiler;
88101e04c3fSmrg    struct isl_device                           isl_dev;
8827ec681f3Smrg    struct intel_perf_config *                    perf;
8837ec681f3Smrg   /* True if hardware support is incomplete/alpha */
8847ec681f3Smrg    bool                                        is_alpha;
8857ec681f3Smrg    /*
8867ec681f3Smrg     * Number of commands required to implement a performance query begin +
8877ec681f3Smrg     * end.
8887ec681f3Smrg     */
8897ec681f3Smrg    uint32_t                                    n_perf_query_commands;
89001e04c3fSmrg    int                                         cmd_parser_version;
89101e04c3fSmrg    bool                                        has_exec_async;
89201e04c3fSmrg    bool                                        has_exec_capture;
89301e04c3fSmrg    bool                                        has_exec_fence;
89401e04c3fSmrg    bool                                        has_syncobj_wait;
8957ec681f3Smrg    bool                                        has_syncobj_wait_available;
89601e04c3fSmrg    bool                                        has_context_priority;
89701e04c3fSmrg    bool                                        has_context_isolation;
8987ec681f3Smrg    bool                                        has_thread_submit;
8997ec681f3Smrg    bool                                        has_mmap_offset;
9007ec681f3Smrg    bool                                        has_userptr_probe;
9017ec681f3Smrg    uint64_t                                    gtt_size;
9027ec681f3Smrg
9037ec681f3Smrg    bool                                        use_softpin;
9049f464c52Smaya    bool                                        always_use_bindless;
9057ec681f3Smrg    bool                                        use_call_secondary;
9069f464c52Smaya
9079f464c52Smaya    /** True if we can access buffers using A64 messages */
9089f464c52Smaya    bool                                        has_a64_buffer_access;
9099f464c52Smaya    /** True if we can use bindless access for images */
9109f464c52Smaya    bool                                        has_bindless_images;
9119f464c52Smaya    /** True if we can use bindless access for samplers */
9129f464c52Smaya    bool                                        has_bindless_samplers;
9137ec681f3Smrg    /** True if we can use timeline semaphores through execbuf */
9147ec681f3Smrg    bool                                        has_exec_timeline;
9157ec681f3Smrg
9167ec681f3Smrg    /** True if we can read the GPU timestamp register
9177ec681f3Smrg     *
9187ec681f3Smrg     * When running in a virtual context, the timestamp register is unreadable
9197ec681f3Smrg     * on Gfx12+.
9207ec681f3Smrg     */
9217ec681f3Smrg    bool                                        has_reg_timestamp;
9227ec681f3Smrg
9237ec681f3Smrg    /** True if this device has implicit AUX
9247ec681f3Smrg     *
9257ec681f3Smrg     * If true, CCS is handled as an implicit attachment to the BO rather than
9267ec681f3Smrg     * as an explicitly bound surface.
9277ec681f3Smrg     */
9287ec681f3Smrg    bool                                        has_implicit_ccs;
92901e04c3fSmrg
9307ec681f3Smrg    bool                                        always_flush_cache;
93101e04c3fSmrg
9327ec681f3Smrg    struct {
9337ec681f3Smrg      uint32_t                                  family_count;
9347ec681f3Smrg      struct anv_queue_family                   families[ANV_MAX_QUEUE_FAMILIES];
9357ec681f3Smrg    } queue;
93601e04c3fSmrg
93701e04c3fSmrg    struct {
93801e04c3fSmrg      uint32_t                                  type_count;
93901e04c3fSmrg      struct anv_memory_type                    types[VK_MAX_MEMORY_TYPES];
94001e04c3fSmrg      uint32_t                                  heap_count;
94101e04c3fSmrg      struct anv_memory_heap                    heaps[VK_MAX_MEMORY_HEAPS];
9427ec681f3Smrg      bool                                      need_clflush;
94301e04c3fSmrg    } memory;
94401e04c3fSmrg
9457ec681f3Smrg    struct anv_memregion                        vram;
9467ec681f3Smrg    struct anv_memregion                        sys;
94701e04c3fSmrg    uint8_t                                     driver_build_sha1[20];
94801e04c3fSmrg    uint8_t                                     pipeline_cache_uuid[VK_UUID_SIZE];
94901e04c3fSmrg    uint8_t                                     driver_uuid[VK_UUID_SIZE];
95001e04c3fSmrg    uint8_t                                     device_uuid[VK_UUID_SIZE];
95101e04c3fSmrg
95201e04c3fSmrg    struct disk_cache *                         disk_cache;
95301e04c3fSmrg
95401e04c3fSmrg    struct wsi_device                       wsi_device;
95501e04c3fSmrg    int                                         local_fd;
9567ec681f3Smrg    bool                                        has_local;
9577ec681f3Smrg    int64_t                                     local_major;
9587ec681f3Smrg    int64_t                                     local_minor;
95901e04c3fSmrg    int                                         master_fd;
9607ec681f3Smrg    bool                                        has_master;
9617ec681f3Smrg    int64_t                                     master_major;
9627ec681f3Smrg    int64_t                                     master_minor;
9637ec681f3Smrg    struct drm_i915_query_engine_info *         engine_info;
9647ec681f3Smrg
9657ec681f3Smrg    void (*cmd_emit_timestamp)(struct anv_batch *, struct anv_bo *, uint32_t );
9667ec681f3Smrg    struct intel_measure_device                 measure_device;
96701e04c3fSmrg};
96801e04c3fSmrg
96901e04c3fSmrgstruct anv_app_info {
97001e04c3fSmrg   const char*        app_name;
97101e04c3fSmrg   uint32_t           app_version;
97201e04c3fSmrg   const char*        engine_name;
97301e04c3fSmrg   uint32_t           engine_version;
97401e04c3fSmrg   uint32_t           api_version;
97501e04c3fSmrg};
97601e04c3fSmrg
97701e04c3fSmrgstruct anv_instance {
9787ec681f3Smrg    struct vk_instance                          vk;
97901e04c3fSmrg
9807ec681f3Smrg    bool                                        physical_devices_enumerated;
9817ec681f3Smrg    struct list_head                            physical_devices;
98201e04c3fSmrg
98301e04c3fSmrg    bool                                        pipeline_cache_enabled;
98401e04c3fSmrg
9859f464c52Smaya    struct driOptionCache                       dri_options;
9869f464c52Smaya    struct driOptionCache                       available_dri_options;
98701e04c3fSmrg};
98801e04c3fSmrg
98901e04c3fSmrgVkResult anv_init_wsi(struct anv_physical_device *physical_device);
99001e04c3fSmrgvoid anv_finish_wsi(struct anv_physical_device *physical_device);
99101e04c3fSmrg
9927ec681f3Smrgstruct anv_queue_submit {
9937ec681f3Smrg   struct anv_cmd_buffer **                  cmd_buffers;
9947ec681f3Smrg   uint32_t                                  cmd_buffer_count;
9957ec681f3Smrg   uint32_t                                  cmd_buffer_array_length;
9967ec681f3Smrg
9977ec681f3Smrg   uint32_t                                  fence_count;
9987ec681f3Smrg   uint32_t                                  fence_array_length;
9997ec681f3Smrg   struct drm_i915_gem_exec_fence *          fences;
10007ec681f3Smrg   uint64_t *                                fence_values;
10017ec681f3Smrg
10027ec681f3Smrg   uint32_t                                  temporary_semaphore_count;
10037ec681f3Smrg   uint32_t                                  temporary_semaphore_array_length;
10047ec681f3Smrg   struct anv_semaphore_impl *               temporary_semaphores;
10057ec681f3Smrg
10067ec681f3Smrg   /* Allocated only with non shareable timelines. */
10077ec681f3Smrg   union {
10087ec681f3Smrg      struct anv_timeline **                 wait_timelines;
10097ec681f3Smrg      uint32_t *                             wait_timeline_syncobjs;
10107ec681f3Smrg   };
10117ec681f3Smrg   uint32_t                                  wait_timeline_count;
10127ec681f3Smrg   uint32_t                                  wait_timeline_array_length;
10137ec681f3Smrg   uint64_t *                                wait_timeline_values;
10147ec681f3Smrg
10157ec681f3Smrg   struct anv_timeline **                    signal_timelines;
10167ec681f3Smrg   uint32_t                                  signal_timeline_count;
10177ec681f3Smrg   uint32_t                                  signal_timeline_array_length;
10187ec681f3Smrg   uint64_t *                                signal_timeline_values;
10197ec681f3Smrg
10207ec681f3Smrg   int                                       in_fence;
10217ec681f3Smrg   bool                                      need_out_fence;
10227ec681f3Smrg   int                                       out_fence;
10237ec681f3Smrg
10247ec681f3Smrg   uint32_t                                  fence_bo_count;
10257ec681f3Smrg   uint32_t                                  fence_bo_array_length;
10267ec681f3Smrg   /* An array of struct anv_bo pointers with lower bit used as a flag to
10277ec681f3Smrg    * signal we will wait on that BO (see anv_(un)pack_ptr).
10287ec681f3Smrg    */
10297ec681f3Smrg   uintptr_t *                               fence_bos;
10307ec681f3Smrg
10317ec681f3Smrg   int                                       perf_query_pass;
10327ec681f3Smrg   struct anv_query_pool *                   perf_query_pool;
10337ec681f3Smrg
10347ec681f3Smrg   const VkAllocationCallbacks *             alloc;
10357ec681f3Smrg   VkSystemAllocationScope                   alloc_scope;
10367ec681f3Smrg
10377ec681f3Smrg   struct anv_bo *                           simple_bo;
10387ec681f3Smrg   uint32_t                                  simple_bo_size;
10397ec681f3Smrg
10407ec681f3Smrg   struct list_head                          link;
10417ec681f3Smrg};
104201e04c3fSmrg
104301e04c3fSmrgstruct anv_queue {
10447ec681f3Smrg   struct vk_queue                           vk;
10457ec681f3Smrg
10467ec681f3Smrg   struct anv_device *                       device;
10477ec681f3Smrg
10487ec681f3Smrg   const struct anv_queue_family *           family;
10497ec681f3Smrg
10507ec681f3Smrg   uint32_t                                  exec_flags;
105101e04c3fSmrg
10527ec681f3Smrg   /* Set once from the device api calls. */
10537ec681f3Smrg   bool                                      lost_signaled;
105401e04c3fSmrg
10557ec681f3Smrg   /* Only set once atomically by the queue */
10567ec681f3Smrg   int                                       lost;
10577ec681f3Smrg   int                                       error_line;
10587ec681f3Smrg   const char *                              error_file;
10597ec681f3Smrg   char                                      error_msg[80];
10607ec681f3Smrg
10617ec681f3Smrg   /*
10627ec681f3Smrg    * This mutext protects the variables below.
10637ec681f3Smrg    */
10647ec681f3Smrg   pthread_mutex_t                           mutex;
10657ec681f3Smrg
10667ec681f3Smrg   pthread_t                                 thread;
10677ec681f3Smrg   pthread_cond_t                            cond;
10687ec681f3Smrg
10697ec681f3Smrg   /*
10707ec681f3Smrg    * A list of struct anv_queue_submit to be submitted to i915.
10717ec681f3Smrg    */
10727ec681f3Smrg   struct list_head                          queued_submits;
10737ec681f3Smrg
10747ec681f3Smrg   /* Set to true to stop the submission thread */
10757ec681f3Smrg   bool                                      quit;
107601e04c3fSmrg};
107701e04c3fSmrg
107801e04c3fSmrgstruct anv_pipeline_cache {
10797ec681f3Smrg   struct vk_object_base                        base;
108001e04c3fSmrg   struct anv_device *                          device;
108101e04c3fSmrg   pthread_mutex_t                              mutex;
108201e04c3fSmrg
10839f464c52Smaya   struct hash_table *                          nir_cache;
10849f464c52Smaya
108501e04c3fSmrg   struct hash_table *                          cache;
10867ec681f3Smrg
10877ec681f3Smrg   bool                                         external_sync;
108801e04c3fSmrg};
108901e04c3fSmrg
10909f464c52Smayastruct nir_xfb_info;
109101e04c3fSmrgstruct anv_pipeline_bind_map;
109201e04c3fSmrg
109301e04c3fSmrgvoid anv_pipeline_cache_init(struct anv_pipeline_cache *cache,
109401e04c3fSmrg                             struct anv_device *device,
10957ec681f3Smrg                             bool cache_enabled,
10967ec681f3Smrg                             bool external_sync);
109701e04c3fSmrgvoid anv_pipeline_cache_finish(struct anv_pipeline_cache *cache);
109801e04c3fSmrg
109901e04c3fSmrgstruct anv_shader_bin *
110001e04c3fSmrganv_pipeline_cache_search(struct anv_pipeline_cache *cache,
110101e04c3fSmrg                          const void *key, uint32_t key_size);
110201e04c3fSmrgstruct anv_shader_bin *
110301e04c3fSmrganv_pipeline_cache_upload_kernel(struct anv_pipeline_cache *cache,
11047ec681f3Smrg                                 gl_shader_stage stage,
110501e04c3fSmrg                                 const void *key_data, uint32_t key_size,
110601e04c3fSmrg                                 const void *kernel_data, uint32_t kernel_size,
110701e04c3fSmrg                                 const struct brw_stage_prog_data *prog_data,
110801e04c3fSmrg                                 uint32_t prog_data_size,
11097ec681f3Smrg                                 const struct brw_compile_stats *stats,
11107ec681f3Smrg                                 uint32_t num_stats,
11119f464c52Smaya                                 const struct nir_xfb_info *xfb_info,
111201e04c3fSmrg                                 const struct anv_pipeline_bind_map *bind_map);
111301e04c3fSmrg
111401e04c3fSmrgstruct anv_shader_bin *
111501e04c3fSmrganv_device_search_for_kernel(struct anv_device *device,
111601e04c3fSmrg                             struct anv_pipeline_cache *cache,
11179f464c52Smaya                             const void *key_data, uint32_t key_size,
11189f464c52Smaya                             bool *user_cache_bit);
111901e04c3fSmrg
112001e04c3fSmrgstruct anv_shader_bin *
112101e04c3fSmrganv_device_upload_kernel(struct anv_device *device,
112201e04c3fSmrg                         struct anv_pipeline_cache *cache,
11237ec681f3Smrg                         gl_shader_stage stage,
112401e04c3fSmrg                         const void *key_data, uint32_t key_size,
112501e04c3fSmrg                         const void *kernel_data, uint32_t kernel_size,
112601e04c3fSmrg                         const struct brw_stage_prog_data *prog_data,
112701e04c3fSmrg                         uint32_t prog_data_size,
11287ec681f3Smrg                         const struct brw_compile_stats *stats,
11297ec681f3Smrg                         uint32_t num_stats,
11309f464c52Smaya                         const struct nir_xfb_info *xfb_info,
113101e04c3fSmrg                         const struct anv_pipeline_bind_map *bind_map);
113201e04c3fSmrg
11339f464c52Smayastruct nir_shader;
11349f464c52Smayastruct nir_shader_compiler_options;
11359f464c52Smaya
11369f464c52Smayastruct nir_shader *
11379f464c52Smayaanv_device_search_for_nir(struct anv_device *device,
11389f464c52Smaya                          struct anv_pipeline_cache *cache,
11399f464c52Smaya                          const struct nir_shader_compiler_options *nir_options,
11409f464c52Smaya                          unsigned char sha1_key[20],
11419f464c52Smaya                          void *mem_ctx);
11429f464c52Smaya
11439f464c52Smayavoid
11449f464c52Smayaanv_device_upload_nir(struct anv_device *device,
11459f464c52Smaya                      struct anv_pipeline_cache *cache,
11469f464c52Smaya                      const struct nir_shader *nir,
11479f464c52Smaya                      unsigned char sha1_key[20]);
11489f464c52Smaya
11497ec681f3Smrgstruct anv_address {
11507ec681f3Smrg   struct anv_bo *bo;
11517ec681f3Smrg   int64_t offset;
11527ec681f3Smrg};
115301e04c3fSmrg
11547ec681f3Smrgstruct anv_device {
11557ec681f3Smrg    struct vk_device                            vk;
115601e04c3fSmrg
11577ec681f3Smrg    struct anv_physical_device *                physical;
11587ec681f3Smrg    struct intel_device_info                      info;
115901e04c3fSmrg    struct isl_device                           isl_dev;
116001e04c3fSmrg    int                                         context_id;
116101e04c3fSmrg    int                                         fd;
116201e04c3fSmrg    bool                                        can_chain_batches;
116301e04c3fSmrg    bool                                        robust_buffer_access;
11647ec681f3Smrg    bool                                        has_thread_submit;
116501e04c3fSmrg
116601e04c3fSmrg    pthread_mutex_t                             vma_mutex;
116701e04c3fSmrg    struct util_vma_heap                        vma_lo;
11687ec681f3Smrg    struct util_vma_heap                        vma_cva;
116901e04c3fSmrg    struct util_vma_heap                        vma_hi;
117001e04c3fSmrg
11719f464c52Smaya    /** List of all anv_device_memory objects */
11729f464c52Smaya    struct list_head                            memory_objects;
11739f464c52Smaya
117401e04c3fSmrg    struct anv_bo_pool                          batch_bo_pool;
117501e04c3fSmrg
117601e04c3fSmrg    struct anv_bo_cache                         bo_cache;
117701e04c3fSmrg
11787ec681f3Smrg    struct anv_state_pool                       general_state_pool;
117901e04c3fSmrg    struct anv_state_pool                       dynamic_state_pool;
118001e04c3fSmrg    struct anv_state_pool                       instruction_state_pool;
118101e04c3fSmrg    struct anv_state_pool                       binding_table_pool;
118201e04c3fSmrg    struct anv_state_pool                       surface_state_pool;
118301e04c3fSmrg
11847ec681f3Smrg    struct anv_state_reserved_pool              custom_border_colors;
11857ec681f3Smrg
11867ec681f3Smrg    /** BO used for various workarounds
11877ec681f3Smrg     *
11887ec681f3Smrg     * There are a number of workarounds on our hardware which require writing
11897ec681f3Smrg     * data somewhere and it doesn't really matter where.  For that, we use
11907ec681f3Smrg     * this BO and just write to the first dword or so.
11917ec681f3Smrg     *
11927ec681f3Smrg     * We also need to be able to handle NULL buffers bound as pushed UBOs.
11937ec681f3Smrg     * For that, we use the high bytes (>= 1024) of the workaround BO.
11947ec681f3Smrg     */
11957ec681f3Smrg    struct anv_bo *                             workaround_bo;
11967ec681f3Smrg    struct anv_address                          workaround_address;
11977ec681f3Smrg
11987ec681f3Smrg    struct anv_bo *                             trivial_batch_bo;
11997ec681f3Smrg    struct anv_state                            null_surface_state;
120001e04c3fSmrg
120101e04c3fSmrg    struct anv_pipeline_cache                   default_pipeline_cache;
120201e04c3fSmrg    struct blorp_context                        blorp;
120301e04c3fSmrg
120401e04c3fSmrg    struct anv_state                            border_colors;
120501e04c3fSmrg
12067ec681f3Smrg    struct anv_state                            slice_hash;
12077ec681f3Smrg
12087ec681f3Smrg    uint32_t                                    queue_count;
12097ec681f3Smrg    struct anv_queue  *                         queues;
121001e04c3fSmrg
121101e04c3fSmrg    struct anv_scratch_pool                     scratch_pool;
12127ec681f3Smrg    struct anv_bo                              *rt_scratch_bos[16];
121301e04c3fSmrg
12147ec681f3Smrg    struct anv_shader_bin                      *rt_trampoline;
12157ec681f3Smrg    struct anv_shader_bin                      *rt_trivial_return;
121601e04c3fSmrg
121701e04c3fSmrg    pthread_mutex_t                             mutex;
121801e04c3fSmrg    pthread_cond_t                              queue_submit;
12197ec681f3Smrg    int                                         _lost;
12207ec681f3Smrg    int                                         lost_reported;
12219f464c52Smaya
12227ec681f3Smrg    struct intel_batch_decode_ctx               decoder_ctx;
12239f464c52Smaya    /*
12249f464c52Smaya     * When decoding a anv_cmd_buffer, we might need to search for BOs through
12259f464c52Smaya     * the cmd_buffer's list.
12269f464c52Smaya     */
12279f464c52Smaya    struct anv_cmd_buffer                      *cmd_buffer_being_decoded;
12287ec681f3Smrg
12297ec681f3Smrg    int                                         perf_fd; /* -1 if no opened */
12307ec681f3Smrg    uint64_t                                    perf_metric; /* 0 if unset */
12317ec681f3Smrg
12327ec681f3Smrg    struct intel_aux_map_context                *aux_map_ctx;
12337ec681f3Smrg
12347ec681f3Smrg    const struct intel_l3_config                *l3_config;
12357ec681f3Smrg
12367ec681f3Smrg    struct intel_debug_block_frame              *debug_frame_desc;
123701e04c3fSmrg};
123801e04c3fSmrg
12397ec681f3Smrg#if defined(GFX_VERx10) && GFX_VERx10 >= 90
12407ec681f3Smrg#define ANV_ALWAYS_SOFTPIN true
12417ec681f3Smrg#else
12427ec681f3Smrg#define ANV_ALWAYS_SOFTPIN false
12437ec681f3Smrg#endif
12447ec681f3Smrg
12457ec681f3Smrgstatic inline bool
12467ec681f3Smrganv_use_softpin(const struct anv_physical_device *pdevice)
12477ec681f3Smrg{
12487ec681f3Smrg#if defined(GFX_VERx10) && GFX_VERx10 >= 90
12497ec681f3Smrg   /* Sky Lake and later always uses softpin */
12507ec681f3Smrg   assert(pdevice->use_softpin);
12517ec681f3Smrg   return true;
12527ec681f3Smrg#elif defined(GFX_VERx10) && GFX_VERx10 < 80
12537ec681f3Smrg   /* Haswell and earlier never use softpin */
12547ec681f3Smrg   assert(!pdevice->use_softpin);
12557ec681f3Smrg   return false;
12567ec681f3Smrg#else
12577ec681f3Smrg   /* If we don't have a GFX_VERx10 #define, we need to look at the physical
12587ec681f3Smrg    * device.  Also, for GFX version 8, we need to look at the physical
12597ec681f3Smrg    * device because Broadwell softpins but Cherryview doesn't.
12607ec681f3Smrg    */
12617ec681f3Smrg   return pdevice->use_softpin;
12627ec681f3Smrg#endif
12637ec681f3Smrg}
12647ec681f3Smrg
126501e04c3fSmrgstatic inline struct anv_state_pool *
126601e04c3fSmrganv_binding_table_pool(struct anv_device *device)
126701e04c3fSmrg{
12687ec681f3Smrg   if (anv_use_softpin(device->physical))
126901e04c3fSmrg      return &device->binding_table_pool;
127001e04c3fSmrg   else
127101e04c3fSmrg      return &device->surface_state_pool;
127201e04c3fSmrg}
127301e04c3fSmrg
127401e04c3fSmrgstatic inline struct anv_state
12757ec681f3Smrganv_binding_table_pool_alloc(struct anv_device *device)
12767ec681f3Smrg{
12777ec681f3Smrg   if (anv_use_softpin(device->physical))
127801e04c3fSmrg      return anv_state_pool_alloc(&device->binding_table_pool,
127901e04c3fSmrg                                  device->binding_table_pool.block_size, 0);
128001e04c3fSmrg   else
128101e04c3fSmrg      return anv_state_pool_alloc_back(&device->surface_state_pool);
128201e04c3fSmrg}
128301e04c3fSmrg
128401e04c3fSmrgstatic inline void
128501e04c3fSmrganv_binding_table_pool_free(struct anv_device *device, struct anv_state state) {
128601e04c3fSmrg   anv_state_pool_free(anv_binding_table_pool(device), state);
128701e04c3fSmrg}
128801e04c3fSmrg
128901e04c3fSmrgstatic inline uint32_t
12907ec681f3Smrganv_mocs(const struct anv_device *device,
12917ec681f3Smrg         const struct anv_bo *bo,
12927ec681f3Smrg         isl_surf_usage_flags_t usage)
129301e04c3fSmrg{
12947ec681f3Smrg   return isl_mocs(&device->isl_dev, usage, bo && bo->is_external);
129501e04c3fSmrg}
129601e04c3fSmrg
129701e04c3fSmrgvoid anv_device_init_blorp(struct anv_device *device);
129801e04c3fSmrgvoid anv_device_finish_blorp(struct anv_device *device);
129901e04c3fSmrg
13007ec681f3Smrgvoid _anv_device_report_lost(struct anv_device *device);
130101e04c3fSmrgVkResult _anv_device_set_lost(struct anv_device *device,
130201e04c3fSmrg                              const char *file, int line,
13037ec681f3Smrg                              const char *msg, ...)
13047ec681f3Smrg   anv_printflike(4, 5);
13057ec681f3SmrgVkResult _anv_queue_set_lost(struct anv_queue *queue,
13067ec681f3Smrg                              const char *file, int line,
13077ec681f3Smrg                              const char *msg, ...)
13087ec681f3Smrg   anv_printflike(4, 5);
130901e04c3fSmrg#define anv_device_set_lost(dev, ...) \
131001e04c3fSmrg   _anv_device_set_lost(dev, __FILE__, __LINE__, __VA_ARGS__)
13117ec681f3Smrg#define anv_queue_set_lost(queue, ...) \
13127ec681f3Smrg   (queue)->device->has_thread_submit ? \
13137ec681f3Smrg   _anv_queue_set_lost(queue, __FILE__, __LINE__, __VA_ARGS__) : \
13147ec681f3Smrg   _anv_device_set_lost(queue->device, __FILE__, __LINE__, __VA_ARGS__)
131501e04c3fSmrg
131601e04c3fSmrgstatic inline bool
131701e04c3fSmrganv_device_is_lost(struct anv_device *device)
131801e04c3fSmrg{
13197ec681f3Smrg   int lost = p_atomic_read(&device->_lost);
13207ec681f3Smrg   if (unlikely(lost && !device->lost_reported))
13217ec681f3Smrg      _anv_device_report_lost(device);
13227ec681f3Smrg   return lost;
132301e04c3fSmrg}
132401e04c3fSmrg
132501e04c3fSmrgVkResult anv_device_query_status(struct anv_device *device);
13267ec681f3Smrg
13277ec681f3Smrg
13287ec681f3Smrgenum anv_bo_alloc_flags {
13297ec681f3Smrg   /** Specifies that the BO must have a 32-bit address
13307ec681f3Smrg    *
13317ec681f3Smrg    * This is the opposite of EXEC_OBJECT_SUPPORTS_48B_ADDRESS.
13327ec681f3Smrg    */
13337ec681f3Smrg   ANV_BO_ALLOC_32BIT_ADDRESS =  (1 << 0),
13347ec681f3Smrg
13357ec681f3Smrg   /** Specifies that the BO may be shared externally */
13367ec681f3Smrg   ANV_BO_ALLOC_EXTERNAL =       (1 << 1),
13377ec681f3Smrg
13387ec681f3Smrg   /** Specifies that the BO should be mapped */
13397ec681f3Smrg   ANV_BO_ALLOC_MAPPED =         (1 << 2),
13407ec681f3Smrg
13417ec681f3Smrg   /** Specifies that the BO should be snooped so we get coherency */
13427ec681f3Smrg   ANV_BO_ALLOC_SNOOPED =        (1 << 3),
13437ec681f3Smrg
13447ec681f3Smrg   /** Specifies that the BO should be captured in error states */
13457ec681f3Smrg   ANV_BO_ALLOC_CAPTURE =        (1 << 4),
13467ec681f3Smrg
13477ec681f3Smrg   /** Specifies that the BO will have an address assigned by the caller
13487ec681f3Smrg    *
13497ec681f3Smrg    * Such BOs do not exist in any VMA heap.
13507ec681f3Smrg    */
13517ec681f3Smrg   ANV_BO_ALLOC_FIXED_ADDRESS = (1 << 5),
13527ec681f3Smrg
13537ec681f3Smrg   /** Enables implicit synchronization on the BO
13547ec681f3Smrg    *
13557ec681f3Smrg    * This is the opposite of EXEC_OBJECT_ASYNC.
13567ec681f3Smrg    */
13577ec681f3Smrg   ANV_BO_ALLOC_IMPLICIT_SYNC =  (1 << 6),
13587ec681f3Smrg
13597ec681f3Smrg   /** Enables implicit synchronization on the BO
13607ec681f3Smrg    *
13617ec681f3Smrg    * This is equivalent to EXEC_OBJECT_WRITE.
13627ec681f3Smrg    */
13637ec681f3Smrg   ANV_BO_ALLOC_IMPLICIT_WRITE = (1 << 7),
13647ec681f3Smrg
13657ec681f3Smrg   /** Has an address which is visible to the client */
13667ec681f3Smrg   ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS = (1 << 8),
13677ec681f3Smrg
13687ec681f3Smrg   /** This buffer has implicit CCS data attached to it */
13697ec681f3Smrg   ANV_BO_ALLOC_IMPLICIT_CCS = (1 << 9),
13707ec681f3Smrg
13717ec681f3Smrg   /** This buffer is allocated from local memory */
13727ec681f3Smrg   ANV_BO_ALLOC_LOCAL_MEM = (1 << 10),
13737ec681f3Smrg};
13747ec681f3Smrg
13757ec681f3SmrgVkResult anv_device_alloc_bo(struct anv_device *device,
13767ec681f3Smrg                             const char *name, uint64_t size,
13777ec681f3Smrg                             enum anv_bo_alloc_flags alloc_flags,
13787ec681f3Smrg                             uint64_t explicit_address,
13797ec681f3Smrg                             struct anv_bo **bo);
13807ec681f3SmrgVkResult anv_device_import_bo_from_host_ptr(struct anv_device *device,
13817ec681f3Smrg                                            void *host_ptr, uint32_t size,
13827ec681f3Smrg                                            enum anv_bo_alloc_flags alloc_flags,
13837ec681f3Smrg                                            uint64_t client_address,
13847ec681f3Smrg                                            struct anv_bo **bo_out);
13857ec681f3SmrgVkResult anv_device_import_bo(struct anv_device *device, int fd,
13867ec681f3Smrg                              enum anv_bo_alloc_flags alloc_flags,
13877ec681f3Smrg                              uint64_t client_address,
13887ec681f3Smrg                              struct anv_bo **bo);
13897ec681f3SmrgVkResult anv_device_export_bo(struct anv_device *device,
13907ec681f3Smrg                              struct anv_bo *bo, int *fd_out);
13917ec681f3Smrgvoid anv_device_release_bo(struct anv_device *device,
13927ec681f3Smrg                           struct anv_bo *bo);
13937ec681f3Smrg
13947ec681f3Smrgstatic inline struct anv_bo *
13957ec681f3Smrganv_device_lookup_bo(struct anv_device *device, uint32_t gem_handle)
13967ec681f3Smrg{
13977ec681f3Smrg   return util_sparse_array_get(&device->bo_cache.bo_map, gem_handle);
13987ec681f3Smrg}
13997ec681f3Smrg
140001e04c3fSmrgVkResult anv_device_bo_busy(struct anv_device *device, struct anv_bo *bo);
140101e04c3fSmrgVkResult anv_device_wait(struct anv_device *device, struct anv_bo *bo,
140201e04c3fSmrg                         int64_t timeout);
140301e04c3fSmrg
14047ec681f3SmrgVkResult anv_queue_init(struct anv_device *device, struct anv_queue *queue,
14057ec681f3Smrg                        uint32_t exec_flags,
14067ec681f3Smrg                        const VkDeviceQueueCreateInfo *pCreateInfo,
14077ec681f3Smrg                        uint32_t index_in_family);
14087ec681f3Smrgvoid anv_queue_finish(struct anv_queue *queue);
14097ec681f3Smrg
14107ec681f3SmrgVkResult anv_queue_execbuf_locked(struct anv_queue *queue, struct anv_queue_submit *submit);
14117ec681f3SmrgVkResult anv_queue_submit_simple_batch(struct anv_queue *queue,
14127ec681f3Smrg                                       struct anv_batch *batch);
14137ec681f3Smrg
14147ec681f3Smrguint64_t anv_gettime_ns(void);
14157ec681f3Smrguint64_t anv_get_absolute_timeout(uint64_t timeout);
14167ec681f3Smrg
141701e04c3fSmrgvoid* anv_gem_mmap(struct anv_device *device,
141801e04c3fSmrg                   uint32_t gem_handle, uint64_t offset, uint64_t size, uint32_t flags);
14197ec681f3Smrgvoid anv_gem_munmap(struct anv_device *device, void *p, uint64_t size);
142001e04c3fSmrguint32_t anv_gem_create(struct anv_device *device, uint64_t size);
142101e04c3fSmrgvoid anv_gem_close(struct anv_device *device, uint32_t gem_handle);
14227ec681f3Smrguint32_t anv_gem_create_regions(struct anv_device *device, uint64_t anv_bo_size,
14237ec681f3Smrg                                uint32_t num_regions,
14247ec681f3Smrg                                struct drm_i915_gem_memory_class_instance *regions);
142501e04c3fSmrguint32_t anv_gem_userptr(struct anv_device *device, void *mem, size_t size);
142601e04c3fSmrgint anv_gem_busy(struct anv_device *device, uint32_t gem_handle);
142701e04c3fSmrgint anv_gem_wait(struct anv_device *device, uint32_t gem_handle, int64_t *timeout_ns);
142801e04c3fSmrgint anv_gem_execbuffer(struct anv_device *device,
142901e04c3fSmrg                       struct drm_i915_gem_execbuffer2 *execbuf);
143001e04c3fSmrgint anv_gem_set_tiling(struct anv_device *device, uint32_t gem_handle,
143101e04c3fSmrg                       uint32_t stride, uint32_t tiling);
143201e04c3fSmrgint anv_gem_create_context(struct anv_device *device);
14337ec681f3Smrgint anv_gem_create_context_engines(struct anv_device *device,
14347ec681f3Smrg                                   const struct drm_i915_query_engine_info *info,
14357ec681f3Smrg                                   int num_engines,
14367ec681f3Smrg                                   uint16_t *engine_classes);
143701e04c3fSmrgbool anv_gem_has_context_priority(int fd);
143801e04c3fSmrgint anv_gem_destroy_context(struct anv_device *device, int context);
143901e04c3fSmrgint anv_gem_set_context_param(int fd, int context, uint32_t param,
144001e04c3fSmrg                              uint64_t value);
144101e04c3fSmrgint anv_gem_get_context_param(int fd, int context, uint32_t param,
144201e04c3fSmrg                              uint64_t *value);
144301e04c3fSmrgint anv_gem_get_param(int fd, uint32_t param);
14447ec681f3Smrguint64_t anv_gem_get_drm_cap(int fd, uint32_t capability);
144501e04c3fSmrgint anv_gem_get_tiling(struct anv_device *device, uint32_t gem_handle);
144601e04c3fSmrgbool anv_gem_get_bit6_swizzle(int fd, uint32_t tiling);
14477ec681f3Smrgint anv_gem_context_get_reset_stats(int fd, int context,
14487ec681f3Smrg                                    uint32_t *active, uint32_t *pending);
144901e04c3fSmrgint anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle);
14507ec681f3Smrgint anv_gem_reg_read(int fd, uint32_t offset, uint64_t *result);
145101e04c3fSmrguint32_t anv_gem_fd_to_handle(struct anv_device *device, int fd);
145201e04c3fSmrgint anv_gem_set_caching(struct anv_device *device, uint32_t gem_handle, uint32_t caching);
145301e04c3fSmrgint anv_gem_set_domain(struct anv_device *device, uint32_t gem_handle,
145401e04c3fSmrg                       uint32_t read_domains, uint32_t write_domain);
145501e04c3fSmrgint anv_gem_sync_file_merge(struct anv_device *device, int fd1, int fd2);
145601e04c3fSmrguint32_t anv_gem_syncobj_create(struct anv_device *device, uint32_t flags);
145701e04c3fSmrgvoid anv_gem_syncobj_destroy(struct anv_device *device, uint32_t handle);
145801e04c3fSmrgint anv_gem_syncobj_handle_to_fd(struct anv_device *device, uint32_t handle);
145901e04c3fSmrguint32_t anv_gem_syncobj_fd_to_handle(struct anv_device *device, int fd);
146001e04c3fSmrgint anv_gem_syncobj_export_sync_file(struct anv_device *device,
146101e04c3fSmrg                                     uint32_t handle);
146201e04c3fSmrgint anv_gem_syncobj_import_sync_file(struct anv_device *device,
146301e04c3fSmrg                                     uint32_t handle, int fd);
146401e04c3fSmrgvoid anv_gem_syncobj_reset(struct anv_device *device, uint32_t handle);
146501e04c3fSmrgbool anv_gem_supports_syncobj_wait(int fd);
146601e04c3fSmrgint anv_gem_syncobj_wait(struct anv_device *device,
14677ec681f3Smrg                         const uint32_t *handles, uint32_t num_handles,
146801e04c3fSmrg                         int64_t abs_timeout_ns, bool wait_all);
14697ec681f3Smrgint anv_gem_syncobj_timeline_wait(struct anv_device *device,
14707ec681f3Smrg                                  const uint32_t *handles, const uint64_t *points,
14717ec681f3Smrg                                  uint32_t num_items, int64_t abs_timeout_ns,
14727ec681f3Smrg                                  bool wait_all, bool wait_materialize);
14737ec681f3Smrgint anv_gem_syncobj_timeline_signal(struct anv_device *device,
14747ec681f3Smrg                                    const uint32_t *handles, const uint64_t *points,
14757ec681f3Smrg                                    uint32_t num_items);
14767ec681f3Smrgint anv_gem_syncobj_timeline_query(struct anv_device *device,
14777ec681f3Smrg                                   const uint32_t *handles, uint64_t *points,
14787ec681f3Smrg                                   uint32_t num_items);
14797ec681f3Smrgint anv_i915_query(int fd, uint64_t query_id, void *buffer,
14807ec681f3Smrg                   int32_t *buffer_len);
14817ec681f3Smrgstruct drm_i915_query_engine_info *anv_gem_get_engine_info(int fd);
14827ec681f3Smrgint anv_gem_count_engines(const struct drm_i915_query_engine_info *info,
14837ec681f3Smrg                          uint16_t engine_class);
14847ec681f3Smrg
14857ec681f3Smrguint64_t anv_vma_alloc(struct anv_device *device,
14867ec681f3Smrg                       uint64_t size, uint64_t align,
14877ec681f3Smrg                       enum anv_bo_alloc_flags alloc_flags,
14887ec681f3Smrg                       uint64_t client_address);
14897ec681f3Smrgvoid anv_vma_free(struct anv_device *device,
14907ec681f3Smrg                  uint64_t address, uint64_t size);
149101e04c3fSmrg
149201e04c3fSmrgstruct anv_reloc_list {
149301e04c3fSmrg   uint32_t                                     num_relocs;
149401e04c3fSmrg   uint32_t                                     array_length;
149501e04c3fSmrg   struct drm_i915_gem_relocation_entry *       relocs;
149601e04c3fSmrg   struct anv_bo **                             reloc_bos;
14977ec681f3Smrg   uint32_t                                     dep_words;
14987ec681f3Smrg   BITSET_WORD *                                deps;
149901e04c3fSmrg};
150001e04c3fSmrg
150101e04c3fSmrgVkResult anv_reloc_list_init(struct anv_reloc_list *list,
150201e04c3fSmrg                             const VkAllocationCallbacks *alloc);
150301e04c3fSmrgvoid anv_reloc_list_finish(struct anv_reloc_list *list,
150401e04c3fSmrg                           const VkAllocationCallbacks *alloc);
150501e04c3fSmrg
150601e04c3fSmrgVkResult anv_reloc_list_add(struct anv_reloc_list *list,
150701e04c3fSmrg                            const VkAllocationCallbacks *alloc,
150801e04c3fSmrg                            uint32_t offset, struct anv_bo *target_bo,
15097ec681f3Smrg                            uint32_t delta, uint64_t *address_u64_out);
15107ec681f3Smrg
15117ec681f3SmrgVkResult anv_reloc_list_add_bo(struct anv_reloc_list *list,
15127ec681f3Smrg                               const VkAllocationCallbacks *alloc,
15137ec681f3Smrg                               struct anv_bo *target_bo);
151401e04c3fSmrg
151501e04c3fSmrgstruct anv_batch_bo {
151601e04c3fSmrg   /* Link in the anv_cmd_buffer.owned_batch_bos list */
151701e04c3fSmrg   struct list_head                             link;
151801e04c3fSmrg
15197ec681f3Smrg   struct anv_bo *                              bo;
152001e04c3fSmrg
152101e04c3fSmrg   /* Bytes actually consumed in this batch BO */
152201e04c3fSmrg   uint32_t                                     length;
152301e04c3fSmrg
15247ec681f3Smrg   /* When this batch BO is used as part of a primary batch buffer, this
15257ec681f3Smrg    * tracked whether it is chained to another primary batch buffer.
15267ec681f3Smrg    *
15277ec681f3Smrg    * If this is the case, the relocation list's last entry points the
15287ec681f3Smrg    * location of the MI_BATCH_BUFFER_START chaining to the next batch.
15297ec681f3Smrg    */
15307ec681f3Smrg   bool                                         chained;
15317ec681f3Smrg
153201e04c3fSmrg   struct anv_reloc_list                        relocs;
153301e04c3fSmrg};
153401e04c3fSmrg
153501e04c3fSmrgstruct anv_batch {
153601e04c3fSmrg   const VkAllocationCallbacks *                alloc;
153701e04c3fSmrg
15387ec681f3Smrg   struct anv_address                           start_addr;
15397ec681f3Smrg
154001e04c3fSmrg   void *                                       start;
154101e04c3fSmrg   void *                                       end;
154201e04c3fSmrg   void *                                       next;
154301e04c3fSmrg
154401e04c3fSmrg   struct anv_reloc_list *                      relocs;
154501e04c3fSmrg
154601e04c3fSmrg   /* This callback is called (with the associated user data) in the event
154701e04c3fSmrg    * that the batch runs out of space.
154801e04c3fSmrg    */
154901e04c3fSmrg   VkResult (*extend_cb)(struct anv_batch *, void *);
155001e04c3fSmrg   void *                                       user_data;
155101e04c3fSmrg
155201e04c3fSmrg   /**
155301e04c3fSmrg    * Current error status of the command buffer. Used to track inconsistent
155401e04c3fSmrg    * or incomplete command buffer states that are the consequence of run-time
155501e04c3fSmrg    * errors such as out of memory scenarios. We want to track this in the
155601e04c3fSmrg    * batch because the command buffer object is not visible to some parts
155701e04c3fSmrg    * of the driver.
155801e04c3fSmrg    */
155901e04c3fSmrg   VkResult                                     status;
156001e04c3fSmrg};
156101e04c3fSmrg
156201e04c3fSmrgvoid *anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords);
156301e04c3fSmrgvoid anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other);
15647ec681f3Smrgstruct anv_address anv_batch_address(struct anv_batch *batch, void *batch_location);
15657ec681f3Smrg
15667ec681f3Smrgstatic inline void
15677ec681f3Smrganv_batch_set_storage(struct anv_batch *batch, struct anv_address addr,
15687ec681f3Smrg                      void *map, size_t size)
15697ec681f3Smrg{
15707ec681f3Smrg   batch->start_addr = addr;
15717ec681f3Smrg   batch->next = batch->start = map;
15727ec681f3Smrg   batch->end = map + size;
15737ec681f3Smrg}
157401e04c3fSmrg
157501e04c3fSmrgstatic inline VkResult
157601e04c3fSmrganv_batch_set_error(struct anv_batch *batch, VkResult error)
157701e04c3fSmrg{
157801e04c3fSmrg   assert(error != VK_SUCCESS);
157901e04c3fSmrg   if (batch->status == VK_SUCCESS)
158001e04c3fSmrg      batch->status = error;
158101e04c3fSmrg   return batch->status;
158201e04c3fSmrg}
158301e04c3fSmrg
158401e04c3fSmrgstatic inline bool
158501e04c3fSmrganv_batch_has_error(struct anv_batch *batch)
158601e04c3fSmrg{
158701e04c3fSmrg   return batch->status != VK_SUCCESS;
158801e04c3fSmrg}
158901e04c3fSmrg
15907ec681f3Smrgstatic inline uint64_t
15917ec681f3Smrganv_batch_emit_reloc(struct anv_batch *batch,
15927ec681f3Smrg                     void *location, struct anv_bo *bo, uint32_t delta)
15937ec681f3Smrg{
15947ec681f3Smrg   uint64_t address_u64 = 0;
15957ec681f3Smrg   VkResult result;
15967ec681f3Smrg
15977ec681f3Smrg   if (ANV_ALWAYS_SOFTPIN) {
15987ec681f3Smrg      address_u64 = bo->offset + delta;
15997ec681f3Smrg      result = anv_reloc_list_add_bo(batch->relocs, batch->alloc, bo);
16007ec681f3Smrg   } else {
16017ec681f3Smrg      result = anv_reloc_list_add(batch->relocs, batch->alloc,
16027ec681f3Smrg                                  location - batch->start, bo, delta,
16037ec681f3Smrg                                  &address_u64);
16047ec681f3Smrg   }
16057ec681f3Smrg   if (unlikely(result != VK_SUCCESS)) {
16067ec681f3Smrg      anv_batch_set_error(batch, result);
16077ec681f3Smrg      return 0;
16087ec681f3Smrg   }
16097ec681f3Smrg
16107ec681f3Smrg   return address_u64;
16117ec681f3Smrg}
16127ec681f3Smrg
161301e04c3fSmrg
161401e04c3fSmrg#define ANV_NULL_ADDRESS ((struct anv_address) { NULL, 0 })
161501e04c3fSmrg
16167ec681f3Smrgstatic inline struct anv_address
16177ec681f3Smrganv_address_from_u64(uint64_t addr_u64)
16187ec681f3Smrg{
16197ec681f3Smrg   assert(addr_u64 == intel_canonical_address(addr_u64));
16207ec681f3Smrg   return (struct anv_address) {
16217ec681f3Smrg      .bo = NULL,
16227ec681f3Smrg      .offset = addr_u64,
16237ec681f3Smrg   };
16247ec681f3Smrg}
16257ec681f3Smrg
162601e04c3fSmrgstatic inline bool
162701e04c3fSmrganv_address_is_null(struct anv_address addr)
162801e04c3fSmrg{
162901e04c3fSmrg   return addr.bo == NULL && addr.offset == 0;
163001e04c3fSmrg}
163101e04c3fSmrg
163201e04c3fSmrgstatic inline uint64_t
163301e04c3fSmrganv_address_physical(struct anv_address addr)
163401e04c3fSmrg{
16357ec681f3Smrg   if (addr.bo && (ANV_ALWAYS_SOFTPIN ||
16367ec681f3Smrg                   (addr.bo->flags & EXEC_OBJECT_PINNED))) {
16377ec681f3Smrg      assert(addr.bo->flags & EXEC_OBJECT_PINNED);
16387ec681f3Smrg      return intel_canonical_address(addr.bo->offset + addr.offset);
16397ec681f3Smrg   } else {
16407ec681f3Smrg      return intel_canonical_address(addr.offset);
16417ec681f3Smrg   }
164201e04c3fSmrg}
164301e04c3fSmrg
164401e04c3fSmrgstatic inline struct anv_address
164501e04c3fSmrganv_address_add(struct anv_address addr, uint64_t offset)
164601e04c3fSmrg{
164701e04c3fSmrg   addr.offset += offset;
164801e04c3fSmrg   return addr;
164901e04c3fSmrg}
165001e04c3fSmrg
165101e04c3fSmrgstatic inline void
165201e04c3fSmrgwrite_reloc(const struct anv_device *device, void *p, uint64_t v, bool flush)
165301e04c3fSmrg{
165401e04c3fSmrg   unsigned reloc_size = 0;
16557ec681f3Smrg   if (device->info.ver >= 8) {
165601e04c3fSmrg      reloc_size = sizeof(uint64_t);
16577ec681f3Smrg      *(uint64_t *)p = intel_canonical_address(v);
165801e04c3fSmrg   } else {
165901e04c3fSmrg      reloc_size = sizeof(uint32_t);
166001e04c3fSmrg      *(uint32_t *)p = v;
166101e04c3fSmrg   }
166201e04c3fSmrg
166301e04c3fSmrg   if (flush && !device->info.has_llc)
16647ec681f3Smrg      intel_flush_range(p, reloc_size);
166501e04c3fSmrg}
166601e04c3fSmrg
166701e04c3fSmrgstatic inline uint64_t
166801e04c3fSmrg_anv_combine_address(struct anv_batch *batch, void *location,
166901e04c3fSmrg                     const struct anv_address address, uint32_t delta)
167001e04c3fSmrg{
167101e04c3fSmrg   if (address.bo == NULL) {
167201e04c3fSmrg      return address.offset + delta;
16737ec681f3Smrg   } else if (batch == NULL) {
16747ec681f3Smrg      assert(address.bo->flags & EXEC_OBJECT_PINNED);
16757ec681f3Smrg      return anv_address_physical(anv_address_add(address, delta));
167601e04c3fSmrg   } else {
167701e04c3fSmrg      assert(batch->start <= location && location < batch->end);
16787ec681f3Smrg      /* i915 relocations are signed. */
16797ec681f3Smrg      assert(INT32_MIN <= address.offset && address.offset <= INT32_MAX);
168001e04c3fSmrg      return anv_batch_emit_reloc(batch, location, address.bo, address.offset + delta);
168101e04c3fSmrg   }
168201e04c3fSmrg}
168301e04c3fSmrg
168401e04c3fSmrg#define __gen_address_type struct anv_address
168501e04c3fSmrg#define __gen_user_data struct anv_batch
168601e04c3fSmrg#define __gen_combine_address _anv_combine_address
168701e04c3fSmrg
168801e04c3fSmrg/* Wrapper macros needed to work around preprocessor argument issues.  In
168901e04c3fSmrg * particular, arguments don't get pre-evaluated if they are concatenated.
169001e04c3fSmrg * This means that, if you pass GENX(3DSTATE_PS) into the emit macro, the
169101e04c3fSmrg * GENX macro won't get evaluated if the emit macro contains "cmd ## foo".
169201e04c3fSmrg * We can work around this easily enough with these helpers.
169301e04c3fSmrg */
169401e04c3fSmrg#define __anv_cmd_length(cmd) cmd ## _length
169501e04c3fSmrg#define __anv_cmd_length_bias(cmd) cmd ## _length_bias
169601e04c3fSmrg#define __anv_cmd_header(cmd) cmd ## _header
169701e04c3fSmrg#define __anv_cmd_pack(cmd) cmd ## _pack
169801e04c3fSmrg#define __anv_reg_num(reg) reg ## _num
169901e04c3fSmrg
170001e04c3fSmrg#define anv_pack_struct(dst, struc, ...) do {                              \
170101e04c3fSmrg      struct struc __template = {                                          \
170201e04c3fSmrg         __VA_ARGS__                                                       \
170301e04c3fSmrg      };                                                                   \
170401e04c3fSmrg      __anv_cmd_pack(struc)(NULL, dst, &__template);                       \
170501e04c3fSmrg      VG(VALGRIND_CHECK_MEM_IS_DEFINED(dst, __anv_cmd_length(struc) * 4)); \
170601e04c3fSmrg   } while (0)
170701e04c3fSmrg
170801e04c3fSmrg#define anv_batch_emitn(batch, n, cmd, ...) ({             \
170901e04c3fSmrg      void *__dst = anv_batch_emit_dwords(batch, n);       \
171001e04c3fSmrg      if (__dst) {                                         \
171101e04c3fSmrg         struct cmd __template = {                         \
171201e04c3fSmrg            __anv_cmd_header(cmd),                         \
171301e04c3fSmrg           .DWordLength = n - __anv_cmd_length_bias(cmd),  \
171401e04c3fSmrg            __VA_ARGS__                                    \
171501e04c3fSmrg         };                                                \
171601e04c3fSmrg         __anv_cmd_pack(cmd)(batch, __dst, &__template);   \
171701e04c3fSmrg      }                                                    \
171801e04c3fSmrg      __dst;                                               \
171901e04c3fSmrg   })
172001e04c3fSmrg
172101e04c3fSmrg#define anv_batch_emit_merge(batch, dwords0, dwords1)                   \
172201e04c3fSmrg   do {                                                                 \
172301e04c3fSmrg      uint32_t *dw;                                                     \
172401e04c3fSmrg                                                                        \
172501e04c3fSmrg      STATIC_ASSERT(ARRAY_SIZE(dwords0) == ARRAY_SIZE(dwords1));        \
172601e04c3fSmrg      dw = anv_batch_emit_dwords((batch), ARRAY_SIZE(dwords0));         \
172701e04c3fSmrg      if (!dw)                                                          \
172801e04c3fSmrg         break;                                                         \
172901e04c3fSmrg      for (uint32_t i = 0; i < ARRAY_SIZE(dwords0); i++)                \
173001e04c3fSmrg         dw[i] = (dwords0)[i] | (dwords1)[i];                           \
173101e04c3fSmrg      VG(VALGRIND_CHECK_MEM_IS_DEFINED(dw, ARRAY_SIZE(dwords0) * 4));\
173201e04c3fSmrg   } while (0)
173301e04c3fSmrg
173401e04c3fSmrg#define anv_batch_emit(batch, cmd, name)                            \
173501e04c3fSmrg   for (struct cmd name = { __anv_cmd_header(cmd) },                    \
173601e04c3fSmrg        *_dst = anv_batch_emit_dwords(batch, __anv_cmd_length(cmd));    \
173701e04c3fSmrg        __builtin_expect(_dst != NULL, 1);                              \
173801e04c3fSmrg        ({ __anv_cmd_pack(cmd)(batch, _dst, &name);                     \
173901e04c3fSmrg           VG(VALGRIND_CHECK_MEM_IS_DEFINED(_dst, __anv_cmd_length(cmd) * 4)); \
174001e04c3fSmrg           _dst = NULL;                                                 \
174101e04c3fSmrg         }))
174201e04c3fSmrg
17437ec681f3Smrg#define anv_batch_write_reg(batch, reg, name)                           \
17447ec681f3Smrg   for (struct reg name = {}, *_cont = (struct reg *)1; _cont != NULL;  \
17457ec681f3Smrg        ({                                                              \
17467ec681f3Smrg            uint32_t _dw[__anv_cmd_length(reg)];                        \
17477ec681f3Smrg            __anv_cmd_pack(reg)(NULL, _dw, &name);                      \
17487ec681f3Smrg            for (unsigned i = 0; i < __anv_cmd_length(reg); i++) {      \
17497ec681f3Smrg               anv_batch_emit(batch, GENX(MI_LOAD_REGISTER_IMM), lri) { \
17507ec681f3Smrg                  lri.RegisterOffset   = __anv_reg_num(reg);            \
17517ec681f3Smrg                  lri.DataDWord        = _dw[i];                        \
17527ec681f3Smrg               }                                                        \
17537ec681f3Smrg            }                                                           \
17547ec681f3Smrg           _cont = NULL;                                                \
17557ec681f3Smrg         }))
175601e04c3fSmrg
17577ec681f3Smrg/* #define __gen_get_batch_dwords anv_batch_emit_dwords */
17587ec681f3Smrg/* #define __gen_get_batch_address anv_batch_address */
17597ec681f3Smrg/* #define __gen_address_value anv_address_physical */
17607ec681f3Smrg/* #define __gen_address_offset anv_address_add */
176101e04c3fSmrg
17627ec681f3Smrgstruct anv_device_memory {
17637ec681f3Smrg   struct vk_object_base                        base;
176401e04c3fSmrg
17657ec681f3Smrg   struct list_head                             link;
176601e04c3fSmrg
17677ec681f3Smrg   struct anv_bo *                              bo;
17687ec681f3Smrg   const struct anv_memory_type *               type;
17697ec681f3Smrg   VkDeviceSize                                 map_size;
17707ec681f3Smrg   void *                                       map;
177101e04c3fSmrg
17727ec681f3Smrg   /* The map, from the user PoV is map + map_delta */
17737ec681f3Smrg   uint32_t                                     map_delta;
17749f464c52Smaya
17759f464c52Smaya   /* If set, we are holding reference to AHardwareBuffer
17769f464c52Smaya    * which we must release when memory is freed.
17779f464c52Smaya    */
17789f464c52Smaya   struct AHardwareBuffer *                     ahw;
17799f464c52Smaya
17809f464c52Smaya   /* If set, this memory comes from a host pointer. */
17819f464c52Smaya   void *                                       host_ptr;
178201e04c3fSmrg};
178301e04c3fSmrg
178401e04c3fSmrg/**
178501e04c3fSmrg * Header for Vertex URB Entry (VUE)
178601e04c3fSmrg */
178701e04c3fSmrgstruct anv_vue_header {
178801e04c3fSmrg   uint32_t Reserved;
178901e04c3fSmrg   uint32_t RTAIndex; /* RenderTargetArrayIndex */
179001e04c3fSmrg   uint32_t ViewportIndex;
179101e04c3fSmrg   float PointWidth;
179201e04c3fSmrg};
179301e04c3fSmrg
17949f464c52Smaya/** Struct representing a sampled image descriptor
17959f464c52Smaya *
17969f464c52Smaya * This descriptor layout is used for sampled images, bare sampler, and
17979f464c52Smaya * combined image/sampler descriptors.
17989f464c52Smaya */
17999f464c52Smayastruct anv_sampled_image_descriptor {
18009f464c52Smaya   /** Bindless image handle
18019f464c52Smaya    *
18029f464c52Smaya    * This is expected to already be shifted such that the 20-bit
18039f464c52Smaya    * SURFACE_STATE table index is in the top 20 bits.
18049f464c52Smaya    */
18059f464c52Smaya   uint32_t image;
18069f464c52Smaya
18079f464c52Smaya   /** Bindless sampler handle
18089f464c52Smaya    *
18099f464c52Smaya    * This is assumed to be a 32B-aligned SAMPLER_STATE pointer relative
18109f464c52Smaya    * to the dynamic state base address.
18119f464c52Smaya    */
18129f464c52Smaya   uint32_t sampler;
18139f464c52Smaya};
18149f464c52Smaya
18159f464c52Smayastruct anv_texture_swizzle_descriptor {
18169f464c52Smaya   /** Texture swizzle
18179f464c52Smaya    *
18189f464c52Smaya    * See also nir_intrinsic_channel_select_intel
18199f464c52Smaya    */
18209f464c52Smaya   uint8_t swizzle[4];
18219f464c52Smaya
18229f464c52Smaya   /** Unused padding to ensure the struct is a multiple of 64 bits */
18239f464c52Smaya   uint32_t _pad;
18249f464c52Smaya};
18259f464c52Smaya
18269f464c52Smaya/** Struct representing a storage image descriptor */
18279f464c52Smayastruct anv_storage_image_descriptor {
18289f464c52Smaya   /** Bindless image handles
18299f464c52Smaya    *
18309f464c52Smaya    * These are expected to already be shifted such that the 20-bit
18319f464c52Smaya    * SURFACE_STATE table index is in the top 20 bits.
18329f464c52Smaya    */
18337ec681f3Smrg   uint32_t vanilla;
18347ec681f3Smrg   uint32_t lowered;
18359f464c52Smaya};
18369f464c52Smaya
18379f464c52Smaya/** Struct representing a address/range descriptor
18389f464c52Smaya *
18399f464c52Smaya * The fields of this struct correspond directly to the data layout of
18409f464c52Smaya * nir_address_format_64bit_bounded_global addresses.  The last field is the
18419f464c52Smaya * offset in the NIR address so it must be zero so that when you load the
18429f464c52Smaya * descriptor you get a pointer to the start of the range.
18439f464c52Smaya */
18449f464c52Smayastruct anv_address_range_descriptor {
18459f464c52Smaya   uint64_t address;
18469f464c52Smaya   uint32_t range;
18479f464c52Smaya   uint32_t zero;
18489f464c52Smaya};
18499f464c52Smaya
18509f464c52Smayaenum anv_descriptor_data {
18519f464c52Smaya   /** The descriptor contains a BTI reference to a surface state */
18529f464c52Smaya   ANV_DESCRIPTOR_SURFACE_STATE  = (1 << 0),
18539f464c52Smaya   /** The descriptor contains a BTI reference to a sampler state */
18549f464c52Smaya   ANV_DESCRIPTOR_SAMPLER_STATE  = (1 << 1),
18559f464c52Smaya   /** The descriptor contains an actual buffer view */
18569f464c52Smaya   ANV_DESCRIPTOR_BUFFER_VIEW    = (1 << 2),
18579f464c52Smaya   /** The descriptor contains auxiliary image layout data */
18589f464c52Smaya   ANV_DESCRIPTOR_IMAGE_PARAM    = (1 << 3),
18599f464c52Smaya   /** The descriptor contains auxiliary image layout data */
18609f464c52Smaya   ANV_DESCRIPTOR_INLINE_UNIFORM = (1 << 4),
18619f464c52Smaya   /** anv_address_range_descriptor with a buffer address and range */
18629f464c52Smaya   ANV_DESCRIPTOR_ADDRESS_RANGE  = (1 << 5),
18639f464c52Smaya   /** Bindless surface handle */
18649f464c52Smaya   ANV_DESCRIPTOR_SAMPLED_IMAGE  = (1 << 6),
18659f464c52Smaya   /** Storage image handles */
18669f464c52Smaya   ANV_DESCRIPTOR_STORAGE_IMAGE  = (1 << 7),
18679f464c52Smaya   /** Storage image handles */
18689f464c52Smaya   ANV_DESCRIPTOR_TEXTURE_SWIZZLE  = (1 << 8),
18699f464c52Smaya};
18709f464c52Smaya
187101e04c3fSmrgstruct anv_descriptor_set_binding_layout {
187201e04c3fSmrg   /* The type of the descriptors in this binding */
187301e04c3fSmrg   VkDescriptorType type;
187401e04c3fSmrg
18759f464c52Smaya   /* Flags provided when this binding was created */
18769f464c52Smaya   VkDescriptorBindingFlagsEXT flags;
18779f464c52Smaya
18789f464c52Smaya   /* Bitfield representing the type of data this descriptor contains */
18799f464c52Smaya   enum anv_descriptor_data data;
18809f464c52Smaya
18819f464c52Smaya   /* Maximum number of YCbCr texture/sampler planes */
18829f464c52Smaya   uint8_t max_plane_count;
18839f464c52Smaya
18849f464c52Smaya   /* Number of array elements in this binding (or size in bytes for inline
18859f464c52Smaya    * uniform data)
18869f464c52Smaya    */
18877ec681f3Smrg   uint32_t array_size;
188801e04c3fSmrg
188901e04c3fSmrg   /* Index into the flattend descriptor set */
18907ec681f3Smrg   uint32_t descriptor_index;
189101e04c3fSmrg
189201e04c3fSmrg   /* Index into the dynamic state array for a dynamic buffer */
189301e04c3fSmrg   int16_t dynamic_offset_index;
189401e04c3fSmrg
189501e04c3fSmrg   /* Index into the descriptor set buffer views */
18967ec681f3Smrg   int32_t buffer_view_index;
189701e04c3fSmrg
18989f464c52Smaya   /* Offset into the descriptor buffer where this descriptor lives */
18999f464c52Smaya   uint32_t descriptor_offset;
190001e04c3fSmrg
190101e04c3fSmrg   /* Immutable samplers (or NULL if no immutable samplers) */
190201e04c3fSmrg   struct anv_sampler **immutable_samplers;
190301e04c3fSmrg};
190401e04c3fSmrg
19059f464c52Smayaunsigned anv_descriptor_size(const struct anv_descriptor_set_binding_layout *layout);
19069f464c52Smaya
19079f464c52Smayaunsigned anv_descriptor_type_size(const struct anv_physical_device *pdevice,
19089f464c52Smaya                                  VkDescriptorType type);
19099f464c52Smaya
19109f464c52Smayabool anv_descriptor_supports_bindless(const struct anv_physical_device *pdevice,
19119f464c52Smaya                                      const struct anv_descriptor_set_binding_layout *binding,
19129f464c52Smaya                                      bool sampler);
19139f464c52Smaya
19149f464c52Smayabool anv_descriptor_requires_bindless(const struct anv_physical_device *pdevice,
19159f464c52Smaya                                      const struct anv_descriptor_set_binding_layout *binding,
19169f464c52Smaya                                      bool sampler);
19179f464c52Smaya
191801e04c3fSmrgstruct anv_descriptor_set_layout {
19197ec681f3Smrg   struct vk_object_base base;
19207ec681f3Smrg
192101e04c3fSmrg   /* Descriptor set layouts can be destroyed at almost any time */
192201e04c3fSmrg   uint32_t ref_cnt;
192301e04c3fSmrg
192401e04c3fSmrg   /* Number of bindings in this descriptor set */
19257ec681f3Smrg   uint32_t binding_count;
192601e04c3fSmrg
19277ec681f3Smrg   /* Total number of descriptors */
19287ec681f3Smrg   uint32_t descriptor_count;
192901e04c3fSmrg
193001e04c3fSmrg   /* Shader stages affected by this descriptor set */
193101e04c3fSmrg   uint16_t shader_stages;
193201e04c3fSmrg
19339f464c52Smaya   /* Number of buffer views in this descriptor set */
19347ec681f3Smrg   uint32_t buffer_view_count;
193501e04c3fSmrg
193601e04c3fSmrg   /* Number of dynamic offsets used by this descriptor set */
193701e04c3fSmrg   uint16_t dynamic_offset_count;
193801e04c3fSmrg
19397ec681f3Smrg   /* For each dynamic buffer, which VkShaderStageFlagBits stages are using
19407ec681f3Smrg    * this buffer
19417ec681f3Smrg    */
19427ec681f3Smrg   VkShaderStageFlags dynamic_offset_stages[MAX_DYNAMIC_BUFFERS];
19437ec681f3Smrg
19449f464c52Smaya   /* Size of the descriptor buffer for this descriptor set */
19459f464c52Smaya   uint32_t descriptor_buffer_size;
19469f464c52Smaya
194701e04c3fSmrg   /* Bindings in this descriptor set */
194801e04c3fSmrg   struct anv_descriptor_set_binding_layout binding[0];
194901e04c3fSmrg};
195001e04c3fSmrg
19517ec681f3Smrgvoid anv_descriptor_set_layout_destroy(struct anv_device *device,
19527ec681f3Smrg                                       struct anv_descriptor_set_layout *layout);
19537ec681f3Smrg
195401e04c3fSmrgstatic inline void
195501e04c3fSmrganv_descriptor_set_layout_ref(struct anv_descriptor_set_layout *layout)
195601e04c3fSmrg{
195701e04c3fSmrg   assert(layout && layout->ref_cnt >= 1);
195801e04c3fSmrg   p_atomic_inc(&layout->ref_cnt);
195901e04c3fSmrg}
196001e04c3fSmrg
196101e04c3fSmrgstatic inline void
196201e04c3fSmrganv_descriptor_set_layout_unref(struct anv_device *device,
196301e04c3fSmrg                                struct anv_descriptor_set_layout *layout)
196401e04c3fSmrg{
196501e04c3fSmrg   assert(layout && layout->ref_cnt >= 1);
196601e04c3fSmrg   if (p_atomic_dec_zero(&layout->ref_cnt))
19677ec681f3Smrg      anv_descriptor_set_layout_destroy(device, layout);
196801e04c3fSmrg}
196901e04c3fSmrg
197001e04c3fSmrgstruct anv_descriptor {
197101e04c3fSmrg   VkDescriptorType type;
197201e04c3fSmrg
197301e04c3fSmrg   union {
197401e04c3fSmrg      struct {
197501e04c3fSmrg         VkImageLayout layout;
197601e04c3fSmrg         struct anv_image_view *image_view;
197701e04c3fSmrg         struct anv_sampler *sampler;
197801e04c3fSmrg      };
197901e04c3fSmrg
198001e04c3fSmrg      struct {
198101e04c3fSmrg         struct anv_buffer *buffer;
198201e04c3fSmrg         uint64_t offset;
198301e04c3fSmrg         uint64_t range;
198401e04c3fSmrg      };
198501e04c3fSmrg
198601e04c3fSmrg      struct anv_buffer_view *buffer_view;
198701e04c3fSmrg   };
198801e04c3fSmrg};
198901e04c3fSmrg
199001e04c3fSmrgstruct anv_descriptor_set {
19917ec681f3Smrg   struct vk_object_base base;
19927ec681f3Smrg
19939f464c52Smaya   struct anv_descriptor_pool *pool;
199401e04c3fSmrg   struct anv_descriptor_set_layout *layout;
19957ec681f3Smrg
19967ec681f3Smrg   /* Amount of space occupied in the the pool by this descriptor set. It can
19977ec681f3Smrg    * be larger than the size of the descriptor set.
19987ec681f3Smrg    */
199901e04c3fSmrg   uint32_t size;
20009f464c52Smaya
20019f464c52Smaya   /* State relative to anv_descriptor_pool::bo */
20029f464c52Smaya   struct anv_state desc_mem;
20039f464c52Smaya   /* Surface state for the descriptor buffer */
20049f464c52Smaya   struct anv_state desc_surface_state;
20059f464c52Smaya
20067ec681f3Smrg   /* Descriptor set address. */
20077ec681f3Smrg   struct anv_address desc_addr;
20087ec681f3Smrg
20099f464c52Smaya   uint32_t buffer_view_count;
201001e04c3fSmrg   struct anv_buffer_view *buffer_views;
2011993e1d59Smrg
2012993e1d59Smrg   /* Link to descriptor pool's desc_sets list . */
2013993e1d59Smrg   struct list_head pool_link;
2014993e1d59Smrg
20157ec681f3Smrg   uint32_t descriptor_count;
201601e04c3fSmrg   struct anv_descriptor descriptors[0];
201701e04c3fSmrg};
201801e04c3fSmrg
20197ec681f3Smrgstatic inline bool
20207ec681f3Smrganv_descriptor_set_is_push(struct anv_descriptor_set *set)
20217ec681f3Smrg{
20227ec681f3Smrg   return set->pool == NULL;
20237ec681f3Smrg}
20247ec681f3Smrg
202501e04c3fSmrgstruct anv_buffer_view {
20267ec681f3Smrg   struct vk_object_base base;
20277ec681f3Smrg
202801e04c3fSmrg   enum isl_format format; /**< VkBufferViewCreateInfo::format */
202901e04c3fSmrg   uint64_t range; /**< VkBufferViewCreateInfo::range */
203001e04c3fSmrg
203101e04c3fSmrg   struct anv_address address;
203201e04c3fSmrg
203301e04c3fSmrg   struct anv_state surface_state;
203401e04c3fSmrg   struct anv_state storage_surface_state;
20357ec681f3Smrg   struct anv_state lowered_storage_surface_state;
203601e04c3fSmrg
20377ec681f3Smrg   struct brw_image_param lowered_storage_image_param;
203801e04c3fSmrg};
203901e04c3fSmrg
204001e04c3fSmrgstruct anv_push_descriptor_set {
204101e04c3fSmrg   struct anv_descriptor_set set;
204201e04c3fSmrg
204301e04c3fSmrg   /* Put this field right behind anv_descriptor_set so it fills up the
204401e04c3fSmrg    * descriptors[0] field. */
204501e04c3fSmrg   struct anv_descriptor descriptors[MAX_PUSH_DESCRIPTORS];
20469f464c52Smaya
20479f464c52Smaya   /** True if the descriptor set buffer has been referenced by a draw or
20489f464c52Smaya    * dispatch command.
20499f464c52Smaya    */
20509f464c52Smaya   bool set_used_on_gpu;
20519f464c52Smaya
205201e04c3fSmrg   struct anv_buffer_view buffer_views[MAX_PUSH_DESCRIPTORS];
205301e04c3fSmrg};
205401e04c3fSmrg
20557ec681f3Smrgstatic inline struct anv_address
20567ec681f3Smrganv_descriptor_set_address(struct anv_descriptor_set *set)
20577ec681f3Smrg{
20587ec681f3Smrg   if (anv_descriptor_set_is_push(set)) {
20597ec681f3Smrg      /* We have to flag push descriptor set as used on the GPU
20607ec681f3Smrg       * so that the next time we push descriptors, we grab a new memory.
20617ec681f3Smrg       */
20627ec681f3Smrg      struct anv_push_descriptor_set *push_set =
20637ec681f3Smrg         (struct anv_push_descriptor_set *)set;
20647ec681f3Smrg      push_set->set_used_on_gpu = true;
20657ec681f3Smrg   }
20667ec681f3Smrg
20677ec681f3Smrg   return set->desc_addr;
20687ec681f3Smrg}
20697ec681f3Smrg
207001e04c3fSmrgstruct anv_descriptor_pool {
20717ec681f3Smrg   struct vk_object_base base;
20727ec681f3Smrg
207301e04c3fSmrg   uint32_t size;
207401e04c3fSmrg   uint32_t next;
207501e04c3fSmrg   uint32_t free_list;
207601e04c3fSmrg
20777ec681f3Smrg   struct anv_bo *bo;
20789f464c52Smaya   struct util_vma_heap bo_heap;
20799f464c52Smaya
208001e04c3fSmrg   struct anv_state_stream surface_state_stream;
208101e04c3fSmrg   void *surface_state_free_list;
208201e04c3fSmrg
2083993e1d59Smrg   struct list_head desc_sets;
2084993e1d59Smrg
208501e04c3fSmrg   char data[0];
208601e04c3fSmrg};
208701e04c3fSmrg
208801e04c3fSmrgenum anv_descriptor_template_entry_type {
208901e04c3fSmrg   ANV_DESCRIPTOR_TEMPLATE_ENTRY_TYPE_IMAGE,
209001e04c3fSmrg   ANV_DESCRIPTOR_TEMPLATE_ENTRY_TYPE_BUFFER,
209101e04c3fSmrg   ANV_DESCRIPTOR_TEMPLATE_ENTRY_TYPE_BUFFER_VIEW
209201e04c3fSmrg};
209301e04c3fSmrg
209401e04c3fSmrgstruct anv_descriptor_template_entry {
209501e04c3fSmrg   /* The type of descriptor in this entry */
209601e04c3fSmrg   VkDescriptorType type;
209701e04c3fSmrg
209801e04c3fSmrg   /* Binding in the descriptor set */
209901e04c3fSmrg   uint32_t binding;
210001e04c3fSmrg
210101e04c3fSmrg   /* Offset at which to write into the descriptor set binding */
210201e04c3fSmrg   uint32_t array_element;
210301e04c3fSmrg
210401e04c3fSmrg   /* Number of elements to write into the descriptor set binding */
210501e04c3fSmrg   uint32_t array_count;
210601e04c3fSmrg
210701e04c3fSmrg   /* Offset into the user provided data */
210801e04c3fSmrg   size_t offset;
210901e04c3fSmrg
211001e04c3fSmrg   /* Stride between elements into the user provided data */
211101e04c3fSmrg   size_t stride;
211201e04c3fSmrg};
211301e04c3fSmrg
211401e04c3fSmrgstruct anv_descriptor_update_template {
21157ec681f3Smrg    struct vk_object_base base;
21167ec681f3Smrg
211701e04c3fSmrg    VkPipelineBindPoint bind_point;
211801e04c3fSmrg
211901e04c3fSmrg   /* The descriptor set this template corresponds to. This value is only
212001e04c3fSmrg    * valid if the template was created with the templateType
21219f464c52Smaya    * VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET.
212201e04c3fSmrg    */
212301e04c3fSmrg   uint8_t set;
212401e04c3fSmrg
212501e04c3fSmrg   /* Number of entries in this template */
212601e04c3fSmrg   uint32_t entry_count;
212701e04c3fSmrg
212801e04c3fSmrg   /* Entries of the template */
212901e04c3fSmrg   struct anv_descriptor_template_entry entries[0];
213001e04c3fSmrg};
213101e04c3fSmrg
213201e04c3fSmrgsize_t
21337ec681f3Smrganv_descriptor_set_layout_size(const struct anv_descriptor_set_layout *layout,
21347ec681f3Smrg                               uint32_t var_desc_count);
21357ec681f3Smrg
21367ec681f3Smrguint32_t
21377ec681f3Smrganv_descriptor_set_layout_descriptor_buffer_size(const struct anv_descriptor_set_layout *set_layout,
21387ec681f3Smrg                                                 uint32_t var_desc_count);
213901e04c3fSmrg
214001e04c3fSmrgvoid
21419f464c52Smayaanv_descriptor_set_write_image_view(struct anv_device *device,
21429f464c52Smaya                                    struct anv_descriptor_set *set,
214301e04c3fSmrg                                    const VkDescriptorImageInfo * const info,
214401e04c3fSmrg                                    VkDescriptorType type,
214501e04c3fSmrg                                    uint32_t binding,
214601e04c3fSmrg                                    uint32_t element);
214701e04c3fSmrg
214801e04c3fSmrgvoid
21499f464c52Smayaanv_descriptor_set_write_buffer_view(struct anv_device *device,
21509f464c52Smaya                                     struct anv_descriptor_set *set,
215101e04c3fSmrg                                     VkDescriptorType type,
215201e04c3fSmrg                                     struct anv_buffer_view *buffer_view,
215301e04c3fSmrg                                     uint32_t binding,
215401e04c3fSmrg                                     uint32_t element);
215501e04c3fSmrg
215601e04c3fSmrgvoid
21579f464c52Smayaanv_descriptor_set_write_buffer(struct anv_device *device,
21589f464c52Smaya                                struct anv_descriptor_set *set,
215901e04c3fSmrg                                struct anv_state_stream *alloc_stream,
216001e04c3fSmrg                                VkDescriptorType type,
216101e04c3fSmrg                                struct anv_buffer *buffer,
216201e04c3fSmrg                                uint32_t binding,
216301e04c3fSmrg                                uint32_t element,
216401e04c3fSmrg                                VkDeviceSize offset,
216501e04c3fSmrg                                VkDeviceSize range);
21667ec681f3Smrg
21677ec681f3Smrgvoid
21687ec681f3Smrganv_descriptor_set_write_acceleration_structure(struct anv_device *device,
21697ec681f3Smrg                                                struct anv_descriptor_set *set,
21707ec681f3Smrg                                                struct anv_acceleration_structure *accel,
21717ec681f3Smrg                                                uint32_t binding,
21727ec681f3Smrg                                                uint32_t element);
21737ec681f3Smrg
21749f464c52Smayavoid
21759f464c52Smayaanv_descriptor_set_write_inline_uniform_data(struct anv_device *device,
21769f464c52Smaya                                             struct anv_descriptor_set *set,
21779f464c52Smaya                                             uint32_t binding,
21789f464c52Smaya                                             const void *data,
21799f464c52Smaya                                             size_t offset,
21809f464c52Smaya                                             size_t size);
218101e04c3fSmrg
218201e04c3fSmrgvoid
21839f464c52Smayaanv_descriptor_set_write_template(struct anv_device *device,
21849f464c52Smaya                                  struct anv_descriptor_set *set,
218501e04c3fSmrg                                  struct anv_state_stream *alloc_stream,
218601e04c3fSmrg                                  const struct anv_descriptor_update_template *template,
218701e04c3fSmrg                                  const void *data);
218801e04c3fSmrg
218901e04c3fSmrgVkResult
219001e04c3fSmrganv_descriptor_set_create(struct anv_device *device,
219101e04c3fSmrg                          struct anv_descriptor_pool *pool,
219201e04c3fSmrg                          struct anv_descriptor_set_layout *layout,
21937ec681f3Smrg                          uint32_t var_desc_count,
219401e04c3fSmrg                          struct anv_descriptor_set **out_set);
219501e04c3fSmrg
219601e04c3fSmrgvoid
219701e04c3fSmrganv_descriptor_set_destroy(struct anv_device *device,
219801e04c3fSmrg                           struct anv_descriptor_pool *pool,
219901e04c3fSmrg                           struct anv_descriptor_set *set);
220001e04c3fSmrg
22017ec681f3Smrg#define ANV_DESCRIPTOR_SET_NULL             (UINT8_MAX - 5)
22027ec681f3Smrg#define ANV_DESCRIPTOR_SET_PUSH_CONSTANTS   (UINT8_MAX - 4)
22039f464c52Smaya#define ANV_DESCRIPTOR_SET_DESCRIPTORS      (UINT8_MAX - 3)
22049f464c52Smaya#define ANV_DESCRIPTOR_SET_NUM_WORK_GROUPS  (UINT8_MAX - 2)
220501e04c3fSmrg#define ANV_DESCRIPTOR_SET_SHADER_CONSTANTS (UINT8_MAX - 1)
220601e04c3fSmrg#define ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS UINT8_MAX
220701e04c3fSmrg
220801e04c3fSmrgstruct anv_pipeline_binding {
22097ec681f3Smrg   /** Index in the descriptor set
22107ec681f3Smrg    *
22117ec681f3Smrg    * This is a flattened index; the descriptor set layout is already taken
22127ec681f3Smrg    * into account.
22137ec681f3Smrg    */
22147ec681f3Smrg   uint32_t index;
22157ec681f3Smrg
22167ec681f3Smrg   /** The descriptor set this surface corresponds to.
22177ec681f3Smrg    *
22187ec681f3Smrg    * The special ANV_DESCRIPTOR_SET_* values above indicates that this
22197ec681f3Smrg    * binding is not a normal descriptor set but something else.
222001e04c3fSmrg    */
222101e04c3fSmrg   uint8_t set;
222201e04c3fSmrg
22237ec681f3Smrg   union {
22247ec681f3Smrg      /** Plane in the binding index for images */
22257ec681f3Smrg      uint8_t plane;
22267ec681f3Smrg
22277ec681f3Smrg      /** Input attachment index (relative to the subpass) */
22287ec681f3Smrg      uint8_t input_attachment_index;
22297ec681f3Smrg
22307ec681f3Smrg      /** Dynamic offset index (for dynamic UBOs and SSBOs) */
22317ec681f3Smrg      uint8_t dynamic_offset_index;
22327ec681f3Smrg   };
22337ec681f3Smrg
22347ec681f3Smrg   /** For a storage image, whether it requires a lowered surface */
22357ec681f3Smrg   uint8_t lowered_storage_surface;
223601e04c3fSmrg
22377ec681f3Smrg   /** Pad to 64 bits so that there are no holes and we can safely memcmp
22387ec681f3Smrg    * assuming POD zero-initialization.
22397ec681f3Smrg    */
22407ec681f3Smrg   uint8_t pad;
22417ec681f3Smrg};
22427ec681f3Smrg
22437ec681f3Smrgstruct anv_push_range {
22447ec681f3Smrg   /** Index in the descriptor set */
224501e04c3fSmrg   uint32_t index;
224601e04c3fSmrg
22477ec681f3Smrg   /** Descriptor set index */
22487ec681f3Smrg   uint8_t set;
224901e04c3fSmrg
22507ec681f3Smrg   /** Dynamic offset index (for dynamic UBOs) */
22517ec681f3Smrg   uint8_t dynamic_offset_index;
225201e04c3fSmrg
22537ec681f3Smrg   /** Start offset in units of 32B */
22547ec681f3Smrg   uint8_t start;
22557ec681f3Smrg
22567ec681f3Smrg   /** Range in units of 32B */
22577ec681f3Smrg   uint8_t length;
225801e04c3fSmrg};
225901e04c3fSmrg
226001e04c3fSmrgstruct anv_pipeline_layout {
22617ec681f3Smrg   struct vk_object_base base;
22627ec681f3Smrg
226301e04c3fSmrg   struct {
226401e04c3fSmrg      struct anv_descriptor_set_layout *layout;
226501e04c3fSmrg      uint32_t dynamic_offset_start;
226601e04c3fSmrg   } set[MAX_SETS];
226701e04c3fSmrg
226801e04c3fSmrg   uint32_t num_sets;
226901e04c3fSmrg
227001e04c3fSmrg   unsigned char sha1[20];
227101e04c3fSmrg};
227201e04c3fSmrg
227301e04c3fSmrgstruct anv_buffer {
22747ec681f3Smrg   struct vk_object_base                        base;
22757ec681f3Smrg
227601e04c3fSmrg   struct anv_device *                          device;
227701e04c3fSmrg   VkDeviceSize                                 size;
227801e04c3fSmrg
22797ec681f3Smrg   VkBufferCreateFlags                          create_flags;
228001e04c3fSmrg   VkBufferUsageFlags                           usage;
228101e04c3fSmrg
228201e04c3fSmrg   /* Set when bound */
228301e04c3fSmrg   struct anv_address                           address;
228401e04c3fSmrg};
228501e04c3fSmrg
228601e04c3fSmrgstatic inline uint64_t
228701e04c3fSmrganv_buffer_get_range(struct anv_buffer *buffer, uint64_t offset, uint64_t range)
228801e04c3fSmrg{
228901e04c3fSmrg   assert(offset <= buffer->size);
229001e04c3fSmrg   if (range == VK_WHOLE_SIZE) {
229101e04c3fSmrg      return buffer->size - offset;
229201e04c3fSmrg   } else {
229301e04c3fSmrg      assert(range + offset >= range);
229401e04c3fSmrg      assert(range + offset <= buffer->size);
229501e04c3fSmrg      return range;
229601e04c3fSmrg   }
229701e04c3fSmrg}
229801e04c3fSmrg
229901e04c3fSmrgenum anv_cmd_dirty_bits {
23007ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_VIEWPORT                    = 1 << 0, /* VK_DYNAMIC_STATE_VIEWPORT */
23017ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_SCISSOR                     = 1 << 1, /* VK_DYNAMIC_STATE_SCISSOR */
23027ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH                  = 1 << 2, /* VK_DYNAMIC_STATE_LINE_WIDTH */
23037ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS                  = 1 << 3, /* VK_DYNAMIC_STATE_DEPTH_BIAS */
23047ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS             = 1 << 4, /* VK_DYNAMIC_STATE_BLEND_CONSTANTS */
23057ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS                = 1 << 5, /* VK_DYNAMIC_STATE_DEPTH_BOUNDS */
23067ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK        = 1 << 6, /* VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK */
23077ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK          = 1 << 7, /* VK_DYNAMIC_STATE_STENCIL_WRITE_MASK */
23087ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE           = 1 << 8, /* VK_DYNAMIC_STATE_STENCIL_REFERENCE */
23097ec681f3Smrg   ANV_CMD_DIRTY_PIPELINE                            = 1 << 9,
23107ec681f3Smrg   ANV_CMD_DIRTY_INDEX_BUFFER                        = 1 << 10,
23117ec681f3Smrg   ANV_CMD_DIRTY_RENDER_TARGETS                      = 1 << 11,
23127ec681f3Smrg   ANV_CMD_DIRTY_XFB_ENABLE                          = 1 << 12,
23137ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE                = 1 << 13, /* VK_DYNAMIC_STATE_LINE_STIPPLE_EXT */
23147ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_CULL_MODE                   = 1 << 14, /* VK_DYNAMIC_STATE_CULL_MODE_EXT */
23157ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE                  = 1 << 15, /* VK_DYNAMIC_STATE_FRONT_FACE_EXT */
23167ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY          = 1 << 16, /* VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT */
23177ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE = 1 << 17, /* VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT */
23187ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE           = 1 << 18, /* VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT */
23197ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE          = 1 << 19, /* VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT */
23207ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP            = 1 << 20, /* VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT */
23217ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE    = 1 << 21, /* VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT */
23227ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE         = 1 << 22, /* VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT */
23237ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP                  = 1 << 23, /* VK_DYNAMIC_STATE_STENCIL_OP_EXT */
23247ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS            = 1 << 24, /* VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT */
23257ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE           = 1 << 25, /* VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT */
23267ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE                = 1 << 26, /* VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR */
23277ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE   = 1 << 27, /* VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT */
23287ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE           = 1 << 28, /* VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT */
23297ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP                    = 1 << 29, /* VK_DYNAMIC_STATE_LOGIC_OP_EXT */
23307ec681f3Smrg   ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE    = 1 << 30, /* VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT */
233101e04c3fSmrg};
233201e04c3fSmrgtypedef uint32_t anv_cmd_dirty_mask_t;
233301e04c3fSmrg
23347ec681f3Smrg#define ANV_CMD_DIRTY_DYNAMIC_ALL                       \
23357ec681f3Smrg   (ANV_CMD_DIRTY_DYNAMIC_VIEWPORT |                    \
23367ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_SCISSOR |                     \
23377ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH |                  \
23387ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS |                  \
23397ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS |             \
23407ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS |                \
23417ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK |        \
23427ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK |          \
23437ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE |           \
23447ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE |                \
23457ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_CULL_MODE |                   \
23467ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE |                  \
23477ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY |          \
23487ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE | \
23497ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE |           \
23507ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE |          \
23517ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP |            \
23527ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE |    \
23537ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE |         \
23547ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP |                  \
23557ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS |            \
23567ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE |           \
23577ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE |                \
23587ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE |   \
23597ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE |           \
23607ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP |                    \
23617ec681f3Smrg    ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)
23627ec681f3Smrg
23637ec681f3Smrgstatic inline enum anv_cmd_dirty_bits
23647ec681f3Smrganv_cmd_dirty_bit_for_vk_dynamic_state(VkDynamicState vk_state)
23657ec681f3Smrg{
23667ec681f3Smrg   switch (vk_state) {
23677ec681f3Smrg   case VK_DYNAMIC_STATE_VIEWPORT:
23687ec681f3Smrg   case VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT:
23697ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
23707ec681f3Smrg   case VK_DYNAMIC_STATE_SCISSOR:
23717ec681f3Smrg   case VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT:
23727ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
23737ec681f3Smrg   case VK_DYNAMIC_STATE_LINE_WIDTH:
23747ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH;
23757ec681f3Smrg   case VK_DYNAMIC_STATE_DEPTH_BIAS:
23767ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
23777ec681f3Smrg   case VK_DYNAMIC_STATE_BLEND_CONSTANTS:
23787ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
23797ec681f3Smrg   case VK_DYNAMIC_STATE_DEPTH_BOUNDS:
23807ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS;
23817ec681f3Smrg   case VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK:
23827ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK;
23837ec681f3Smrg   case VK_DYNAMIC_STATE_STENCIL_WRITE_MASK:
23847ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK;
23857ec681f3Smrg   case VK_DYNAMIC_STATE_STENCIL_REFERENCE:
23867ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
23877ec681f3Smrg   case VK_DYNAMIC_STATE_LINE_STIPPLE_EXT:
23887ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE;
23897ec681f3Smrg   case VK_DYNAMIC_STATE_CULL_MODE_EXT:
23907ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_CULL_MODE;
23917ec681f3Smrg   case VK_DYNAMIC_STATE_FRONT_FACE_EXT:
23927ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
23937ec681f3Smrg   case VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT:
23947ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY;
23957ec681f3Smrg   case VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT:
23967ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE;
23977ec681f3Smrg   case VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT:
23987ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE;
23997ec681f3Smrg   case VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT:
24007ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE;
24017ec681f3Smrg   case VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT:
24027ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP;
24037ec681f3Smrg   case VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT:
24047ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE;
24057ec681f3Smrg   case VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT:
24067ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE;
24077ec681f3Smrg   case VK_DYNAMIC_STATE_STENCIL_OP_EXT:
24087ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP;
24097ec681f3Smrg   case VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT:
24107ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;
24117ec681f3Smrg   case VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT:
24127ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE;
24137ec681f3Smrg   case VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR:
24147ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE;
24157ec681f3Smrg   case VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT:
24167ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE;
24177ec681f3Smrg   case VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT:
24187ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE;
24197ec681f3Smrg   case VK_DYNAMIC_STATE_LOGIC_OP_EXT:
24207ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP;
24217ec681f3Smrg   case VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT:
24227ec681f3Smrg      return ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
24237ec681f3Smrg   default:
24247ec681f3Smrg      assert(!"Unsupported dynamic state");
24257ec681f3Smrg      return 0;
24267ec681f3Smrg   }
24277ec681f3Smrg}
24287ec681f3Smrg
24297ec681f3Smrg
243001e04c3fSmrgenum anv_pipe_bits {
243101e04c3fSmrg   ANV_PIPE_DEPTH_CACHE_FLUSH_BIT            = (1 << 0),
243201e04c3fSmrg   ANV_PIPE_STALL_AT_SCOREBOARD_BIT          = (1 << 1),
243301e04c3fSmrg   ANV_PIPE_STATE_CACHE_INVALIDATE_BIT       = (1 << 2),
243401e04c3fSmrg   ANV_PIPE_CONSTANT_CACHE_INVALIDATE_BIT    = (1 << 3),
243501e04c3fSmrg   ANV_PIPE_VF_CACHE_INVALIDATE_BIT          = (1 << 4),
243601e04c3fSmrg   ANV_PIPE_DATA_CACHE_FLUSH_BIT             = (1 << 5),
24377ec681f3Smrg   ANV_PIPE_TILE_CACHE_FLUSH_BIT             = (1 << 6),
243801e04c3fSmrg   ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT     = (1 << 10),
243901e04c3fSmrg   ANV_PIPE_INSTRUCTION_CACHE_INVALIDATE_BIT = (1 << 11),
244001e04c3fSmrg   ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT    = (1 << 12),
244101e04c3fSmrg   ANV_PIPE_DEPTH_STALL_BIT                  = (1 << 13),
24427ec681f3Smrg
24437ec681f3Smrg   /* ANV_PIPE_HDC_PIPELINE_FLUSH_BIT is a precise way to ensure prior data
24447ec681f3Smrg    * cache work has completed.  Available on Gfx12+.  For earlier Gfx we
24457ec681f3Smrg    * must reinterpret this flush as ANV_PIPE_DATA_CACHE_FLUSH_BIT.
24467ec681f3Smrg    */
24477ec681f3Smrg   ANV_PIPE_HDC_PIPELINE_FLUSH_BIT           = (1 << 14),
244801e04c3fSmrg   ANV_PIPE_CS_STALL_BIT                     = (1 << 20),
24497ec681f3Smrg   ANV_PIPE_END_OF_PIPE_SYNC_BIT             = (1 << 21),
245001e04c3fSmrg
245101e04c3fSmrg   /* This bit does not exist directly in PIPE_CONTROL.  Instead it means that
245201e04c3fSmrg    * a flush has happened but not a CS stall.  The next time we do any sort
245301e04c3fSmrg    * of invalidation we need to insert a CS stall at that time.  Otherwise,
245401e04c3fSmrg    * we would have to CS stall on every flush which could be bad.
245501e04c3fSmrg    */
24567ec681f3Smrg   ANV_PIPE_NEEDS_END_OF_PIPE_SYNC_BIT       = (1 << 22),
245701e04c3fSmrg
245801e04c3fSmrg   /* This bit does not exist directly in PIPE_CONTROL. It means that render
24599f464c52Smaya    * target operations related to transfer commands with VkBuffer as
24609f464c52Smaya    * destination are ongoing. Some operations like copies on the command
24619f464c52Smaya    * streamer might need to be aware of this to trigger the appropriate stall
24629f464c52Smaya    * before they can proceed with the copy.
246301e04c3fSmrg    */
24647ec681f3Smrg   ANV_PIPE_RENDER_TARGET_BUFFER_WRITES      = (1 << 23),
24657ec681f3Smrg
24667ec681f3Smrg   /* This bit does not exist directly in PIPE_CONTROL. It means that Gfx12
24677ec681f3Smrg    * AUX-TT data has changed and we need to invalidate AUX-TT data.  This is
24687ec681f3Smrg    * done by writing the AUX-TT register.
24697ec681f3Smrg    */
24707ec681f3Smrg   ANV_PIPE_AUX_TABLE_INVALIDATE_BIT         = (1 << 24),
24717ec681f3Smrg
24727ec681f3Smrg   /* This bit does not exist directly in PIPE_CONTROL. It means that a
24737ec681f3Smrg    * PIPE_CONTROL with a post-sync operation will follow. This is used to
24747ec681f3Smrg    * implement a workaround for Gfx9.
24757ec681f3Smrg    */
24767ec681f3Smrg   ANV_PIPE_POST_SYNC_BIT                    = (1 << 25),
247701e04c3fSmrg};
247801e04c3fSmrg
247901e04c3fSmrg#define ANV_PIPE_FLUSH_BITS ( \
248001e04c3fSmrg   ANV_PIPE_DEPTH_CACHE_FLUSH_BIT | \
248101e04c3fSmrg   ANV_PIPE_DATA_CACHE_FLUSH_BIT | \
24827ec681f3Smrg   ANV_PIPE_HDC_PIPELINE_FLUSH_BIT | \
24837ec681f3Smrg   ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT | \
24847ec681f3Smrg   ANV_PIPE_TILE_CACHE_FLUSH_BIT)
248501e04c3fSmrg
248601e04c3fSmrg#define ANV_PIPE_STALL_BITS ( \
248701e04c3fSmrg   ANV_PIPE_STALL_AT_SCOREBOARD_BIT | \
248801e04c3fSmrg   ANV_PIPE_DEPTH_STALL_BIT | \
248901e04c3fSmrg   ANV_PIPE_CS_STALL_BIT)
249001e04c3fSmrg
249101e04c3fSmrg#define ANV_PIPE_INVALIDATE_BITS ( \
249201e04c3fSmrg   ANV_PIPE_STATE_CACHE_INVALIDATE_BIT | \
249301e04c3fSmrg   ANV_PIPE_CONSTANT_CACHE_INVALIDATE_BIT | \
249401e04c3fSmrg   ANV_PIPE_VF_CACHE_INVALIDATE_BIT | \
24957ec681f3Smrg   ANV_PIPE_HDC_PIPELINE_FLUSH_BIT | \
249601e04c3fSmrg   ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT | \
24977ec681f3Smrg   ANV_PIPE_INSTRUCTION_CACHE_INVALIDATE_BIT | \
24987ec681f3Smrg   ANV_PIPE_AUX_TABLE_INVALIDATE_BIT)
249901e04c3fSmrg
250001e04c3fSmrgstatic inline enum anv_pipe_bits
25017ec681f3Smrganv_pipe_flush_bits_for_access_flags(struct anv_device *device,
25027ec681f3Smrg                                     VkAccessFlags2KHR flags)
250301e04c3fSmrg{
250401e04c3fSmrg   enum anv_pipe_bits pipe_bits = 0;
250501e04c3fSmrg
25067ec681f3Smrg   u_foreach_bit64(b, flags) {
25077ec681f3Smrg      switch ((VkAccessFlags2KHR)BITFIELD64_BIT(b)) {
25087ec681f3Smrg      case VK_ACCESS_2_SHADER_WRITE_BIT_KHR:
25097ec681f3Smrg      case VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR:
25109f464c52Smaya         /* We're transitioning a buffer that was previously used as write
25119f464c52Smaya          * destination through the data port. To make its content available
25127ec681f3Smrg          * to future operations, flush the hdc pipeline.
25139f464c52Smaya          */
25147ec681f3Smrg         pipe_bits |= ANV_PIPE_HDC_PIPELINE_FLUSH_BIT;
251501e04c3fSmrg         break;
25167ec681f3Smrg      case VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR:
25179f464c52Smaya         /* We're transitioning a buffer that was previously used as render
25189f464c52Smaya          * target. To make its content available to future operations, flush
25199f464c52Smaya          * the render target cache.
25209f464c52Smaya          */
252101e04c3fSmrg         pipe_bits |= ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT;
252201e04c3fSmrg         break;
25237ec681f3Smrg      case VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR:
25249f464c52Smaya         /* We're transitioning a buffer that was previously used as depth
25259f464c52Smaya          * buffer. To make its content available to future operations, flush
25269f464c52Smaya          * the depth cache.
25279f464c52Smaya          */
252801e04c3fSmrg         pipe_bits |= ANV_PIPE_DEPTH_CACHE_FLUSH_BIT;
252901e04c3fSmrg         break;
25307ec681f3Smrg      case VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR:
25319f464c52Smaya         /* We're transitioning a buffer that was previously used as a
25329f464c52Smaya          * transfer write destination. Generic write operations include color
25339f464c52Smaya          * & depth operations as well as buffer operations like :
25349f464c52Smaya          *     - vkCmdClearColorImage()
25359f464c52Smaya          *     - vkCmdClearDepthStencilImage()
25369f464c52Smaya          *     - vkCmdBlitImage()
25379f464c52Smaya          *     - vkCmdCopy*(), vkCmdUpdate*(), vkCmdFill*()
25389f464c52Smaya          *
25399f464c52Smaya          * Most of these operations are implemented using Blorp which writes
25409f464c52Smaya          * through the render target, so flush that cache to make it visible
25419f464c52Smaya          * to future operations. And for depth related operations we also
25429f464c52Smaya          * need to flush the depth cache.
25439f464c52Smaya          */
254401e04c3fSmrg         pipe_bits |= ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT;
254501e04c3fSmrg         pipe_bits |= ANV_PIPE_DEPTH_CACHE_FLUSH_BIT;
254601e04c3fSmrg         break;
25477ec681f3Smrg      case VK_ACCESS_2_MEMORY_WRITE_BIT_KHR:
25489f464c52Smaya         /* We're transitioning a buffer for generic write operations. Flush
25499f464c52Smaya          * all the caches.
25509f464c52Smaya          */
255101e04c3fSmrg         pipe_bits |= ANV_PIPE_FLUSH_BITS;
255201e04c3fSmrg         break;
25537ec681f3Smrg      case VK_ACCESS_2_HOST_WRITE_BIT_KHR:
25547ec681f3Smrg         /* We're transitioning a buffer for access by CPU. Invalidate
25557ec681f3Smrg          * all the caches. Since data and tile caches don't have invalidate,
25567ec681f3Smrg          * we are forced to flush those as well.
25577ec681f3Smrg          */
25587ec681f3Smrg         pipe_bits |= ANV_PIPE_FLUSH_BITS;
25597ec681f3Smrg         pipe_bits |= ANV_PIPE_INVALIDATE_BITS;
25607ec681f3Smrg         break;
25617ec681f3Smrg      case VK_ACCESS_2_TRANSFORM_FEEDBACK_WRITE_BIT_EXT:
25627ec681f3Smrg      case VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT:
25637ec681f3Smrg         /* We're transitioning a buffer written either from VS stage or from
25647ec681f3Smrg          * the command streamer (see CmdEndTransformFeedbackEXT), we just
25657ec681f3Smrg          * need to stall the CS.
25667ec681f3Smrg          */
25677ec681f3Smrg         pipe_bits |= ANV_PIPE_CS_STALL_BIT;
25687ec681f3Smrg         break;
256901e04c3fSmrg      default:
257001e04c3fSmrg         break; /* Nothing to do */
257101e04c3fSmrg      }
257201e04c3fSmrg   }
257301e04c3fSmrg
257401e04c3fSmrg   return pipe_bits;
257501e04c3fSmrg}
257601e04c3fSmrg
257701e04c3fSmrgstatic inline enum anv_pipe_bits
25787ec681f3Smrganv_pipe_invalidate_bits_for_access_flags(struct anv_device *device,
25797ec681f3Smrg                                          VkAccessFlags2KHR flags)
258001e04c3fSmrg{
258101e04c3fSmrg   enum anv_pipe_bits pipe_bits = 0;
258201e04c3fSmrg
25837ec681f3Smrg   u_foreach_bit64(b, flags) {
25847ec681f3Smrg      switch ((VkAccessFlags2KHR)BITFIELD64_BIT(b)) {
25857ec681f3Smrg      case VK_ACCESS_2_INDIRECT_COMMAND_READ_BIT_KHR:
25869f464c52Smaya         /* Indirect draw commands take a buffer as input that we're going to
25879f464c52Smaya          * read from the command streamer to load some of the HW registers
25889f464c52Smaya          * (see genX_cmd_buffer.c:load_indirect_parameters). This requires a
25899f464c52Smaya          * command streamer stall so that all the cache flushes have
25909f464c52Smaya          * completed before the command streamer loads from memory.
25919f464c52Smaya          */
25929f464c52Smaya         pipe_bits |=  ANV_PIPE_CS_STALL_BIT;
25939f464c52Smaya         /* Indirect draw commands also set gl_BaseVertex & gl_BaseIndex
25949f464c52Smaya          * through a vertex buffer, so invalidate that cache.
25959f464c52Smaya          */
25969f464c52Smaya         pipe_bits |= ANV_PIPE_VF_CACHE_INVALIDATE_BIT;
25979f464c52Smaya         /* For CmdDipatchIndirect, we also load gl_NumWorkGroups through a
25989f464c52Smaya          * UBO from the buffer, so we need to invalidate constant cache.
25999f464c52Smaya          */
26009f464c52Smaya         pipe_bits |= ANV_PIPE_CONSTANT_CACHE_INVALIDATE_BIT;
26017ec681f3Smrg         pipe_bits |= ANV_PIPE_DATA_CACHE_FLUSH_BIT;
26027ec681f3Smrg         /* Tile cache flush needed For CmdDipatchIndirect since command
26037ec681f3Smrg          * streamer and vertex fetch aren't L3 coherent.
26047ec681f3Smrg          */
26057ec681f3Smrg         pipe_bits |= ANV_PIPE_TILE_CACHE_FLUSH_BIT;
26069f464c52Smaya         break;
26077ec681f3Smrg      case VK_ACCESS_2_INDEX_READ_BIT_KHR:
26087ec681f3Smrg      case VK_ACCESS_2_VERTEX_ATTRIBUTE_READ_BIT_KHR:
26099f464c52Smaya         /* We transitioning a buffer to be used for as input for vkCmdDraw*
26109f464c52Smaya          * commands, so we invalidate the VF cache to make sure there is no
26119f464c52Smaya          * stale data when we start rendering.
26129f464c52Smaya          */
261301e04c3fSmrg         pipe_bits |= ANV_PIPE_VF_CACHE_INVALIDATE_BIT;
261401e04c3fSmrg         break;
26157ec681f3Smrg      case VK_ACCESS_2_UNIFORM_READ_BIT_KHR:
26169f464c52Smaya         /* We transitioning a buffer to be used as uniform data. Because
26179f464c52Smaya          * uniform is accessed through the data port & sampler, we need to
26189f464c52Smaya          * invalidate the texture cache (sampler) & constant cache (data
26199f464c52Smaya          * port) to avoid stale data.
26209f464c52Smaya          */
262101e04c3fSmrg         pipe_bits |= ANV_PIPE_CONSTANT_CACHE_INVALIDATE_BIT;
26227ec681f3Smrg         if (device->physical->compiler->indirect_ubos_use_sampler)
26237ec681f3Smrg            pipe_bits |= ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT;
26247ec681f3Smrg         else
26257ec681f3Smrg            pipe_bits |= ANV_PIPE_HDC_PIPELINE_FLUSH_BIT;
262601e04c3fSmrg         break;
26277ec681f3Smrg      case VK_ACCESS_2_SHADER_READ_BIT_KHR:
26287ec681f3Smrg      case VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR:
26297ec681f3Smrg      case VK_ACCESS_2_TRANSFER_READ_BIT_KHR:
26309f464c52Smaya         /* Transitioning a buffer to be read through the sampler, so
26319f464c52Smaya          * invalidate the texture cache, we don't want any stale data.
26329f464c52Smaya          */
263301e04c3fSmrg         pipe_bits |= ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT;
263401e04c3fSmrg         break;
26357ec681f3Smrg      case VK_ACCESS_2_MEMORY_READ_BIT_KHR:
26369f464c52Smaya         /* Transitioning a buffer for generic read, invalidate all the
26379f464c52Smaya          * caches.
26389f464c52Smaya          */
263901e04c3fSmrg         pipe_bits |= ANV_PIPE_INVALIDATE_BITS;
264001e04c3fSmrg         break;
26417ec681f3Smrg      case VK_ACCESS_2_MEMORY_WRITE_BIT_KHR:
26429f464c52Smaya         /* Generic write, make sure all previously written things land in
26439f464c52Smaya          * memory.
26449f464c52Smaya          */
264501e04c3fSmrg         pipe_bits |= ANV_PIPE_FLUSH_BITS;
264601e04c3fSmrg         break;
26477ec681f3Smrg      case VK_ACCESS_2_CONDITIONAL_RENDERING_READ_BIT_EXT:
26487ec681f3Smrg      case VK_ACCESS_2_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT:
26497ec681f3Smrg         /* Transitioning a buffer for conditional rendering or transform
26507ec681f3Smrg          * feedback. We'll load the content of this buffer into HW registers
26517ec681f3Smrg          * using the command streamer, so we need to stall the command
26527ec681f3Smrg          * streamer , so we need to stall the command streamer to make sure
26539f464c52Smaya          * any in-flight flush operations have completed.
26549f464c52Smaya          */
26559f464c52Smaya         pipe_bits |= ANV_PIPE_CS_STALL_BIT;
26567ec681f3Smrg         pipe_bits |= ANV_PIPE_TILE_CACHE_FLUSH_BIT;
26577ec681f3Smrg         pipe_bits |= ANV_PIPE_DATA_CACHE_FLUSH_BIT;
26587ec681f3Smrg         break;
26597ec681f3Smrg      case VK_ACCESS_2_HOST_READ_BIT_KHR:
26607ec681f3Smrg         /* We're transitioning a buffer that was written by CPU.  Flush
26617ec681f3Smrg          * all the caches.
26627ec681f3Smrg          */
26637ec681f3Smrg         pipe_bits |= ANV_PIPE_FLUSH_BITS;
26649f464c52Smaya         break;
266501e04c3fSmrg      default:
266601e04c3fSmrg         break; /* Nothing to do */
266701e04c3fSmrg      }
266801e04c3fSmrg   }
266901e04c3fSmrg
267001e04c3fSmrg   return pipe_bits;
267101e04c3fSmrg}
267201e04c3fSmrg
267301e04c3fSmrg#define VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV (         \
267401e04c3fSmrg   VK_IMAGE_ASPECT_COLOR_BIT | \
267501e04c3fSmrg   VK_IMAGE_ASPECT_PLANE_0_BIT | \
267601e04c3fSmrg   VK_IMAGE_ASPECT_PLANE_1_BIT | \
267701e04c3fSmrg   VK_IMAGE_ASPECT_PLANE_2_BIT)
267801e04c3fSmrg#define VK_IMAGE_ASPECT_PLANES_BITS_ANV ( \
267901e04c3fSmrg   VK_IMAGE_ASPECT_PLANE_0_BIT | \
268001e04c3fSmrg   VK_IMAGE_ASPECT_PLANE_1_BIT | \
268101e04c3fSmrg   VK_IMAGE_ASPECT_PLANE_2_BIT)
268201e04c3fSmrg
268301e04c3fSmrgstruct anv_vertex_binding {
268401e04c3fSmrg   struct anv_buffer *                          buffer;
268501e04c3fSmrg   VkDeviceSize                                 offset;
26867ec681f3Smrg   VkDeviceSize                                 stride;
26877ec681f3Smrg   VkDeviceSize                                 size;
268801e04c3fSmrg};
268901e04c3fSmrg
26909f464c52Smayastruct anv_xfb_binding {
26919f464c52Smaya   struct anv_buffer *                          buffer;
26929f464c52Smaya   VkDeviceSize                                 offset;
26939f464c52Smaya   VkDeviceSize                                 size;
26949f464c52Smaya};
26959f464c52Smaya
26969f464c52Smayastruct anv_push_constants {
26977ec681f3Smrg   /** Push constant data provided by the client through vkPushConstants */
269801e04c3fSmrg   uint8_t client_data[MAX_PUSH_CONSTANTS_SIZE];
269901e04c3fSmrg
27007ec681f3Smrg   /** Dynamic offsets for dynamic UBOs and SSBOs */
27017ec681f3Smrg   uint32_t dynamic_offsets[MAX_DYNAMIC_BUFFERS];
27027ec681f3Smrg
27037ec681f3Smrg   /* Robust access pushed registers. */
27047ec681f3Smrg   uint64_t push_reg_mask[MESA_SHADER_STAGES];
27057ec681f3Smrg
27067ec681f3Smrg   /** Pad out to a multiple of 32 bytes */
27077ec681f3Smrg   uint32_t pad[2];
27087ec681f3Smrg
27097ec681f3Smrg   /* Base addresses for descriptor sets */
27107ec681f3Smrg   uint64_t desc_sets[MAX_SETS];
27117ec681f3Smrg
27127ec681f3Smrg   struct {
27137ec681f3Smrg      /** Base workgroup ID
27147ec681f3Smrg       *
27157ec681f3Smrg       * Used for vkCmdDispatchBase.
27167ec681f3Smrg       */
27177ec681f3Smrg      uint32_t base_work_group_id[3];
27187ec681f3Smrg
27197ec681f3Smrg      /** Subgroup ID
27207ec681f3Smrg       *
27217ec681f3Smrg       * This is never set by software but is implicitly filled out when
27227ec681f3Smrg       * uploading the push constants for compute shaders.
27237ec681f3Smrg       */
27247ec681f3Smrg      uint32_t subgroup_id;
27257ec681f3Smrg   } cs;
272601e04c3fSmrg};
272701e04c3fSmrg
272801e04c3fSmrgstruct anv_dynamic_state {
272901e04c3fSmrg   struct {
273001e04c3fSmrg      uint32_t                                  count;
273101e04c3fSmrg      VkViewport                                viewports[MAX_VIEWPORTS];
273201e04c3fSmrg   } viewport;
273301e04c3fSmrg
273401e04c3fSmrg   struct {
273501e04c3fSmrg      uint32_t                                  count;
273601e04c3fSmrg      VkRect2D                                  scissors[MAX_SCISSORS];
273701e04c3fSmrg   } scissor;
273801e04c3fSmrg
273901e04c3fSmrg   float                                        line_width;
274001e04c3fSmrg
274101e04c3fSmrg   struct {
274201e04c3fSmrg      float                                     bias;
274301e04c3fSmrg      float                                     clamp;
274401e04c3fSmrg      float                                     slope;
274501e04c3fSmrg   } depth_bias;
274601e04c3fSmrg
274701e04c3fSmrg   float                                        blend_constants[4];
274801e04c3fSmrg
274901e04c3fSmrg   struct {
275001e04c3fSmrg      float                                     min;
275101e04c3fSmrg      float                                     max;
275201e04c3fSmrg   } depth_bounds;
275301e04c3fSmrg
275401e04c3fSmrg   struct {
275501e04c3fSmrg      uint32_t                                  front;
275601e04c3fSmrg      uint32_t                                  back;
275701e04c3fSmrg   } stencil_compare_mask;
275801e04c3fSmrg
275901e04c3fSmrg   struct {
276001e04c3fSmrg      uint32_t                                  front;
276101e04c3fSmrg      uint32_t                                  back;
276201e04c3fSmrg   } stencil_write_mask;
276301e04c3fSmrg
276401e04c3fSmrg   struct {
276501e04c3fSmrg      uint32_t                                  front;
276601e04c3fSmrg      uint32_t                                  back;
276701e04c3fSmrg   } stencil_reference;
27687ec681f3Smrg
27697ec681f3Smrg   struct {
27707ec681f3Smrg      struct {
27717ec681f3Smrg         VkStencilOp fail_op;
27727ec681f3Smrg         VkStencilOp pass_op;
27737ec681f3Smrg         VkStencilOp depth_fail_op;
27747ec681f3Smrg         VkCompareOp compare_op;
27757ec681f3Smrg      } front;
27767ec681f3Smrg      struct {
27777ec681f3Smrg         VkStencilOp fail_op;
27787ec681f3Smrg         VkStencilOp pass_op;
27797ec681f3Smrg         VkStencilOp depth_fail_op;
27807ec681f3Smrg         VkCompareOp compare_op;
27817ec681f3Smrg      } back;
27827ec681f3Smrg   } stencil_op;
27837ec681f3Smrg
27847ec681f3Smrg   struct {
27857ec681f3Smrg      uint32_t                                  factor;
27867ec681f3Smrg      uint16_t                                  pattern;
27877ec681f3Smrg   } line_stipple;
27887ec681f3Smrg
27897ec681f3Smrg   struct {
27907ec681f3Smrg      uint32_t                                  samples;
27917ec681f3Smrg      VkSampleLocationEXT                       locations[MAX_SAMPLE_LOCATIONS];
27927ec681f3Smrg   } sample_locations;
27937ec681f3Smrg
27947ec681f3Smrg   VkExtent2D                                   fragment_shading_rate;
27957ec681f3Smrg
27967ec681f3Smrg   VkCullModeFlags                              cull_mode;
27977ec681f3Smrg   VkFrontFace                                  front_face;
27987ec681f3Smrg   VkPrimitiveTopology                          primitive_topology;
27997ec681f3Smrg   bool                                         depth_test_enable;
28007ec681f3Smrg   bool                                         depth_write_enable;
28017ec681f3Smrg   VkCompareOp                                  depth_compare_op;
28027ec681f3Smrg   bool                                         depth_bounds_test_enable;
28037ec681f3Smrg   bool                                         stencil_test_enable;
28047ec681f3Smrg   bool                                         raster_discard;
28057ec681f3Smrg   bool                                         depth_bias_enable;
28067ec681f3Smrg   bool                                         primitive_restart_enable;
28077ec681f3Smrg   VkLogicOp                                    logic_op;
28087ec681f3Smrg   bool                                         dyn_vbo_stride;
28097ec681f3Smrg   bool                                         dyn_vbo_size;
28107ec681f3Smrg
28117ec681f3Smrg   /* Bitfield, one bit per render target */
28127ec681f3Smrg   uint8_t                                      color_writes;
281301e04c3fSmrg};
281401e04c3fSmrg
281501e04c3fSmrgextern const struct anv_dynamic_state default_dynamic_state;
281601e04c3fSmrg
28177ec681f3Smrguint32_t anv_dynamic_state_copy(struct anv_dynamic_state *dest,
28187ec681f3Smrg                                const struct anv_dynamic_state *src,
28197ec681f3Smrg                                uint32_t copy_mask);
282001e04c3fSmrg
282101e04c3fSmrgstruct anv_surface_state {
282201e04c3fSmrg   struct anv_state state;
282301e04c3fSmrg   /** Address of the surface referred to by this state
282401e04c3fSmrg    *
282501e04c3fSmrg    * This address is relative to the start of the BO.
282601e04c3fSmrg    */
282701e04c3fSmrg   struct anv_address address;
282801e04c3fSmrg   /* Address of the aux surface, if any
282901e04c3fSmrg    *
283001e04c3fSmrg    * This field is ANV_NULL_ADDRESS if and only if no aux surface exists.
283101e04c3fSmrg    *
28327ec681f3Smrg    * With the exception of gfx8, the bottom 12 bits of this address' offset
283301e04c3fSmrg    * include extra aux information.
283401e04c3fSmrg    */
283501e04c3fSmrg   struct anv_address aux_address;
283601e04c3fSmrg   /* Address of the clear color, if any
283701e04c3fSmrg    *
283801e04c3fSmrg    * This address is relative to the start of the BO.
283901e04c3fSmrg    */
284001e04c3fSmrg   struct anv_address clear_address;
284101e04c3fSmrg};
284201e04c3fSmrg
284301e04c3fSmrg/**
284401e04c3fSmrg * Attachment state when recording a renderpass instance.
284501e04c3fSmrg *
284601e04c3fSmrg * The clear value is valid only if there exists a pending clear.
284701e04c3fSmrg */
284801e04c3fSmrgstruct anv_attachment_state {
284901e04c3fSmrg   enum isl_aux_usage                           aux_usage;
285001e04c3fSmrg   struct anv_surface_state                     color;
285101e04c3fSmrg   struct anv_surface_state                     input;
285201e04c3fSmrg
285301e04c3fSmrg   VkImageLayout                                current_layout;
28547ec681f3Smrg   VkImageLayout                                current_stencil_layout;
285501e04c3fSmrg   VkImageAspectFlags                           pending_clear_aspects;
285601e04c3fSmrg   VkImageAspectFlags                           pending_load_aspects;
285701e04c3fSmrg   bool                                         fast_clear;
285801e04c3fSmrg   VkClearValue                                 clear_value;
285901e04c3fSmrg
286001e04c3fSmrg   /* When multiview is active, attachments with a renderpass clear
286101e04c3fSmrg    * operation have their respective layers cleared on the first
286201e04c3fSmrg    * subpass that uses them, and only in that subpass. We keep track
286301e04c3fSmrg    * of this using a bitfield to indicate which layers of an attachment
286401e04c3fSmrg    * have not been cleared yet when multiview is active.
286501e04c3fSmrg    */
286601e04c3fSmrg   uint32_t                                     pending_clear_views;
28677ec681f3Smrg   struct anv_image_view *                      image_view;
28687ec681f3Smrg};
28697ec681f3Smrg
28707ec681f3Smrg/** State tracking for vertex buffer flushes
28717ec681f3Smrg *
28727ec681f3Smrg * On Gfx8-9, the VF cache only considers the bottom 32 bits of memory
28737ec681f3Smrg * addresses.  If you happen to have two vertex buffers which get placed
28747ec681f3Smrg * exactly 4 GiB apart and use them in back-to-back draw calls, you can get
28757ec681f3Smrg * collisions.  In order to solve this problem, we track vertex address ranges
28767ec681f3Smrg * which are live in the cache and invalidate the cache if one ever exceeds 32
28777ec681f3Smrg * bits.
28787ec681f3Smrg */
28797ec681f3Smrgstruct anv_vb_cache_range {
28807ec681f3Smrg   /* Virtual address at which the live vertex buffer cache range starts for
28817ec681f3Smrg    * this vertex buffer index.
28827ec681f3Smrg    */
28837ec681f3Smrg   uint64_t start;
28847ec681f3Smrg
28857ec681f3Smrg   /* Virtual address of the byte after where vertex buffer cache range ends.
28867ec681f3Smrg    * This is exclusive such that end - start is the size of the range.
28877ec681f3Smrg    */
28887ec681f3Smrg   uint64_t end;
288901e04c3fSmrg};
289001e04c3fSmrg
289101e04c3fSmrg/** State tracking for particular pipeline bind point
289201e04c3fSmrg *
289301e04c3fSmrg * This struct is the base struct for anv_cmd_graphics_state and
289401e04c3fSmrg * anv_cmd_compute_state.  These are used to track state which is bound to a
289501e04c3fSmrg * particular type of pipeline.  Generic state that applies per-stage such as
289601e04c3fSmrg * binding table offsets and push constants is tracked generically with a
289701e04c3fSmrg * per-stage array in anv_cmd_state.
289801e04c3fSmrg */
289901e04c3fSmrgstruct anv_cmd_pipeline_state {
290001e04c3fSmrg   struct anv_descriptor_set *descriptors[MAX_SETS];
290101e04c3fSmrg   struct anv_push_descriptor_set *push_descriptors[MAX_SETS];
29027ec681f3Smrg
29037ec681f3Smrg   struct anv_push_constants push_constants;
29047ec681f3Smrg
29057ec681f3Smrg   /* Push constant state allocated when flushing push constants. */
29067ec681f3Smrg   struct anv_state          push_constants_state;
290701e04c3fSmrg};
290801e04c3fSmrg
290901e04c3fSmrg/** State tracking for graphics pipeline
291001e04c3fSmrg *
291101e04c3fSmrg * This has anv_cmd_pipeline_state as a base struct to track things which get
291201e04c3fSmrg * bound to a graphics pipeline.  Along with general pipeline bind point state
291301e04c3fSmrg * which is in the anv_cmd_pipeline_state base struct, it also contains other
291401e04c3fSmrg * state which is graphics-specific.
291501e04c3fSmrg */
291601e04c3fSmrgstruct anv_cmd_graphics_state {
291701e04c3fSmrg   struct anv_cmd_pipeline_state base;
291801e04c3fSmrg
29197ec681f3Smrg   struct anv_graphics_pipeline *pipeline;
29207ec681f3Smrg
292101e04c3fSmrg   anv_cmd_dirty_mask_t dirty;
292201e04c3fSmrg   uint32_t vb_dirty;
292301e04c3fSmrg
29247ec681f3Smrg   struct anv_vb_cache_range ib_bound_range;
29257ec681f3Smrg   struct anv_vb_cache_range ib_dirty_range;
29267ec681f3Smrg   struct anv_vb_cache_range vb_bound_ranges[33];
29277ec681f3Smrg   struct anv_vb_cache_range vb_dirty_ranges[33];
29287ec681f3Smrg
29297ec681f3Smrg   VkShaderStageFlags push_constant_stages;
29307ec681f3Smrg
293101e04c3fSmrg   struct anv_dynamic_state dynamic;
293201e04c3fSmrg
29337ec681f3Smrg   uint32_t primitive_topology;
29347ec681f3Smrg
293501e04c3fSmrg   struct {
293601e04c3fSmrg      struct anv_buffer *index_buffer;
293701e04c3fSmrg      uint32_t index_type; /**< 3DSTATE_INDEX_BUFFER.IndexFormat */
293801e04c3fSmrg      uint32_t index_offset;
29397ec681f3Smrg   } gfx7;
29407ec681f3Smrg};
29417ec681f3Smrg
29427ec681f3Smrgenum anv_depth_reg_mode {
29437ec681f3Smrg   ANV_DEPTH_REG_MODE_UNKNOWN = 0,
29447ec681f3Smrg   ANV_DEPTH_REG_MODE_HW_DEFAULT,
29457ec681f3Smrg   ANV_DEPTH_REG_MODE_D16,
294601e04c3fSmrg};
294701e04c3fSmrg
294801e04c3fSmrg/** State tracking for compute pipeline
294901e04c3fSmrg *
295001e04c3fSmrg * This has anv_cmd_pipeline_state as a base struct to track things which get
295101e04c3fSmrg * bound to a compute pipeline.  Along with general pipeline bind point state
295201e04c3fSmrg * which is in the anv_cmd_pipeline_state base struct, it also contains other
295301e04c3fSmrg * state which is compute-specific.
295401e04c3fSmrg */
295501e04c3fSmrgstruct anv_cmd_compute_state {
295601e04c3fSmrg   struct anv_cmd_pipeline_state base;
295701e04c3fSmrg
29587ec681f3Smrg   struct anv_compute_pipeline *pipeline;
29597ec681f3Smrg
296001e04c3fSmrg   bool pipeline_dirty;
296101e04c3fSmrg
29627ec681f3Smrg   struct anv_state push_data;
29637ec681f3Smrg
296401e04c3fSmrg   struct anv_address num_workgroups;
296501e04c3fSmrg};
296601e04c3fSmrg
29677ec681f3Smrgstruct anv_cmd_ray_tracing_state {
29687ec681f3Smrg   struct anv_cmd_pipeline_state base;
29697ec681f3Smrg
29707ec681f3Smrg   struct anv_ray_tracing_pipeline *pipeline;
29717ec681f3Smrg
29727ec681f3Smrg   bool pipeline_dirty;
29737ec681f3Smrg
29747ec681f3Smrg   struct {
29757ec681f3Smrg      struct anv_bo *bo;
29767ec681f3Smrg      struct brw_rt_scratch_layout layout;
29777ec681f3Smrg   } scratch;
29787ec681f3Smrg};
29797ec681f3Smrg
298001e04c3fSmrg/** State required while building cmd buffer */
298101e04c3fSmrgstruct anv_cmd_state {
298201e04c3fSmrg   /* PIPELINE_SELECT.PipelineSelection */
298301e04c3fSmrg   uint32_t                                     current_pipeline;
29847ec681f3Smrg   const struct intel_l3_config *               current_l3_config;
29857ec681f3Smrg   uint32_t                                     last_aux_map_state;
298601e04c3fSmrg
298701e04c3fSmrg   struct anv_cmd_graphics_state                gfx;
298801e04c3fSmrg   struct anv_cmd_compute_state                 compute;
29897ec681f3Smrg   struct anv_cmd_ray_tracing_state             rt;
299001e04c3fSmrg
299101e04c3fSmrg   enum anv_pipe_bits                           pending_pipe_bits;
299201e04c3fSmrg   VkShaderStageFlags                           descriptors_dirty;
299301e04c3fSmrg   VkShaderStageFlags                           push_constants_dirty;
299401e04c3fSmrg
299501e04c3fSmrg   struct anv_framebuffer *                     framebuffer;
299601e04c3fSmrg   struct anv_render_pass *                     pass;
299701e04c3fSmrg   struct anv_subpass *                         subpass;
299801e04c3fSmrg   VkRect2D                                     render_area;
299901e04c3fSmrg   uint32_t                                     restart_index;
300001e04c3fSmrg   struct anv_vertex_binding                    vertex_bindings[MAX_VBS];
30019f464c52Smaya   bool                                         xfb_enabled;
30029f464c52Smaya   struct anv_xfb_binding                       xfb_bindings[MAX_XFB_BUFFERS];
30037ec681f3Smrg   struct anv_state                             binding_tables[MESA_VULKAN_SHADER_STAGES];
30047ec681f3Smrg   struct anv_state                             samplers[MESA_VULKAN_SHADER_STAGES];
30057ec681f3Smrg
30067ec681f3Smrg   unsigned char                                sampler_sha1s[MESA_SHADER_STAGES][20];
30077ec681f3Smrg   unsigned char                                surface_sha1s[MESA_SHADER_STAGES][20];
30087ec681f3Smrg   unsigned char                                push_sha1s[MESA_SHADER_STAGES][20];
300901e04c3fSmrg
301001e04c3fSmrg   /**
30117ec681f3Smrg    * Whether or not the gfx8 PMA fix is enabled.  We ensure that, at the top
301201e04c3fSmrg    * of any command buffer it is disabled by disabling it in EndCommandBuffer
301301e04c3fSmrg    * and before invoking the secondary in ExecuteCommands.
301401e04c3fSmrg    */
301501e04c3fSmrg   bool                                         pma_fix_enabled;
301601e04c3fSmrg
301701e04c3fSmrg   /**
301801e04c3fSmrg    * Whether or not we know for certain that HiZ is enabled for the current
301901e04c3fSmrg    * subpass.  If, for whatever reason, we are unsure as to whether HiZ is
302001e04c3fSmrg    * enabled or not, this will be false.
302101e04c3fSmrg    */
302201e04c3fSmrg   bool                                         hiz_enabled;
302301e04c3fSmrg
30247ec681f3Smrg   /* We ensure the registers for the gfx12 D16 fix are initalized at the
30257ec681f3Smrg    * first non-NULL depth stencil packet emission of every command buffer.
30267ec681f3Smrg    * For secondary command buffer execution, we transfer the state from the
30277ec681f3Smrg    * last command buffer to the primary (if known).
30287ec681f3Smrg    */
30297ec681f3Smrg   enum anv_depth_reg_mode                      depth_reg_mode;
30307ec681f3Smrg
30319f464c52Smaya   bool                                         conditional_render_enabled;
30329f464c52Smaya
30337ec681f3Smrg   /**
30347ec681f3Smrg    * Last rendering scale argument provided to
30357ec681f3Smrg    * genX(cmd_buffer_emit_hashing_mode)().
30367ec681f3Smrg    */
30377ec681f3Smrg   unsigned                                     current_hash_scale;
30387ec681f3Smrg
303901e04c3fSmrg   /**
304001e04c3fSmrg    * Array length is anv_cmd_state::pass::attachment_count. Array content is
304101e04c3fSmrg    * valid only when recording a render pass instance.
304201e04c3fSmrg    */
304301e04c3fSmrg   struct anv_attachment_state *                attachments;
304401e04c3fSmrg
304501e04c3fSmrg   /**
304601e04c3fSmrg    * Surface states for color render targets.  These are stored in a single
304701e04c3fSmrg    * flat array.  For depth-stencil attachments, the surface state is simply
304801e04c3fSmrg    * left blank.
304901e04c3fSmrg    */
30507ec681f3Smrg   struct anv_state                             attachment_states;
305101e04c3fSmrg
305201e04c3fSmrg   /**
305301e04c3fSmrg    * A null surface state of the right size to match the framebuffer.  This
30547ec681f3Smrg    * is one of the states in attachment_states.
305501e04c3fSmrg    */
305601e04c3fSmrg   struct anv_state                             null_surface_state;
305701e04c3fSmrg};
305801e04c3fSmrg
305901e04c3fSmrgstruct anv_cmd_pool {
30607ec681f3Smrg   struct vk_object_base                        base;
306101e04c3fSmrg   VkAllocationCallbacks                        alloc;
306201e04c3fSmrg   struct list_head                             cmd_buffers;
30637ec681f3Smrg
30647ec681f3Smrg   VkCommandPoolCreateFlags                     flags;
30657ec681f3Smrg   struct anv_queue_family *                    queue_family;
306601e04c3fSmrg};
306701e04c3fSmrg
30687ec681f3Smrg#define ANV_MIN_CMD_BUFFER_BATCH_SIZE 8192
30697ec681f3Smrg#define ANV_MAX_CMD_BUFFER_BATCH_SIZE (16 * 1024 * 1024)
307001e04c3fSmrg
307101e04c3fSmrgenum anv_cmd_buffer_exec_mode {
307201e04c3fSmrg   ANV_CMD_BUFFER_EXEC_MODE_PRIMARY,
307301e04c3fSmrg   ANV_CMD_BUFFER_EXEC_MODE_EMIT,
307401e04c3fSmrg   ANV_CMD_BUFFER_EXEC_MODE_GROW_AND_EMIT,
307501e04c3fSmrg   ANV_CMD_BUFFER_EXEC_MODE_CHAIN,
307601e04c3fSmrg   ANV_CMD_BUFFER_EXEC_MODE_COPY_AND_CHAIN,
30777ec681f3Smrg   ANV_CMD_BUFFER_EXEC_MODE_CALL_AND_RETURN,
307801e04c3fSmrg};
307901e04c3fSmrg
30807ec681f3Smrgstruct anv_measure_batch;
30817ec681f3Smrg
308201e04c3fSmrgstruct anv_cmd_buffer {
30837ec681f3Smrg   struct vk_command_buffer                     vk;
308401e04c3fSmrg
308501e04c3fSmrg   struct anv_device *                          device;
308601e04c3fSmrg
308701e04c3fSmrg   struct anv_cmd_pool *                        pool;
308801e04c3fSmrg   struct list_head                             pool_link;
308901e04c3fSmrg
309001e04c3fSmrg   struct anv_batch                             batch;
309101e04c3fSmrg
30927ec681f3Smrg   /* Pointer to the location in the batch where MI_BATCH_BUFFER_END was
30937ec681f3Smrg    * recorded upon calling vkEndCommandBuffer(). This is useful if we need to
30947ec681f3Smrg    * rewrite the end to chain multiple batch together at vkQueueSubmit().
30957ec681f3Smrg    */
30967ec681f3Smrg   void *                                       batch_end;
30977ec681f3Smrg
309801e04c3fSmrg   /* Fields required for the actual chain of anv_batch_bo's.
309901e04c3fSmrg    *
310001e04c3fSmrg    * These fields are initialized by anv_cmd_buffer_init_batch_bo_chain().
310101e04c3fSmrg    */
310201e04c3fSmrg   struct list_head                             batch_bos;
310301e04c3fSmrg   enum anv_cmd_buffer_exec_mode                exec_mode;
310401e04c3fSmrg
310501e04c3fSmrg   /* A vector of anv_batch_bo pointers for every batch or surface buffer
310601e04c3fSmrg    * referenced by this command buffer
310701e04c3fSmrg    *
310801e04c3fSmrg    * initialized by anv_cmd_buffer_init_batch_bo_chain()
310901e04c3fSmrg    */
311001e04c3fSmrg   struct u_vector                            seen_bbos;
311101e04c3fSmrg
311201e04c3fSmrg   /* A vector of int32_t's for every block of binding tables.
311301e04c3fSmrg    *
311401e04c3fSmrg    * initialized by anv_cmd_buffer_init_batch_bo_chain()
311501e04c3fSmrg    */
311601e04c3fSmrg   struct u_vector                              bt_block_states;
31177ec681f3Smrg   struct anv_state                             bt_next;
311801e04c3fSmrg
311901e04c3fSmrg   struct anv_reloc_list                        surface_relocs;
312001e04c3fSmrg   /** Last seen surface state block pool center bo offset */
312101e04c3fSmrg   uint32_t                                     last_ss_pool_center;
312201e04c3fSmrg
312301e04c3fSmrg   /* Serial for tracking buffer completion */
312401e04c3fSmrg   uint32_t                                     serial;
312501e04c3fSmrg
312601e04c3fSmrg   /* Stream objects for storing temporary data */
312701e04c3fSmrg   struct anv_state_stream                      surface_state_stream;
312801e04c3fSmrg   struct anv_state_stream                      dynamic_state_stream;
31297ec681f3Smrg   struct anv_state_stream                      general_state_stream;
313001e04c3fSmrg
313101e04c3fSmrg   VkCommandBufferUsageFlags                    usage_flags;
313201e04c3fSmrg   VkCommandBufferLevel                         level;
313301e04c3fSmrg
31347ec681f3Smrg   struct anv_query_pool                       *perf_query_pool;
31357ec681f3Smrg
313601e04c3fSmrg   struct anv_cmd_state                         state;
31377ec681f3Smrg
31387ec681f3Smrg   struct anv_address                           return_addr;
31397ec681f3Smrg
31407ec681f3Smrg   /* Set by SetPerformanceMarkerINTEL, written into queries by CmdBeginQuery */
31417ec681f3Smrg   uint64_t                                     intel_perf_marker;
31427ec681f3Smrg
31437ec681f3Smrg   struct anv_measure_batch *measure;
31447ec681f3Smrg
31457ec681f3Smrg   /**
31467ec681f3Smrg    * KHR_performance_query requires self modifying command buffers and this
31477ec681f3Smrg    * array has the location of modifying commands to the query begin and end
31487ec681f3Smrg    * instructions storing performance counters. The array length is
31497ec681f3Smrg    * anv_physical_device::n_perf_query_commands.
31507ec681f3Smrg    */
31517ec681f3Smrg   struct mi_address_token                  *self_mod_locations;
31527ec681f3Smrg
31537ec681f3Smrg   /**
31547ec681f3Smrg    * Index tracking which of the self_mod_locations items have already been
31557ec681f3Smrg    * used.
31567ec681f3Smrg    */
31577ec681f3Smrg   uint32_t                                      perf_reloc_idx;
31587ec681f3Smrg
31597ec681f3Smrg   /**
31607ec681f3Smrg    * Sum of all the anv_batch_bo sizes allocated for this command buffer.
31617ec681f3Smrg    * Used to increase allocation size for long command buffers.
31627ec681f3Smrg    */
31637ec681f3Smrg   uint32_t                                     total_batch_size;
316401e04c3fSmrg};
316501e04c3fSmrg
31667ec681f3Smrg/* Determine whether we can chain a given cmd_buffer to another one. We need
31677ec681f3Smrg * softpin and we also need to make sure that we can edit the end of the batch
31687ec681f3Smrg * to point to next one, which requires the command buffer to not be used
31697ec681f3Smrg * simultaneously.
31707ec681f3Smrg */
31717ec681f3Smrgstatic inline bool
31727ec681f3Smrganv_cmd_buffer_is_chainable(struct anv_cmd_buffer *cmd_buffer)
31737ec681f3Smrg{
31747ec681f3Smrg   return anv_use_softpin(cmd_buffer->device->physical) &&
31757ec681f3Smrg      !(cmd_buffer->usage_flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT);
31767ec681f3Smrg}
31777ec681f3Smrg
317801e04c3fSmrgVkResult anv_cmd_buffer_init_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer);
317901e04c3fSmrgvoid anv_cmd_buffer_fini_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer);
318001e04c3fSmrgvoid anv_cmd_buffer_reset_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer);
318101e04c3fSmrgvoid anv_cmd_buffer_end_batch_buffer(struct anv_cmd_buffer *cmd_buffer);
318201e04c3fSmrgvoid anv_cmd_buffer_add_secondary(struct anv_cmd_buffer *primary,
318301e04c3fSmrg                                  struct anv_cmd_buffer *secondary);
318401e04c3fSmrgvoid anv_cmd_buffer_prepare_execbuf(struct anv_cmd_buffer *cmd_buffer);
31857ec681f3SmrgVkResult anv_cmd_buffer_execbuf(struct anv_queue *queue,
318601e04c3fSmrg                                struct anv_cmd_buffer *cmd_buffer,
318701e04c3fSmrg                                const VkSemaphore *in_semaphores,
31887ec681f3Smrg                                const uint64_t *in_wait_values,
318901e04c3fSmrg                                uint32_t num_in_semaphores,
319001e04c3fSmrg                                const VkSemaphore *out_semaphores,
31917ec681f3Smrg                                const uint64_t *out_signal_values,
319201e04c3fSmrg                                uint32_t num_out_semaphores,
31937ec681f3Smrg                                VkFence fence,
31947ec681f3Smrg                                int perf_query_pass);
319501e04c3fSmrg
319601e04c3fSmrgVkResult anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer);
319701e04c3fSmrg
319801e04c3fSmrgstruct anv_state anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
319901e04c3fSmrg                                             const void *data, uint32_t size, uint32_t alignment);
320001e04c3fSmrgstruct anv_state anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
320101e04c3fSmrg                                              uint32_t *a, uint32_t *b,
320201e04c3fSmrg                                              uint32_t dwords, uint32_t alignment);
320301e04c3fSmrg
320401e04c3fSmrgstruct anv_address
320501e04c3fSmrganv_cmd_buffer_surface_base_address(struct anv_cmd_buffer *cmd_buffer);
320601e04c3fSmrgstruct anv_state
320701e04c3fSmrganv_cmd_buffer_alloc_binding_table(struct anv_cmd_buffer *cmd_buffer,
320801e04c3fSmrg                                   uint32_t entries, uint32_t *state_offset);
320901e04c3fSmrgstruct anv_state
321001e04c3fSmrganv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer *cmd_buffer);
321101e04c3fSmrgstruct anv_state
321201e04c3fSmrganv_cmd_buffer_alloc_dynamic_state(struct anv_cmd_buffer *cmd_buffer,
321301e04c3fSmrg                                   uint32_t size, uint32_t alignment);
321401e04c3fSmrg
321501e04c3fSmrgVkResult
321601e04c3fSmrganv_cmd_buffer_new_binding_table_block(struct anv_cmd_buffer *cmd_buffer);
321701e04c3fSmrg
32187ec681f3Smrgvoid gfx8_cmd_buffer_emit_viewport(struct anv_cmd_buffer *cmd_buffer);
32197ec681f3Smrgvoid gfx8_cmd_buffer_emit_depth_viewport(struct anv_cmd_buffer *cmd_buffer,
322001e04c3fSmrg                                         bool depth_clamp_enable);
32217ec681f3Smrgvoid gfx7_cmd_buffer_emit_scissor(struct anv_cmd_buffer *cmd_buffer);
322201e04c3fSmrg
322301e04c3fSmrgvoid anv_cmd_buffer_setup_attachments(struct anv_cmd_buffer *cmd_buffer,
322401e04c3fSmrg                                      struct anv_render_pass *pass,
322501e04c3fSmrg                                      struct anv_framebuffer *framebuffer,
322601e04c3fSmrg                                      const VkClearValue *clear_values);
322701e04c3fSmrg
322801e04c3fSmrgvoid anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer);
322901e04c3fSmrg
323001e04c3fSmrgstruct anv_state
32317ec681f3Smrganv_cmd_buffer_gfx_push_constants(struct anv_cmd_buffer *cmd_buffer);
323201e04c3fSmrgstruct anv_state
323301e04c3fSmrganv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer);
323401e04c3fSmrg
323501e04c3fSmrgconst struct anv_image_view *
323601e04c3fSmrganv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer);
323701e04c3fSmrg
323801e04c3fSmrgVkResult
323901e04c3fSmrganv_cmd_buffer_alloc_blorp_binding_table(struct anv_cmd_buffer *cmd_buffer,
324001e04c3fSmrg                                         uint32_t num_entries,
324101e04c3fSmrg                                         uint32_t *state_offset,
324201e04c3fSmrg                                         struct anv_state *bt_state);
324301e04c3fSmrg
324401e04c3fSmrgvoid anv_cmd_buffer_dump(struct anv_cmd_buffer *cmd_buffer);
324501e04c3fSmrg
32469f464c52Smayavoid anv_cmd_emit_conditional_render_predicate(struct anv_cmd_buffer *cmd_buffer);
32479f464c52Smaya
324801e04c3fSmrgenum anv_fence_type {
324901e04c3fSmrg   ANV_FENCE_TYPE_NONE = 0,
325001e04c3fSmrg   ANV_FENCE_TYPE_BO,
32517ec681f3Smrg   ANV_FENCE_TYPE_WSI_BO,
325201e04c3fSmrg   ANV_FENCE_TYPE_SYNCOBJ,
325301e04c3fSmrg   ANV_FENCE_TYPE_WSI,
325401e04c3fSmrg};
325501e04c3fSmrg
325601e04c3fSmrgenum anv_bo_fence_state {
325701e04c3fSmrg   /** Indicates that this is a new (or newly reset fence) */
325801e04c3fSmrg   ANV_BO_FENCE_STATE_RESET,
325901e04c3fSmrg
326001e04c3fSmrg   /** Indicates that this fence has been submitted to the GPU but is still
326101e04c3fSmrg    * (as far as we know) in use by the GPU.
326201e04c3fSmrg    */
326301e04c3fSmrg   ANV_BO_FENCE_STATE_SUBMITTED,
326401e04c3fSmrg
326501e04c3fSmrg   ANV_BO_FENCE_STATE_SIGNALED,
326601e04c3fSmrg};
326701e04c3fSmrg
326801e04c3fSmrgstruct anv_fence_impl {
326901e04c3fSmrg   enum anv_fence_type type;
327001e04c3fSmrg
327101e04c3fSmrg   union {
327201e04c3fSmrg      /** Fence implementation for BO fences
327301e04c3fSmrg       *
327401e04c3fSmrg       * These fences use a BO and a set of CPU-tracked state flags.  The BO
327501e04c3fSmrg       * is added to the object list of the last execbuf call in a QueueSubmit
327601e04c3fSmrg       * and is marked EXEC_WRITE.  The state flags track when the BO has been
327701e04c3fSmrg       * submitted to the kernel.  We need to do this because Vulkan lets you
327801e04c3fSmrg       * wait on a fence that has not yet been submitted and I915_GEM_BUSY
327901e04c3fSmrg       * will say it's idle in this case.
328001e04c3fSmrg       */
328101e04c3fSmrg      struct {
32827ec681f3Smrg         struct anv_bo *bo;
328301e04c3fSmrg         enum anv_bo_fence_state state;
328401e04c3fSmrg      } bo;
328501e04c3fSmrg
328601e04c3fSmrg      /** DRM syncobj handle for syncobj-based fences */
328701e04c3fSmrg      uint32_t syncobj;
328801e04c3fSmrg
328901e04c3fSmrg      /** WSI fence */
329001e04c3fSmrg      struct wsi_fence *fence_wsi;
329101e04c3fSmrg   };
329201e04c3fSmrg};
329301e04c3fSmrg
329401e04c3fSmrgstruct anv_fence {
32957ec681f3Smrg   struct vk_object_base base;
32967ec681f3Smrg
329701e04c3fSmrg   /* Permanent fence state.  Every fence has some form of permanent state
329801e04c3fSmrg    * (type != ANV_SEMAPHORE_TYPE_NONE).  This may be a BO to fence on (for
329901e04c3fSmrg    * cross-process fences) or it could just be a dummy for use internally.
330001e04c3fSmrg    */
330101e04c3fSmrg   struct anv_fence_impl permanent;
330201e04c3fSmrg
330301e04c3fSmrg   /* Temporary fence state.  A fence *may* have temporary state.  That state
330401e04c3fSmrg    * is added to the fence by an import operation and is reset back to
330501e04c3fSmrg    * ANV_SEMAPHORE_TYPE_NONE when the fence is reset.  A fence with temporary
330601e04c3fSmrg    * state cannot be signaled because the fence must already be signaled
330701e04c3fSmrg    * before the temporary state can be exported from the fence in the other
330801e04c3fSmrg    * process and imported here.
330901e04c3fSmrg    */
331001e04c3fSmrg   struct anv_fence_impl temporary;
331101e04c3fSmrg};
331201e04c3fSmrg
33137ec681f3Smrgvoid anv_fence_reset_temporary(struct anv_device *device,
33147ec681f3Smrg                               struct anv_fence *fence);
33157ec681f3Smrg
331601e04c3fSmrgstruct anv_event {
33177ec681f3Smrg   struct vk_object_base                        base;
331801e04c3fSmrg   uint64_t                                     semaphore;
331901e04c3fSmrg   struct anv_state                             state;
332001e04c3fSmrg};
332101e04c3fSmrg
332201e04c3fSmrgenum anv_semaphore_type {
332301e04c3fSmrg   ANV_SEMAPHORE_TYPE_NONE = 0,
332401e04c3fSmrg   ANV_SEMAPHORE_TYPE_DUMMY,
33257ec681f3Smrg   ANV_SEMAPHORE_TYPE_WSI_BO,
332601e04c3fSmrg   ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ,
33277ec681f3Smrg   ANV_SEMAPHORE_TYPE_TIMELINE,
33287ec681f3Smrg   ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ_TIMELINE,
33297ec681f3Smrg};
33307ec681f3Smrg
33317ec681f3Smrgstruct anv_timeline_point {
33327ec681f3Smrg   struct list_head link;
33337ec681f3Smrg
33347ec681f3Smrg   uint64_t serial;
33357ec681f3Smrg
33367ec681f3Smrg   /* Number of waiter on this point, when > 0 the point should not be garbage
33377ec681f3Smrg    * collected.
33387ec681f3Smrg    */
33397ec681f3Smrg   int waiting;
33407ec681f3Smrg
33417ec681f3Smrg   /* BO used for synchronization. */
33427ec681f3Smrg   struct anv_bo *bo;
33437ec681f3Smrg};
33447ec681f3Smrg
33457ec681f3Smrgstruct anv_timeline {
33467ec681f3Smrg   pthread_mutex_t mutex;
33477ec681f3Smrg   pthread_cond_t  cond;
33487ec681f3Smrg
33497ec681f3Smrg   uint64_t highest_past;
33507ec681f3Smrg   uint64_t highest_pending;
33517ec681f3Smrg
33527ec681f3Smrg   struct list_head points;
33537ec681f3Smrg   struct list_head free_points;
335401e04c3fSmrg};
335501e04c3fSmrg
335601e04c3fSmrgstruct anv_semaphore_impl {
335701e04c3fSmrg   enum anv_semaphore_type type;
335801e04c3fSmrg
335901e04c3fSmrg   union {
33607ec681f3Smrg      /* A BO representing this semaphore when type == ANV_SEMAPHORE_TYPE_BO
33617ec681f3Smrg       * or type == ANV_SEMAPHORE_TYPE_WSI_BO.  This BO will be added to the
33627ec681f3Smrg       * object list on any execbuf2 calls for which this semaphore is used as
33637ec681f3Smrg       * a wait or signal fence.  When used as a signal fence or when type ==
33647ec681f3Smrg       * ANV_SEMAPHORE_TYPE_WSI_BO, the EXEC_OBJECT_WRITE flag will be set.
336501e04c3fSmrg       */
336601e04c3fSmrg      struct anv_bo *bo;
336701e04c3fSmrg
336801e04c3fSmrg      /* Sync object handle when type == ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ.
336901e04c3fSmrg       * Unlike GEM BOs, DRM sync objects aren't deduplicated by the kernel on
337001e04c3fSmrg       * import so we don't need to bother with a userspace cache.
337101e04c3fSmrg       */
337201e04c3fSmrg      uint32_t syncobj;
33737ec681f3Smrg
33747ec681f3Smrg      /* Non shareable timeline semaphore
33757ec681f3Smrg       *
33767ec681f3Smrg       * Used when kernel don't have support for timeline semaphores.
33777ec681f3Smrg       */
33787ec681f3Smrg      struct anv_timeline timeline;
337901e04c3fSmrg   };
338001e04c3fSmrg};
338101e04c3fSmrg
338201e04c3fSmrgstruct anv_semaphore {
33837ec681f3Smrg   struct vk_object_base base;
33847ec681f3Smrg
338501e04c3fSmrg   /* Permanent semaphore state.  Every semaphore has some form of permanent
338601e04c3fSmrg    * state (type != ANV_SEMAPHORE_TYPE_NONE).  This may be a BO to fence on
338701e04c3fSmrg    * (for cross-process semaphores0 or it could just be a dummy for use
338801e04c3fSmrg    * internally.
338901e04c3fSmrg    */
339001e04c3fSmrg   struct anv_semaphore_impl permanent;
339101e04c3fSmrg
339201e04c3fSmrg   /* Temporary semaphore state.  A semaphore *may* have temporary state.
339301e04c3fSmrg    * That state is added to the semaphore by an import operation and is reset
339401e04c3fSmrg    * back to ANV_SEMAPHORE_TYPE_NONE when the semaphore is waited on.  A
339501e04c3fSmrg    * semaphore with temporary state cannot be signaled because the semaphore
339601e04c3fSmrg    * must already be signaled before the temporary state can be exported from
339701e04c3fSmrg    * the semaphore in the other process and imported here.
339801e04c3fSmrg    */
339901e04c3fSmrg   struct anv_semaphore_impl temporary;
340001e04c3fSmrg};
340101e04c3fSmrg
340201e04c3fSmrgvoid anv_semaphore_reset_temporary(struct anv_device *device,
340301e04c3fSmrg                                   struct anv_semaphore *semaphore);
340401e04c3fSmrg
34057ec681f3Smrg#define ANV_STAGE_MASK ((1 << MESA_VULKAN_SHADER_STAGES) - 1)
340601e04c3fSmrg
340701e04c3fSmrg#define anv_foreach_stage(stage, stage_bits)                         \
340801e04c3fSmrg   for (gl_shader_stage stage,                                       \
340901e04c3fSmrg        __tmp = (gl_shader_stage)((stage_bits) & ANV_STAGE_MASK);    \
341001e04c3fSmrg        stage = __builtin_ffs(__tmp) - 1, __tmp;                     \
341101e04c3fSmrg        __tmp &= ~(1 << (stage)))
341201e04c3fSmrg
341301e04c3fSmrgstruct anv_pipeline_bind_map {
34147ec681f3Smrg   unsigned char                                surface_sha1[20];
34157ec681f3Smrg   unsigned char                                sampler_sha1[20];
34167ec681f3Smrg   unsigned char                                push_sha1[20];
34177ec681f3Smrg
341801e04c3fSmrg   uint32_t surface_count;
341901e04c3fSmrg   uint32_t sampler_count;
342001e04c3fSmrg
342101e04c3fSmrg   struct anv_pipeline_binding *                surface_to_descriptor;
342201e04c3fSmrg   struct anv_pipeline_binding *                sampler_to_descriptor;
34237ec681f3Smrg
34247ec681f3Smrg   struct anv_push_range                        push_ranges[4];
342501e04c3fSmrg};
342601e04c3fSmrg
342701e04c3fSmrgstruct anv_shader_bin_key {
342801e04c3fSmrg   uint32_t size;
342901e04c3fSmrg   uint8_t data[0];
343001e04c3fSmrg};
343101e04c3fSmrg
343201e04c3fSmrgstruct anv_shader_bin {
343301e04c3fSmrg   uint32_t ref_cnt;
343401e04c3fSmrg
34357ec681f3Smrg   gl_shader_stage stage;
34367ec681f3Smrg
343701e04c3fSmrg   const struct anv_shader_bin_key *key;
343801e04c3fSmrg
343901e04c3fSmrg   struct anv_state kernel;
344001e04c3fSmrg   uint32_t kernel_size;
344101e04c3fSmrg
344201e04c3fSmrg   const struct brw_stage_prog_data *prog_data;
344301e04c3fSmrg   uint32_t prog_data_size;
344401e04c3fSmrg
34457ec681f3Smrg   struct brw_compile_stats stats[3];
34467ec681f3Smrg   uint32_t num_stats;
34477ec681f3Smrg
34489f464c52Smaya   struct nir_xfb_info *xfb_info;
34499f464c52Smaya
345001e04c3fSmrg   struct anv_pipeline_bind_map bind_map;
345101e04c3fSmrg};
345201e04c3fSmrg
345301e04c3fSmrgstruct anv_shader_bin *
345401e04c3fSmrganv_shader_bin_create(struct anv_device *device,
34557ec681f3Smrg                      gl_shader_stage stage,
345601e04c3fSmrg                      const void *key, uint32_t key_size,
345701e04c3fSmrg                      const void *kernel, uint32_t kernel_size,
345801e04c3fSmrg                      const struct brw_stage_prog_data *prog_data,
34597ec681f3Smrg                      uint32_t prog_data_size,
34607ec681f3Smrg                      const struct brw_compile_stats *stats, uint32_t num_stats,
34619f464c52Smaya                      const struct nir_xfb_info *xfb_info,
346201e04c3fSmrg                      const struct anv_pipeline_bind_map *bind_map);
346301e04c3fSmrg
346401e04c3fSmrgvoid
346501e04c3fSmrganv_shader_bin_destroy(struct anv_device *device, struct anv_shader_bin *shader);
346601e04c3fSmrg
346701e04c3fSmrgstatic inline void
346801e04c3fSmrganv_shader_bin_ref(struct anv_shader_bin *shader)
346901e04c3fSmrg{
347001e04c3fSmrg   assert(shader && shader->ref_cnt >= 1);
347101e04c3fSmrg   p_atomic_inc(&shader->ref_cnt);
347201e04c3fSmrg}
347301e04c3fSmrg
347401e04c3fSmrgstatic inline void
347501e04c3fSmrganv_shader_bin_unref(struct anv_device *device, struct anv_shader_bin *shader)
347601e04c3fSmrg{
347701e04c3fSmrg   assert(shader && shader->ref_cnt >= 1);
347801e04c3fSmrg   if (p_atomic_dec_zero(&shader->ref_cnt))
347901e04c3fSmrg      anv_shader_bin_destroy(device, shader);
348001e04c3fSmrg}
348101e04c3fSmrg
34827ec681f3Smrg#define anv_shader_bin_get_bsr(bin, local_arg_offset) ({             \
34837ec681f3Smrg   assert((local_arg_offset) % 8 == 0);                              \
34847ec681f3Smrg   const struct brw_bs_prog_data *prog_data =                        \
34857ec681f3Smrg      brw_bs_prog_data_const(bin->prog_data);                        \
34867ec681f3Smrg   assert(prog_data->simd_size == 8 || prog_data->simd_size == 16);  \
34877ec681f3Smrg                                                                     \
34887ec681f3Smrg   (struct GFX_BINDLESS_SHADER_RECORD) {                             \
34897ec681f3Smrg      .OffsetToLocalArguments = (local_arg_offset) / 8,              \
34907ec681f3Smrg      .BindlessShaderDispatchMode =                                  \
34917ec681f3Smrg         prog_data->simd_size == 16 ? RT_SIMD16 : RT_SIMD8,          \
34927ec681f3Smrg      .KernelStartPointer = bin->kernel.offset,                      \
34937ec681f3Smrg   };                                                                \
34947ec681f3Smrg})
34957ec681f3Smrg
34967ec681f3Smrgstruct anv_pipeline_executable {
34977ec681f3Smrg   gl_shader_stage stage;
34987ec681f3Smrg
34997ec681f3Smrg   struct brw_compile_stats stats;
35007ec681f3Smrg
35017ec681f3Smrg   char *nir;
35027ec681f3Smrg   char *disasm;
35037ec681f3Smrg};
35047ec681f3Smrg
35057ec681f3Smrgenum anv_pipeline_type {
35067ec681f3Smrg   ANV_PIPELINE_GRAPHICS,
35077ec681f3Smrg   ANV_PIPELINE_COMPUTE,
35087ec681f3Smrg   ANV_PIPELINE_RAY_TRACING,
35097ec681f3Smrg};
35107ec681f3Smrg
351101e04c3fSmrgstruct anv_pipeline {
35127ec681f3Smrg   struct vk_object_base                        base;
35137ec681f3Smrg
351401e04c3fSmrg   struct anv_device *                          device;
35157ec681f3Smrg
351601e04c3fSmrg   struct anv_batch                             batch;
351701e04c3fSmrg   struct anv_reloc_list                        batch_relocs;
351801e04c3fSmrg
35197ec681f3Smrg   void *                                       mem_ctx;
352001e04c3fSmrg
35217ec681f3Smrg   enum anv_pipeline_type                       type;
35227ec681f3Smrg   VkPipelineCreateFlags                        flags;
352301e04c3fSmrg
35247ec681f3Smrg   struct util_dynarray                         executables;
352501e04c3fSmrg
35267ec681f3Smrg   const struct intel_l3_config *               l3_config;
35277ec681f3Smrg};
352801e04c3fSmrg
35297ec681f3Smrgstruct anv_graphics_pipeline {
35307ec681f3Smrg   struct anv_pipeline                          base;
353101e04c3fSmrg
35327ec681f3Smrg   uint32_t                                     batch_data[512];
35337ec681f3Smrg
35347ec681f3Smrg   /* States that are part of batch_data and should be not emitted
35357ec681f3Smrg    * dynamically.
35367ec681f3Smrg    */
35377ec681f3Smrg   anv_cmd_dirty_mask_t                         static_state_mask;
35387ec681f3Smrg
35397ec681f3Smrg   /* States that need to be reemitted in cmd_buffer_flush_dynamic_state().
35407ec681f3Smrg    * This might cover more than the dynamic states specified at pipeline
35417ec681f3Smrg    * creation.
35427ec681f3Smrg    */
35437ec681f3Smrg   anv_cmd_dirty_mask_t                         dynamic_state_mask;
354401e04c3fSmrg
35457ec681f3Smrg   struct anv_dynamic_state                     dynamic_state;
35467ec681f3Smrg
35477ec681f3Smrg   /* States declared dynamic at pipeline creation. */
35487ec681f3Smrg   anv_cmd_dirty_mask_t                         dynamic_states;
35499f464c52Smaya
355001e04c3fSmrg   uint32_t                                     topology;
355101e04c3fSmrg
35527ec681f3Smrg   /* These fields are required with dynamic primitive topology,
35537ec681f3Smrg    * rasterization_samples used only with gen < 8.
35547ec681f3Smrg    */
35557ec681f3Smrg   VkLineRasterizationModeEXT                   line_mode;
35567ec681f3Smrg   VkPolygonMode                                polygon_mode;
35577ec681f3Smrg   uint32_t                                     rasterization_samples;
35587ec681f3Smrg
35597ec681f3Smrg   struct anv_subpass *                         subpass;
35607ec681f3Smrg
35617ec681f3Smrg   struct anv_shader_bin *                      shaders[MESA_SHADER_STAGES];
35627ec681f3Smrg
35637ec681f3Smrg   VkShaderStageFlags                           active_stages;
356401e04c3fSmrg
356501e04c3fSmrg   bool                                         writes_depth;
356601e04c3fSmrg   bool                                         depth_test_enable;
356701e04c3fSmrg   bool                                         writes_stencil;
356801e04c3fSmrg   bool                                         stencil_test_enable;
356901e04c3fSmrg   bool                                         depth_clamp_enable;
35709f464c52Smaya   bool                                         depth_clip_enable;
357101e04c3fSmrg   bool                                         sample_shading_enable;
357201e04c3fSmrg   bool                                         kill_pixel;
35737ec681f3Smrg   bool                                         depth_bounds_test_enable;
35747ec681f3Smrg   bool                                         force_fragment_thread_dispatch;
35757ec681f3Smrg
35767ec681f3Smrg   /* When primitive replication is used, subpass->view_mask will describe what
35777ec681f3Smrg    * views to replicate.
35787ec681f3Smrg    */
35797ec681f3Smrg   bool                                         use_primitive_replication;
35807ec681f3Smrg
35817ec681f3Smrg   struct anv_state                             blend_state;
35827ec681f3Smrg
35837ec681f3Smrg   struct anv_state                             cps_state;
35847ec681f3Smrg
35857ec681f3Smrg   uint32_t                                     vb_used;
35867ec681f3Smrg   struct anv_pipeline_vertex_binding {
35877ec681f3Smrg      uint32_t                                  stride;
35887ec681f3Smrg      bool                                      instanced;
35897ec681f3Smrg      uint32_t                                  instance_divisor;
35907ec681f3Smrg   } vb[MAX_VBS];
359101e04c3fSmrg
359201e04c3fSmrg   struct {
359301e04c3fSmrg      uint32_t                                  sf[7];
359401e04c3fSmrg      uint32_t                                  depth_stencil_state[3];
35957ec681f3Smrg      uint32_t                                  clip[4];
35967ec681f3Smrg      uint32_t                                  xfb_bo_pitch[4];
35977ec681f3Smrg      uint32_t                                  wm[3];
35987ec681f3Smrg      uint32_t                                  blend_state[MAX_RTS * 2];
35997ec681f3Smrg      uint32_t                                  streamout_state[3];
36007ec681f3Smrg   } gfx7;
360101e04c3fSmrg
360201e04c3fSmrg   struct {
360301e04c3fSmrg      uint32_t                                  sf[4];
360401e04c3fSmrg      uint32_t                                  raster[5];
360501e04c3fSmrg      uint32_t                                  wm_depth_stencil[3];
36067ec681f3Smrg      uint32_t                                  wm[2];
36077ec681f3Smrg      uint32_t                                  ps_blend[2];
36087ec681f3Smrg      uint32_t                                  blend_state[1 + MAX_RTS * 2];
36097ec681f3Smrg      uint32_t                                  streamout_state[5];
36107ec681f3Smrg   } gfx8;
361101e04c3fSmrg
361201e04c3fSmrg   struct {
361301e04c3fSmrg      uint32_t                                  wm_depth_stencil[4];
36147ec681f3Smrg   } gfx9;
36157ec681f3Smrg};
36167ec681f3Smrg
36177ec681f3Smrgstruct anv_compute_pipeline {
36187ec681f3Smrg   struct anv_pipeline                          base;
361901e04c3fSmrg
36207ec681f3Smrg   struct anv_shader_bin *                      cs;
36217ec681f3Smrg   uint32_t                                     batch_data[9];
362201e04c3fSmrg   uint32_t                                     interface_descriptor_data[8];
362301e04c3fSmrg};
362401e04c3fSmrg
36257ec681f3Smrgstruct anv_rt_shader_group {
36267ec681f3Smrg   VkRayTracingShaderGroupTypeKHR type;
36277ec681f3Smrg
36287ec681f3Smrg   struct anv_shader_bin *general;
36297ec681f3Smrg   struct anv_shader_bin *closest_hit;
36307ec681f3Smrg   struct anv_shader_bin *any_hit;
36317ec681f3Smrg   struct anv_shader_bin *intersection;
36327ec681f3Smrg
36337ec681f3Smrg   /* VK_KHR_ray_tracing requires shaderGroupHandleSize == 32 */
36347ec681f3Smrg   uint32_t handle[8];
36357ec681f3Smrg};
36367ec681f3Smrg
36377ec681f3Smrgstruct anv_ray_tracing_pipeline {
36387ec681f3Smrg   struct anv_pipeline                          base;
36397ec681f3Smrg
36407ec681f3Smrg   /* All shaders in the pipeline */
36417ec681f3Smrg   struct util_dynarray                         shaders;
36427ec681f3Smrg
36437ec681f3Smrg   uint32_t                                     group_count;
36447ec681f3Smrg   struct anv_rt_shader_group *                 groups;
36457ec681f3Smrg
36467ec681f3Smrg   /* If non-zero, this is the default computed stack size as per the stack
36477ec681f3Smrg    * size computation in the Vulkan spec.  If zero, that indicates that the
36487ec681f3Smrg    * client has requested a dynamic stack size.
36497ec681f3Smrg    */
36507ec681f3Smrg   uint32_t                                     stack_size;
36517ec681f3Smrg};
36527ec681f3Smrg
36537ec681f3Smrg#define ANV_DECL_PIPELINE_DOWNCAST(pipe_type, pipe_enum)             \
36547ec681f3Smrg   static inline struct anv_##pipe_type##_pipeline *                 \
36557ec681f3Smrg   anv_pipeline_to_##pipe_type(struct anv_pipeline *pipeline)      \
36567ec681f3Smrg   {                                                                 \
36577ec681f3Smrg      assert(pipeline->type == pipe_enum);                           \
36587ec681f3Smrg      return (struct anv_##pipe_type##_pipeline *) pipeline;         \
36597ec681f3Smrg   }
36607ec681f3Smrg
36617ec681f3SmrgANV_DECL_PIPELINE_DOWNCAST(graphics, ANV_PIPELINE_GRAPHICS)
36627ec681f3SmrgANV_DECL_PIPELINE_DOWNCAST(compute, ANV_PIPELINE_COMPUTE)
36637ec681f3SmrgANV_DECL_PIPELINE_DOWNCAST(ray_tracing, ANV_PIPELINE_RAY_TRACING)
36647ec681f3Smrg
366501e04c3fSmrgstatic inline bool
36667ec681f3Smrganv_pipeline_has_stage(const struct anv_graphics_pipeline *pipeline,
366701e04c3fSmrg                       gl_shader_stage stage)
366801e04c3fSmrg{
366901e04c3fSmrg   return (pipeline->active_stages & mesa_to_vk_shader_stage(stage)) != 0;
367001e04c3fSmrg}
367101e04c3fSmrg
36727ec681f3Smrgstatic inline bool
36737ec681f3Smrganv_pipeline_is_primitive(const struct anv_graphics_pipeline *pipeline)
36747ec681f3Smrg{
36757ec681f3Smrg   return anv_pipeline_has_stage(pipeline, MESA_SHADER_VERTEX);
36767ec681f3Smrg}
36777ec681f3Smrg
36787ec681f3Smrg#define ANV_DECL_GET_GRAPHICS_PROG_DATA_FUNC(prefix, stage)             \
36797ec681f3Smrgstatic inline const struct brw_##prefix##_prog_data *                   \
36807ec681f3Smrgget_##prefix##_prog_data(const struct anv_graphics_pipeline *pipeline)  \
36817ec681f3Smrg{                                                                       \
36827ec681f3Smrg   if (anv_pipeline_has_stage(pipeline, stage)) {                       \
36837ec681f3Smrg      return (const struct brw_##prefix##_prog_data *)                  \
36847ec681f3Smrg             pipeline->shaders[stage]->prog_data;                       \
36857ec681f3Smrg   } else {                                                             \
36867ec681f3Smrg      return NULL;                                                      \
36877ec681f3Smrg   }                                                                    \
368801e04c3fSmrg}
368901e04c3fSmrg
36907ec681f3SmrgANV_DECL_GET_GRAPHICS_PROG_DATA_FUNC(vs, MESA_SHADER_VERTEX)
36917ec681f3SmrgANV_DECL_GET_GRAPHICS_PROG_DATA_FUNC(tcs, MESA_SHADER_TESS_CTRL)
36927ec681f3SmrgANV_DECL_GET_GRAPHICS_PROG_DATA_FUNC(tes, MESA_SHADER_TESS_EVAL)
36937ec681f3SmrgANV_DECL_GET_GRAPHICS_PROG_DATA_FUNC(gs, MESA_SHADER_GEOMETRY)
36947ec681f3SmrgANV_DECL_GET_GRAPHICS_PROG_DATA_FUNC(wm, MESA_SHADER_FRAGMENT)
36957ec681f3Smrg
36967ec681f3Smrgstatic inline const struct brw_cs_prog_data *
36977ec681f3Smrgget_cs_prog_data(const struct anv_compute_pipeline *pipeline)
36987ec681f3Smrg{
36997ec681f3Smrg   assert(pipeline->cs);
37007ec681f3Smrg   return (const struct brw_cs_prog_data *) pipeline->cs->prog_data;
37017ec681f3Smrg}
370201e04c3fSmrg
370301e04c3fSmrgstatic inline const struct brw_vue_prog_data *
37047ec681f3Smrganv_pipeline_get_last_vue_prog_data(const struct anv_graphics_pipeline *pipeline)
370501e04c3fSmrg{
370601e04c3fSmrg   if (anv_pipeline_has_stage(pipeline, MESA_SHADER_GEOMETRY))
370701e04c3fSmrg      return &get_gs_prog_data(pipeline)->base;
370801e04c3fSmrg   else if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL))
370901e04c3fSmrg      return &get_tes_prog_data(pipeline)->base;
371001e04c3fSmrg   else
371101e04c3fSmrg      return &get_vs_prog_data(pipeline)->base;
371201e04c3fSmrg}
371301e04c3fSmrg
371401e04c3fSmrgVkResult
37157ec681f3Smrganv_device_init_rt_shaders(struct anv_device *device);
37167ec681f3Smrg
37177ec681f3Smrgvoid
37187ec681f3Smrganv_device_finish_rt_shaders(struct anv_device *device);
37197ec681f3Smrg
37207ec681f3SmrgVkResult
37217ec681f3Smrganv_pipeline_init(struct anv_pipeline *pipeline,
37227ec681f3Smrg                  struct anv_device *device,
37237ec681f3Smrg                  enum anv_pipeline_type type,
37247ec681f3Smrg                  VkPipelineCreateFlags flags,
37257ec681f3Smrg                  const VkAllocationCallbacks *pAllocator);
37267ec681f3Smrg
37277ec681f3Smrgvoid
37287ec681f3Smrganv_pipeline_finish(struct anv_pipeline *pipeline,
37297ec681f3Smrg                    struct anv_device *device,
37307ec681f3Smrg                    const VkAllocationCallbacks *pAllocator);
37317ec681f3Smrg
37327ec681f3SmrgVkResult
37337ec681f3Smrganv_graphics_pipeline_init(struct anv_graphics_pipeline *pipeline, struct anv_device *device,
37347ec681f3Smrg                           struct anv_pipeline_cache *cache,
37357ec681f3Smrg                           const VkGraphicsPipelineCreateInfo *pCreateInfo,
37367ec681f3Smrg                           const VkAllocationCallbacks *alloc);
373701e04c3fSmrg
373801e04c3fSmrgVkResult
37397ec681f3Smrganv_pipeline_compile_cs(struct anv_compute_pipeline *pipeline,
374001e04c3fSmrg                        struct anv_pipeline_cache *cache,
374101e04c3fSmrg                        const VkComputePipelineCreateInfo *info,
37427ec681f3Smrg                        const struct vk_shader_module *module,
374301e04c3fSmrg                        const char *entrypoint,
374401e04c3fSmrg                        const VkSpecializationInfo *spec_info);
374501e04c3fSmrg
37467ec681f3SmrgVkResult
37477ec681f3Smrganv_ray_tracing_pipeline_init(struct anv_ray_tracing_pipeline *pipeline,
37487ec681f3Smrg                              struct anv_device *device,
37497ec681f3Smrg                              struct anv_pipeline_cache *cache,
37507ec681f3Smrg                              const VkRayTracingPipelineCreateInfoKHR *pCreateInfo,
37517ec681f3Smrg                              const VkAllocationCallbacks *alloc);
37527ec681f3Smrg
375301e04c3fSmrgstruct anv_format_plane {
375401e04c3fSmrg   enum isl_format isl_format:16;
375501e04c3fSmrg   struct isl_swizzle swizzle;
375601e04c3fSmrg
375701e04c3fSmrg   /* Whether this plane contains chroma channels */
375801e04c3fSmrg   bool has_chroma;
375901e04c3fSmrg
376001e04c3fSmrg   /* For downscaling of YUV planes */
376101e04c3fSmrg   uint8_t denominator_scales[2];
376201e04c3fSmrg
376301e04c3fSmrg   /* How to map sampled ycbcr planes to a single 4 component element. */
376401e04c3fSmrg   struct isl_swizzle ycbcr_swizzle;
37659f464c52Smaya
37669f464c52Smaya   /* What aspect is associated to this plane */
37679f464c52Smaya   VkImageAspectFlags aspect;
376801e04c3fSmrg};
376901e04c3fSmrg
377001e04c3fSmrg
377101e04c3fSmrgstruct anv_format {
377201e04c3fSmrg   struct anv_format_plane planes[3];
37739f464c52Smaya   VkFormat vk_format;
377401e04c3fSmrg   uint8_t n_planes;
377501e04c3fSmrg   bool can_ycbcr;
377601e04c3fSmrg};
377701e04c3fSmrg
37787ec681f3Smrgstatic inline void
37797ec681f3Smrganv_assert_valid_aspect_set(VkImageAspectFlags aspects)
378001e04c3fSmrg{
37817ec681f3Smrg   if (util_bitcount(aspects) == 1) {
37827ec681f3Smrg      assert(aspects & (VK_IMAGE_ASPECT_COLOR_BIT |
37837ec681f3Smrg                        VK_IMAGE_ASPECT_DEPTH_BIT |
37847ec681f3Smrg                        VK_IMAGE_ASPECT_STENCIL_BIT |
37857ec681f3Smrg                        VK_IMAGE_ASPECT_PLANE_0_BIT |
37867ec681f3Smrg                        VK_IMAGE_ASPECT_PLANE_1_BIT |
37877ec681f3Smrg                        VK_IMAGE_ASPECT_PLANE_2_BIT));
37887ec681f3Smrg   } else if (aspects & VK_IMAGE_ASPECT_PLANES_BITS_ANV) {
37897ec681f3Smrg      assert(aspects == VK_IMAGE_ASPECT_PLANE_0_BIT ||
37907ec681f3Smrg             aspects == (VK_IMAGE_ASPECT_PLANE_0_BIT |
37917ec681f3Smrg                         VK_IMAGE_ASPECT_PLANE_1_BIT) ||
37927ec681f3Smrg             aspects == (VK_IMAGE_ASPECT_PLANE_0_BIT |
37937ec681f3Smrg                         VK_IMAGE_ASPECT_PLANE_1_BIT |
37947ec681f3Smrg                         VK_IMAGE_ASPECT_PLANE_2_BIT));
37957ec681f3Smrg   } else {
37967ec681f3Smrg      assert(aspects == (VK_IMAGE_ASPECT_DEPTH_BIT |
37977ec681f3Smrg                         VK_IMAGE_ASPECT_STENCIL_BIT));
379801e04c3fSmrg   }
379901e04c3fSmrg}
380001e04c3fSmrg
38017ec681f3Smrg/**
38027ec681f3Smrg * Return the aspect's plane relative to all_aspects.  For an image, for
38037ec681f3Smrg * instance, all_aspects would be the set of aspects in the image.  For
38047ec681f3Smrg * an image view, all_aspects would be the subset of aspects represented
38057ec681f3Smrg * by that particular view.
38067ec681f3Smrg */
38077ec681f3Smrgstatic inline uint32_t
38087ec681f3Smrganv_aspect_to_plane(VkImageAspectFlags all_aspects,
38097ec681f3Smrg                    VkImageAspectFlagBits aspect)
381001e04c3fSmrg{
38117ec681f3Smrg   anv_assert_valid_aspect_set(all_aspects);
38127ec681f3Smrg   assert(util_bitcount(aspect) == 1);
38137ec681f3Smrg   assert(!(aspect & ~all_aspects));
38147ec681f3Smrg
38157ec681f3Smrg   /* Because we always put image and view planes in aspect-bit-order, the
38167ec681f3Smrg    * plane index is the number of bits in all_aspects before aspect.
38177ec681f3Smrg    */
38187ec681f3Smrg   return util_bitcount(all_aspects & (aspect - 1));
381901e04c3fSmrg}
382001e04c3fSmrg
382101e04c3fSmrg#define anv_foreach_image_aspect_bit(b, image, aspects) \
38227ec681f3Smrg   u_foreach_bit(b, vk_image_expand_aspect_mask(&(image)->vk, aspects))
382301e04c3fSmrg
382401e04c3fSmrgconst struct anv_format *
382501e04c3fSmrganv_get_format(VkFormat format);
382601e04c3fSmrg
382701e04c3fSmrgstatic inline uint32_t
382801e04c3fSmrganv_get_format_planes(VkFormat vk_format)
382901e04c3fSmrg{
383001e04c3fSmrg   const struct anv_format *format = anv_get_format(vk_format);
383101e04c3fSmrg
383201e04c3fSmrg   return format != NULL ? format->n_planes : 0;
383301e04c3fSmrg}
383401e04c3fSmrg
383501e04c3fSmrgstruct anv_format_plane
38367ec681f3Smrganv_get_format_plane(const struct intel_device_info *devinfo,
38377ec681f3Smrg                     VkFormat vk_format, uint32_t plane,
38387ec681f3Smrg                     VkImageTiling tiling);
38397ec681f3Smrg
38407ec681f3Smrgstruct anv_format_plane
38417ec681f3Smrganv_get_format_aspect(const struct intel_device_info *devinfo,
38427ec681f3Smrg                      VkFormat vk_format,
38437ec681f3Smrg                      VkImageAspectFlagBits aspect, VkImageTiling tiling);
384401e04c3fSmrg
384501e04c3fSmrgstatic inline enum isl_format
38467ec681f3Smrganv_get_isl_format(const struct intel_device_info *devinfo, VkFormat vk_format,
384701e04c3fSmrg                   VkImageAspectFlags aspect, VkImageTiling tiling)
384801e04c3fSmrg{
38497ec681f3Smrg   return anv_get_format_aspect(devinfo, vk_format, aspect, tiling).isl_format;
385001e04c3fSmrg}
385101e04c3fSmrg
38527ec681f3Smrgbool anv_formats_ccs_e_compatible(const struct intel_device_info *devinfo,
38537ec681f3Smrg                                  VkImageCreateFlags create_flags,
38547ec681f3Smrg                                  VkFormat vk_format,
38557ec681f3Smrg                                  VkImageTiling vk_tiling,
38567ec681f3Smrg                                  const VkImageFormatListCreateInfoKHR *fmt_list);
38577ec681f3Smrg
38587ec681f3Smrgextern VkFormat
38597ec681f3Smrgvk_format_from_android(unsigned android_format, unsigned android_usage);
38607ec681f3Smrg
386101e04c3fSmrgstatic inline struct isl_swizzle
386201e04c3fSmrganv_swizzle_for_render(struct isl_swizzle swizzle)
386301e04c3fSmrg{
386401e04c3fSmrg   /* Sometimes the swizzle will have alpha map to one.  We do this to fake
386501e04c3fSmrg    * RGB as RGBA for texturing
386601e04c3fSmrg    */
386701e04c3fSmrg   assert(swizzle.a == ISL_CHANNEL_SELECT_ONE ||
386801e04c3fSmrg          swizzle.a == ISL_CHANNEL_SELECT_ALPHA);
386901e04c3fSmrg
387001e04c3fSmrg   /* But it doesn't matter what we render to that channel */
387101e04c3fSmrg   swizzle.a = ISL_CHANNEL_SELECT_ALPHA;
387201e04c3fSmrg
387301e04c3fSmrg   return swizzle;
387401e04c3fSmrg}
387501e04c3fSmrg
387601e04c3fSmrgvoid
387701e04c3fSmrganv_pipeline_setup_l3_config(struct anv_pipeline *pipeline, bool needs_slm);
387801e04c3fSmrg
387901e04c3fSmrg/**
38807ec681f3Smrg * Describes how each part of anv_image will be bound to memory.
388101e04c3fSmrg */
38827ec681f3Smrgstruct anv_image_memory_range {
38837ec681f3Smrg   /**
38847ec681f3Smrg    * Disjoint bindings into which each portion of the image will be bound.
38857ec681f3Smrg    *
38867ec681f3Smrg    * Binding images to memory can be complicated and invold binding different
38877ec681f3Smrg    * portions of the image to different memory objects or regions.  For most
38887ec681f3Smrg    * images, everything lives in the MAIN binding and gets bound by
38897ec681f3Smrg    * vkBindImageMemory.  For disjoint multi-planar images, each plane has
38907ec681f3Smrg    * a unique, disjoint binding and gets bound by vkBindImageMemory2 with
38917ec681f3Smrg    * VkBindImagePlaneMemoryInfo.  There may also exist bits of memory which are
38927ec681f3Smrg    * implicit or driver-managed and live in special-case bindings.
38937ec681f3Smrg    */
38947ec681f3Smrg   enum anv_image_memory_binding {
38957ec681f3Smrg      /**
38967ec681f3Smrg       * Used if and only if image is not multi-planar disjoint. Bound by
38977ec681f3Smrg       * vkBindImageMemory2 without VkBindImagePlaneMemoryInfo.
38987ec681f3Smrg       */
38997ec681f3Smrg      ANV_IMAGE_MEMORY_BINDING_MAIN,
39007ec681f3Smrg
39017ec681f3Smrg      /**
39027ec681f3Smrg       * Used if and only if image is multi-planar disjoint.  Bound by
39037ec681f3Smrg       * vkBindImageMemory2 with VkBindImagePlaneMemoryInfo.
39047ec681f3Smrg       */
39057ec681f3Smrg      ANV_IMAGE_MEMORY_BINDING_PLANE_0,
39067ec681f3Smrg      ANV_IMAGE_MEMORY_BINDING_PLANE_1,
39077ec681f3Smrg      ANV_IMAGE_MEMORY_BINDING_PLANE_2,
39087ec681f3Smrg
39097ec681f3Smrg      /**
39107ec681f3Smrg       * Driver-private bo. In special cases we may store the aux surface and/or
39117ec681f3Smrg       * aux state in this binding.
39127ec681f3Smrg       */
39137ec681f3Smrg      ANV_IMAGE_MEMORY_BINDING_PRIVATE,
39147ec681f3Smrg
39157ec681f3Smrg      /** Sentinel */
39167ec681f3Smrg      ANV_IMAGE_MEMORY_BINDING_END,
39177ec681f3Smrg   } binding;
391801e04c3fSmrg
391901e04c3fSmrg   /**
39207ec681f3Smrg    * Offset is relative to the start of the binding created by
39217ec681f3Smrg    * vkBindImageMemory, not to the start of the bo.
392201e04c3fSmrg    */
39237ec681f3Smrg   uint64_t offset;
39247ec681f3Smrg
39257ec681f3Smrg   uint64_t size;
39267ec681f3Smrg   uint32_t alignment;
39277ec681f3Smrg};
39287ec681f3Smrg
39297ec681f3Smrg/**
39307ec681f3Smrg * Subsurface of an anv_image.
39317ec681f3Smrg */
39327ec681f3Smrgstruct anv_surface {
39337ec681f3Smrg   struct isl_surf isl;
39347ec681f3Smrg   struct anv_image_memory_range memory_range;
393501e04c3fSmrg};
393601e04c3fSmrg
39377ec681f3Smrgstatic inline bool MUST_CHECK
39387ec681f3Smrganv_surface_is_valid(const struct anv_surface *surface)
39397ec681f3Smrg{
39407ec681f3Smrg   return surface->isl.size_B > 0 && surface->memory_range.size > 0;
39417ec681f3Smrg}
39427ec681f3Smrg
394301e04c3fSmrgstruct anv_image {
39447ec681f3Smrg   struct vk_image vk;
394501e04c3fSmrg
394601e04c3fSmrg   uint32_t n_planes;
394701e04c3fSmrg
39487ec681f3Smrg   /**
39497ec681f3Smrg    * Image has multi-planar format and was created with
39507ec681f3Smrg    * VK_IMAGE_CREATE_DISJOINT_BIT.
395101e04c3fSmrg    */
39527ec681f3Smrg   bool disjoint;
395301e04c3fSmrg
395401e04c3fSmrg   /**
39557ec681f3Smrg    * Image was imported from an struct AHardwareBuffer.  We have to delay
39567ec681f3Smrg    * final image creation until bind time.
395701e04c3fSmrg    */
39587ec681f3Smrg   bool from_ahb;
395901e04c3fSmrg
39607ec681f3Smrg   /**
39617ec681f3Smrg    * Image was imported from gralloc with VkNativeBufferANDROID. The gralloc bo
39627ec681f3Smrg    * must be released when the image is destroyed.
396301e04c3fSmrg    */
39647ec681f3Smrg   bool from_gralloc;
396501e04c3fSmrg
39667ec681f3Smrg   /**
39677ec681f3Smrg    * The memory bindings created by vkCreateImage and vkBindImageMemory.
39687ec681f3Smrg    *
39697ec681f3Smrg    * For details on the image's memory layout, see check_memory_bindings().
39707ec681f3Smrg    *
39717ec681f3Smrg    * vkCreateImage constructs the `memory_range` for each
39727ec681f3Smrg    * anv_image_memory_binding.  After vkCreateImage, each binding is valid if
39737ec681f3Smrg    * and only if `memory_range::size > 0`.
39747ec681f3Smrg    *
39757ec681f3Smrg    * vkBindImageMemory binds each valid `memory_range` to an `address`.
39767ec681f3Smrg    * Usually, the app will provide the address via the parameters of
39777ec681f3Smrg    * vkBindImageMemory.  However, special-case bindings may be bound to
39787ec681f3Smrg    * driver-private memory.
39799f464c52Smaya    */
39807ec681f3Smrg   struct anv_image_binding {
39817ec681f3Smrg      struct anv_image_memory_range memory_range;
39827ec681f3Smrg      struct anv_address address;
39837ec681f3Smrg   } bindings[ANV_IMAGE_MEMORY_BINDING_END];
39849f464c52Smaya
398501e04c3fSmrg   /**
398601e04c3fSmrg    * Image subsurfaces
398701e04c3fSmrg    *
398801e04c3fSmrg    * For each foo, anv_image::planes[x].surface is valid if and only if
398901e04c3fSmrg    * anv_image::aspects has a x aspect. Refer to anv_image_aspect_to_plane()
399001e04c3fSmrg    * to figure the number associated with a given aspect.
399101e04c3fSmrg    *
399201e04c3fSmrg    * The hardware requires that the depth buffer and stencil buffer be
399301e04c3fSmrg    * separate surfaces.  From Vulkan's perspective, though, depth and stencil
399401e04c3fSmrg    * reside in the same VkImage.  To satisfy both the hardware and Vulkan, we
399501e04c3fSmrg    * allocate the depth and stencil buffers as separate surfaces in the same
399601e04c3fSmrg    * bo.
399701e04c3fSmrg    */
39987ec681f3Smrg   struct anv_image_plane {
39997ec681f3Smrg      struct anv_surface primary_surface;
400001e04c3fSmrg
400101e04c3fSmrg      /**
400201e04c3fSmrg       * A surface which shadows the main surface and may have different
400301e04c3fSmrg       * tiling. This is used for sampling using a tiling that isn't supported
400401e04c3fSmrg       * for other operations.
400501e04c3fSmrg       */
400601e04c3fSmrg      struct anv_surface shadow_surface;
400701e04c3fSmrg
400801e04c3fSmrg      /**
40097ec681f3Smrg       * The base aux usage for this image.  For color images, this can be
40107ec681f3Smrg       * either CCS_E or CCS_D depending on whether or not we can reliably
40117ec681f3Smrg       * leave CCS on all the time.
401201e04c3fSmrg       */
401301e04c3fSmrg      enum isl_aux_usage aux_usage;
401401e04c3fSmrg
401501e04c3fSmrg      struct anv_surface aux_surface;
401601e04c3fSmrg
40177ec681f3Smrg      /** Location of the fast clear state.  */
40187ec681f3Smrg      struct anv_image_memory_range fast_clear_memory_range;
401901e04c3fSmrg   } planes[3];
402001e04c3fSmrg};
402101e04c3fSmrg
402201e04c3fSmrg/* The ordering of this enum is important */
402301e04c3fSmrgenum anv_fast_clear_type {
402401e04c3fSmrg   /** Image does not have/support any fast-clear blocks */
402501e04c3fSmrg   ANV_FAST_CLEAR_NONE = 0,
402601e04c3fSmrg   /** Image has/supports fast-clear but only to the default value */
402701e04c3fSmrg   ANV_FAST_CLEAR_DEFAULT_VALUE = 1,
402801e04c3fSmrg   /** Image has/supports fast-clear with an arbitrary fast-clear value */
402901e04c3fSmrg   ANV_FAST_CLEAR_ANY = 2,
403001e04c3fSmrg};
403101e04c3fSmrg
40327ec681f3Smrg/**
40337ec681f3Smrg * Return the aspect's _format_ plane, not its _memory_ plane (using the
40347ec681f3Smrg * vocabulary of VK_EXT_image_drm_format_modifier). As a consequence, \a
40357ec681f3Smrg * aspect_mask may contain VK_IMAGE_ASPECT_PLANE_*, but must not contain
40367ec681f3Smrg * VK_IMAGE_ASPECT_MEMORY_PLANE_* .
40377ec681f3Smrg */
40387ec681f3Smrgstatic inline uint32_t
40397ec681f3Smrganv_image_aspect_to_plane(const struct anv_image *image,
40407ec681f3Smrg                          VkImageAspectFlagBits aspect)
40417ec681f3Smrg{
40427ec681f3Smrg   return anv_aspect_to_plane(image->vk.aspects, aspect);
40437ec681f3Smrg}
40447ec681f3Smrg
404501e04c3fSmrg/* Returns the number of auxiliary buffer levels attached to an image. */
404601e04c3fSmrgstatic inline uint8_t
404701e04c3fSmrganv_image_aux_levels(const struct anv_image * const image,
404801e04c3fSmrg                     VkImageAspectFlagBits aspect)
404901e04c3fSmrg{
40507ec681f3Smrg   uint32_t plane = anv_image_aspect_to_plane(image, aspect);
40517ec681f3Smrg   if (image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE)
40527ec681f3Smrg      return 0;
40537ec681f3Smrg
40547ec681f3Smrg   return image->vk.mip_levels;
405501e04c3fSmrg}
405601e04c3fSmrg
405701e04c3fSmrg/* Returns the number of auxiliary buffer layers attached to an image. */
405801e04c3fSmrgstatic inline uint32_t
405901e04c3fSmrganv_image_aux_layers(const struct anv_image * const image,
406001e04c3fSmrg                     VkImageAspectFlagBits aspect,
406101e04c3fSmrg                     const uint8_t miplevel)
406201e04c3fSmrg{
406301e04c3fSmrg   assert(image);
406401e04c3fSmrg
406501e04c3fSmrg   /* The miplevel must exist in the main buffer. */
40667ec681f3Smrg   assert(miplevel < image->vk.mip_levels);
406701e04c3fSmrg
406801e04c3fSmrg   if (miplevel >= anv_image_aux_levels(image, aspect)) {
406901e04c3fSmrg      /* There are no layers with auxiliary data because the miplevel has no
407001e04c3fSmrg       * auxiliary data.
407101e04c3fSmrg       */
407201e04c3fSmrg      return 0;
407301e04c3fSmrg   }
40747ec681f3Smrg
40757ec681f3Smrg   return MAX2(image->vk.array_layers, image->vk.extent.depth >> miplevel);
40767ec681f3Smrg}
40777ec681f3Smrg
40787ec681f3Smrgstatic inline struct anv_address MUST_CHECK
40797ec681f3Smrganv_image_address(const struct anv_image *image,
40807ec681f3Smrg                  const struct anv_image_memory_range *mem_range)
40817ec681f3Smrg{
40827ec681f3Smrg   const struct anv_image_binding *binding = &image->bindings[mem_range->binding];
40837ec681f3Smrg   assert(binding->memory_range.offset == 0);
40847ec681f3Smrg
40857ec681f3Smrg   if (mem_range->size == 0)
40867ec681f3Smrg      return ANV_NULL_ADDRESS;
40877ec681f3Smrg
40887ec681f3Smrg   return anv_address_add(binding->address, mem_range->offset);
408901e04c3fSmrg}
409001e04c3fSmrg
409101e04c3fSmrgstatic inline struct anv_address
40927ec681f3Smrganv_image_get_clear_color_addr(UNUSED const struct anv_device *device,
409301e04c3fSmrg                               const struct anv_image *image,
409401e04c3fSmrg                               VkImageAspectFlagBits aspect)
409501e04c3fSmrg{
40967ec681f3Smrg   assert(image->vk.aspects & (VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV |
40977ec681f3Smrg                               VK_IMAGE_ASPECT_DEPTH_BIT));
409801e04c3fSmrg
40997ec681f3Smrg   uint32_t plane = anv_image_aspect_to_plane(image, aspect);
41007ec681f3Smrg   const struct anv_image_memory_range *mem_range =
41017ec681f3Smrg      &image->planes[plane].fast_clear_memory_range;
41027ec681f3Smrg
41037ec681f3Smrg   return anv_image_address(image, mem_range);
410401e04c3fSmrg}
410501e04c3fSmrg
410601e04c3fSmrgstatic inline struct anv_address
410701e04c3fSmrganv_image_get_fast_clear_type_addr(const struct anv_device *device,
410801e04c3fSmrg                                   const struct anv_image *image,
410901e04c3fSmrg                                   VkImageAspectFlagBits aspect)
411001e04c3fSmrg{
411101e04c3fSmrg   struct anv_address addr =
411201e04c3fSmrg      anv_image_get_clear_color_addr(device, image, aspect);
411301e04c3fSmrg
41147ec681f3Smrg   const unsigned clear_color_state_size = device->info.ver >= 10 ?
411501e04c3fSmrg      device->isl_dev.ss.clear_color_state_size :
411601e04c3fSmrg      device->isl_dev.ss.clear_value_size;
41179f464c52Smaya   return anv_address_add(addr, clear_color_state_size);
411801e04c3fSmrg}
411901e04c3fSmrg
412001e04c3fSmrgstatic inline struct anv_address
412101e04c3fSmrganv_image_get_compression_state_addr(const struct anv_device *device,
412201e04c3fSmrg                                     const struct anv_image *image,
412301e04c3fSmrg                                     VkImageAspectFlagBits aspect,
412401e04c3fSmrg                                     uint32_t level, uint32_t array_layer)
412501e04c3fSmrg{
412601e04c3fSmrg   assert(level < anv_image_aux_levels(image, aspect));
412701e04c3fSmrg   assert(array_layer < anv_image_aux_layers(image, aspect, level));
41287ec681f3Smrg   UNUSED uint32_t plane = anv_image_aspect_to_plane(image, aspect);
412901e04c3fSmrg   assert(image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E);
413001e04c3fSmrg
41317ec681f3Smrg   /* Relative to start of the plane's fast clear memory range */
41327ec681f3Smrg   uint32_t offset;
41337ec681f3Smrg
41347ec681f3Smrg   offset = 4; /* Go past the fast clear type */
413501e04c3fSmrg
41367ec681f3Smrg   if (image->vk.image_type == VK_IMAGE_TYPE_3D) {
413701e04c3fSmrg      for (uint32_t l = 0; l < level; l++)
41387ec681f3Smrg         offset += anv_minify(image->vk.extent.depth, l) * 4;
413901e04c3fSmrg   } else {
41407ec681f3Smrg      offset += level * image->vk.array_layers * 4;
414101e04c3fSmrg   }
414201e04c3fSmrg
41437ec681f3Smrg   offset += array_layer * 4;
41447ec681f3Smrg
41457ec681f3Smrg   assert(offset < image->planes[plane].fast_clear_memory_range.size);
41467ec681f3Smrg
41477ec681f3Smrg   return anv_address_add(
41487ec681f3Smrg      anv_image_get_fast_clear_type_addr(device, image, aspect),
41497ec681f3Smrg      offset);
415001e04c3fSmrg}
415101e04c3fSmrg
415201e04c3fSmrg/* Returns true if a HiZ-enabled depth buffer can be sampled from. */
415301e04c3fSmrgstatic inline bool
41547ec681f3Smrganv_can_sample_with_hiz(const struct intel_device_info * const devinfo,
415501e04c3fSmrg                        const struct anv_image *image)
415601e04c3fSmrg{
41577ec681f3Smrg   if (!(image->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT))
41587ec681f3Smrg      return false;
41597ec681f3Smrg
41607ec681f3Smrg   /* For Gfx8-11, there are some restrictions around sampling from HiZ.
41617ec681f3Smrg    * The Skylake PRM docs for RENDER_SURFACE_STATE::AuxiliarySurfaceMode
41627ec681f3Smrg    * say:
41637ec681f3Smrg    *
41647ec681f3Smrg    *    "If this field is set to AUX_HIZ, Number of Multisamples must
41657ec681f3Smrg    *    be MULTISAMPLECOUNT_1, and Surface Type cannot be SURFTYPE_3D."
41667ec681f3Smrg    */
41677ec681f3Smrg   if (image->vk.image_type == VK_IMAGE_TYPE_3D)
416801e04c3fSmrg      return false;
416901e04c3fSmrg
41709f464c52Smaya   /* Allow this feature on BDW even though it is disabled in the BDW devinfo
41719f464c52Smaya    * struct. There's documentation which suggests that this feature actually
41729f464c52Smaya    * reduces performance on BDW, but it has only been observed to help so
41739f464c52Smaya    * far. Sampling fast-cleared blocks on BDW must also be handled with care
41749f464c52Smaya    * (see depth_stencil_attachment_compute_aux_usage() for more info).
41759f464c52Smaya    */
41767ec681f3Smrg   if (devinfo->ver != 8 && !devinfo->has_sample_with_hiz)
417701e04c3fSmrg      return false;
417801e04c3fSmrg
41797ec681f3Smrg   return image->vk.samples == 1;
41807ec681f3Smrg}
41817ec681f3Smrg
41827ec681f3Smrg/* Returns true if an MCS-enabled buffer can be sampled from. */
41837ec681f3Smrgstatic inline bool
41847ec681f3Smrganv_can_sample_mcs_with_clear(const struct intel_device_info * const devinfo,
41857ec681f3Smrg                              const struct anv_image *image)
41867ec681f3Smrg{
41877ec681f3Smrg   assert(image->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT);
41887ec681f3Smrg   const uint32_t plane =
41897ec681f3Smrg      anv_image_aspect_to_plane(image, VK_IMAGE_ASPECT_COLOR_BIT);
41907ec681f3Smrg
41917ec681f3Smrg   assert(isl_aux_usage_has_mcs(image->planes[plane].aux_usage));
41927ec681f3Smrg
41937ec681f3Smrg   const struct anv_surface *anv_surf = &image->planes[plane].primary_surface;
41947ec681f3Smrg
41957ec681f3Smrg   /* On TGL, the sampler has an issue with some 8 and 16bpp MSAA fast clears.
41967ec681f3Smrg    * See HSD 1707282275, wa_14013111325. Due to the use of
41977ec681f3Smrg    * format-reinterpretation, a simplified workaround is implemented.
41987ec681f3Smrg    */
41997ec681f3Smrg   if (devinfo->ver >= 12 &&
42007ec681f3Smrg       isl_format_get_layout(anv_surf->isl.format)->bpb <= 16) {
42017ec681f3Smrg      return false;
42027ec681f3Smrg   }
42037ec681f3Smrg
42047ec681f3Smrg   return true;
42057ec681f3Smrg}
42067ec681f3Smrg
42077ec681f3Smrgstatic inline bool
42087ec681f3Smrganv_image_plane_uses_aux_map(const struct anv_device *device,
42097ec681f3Smrg                             const struct anv_image *image,
42107ec681f3Smrg                             uint32_t plane)
42117ec681f3Smrg{
42127ec681f3Smrg   return device->info.has_aux_map &&
42137ec681f3Smrg      isl_aux_usage_has_ccs(image->planes[plane].aux_usage);
421401e04c3fSmrg}
421501e04c3fSmrg
421601e04c3fSmrgvoid
421701e04c3fSmrganv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer,
421801e04c3fSmrg                                  const struct anv_image *image,
421901e04c3fSmrg                                  VkImageAspectFlagBits aspect,
422001e04c3fSmrg                                  enum isl_aux_usage aux_usage,
422101e04c3fSmrg                                  uint32_t level,
422201e04c3fSmrg                                  uint32_t base_layer,
422301e04c3fSmrg                                  uint32_t layer_count);
422401e04c3fSmrg
422501e04c3fSmrgvoid
422601e04c3fSmrganv_image_clear_color(struct anv_cmd_buffer *cmd_buffer,
422701e04c3fSmrg                      const struct anv_image *image,
422801e04c3fSmrg                      VkImageAspectFlagBits aspect,
422901e04c3fSmrg                      enum isl_aux_usage aux_usage,
423001e04c3fSmrg                      enum isl_format format, struct isl_swizzle swizzle,
423101e04c3fSmrg                      uint32_t level, uint32_t base_layer, uint32_t layer_count,
423201e04c3fSmrg                      VkRect2D area, union isl_color_value clear_color);
423301e04c3fSmrgvoid
423401e04c3fSmrganv_image_clear_depth_stencil(struct anv_cmd_buffer *cmd_buffer,
423501e04c3fSmrg                              const struct anv_image *image,
423601e04c3fSmrg                              VkImageAspectFlags aspects,
423701e04c3fSmrg                              enum isl_aux_usage depth_aux_usage,
423801e04c3fSmrg                              uint32_t level,
423901e04c3fSmrg                              uint32_t base_layer, uint32_t layer_count,
424001e04c3fSmrg                              VkRect2D area,
424101e04c3fSmrg                              float depth_value, uint8_t stencil_value);
424201e04c3fSmrgvoid
42439f464c52Smayaanv_image_msaa_resolve(struct anv_cmd_buffer *cmd_buffer,
42449f464c52Smaya                       const struct anv_image *src_image,
42459f464c52Smaya                       enum isl_aux_usage src_aux_usage,
42469f464c52Smaya                       uint32_t src_level, uint32_t src_base_layer,
42479f464c52Smaya                       const struct anv_image *dst_image,
42489f464c52Smaya                       enum isl_aux_usage dst_aux_usage,
42499f464c52Smaya                       uint32_t dst_level, uint32_t dst_base_layer,
42509f464c52Smaya                       VkImageAspectFlagBits aspect,
42519f464c52Smaya                       uint32_t src_x, uint32_t src_y,
42529f464c52Smaya                       uint32_t dst_x, uint32_t dst_y,
42539f464c52Smaya                       uint32_t width, uint32_t height,
42549f464c52Smaya                       uint32_t layer_count,
42559f464c52Smaya                       enum blorp_filter filter);
42569f464c52Smayavoid
425701e04c3fSmrganv_image_hiz_op(struct anv_cmd_buffer *cmd_buffer,
425801e04c3fSmrg                 const struct anv_image *image,
425901e04c3fSmrg                 VkImageAspectFlagBits aspect, uint32_t level,
426001e04c3fSmrg                 uint32_t base_layer, uint32_t layer_count,
426101e04c3fSmrg                 enum isl_aux_op hiz_op);
426201e04c3fSmrgvoid
426301e04c3fSmrganv_image_hiz_clear(struct anv_cmd_buffer *cmd_buffer,
426401e04c3fSmrg                    const struct anv_image *image,
426501e04c3fSmrg                    VkImageAspectFlags aspects,
426601e04c3fSmrg                    uint32_t level,
426701e04c3fSmrg                    uint32_t base_layer, uint32_t layer_count,
426801e04c3fSmrg                    VkRect2D area, uint8_t stencil_value);
426901e04c3fSmrgvoid
427001e04c3fSmrganv_image_mcs_op(struct anv_cmd_buffer *cmd_buffer,
427101e04c3fSmrg                 const struct anv_image *image,
42727ec681f3Smrg                 enum isl_format format, struct isl_swizzle swizzle,
427301e04c3fSmrg                 VkImageAspectFlagBits aspect,
427401e04c3fSmrg                 uint32_t base_layer, uint32_t layer_count,
427501e04c3fSmrg                 enum isl_aux_op mcs_op, union isl_color_value *clear_value,
427601e04c3fSmrg                 bool predicate);
427701e04c3fSmrgvoid
427801e04c3fSmrganv_image_ccs_op(struct anv_cmd_buffer *cmd_buffer,
427901e04c3fSmrg                 const struct anv_image *image,
42807ec681f3Smrg                 enum isl_format format, struct isl_swizzle swizzle,
428101e04c3fSmrg                 VkImageAspectFlagBits aspect, uint32_t level,
428201e04c3fSmrg                 uint32_t base_layer, uint32_t layer_count,
428301e04c3fSmrg                 enum isl_aux_op ccs_op, union isl_color_value *clear_value,
428401e04c3fSmrg                 bool predicate);
428501e04c3fSmrg
428601e04c3fSmrgvoid
428701e04c3fSmrganv_image_copy_to_shadow(struct anv_cmd_buffer *cmd_buffer,
428801e04c3fSmrg                         const struct anv_image *image,
42897ec681f3Smrg                         VkImageAspectFlagBits aspect,
429001e04c3fSmrg                         uint32_t base_level, uint32_t level_count,
429101e04c3fSmrg                         uint32_t base_layer, uint32_t layer_count);
429201e04c3fSmrg
42937ec681f3Smrgenum isl_aux_state ATTRIBUTE_PURE
42947ec681f3Smrganv_layout_to_aux_state(const struct intel_device_info * const devinfo,
42957ec681f3Smrg                        const struct anv_image *image,
42967ec681f3Smrg                        const VkImageAspectFlagBits aspect,
42977ec681f3Smrg                        const VkImageLayout layout);
42987ec681f3Smrg
42997ec681f3Smrgenum isl_aux_usage ATTRIBUTE_PURE
43007ec681f3Smrganv_layout_to_aux_usage(const struct intel_device_info * const devinfo,
430101e04c3fSmrg                        const struct anv_image *image,
430201e04c3fSmrg                        const VkImageAspectFlagBits aspect,
43037ec681f3Smrg                        const VkImageUsageFlagBits usage,
430401e04c3fSmrg                        const VkImageLayout layout);
430501e04c3fSmrg
43067ec681f3Smrgenum anv_fast_clear_type ATTRIBUTE_PURE
43077ec681f3Smrganv_layout_to_fast_clear_type(const struct intel_device_info * const devinfo,
430801e04c3fSmrg                              const struct anv_image * const image,
430901e04c3fSmrg                              const VkImageAspectFlagBits aspect,
431001e04c3fSmrg                              const VkImageLayout layout);
431101e04c3fSmrg
431201e04c3fSmrgstatic inline bool
431301e04c3fSmrganv_image_aspects_compatible(VkImageAspectFlags aspects1,
431401e04c3fSmrg                             VkImageAspectFlags aspects2)
431501e04c3fSmrg{
431601e04c3fSmrg   if (aspects1 == aspects2)
431701e04c3fSmrg      return true;
431801e04c3fSmrg
431901e04c3fSmrg   /* Only 1 color aspects are compatibles. */
432001e04c3fSmrg   if ((aspects1 & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) != 0 &&
432101e04c3fSmrg       (aspects2 & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) != 0 &&
432201e04c3fSmrg       util_bitcount(aspects1) == util_bitcount(aspects2))
432301e04c3fSmrg      return true;
432401e04c3fSmrg
432501e04c3fSmrg   return false;
432601e04c3fSmrg}
432701e04c3fSmrg
432801e04c3fSmrgstruct anv_image_view {
43297ec681f3Smrg   struct vk_image_view vk;
433001e04c3fSmrg
43317ec681f3Smrg   const struct anv_image *image; /**< VkImageViewCreateInfo::image */
433201e04c3fSmrg
433301e04c3fSmrg   unsigned n_planes;
433401e04c3fSmrg   struct {
433501e04c3fSmrg      uint32_t image_plane;
433601e04c3fSmrg
433701e04c3fSmrg      struct isl_view isl;
433801e04c3fSmrg
433901e04c3fSmrg      /**
434001e04c3fSmrg       * RENDER_SURFACE_STATE when using image as a sampler surface with an
434101e04c3fSmrg       * image layout of SHADER_READ_ONLY_OPTIMAL or
434201e04c3fSmrg       * DEPTH_STENCIL_READ_ONLY_OPTIMAL.
434301e04c3fSmrg       */
434401e04c3fSmrg      struct anv_surface_state optimal_sampler_surface_state;
434501e04c3fSmrg
434601e04c3fSmrg      /**
434701e04c3fSmrg       * RENDER_SURFACE_STATE when using image as a sampler surface with an
434801e04c3fSmrg       * image layout of GENERAL.
434901e04c3fSmrg       */
435001e04c3fSmrg      struct anv_surface_state general_sampler_surface_state;
435101e04c3fSmrg
435201e04c3fSmrg      /**
435301e04c3fSmrg       * RENDER_SURFACE_STATE when using image as a storage image. Separate
43547ec681f3Smrg       * states for vanilla (with the original format) and one which has been
43557ec681f3Smrg       * lowered to a format suitable for reading.  This may be a raw surface
43567ec681f3Smrg       * in extreme cases or simply a surface with a different format where we
43577ec681f3Smrg       * expect some conversion to be done in the shader.
435801e04c3fSmrg       */
435901e04c3fSmrg      struct anv_surface_state storage_surface_state;
43607ec681f3Smrg      struct anv_surface_state lowered_storage_surface_state;
436101e04c3fSmrg
43627ec681f3Smrg      struct brw_image_param lowered_storage_image_param;
436301e04c3fSmrg   } planes[3];
436401e04c3fSmrg};
436501e04c3fSmrg
436601e04c3fSmrgenum anv_image_view_state_flags {
43677ec681f3Smrg   ANV_IMAGE_VIEW_STATE_STORAGE_LOWERED      = (1 << 0),
436801e04c3fSmrg   ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL      = (1 << 1),
436901e04c3fSmrg};
437001e04c3fSmrg
437101e04c3fSmrgvoid anv_image_fill_surface_state(struct anv_device *device,
437201e04c3fSmrg                                  const struct anv_image *image,
437301e04c3fSmrg                                  VkImageAspectFlagBits aspect,
437401e04c3fSmrg                                  const struct isl_view *view,
437501e04c3fSmrg                                  isl_surf_usage_flags_t view_usage,
437601e04c3fSmrg                                  enum isl_aux_usage aux_usage,
437701e04c3fSmrg                                  const union isl_color_value *clear_color,
437801e04c3fSmrg                                  enum anv_image_view_state_flags flags,
437901e04c3fSmrg                                  struct anv_surface_state *state_inout,
438001e04c3fSmrg                                  struct brw_image_param *image_param_out);
438101e04c3fSmrg
438201e04c3fSmrgstruct anv_image_create_info {
438301e04c3fSmrg   const VkImageCreateInfo *vk_info;
438401e04c3fSmrg
438501e04c3fSmrg   /** An opt-in bitmask which filters an ISL-mapping of the Vulkan tiling. */
438601e04c3fSmrg   isl_tiling_flags_t isl_tiling_flags;
438701e04c3fSmrg
438801e04c3fSmrg   /** These flags will be added to any derived from VkImageCreateInfo. */
438901e04c3fSmrg   isl_surf_usage_flags_t isl_extra_usage_flags;
439001e04c3fSmrg};
439101e04c3fSmrg
43927ec681f3SmrgVkResult anv_image_init(struct anv_device *device, struct anv_image *image,
43937ec681f3Smrg                        const struct anv_image_create_info *create_info);
43947ec681f3Smrg
43957ec681f3Smrgvoid anv_image_finish(struct anv_image *image);
439601e04c3fSmrg
43977ec681f3Smrgvoid anv_image_get_memory_requirements(struct anv_device *device,
43987ec681f3Smrg                                       struct anv_image *image,
43997ec681f3Smrg                                       VkImageAspectFlags aspects,
44007ec681f3Smrg                                       VkMemoryRequirements2 *pMemoryRequirements);
440101e04c3fSmrg
440201e04c3fSmrgenum isl_format
44037ec681f3Smrganv_isl_format_for_descriptor_type(const struct anv_device *device,
44047ec681f3Smrg                                   VkDescriptorType type);
440501e04c3fSmrg
44067ec681f3Smrgstatic inline VkExtent3D
440701e04c3fSmrganv_sanitize_image_extent(const VkImageType imageType,
44087ec681f3Smrg                          const VkExtent3D imageExtent)
440901e04c3fSmrg{
441001e04c3fSmrg   switch (imageType) {
441101e04c3fSmrg   case VK_IMAGE_TYPE_1D:
441201e04c3fSmrg      return (VkExtent3D) { imageExtent.width, 1, 1 };
441301e04c3fSmrg   case VK_IMAGE_TYPE_2D:
441401e04c3fSmrg      return (VkExtent3D) { imageExtent.width, imageExtent.height, 1 };
441501e04c3fSmrg   case VK_IMAGE_TYPE_3D:
441601e04c3fSmrg      return imageExtent;
441701e04c3fSmrg   default:
441801e04c3fSmrg      unreachable("invalid image type");
441901e04c3fSmrg   }
442001e04c3fSmrg}
442101e04c3fSmrg
44227ec681f3Smrgstatic inline VkOffset3D
442301e04c3fSmrganv_sanitize_image_offset(const VkImageType imageType,
44247ec681f3Smrg                          const VkOffset3D imageOffset)
442501e04c3fSmrg{
442601e04c3fSmrg   switch (imageType) {
442701e04c3fSmrg   case VK_IMAGE_TYPE_1D:
442801e04c3fSmrg      return (VkOffset3D) { imageOffset.x, 0, 0 };
442901e04c3fSmrg   case VK_IMAGE_TYPE_2D:
443001e04c3fSmrg      return (VkOffset3D) { imageOffset.x, imageOffset.y, 0 };
443101e04c3fSmrg   case VK_IMAGE_TYPE_3D:
443201e04c3fSmrg      return imageOffset;
443301e04c3fSmrg   default:
443401e04c3fSmrg      unreachable("invalid image type");
443501e04c3fSmrg   }
443601e04c3fSmrg}
443701e04c3fSmrg
44387ec681f3Smrgstatic inline uint32_t
44397ec681f3Smrganv_rasterization_aa_mode(VkPolygonMode raster_mode,
44407ec681f3Smrg                          VkLineRasterizationModeEXT line_mode)
44417ec681f3Smrg{
44427ec681f3Smrg   if (raster_mode == VK_POLYGON_MODE_LINE &&
44437ec681f3Smrg       line_mode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT)
44447ec681f3Smrg      return true;
44457ec681f3Smrg   return false;
44467ec681f3Smrg}
44477ec681f3Smrg
44487ec681f3SmrgVkFormatFeatureFlags2KHR
44497ec681f3Smrganv_get_image_format_features2(const struct intel_device_info *devinfo,
44507ec681f3Smrg                               VkFormat vk_format,
44517ec681f3Smrg                               const struct anv_format *anv_format,
44527ec681f3Smrg                               VkImageTiling vk_tiling,
44537ec681f3Smrg                               const struct isl_drm_modifier_info *isl_mod_info);
445401e04c3fSmrg
445501e04c3fSmrgvoid anv_fill_buffer_surface_state(struct anv_device *device,
445601e04c3fSmrg                                   struct anv_state state,
445701e04c3fSmrg                                   enum isl_format format,
44587ec681f3Smrg                                   isl_surf_usage_flags_t usage,
445901e04c3fSmrg                                   struct anv_address address,
446001e04c3fSmrg                                   uint32_t range, uint32_t stride);
446101e04c3fSmrg
446201e04c3fSmrgstatic inline void
446301e04c3fSmrganv_clear_color_from_att_state(union isl_color_value *clear_color,
446401e04c3fSmrg                               const struct anv_attachment_state *att_state,
446501e04c3fSmrg                               const struct anv_image_view *iview)
446601e04c3fSmrg{
446701e04c3fSmrg   const struct isl_format_layout *view_fmtl =
446801e04c3fSmrg      isl_format_get_layout(iview->planes[0].isl.format);
446901e04c3fSmrg
447001e04c3fSmrg#define COPY_CLEAR_COLOR_CHANNEL(c, i) \
447101e04c3fSmrg   if (view_fmtl->channels.c.bits) \
447201e04c3fSmrg      clear_color->u32[i] = att_state->clear_value.color.uint32[i]
447301e04c3fSmrg
447401e04c3fSmrg   COPY_CLEAR_COLOR_CHANNEL(r, 0);
447501e04c3fSmrg   COPY_CLEAR_COLOR_CHANNEL(g, 1);
447601e04c3fSmrg   COPY_CLEAR_COLOR_CHANNEL(b, 2);
447701e04c3fSmrg   COPY_CLEAR_COLOR_CHANNEL(a, 3);
447801e04c3fSmrg
447901e04c3fSmrg#undef COPY_CLEAR_COLOR_CHANNEL
448001e04c3fSmrg}
448101e04c3fSmrg
448201e04c3fSmrg
44837ec681f3Smrg/* Haswell border color is a bit of a disaster.  Float and unorm formats use a
44847ec681f3Smrg * straightforward 32-bit float color in the first 64 bytes.  Instead of using
44857ec681f3Smrg * a nice float/integer union like Gfx8+, Haswell specifies the integer border
44867ec681f3Smrg * color as a separate entry /after/ the float color.  The layout of this entry
44877ec681f3Smrg * also depends on the format's bpp (with extra hacks for RG32), and overlaps.
44887ec681f3Smrg *
44897ec681f3Smrg * Since we don't know the format/bpp, we can't make any of the border colors
44907ec681f3Smrg * containing '1' work for all formats, as it would be in the wrong place for
44917ec681f3Smrg * some of them.  We opt to make 32-bit integers work as this seems like the
44927ec681f3Smrg * most common option.  Fortunately, transparent black works regardless, as
44937ec681f3Smrg * all zeroes is the same in every bit-size.
44947ec681f3Smrg */
44957ec681f3Smrgstruct hsw_border_color {
44967ec681f3Smrg   float float32[4];
44977ec681f3Smrg   uint32_t _pad0[12];
44987ec681f3Smrg   uint32_t uint32[4];
44997ec681f3Smrg   uint32_t _pad1[108];
45007ec681f3Smrg};
45017ec681f3Smrg
45027ec681f3Smrgstruct gfx8_border_color {
45037ec681f3Smrg   union {
45047ec681f3Smrg      float float32[4];
45057ec681f3Smrg      uint32_t uint32[4];
45067ec681f3Smrg   };
45077ec681f3Smrg   /* Pad out to 64 bytes */
45087ec681f3Smrg   uint32_t _pad[12];
45097ec681f3Smrg};
45107ec681f3Smrg
451101e04c3fSmrgstruct anv_ycbcr_conversion {
45127ec681f3Smrg   struct vk_object_base base;
45137ec681f3Smrg
451401e04c3fSmrg   const struct anv_format *        format;
451501e04c3fSmrg   VkSamplerYcbcrModelConversion    ycbcr_model;
451601e04c3fSmrg   VkSamplerYcbcrRange              ycbcr_range;
451701e04c3fSmrg   VkComponentSwizzle               mapping[4];
451801e04c3fSmrg   VkChromaLocation                 chroma_offsets[2];
451901e04c3fSmrg   VkFilter                         chroma_filter;
452001e04c3fSmrg   bool                             chroma_reconstruction;
452101e04c3fSmrg};
452201e04c3fSmrg
452301e04c3fSmrgstruct anv_sampler {
45247ec681f3Smrg   struct vk_object_base        base;
45257ec681f3Smrg
452601e04c3fSmrg   uint32_t                     state[3][4];
452701e04c3fSmrg   uint32_t                     n_planes;
452801e04c3fSmrg   struct anv_ycbcr_conversion *conversion;
45299f464c52Smaya
45309f464c52Smaya   /* Blob of sampler state data which is guaranteed to be 32-byte aligned
45319f464c52Smaya    * and with a 32-byte stride for use as bindless samplers.
45329f464c52Smaya    */
45339f464c52Smaya   struct anv_state             bindless_state;
45347ec681f3Smrg
45357ec681f3Smrg   struct anv_state             custom_border_color;
453601e04c3fSmrg};
453701e04c3fSmrg
453801e04c3fSmrgstruct anv_framebuffer {
45397ec681f3Smrg   struct vk_object_base                        base;
45407ec681f3Smrg
454101e04c3fSmrg   uint32_t                                     width;
454201e04c3fSmrg   uint32_t                                     height;
454301e04c3fSmrg   uint32_t                                     layers;
454401e04c3fSmrg
454501e04c3fSmrg   uint32_t                                     attachment_count;
454601e04c3fSmrg   struct anv_image_view *                      attachments[0];
454701e04c3fSmrg};
454801e04c3fSmrg
454901e04c3fSmrgstruct anv_subpass_attachment {
455001e04c3fSmrg   VkImageUsageFlagBits usage;
455101e04c3fSmrg   uint32_t attachment;
455201e04c3fSmrg   VkImageLayout layout;
45537ec681f3Smrg
45547ec681f3Smrg   /* Used only with attachment containing stencil data. */
45557ec681f3Smrg   VkImageLayout stencil_layout;
455601e04c3fSmrg};
455701e04c3fSmrg
455801e04c3fSmrgstruct anv_subpass {
455901e04c3fSmrg   uint32_t                                     attachment_count;
456001e04c3fSmrg
456101e04c3fSmrg   /**
456201e04c3fSmrg    * A pointer to all attachment references used in this subpass.
456301e04c3fSmrg    * Only valid if ::attachment_count > 0.
456401e04c3fSmrg    */
456501e04c3fSmrg   struct anv_subpass_attachment *              attachments;
456601e04c3fSmrg   uint32_t                                     input_count;
456701e04c3fSmrg   struct anv_subpass_attachment *              input_attachments;
456801e04c3fSmrg   uint32_t                                     color_count;
456901e04c3fSmrg   struct anv_subpass_attachment *              color_attachments;
457001e04c3fSmrg   struct anv_subpass_attachment *              resolve_attachments;
457101e04c3fSmrg
457201e04c3fSmrg   struct anv_subpass_attachment *              depth_stencil_attachment;
45739f464c52Smaya   struct anv_subpass_attachment *              ds_resolve_attachment;
45749f464c52Smaya   VkResolveModeFlagBitsKHR                     depth_resolve_mode;
45759f464c52Smaya   VkResolveModeFlagBitsKHR                     stencil_resolve_mode;
457601e04c3fSmrg
457701e04c3fSmrg   uint32_t                                     view_mask;
457801e04c3fSmrg
457901e04c3fSmrg   /** Subpass has a depth/stencil self-dependency */
458001e04c3fSmrg   bool                                         has_ds_self_dep;
458101e04c3fSmrg
45829f464c52Smaya   /** Subpass has at least one color resolve attachment */
45839f464c52Smaya   bool                                         has_color_resolve;
458401e04c3fSmrg};
458501e04c3fSmrg
458601e04c3fSmrgstatic inline unsigned
458701e04c3fSmrganv_subpass_view_count(const struct anv_subpass *subpass)
458801e04c3fSmrg{
458901e04c3fSmrg   return MAX2(1, util_bitcount(subpass->view_mask));
459001e04c3fSmrg}
459101e04c3fSmrg
459201e04c3fSmrgstruct anv_render_pass_attachment {
459301e04c3fSmrg   /* TODO: Consider using VkAttachmentDescription instead of storing each of
459401e04c3fSmrg    * its members individually.
459501e04c3fSmrg    */
459601e04c3fSmrg   VkFormat                                     format;
459701e04c3fSmrg   uint32_t                                     samples;
459801e04c3fSmrg   VkImageUsageFlags                            usage;
459901e04c3fSmrg   VkAttachmentLoadOp                           load_op;
460001e04c3fSmrg   VkAttachmentStoreOp                          store_op;
460101e04c3fSmrg   VkAttachmentLoadOp                           stencil_load_op;
460201e04c3fSmrg   VkImageLayout                                initial_layout;
460301e04c3fSmrg   VkImageLayout                                final_layout;
460401e04c3fSmrg   VkImageLayout                                first_subpass_layout;
460501e04c3fSmrg
46067ec681f3Smrg   VkImageLayout                                stencil_initial_layout;
46077ec681f3Smrg   VkImageLayout                                stencil_final_layout;
46087ec681f3Smrg
460901e04c3fSmrg   /* The subpass id in which the attachment will be used last. */
461001e04c3fSmrg   uint32_t                                     last_subpass_idx;
461101e04c3fSmrg};
461201e04c3fSmrg
461301e04c3fSmrgstruct anv_render_pass {
46147ec681f3Smrg   struct vk_object_base                        base;
46157ec681f3Smrg
461601e04c3fSmrg   uint32_t                                     attachment_count;
461701e04c3fSmrg   uint32_t                                     subpass_count;
461801e04c3fSmrg   /* An array of subpass_count+1 flushes, one per subpass boundary */
461901e04c3fSmrg   enum anv_pipe_bits *                         subpass_flushes;
462001e04c3fSmrg   struct anv_render_pass_attachment *          attachments;
462101e04c3fSmrg   struct anv_subpass                           subpasses[0];
462201e04c3fSmrg};
462301e04c3fSmrg
462401e04c3fSmrg#define ANV_PIPELINE_STATISTICS_MASK 0x000007ff
462501e04c3fSmrg
462601e04c3fSmrgstruct anv_query_pool {
46277ec681f3Smrg   struct vk_object_base                        base;
46287ec681f3Smrg
462901e04c3fSmrg   VkQueryType                                  type;
463001e04c3fSmrg   VkQueryPipelineStatisticFlags                pipeline_statistics;
463101e04c3fSmrg   /** Stride between slots, in bytes */
463201e04c3fSmrg   uint32_t                                     stride;
463301e04c3fSmrg   /** Number of slots in this query pool */
463401e04c3fSmrg   uint32_t                                     slots;
46357ec681f3Smrg   struct anv_bo *                              bo;
46367ec681f3Smrg
46377ec681f3Smrg   /* KHR perf queries : */
46387ec681f3Smrg   uint32_t                                     pass_size;
46397ec681f3Smrg   uint32_t                                     data_offset;
46407ec681f3Smrg   uint32_t                                     snapshot_size;
46417ec681f3Smrg   uint32_t                                     n_counters;
46427ec681f3Smrg   struct intel_perf_counter_pass                *counter_pass;
46437ec681f3Smrg   uint32_t                                     n_passes;
46447ec681f3Smrg   struct intel_perf_query_info                 **pass_query;
46457ec681f3Smrg};
46467ec681f3Smrg
46477ec681f3Smrgstatic inline uint32_t khr_perf_query_preamble_offset(const struct anv_query_pool *pool,
46487ec681f3Smrg                                                      uint32_t pass)
46497ec681f3Smrg{
46507ec681f3Smrg   return pool->pass_size * pass + 8;
46517ec681f3Smrg}
46527ec681f3Smrg
46537ec681f3Smrgstruct anv_acceleration_structure {
46547ec681f3Smrg   struct vk_object_base                        base;
46557ec681f3Smrg
46567ec681f3Smrg   VkDeviceSize                                 size;
46577ec681f3Smrg   struct anv_address                           address;
465801e04c3fSmrg};
465901e04c3fSmrg
466001e04c3fSmrgint anv_get_instance_entrypoint_index(const char *name);
466101e04c3fSmrgint anv_get_device_entrypoint_index(const char *name);
46627ec681f3Smrgint anv_get_physical_device_entrypoint_index(const char *name);
46637ec681f3Smrg
46647ec681f3Smrgconst char *anv_get_instance_entry_name(int index);
46657ec681f3Smrgconst char *anv_get_physical_device_entry_name(int index);
46667ec681f3Smrgconst char *anv_get_device_entry_name(int index);
466701e04c3fSmrg
466801e04c3fSmrgbool
466901e04c3fSmrganv_instance_entrypoint_is_enabled(int index, uint32_t core_version,
46707ec681f3Smrg                                   const struct vk_instance_extension_table *instance);
46717ec681f3Smrgbool
46727ec681f3Smrganv_physical_device_entrypoint_is_enabled(int index, uint32_t core_version,
46737ec681f3Smrg                                          const struct vk_instance_extension_table *instance);
467401e04c3fSmrgbool
467501e04c3fSmrganv_device_entrypoint_is_enabled(int index, uint32_t core_version,
46767ec681f3Smrg                                 const struct vk_instance_extension_table *instance,
46777ec681f3Smrg                                 const struct vk_device_extension_table *device);
467801e04c3fSmrg
46797ec681f3Smrgconst struct vk_device_dispatch_table *
46807ec681f3Smrganv_get_device_dispatch_table(const struct intel_device_info *devinfo);
468101e04c3fSmrg
46827ec681f3Smrgvoid
46837ec681f3Smrganv_dump_pipe_bits(enum anv_pipe_bits bits);
468401e04c3fSmrg
46857ec681f3Smrgstatic inline void
46867ec681f3Smrganv_add_pending_pipe_bits(struct anv_cmd_buffer* cmd_buffer,
46877ec681f3Smrg                          enum anv_pipe_bits bits,
46887ec681f3Smrg                          const char* reason)
46897ec681f3Smrg{
46907ec681f3Smrg   cmd_buffer->state.pending_pipe_bits |= bits;
46917ec681f3Smrg   if (INTEL_DEBUG(DEBUG_PIPE_CONTROL) && bits)
46927ec681f3Smrg   {
46937ec681f3Smrg      fputs("pc: add ", stderr);
46947ec681f3Smrg      anv_dump_pipe_bits(bits);
46957ec681f3Smrg      fprintf(stderr, "reason: %s\n", reason);
46967ec681f3Smrg   }
46977ec681f3Smrg}
469801e04c3fSmrg
469901e04c3fSmrgstatic inline uint32_t
470001e04c3fSmrganv_get_subpass_id(const struct anv_cmd_state * const cmd_state)
470101e04c3fSmrg{
470201e04c3fSmrg   /* This function must be called from within a subpass. */
470301e04c3fSmrg   assert(cmd_state->pass && cmd_state->subpass);
470401e04c3fSmrg
470501e04c3fSmrg   const uint32_t subpass_id = cmd_state->subpass - cmd_state->pass->subpasses;
470601e04c3fSmrg
470701e04c3fSmrg   /* The id of this subpass shouldn't exceed the number of subpasses in this
470801e04c3fSmrg    * render pass minus 1.
470901e04c3fSmrg    */
471001e04c3fSmrg   assert(subpass_id < cmd_state->pass->subpass_count);
471101e04c3fSmrg   return subpass_id;
471201e04c3fSmrg}
471301e04c3fSmrg
47147ec681f3Smrgstruct anv_performance_configuration_intel {
47157ec681f3Smrg   struct vk_object_base      base;
471601e04c3fSmrg
47177ec681f3Smrg   struct intel_perf_registers *register_config;
47187ec681f3Smrg
47197ec681f3Smrg   uint64_t                   config_id;
47207ec681f3Smrg};
47217ec681f3Smrg
47227ec681f3Smrgvoid anv_physical_device_init_perf(struct anv_physical_device *device, int fd);
47237ec681f3Smrgvoid anv_device_perf_init(struct anv_device *device);
47247ec681f3Smrgvoid anv_perf_write_pass_results(struct intel_perf_config *perf,
47257ec681f3Smrg                                 struct anv_query_pool *pool, uint32_t pass,
47267ec681f3Smrg                                 const struct intel_perf_query_result *accumulated_results,
47277ec681f3Smrg                                 union VkPerformanceCounterResultKHR *results);
472801e04c3fSmrg
472901e04c3fSmrg#define ANV_FROM_HANDLE(__anv_type, __name, __handle) \
47307ec681f3Smrg   VK_FROM_HANDLE(__anv_type, __name, __handle)
47317ec681f3Smrg
47327ec681f3SmrgVK_DEFINE_HANDLE_CASTS(anv_cmd_buffer, vk.base, VkCommandBuffer,
47337ec681f3Smrg                       VK_OBJECT_TYPE_COMMAND_BUFFER)
47347ec681f3SmrgVK_DEFINE_HANDLE_CASTS(anv_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE)
47357ec681f3SmrgVK_DEFINE_HANDLE_CASTS(anv_instance, vk.base, VkInstance, VK_OBJECT_TYPE_INSTANCE)
47367ec681f3SmrgVK_DEFINE_HANDLE_CASTS(anv_physical_device, vk.base, VkPhysicalDevice,
47377ec681f3Smrg                       VK_OBJECT_TYPE_PHYSICAL_DEVICE)
47387ec681f3SmrgVK_DEFINE_HANDLE_CASTS(anv_queue, vk.base, VkQueue, VK_OBJECT_TYPE_QUEUE)
47397ec681f3Smrg
47407ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_acceleration_structure, base,
47417ec681f3Smrg                               VkAccelerationStructureKHR,
47427ec681f3Smrg                               VK_OBJECT_TYPE_ACCELERATION_STRUCTURE_KHR)
47437ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_cmd_pool, base, VkCommandPool,
47447ec681f3Smrg                               VK_OBJECT_TYPE_COMMAND_POOL)
47457ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_buffer, base, VkBuffer,
47467ec681f3Smrg                               VK_OBJECT_TYPE_BUFFER)
47477ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_buffer_view, base, VkBufferView,
47487ec681f3Smrg                               VK_OBJECT_TYPE_BUFFER_VIEW)
47497ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_pool, base, VkDescriptorPool,
47507ec681f3Smrg                               VK_OBJECT_TYPE_DESCRIPTOR_POOL)
47517ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_set, base, VkDescriptorSet,
47527ec681f3Smrg                               VK_OBJECT_TYPE_DESCRIPTOR_SET)
47537ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_set_layout, base,
47547ec681f3Smrg                               VkDescriptorSetLayout,
47557ec681f3Smrg                               VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT)
47567ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_update_template, base,
47577ec681f3Smrg                               VkDescriptorUpdateTemplate,
47587ec681f3Smrg                               VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE)
47597ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_device_memory, base, VkDeviceMemory,
47607ec681f3Smrg                               VK_OBJECT_TYPE_DEVICE_MEMORY)
47617ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_fence, base, VkFence, VK_OBJECT_TYPE_FENCE)
47627ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_event, base, VkEvent, VK_OBJECT_TYPE_EVENT)
47637ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_framebuffer, base, VkFramebuffer,
47647ec681f3Smrg                               VK_OBJECT_TYPE_FRAMEBUFFER)
47657ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_image, vk.base, VkImage, VK_OBJECT_TYPE_IMAGE)
47667ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_image_view, vk.base, VkImageView,
47677ec681f3Smrg                               VK_OBJECT_TYPE_IMAGE_VIEW);
47687ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_pipeline_cache, base, VkPipelineCache,
47697ec681f3Smrg                               VK_OBJECT_TYPE_PIPELINE_CACHE)
47707ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_pipeline, base, VkPipeline,
47717ec681f3Smrg                               VK_OBJECT_TYPE_PIPELINE)
47727ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_pipeline_layout, base, VkPipelineLayout,
47737ec681f3Smrg                               VK_OBJECT_TYPE_PIPELINE_LAYOUT)
47747ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_query_pool, base, VkQueryPool,
47757ec681f3Smrg                               VK_OBJECT_TYPE_QUERY_POOL)
47767ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_render_pass, base, VkRenderPass,
47777ec681f3Smrg                               VK_OBJECT_TYPE_RENDER_PASS)
47787ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_sampler, base, VkSampler,
47797ec681f3Smrg                               VK_OBJECT_TYPE_SAMPLER)
47807ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_semaphore, base, VkSemaphore,
47817ec681f3Smrg                               VK_OBJECT_TYPE_SEMAPHORE)
47827ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_ycbcr_conversion, base,
47837ec681f3Smrg                               VkSamplerYcbcrConversion,
47847ec681f3Smrg                               VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION)
47857ec681f3SmrgVK_DEFINE_NONDISP_HANDLE_CASTS(anv_performance_configuration_intel, base,
47867ec681f3Smrg                               VkPerformanceConfigurationINTEL,
47877ec681f3Smrg                               VK_OBJECT_TYPE_PERFORMANCE_CONFIGURATION_INTEL)
47887ec681f3Smrg
47897ec681f3Smrg#define anv_genX(devinfo, thing) ({             \
47907ec681f3Smrg   __typeof(&gfx9_##thing) genX_thing;          \
47917ec681f3Smrg   switch ((devinfo)->verx10) {                 \
47927ec681f3Smrg   case 70:                                     \
47937ec681f3Smrg      genX_thing = &gfx7_##thing;               \
47947ec681f3Smrg      break;                                    \
47957ec681f3Smrg   case 75:                                     \
47967ec681f3Smrg      genX_thing = &gfx75_##thing;              \
47977ec681f3Smrg      break;                                    \
47987ec681f3Smrg   case 80:                                     \
47997ec681f3Smrg      genX_thing = &gfx8_##thing;               \
48007ec681f3Smrg      break;                                    \
48017ec681f3Smrg   case 90:                                     \
48027ec681f3Smrg      genX_thing = &gfx9_##thing;               \
48037ec681f3Smrg      break;                                    \
48047ec681f3Smrg   case 110:                                    \
48057ec681f3Smrg      genX_thing = &gfx11_##thing;              \
48067ec681f3Smrg      break;                                    \
48077ec681f3Smrg   case 120:                                    \
48087ec681f3Smrg      genX_thing = &gfx12_##thing;              \
48097ec681f3Smrg      break;                                    \
48107ec681f3Smrg   case 125:                                    \
48117ec681f3Smrg      genX_thing = &gfx125_##thing;             \
48127ec681f3Smrg      break;                                    \
48137ec681f3Smrg   default:                                     \
48147ec681f3Smrg      unreachable("Unknown hardware generation"); \
48157ec681f3Smrg   }                                            \
48167ec681f3Smrg   genX_thing;                                  \
48177ec681f3Smrg})
481801e04c3fSmrg
481901e04c3fSmrg/* Gen-specific function declarations */
482001e04c3fSmrg#ifdef genX
482101e04c3fSmrg#  include "anv_genX.h"
482201e04c3fSmrg#else
48237ec681f3Smrg#  define genX(x) gfx7_##x
48247ec681f3Smrg#  include "anv_genX.h"
48257ec681f3Smrg#  undef genX
48267ec681f3Smrg#  define genX(x) gfx75_##x
482701e04c3fSmrg#  include "anv_genX.h"
482801e04c3fSmrg#  undef genX
48297ec681f3Smrg#  define genX(x) gfx8_##x
483001e04c3fSmrg#  include "anv_genX.h"
483101e04c3fSmrg#  undef genX
48327ec681f3Smrg#  define genX(x) gfx9_##x
483301e04c3fSmrg#  include "anv_genX.h"
483401e04c3fSmrg#  undef genX
48357ec681f3Smrg#  define genX(x) gfx11_##x
483601e04c3fSmrg#  include "anv_genX.h"
483701e04c3fSmrg#  undef genX
48387ec681f3Smrg#  define genX(x) gfx12_##x
483901e04c3fSmrg#  include "anv_genX.h"
484001e04c3fSmrg#  undef genX
48417ec681f3Smrg#  define genX(x) gfx125_##x
484201e04c3fSmrg#  include "anv_genX.h"
484301e04c3fSmrg#  undef genX
484401e04c3fSmrg#endif
484501e04c3fSmrg
484601e04c3fSmrg#endif /* ANV_PRIVATE_H */
4847