xref: /aosp_15_r20/external/mesa3d/src/intel/vulkan/anv_va.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2023 Intel Corporation
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #include "anv_private.h"
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
27*61046927SAndroid Build Coastguard Worker 
28*61046927SAndroid Build Coastguard Worker static uint64_t
va_add(struct anv_va_range * range,uint64_t addr,uint64_t size)29*61046927SAndroid Build Coastguard Worker va_add(struct anv_va_range *range, uint64_t addr, uint64_t size)
30*61046927SAndroid Build Coastguard Worker {
31*61046927SAndroid Build Coastguard Worker    range->addr = addr;
32*61046927SAndroid Build Coastguard Worker    range->size = size;
33*61046927SAndroid Build Coastguard Worker 
34*61046927SAndroid Build Coastguard Worker    return addr + size;
35*61046927SAndroid Build Coastguard Worker }
36*61046927SAndroid Build Coastguard Worker 
37*61046927SAndroid Build Coastguard Worker static void
va_at(struct anv_va_range * range,uint64_t addr,uint64_t size)38*61046927SAndroid Build Coastguard Worker va_at(struct anv_va_range *range, uint64_t addr, uint64_t size)
39*61046927SAndroid Build Coastguard Worker {
40*61046927SAndroid Build Coastguard Worker    range->addr = addr;
41*61046927SAndroid Build Coastguard Worker    range->size = size;
42*61046927SAndroid Build Coastguard Worker }
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker static void
anv_device_print_vas(struct anv_physical_device * device)45*61046927SAndroid Build Coastguard Worker anv_device_print_vas(struct anv_physical_device *device)
46*61046927SAndroid Build Coastguard Worker {
47*61046927SAndroid Build Coastguard Worker    fprintf(stderr, "Driver heaps:\n");
48*61046927SAndroid Build Coastguard Worker #define PRINT_HEAP(name) \
49*61046927SAndroid Build Coastguard Worker    fprintf(stderr, "   0x%016"PRIx64"-0x%016"PRIx64": %s\n", \
50*61046927SAndroid Build Coastguard Worker            device->va.name.addr, \
51*61046927SAndroid Build Coastguard Worker            device->va.name.addr + device->va.name.size, \
52*61046927SAndroid Build Coastguard Worker            #name);
53*61046927SAndroid Build Coastguard Worker    PRINT_HEAP(general_state_pool);
54*61046927SAndroid Build Coastguard Worker    PRINT_HEAP(low_heap);
55*61046927SAndroid Build Coastguard Worker    PRINT_HEAP(binding_table_pool);
56*61046927SAndroid Build Coastguard Worker    PRINT_HEAP(internal_surface_state_pool);
57*61046927SAndroid Build Coastguard Worker    PRINT_HEAP(scratch_surface_state_pool);
58*61046927SAndroid Build Coastguard Worker    PRINT_HEAP(bindless_surface_state_pool);
59*61046927SAndroid Build Coastguard Worker    PRINT_HEAP(indirect_descriptor_pool);
60*61046927SAndroid Build Coastguard Worker    PRINT_HEAP(indirect_push_descriptor_pool);
61*61046927SAndroid Build Coastguard Worker    PRINT_HEAP(instruction_state_pool);
62*61046927SAndroid Build Coastguard Worker    PRINT_HEAP(dynamic_state_pool);
63*61046927SAndroid Build Coastguard Worker    PRINT_HEAP(dynamic_visible_pool);
64*61046927SAndroid Build Coastguard Worker    PRINT_HEAP(push_descriptor_buffer_pool);
65*61046927SAndroid Build Coastguard Worker    PRINT_HEAP(high_heap);
66*61046927SAndroid Build Coastguard Worker    PRINT_HEAP(trtt);
67*61046927SAndroid Build Coastguard Worker }
68*61046927SAndroid Build Coastguard Worker 
69*61046927SAndroid Build Coastguard Worker void
anv_physical_device_init_va_ranges(struct anv_physical_device * device)70*61046927SAndroid Build Coastguard Worker anv_physical_device_init_va_ranges(struct anv_physical_device *device)
71*61046927SAndroid Build Coastguard Worker {
72*61046927SAndroid Build Coastguard Worker    /* anv Virtual Memory Layout
73*61046927SAndroid Build Coastguard Worker     * =========================
74*61046927SAndroid Build Coastguard Worker     *
75*61046927SAndroid Build Coastguard Worker     * When the anv driver is determining the virtual graphics addresses of
76*61046927SAndroid Build Coastguard Worker     * memory objects itself using the softpin mechanism, the following memory
77*61046927SAndroid Build Coastguard Worker     * ranges will be used.
78*61046927SAndroid Build Coastguard Worker     *
79*61046927SAndroid Build Coastguard Worker     * Three special considerations to notice:
80*61046927SAndroid Build Coastguard Worker     *
81*61046927SAndroid Build Coastguard Worker     * (1) the dynamic state pool is located within the same 4 GiB as the low
82*61046927SAndroid Build Coastguard Worker     * heap. This is to work around a VF cache issue described in a comment in
83*61046927SAndroid Build Coastguard Worker     * anv_physical_device_init_heaps.
84*61046927SAndroid Build Coastguard Worker     *
85*61046927SAndroid Build Coastguard Worker     * (2) the binding table pool is located at lower addresses than the BT
86*61046927SAndroid Build Coastguard Worker     * (binding table) surface state pool, within a 4 GiB range which also
87*61046927SAndroid Build Coastguard Worker     * contains the bindless surface state pool. This allows surface state base
88*61046927SAndroid Build Coastguard Worker     * addresses to cover both binding tables (16 bit offsets), the internal
89*61046927SAndroid Build Coastguard Worker     * surface states (32 bit offsets) and the bindless surface states.
90*61046927SAndroid Build Coastguard Worker     *
91*61046927SAndroid Build Coastguard Worker     * (3) the last 4 GiB of the address space is withheld from the high heap.
92*61046927SAndroid Build Coastguard Worker     * Various hardware units will read past the end of an object for various
93*61046927SAndroid Build Coastguard Worker     * reasons. This healthy margin prevents reads from wrapping around 48-bit
94*61046927SAndroid Build Coastguard Worker     * addresses.
95*61046927SAndroid Build Coastguard Worker     */
96*61046927SAndroid Build Coastguard Worker    uint64_t _1Mb = 1ull * 1024 * 1024;
97*61046927SAndroid Build Coastguard Worker    uint64_t _1Gb = 1ull * 1024 * 1024 * 1024;
98*61046927SAndroid Build Coastguard Worker    uint64_t _4Gb = 4ull * 1024 * 1024 * 1024;
99*61046927SAndroid Build Coastguard Worker 
100*61046927SAndroid Build Coastguard Worker    uint64_t address = 0x000000200000ULL; /* 2MiB */
101*61046927SAndroid Build Coastguard Worker 
102*61046927SAndroid Build Coastguard Worker    address = va_add(&device->va.general_state_pool, address,
103*61046927SAndroid Build Coastguard Worker                     _1Gb - address);
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker    address = va_add(&device->va.low_heap, address, _1Gb);
106*61046927SAndroid Build Coastguard Worker 
107*61046927SAndroid Build Coastguard Worker    /* The binding table pool has to be located directly in front of the
108*61046927SAndroid Build Coastguard Worker     * surface states.
109*61046927SAndroid Build Coastguard Worker     */
110*61046927SAndroid Build Coastguard Worker    address += _1Gb;
111*61046927SAndroid Build Coastguard Worker    address = va_add(&device->va.binding_table_pool, address, _1Gb);
112*61046927SAndroid Build Coastguard Worker    address = va_add(&device->va.internal_surface_state_pool, address, 1 * _1Gb);
113*61046927SAndroid Build Coastguard Worker    assert(device->va.internal_surface_state_pool.addr ==
114*61046927SAndroid Build Coastguard Worker           align64(device->va.internal_surface_state_pool.addr, 2 * _1Gb));
115*61046927SAndroid Build Coastguard Worker    /* Scratch surface state overlaps with the internal surface state */
116*61046927SAndroid Build Coastguard Worker    va_at(&device->va.scratch_surface_state_pool,
117*61046927SAndroid Build Coastguard Worker          device->va.internal_surface_state_pool.addr,
118*61046927SAndroid Build Coastguard Worker          8 * _1Mb);
119*61046927SAndroid Build Coastguard Worker    address = va_add(&device->va.bindless_surface_state_pool, address, 2 * _1Gb);
120*61046927SAndroid Build Coastguard Worker 
121*61046927SAndroid Build Coastguard Worker    if (device->indirect_descriptors) {
122*61046927SAndroid Build Coastguard Worker       /* With indirect descriptors, descriptor buffers can go anywhere, they
123*61046927SAndroid Build Coastguard Worker        * just need to be in a 4Gb aligned range, so all shader accesses can
124*61046927SAndroid Build Coastguard Worker        * use a relocatable upper dword for the 64bit address.
125*61046927SAndroid Build Coastguard Worker        */
126*61046927SAndroid Build Coastguard Worker       address = align64(address, _4Gb);
127*61046927SAndroid Build Coastguard Worker       address = va_add(&device->va.indirect_descriptor_pool, address, 3 * _1Gb);
128*61046927SAndroid Build Coastguard Worker       address = va_add(&device->va.indirect_push_descriptor_pool, address, _1Gb);
129*61046927SAndroid Build Coastguard Worker    }
130*61046927SAndroid Build Coastguard Worker 
131*61046927SAndroid Build Coastguard Worker    /* We use a trick to compute constant data offsets in the shaders to avoid
132*61046927SAndroid Build Coastguard Worker     * unnecessary 64bit address computations (see lower_load_constant() in
133*61046927SAndroid Build Coastguard Worker     * anv_nir_apply_pipeline_layout.c). This assumes the instruction pool is
134*61046927SAndroid Build Coastguard Worker     * located at an address with the lower 32bits at 0.
135*61046927SAndroid Build Coastguard Worker     */
136*61046927SAndroid Build Coastguard Worker    address = align64(address, _4Gb);
137*61046927SAndroid Build Coastguard Worker    address = va_add(&device->va.instruction_state_pool, address, 2 * _1Gb);
138*61046927SAndroid Build Coastguard Worker 
139*61046927SAndroid Build Coastguard Worker    address += 1 * _1Gb;
140*61046927SAndroid Build Coastguard Worker    address = va_add(&device->va.dynamic_state_pool, address, _1Gb);
141*61046927SAndroid Build Coastguard Worker    address = va_add(&device->va.dynamic_visible_pool, address,
142*61046927SAndroid Build Coastguard Worker                     device->info.verx10 >= 125 ? (2 * _1Gb) : (3 * _1Gb - 4096));
143*61046927SAndroid Build Coastguard Worker    assert(device->va.dynamic_visible_pool.addr % _4Gb == 0);
144*61046927SAndroid Build Coastguard Worker    if (device->info.verx10 >= 125)
145*61046927SAndroid Build Coastguard Worker       address = va_add(&device->va.push_descriptor_buffer_pool, address, _1Gb - 4096);
146*61046927SAndroid Build Coastguard Worker 
147*61046927SAndroid Build Coastguard Worker    address = align64(address, device->info.mem_alignment);
148*61046927SAndroid Build Coastguard Worker    address = va_add(&device->va.aux_tt_pool, address, 2 * _1Gb);
149*61046927SAndroid Build Coastguard Worker 
150*61046927SAndroid Build Coastguard Worker    /* What's left to do for us is to set va.high_heap and va.trtt without
151*61046927SAndroid Build Coastguard Worker     * overlap, but there are a few things to be considered:
152*61046927SAndroid Build Coastguard Worker     *
153*61046927SAndroid Build Coastguard Worker     * The TR-TT address space is governed by the GFX_TRTT_VA_RANGE register,
154*61046927SAndroid Build Coastguard Worker     * which carves out part of the address space for TR-TT and is independent
155*61046927SAndroid Build Coastguard Worker     * of device->gtt_size. We use 47:44 for gen9+, the values we set here
156*61046927SAndroid Build Coastguard Worker     * should be in sync with what we write to the register.
157*61046927SAndroid Build Coastguard Worker     *
158*61046927SAndroid Build Coastguard Worker     * If we ever gain the capability to use more than 48 bits of address space
159*61046927SAndroid Build Coastguard Worker     * we'll have to adjust where we put the TR-TT space (and how we set
160*61046927SAndroid Build Coastguard Worker     * GFX_TRTT_VA_RANGE).
161*61046927SAndroid Build Coastguard Worker     *
162*61046927SAndroid Build Coastguard Worker     * We have to leave the last 4GiB out of the high vma range, so that no
163*61046927SAndroid Build Coastguard Worker     * state base address + size can overflow 48 bits. For more information see
164*61046927SAndroid Build Coastguard Worker     * the comment about Wa32bitGeneralStateOffset in anv_allocator.c
165*61046927SAndroid Build Coastguard Worker     *
166*61046927SAndroid Build Coastguard Worker     * Despite the comment above, before we had TR-TT we were not only avoiding
167*61046927SAndroid Build Coastguard Worker     * the last 4GiB of the 48bit address space, but also avoiding the last
168*61046927SAndroid Build Coastguard Worker     * 4GiB from gtt_size, so let's be on the safe side and do the 4GiB
169*61046927SAndroid Build Coastguard Worker     * avoiding for both the TR-TT space top and the gtt top.
170*61046927SAndroid Build Coastguard Worker     */
171*61046927SAndroid Build Coastguard Worker    assert(device->gtt_size <= (1uLL << 48));
172*61046927SAndroid Build Coastguard Worker    uint64_t trtt_start = 0xFuLL << 44;
173*61046927SAndroid Build Coastguard Worker    uint64_t trtt_end = (1uLL << 48) - 4 * _1Gb;
174*61046927SAndroid Build Coastguard Worker    uint64_t addressable_top = MIN2(device->gtt_size, trtt_start) - 4 * _1Gb;
175*61046927SAndroid Build Coastguard Worker 
176*61046927SAndroid Build Coastguard Worker    uint64_t user_heaps_size = addressable_top - address;
177*61046927SAndroid Build Coastguard Worker    address = va_add(&device->va.high_heap, address, user_heaps_size);
178*61046927SAndroid Build Coastguard Worker    assert(address <= trtt_start);
179*61046927SAndroid Build Coastguard Worker    address = va_add(&device->va.trtt, trtt_start, trtt_end - trtt_start);
180*61046927SAndroid Build Coastguard Worker 
181*61046927SAndroid Build Coastguard Worker    if (INTEL_DEBUG(DEBUG_HEAPS))
182*61046927SAndroid Build Coastguard Worker       anv_device_print_vas(device);
183*61046927SAndroid Build Coastguard Worker }
184