xref: /aosp_15_r20/external/mesa3d/src/amd/vulkan/radv_device.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Red Hat.
3*61046927SAndroid Build Coastguard Worker  * Copyright © 2016 Bas Nieuwenhuizen
4*61046927SAndroid Build Coastguard Worker  *
5*61046927SAndroid Build Coastguard Worker  * based in part on anv driver which is:
6*61046927SAndroid Build Coastguard Worker  * Copyright © 2015 Intel Corporation
7*61046927SAndroid Build Coastguard Worker  *
8*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
9*61046927SAndroid Build Coastguard Worker  */
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker #include <fcntl.h>
12*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
13*61046927SAndroid Build Coastguard Worker #include <string.h>
14*61046927SAndroid Build Coastguard Worker 
15*61046927SAndroid Build Coastguard Worker #ifdef __FreeBSD__
16*61046927SAndroid Build Coastguard Worker #include <sys/types.h>
17*61046927SAndroid Build Coastguard Worker #endif
18*61046927SAndroid Build Coastguard Worker #ifdef MAJOR_IN_MKDEV
19*61046927SAndroid Build Coastguard Worker #include <sys/mkdev.h>
20*61046927SAndroid Build Coastguard Worker #endif
21*61046927SAndroid Build Coastguard Worker #ifdef MAJOR_IN_SYSMACROS
22*61046927SAndroid Build Coastguard Worker #include <sys/sysmacros.h>
23*61046927SAndroid Build Coastguard Worker #endif
24*61046927SAndroid Build Coastguard Worker 
25*61046927SAndroid Build Coastguard Worker #ifdef __linux__
26*61046927SAndroid Build Coastguard Worker #include <sys/inotify.h>
27*61046927SAndroid Build Coastguard Worker #endif
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker #include "meta/radv_meta.h"
30*61046927SAndroid Build Coastguard Worker #include "util/disk_cache.h"
31*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
32*61046927SAndroid Build Coastguard Worker #include "radv_cs.h"
33*61046927SAndroid Build Coastguard Worker #include "radv_debug.h"
34*61046927SAndroid Build Coastguard Worker #include "radv_entrypoints.h"
35*61046927SAndroid Build Coastguard Worker #include "radv_formats.h"
36*61046927SAndroid Build Coastguard Worker #include "radv_physical_device.h"
37*61046927SAndroid Build Coastguard Worker #include "radv_printf.h"
38*61046927SAndroid Build Coastguard Worker #include "radv_rmv.h"
39*61046927SAndroid Build Coastguard Worker #include "radv_shader.h"
40*61046927SAndroid Build Coastguard Worker #include "radv_spm.h"
41*61046927SAndroid Build Coastguard Worker #include "radv_sqtt.h"
42*61046927SAndroid Build Coastguard Worker #include "vk_common_entrypoints.h"
43*61046927SAndroid Build Coastguard Worker #include "vk_pipeline_cache.h"
44*61046927SAndroid Build Coastguard Worker #include "vk_semaphore.h"
45*61046927SAndroid Build Coastguard Worker #include "vk_util.h"
46*61046927SAndroid Build Coastguard Worker #ifdef _WIN32
47*61046927SAndroid Build Coastguard Worker typedef void *drmDevicePtr;
48*61046927SAndroid Build Coastguard Worker #include <io.h>
49*61046927SAndroid Build Coastguard Worker #else
50*61046927SAndroid Build Coastguard Worker #include <amdgpu.h>
51*61046927SAndroid Build Coastguard Worker #include <xf86drm.h>
52*61046927SAndroid Build Coastguard Worker #include "drm-uapi/amdgpu_drm.h"
53*61046927SAndroid Build Coastguard Worker #include "winsys/amdgpu/radv_amdgpu_winsys_public.h"
54*61046927SAndroid Build Coastguard Worker #endif
55*61046927SAndroid Build Coastguard Worker #include "util/build_id.h"
56*61046927SAndroid Build Coastguard Worker #include "util/driconf.h"
57*61046927SAndroid Build Coastguard Worker #include "util/mesa-sha1.h"
58*61046927SAndroid Build Coastguard Worker #include "util/os_time.h"
59*61046927SAndroid Build Coastguard Worker #include "util/timespec.h"
60*61046927SAndroid Build Coastguard Worker #include "util/u_atomic.h"
61*61046927SAndroid Build Coastguard Worker #include "util/u_process.h"
62*61046927SAndroid Build Coastguard Worker #include "vulkan/vk_icd.h"
63*61046927SAndroid Build Coastguard Worker #include "winsys/null/radv_null_winsys_public.h"
64*61046927SAndroid Build Coastguard Worker #include "git_sha1.h"
65*61046927SAndroid Build Coastguard Worker #include "sid.h"
66*61046927SAndroid Build Coastguard Worker #include "vk_common_entrypoints.h"
67*61046927SAndroid Build Coastguard Worker #include "vk_format.h"
68*61046927SAndroid Build Coastguard Worker #include "vk_sync.h"
69*61046927SAndroid Build Coastguard Worker #include "vk_sync_dummy.h"
70*61046927SAndroid Build Coastguard Worker 
71*61046927SAndroid Build Coastguard Worker #if AMD_LLVM_AVAILABLE
72*61046927SAndroid Build Coastguard Worker #include "ac_llvm_util.h"
73*61046927SAndroid Build Coastguard Worker #endif
74*61046927SAndroid Build Coastguard Worker 
75*61046927SAndroid Build Coastguard Worker #include "ac_descriptors.h"
76*61046927SAndroid Build Coastguard Worker #include "ac_formats.h"
77*61046927SAndroid Build Coastguard Worker 
78*61046927SAndroid Build Coastguard Worker static bool
radv_spm_trace_enabled(const struct radv_instance * instance)79*61046927SAndroid Build Coastguard Worker radv_spm_trace_enabled(const struct radv_instance *instance)
80*61046927SAndroid Build Coastguard Worker {
81*61046927SAndroid Build Coastguard Worker    return (instance->vk.trace_mode & RADV_TRACE_MODE_RGP) &&
82*61046927SAndroid Build Coastguard Worker           debug_get_bool_option("RADV_THREAD_TRACE_CACHE_COUNTERS", true);
83*61046927SAndroid Build Coastguard Worker }
84*61046927SAndroid Build Coastguard Worker 
85*61046927SAndroid Build Coastguard Worker static bool
radv_trap_handler_enabled()86*61046927SAndroid Build Coastguard Worker radv_trap_handler_enabled()
87*61046927SAndroid Build Coastguard Worker {
88*61046927SAndroid Build Coastguard Worker    return !!getenv("RADV_TRAP_HANDLER");
89*61046927SAndroid Build Coastguard Worker }
90*61046927SAndroid Build Coastguard Worker 
91*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
radv_GetMemoryHostPointerPropertiesEXT(VkDevice _device,VkExternalMemoryHandleTypeFlagBits handleType,const void * pHostPointer,VkMemoryHostPointerPropertiesEXT * pMemoryHostPointerProperties)92*61046927SAndroid Build Coastguard Worker radv_GetMemoryHostPointerPropertiesEXT(VkDevice _device, VkExternalMemoryHandleTypeFlagBits handleType,
93*61046927SAndroid Build Coastguard Worker                                        const void *pHostPointer,
94*61046927SAndroid Build Coastguard Worker                                        VkMemoryHostPointerPropertiesEXT *pMemoryHostPointerProperties)
95*61046927SAndroid Build Coastguard Worker {
96*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(radv_device, device, _device);
97*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
98*61046927SAndroid Build Coastguard Worker 
99*61046927SAndroid Build Coastguard Worker    switch (handleType) {
100*61046927SAndroid Build Coastguard Worker    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: {
101*61046927SAndroid Build Coastguard Worker       uint32_t memoryTypeBits = 0;
102*61046927SAndroid Build Coastguard Worker       for (int i = 0; i < pdev->memory_properties.memoryTypeCount; i++) {
103*61046927SAndroid Build Coastguard Worker          if (pdev->memory_domains[i] == RADEON_DOMAIN_GTT && !(pdev->memory_flags[i] & RADEON_FLAG_GTT_WC)) {
104*61046927SAndroid Build Coastguard Worker             memoryTypeBits = (1 << i);
105*61046927SAndroid Build Coastguard Worker             break;
106*61046927SAndroid Build Coastguard Worker          }
107*61046927SAndroid Build Coastguard Worker       }
108*61046927SAndroid Build Coastguard Worker       pMemoryHostPointerProperties->memoryTypeBits = memoryTypeBits;
109*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
110*61046927SAndroid Build Coastguard Worker    }
111*61046927SAndroid Build Coastguard Worker    default:
112*61046927SAndroid Build Coastguard Worker       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
113*61046927SAndroid Build Coastguard Worker    }
114*61046927SAndroid Build Coastguard Worker }
115*61046927SAndroid Build Coastguard Worker 
116*61046927SAndroid Build Coastguard Worker static VkResult
radv_device_init_border_color(struct radv_device * device)117*61046927SAndroid Build Coastguard Worker radv_device_init_border_color(struct radv_device *device)
118*61046927SAndroid Build Coastguard Worker {
119*61046927SAndroid Build Coastguard Worker    VkResult result;
120*61046927SAndroid Build Coastguard Worker 
121*61046927SAndroid Build Coastguard Worker    result = radv_bo_create(device, NULL, RADV_BORDER_COLOR_BUFFER_SIZE, 4096, RADEON_DOMAIN_VRAM,
122*61046927SAndroid Build Coastguard Worker                            RADEON_FLAG_CPU_ACCESS | RADEON_FLAG_READ_ONLY | RADEON_FLAG_NO_INTERPROCESS_SHARING,
123*61046927SAndroid Build Coastguard Worker                            RADV_BO_PRIORITY_SHADER, 0, true, &device->border_color_data.bo);
124*61046927SAndroid Build Coastguard Worker 
125*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
126*61046927SAndroid Build Coastguard Worker       return vk_error(device, result);
127*61046927SAndroid Build Coastguard Worker 
128*61046927SAndroid Build Coastguard Worker    radv_rmv_log_border_color_palette_create(device, device->border_color_data.bo);
129*61046927SAndroid Build Coastguard Worker 
130*61046927SAndroid Build Coastguard Worker    result = device->ws->buffer_make_resident(device->ws, device->border_color_data.bo, true);
131*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
132*61046927SAndroid Build Coastguard Worker       return vk_error(device, result);
133*61046927SAndroid Build Coastguard Worker 
134*61046927SAndroid Build Coastguard Worker    device->border_color_data.colors_gpu_ptr = radv_buffer_map(device->ws, device->border_color_data.bo);
135*61046927SAndroid Build Coastguard Worker    if (!device->border_color_data.colors_gpu_ptr)
136*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
137*61046927SAndroid Build Coastguard Worker    mtx_init(&device->border_color_data.mutex, mtx_plain);
138*61046927SAndroid Build Coastguard Worker 
139*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
140*61046927SAndroid Build Coastguard Worker }
141*61046927SAndroid Build Coastguard Worker 
142*61046927SAndroid Build Coastguard Worker static void
radv_device_finish_border_color(struct radv_device * device)143*61046927SAndroid Build Coastguard Worker radv_device_finish_border_color(struct radv_device *device)
144*61046927SAndroid Build Coastguard Worker {
145*61046927SAndroid Build Coastguard Worker    if (device->border_color_data.bo) {
146*61046927SAndroid Build Coastguard Worker       radv_rmv_log_border_color_palette_destroy(device, device->border_color_data.bo);
147*61046927SAndroid Build Coastguard Worker       device->ws->buffer_make_resident(device->ws, device->border_color_data.bo, false);
148*61046927SAndroid Build Coastguard Worker       radv_bo_destroy(device, NULL, device->border_color_data.bo);
149*61046927SAndroid Build Coastguard Worker 
150*61046927SAndroid Build Coastguard Worker       mtx_destroy(&device->border_color_data.mutex);
151*61046927SAndroid Build Coastguard Worker    }
152*61046927SAndroid Build Coastguard Worker }
153*61046927SAndroid Build Coastguard Worker 
154*61046927SAndroid Build Coastguard Worker static struct radv_shader_part *
_radv_create_vs_prolog(struct radv_device * device,const void * _key)155*61046927SAndroid Build Coastguard Worker _radv_create_vs_prolog(struct radv_device *device, const void *_key)
156*61046927SAndroid Build Coastguard Worker {
157*61046927SAndroid Build Coastguard Worker    struct radv_vs_prolog_key *key = (struct radv_vs_prolog_key *)_key;
158*61046927SAndroid Build Coastguard Worker    return radv_create_vs_prolog(device, key);
159*61046927SAndroid Build Coastguard Worker }
160*61046927SAndroid Build Coastguard Worker 
161*61046927SAndroid Build Coastguard Worker static uint32_t
radv_hash_vs_prolog(const void * key_)162*61046927SAndroid Build Coastguard Worker radv_hash_vs_prolog(const void *key_)
163*61046927SAndroid Build Coastguard Worker {
164*61046927SAndroid Build Coastguard Worker    const struct radv_vs_prolog_key *key = key_;
165*61046927SAndroid Build Coastguard Worker    return _mesa_hash_data(key, sizeof(*key));
166*61046927SAndroid Build Coastguard Worker }
167*61046927SAndroid Build Coastguard Worker 
168*61046927SAndroid Build Coastguard Worker static bool
radv_cmp_vs_prolog(const void * a_,const void * b_)169*61046927SAndroid Build Coastguard Worker radv_cmp_vs_prolog(const void *a_, const void *b_)
170*61046927SAndroid Build Coastguard Worker {
171*61046927SAndroid Build Coastguard Worker    const struct radv_vs_prolog_key *a = a_;
172*61046927SAndroid Build Coastguard Worker    const struct radv_vs_prolog_key *b = b_;
173*61046927SAndroid Build Coastguard Worker 
174*61046927SAndroid Build Coastguard Worker    return memcmp(a, b, sizeof(*a)) == 0;
175*61046927SAndroid Build Coastguard Worker }
176*61046927SAndroid Build Coastguard Worker 
177*61046927SAndroid Build Coastguard Worker static struct radv_shader_part_cache_ops vs_prolog_ops = {
178*61046927SAndroid Build Coastguard Worker    .create = _radv_create_vs_prolog,
179*61046927SAndroid Build Coastguard Worker    .hash = radv_hash_vs_prolog,
180*61046927SAndroid Build Coastguard Worker    .equals = radv_cmp_vs_prolog,
181*61046927SAndroid Build Coastguard Worker };
182*61046927SAndroid Build Coastguard Worker 
183*61046927SAndroid Build Coastguard Worker static VkResult
radv_device_init_vs_prologs(struct radv_device * device)184*61046927SAndroid Build Coastguard Worker radv_device_init_vs_prologs(struct radv_device *device)
185*61046927SAndroid Build Coastguard Worker {
186*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
187*61046927SAndroid Build Coastguard Worker    const struct radv_instance *instance = radv_physical_device_instance(pdev);
188*61046927SAndroid Build Coastguard Worker 
189*61046927SAndroid Build Coastguard Worker    if (!radv_shader_part_cache_init(&device->vs_prologs, &vs_prolog_ops))
190*61046927SAndroid Build Coastguard Worker       return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
191*61046927SAndroid Build Coastguard Worker 
192*61046927SAndroid Build Coastguard Worker    /* don't pre-compile prologs if we want to print them */
193*61046927SAndroid Build Coastguard Worker    if (instance->debug_flags & RADV_DEBUG_DUMP_PROLOGS)
194*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
195*61046927SAndroid Build Coastguard Worker 
196*61046927SAndroid Build Coastguard Worker    struct radv_vs_prolog_key key;
197*61046927SAndroid Build Coastguard Worker    memset(&key, 0, sizeof(key));
198*61046927SAndroid Build Coastguard Worker    key.as_ls = false;
199*61046927SAndroid Build Coastguard Worker    key.is_ngg = pdev->use_ngg;
200*61046927SAndroid Build Coastguard Worker    key.next_stage = MESA_SHADER_VERTEX;
201*61046927SAndroid Build Coastguard Worker    key.wave32 = pdev->ge_wave_size == 32;
202*61046927SAndroid Build Coastguard Worker 
203*61046927SAndroid Build Coastguard Worker    for (unsigned i = 1; i <= MAX_VERTEX_ATTRIBS; i++) {
204*61046927SAndroid Build Coastguard Worker       key.instance_rate_inputs = 0;
205*61046927SAndroid Build Coastguard Worker       key.num_attributes = i;
206*61046927SAndroid Build Coastguard Worker 
207*61046927SAndroid Build Coastguard Worker       device->simple_vs_prologs[i - 1] = radv_create_vs_prolog(device, &key);
208*61046927SAndroid Build Coastguard Worker       if (!device->simple_vs_prologs[i - 1])
209*61046927SAndroid Build Coastguard Worker          return vk_error(instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
210*61046927SAndroid Build Coastguard Worker    }
211*61046927SAndroid Build Coastguard Worker 
212*61046927SAndroid Build Coastguard Worker    unsigned idx = 0;
213*61046927SAndroid Build Coastguard Worker    for (unsigned num_attributes = 1; num_attributes <= 16; num_attributes++) {
214*61046927SAndroid Build Coastguard Worker       for (unsigned count = 1; count <= num_attributes; count++) {
215*61046927SAndroid Build Coastguard Worker          for (unsigned start = 0; start <= (num_attributes - count); start++) {
216*61046927SAndroid Build Coastguard Worker             key.instance_rate_inputs = u_bit_consecutive(start, count);
217*61046927SAndroid Build Coastguard Worker             key.num_attributes = num_attributes;
218*61046927SAndroid Build Coastguard Worker 
219*61046927SAndroid Build Coastguard Worker             struct radv_shader_part *prolog = radv_create_vs_prolog(device, &key);
220*61046927SAndroid Build Coastguard Worker             if (!prolog)
221*61046927SAndroid Build Coastguard Worker                return vk_error(instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
222*61046927SAndroid Build Coastguard Worker 
223*61046927SAndroid Build Coastguard Worker             assert(idx == radv_instance_rate_prolog_index(num_attributes, key.instance_rate_inputs));
224*61046927SAndroid Build Coastguard Worker             device->instance_rate_vs_prologs[idx++] = prolog;
225*61046927SAndroid Build Coastguard Worker          }
226*61046927SAndroid Build Coastguard Worker       }
227*61046927SAndroid Build Coastguard Worker    }
228*61046927SAndroid Build Coastguard Worker    assert(idx == ARRAY_SIZE(device->instance_rate_vs_prologs));
229*61046927SAndroid Build Coastguard Worker 
230*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
231*61046927SAndroid Build Coastguard Worker }
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker static void
radv_device_finish_vs_prologs(struct radv_device * device)234*61046927SAndroid Build Coastguard Worker radv_device_finish_vs_prologs(struct radv_device *device)
235*61046927SAndroid Build Coastguard Worker {
236*61046927SAndroid Build Coastguard Worker    if (device->vs_prologs.ops)
237*61046927SAndroid Build Coastguard Worker       radv_shader_part_cache_finish(device, &device->vs_prologs);
238*61046927SAndroid Build Coastguard Worker 
239*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ARRAY_SIZE(device->simple_vs_prologs); i++) {
240*61046927SAndroid Build Coastguard Worker       if (!device->simple_vs_prologs[i])
241*61046927SAndroid Build Coastguard Worker          continue;
242*61046927SAndroid Build Coastguard Worker 
243*61046927SAndroid Build Coastguard Worker       radv_shader_part_unref(device, device->simple_vs_prologs[i]);
244*61046927SAndroid Build Coastguard Worker    }
245*61046927SAndroid Build Coastguard Worker 
246*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ARRAY_SIZE(device->instance_rate_vs_prologs); i++) {
247*61046927SAndroid Build Coastguard Worker       if (!device->instance_rate_vs_prologs[i])
248*61046927SAndroid Build Coastguard Worker          continue;
249*61046927SAndroid Build Coastguard Worker 
250*61046927SAndroid Build Coastguard Worker       radv_shader_part_unref(device, device->instance_rate_vs_prologs[i]);
251*61046927SAndroid Build Coastguard Worker    }
252*61046927SAndroid Build Coastguard Worker }
253*61046927SAndroid Build Coastguard Worker 
254*61046927SAndroid Build Coastguard Worker static struct radv_shader_part *
_radv_create_ps_epilog(struct radv_device * device,const void * _key)255*61046927SAndroid Build Coastguard Worker _radv_create_ps_epilog(struct radv_device *device, const void *_key)
256*61046927SAndroid Build Coastguard Worker {
257*61046927SAndroid Build Coastguard Worker    struct radv_ps_epilog_key *key = (struct radv_ps_epilog_key *)_key;
258*61046927SAndroid Build Coastguard Worker    return radv_create_ps_epilog(device, key, NULL);
259*61046927SAndroid Build Coastguard Worker }
260*61046927SAndroid Build Coastguard Worker 
261*61046927SAndroid Build Coastguard Worker static uint32_t
radv_hash_ps_epilog(const void * key_)262*61046927SAndroid Build Coastguard Worker radv_hash_ps_epilog(const void *key_)
263*61046927SAndroid Build Coastguard Worker {
264*61046927SAndroid Build Coastguard Worker    const struct radv_ps_epilog_key *key = key_;
265*61046927SAndroid Build Coastguard Worker    return _mesa_hash_data(key, sizeof(*key));
266*61046927SAndroid Build Coastguard Worker }
267*61046927SAndroid Build Coastguard Worker 
268*61046927SAndroid Build Coastguard Worker static bool
radv_cmp_ps_epilog(const void * a_,const void * b_)269*61046927SAndroid Build Coastguard Worker radv_cmp_ps_epilog(const void *a_, const void *b_)
270*61046927SAndroid Build Coastguard Worker {
271*61046927SAndroid Build Coastguard Worker    const struct radv_ps_epilog_key *a = a_;
272*61046927SAndroid Build Coastguard Worker    const struct radv_ps_epilog_key *b = b_;
273*61046927SAndroid Build Coastguard Worker 
274*61046927SAndroid Build Coastguard Worker    return memcmp(a, b, sizeof(*a)) == 0;
275*61046927SAndroid Build Coastguard Worker }
276*61046927SAndroid Build Coastguard Worker 
277*61046927SAndroid Build Coastguard Worker static struct radv_shader_part_cache_ops ps_epilog_ops = {
278*61046927SAndroid Build Coastguard Worker    .create = _radv_create_ps_epilog,
279*61046927SAndroid Build Coastguard Worker    .hash = radv_hash_ps_epilog,
280*61046927SAndroid Build Coastguard Worker    .equals = radv_cmp_ps_epilog,
281*61046927SAndroid Build Coastguard Worker };
282*61046927SAndroid Build Coastguard Worker 
283*61046927SAndroid Build Coastguard Worker VkResult
radv_device_init_vrs_state(struct radv_device * device)284*61046927SAndroid Build Coastguard Worker radv_device_init_vrs_state(struct radv_device *device)
285*61046927SAndroid Build Coastguard Worker {
286*61046927SAndroid Build Coastguard Worker    VkDeviceMemory mem;
287*61046927SAndroid Build Coastguard Worker    VkBuffer buffer;
288*61046927SAndroid Build Coastguard Worker    VkResult result;
289*61046927SAndroid Build Coastguard Worker    VkImage image;
290*61046927SAndroid Build Coastguard Worker 
291*61046927SAndroid Build Coastguard Worker    VkImageCreateInfo image_create_info = {
292*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
293*61046927SAndroid Build Coastguard Worker       .imageType = VK_IMAGE_TYPE_2D,
294*61046927SAndroid Build Coastguard Worker       .format = VK_FORMAT_D16_UNORM,
295*61046927SAndroid Build Coastguard Worker       .extent = {MAX_FRAMEBUFFER_WIDTH, MAX_FRAMEBUFFER_HEIGHT, 1},
296*61046927SAndroid Build Coastguard Worker       .mipLevels = 1,
297*61046927SAndroid Build Coastguard Worker       .arrayLayers = 1,
298*61046927SAndroid Build Coastguard Worker       .samples = VK_SAMPLE_COUNT_1_BIT,
299*61046927SAndroid Build Coastguard Worker       .tiling = VK_IMAGE_TILING_OPTIMAL,
300*61046927SAndroid Build Coastguard Worker       .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
301*61046927SAndroid Build Coastguard Worker       .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
302*61046927SAndroid Build Coastguard Worker       .queueFamilyIndexCount = 0,
303*61046927SAndroid Build Coastguard Worker       .pQueueFamilyIndices = NULL,
304*61046927SAndroid Build Coastguard Worker       .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
305*61046927SAndroid Build Coastguard Worker    };
306*61046927SAndroid Build Coastguard Worker 
307*61046927SAndroid Build Coastguard Worker    result =
308*61046927SAndroid Build Coastguard Worker       radv_image_create(radv_device_to_handle(device), &(struct radv_image_create_info){.vk_info = &image_create_info},
309*61046927SAndroid Build Coastguard Worker                         &device->meta_state.alloc, &image, true);
310*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
311*61046927SAndroid Build Coastguard Worker       return result;
312*61046927SAndroid Build Coastguard Worker 
313*61046927SAndroid Build Coastguard Worker    VkBufferCreateInfo buffer_create_info = {
314*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
315*61046927SAndroid Build Coastguard Worker       .pNext =
316*61046927SAndroid Build Coastguard Worker          &(VkBufferUsageFlags2CreateInfoKHR){
317*61046927SAndroid Build Coastguard Worker             .sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO_KHR,
318*61046927SAndroid Build Coastguard Worker             .usage = VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT_KHR,
319*61046927SAndroid Build Coastguard Worker          },
320*61046927SAndroid Build Coastguard Worker       .size = radv_image_from_handle(image)->planes[0].surface.meta_size,
321*61046927SAndroid Build Coastguard Worker       .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
322*61046927SAndroid Build Coastguard Worker    };
323*61046927SAndroid Build Coastguard Worker 
324*61046927SAndroid Build Coastguard Worker    result = radv_create_buffer(device, &buffer_create_info, &device->meta_state.alloc, &buffer, true);
325*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
326*61046927SAndroid Build Coastguard Worker       goto fail_create;
327*61046927SAndroid Build Coastguard Worker 
328*61046927SAndroid Build Coastguard Worker    VkBufferMemoryRequirementsInfo2 info = {
329*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
330*61046927SAndroid Build Coastguard Worker       .buffer = buffer,
331*61046927SAndroid Build Coastguard Worker    };
332*61046927SAndroid Build Coastguard Worker    VkMemoryRequirements2 mem_req = {
333*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
334*61046927SAndroid Build Coastguard Worker    };
335*61046927SAndroid Build Coastguard Worker    vk_common_GetBufferMemoryRequirements2(radv_device_to_handle(device), &info, &mem_req);
336*61046927SAndroid Build Coastguard Worker 
337*61046927SAndroid Build Coastguard Worker    VkMemoryAllocateInfo alloc_info = {
338*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
339*61046927SAndroid Build Coastguard Worker       .allocationSize = mem_req.memoryRequirements.size,
340*61046927SAndroid Build Coastguard Worker    };
341*61046927SAndroid Build Coastguard Worker 
342*61046927SAndroid Build Coastguard Worker    result = radv_alloc_memory(device, &alloc_info, &device->meta_state.alloc, &mem, true);
343*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
344*61046927SAndroid Build Coastguard Worker       goto fail_alloc;
345*61046927SAndroid Build Coastguard Worker 
346*61046927SAndroid Build Coastguard Worker    VkBindBufferMemoryInfo bind_info = {.sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
347*61046927SAndroid Build Coastguard Worker                                        .buffer = buffer,
348*61046927SAndroid Build Coastguard Worker                                        .memory = mem,
349*61046927SAndroid Build Coastguard Worker                                        .memoryOffset = 0};
350*61046927SAndroid Build Coastguard Worker 
351*61046927SAndroid Build Coastguard Worker    result = radv_BindBufferMemory2(radv_device_to_handle(device), 1, &bind_info);
352*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
353*61046927SAndroid Build Coastguard Worker       goto fail_bind;
354*61046927SAndroid Build Coastguard Worker 
355*61046927SAndroid Build Coastguard Worker    device->vrs.image = radv_image_from_handle(image);
356*61046927SAndroid Build Coastguard Worker    device->vrs.buffer = radv_buffer_from_handle(buffer);
357*61046927SAndroid Build Coastguard Worker    device->vrs.mem = radv_device_memory_from_handle(mem);
358*61046927SAndroid Build Coastguard Worker 
359*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
360*61046927SAndroid Build Coastguard Worker 
361*61046927SAndroid Build Coastguard Worker fail_bind:
362*61046927SAndroid Build Coastguard Worker    radv_FreeMemory(radv_device_to_handle(device), mem, &device->meta_state.alloc);
363*61046927SAndroid Build Coastguard Worker fail_alloc:
364*61046927SAndroid Build Coastguard Worker    radv_DestroyBuffer(radv_device_to_handle(device), buffer, &device->meta_state.alloc);
365*61046927SAndroid Build Coastguard Worker fail_create:
366*61046927SAndroid Build Coastguard Worker    radv_DestroyImage(radv_device_to_handle(device), image, &device->meta_state.alloc);
367*61046927SAndroid Build Coastguard Worker 
368*61046927SAndroid Build Coastguard Worker    return result;
369*61046927SAndroid Build Coastguard Worker }
370*61046927SAndroid Build Coastguard Worker 
371*61046927SAndroid Build Coastguard Worker static void
radv_device_finish_vrs_image(struct radv_device * device)372*61046927SAndroid Build Coastguard Worker radv_device_finish_vrs_image(struct radv_device *device)
373*61046927SAndroid Build Coastguard Worker {
374*61046927SAndroid Build Coastguard Worker    if (!device->vrs.image)
375*61046927SAndroid Build Coastguard Worker       return;
376*61046927SAndroid Build Coastguard Worker 
377*61046927SAndroid Build Coastguard Worker    radv_FreeMemory(radv_device_to_handle(device), radv_device_memory_to_handle(device->vrs.mem),
378*61046927SAndroid Build Coastguard Worker                    &device->meta_state.alloc);
379*61046927SAndroid Build Coastguard Worker    radv_DestroyBuffer(radv_device_to_handle(device), radv_buffer_to_handle(device->vrs.buffer),
380*61046927SAndroid Build Coastguard Worker                       &device->meta_state.alloc);
381*61046927SAndroid Build Coastguard Worker    radv_DestroyImage(radv_device_to_handle(device), radv_image_to_handle(device->vrs.image), &device->meta_state.alloc);
382*61046927SAndroid Build Coastguard Worker }
383*61046927SAndroid Build Coastguard Worker 
384*61046927SAndroid Build Coastguard Worker static enum radv_force_vrs
radv_parse_vrs_rates(const char * str)385*61046927SAndroid Build Coastguard Worker radv_parse_vrs_rates(const char *str)
386*61046927SAndroid Build Coastguard Worker {
387*61046927SAndroid Build Coastguard Worker    if (!strcmp(str, "2x2")) {
388*61046927SAndroid Build Coastguard Worker       return RADV_FORCE_VRS_2x2;
389*61046927SAndroid Build Coastguard Worker    } else if (!strcmp(str, "2x1")) {
390*61046927SAndroid Build Coastguard Worker       return RADV_FORCE_VRS_2x1;
391*61046927SAndroid Build Coastguard Worker    } else if (!strcmp(str, "1x2")) {
392*61046927SAndroid Build Coastguard Worker       return RADV_FORCE_VRS_1x2;
393*61046927SAndroid Build Coastguard Worker    } else if (!strcmp(str, "1x1")) {
394*61046927SAndroid Build Coastguard Worker       return RADV_FORCE_VRS_1x1;
395*61046927SAndroid Build Coastguard Worker    }
396*61046927SAndroid Build Coastguard Worker 
397*61046927SAndroid Build Coastguard Worker    fprintf(stderr, "radv: Invalid VRS rates specified (valid values are 2x2, 2x1, 1x2 and 1x1)\n");
398*61046927SAndroid Build Coastguard Worker    return RADV_FORCE_VRS_1x1;
399*61046927SAndroid Build Coastguard Worker }
400*61046927SAndroid Build Coastguard Worker 
401*61046927SAndroid Build Coastguard Worker static const char *
radv_get_force_vrs_config_file(void)402*61046927SAndroid Build Coastguard Worker radv_get_force_vrs_config_file(void)
403*61046927SAndroid Build Coastguard Worker {
404*61046927SAndroid Build Coastguard Worker    return getenv("RADV_FORCE_VRS_CONFIG_FILE");
405*61046927SAndroid Build Coastguard Worker }
406*61046927SAndroid Build Coastguard Worker 
407*61046927SAndroid Build Coastguard Worker static enum radv_force_vrs
radv_parse_force_vrs_config_file(const char * config_file)408*61046927SAndroid Build Coastguard Worker radv_parse_force_vrs_config_file(const char *config_file)
409*61046927SAndroid Build Coastguard Worker {
410*61046927SAndroid Build Coastguard Worker    enum radv_force_vrs force_vrs = RADV_FORCE_VRS_1x1;
411*61046927SAndroid Build Coastguard Worker    char buf[4];
412*61046927SAndroid Build Coastguard Worker    FILE *f;
413*61046927SAndroid Build Coastguard Worker 
414*61046927SAndroid Build Coastguard Worker    f = fopen(config_file, "r");
415*61046927SAndroid Build Coastguard Worker    if (!f) {
416*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "radv: Can't open file: '%s'.\n", config_file);
417*61046927SAndroid Build Coastguard Worker       return force_vrs;
418*61046927SAndroid Build Coastguard Worker    }
419*61046927SAndroid Build Coastguard Worker 
420*61046927SAndroid Build Coastguard Worker    if (fread(buf, sizeof(buf), 1, f) == 1) {
421*61046927SAndroid Build Coastguard Worker       buf[3] = '\0';
422*61046927SAndroid Build Coastguard Worker       force_vrs = radv_parse_vrs_rates(buf);
423*61046927SAndroid Build Coastguard Worker    }
424*61046927SAndroid Build Coastguard Worker 
425*61046927SAndroid Build Coastguard Worker    fclose(f);
426*61046927SAndroid Build Coastguard Worker    return force_vrs;
427*61046927SAndroid Build Coastguard Worker }
428*61046927SAndroid Build Coastguard Worker 
429*61046927SAndroid Build Coastguard Worker #ifdef __linux__
430*61046927SAndroid Build Coastguard Worker 
431*61046927SAndroid Build Coastguard Worker #define BUF_LEN ((10 * (sizeof(struct inotify_event) + NAME_MAX + 1)))
432*61046927SAndroid Build Coastguard Worker 
433*61046927SAndroid Build Coastguard Worker static int
radv_notifier_thread_run(void * data)434*61046927SAndroid Build Coastguard Worker radv_notifier_thread_run(void *data)
435*61046927SAndroid Build Coastguard Worker {
436*61046927SAndroid Build Coastguard Worker    struct radv_device *device = data;
437*61046927SAndroid Build Coastguard Worker    struct radv_notifier *notifier = &device->notifier;
438*61046927SAndroid Build Coastguard Worker    char buf[BUF_LEN];
439*61046927SAndroid Build Coastguard Worker 
440*61046927SAndroid Build Coastguard Worker    while (!notifier->quit) {
441*61046927SAndroid Build Coastguard Worker       const char *file = radv_get_force_vrs_config_file();
442*61046927SAndroid Build Coastguard Worker       struct timespec tm = {.tv_nsec = 100000000}; /* 1OOms */
443*61046927SAndroid Build Coastguard Worker       int length, i = 0;
444*61046927SAndroid Build Coastguard Worker 
445*61046927SAndroid Build Coastguard Worker       length = read(notifier->fd, buf, BUF_LEN);
446*61046927SAndroid Build Coastguard Worker       while (i < length) {
447*61046927SAndroid Build Coastguard Worker          struct inotify_event *event = (struct inotify_event *)&buf[i];
448*61046927SAndroid Build Coastguard Worker 
449*61046927SAndroid Build Coastguard Worker          i += sizeof(struct inotify_event) + event->len;
450*61046927SAndroid Build Coastguard Worker          if (event->mask & IN_MODIFY || event->mask & IN_DELETE_SELF) {
451*61046927SAndroid Build Coastguard Worker             /* Sleep 100ms for editors that use a temporary file and delete the original. */
452*61046927SAndroid Build Coastguard Worker             thrd_sleep(&tm, NULL);
453*61046927SAndroid Build Coastguard Worker             device->force_vrs = radv_parse_force_vrs_config_file(file);
454*61046927SAndroid Build Coastguard Worker 
455*61046927SAndroid Build Coastguard Worker             fprintf(stderr, "radv: Updated the per-vertex VRS rate to '%d'.\n", device->force_vrs);
456*61046927SAndroid Build Coastguard Worker 
457*61046927SAndroid Build Coastguard Worker             if (event->mask & IN_DELETE_SELF) {
458*61046927SAndroid Build Coastguard Worker                inotify_rm_watch(notifier->fd, notifier->watch);
459*61046927SAndroid Build Coastguard Worker                notifier->watch = inotify_add_watch(notifier->fd, file, IN_MODIFY | IN_DELETE_SELF);
460*61046927SAndroid Build Coastguard Worker             }
461*61046927SAndroid Build Coastguard Worker          }
462*61046927SAndroid Build Coastguard Worker       }
463*61046927SAndroid Build Coastguard Worker 
464*61046927SAndroid Build Coastguard Worker       thrd_sleep(&tm, NULL);
465*61046927SAndroid Build Coastguard Worker    }
466*61046927SAndroid Build Coastguard Worker 
467*61046927SAndroid Build Coastguard Worker    return 0;
468*61046927SAndroid Build Coastguard Worker }
469*61046927SAndroid Build Coastguard Worker 
470*61046927SAndroid Build Coastguard Worker #endif
471*61046927SAndroid Build Coastguard Worker 
472*61046927SAndroid Build Coastguard Worker static int
radv_device_init_notifier(struct radv_device * device)473*61046927SAndroid Build Coastguard Worker radv_device_init_notifier(struct radv_device *device)
474*61046927SAndroid Build Coastguard Worker {
475*61046927SAndroid Build Coastguard Worker #ifndef __linux__
476*61046927SAndroid Build Coastguard Worker    return true;
477*61046927SAndroid Build Coastguard Worker #else
478*61046927SAndroid Build Coastguard Worker    struct radv_notifier *notifier = &device->notifier;
479*61046927SAndroid Build Coastguard Worker    const char *file = radv_get_force_vrs_config_file();
480*61046927SAndroid Build Coastguard Worker    int ret;
481*61046927SAndroid Build Coastguard Worker 
482*61046927SAndroid Build Coastguard Worker    notifier->fd = inotify_init1(IN_NONBLOCK);
483*61046927SAndroid Build Coastguard Worker    if (notifier->fd < 0)
484*61046927SAndroid Build Coastguard Worker       return false;
485*61046927SAndroid Build Coastguard Worker 
486*61046927SAndroid Build Coastguard Worker    notifier->watch = inotify_add_watch(notifier->fd, file, IN_MODIFY | IN_DELETE_SELF);
487*61046927SAndroid Build Coastguard Worker    if (notifier->watch < 0)
488*61046927SAndroid Build Coastguard Worker       goto fail_watch;
489*61046927SAndroid Build Coastguard Worker 
490*61046927SAndroid Build Coastguard Worker    ret = thrd_create(&notifier->thread, radv_notifier_thread_run, device);
491*61046927SAndroid Build Coastguard Worker    if (ret)
492*61046927SAndroid Build Coastguard Worker       goto fail_thread;
493*61046927SAndroid Build Coastguard Worker 
494*61046927SAndroid Build Coastguard Worker    return true;
495*61046927SAndroid Build Coastguard Worker 
496*61046927SAndroid Build Coastguard Worker fail_thread:
497*61046927SAndroid Build Coastguard Worker    inotify_rm_watch(notifier->fd, notifier->watch);
498*61046927SAndroid Build Coastguard Worker fail_watch:
499*61046927SAndroid Build Coastguard Worker    close(notifier->fd);
500*61046927SAndroid Build Coastguard Worker 
501*61046927SAndroid Build Coastguard Worker    return false;
502*61046927SAndroid Build Coastguard Worker #endif
503*61046927SAndroid Build Coastguard Worker }
504*61046927SAndroid Build Coastguard Worker 
505*61046927SAndroid Build Coastguard Worker static void
radv_device_finish_notifier(struct radv_device * device)506*61046927SAndroid Build Coastguard Worker radv_device_finish_notifier(struct radv_device *device)
507*61046927SAndroid Build Coastguard Worker {
508*61046927SAndroid Build Coastguard Worker #ifdef __linux__
509*61046927SAndroid Build Coastguard Worker    struct radv_notifier *notifier = &device->notifier;
510*61046927SAndroid Build Coastguard Worker 
511*61046927SAndroid Build Coastguard Worker    if (!notifier->thread)
512*61046927SAndroid Build Coastguard Worker       return;
513*61046927SAndroid Build Coastguard Worker 
514*61046927SAndroid Build Coastguard Worker    notifier->quit = true;
515*61046927SAndroid Build Coastguard Worker    thrd_join(notifier->thread, NULL);
516*61046927SAndroid Build Coastguard Worker    inotify_rm_watch(notifier->fd, notifier->watch);
517*61046927SAndroid Build Coastguard Worker    close(notifier->fd);
518*61046927SAndroid Build Coastguard Worker #endif
519*61046927SAndroid Build Coastguard Worker }
520*61046927SAndroid Build Coastguard Worker 
521*61046927SAndroid Build Coastguard Worker static VkResult
radv_device_init_perf_counter(struct radv_device * device)522*61046927SAndroid Build Coastguard Worker radv_device_init_perf_counter(struct radv_device *device)
523*61046927SAndroid Build Coastguard Worker {
524*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
525*61046927SAndroid Build Coastguard Worker    const size_t bo_size = PERF_CTR_BO_PASS_OFFSET + sizeof(uint64_t) * PERF_CTR_MAX_PASSES;
526*61046927SAndroid Build Coastguard Worker    VkResult result;
527*61046927SAndroid Build Coastguard Worker 
528*61046927SAndroid Build Coastguard Worker    result = radv_bo_create(device, NULL, bo_size, 4096, RADEON_DOMAIN_GTT,
529*61046927SAndroid Build Coastguard Worker                            RADEON_FLAG_CPU_ACCESS | RADEON_FLAG_NO_INTERPROCESS_SHARING, RADV_BO_PRIORITY_UPLOAD_BUFFER,
530*61046927SAndroid Build Coastguard Worker                            0, true, &device->perf_counter_bo);
531*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
532*61046927SAndroid Build Coastguard Worker       return result;
533*61046927SAndroid Build Coastguard Worker 
534*61046927SAndroid Build Coastguard Worker    device->perf_counter_lock_cs = calloc(sizeof(struct radeon_winsys_cs *), 2 * PERF_CTR_MAX_PASSES);
535*61046927SAndroid Build Coastguard Worker    if (!device->perf_counter_lock_cs)
536*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
537*61046927SAndroid Build Coastguard Worker 
538*61046927SAndroid Build Coastguard Worker    if (!pdev->ac_perfcounters.blocks)
539*61046927SAndroid Build Coastguard Worker       return VK_ERROR_INITIALIZATION_FAILED;
540*61046927SAndroid Build Coastguard Worker 
541*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
542*61046927SAndroid Build Coastguard Worker }
543*61046927SAndroid Build Coastguard Worker 
544*61046927SAndroid Build Coastguard Worker static void
radv_device_finish_perf_counter(struct radv_device * device)545*61046927SAndroid Build Coastguard Worker radv_device_finish_perf_counter(struct radv_device *device)
546*61046927SAndroid Build Coastguard Worker {
547*61046927SAndroid Build Coastguard Worker    if (device->perf_counter_bo)
548*61046927SAndroid Build Coastguard Worker       radv_bo_destroy(device, NULL, device->perf_counter_bo);
549*61046927SAndroid Build Coastguard Worker 
550*61046927SAndroid Build Coastguard Worker    if (!device->perf_counter_lock_cs)
551*61046927SAndroid Build Coastguard Worker       return;
552*61046927SAndroid Build Coastguard Worker 
553*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < 2 * PERF_CTR_MAX_PASSES; ++i) {
554*61046927SAndroid Build Coastguard Worker       if (device->perf_counter_lock_cs[i])
555*61046927SAndroid Build Coastguard Worker          device->ws->cs_destroy(device->perf_counter_lock_cs[i]);
556*61046927SAndroid Build Coastguard Worker    }
557*61046927SAndroid Build Coastguard Worker 
558*61046927SAndroid Build Coastguard Worker    free(device->perf_counter_lock_cs);
559*61046927SAndroid Build Coastguard Worker }
560*61046927SAndroid Build Coastguard Worker 
561*61046927SAndroid Build Coastguard Worker static VkResult
radv_device_init_memory_cache(struct radv_device * device)562*61046927SAndroid Build Coastguard Worker radv_device_init_memory_cache(struct radv_device *device)
563*61046927SAndroid Build Coastguard Worker {
564*61046927SAndroid Build Coastguard Worker    struct vk_pipeline_cache_create_info info = {.weak_ref = true};
565*61046927SAndroid Build Coastguard Worker 
566*61046927SAndroid Build Coastguard Worker    device->mem_cache = vk_pipeline_cache_create(&device->vk, &info, NULL);
567*61046927SAndroid Build Coastguard Worker    if (!device->mem_cache)
568*61046927SAndroid Build Coastguard Worker       return VK_ERROR_OUT_OF_HOST_MEMORY;
569*61046927SAndroid Build Coastguard Worker 
570*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
571*61046927SAndroid Build Coastguard Worker }
572*61046927SAndroid Build Coastguard Worker 
573*61046927SAndroid Build Coastguard Worker static void
radv_device_finish_memory_cache(struct radv_device * device)574*61046927SAndroid Build Coastguard Worker radv_device_finish_memory_cache(struct radv_device *device)
575*61046927SAndroid Build Coastguard Worker {
576*61046927SAndroid Build Coastguard Worker    if (device->mem_cache)
577*61046927SAndroid Build Coastguard Worker       vk_pipeline_cache_destroy(device->mem_cache, NULL);
578*61046927SAndroid Build Coastguard Worker }
579*61046927SAndroid Build Coastguard Worker 
580*61046927SAndroid Build Coastguard Worker static VkResult
radv_device_init_rgp(struct radv_device * device)581*61046927SAndroid Build Coastguard Worker radv_device_init_rgp(struct radv_device *device)
582*61046927SAndroid Build Coastguard Worker {
583*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
584*61046927SAndroid Build Coastguard Worker    const struct radv_instance *instance = radv_physical_device_instance(pdev);
585*61046927SAndroid Build Coastguard Worker 
586*61046927SAndroid Build Coastguard Worker    if (!(instance->vk.trace_mode & RADV_TRACE_MODE_RGP))
587*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
588*61046927SAndroid Build Coastguard Worker 
589*61046927SAndroid Build Coastguard Worker    if (pdev->info.gfx_level < GFX8 || pdev->info.gfx_level > GFX11_5) {
590*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "GPU hardware not supported: refer to "
591*61046927SAndroid Build Coastguard Worker                       "the RGP documentation for the list of "
592*61046927SAndroid Build Coastguard Worker                       "supported GPUs!\n");
593*61046927SAndroid Build Coastguard Worker       abort();
594*61046927SAndroid Build Coastguard Worker    }
595*61046927SAndroid Build Coastguard Worker 
596*61046927SAndroid Build Coastguard Worker    if (!radv_sqtt_init(device))
597*61046927SAndroid Build Coastguard Worker       return VK_ERROR_INITIALIZATION_FAILED;
598*61046927SAndroid Build Coastguard Worker 
599*61046927SAndroid Build Coastguard Worker    fprintf(stderr,
600*61046927SAndroid Build Coastguard Worker            "radv: Thread trace support is enabled (initial buffer size: %u MiB, "
601*61046927SAndroid Build Coastguard Worker            "instruction timing: %s, cache counters: %s, queue events: %s).\n",
602*61046927SAndroid Build Coastguard Worker            device->sqtt.buffer_size / (1024 * 1024), radv_is_instruction_timing_enabled() ? "enabled" : "disabled",
603*61046927SAndroid Build Coastguard Worker            radv_spm_trace_enabled(instance) ? "enabled" : "disabled",
604*61046927SAndroid Build Coastguard Worker            radv_sqtt_queue_events_enabled() ? "enabled" : "disabled");
605*61046927SAndroid Build Coastguard Worker 
606*61046927SAndroid Build Coastguard Worker    if (radv_spm_trace_enabled(instance)) {
607*61046927SAndroid Build Coastguard Worker       if (pdev->info.gfx_level >= GFX10 && pdev->info.gfx_level < GFX11_5) {
608*61046927SAndroid Build Coastguard Worker          if (!radv_spm_init(device))
609*61046927SAndroid Build Coastguard Worker             return VK_ERROR_INITIALIZATION_FAILED;
610*61046927SAndroid Build Coastguard Worker       } else {
611*61046927SAndroid Build Coastguard Worker          fprintf(stderr, "radv: SPM isn't supported for this GPU (%s)!\n", pdev->name);
612*61046927SAndroid Build Coastguard Worker       }
613*61046927SAndroid Build Coastguard Worker    }
614*61046927SAndroid Build Coastguard Worker 
615*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
616*61046927SAndroid Build Coastguard Worker }
617*61046927SAndroid Build Coastguard Worker 
618*61046927SAndroid Build Coastguard Worker static void
radv_device_finish_rgp(struct radv_device * device)619*61046927SAndroid Build Coastguard Worker radv_device_finish_rgp(struct radv_device *device)
620*61046927SAndroid Build Coastguard Worker {
621*61046927SAndroid Build Coastguard Worker    radv_sqtt_finish(device);
622*61046927SAndroid Build Coastguard Worker    radv_spm_finish(device);
623*61046927SAndroid Build Coastguard Worker }
624*61046927SAndroid Build Coastguard Worker 
625*61046927SAndroid Build Coastguard Worker static void
radv_device_init_rmv(struct radv_device * device)626*61046927SAndroid Build Coastguard Worker radv_device_init_rmv(struct radv_device *device)
627*61046927SAndroid Build Coastguard Worker {
628*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
629*61046927SAndroid Build Coastguard Worker    const struct radv_instance *instance = radv_physical_device_instance(pdev);
630*61046927SAndroid Build Coastguard Worker 
631*61046927SAndroid Build Coastguard Worker    if (!(instance->vk.trace_mode & VK_TRACE_MODE_RMV))
632*61046927SAndroid Build Coastguard Worker       return;
633*61046927SAndroid Build Coastguard Worker 
634*61046927SAndroid Build Coastguard Worker    struct vk_rmv_device_info info;
635*61046927SAndroid Build Coastguard Worker    memset(&info, 0, sizeof(struct vk_rmv_device_info));
636*61046927SAndroid Build Coastguard Worker    radv_rmv_fill_device_info(pdev, &info);
637*61046927SAndroid Build Coastguard Worker    vk_memory_trace_init(&device->vk, &info);
638*61046927SAndroid Build Coastguard Worker    radv_memory_trace_init(device);
639*61046927SAndroid Build Coastguard Worker }
640*61046927SAndroid Build Coastguard Worker 
641*61046927SAndroid Build Coastguard Worker static VkResult
radv_device_init_trap_handler(struct radv_device * device)642*61046927SAndroid Build Coastguard Worker radv_device_init_trap_handler(struct radv_device *device)
643*61046927SAndroid Build Coastguard Worker {
644*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
645*61046927SAndroid Build Coastguard Worker 
646*61046927SAndroid Build Coastguard Worker    if (!radv_trap_handler_enabled())
647*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
648*61046927SAndroid Build Coastguard Worker 
649*61046927SAndroid Build Coastguard Worker    /* TODO: Add support for more hardware. */
650*61046927SAndroid Build Coastguard Worker    assert(pdev->info.gfx_level == GFX8);
651*61046927SAndroid Build Coastguard Worker 
652*61046927SAndroid Build Coastguard Worker    fprintf(stderr, "**********************************************************************\n");
653*61046927SAndroid Build Coastguard Worker    fprintf(stderr, "* WARNING: RADV_TRAP_HANDLER is experimental and only for debugging! *\n");
654*61046927SAndroid Build Coastguard Worker    fprintf(stderr, "**********************************************************************\n");
655*61046927SAndroid Build Coastguard Worker 
656*61046927SAndroid Build Coastguard Worker    if (!radv_trap_handler_init(device))
657*61046927SAndroid Build Coastguard Worker       return VK_ERROR_INITIALIZATION_FAILED;
658*61046927SAndroid Build Coastguard Worker 
659*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
660*61046927SAndroid Build Coastguard Worker }
661*61046927SAndroid Build Coastguard Worker 
662*61046927SAndroid Build Coastguard Worker static VkResult
radv_device_init_device_fault_detection(struct radv_device * device)663*61046927SAndroid Build Coastguard Worker radv_device_init_device_fault_detection(struct radv_device *device)
664*61046927SAndroid Build Coastguard Worker {
665*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
666*61046927SAndroid Build Coastguard Worker    struct radv_instance *instance = radv_physical_device_instance(pdev);
667*61046927SAndroid Build Coastguard Worker 
668*61046927SAndroid Build Coastguard Worker    if (!radv_device_fault_detection_enabled(device))
669*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
670*61046927SAndroid Build Coastguard Worker 
671*61046927SAndroid Build Coastguard Worker    if (!radv_init_trace(device))
672*61046927SAndroid Build Coastguard Worker       return VK_ERROR_INITIALIZATION_FAILED;
673*61046927SAndroid Build Coastguard Worker 
674*61046927SAndroid Build Coastguard Worker    fprintf(stderr, "*****************************************************************************\n");
675*61046927SAndroid Build Coastguard Worker    fprintf(stderr, "* WARNING: RADV_DEBUG=hang is costly and should only be used for debugging! *\n");
676*61046927SAndroid Build Coastguard Worker    fprintf(stderr, "*****************************************************************************\n");
677*61046927SAndroid Build Coastguard Worker 
678*61046927SAndroid Build Coastguard Worker    /* Wait for idle after every draw/dispatch to identify the
679*61046927SAndroid Build Coastguard Worker     * first bad call.
680*61046927SAndroid Build Coastguard Worker     */
681*61046927SAndroid Build Coastguard Worker    instance->debug_flags |= RADV_DEBUG_SYNC_SHADERS;
682*61046927SAndroid Build Coastguard Worker 
683*61046927SAndroid Build Coastguard Worker    radv_dump_enabled_options(device, stderr);
684*61046927SAndroid Build Coastguard Worker 
685*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
686*61046927SAndroid Build Coastguard Worker }
687*61046927SAndroid Build Coastguard Worker 
688*61046927SAndroid Build Coastguard Worker static void
radv_device_finish_device_fault_detection(struct radv_device * device)689*61046927SAndroid Build Coastguard Worker radv_device_finish_device_fault_detection(struct radv_device *device)
690*61046927SAndroid Build Coastguard Worker {
691*61046927SAndroid Build Coastguard Worker    radv_finish_trace(device);
692*61046927SAndroid Build Coastguard Worker    ralloc_free(device->gpu_hang_report);
693*61046927SAndroid Build Coastguard Worker }
694*61046927SAndroid Build Coastguard Worker 
695*61046927SAndroid Build Coastguard Worker static VkResult
radv_device_init_tools(struct radv_device * device)696*61046927SAndroid Build Coastguard Worker radv_device_init_tools(struct radv_device *device)
697*61046927SAndroid Build Coastguard Worker {
698*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
699*61046927SAndroid Build Coastguard Worker    struct radv_instance *instance = radv_physical_device_instance(pdev);
700*61046927SAndroid Build Coastguard Worker    VkResult result;
701*61046927SAndroid Build Coastguard Worker 
702*61046927SAndroid Build Coastguard Worker    result = radv_device_init_device_fault_detection(device);
703*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
704*61046927SAndroid Build Coastguard Worker       return result;
705*61046927SAndroid Build Coastguard Worker 
706*61046927SAndroid Build Coastguard Worker    result = radv_device_init_rgp(device);
707*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
708*61046927SAndroid Build Coastguard Worker       return result;
709*61046927SAndroid Build Coastguard Worker 
710*61046927SAndroid Build Coastguard Worker    radv_device_init_rmv(device);
711*61046927SAndroid Build Coastguard Worker 
712*61046927SAndroid Build Coastguard Worker    result = radv_device_init_trap_handler(device);
713*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
714*61046927SAndroid Build Coastguard Worker       return result;
715*61046927SAndroid Build Coastguard Worker 
716*61046927SAndroid Build Coastguard Worker    if ((instance->vk.trace_mode & RADV_TRACE_MODE_RRA) && radv_enable_rt(pdev, false)) {
717*61046927SAndroid Build Coastguard Worker       result = radv_rra_trace_init(device);
718*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
719*61046927SAndroid Build Coastguard Worker          return result;
720*61046927SAndroid Build Coastguard Worker    }
721*61046927SAndroid Build Coastguard Worker 
722*61046927SAndroid Build Coastguard Worker    result = radv_printf_data_init(device);
723*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
724*61046927SAndroid Build Coastguard Worker       return result;
725*61046927SAndroid Build Coastguard Worker 
726*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
727*61046927SAndroid Build Coastguard Worker }
728*61046927SAndroid Build Coastguard Worker 
729*61046927SAndroid Build Coastguard Worker static void
radv_device_finish_tools(struct radv_device * device)730*61046927SAndroid Build Coastguard Worker radv_device_finish_tools(struct radv_device *device)
731*61046927SAndroid Build Coastguard Worker {
732*61046927SAndroid Build Coastguard Worker    radv_printf_data_finish(device);
733*61046927SAndroid Build Coastguard Worker    radv_rra_trace_finish(radv_device_to_handle(device), &device->rra_trace);
734*61046927SAndroid Build Coastguard Worker    radv_trap_handler_finish(device);
735*61046927SAndroid Build Coastguard Worker    radv_memory_trace_finish(device);
736*61046927SAndroid Build Coastguard Worker    radv_device_finish_rgp(device);
737*61046927SAndroid Build Coastguard Worker    radv_device_finish_device_fault_detection(device);
738*61046927SAndroid Build Coastguard Worker }
739*61046927SAndroid Build Coastguard Worker 
740*61046927SAndroid Build Coastguard Worker struct dispatch_table_builder {
741*61046927SAndroid Build Coastguard Worker    struct vk_device_dispatch_table *tables[RADV_DISPATCH_TABLE_COUNT];
742*61046927SAndroid Build Coastguard Worker    bool used[RADV_DISPATCH_TABLE_COUNT];
743*61046927SAndroid Build Coastguard Worker    bool initialized[RADV_DISPATCH_TABLE_COUNT];
744*61046927SAndroid Build Coastguard Worker };
745*61046927SAndroid Build Coastguard Worker 
746*61046927SAndroid Build Coastguard Worker static void
add_entrypoints(struct dispatch_table_builder * b,const struct vk_device_entrypoint_table * entrypoints,enum radv_dispatch_table table)747*61046927SAndroid Build Coastguard Worker add_entrypoints(struct dispatch_table_builder *b, const struct vk_device_entrypoint_table *entrypoints,
748*61046927SAndroid Build Coastguard Worker                 enum radv_dispatch_table table)
749*61046927SAndroid Build Coastguard Worker {
750*61046927SAndroid Build Coastguard Worker    for (int32_t i = table - 1; i >= RADV_DEVICE_DISPATCH_TABLE; i--) {
751*61046927SAndroid Build Coastguard Worker       if (i == RADV_DEVICE_DISPATCH_TABLE || b->used[i]) {
752*61046927SAndroid Build Coastguard Worker          vk_device_dispatch_table_from_entrypoints(b->tables[i], entrypoints, !b->initialized[i]);
753*61046927SAndroid Build Coastguard Worker          b->initialized[i] = true;
754*61046927SAndroid Build Coastguard Worker       }
755*61046927SAndroid Build Coastguard Worker    }
756*61046927SAndroid Build Coastguard Worker 
757*61046927SAndroid Build Coastguard Worker    if (table < RADV_DISPATCH_TABLE_COUNT)
758*61046927SAndroid Build Coastguard Worker       b->used[table] = true;
759*61046927SAndroid Build Coastguard Worker }
760*61046927SAndroid Build Coastguard Worker 
761*61046927SAndroid Build Coastguard Worker static void
init_dispatch_tables(struct radv_device * device,struct radv_physical_device * pdev)762*61046927SAndroid Build Coastguard Worker init_dispatch_tables(struct radv_device *device, struct radv_physical_device *pdev)
763*61046927SAndroid Build Coastguard Worker {
764*61046927SAndroid Build Coastguard Worker    const struct radv_instance *instance = radv_physical_device_instance(pdev);
765*61046927SAndroid Build Coastguard Worker    struct dispatch_table_builder b = {0};
766*61046927SAndroid Build Coastguard Worker    b.tables[RADV_DEVICE_DISPATCH_TABLE] = &device->vk.dispatch_table;
767*61046927SAndroid Build Coastguard Worker    b.tables[RADV_ANNOTATE_DISPATCH_TABLE] = &device->layer_dispatch.annotate;
768*61046927SAndroid Build Coastguard Worker    b.tables[RADV_APP_DISPATCH_TABLE] = &device->layer_dispatch.app;
769*61046927SAndroid Build Coastguard Worker    b.tables[RADV_RGP_DISPATCH_TABLE] = &device->layer_dispatch.rgp;
770*61046927SAndroid Build Coastguard Worker    b.tables[RADV_RRA_DISPATCH_TABLE] = &device->layer_dispatch.rra;
771*61046927SAndroid Build Coastguard Worker    b.tables[RADV_RMV_DISPATCH_TABLE] = &device->layer_dispatch.rmv;
772*61046927SAndroid Build Coastguard Worker    b.tables[RADV_CTX_ROLL_DISPATCH_TABLE] = &device->layer_dispatch.ctx_roll;
773*61046927SAndroid Build Coastguard Worker 
774*61046927SAndroid Build Coastguard Worker    bool gather_ctx_rolls = instance->vk.trace_mode & RADV_TRACE_MODE_CTX_ROLLS;
775*61046927SAndroid Build Coastguard Worker    if (radv_device_fault_detection_enabled(device) || gather_ctx_rolls)
776*61046927SAndroid Build Coastguard Worker       add_entrypoints(&b, &annotate_device_entrypoints, RADV_ANNOTATE_DISPATCH_TABLE);
777*61046927SAndroid Build Coastguard Worker 
778*61046927SAndroid Build Coastguard Worker    if (!strcmp(instance->drirc.app_layer, "metroexodus")) {
779*61046927SAndroid Build Coastguard Worker       add_entrypoints(&b, &metro_exodus_device_entrypoints, RADV_APP_DISPATCH_TABLE);
780*61046927SAndroid Build Coastguard Worker    } else if (!strcmp(instance->drirc.app_layer, "rage2")) {
781*61046927SAndroid Build Coastguard Worker       add_entrypoints(&b, &rage2_device_entrypoints, RADV_APP_DISPATCH_TABLE);
782*61046927SAndroid Build Coastguard Worker    } else if (!strcmp(instance->drirc.app_layer, "quanticdream")) {
783*61046927SAndroid Build Coastguard Worker       add_entrypoints(&b, &quantic_dream_device_entrypoints, RADV_APP_DISPATCH_TABLE);
784*61046927SAndroid Build Coastguard Worker    }
785*61046927SAndroid Build Coastguard Worker 
786*61046927SAndroid Build Coastguard Worker    if (instance->vk.trace_mode & RADV_TRACE_MODE_RGP)
787*61046927SAndroid Build Coastguard Worker       add_entrypoints(&b, &sqtt_device_entrypoints, RADV_RGP_DISPATCH_TABLE);
788*61046927SAndroid Build Coastguard Worker 
789*61046927SAndroid Build Coastguard Worker    if ((instance->vk.trace_mode & RADV_TRACE_MODE_RRA) && radv_enable_rt(pdev, false))
790*61046927SAndroid Build Coastguard Worker       add_entrypoints(&b, &rra_device_entrypoints, RADV_RRA_DISPATCH_TABLE);
791*61046927SAndroid Build Coastguard Worker 
792*61046927SAndroid Build Coastguard Worker #ifndef _WIN32
793*61046927SAndroid Build Coastguard Worker    if (instance->vk.trace_mode & VK_TRACE_MODE_RMV)
794*61046927SAndroid Build Coastguard Worker       add_entrypoints(&b, &rmv_device_entrypoints, RADV_RMV_DISPATCH_TABLE);
795*61046927SAndroid Build Coastguard Worker #endif
796*61046927SAndroid Build Coastguard Worker 
797*61046927SAndroid Build Coastguard Worker    if (gather_ctx_rolls)
798*61046927SAndroid Build Coastguard Worker       add_entrypoints(&b, &ctx_roll_device_entrypoints, RADV_CTX_ROLL_DISPATCH_TABLE);
799*61046927SAndroid Build Coastguard Worker 
800*61046927SAndroid Build Coastguard Worker    add_entrypoints(&b, &radv_device_entrypoints, RADV_DISPATCH_TABLE_COUNT);
801*61046927SAndroid Build Coastguard Worker    add_entrypoints(&b, &wsi_device_entrypoints, RADV_DISPATCH_TABLE_COUNT);
802*61046927SAndroid Build Coastguard Worker    add_entrypoints(&b, &vk_common_device_entrypoints, RADV_DISPATCH_TABLE_COUNT);
803*61046927SAndroid Build Coastguard Worker }
804*61046927SAndroid Build Coastguard Worker 
805*61046927SAndroid Build Coastguard Worker static VkResult
capture_trace(VkQueue _queue)806*61046927SAndroid Build Coastguard Worker capture_trace(VkQueue _queue)
807*61046927SAndroid Build Coastguard Worker {
808*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(radv_queue, queue, _queue);
809*61046927SAndroid Build Coastguard Worker    struct radv_device *device = radv_queue_device(queue);
810*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
811*61046927SAndroid Build Coastguard Worker    const struct radv_instance *instance = radv_physical_device_instance(pdev);
812*61046927SAndroid Build Coastguard Worker 
813*61046927SAndroid Build Coastguard Worker    VkResult result = VK_SUCCESS;
814*61046927SAndroid Build Coastguard Worker 
815*61046927SAndroid Build Coastguard Worker    if (instance->vk.trace_mode & RADV_TRACE_MODE_RRA)
816*61046927SAndroid Build Coastguard Worker       device->rra_trace.triggered = true;
817*61046927SAndroid Build Coastguard Worker 
818*61046927SAndroid Build Coastguard Worker    if (device->vk.memory_trace_data.is_enabled) {
819*61046927SAndroid Build Coastguard Worker       simple_mtx_lock(&device->vk.memory_trace_data.token_mtx);
820*61046927SAndroid Build Coastguard Worker       radv_rmv_collect_trace_events(device);
821*61046927SAndroid Build Coastguard Worker       vk_dump_rmv_capture(&device->vk.memory_trace_data);
822*61046927SAndroid Build Coastguard Worker       simple_mtx_unlock(&device->vk.memory_trace_data.token_mtx);
823*61046927SAndroid Build Coastguard Worker    }
824*61046927SAndroid Build Coastguard Worker 
825*61046927SAndroid Build Coastguard Worker    if (instance->vk.trace_mode & RADV_TRACE_MODE_RGP)
826*61046927SAndroid Build Coastguard Worker       device->sqtt_triggered = true;
827*61046927SAndroid Build Coastguard Worker 
828*61046927SAndroid Build Coastguard Worker    if (instance->vk.trace_mode & RADV_TRACE_MODE_CTX_ROLLS) {
829*61046927SAndroid Build Coastguard Worker       char filename[2048];
830*61046927SAndroid Build Coastguard Worker       time_t t = time(NULL);
831*61046927SAndroid Build Coastguard Worker       struct tm now = *localtime(&t);
832*61046927SAndroid Build Coastguard Worker       snprintf(filename, sizeof(filename), "/tmp/%s_%04d.%02d.%02d_%02d.%02d.%02d.ctxroll", util_get_process_name(),
833*61046927SAndroid Build Coastguard Worker                1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec);
834*61046927SAndroid Build Coastguard Worker 
835*61046927SAndroid Build Coastguard Worker       simple_mtx_lock(&device->ctx_roll_mtx);
836*61046927SAndroid Build Coastguard Worker 
837*61046927SAndroid Build Coastguard Worker       device->ctx_roll_file = fopen(filename, "w");
838*61046927SAndroid Build Coastguard Worker       if (device->ctx_roll_file)
839*61046927SAndroid Build Coastguard Worker          fprintf(stderr, "radv: Writing context rolls to '%s'...\n", filename);
840*61046927SAndroid Build Coastguard Worker 
841*61046927SAndroid Build Coastguard Worker       simple_mtx_unlock(&device->ctx_roll_mtx);
842*61046927SAndroid Build Coastguard Worker    }
843*61046927SAndroid Build Coastguard Worker 
844*61046927SAndroid Build Coastguard Worker    return result;
845*61046927SAndroid Build Coastguard Worker }
846*61046927SAndroid Build Coastguard Worker 
847*61046927SAndroid Build Coastguard Worker static void
radv_device_init_cache_key(struct radv_device * device)848*61046927SAndroid Build Coastguard Worker radv_device_init_cache_key(struct radv_device *device)
849*61046927SAndroid Build Coastguard Worker {
850*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
851*61046927SAndroid Build Coastguard Worker    struct radv_device_cache_key *key = &device->cache_key;
852*61046927SAndroid Build Coastguard Worker 
853*61046927SAndroid Build Coastguard Worker    key->disable_trunc_coord = device->disable_trunc_coord;
854*61046927SAndroid Build Coastguard Worker    key->image_2d_view_of_3d = device->vk.enabled_features.image2DViewOf3D && pdev->info.gfx_level == GFX9;
855*61046927SAndroid Build Coastguard Worker    key->mesh_shader_queries = device->vk.enabled_features.meshShaderQueries;
856*61046927SAndroid Build Coastguard Worker    key->primitives_generated_query = radv_uses_primitives_generated_query(device);
857*61046927SAndroid Build Coastguard Worker 
858*61046927SAndroid Build Coastguard Worker    /* The Vulkan spec says:
859*61046927SAndroid Build Coastguard Worker     *  "Binary shaders retrieved from a physical device with a certain shaderBinaryUUID are
860*61046927SAndroid Build Coastguard Worker     *   guaranteed to be compatible with all other physical devices reporting the same
861*61046927SAndroid Build Coastguard Worker     *   shaderBinaryUUID and the same or higher shaderBinaryVersion."
862*61046927SAndroid Build Coastguard Worker     *
863*61046927SAndroid Build Coastguard Worker     * That means the driver should compile shaders for the "worst" case of all features being
864*61046927SAndroid Build Coastguard Worker     * enabled, regardless of what features are actually enabled on the logical device.
865*61046927SAndroid Build Coastguard Worker     */
866*61046927SAndroid Build Coastguard Worker    if (device->vk.enabled_features.shaderObject) {
867*61046927SAndroid Build Coastguard Worker       key->image_2d_view_of_3d = pdev->info.gfx_level == GFX9;
868*61046927SAndroid Build Coastguard Worker       key->primitives_generated_query = true;
869*61046927SAndroid Build Coastguard Worker    }
870*61046927SAndroid Build Coastguard Worker 
871*61046927SAndroid Build Coastguard Worker    _mesa_blake3_compute(key, sizeof(*key), device->cache_hash);
872*61046927SAndroid Build Coastguard Worker }
873*61046927SAndroid Build Coastguard Worker 
874*61046927SAndroid Build Coastguard Worker static void
radv_create_gfx_preamble(struct radv_device * device)875*61046927SAndroid Build Coastguard Worker radv_create_gfx_preamble(struct radv_device *device)
876*61046927SAndroid Build Coastguard Worker {
877*61046927SAndroid Build Coastguard Worker    struct radeon_cmdbuf *cs = device->ws->cs_create(device->ws, AMD_IP_GFX, false);
878*61046927SAndroid Build Coastguard Worker    if (!cs)
879*61046927SAndroid Build Coastguard Worker       return;
880*61046927SAndroid Build Coastguard Worker 
881*61046927SAndroid Build Coastguard Worker    radeon_check_space(device->ws, cs, 512);
882*61046927SAndroid Build Coastguard Worker 
883*61046927SAndroid Build Coastguard Worker    radv_emit_graphics(device, cs);
884*61046927SAndroid Build Coastguard Worker 
885*61046927SAndroid Build Coastguard Worker    device->ws->cs_pad(cs, 0);
886*61046927SAndroid Build Coastguard Worker 
887*61046927SAndroid Build Coastguard Worker    VkResult result = radv_bo_create(
888*61046927SAndroid Build Coastguard Worker       device, NULL, cs->cdw * 4, 4096, device->ws->cs_domain(device->ws),
889*61046927SAndroid Build Coastguard Worker       RADEON_FLAG_CPU_ACCESS | RADEON_FLAG_NO_INTERPROCESS_SHARING | RADEON_FLAG_READ_ONLY | RADEON_FLAG_GTT_WC,
890*61046927SAndroid Build Coastguard Worker       RADV_BO_PRIORITY_CS, 0, true, &device->gfx_init);
891*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
892*61046927SAndroid Build Coastguard Worker       goto fail;
893*61046927SAndroid Build Coastguard Worker 
894*61046927SAndroid Build Coastguard Worker    void *map = radv_buffer_map(device->ws, device->gfx_init);
895*61046927SAndroid Build Coastguard Worker    if (!map) {
896*61046927SAndroid Build Coastguard Worker       radv_bo_destroy(device, NULL, device->gfx_init);
897*61046927SAndroid Build Coastguard Worker       device->gfx_init = NULL;
898*61046927SAndroid Build Coastguard Worker       goto fail;
899*61046927SAndroid Build Coastguard Worker    }
900*61046927SAndroid Build Coastguard Worker    memcpy(map, cs->buf, cs->cdw * 4);
901*61046927SAndroid Build Coastguard Worker 
902*61046927SAndroid Build Coastguard Worker    device->ws->buffer_unmap(device->ws, device->gfx_init, false);
903*61046927SAndroid Build Coastguard Worker    device->gfx_init_size_dw = cs->cdw;
904*61046927SAndroid Build Coastguard Worker fail:
905*61046927SAndroid Build Coastguard Worker    device->ws->cs_destroy(cs);
906*61046927SAndroid Build Coastguard Worker }
907*61046927SAndroid Build Coastguard Worker 
908*61046927SAndroid Build Coastguard Worker /* For MSAA sample positions. */
909*61046927SAndroid Build Coastguard Worker #define FILL_SREG(s0x, s0y, s1x, s1y, s2x, s2y, s3x, s3y)                                                              \
910*61046927SAndroid Build Coastguard Worker    ((((unsigned)(s0x)&0xf) << 0) | (((unsigned)(s0y)&0xf) << 4) | (((unsigned)(s1x)&0xf) << 8) |                       \
911*61046927SAndroid Build Coastguard Worker     (((unsigned)(s1y)&0xf) << 12) | (((unsigned)(s2x)&0xf) << 16) | (((unsigned)(s2y)&0xf) << 20) |                    \
912*61046927SAndroid Build Coastguard Worker     (((unsigned)(s3x)&0xf) << 24) | (((unsigned)(s3y)&0xf) << 28))
913*61046927SAndroid Build Coastguard Worker 
914*61046927SAndroid Build Coastguard Worker /* For obtaining location coordinates from registers */
915*61046927SAndroid Build Coastguard Worker #define SEXT4(x)               ((int)((x) | ((x)&0x8 ? 0xfffffff0 : 0)))
916*61046927SAndroid Build Coastguard Worker #define GET_SFIELD(reg, index) SEXT4(((reg) >> ((index)*4)) & 0xf)
917*61046927SAndroid Build Coastguard Worker #define GET_SX(reg, index)     GET_SFIELD((reg)[(index) / 4], ((index) % 4) * 2)
918*61046927SAndroid Build Coastguard Worker #define GET_SY(reg, index)     GET_SFIELD((reg)[(index) / 4], ((index) % 4) * 2 + 1)
919*61046927SAndroid Build Coastguard Worker 
920*61046927SAndroid Build Coastguard Worker /* 1x MSAA */
921*61046927SAndroid Build Coastguard Worker static const uint32_t sample_locs_1x = FILL_SREG(0, 0, 0, 0, 0, 0, 0, 0);
922*61046927SAndroid Build Coastguard Worker static const unsigned max_dist_1x = 0;
923*61046927SAndroid Build Coastguard Worker static const uint64_t centroid_priority_1x = 0x0000000000000000ull;
924*61046927SAndroid Build Coastguard Worker 
925*61046927SAndroid Build Coastguard Worker /* 2xMSAA */
926*61046927SAndroid Build Coastguard Worker static const uint32_t sample_locs_2x = FILL_SREG(4, 4, -4, -4, 0, 0, 0, 0);
927*61046927SAndroid Build Coastguard Worker static const unsigned max_dist_2x = 4;
928*61046927SAndroid Build Coastguard Worker static const uint64_t centroid_priority_2x = 0x1010101010101010ull;
929*61046927SAndroid Build Coastguard Worker 
930*61046927SAndroid Build Coastguard Worker /* 4xMSAA */
931*61046927SAndroid Build Coastguard Worker static const uint32_t sample_locs_4x = FILL_SREG(-2, -6, 6, -2, -6, 2, 2, 6);
932*61046927SAndroid Build Coastguard Worker static const unsigned max_dist_4x = 6;
933*61046927SAndroid Build Coastguard Worker static const uint64_t centroid_priority_4x = 0x3210321032103210ull;
934*61046927SAndroid Build Coastguard Worker 
935*61046927SAndroid Build Coastguard Worker /* 8xMSAA */
936*61046927SAndroid Build Coastguard Worker static const uint32_t sample_locs_8x[] = {
937*61046927SAndroid Build Coastguard Worker    FILL_SREG(1, -3, -1, 3, 5, 1, -3, -5),
938*61046927SAndroid Build Coastguard Worker    FILL_SREG(-5, 5, -7, -1, 3, 7, 7, -7),
939*61046927SAndroid Build Coastguard Worker    /* The following are unused by hardware, but we emit them to IBs
940*61046927SAndroid Build Coastguard Worker     * instead of multiple SET_CONTEXT_REG packets. */
941*61046927SAndroid Build Coastguard Worker    0,
942*61046927SAndroid Build Coastguard Worker    0,
943*61046927SAndroid Build Coastguard Worker };
944*61046927SAndroid Build Coastguard Worker static const unsigned max_dist_8x = 7;
945*61046927SAndroid Build Coastguard Worker static const uint64_t centroid_priority_8x = 0x7654321076543210ull;
946*61046927SAndroid Build Coastguard Worker 
947*61046927SAndroid Build Coastguard Worker unsigned
radv_get_default_max_sample_dist(int log_samples)948*61046927SAndroid Build Coastguard Worker radv_get_default_max_sample_dist(int log_samples)
949*61046927SAndroid Build Coastguard Worker {
950*61046927SAndroid Build Coastguard Worker    unsigned max_dist[] = {
951*61046927SAndroid Build Coastguard Worker       max_dist_1x,
952*61046927SAndroid Build Coastguard Worker       max_dist_2x,
953*61046927SAndroid Build Coastguard Worker       max_dist_4x,
954*61046927SAndroid Build Coastguard Worker       max_dist_8x,
955*61046927SAndroid Build Coastguard Worker    };
956*61046927SAndroid Build Coastguard Worker    return max_dist[log_samples];
957*61046927SAndroid Build Coastguard Worker }
958*61046927SAndroid Build Coastguard Worker 
959*61046927SAndroid Build Coastguard Worker void
radv_emit_default_sample_locations(const struct radv_physical_device * pdev,struct radeon_cmdbuf * cs,int nr_samples)960*61046927SAndroid Build Coastguard Worker radv_emit_default_sample_locations(const struct radv_physical_device *pdev, struct radeon_cmdbuf *cs, int nr_samples)
961*61046927SAndroid Build Coastguard Worker {
962*61046927SAndroid Build Coastguard Worker    uint64_t centroid_priority;
963*61046927SAndroid Build Coastguard Worker 
964*61046927SAndroid Build Coastguard Worker    switch (nr_samples) {
965*61046927SAndroid Build Coastguard Worker    default:
966*61046927SAndroid Build Coastguard Worker    case 1:
967*61046927SAndroid Build Coastguard Worker       centroid_priority = centroid_priority_1x;
968*61046927SAndroid Build Coastguard Worker 
969*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg(cs, R_028BF8_PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0, sample_locs_1x);
970*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg(cs, R_028C08_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0, sample_locs_1x);
971*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg(cs, R_028C18_PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0, sample_locs_1x);
972*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg(cs, R_028C28_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0, sample_locs_1x);
973*61046927SAndroid Build Coastguard Worker       break;
974*61046927SAndroid Build Coastguard Worker    case 2:
975*61046927SAndroid Build Coastguard Worker       centroid_priority = centroid_priority_2x;
976*61046927SAndroid Build Coastguard Worker 
977*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg(cs, R_028BF8_PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0, sample_locs_2x);
978*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg(cs, R_028C08_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0, sample_locs_2x);
979*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg(cs, R_028C18_PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0, sample_locs_2x);
980*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg(cs, R_028C28_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0, sample_locs_2x);
981*61046927SAndroid Build Coastguard Worker       break;
982*61046927SAndroid Build Coastguard Worker    case 4:
983*61046927SAndroid Build Coastguard Worker       centroid_priority = centroid_priority_4x;
984*61046927SAndroid Build Coastguard Worker 
985*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg(cs, R_028BF8_PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0, sample_locs_4x);
986*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg(cs, R_028C08_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y0_0, sample_locs_4x);
987*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg(cs, R_028C18_PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y1_0, sample_locs_4x);
988*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg(cs, R_028C28_PA_SC_AA_SAMPLE_LOCS_PIXEL_X1Y1_0, sample_locs_4x);
989*61046927SAndroid Build Coastguard Worker       break;
990*61046927SAndroid Build Coastguard Worker    case 8:
991*61046927SAndroid Build Coastguard Worker       centroid_priority = centroid_priority_8x;
992*61046927SAndroid Build Coastguard Worker 
993*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg_seq(cs, R_028BF8_PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0, 14);
994*61046927SAndroid Build Coastguard Worker       radeon_emit_array(cs, sample_locs_8x, 4);
995*61046927SAndroid Build Coastguard Worker       radeon_emit_array(cs, sample_locs_8x, 4);
996*61046927SAndroid Build Coastguard Worker       radeon_emit_array(cs, sample_locs_8x, 4);
997*61046927SAndroid Build Coastguard Worker       radeon_emit_array(cs, sample_locs_8x, 2);
998*61046927SAndroid Build Coastguard Worker       break;
999*61046927SAndroid Build Coastguard Worker    }
1000*61046927SAndroid Build Coastguard Worker 
1001*61046927SAndroid Build Coastguard Worker    if (pdev->info.gfx_level >= GFX12) {
1002*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg_seq(cs, R_028BF0_PA_SC_CENTROID_PRIORITY_0, 2);
1003*61046927SAndroid Build Coastguard Worker    } else {
1004*61046927SAndroid Build Coastguard Worker       radeon_set_context_reg_seq(cs, R_028BD4_PA_SC_CENTROID_PRIORITY_0, 2);
1005*61046927SAndroid Build Coastguard Worker    }
1006*61046927SAndroid Build Coastguard Worker    radeon_emit(cs, centroid_priority);
1007*61046927SAndroid Build Coastguard Worker    radeon_emit(cs, centroid_priority >> 32);
1008*61046927SAndroid Build Coastguard Worker }
1009*61046927SAndroid Build Coastguard Worker 
1010*61046927SAndroid Build Coastguard Worker static void
radv_get_sample_position(struct radv_device * device,unsigned sample_count,unsigned sample_index,float * out_value)1011*61046927SAndroid Build Coastguard Worker radv_get_sample_position(struct radv_device *device, unsigned sample_count, unsigned sample_index, float *out_value)
1012*61046927SAndroid Build Coastguard Worker {
1013*61046927SAndroid Build Coastguard Worker    const uint32_t *sample_locs;
1014*61046927SAndroid Build Coastguard Worker 
1015*61046927SAndroid Build Coastguard Worker    switch (sample_count) {
1016*61046927SAndroid Build Coastguard Worker    case 1:
1017*61046927SAndroid Build Coastguard Worker    default:
1018*61046927SAndroid Build Coastguard Worker       sample_locs = &sample_locs_1x;
1019*61046927SAndroid Build Coastguard Worker       break;
1020*61046927SAndroid Build Coastguard Worker    case 2:
1021*61046927SAndroid Build Coastguard Worker       sample_locs = &sample_locs_2x;
1022*61046927SAndroid Build Coastguard Worker       break;
1023*61046927SAndroid Build Coastguard Worker    case 4:
1024*61046927SAndroid Build Coastguard Worker       sample_locs = &sample_locs_4x;
1025*61046927SAndroid Build Coastguard Worker       break;
1026*61046927SAndroid Build Coastguard Worker    case 8:
1027*61046927SAndroid Build Coastguard Worker       sample_locs = sample_locs_8x;
1028*61046927SAndroid Build Coastguard Worker       break;
1029*61046927SAndroid Build Coastguard Worker    }
1030*61046927SAndroid Build Coastguard Worker 
1031*61046927SAndroid Build Coastguard Worker    out_value[0] = (GET_SX(sample_locs, sample_index) + 8) / 16.0f;
1032*61046927SAndroid Build Coastguard Worker    out_value[1] = (GET_SY(sample_locs, sample_index) + 8) / 16.0f;
1033*61046927SAndroid Build Coastguard Worker }
1034*61046927SAndroid Build Coastguard Worker 
1035*61046927SAndroid Build Coastguard Worker static void
radv_device_init_msaa(struct radv_device * device)1036*61046927SAndroid Build Coastguard Worker radv_device_init_msaa(struct radv_device *device)
1037*61046927SAndroid Build Coastguard Worker {
1038*61046927SAndroid Build Coastguard Worker    int i;
1039*61046927SAndroid Build Coastguard Worker 
1040*61046927SAndroid Build Coastguard Worker    radv_get_sample_position(device, 1, 0, device->sample_locations_1x[0]);
1041*61046927SAndroid Build Coastguard Worker 
1042*61046927SAndroid Build Coastguard Worker    for (i = 0; i < 2; i++)
1043*61046927SAndroid Build Coastguard Worker       radv_get_sample_position(device, 2, i, device->sample_locations_2x[i]);
1044*61046927SAndroid Build Coastguard Worker    for (i = 0; i < 4; i++)
1045*61046927SAndroid Build Coastguard Worker       radv_get_sample_position(device, 4, i, device->sample_locations_4x[i]);
1046*61046927SAndroid Build Coastguard Worker    for (i = 0; i < 8; i++)
1047*61046927SAndroid Build Coastguard Worker       radv_get_sample_position(device, 8, i, device->sample_locations_8x[i]);
1048*61046927SAndroid Build Coastguard Worker }
1049*61046927SAndroid Build Coastguard Worker 
1050*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
radv_CreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)1051*61046927SAndroid Build Coastguard Worker radv_CreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
1052*61046927SAndroid Build Coastguard Worker                   const VkAllocationCallbacks *pAllocator, VkDevice *pDevice)
1053*61046927SAndroid Build Coastguard Worker {
1054*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(radv_physical_device, pdev, physicalDevice);
1055*61046927SAndroid Build Coastguard Worker    struct radv_instance *instance = radv_physical_device_instance(pdev);
1056*61046927SAndroid Build Coastguard Worker    VkResult result;
1057*61046927SAndroid Build Coastguard Worker    struct radv_device *device;
1058*61046927SAndroid Build Coastguard Worker 
1059*61046927SAndroid Build Coastguard Worker    bool overallocation_disallowed = false;
1060*61046927SAndroid Build Coastguard Worker 
1061*61046927SAndroid Build Coastguard Worker    vk_foreach_struct_const (ext, pCreateInfo->pNext) {
1062*61046927SAndroid Build Coastguard Worker       switch (ext->sType) {
1063*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD: {
1064*61046927SAndroid Build Coastguard Worker          const VkDeviceMemoryOverallocationCreateInfoAMD *overallocation = (const void *)ext;
1065*61046927SAndroid Build Coastguard Worker          if (overallocation->overallocationBehavior == VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD)
1066*61046927SAndroid Build Coastguard Worker             overallocation_disallowed = true;
1067*61046927SAndroid Build Coastguard Worker          break;
1068*61046927SAndroid Build Coastguard Worker       }
1069*61046927SAndroid Build Coastguard Worker       default:
1070*61046927SAndroid Build Coastguard Worker          break;
1071*61046927SAndroid Build Coastguard Worker       }
1072*61046927SAndroid Build Coastguard Worker    }
1073*61046927SAndroid Build Coastguard Worker 
1074*61046927SAndroid Build Coastguard Worker    device = vk_zalloc2(&instance->vk.alloc, pAllocator, sizeof(*device), 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1075*61046927SAndroid Build Coastguard Worker    if (!device)
1076*61046927SAndroid Build Coastguard Worker       return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1077*61046927SAndroid Build Coastguard Worker 
1078*61046927SAndroid Build Coastguard Worker    result = vk_device_init(&device->vk, &pdev->vk, NULL, pCreateInfo, pAllocator);
1079*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS) {
1080*61046927SAndroid Build Coastguard Worker       vk_free(&device->vk.alloc, device);
1081*61046927SAndroid Build Coastguard Worker       return result;
1082*61046927SAndroid Build Coastguard Worker    }
1083*61046927SAndroid Build Coastguard Worker 
1084*61046927SAndroid Build Coastguard Worker    device->vk.capture_trace = capture_trace;
1085*61046927SAndroid Build Coastguard Worker 
1086*61046927SAndroid Build Coastguard Worker    device->vk.command_buffer_ops = &radv_cmd_buffer_ops;
1087*61046927SAndroid Build Coastguard Worker 
1088*61046927SAndroid Build Coastguard Worker    init_dispatch_tables(device, pdev);
1089*61046927SAndroid Build Coastguard Worker 
1090*61046927SAndroid Build Coastguard Worker    simple_mtx_init(&device->ctx_roll_mtx, mtx_plain);
1091*61046927SAndroid Build Coastguard Worker    simple_mtx_init(&device->trace_mtx, mtx_plain);
1092*61046927SAndroid Build Coastguard Worker    simple_mtx_init(&device->pstate_mtx, mtx_plain);
1093*61046927SAndroid Build Coastguard Worker    simple_mtx_init(&device->rt_handles_mtx, mtx_plain);
1094*61046927SAndroid Build Coastguard Worker    simple_mtx_init(&device->compute_scratch_mtx, mtx_plain);
1095*61046927SAndroid Build Coastguard Worker    simple_mtx_init(&device->pso_cache_stats_mtx, mtx_plain);
1096*61046927SAndroid Build Coastguard Worker 
1097*61046927SAndroid Build Coastguard Worker    device->rt_handles = _mesa_hash_table_create(NULL, _mesa_hash_u32, _mesa_key_u32_equal);
1098*61046927SAndroid Build Coastguard Worker 
1099*61046927SAndroid Build Coastguard Worker    device->ws = pdev->ws;
1100*61046927SAndroid Build Coastguard Worker    vk_device_set_drm_fd(&device->vk, device->ws->get_fd(device->ws));
1101*61046927SAndroid Build Coastguard Worker 
1102*61046927SAndroid Build Coastguard Worker    /* With update after bind we can't attach bo's to the command buffer
1103*61046927SAndroid Build Coastguard Worker     * from the descriptor set anymore, so we have to use a global BO list.
1104*61046927SAndroid Build Coastguard Worker     */
1105*61046927SAndroid Build Coastguard Worker    device->use_global_bo_list =
1106*61046927SAndroid Build Coastguard Worker       (instance->perftest_flags & RADV_PERFTEST_BO_LIST) || device->vk.enabled_features.bufferDeviceAddress ||
1107*61046927SAndroid Build Coastguard Worker       device->vk.enabled_features.descriptorIndexing || device->vk.enabled_extensions.EXT_descriptor_indexing ||
1108*61046927SAndroid Build Coastguard Worker       device->vk.enabled_extensions.EXT_buffer_device_address ||
1109*61046927SAndroid Build Coastguard Worker       device->vk.enabled_extensions.KHR_buffer_device_address ||
1110*61046927SAndroid Build Coastguard Worker       device->vk.enabled_extensions.KHR_ray_tracing_pipeline ||
1111*61046927SAndroid Build Coastguard Worker       device->vk.enabled_extensions.KHR_acceleration_structure ||
1112*61046927SAndroid Build Coastguard Worker       device->vk.enabled_extensions.VALVE_descriptor_set_host_mapping;
1113*61046927SAndroid Build Coastguard Worker 
1114*61046927SAndroid Build Coastguard Worker    radv_init_shader_arenas(device);
1115*61046927SAndroid Build Coastguard Worker 
1116*61046927SAndroid Build Coastguard Worker    device->overallocation_disallowed = overallocation_disallowed;
1117*61046927SAndroid Build Coastguard Worker    mtx_init(&device->overallocation_mutex, mtx_plain);
1118*61046927SAndroid Build Coastguard Worker 
1119*61046927SAndroid Build Coastguard Worker    if (pdev->info.register_shadowing_required || instance->debug_flags & RADV_DEBUG_SHADOW_REGS)
1120*61046927SAndroid Build Coastguard Worker       device->uses_shadow_regs = true;
1121*61046927SAndroid Build Coastguard Worker 
1122*61046927SAndroid Build Coastguard Worker    /* Create one context per queue priority. */
1123*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
1124*61046927SAndroid Build Coastguard Worker       const VkDeviceQueueCreateInfo *queue_create = &pCreateInfo->pQueueCreateInfos[i];
1125*61046927SAndroid Build Coastguard Worker       const VkDeviceQueueGlobalPriorityCreateInfoKHR *global_priority =
1126*61046927SAndroid Build Coastguard Worker          vk_find_struct_const(queue_create->pNext, DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR);
1127*61046927SAndroid Build Coastguard Worker       enum radeon_ctx_priority priority = radv_get_queue_global_priority(global_priority);
1128*61046927SAndroid Build Coastguard Worker 
1129*61046927SAndroid Build Coastguard Worker       if (device->hw_ctx[priority])
1130*61046927SAndroid Build Coastguard Worker          continue;
1131*61046927SAndroid Build Coastguard Worker 
1132*61046927SAndroid Build Coastguard Worker       result = device->ws->ctx_create(device->ws, priority, &device->hw_ctx[priority]);
1133*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
1134*61046927SAndroid Build Coastguard Worker          goto fail_queue;
1135*61046927SAndroid Build Coastguard Worker    }
1136*61046927SAndroid Build Coastguard Worker 
1137*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
1138*61046927SAndroid Build Coastguard Worker       const VkDeviceQueueCreateInfo *queue_create = &pCreateInfo->pQueueCreateInfos[i];
1139*61046927SAndroid Build Coastguard Worker       uint32_t qfi = queue_create->queueFamilyIndex;
1140*61046927SAndroid Build Coastguard Worker       const VkDeviceQueueGlobalPriorityCreateInfoKHR *global_priority =
1141*61046927SAndroid Build Coastguard Worker          vk_find_struct_const(queue_create->pNext, DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_KHR);
1142*61046927SAndroid Build Coastguard Worker 
1143*61046927SAndroid Build Coastguard Worker       device->queues[qfi] = vk_zalloc(&device->vk.alloc, queue_create->queueCount * sizeof(struct radv_queue), 8,
1144*61046927SAndroid Build Coastguard Worker                                       VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
1145*61046927SAndroid Build Coastguard Worker       if (!device->queues[qfi]) {
1146*61046927SAndroid Build Coastguard Worker          result = VK_ERROR_OUT_OF_HOST_MEMORY;
1147*61046927SAndroid Build Coastguard Worker          goto fail_queue;
1148*61046927SAndroid Build Coastguard Worker       }
1149*61046927SAndroid Build Coastguard Worker 
1150*61046927SAndroid Build Coastguard Worker       device->queue_count[qfi] = queue_create->queueCount;
1151*61046927SAndroid Build Coastguard Worker 
1152*61046927SAndroid Build Coastguard Worker       for (unsigned q = 0; q < queue_create->queueCount; q++) {
1153*61046927SAndroid Build Coastguard Worker          result = radv_queue_init(device, &device->queues[qfi][q], q, queue_create, global_priority);
1154*61046927SAndroid Build Coastguard Worker          if (result != VK_SUCCESS)
1155*61046927SAndroid Build Coastguard Worker             goto fail_queue;
1156*61046927SAndroid Build Coastguard Worker       }
1157*61046927SAndroid Build Coastguard Worker    }
1158*61046927SAndroid Build Coastguard Worker    device->private_sdma_queue = VK_NULL_HANDLE;
1159*61046927SAndroid Build Coastguard Worker 
1160*61046927SAndroid Build Coastguard Worker    device->shader_use_invisible_vram = (instance->perftest_flags & RADV_PERFTEST_DMA_SHADERS) &&
1161*61046927SAndroid Build Coastguard Worker                                        /* SDMA buffer copy is only implemented for GFX7+. */
1162*61046927SAndroid Build Coastguard Worker                                        pdev->info.gfx_level >= GFX7;
1163*61046927SAndroid Build Coastguard Worker    result = radv_init_shader_upload_queue(device);
1164*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1165*61046927SAndroid Build Coastguard Worker       goto fail;
1166*61046927SAndroid Build Coastguard Worker 
1167*61046927SAndroid Build Coastguard Worker    device->pbb_allowed = pdev->info.gfx_level >= GFX9 && !(instance->debug_flags & RADV_DEBUG_NOBINNING);
1168*61046927SAndroid Build Coastguard Worker 
1169*61046927SAndroid Build Coastguard Worker    device->disable_trunc_coord = instance->drirc.disable_trunc_coord;
1170*61046927SAndroid Build Coastguard Worker 
1171*61046927SAndroid Build Coastguard Worker    if (instance->vk.app_info.engine_name && !strcmp(instance->vk.app_info.engine_name, "DXVK")) {
1172*61046927SAndroid Build Coastguard Worker       /* For DXVK 2.3.0 and older, use dualSrcBlend to determine if this is D3D9. */
1173*61046927SAndroid Build Coastguard Worker       bool is_d3d9 = !device->vk.enabled_features.dualSrcBlend;
1174*61046927SAndroid Build Coastguard Worker       if (instance->vk.app_info.engine_version > VK_MAKE_VERSION(2, 3, 0))
1175*61046927SAndroid Build Coastguard Worker          is_d3d9 = instance->vk.app_info.app_version & 0x1;
1176*61046927SAndroid Build Coastguard Worker 
1177*61046927SAndroid Build Coastguard Worker       device->disable_trunc_coord &= !is_d3d9;
1178*61046927SAndroid Build Coastguard Worker    }
1179*61046927SAndroid Build Coastguard Worker 
1180*61046927SAndroid Build Coastguard Worker    /* The maximum number of scratch waves. Scratch space isn't divided
1181*61046927SAndroid Build Coastguard Worker     * evenly between CUs. The number is only a function of the number of CUs.
1182*61046927SAndroid Build Coastguard Worker     * We can decrease the constant to decrease the scratch buffer size.
1183*61046927SAndroid Build Coastguard Worker     *
1184*61046927SAndroid Build Coastguard Worker     * sctx->scratch_waves must be >= the maximum possible size of
1185*61046927SAndroid Build Coastguard Worker     * 1 threadgroup, so that the hw doesn't hang from being unable
1186*61046927SAndroid Build Coastguard Worker     * to start any.
1187*61046927SAndroid Build Coastguard Worker     *
1188*61046927SAndroid Build Coastguard Worker     * The recommended value is 4 per CU at most. Higher numbers don't
1189*61046927SAndroid Build Coastguard Worker     * bring much benefit, but they still occupy chip resources (think
1190*61046927SAndroid Build Coastguard Worker     * async compute). I've seen ~2% performance difference between 4 and 32.
1191*61046927SAndroid Build Coastguard Worker     */
1192*61046927SAndroid Build Coastguard Worker    uint32_t max_threads_per_block = 2048;
1193*61046927SAndroid Build Coastguard Worker    device->scratch_waves = MAX2(32 * pdev->info.num_cu, max_threads_per_block / 64);
1194*61046927SAndroid Build Coastguard Worker 
1195*61046927SAndroid Build Coastguard Worker    device->dispatch_initiator = S_00B800_COMPUTE_SHADER_EN(1);
1196*61046927SAndroid Build Coastguard Worker 
1197*61046927SAndroid Build Coastguard Worker    if (pdev->info.gfx_level >= GFX7) {
1198*61046927SAndroid Build Coastguard Worker       /* If the KMD allows it (there is a KMD hw register for it),
1199*61046927SAndroid Build Coastguard Worker        * allow launching waves out-of-order.
1200*61046927SAndroid Build Coastguard Worker        */
1201*61046927SAndroid Build Coastguard Worker       device->dispatch_initiator |= S_00B800_ORDER_MODE(1);
1202*61046927SAndroid Build Coastguard Worker    }
1203*61046927SAndroid Build Coastguard Worker    if (pdev->info.gfx_level >= GFX10) {
1204*61046927SAndroid Build Coastguard Worker       /* Enable asynchronous compute tunneling. The KMD restricts this feature
1205*61046927SAndroid Build Coastguard Worker        * to high-priority compute queues, so setting the bit on any other queue
1206*61046927SAndroid Build Coastguard Worker        * is a no-op. PAL always sets this bit as well.
1207*61046927SAndroid Build Coastguard Worker        */
1208*61046927SAndroid Build Coastguard Worker       device->dispatch_initiator |= S_00B800_TUNNEL_ENABLE(1);
1209*61046927SAndroid Build Coastguard Worker    }
1210*61046927SAndroid Build Coastguard Worker 
1211*61046927SAndroid Build Coastguard Worker    /* Disable partial preemption for task shaders.
1212*61046927SAndroid Build Coastguard Worker     * The kernel may not support preemption, but PAL always sets this bit,
1213*61046927SAndroid Build Coastguard Worker     * so let's also set it here for consistency.
1214*61046927SAndroid Build Coastguard Worker     */
1215*61046927SAndroid Build Coastguard Worker    device->dispatch_initiator_task = device->dispatch_initiator | S_00B800_DISABLE_DISP_PREMPT_EN(1);
1216*61046927SAndroid Build Coastguard Worker 
1217*61046927SAndroid Build Coastguard Worker    if (pdev->info.gfx_level == GFX10_3) {
1218*61046927SAndroid Build Coastguard Worker       if (getenv("RADV_FORCE_VRS_CONFIG_FILE")) {
1219*61046927SAndroid Build Coastguard Worker          const char *file = radv_get_force_vrs_config_file();
1220*61046927SAndroid Build Coastguard Worker 
1221*61046927SAndroid Build Coastguard Worker          device->force_vrs = radv_parse_force_vrs_config_file(file);
1222*61046927SAndroid Build Coastguard Worker 
1223*61046927SAndroid Build Coastguard Worker          if (radv_device_init_notifier(device)) {
1224*61046927SAndroid Build Coastguard Worker             device->force_vrs_enabled = true;
1225*61046927SAndroid Build Coastguard Worker          } else {
1226*61046927SAndroid Build Coastguard Worker             fprintf(stderr, "radv: Failed to initialize the notifier for RADV_FORCE_VRS_CONFIG_FILE!\n");
1227*61046927SAndroid Build Coastguard Worker          }
1228*61046927SAndroid Build Coastguard Worker       } else if (getenv("RADV_FORCE_VRS")) {
1229*61046927SAndroid Build Coastguard Worker          const char *vrs_rates = getenv("RADV_FORCE_VRS");
1230*61046927SAndroid Build Coastguard Worker 
1231*61046927SAndroid Build Coastguard Worker          device->force_vrs = radv_parse_vrs_rates(vrs_rates);
1232*61046927SAndroid Build Coastguard Worker          device->force_vrs_enabled = device->force_vrs != RADV_FORCE_VRS_1x1;
1233*61046927SAndroid Build Coastguard Worker       }
1234*61046927SAndroid Build Coastguard Worker    }
1235*61046927SAndroid Build Coastguard Worker 
1236*61046927SAndroid Build Coastguard Worker    /* PKT3_LOAD_SH_REG_INDEX is supported on GFX8+, but it hangs with compute queues until GFX10.3. */
1237*61046927SAndroid Build Coastguard Worker    device->load_grid_size_from_user_sgpr = pdev->info.gfx_level >= GFX10_3;
1238*61046927SAndroid Build Coastguard Worker 
1239*61046927SAndroid Build Coastguard Worker    /* Keep shader info for GPU hangs debugging. */
1240*61046927SAndroid Build Coastguard Worker    device->keep_shader_info = radv_device_fault_detection_enabled(device) || radv_trap_handler_enabled();
1241*61046927SAndroid Build Coastguard Worker 
1242*61046927SAndroid Build Coastguard Worker    /* Initialize the per-device cache key before compiling meta shaders. */
1243*61046927SAndroid Build Coastguard Worker    radv_device_init_cache_key(device);
1244*61046927SAndroid Build Coastguard Worker 
1245*61046927SAndroid Build Coastguard Worker    result = radv_device_init_tools(device);
1246*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1247*61046927SAndroid Build Coastguard Worker       goto fail;
1248*61046927SAndroid Build Coastguard Worker 
1249*61046927SAndroid Build Coastguard Worker    result = radv_device_init_meta(device);
1250*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
1251*61046927SAndroid Build Coastguard Worker       goto fail;
1252*61046927SAndroid Build Coastguard Worker 
1253*61046927SAndroid Build Coastguard Worker    radv_device_init_msaa(device);
1254*61046927SAndroid Build Coastguard Worker 
1255*61046927SAndroid Build Coastguard Worker    /* If the border color extension is enabled, let's create the buffer we need. */
1256*61046927SAndroid Build Coastguard Worker    if (device->vk.enabled_features.customBorderColors) {
1257*61046927SAndroid Build Coastguard Worker       result = radv_device_init_border_color(device);
1258*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
1259*61046927SAndroid Build Coastguard Worker          goto fail;
1260*61046927SAndroid Build Coastguard Worker    }
1261*61046927SAndroid Build Coastguard Worker 
1262*61046927SAndroid Build Coastguard Worker    if (device->vk.enabled_features.vertexInputDynamicState || device->vk.enabled_features.graphicsPipelineLibrary ||
1263*61046927SAndroid Build Coastguard Worker        device->vk.enabled_features.shaderObject) {
1264*61046927SAndroid Build Coastguard Worker       result = radv_device_init_vs_prologs(device);
1265*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
1266*61046927SAndroid Build Coastguard Worker          goto fail;
1267*61046927SAndroid Build Coastguard Worker    }
1268*61046927SAndroid Build Coastguard Worker 
1269*61046927SAndroid Build Coastguard Worker    if (device->vk.enabled_features.graphicsPipelineLibrary || device->vk.enabled_features.shaderObject ||
1270*61046927SAndroid Build Coastguard Worker        device->vk.enabled_features.extendedDynamicState3ColorBlendEnable ||
1271*61046927SAndroid Build Coastguard Worker        device->vk.enabled_features.extendedDynamicState3ColorWriteMask ||
1272*61046927SAndroid Build Coastguard Worker        device->vk.enabled_features.extendedDynamicState3AlphaToCoverageEnable ||
1273*61046927SAndroid Build Coastguard Worker        device->vk.enabled_features.extendedDynamicState3ColorBlendEquation) {
1274*61046927SAndroid Build Coastguard Worker       if (!radv_shader_part_cache_init(&device->ps_epilogs, &ps_epilog_ops)) {
1275*61046927SAndroid Build Coastguard Worker          result = VK_ERROR_OUT_OF_HOST_MEMORY;
1276*61046927SAndroid Build Coastguard Worker          goto fail;
1277*61046927SAndroid Build Coastguard Worker       }
1278*61046927SAndroid Build Coastguard Worker    }
1279*61046927SAndroid Build Coastguard Worker 
1280*61046927SAndroid Build Coastguard Worker    if (!(instance->debug_flags & RADV_DEBUG_NO_IBS))
1281*61046927SAndroid Build Coastguard Worker       radv_create_gfx_preamble(device);
1282*61046927SAndroid Build Coastguard Worker 
1283*61046927SAndroid Build Coastguard Worker    if (!device->vk.disable_internal_cache) {
1284*61046927SAndroid Build Coastguard Worker       result = radv_device_init_memory_cache(device);
1285*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
1286*61046927SAndroid Build Coastguard Worker          goto fail_meta;
1287*61046927SAndroid Build Coastguard Worker    }
1288*61046927SAndroid Build Coastguard Worker 
1289*61046927SAndroid Build Coastguard Worker    device->force_aniso = MIN2(16, (int)debug_get_num_option("RADV_TEX_ANISO", -1));
1290*61046927SAndroid Build Coastguard Worker    if (device->force_aniso >= 0) {
1291*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "radv: Forcing anisotropy filter to %ix\n", 1 << util_logbase2(device->force_aniso));
1292*61046927SAndroid Build Coastguard Worker    }
1293*61046927SAndroid Build Coastguard Worker 
1294*61046927SAndroid Build Coastguard Worker    if (device->vk.enabled_features.performanceCounterQueryPools) {
1295*61046927SAndroid Build Coastguard Worker       result = radv_device_init_perf_counter(device);
1296*61046927SAndroid Build Coastguard Worker       if (result != VK_SUCCESS)
1297*61046927SAndroid Build Coastguard Worker          goto fail_cache;
1298*61046927SAndroid Build Coastguard Worker    }
1299*61046927SAndroid Build Coastguard Worker 
1300*61046927SAndroid Build Coastguard Worker    if (device->vk.enabled_features.rayTracingPipelineShaderGroupHandleCaptureReplay) {
1301*61046927SAndroid Build Coastguard Worker       device->capture_replay_arena_vas = _mesa_hash_table_u64_create(NULL);
1302*61046927SAndroid Build Coastguard Worker    }
1303*61046927SAndroid Build Coastguard Worker 
1304*61046927SAndroid Build Coastguard Worker    if (pdev->info.gfx_level == GFX11 && pdev->info.has_dedicated_vram && instance->drirc.force_pstate_peak_gfx11_dgpu) {
1305*61046927SAndroid Build Coastguard Worker       if (!radv_device_acquire_performance_counters(device))
1306*61046927SAndroid Build Coastguard Worker          fprintf(stderr, "radv: failed to set pstate to profile_peak.\n");
1307*61046927SAndroid Build Coastguard Worker    }
1308*61046927SAndroid Build Coastguard Worker 
1309*61046927SAndroid Build Coastguard Worker    *pDevice = radv_device_to_handle(device);
1310*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1311*61046927SAndroid Build Coastguard Worker 
1312*61046927SAndroid Build Coastguard Worker fail_cache:
1313*61046927SAndroid Build Coastguard Worker    radv_device_finish_memory_cache(device);
1314*61046927SAndroid Build Coastguard Worker fail_meta:
1315*61046927SAndroid Build Coastguard Worker    radv_device_finish_meta(device);
1316*61046927SAndroid Build Coastguard Worker fail:
1317*61046927SAndroid Build Coastguard Worker    radv_device_finish_perf_counter(device);
1318*61046927SAndroid Build Coastguard Worker 
1319*61046927SAndroid Build Coastguard Worker    radv_device_finish_tools(device);
1320*61046927SAndroid Build Coastguard Worker 
1321*61046927SAndroid Build Coastguard Worker    if (device->gfx_init)
1322*61046927SAndroid Build Coastguard Worker       radv_bo_destroy(device, NULL, device->gfx_init);
1323*61046927SAndroid Build Coastguard Worker 
1324*61046927SAndroid Build Coastguard Worker    radv_device_finish_notifier(device);
1325*61046927SAndroid Build Coastguard Worker    radv_device_finish_vs_prologs(device);
1326*61046927SAndroid Build Coastguard Worker    if (device->ps_epilogs.ops)
1327*61046927SAndroid Build Coastguard Worker       radv_shader_part_cache_finish(device, &device->ps_epilogs);
1328*61046927SAndroid Build Coastguard Worker    radv_device_finish_border_color(device);
1329*61046927SAndroid Build Coastguard Worker 
1330*61046927SAndroid Build Coastguard Worker    radv_destroy_shader_upload_queue(device);
1331*61046927SAndroid Build Coastguard Worker 
1332*61046927SAndroid Build Coastguard Worker fail_queue:
1333*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < RADV_MAX_QUEUE_FAMILIES; i++) {
1334*61046927SAndroid Build Coastguard Worker       for (unsigned q = 0; q < device->queue_count[i]; q++)
1335*61046927SAndroid Build Coastguard Worker          radv_queue_finish(&device->queues[i][q]);
1336*61046927SAndroid Build Coastguard Worker       if (device->queue_count[i])
1337*61046927SAndroid Build Coastguard Worker          vk_free(&device->vk.alloc, device->queues[i]);
1338*61046927SAndroid Build Coastguard Worker    }
1339*61046927SAndroid Build Coastguard Worker 
1340*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < RADV_NUM_HW_CTX; i++) {
1341*61046927SAndroid Build Coastguard Worker       if (device->hw_ctx[i])
1342*61046927SAndroid Build Coastguard Worker          device->ws->ctx_destroy(device->hw_ctx[i]);
1343*61046927SAndroid Build Coastguard Worker    }
1344*61046927SAndroid Build Coastguard Worker 
1345*61046927SAndroid Build Coastguard Worker    radv_destroy_shader_arenas(device);
1346*61046927SAndroid Build Coastguard Worker 
1347*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_destroy(device->rt_handles, NULL);
1348*61046927SAndroid Build Coastguard Worker 
1349*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&device->ctx_roll_mtx);
1350*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&device->pstate_mtx);
1351*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&device->trace_mtx);
1352*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&device->rt_handles_mtx);
1353*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&device->compute_scratch_mtx);
1354*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&device->pso_cache_stats_mtx);
1355*61046927SAndroid Build Coastguard Worker    mtx_destroy(&device->overallocation_mutex);
1356*61046927SAndroid Build Coastguard Worker 
1357*61046927SAndroid Build Coastguard Worker    vk_device_finish(&device->vk);
1358*61046927SAndroid Build Coastguard Worker    vk_free(&device->vk.alloc, device);
1359*61046927SAndroid Build Coastguard Worker    return result;
1360*61046927SAndroid Build Coastguard Worker }
1361*61046927SAndroid Build Coastguard Worker 
1362*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
radv_DestroyDevice(VkDevice _device,const VkAllocationCallbacks * pAllocator)1363*61046927SAndroid Build Coastguard Worker radv_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator)
1364*61046927SAndroid Build Coastguard Worker {
1365*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(radv_device, device, _device);
1366*61046927SAndroid Build Coastguard Worker 
1367*61046927SAndroid Build Coastguard Worker    if (!device)
1368*61046927SAndroid Build Coastguard Worker       return;
1369*61046927SAndroid Build Coastguard Worker 
1370*61046927SAndroid Build Coastguard Worker    radv_device_finish_perf_counter(device);
1371*61046927SAndroid Build Coastguard Worker 
1372*61046927SAndroid Build Coastguard Worker    if (device->gfx_init)
1373*61046927SAndroid Build Coastguard Worker       radv_bo_destroy(device, NULL, device->gfx_init);
1374*61046927SAndroid Build Coastguard Worker 
1375*61046927SAndroid Build Coastguard Worker    radv_device_finish_notifier(device);
1376*61046927SAndroid Build Coastguard Worker    radv_device_finish_vs_prologs(device);
1377*61046927SAndroid Build Coastguard Worker    if (device->ps_epilogs.ops)
1378*61046927SAndroid Build Coastguard Worker       radv_shader_part_cache_finish(device, &device->ps_epilogs);
1379*61046927SAndroid Build Coastguard Worker    radv_device_finish_border_color(device);
1380*61046927SAndroid Build Coastguard Worker    radv_device_finish_vrs_image(device);
1381*61046927SAndroid Build Coastguard Worker 
1382*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < RADV_MAX_QUEUE_FAMILIES; i++) {
1383*61046927SAndroid Build Coastguard Worker       for (unsigned q = 0; q < device->queue_count[i]; q++)
1384*61046927SAndroid Build Coastguard Worker          radv_queue_finish(&device->queues[i][q]);
1385*61046927SAndroid Build Coastguard Worker       if (device->queue_count[i])
1386*61046927SAndroid Build Coastguard Worker          vk_free(&device->vk.alloc, device->queues[i]);
1387*61046927SAndroid Build Coastguard Worker    }
1388*61046927SAndroid Build Coastguard Worker    if (device->private_sdma_queue != VK_NULL_HANDLE) {
1389*61046927SAndroid Build Coastguard Worker       radv_queue_finish(device->private_sdma_queue);
1390*61046927SAndroid Build Coastguard Worker       vk_free(&device->vk.alloc, device->private_sdma_queue);
1391*61046927SAndroid Build Coastguard Worker    }
1392*61046927SAndroid Build Coastguard Worker 
1393*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_destroy(device->rt_handles, NULL);
1394*61046927SAndroid Build Coastguard Worker 
1395*61046927SAndroid Build Coastguard Worker    radv_device_finish_meta(device);
1396*61046927SAndroid Build Coastguard Worker 
1397*61046927SAndroid Build Coastguard Worker    radv_device_finish_memory_cache(device);
1398*61046927SAndroid Build Coastguard Worker 
1399*61046927SAndroid Build Coastguard Worker    radv_destroy_shader_upload_queue(device);
1400*61046927SAndroid Build Coastguard Worker 
1401*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < RADV_NUM_HW_CTX; i++) {
1402*61046927SAndroid Build Coastguard Worker       if (device->hw_ctx[i])
1403*61046927SAndroid Build Coastguard Worker          device->ws->ctx_destroy(device->hw_ctx[i]);
1404*61046927SAndroid Build Coastguard Worker    }
1405*61046927SAndroid Build Coastguard Worker 
1406*61046927SAndroid Build Coastguard Worker    mtx_destroy(&device->overallocation_mutex);
1407*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&device->ctx_roll_mtx);
1408*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&device->pstate_mtx);
1409*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&device->trace_mtx);
1410*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&device->rt_handles_mtx);
1411*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&device->compute_scratch_mtx);
1412*61046927SAndroid Build Coastguard Worker    simple_mtx_destroy(&device->pso_cache_stats_mtx);
1413*61046927SAndroid Build Coastguard Worker 
1414*61046927SAndroid Build Coastguard Worker    radv_destroy_shader_arenas(device);
1415*61046927SAndroid Build Coastguard Worker    if (device->capture_replay_arena_vas)
1416*61046927SAndroid Build Coastguard Worker       _mesa_hash_table_u64_destroy(device->capture_replay_arena_vas);
1417*61046927SAndroid Build Coastguard Worker 
1418*61046927SAndroid Build Coastguard Worker    vk_device_finish(&device->vk);
1419*61046927SAndroid Build Coastguard Worker    vk_free(&device->vk.alloc, device);
1420*61046927SAndroid Build Coastguard Worker }
1421*61046927SAndroid Build Coastguard Worker 
1422*61046927SAndroid Build Coastguard Worker bool
radv_get_memory_fd(struct radv_device * device,struct radv_device_memory * memory,int * pFD)1423*61046927SAndroid Build Coastguard Worker radv_get_memory_fd(struct radv_device *device, struct radv_device_memory *memory, int *pFD)
1424*61046927SAndroid Build Coastguard Worker {
1425*61046927SAndroid Build Coastguard Worker    /* Set BO metadata for dedicated image allocations.  We don't need it for import when the image
1426*61046927SAndroid Build Coastguard Worker     * tiling is VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, but we set it anyway for foreign consumers.
1427*61046927SAndroid Build Coastguard Worker     */
1428*61046927SAndroid Build Coastguard Worker    if (memory->image) {
1429*61046927SAndroid Build Coastguard Worker       struct radeon_bo_metadata metadata;
1430*61046927SAndroid Build Coastguard Worker 
1431*61046927SAndroid Build Coastguard Worker       assert(memory->image->bindings[0].offset == 0);
1432*61046927SAndroid Build Coastguard Worker       radv_init_metadata(device, memory->image, &metadata);
1433*61046927SAndroid Build Coastguard Worker       device->ws->buffer_set_metadata(device->ws, memory->bo, &metadata);
1434*61046927SAndroid Build Coastguard Worker    }
1435*61046927SAndroid Build Coastguard Worker 
1436*61046927SAndroid Build Coastguard Worker    return device->ws->buffer_get_fd(device->ws, memory->bo, pFD);
1437*61046927SAndroid Build Coastguard Worker }
1438*61046927SAndroid Build Coastguard Worker 
1439*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
radv_GetImageMemoryRequirements2(VkDevice _device,const VkImageMemoryRequirementsInfo2 * pInfo,VkMemoryRequirements2 * pMemoryRequirements)1440*61046927SAndroid Build Coastguard Worker radv_GetImageMemoryRequirements2(VkDevice _device, const VkImageMemoryRequirementsInfo2 *pInfo,
1441*61046927SAndroid Build Coastguard Worker                                  VkMemoryRequirements2 *pMemoryRequirements)
1442*61046927SAndroid Build Coastguard Worker {
1443*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(radv_device, device, _device);
1444*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(radv_image, image, pInfo->image);
1445*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
1446*61046927SAndroid Build Coastguard Worker    uint32_t alignment;
1447*61046927SAndroid Build Coastguard Worker    uint64_t size;
1448*61046927SAndroid Build Coastguard Worker 
1449*61046927SAndroid Build Coastguard Worker    const VkImagePlaneMemoryRequirementsInfo *plane_info =
1450*61046927SAndroid Build Coastguard Worker       vk_find_struct_const(pInfo->pNext, IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO);
1451*61046927SAndroid Build Coastguard Worker 
1452*61046927SAndroid Build Coastguard Worker    if (plane_info) {
1453*61046927SAndroid Build Coastguard Worker       const uint32_t plane = radv_plane_from_aspect(plane_info->planeAspect);
1454*61046927SAndroid Build Coastguard Worker 
1455*61046927SAndroid Build Coastguard Worker       size = image->planes[plane].surface.total_size;
1456*61046927SAndroid Build Coastguard Worker       alignment = 1 << image->planes[plane].surface.alignment_log2;
1457*61046927SAndroid Build Coastguard Worker    } else {
1458*61046927SAndroid Build Coastguard Worker       size = image->size;
1459*61046927SAndroid Build Coastguard Worker       alignment = image->alignment;
1460*61046927SAndroid Build Coastguard Worker    }
1461*61046927SAndroid Build Coastguard Worker 
1462*61046927SAndroid Build Coastguard Worker    pMemoryRequirements->memoryRequirements.memoryTypeBits =
1463*61046927SAndroid Build Coastguard Worker       ((1u << pdev->memory_properties.memoryTypeCount) - 1u) & ~pdev->memory_types_32bit;
1464*61046927SAndroid Build Coastguard Worker 
1465*61046927SAndroid Build Coastguard Worker    pMemoryRequirements->memoryRequirements.size = size;
1466*61046927SAndroid Build Coastguard Worker    pMemoryRequirements->memoryRequirements.alignment = alignment;
1467*61046927SAndroid Build Coastguard Worker 
1468*61046927SAndroid Build Coastguard Worker    vk_foreach_struct (ext, pMemoryRequirements->pNext) {
1469*61046927SAndroid Build Coastguard Worker       switch (ext->sType) {
1470*61046927SAndroid Build Coastguard Worker       case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
1471*61046927SAndroid Build Coastguard Worker          VkMemoryDedicatedRequirements *req = (VkMemoryDedicatedRequirements *)ext;
1472*61046927SAndroid Build Coastguard Worker          req->requiresDedicatedAllocation = image->shareable && image->vk.tiling != VK_IMAGE_TILING_LINEAR;
1473*61046927SAndroid Build Coastguard Worker          req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
1474*61046927SAndroid Build Coastguard Worker          break;
1475*61046927SAndroid Build Coastguard Worker       }
1476*61046927SAndroid Build Coastguard Worker       default:
1477*61046927SAndroid Build Coastguard Worker          break;
1478*61046927SAndroid Build Coastguard Worker       }
1479*61046927SAndroid Build Coastguard Worker    }
1480*61046927SAndroid Build Coastguard Worker }
1481*61046927SAndroid Build Coastguard Worker 
1482*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
radv_GetDeviceImageMemoryRequirements(VkDevice device,const VkDeviceImageMemoryRequirements * pInfo,VkMemoryRequirements2 * pMemoryRequirements)1483*61046927SAndroid Build Coastguard Worker radv_GetDeviceImageMemoryRequirements(VkDevice device, const VkDeviceImageMemoryRequirements *pInfo,
1484*61046927SAndroid Build Coastguard Worker                                       VkMemoryRequirements2 *pMemoryRequirements)
1485*61046927SAndroid Build Coastguard Worker {
1486*61046927SAndroid Build Coastguard Worker    UNUSED VkResult result;
1487*61046927SAndroid Build Coastguard Worker    VkImage image;
1488*61046927SAndroid Build Coastguard Worker 
1489*61046927SAndroid Build Coastguard Worker    /* Determining the image size/alignment require to create a surface, which is complicated without
1490*61046927SAndroid Build Coastguard Worker     * creating an image.
1491*61046927SAndroid Build Coastguard Worker     * TODO: Avoid creating an image.
1492*61046927SAndroid Build Coastguard Worker     */
1493*61046927SAndroid Build Coastguard Worker    result =
1494*61046927SAndroid Build Coastguard Worker       radv_image_create(device, &(struct radv_image_create_info){.vk_info = pInfo->pCreateInfo}, NULL, &image, true);
1495*61046927SAndroid Build Coastguard Worker    assert(result == VK_SUCCESS);
1496*61046927SAndroid Build Coastguard Worker 
1497*61046927SAndroid Build Coastguard Worker    VkImageMemoryRequirementsInfo2 info2 = {
1498*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
1499*61046927SAndroid Build Coastguard Worker       .image = image,
1500*61046927SAndroid Build Coastguard Worker    };
1501*61046927SAndroid Build Coastguard Worker 
1502*61046927SAndroid Build Coastguard Worker    radv_GetImageMemoryRequirements2(device, &info2, pMemoryRequirements);
1503*61046927SAndroid Build Coastguard Worker 
1504*61046927SAndroid Build Coastguard Worker    radv_DestroyImage(device, image, NULL);
1505*61046927SAndroid Build Coastguard Worker }
1506*61046927SAndroid Build Coastguard Worker 
1507*61046927SAndroid Build Coastguard Worker static uint32_t
radv_surface_max_layer_count(struct radv_image_view * iview)1508*61046927SAndroid Build Coastguard Worker radv_surface_max_layer_count(struct radv_image_view *iview)
1509*61046927SAndroid Build Coastguard Worker {
1510*61046927SAndroid Build Coastguard Worker    return iview->vk.view_type == VK_IMAGE_VIEW_TYPE_3D ? iview->extent.depth
1511*61046927SAndroid Build Coastguard Worker                                                        : (iview->vk.base_array_layer + iview->vk.layer_count);
1512*61046927SAndroid Build Coastguard Worker }
1513*61046927SAndroid Build Coastguard Worker 
1514*61046927SAndroid Build Coastguard Worker unsigned
radv_get_dcc_max_uncompressed_block_size(const struct radv_device * device,const struct radv_image * image)1515*61046927SAndroid Build Coastguard Worker radv_get_dcc_max_uncompressed_block_size(const struct radv_device *device, const struct radv_image *image)
1516*61046927SAndroid Build Coastguard Worker {
1517*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
1518*61046927SAndroid Build Coastguard Worker 
1519*61046927SAndroid Build Coastguard Worker    if (pdev->info.gfx_level < GFX10 && image->vk.samples > 1) {
1520*61046927SAndroid Build Coastguard Worker       if (image->planes[0].surface.bpe == 1)
1521*61046927SAndroid Build Coastguard Worker          return V_028C78_MAX_BLOCK_SIZE_64B;
1522*61046927SAndroid Build Coastguard Worker       else if (image->planes[0].surface.bpe == 2)
1523*61046927SAndroid Build Coastguard Worker          return V_028C78_MAX_BLOCK_SIZE_128B;
1524*61046927SAndroid Build Coastguard Worker    }
1525*61046927SAndroid Build Coastguard Worker 
1526*61046927SAndroid Build Coastguard Worker    return V_028C78_MAX_BLOCK_SIZE_256B;
1527*61046927SAndroid Build Coastguard Worker }
1528*61046927SAndroid Build Coastguard Worker 
1529*61046927SAndroid Build Coastguard Worker void
radv_initialise_color_surface(struct radv_device * device,struct radv_color_buffer_info * cb,struct radv_image_view * iview)1530*61046927SAndroid Build Coastguard Worker radv_initialise_color_surface(struct radv_device *device, struct radv_color_buffer_info *cb,
1531*61046927SAndroid Build Coastguard Worker                               struct radv_image_view *iview)
1532*61046927SAndroid Build Coastguard Worker {
1533*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
1534*61046927SAndroid Build Coastguard Worker    const struct radv_instance *instance = radv_physical_device_instance(pdev);
1535*61046927SAndroid Build Coastguard Worker    uint64_t va;
1536*61046927SAndroid Build Coastguard Worker    const struct radv_image_plane *plane = &iview->image->planes[iview->plane_id];
1537*61046927SAndroid Build Coastguard Worker    const struct radeon_surf *surf = &plane->surface;
1538*61046927SAndroid Build Coastguard Worker 
1539*61046927SAndroid Build Coastguard Worker    memset(cb, 0, sizeof(*cb));
1540*61046927SAndroid Build Coastguard Worker 
1541*61046927SAndroid Build Coastguard Worker    const unsigned num_layers =
1542*61046927SAndroid Build Coastguard Worker       iview->image->vk.image_type == VK_IMAGE_TYPE_3D ? (iview->extent.depth - 1) : (iview->image->vk.array_layers - 1);
1543*61046927SAndroid Build Coastguard Worker 
1544*61046927SAndroid Build Coastguard Worker    const struct ac_cb_state cb_state = {
1545*61046927SAndroid Build Coastguard Worker       .surf = surf,
1546*61046927SAndroid Build Coastguard Worker       .format = vk_format_to_pipe_format(iview->vk.format),
1547*61046927SAndroid Build Coastguard Worker       .width = vk_format_get_plane_width(iview->image->vk.format, iview->plane_id, iview->extent.width),
1548*61046927SAndroid Build Coastguard Worker       .height = vk_format_get_plane_height(iview->image->vk.format, iview->plane_id, iview->extent.height),
1549*61046927SAndroid Build Coastguard Worker       .first_layer = iview->vk.base_array_layer,
1550*61046927SAndroid Build Coastguard Worker       .last_layer = radv_surface_max_layer_count(iview) - 1,
1551*61046927SAndroid Build Coastguard Worker       .num_layers = num_layers,
1552*61046927SAndroid Build Coastguard Worker       .num_samples = iview->image->vk.samples,
1553*61046927SAndroid Build Coastguard Worker       .num_storage_samples = iview->image->vk.samples,
1554*61046927SAndroid Build Coastguard Worker       .base_level = iview->vk.base_mip_level,
1555*61046927SAndroid Build Coastguard Worker       .num_levels = iview->image->vk.mip_levels,
1556*61046927SAndroid Build Coastguard Worker       .gfx10 =
1557*61046927SAndroid Build Coastguard Worker          {
1558*61046927SAndroid Build Coastguard Worker             .nbc_view = iview->nbc_view.valid ? &iview->nbc_view : NULL,
1559*61046927SAndroid Build Coastguard Worker          },
1560*61046927SAndroid Build Coastguard Worker    };
1561*61046927SAndroid Build Coastguard Worker 
1562*61046927SAndroid Build Coastguard Worker    ac_init_cb_surface(&pdev->info, &cb_state, &cb->ac);
1563*61046927SAndroid Build Coastguard Worker 
1564*61046927SAndroid Build Coastguard Worker    uint32_t plane_id = iview->image->disjoint ? iview->plane_id : 0;
1565*61046927SAndroid Build Coastguard Worker    va = radv_image_get_va(iview->image, plane_id);
1566*61046927SAndroid Build Coastguard Worker 
1567*61046927SAndroid Build Coastguard Worker    const struct ac_mutable_cb_state mutable_cb_state = {
1568*61046927SAndroid Build Coastguard Worker       .surf = surf,
1569*61046927SAndroid Build Coastguard Worker       .cb = &cb->ac,
1570*61046927SAndroid Build Coastguard Worker       .va = va,
1571*61046927SAndroid Build Coastguard Worker       .base_level = iview->vk.base_mip_level,
1572*61046927SAndroid Build Coastguard Worker       .num_samples = iview->image->vk.samples,
1573*61046927SAndroid Build Coastguard Worker       .fmask_enabled = radv_image_has_fmask(iview->image),
1574*61046927SAndroid Build Coastguard Worker       .cmask_enabled = radv_image_has_cmask(iview->image),
1575*61046927SAndroid Build Coastguard Worker       .fast_clear_enabled = !(instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS),
1576*61046927SAndroid Build Coastguard Worker       .tc_compat_cmask_enabled = radv_image_is_tc_compat_cmask(iview->image),
1577*61046927SAndroid Build Coastguard Worker       .dcc_enabled = radv_dcc_enabled(iview->image, iview->vk.base_mip_level) &&
1578*61046927SAndroid Build Coastguard Worker                      (pdev->info.gfx_level >= GFX11 || !iview->disable_dcc_mrt),
1579*61046927SAndroid Build Coastguard Worker       .gfx10 =
1580*61046927SAndroid Build Coastguard Worker          {
1581*61046927SAndroid Build Coastguard Worker             .nbc_view = iview->nbc_view.valid ? &iview->nbc_view : NULL,
1582*61046927SAndroid Build Coastguard Worker          },
1583*61046927SAndroid Build Coastguard Worker    };
1584*61046927SAndroid Build Coastguard Worker 
1585*61046927SAndroid Build Coastguard Worker    ac_set_mutable_cb_surface_fields(&pdev->info, &mutable_cb_state, &cb->ac);
1586*61046927SAndroid Build Coastguard Worker }
1587*61046927SAndroid Build Coastguard Worker 
1588*61046927SAndroid Build Coastguard Worker void
radv_initialise_vrs_surface(struct radv_image * image,struct radv_buffer * htile_buffer,struct radv_ds_buffer_info * ds)1589*61046927SAndroid Build Coastguard Worker radv_initialise_vrs_surface(struct radv_image *image, struct radv_buffer *htile_buffer, struct radv_ds_buffer_info *ds)
1590*61046927SAndroid Build Coastguard Worker {
1591*61046927SAndroid Build Coastguard Worker    const struct radeon_surf *surf = &image->planes[0].surface;
1592*61046927SAndroid Build Coastguard Worker 
1593*61046927SAndroid Build Coastguard Worker    assert(image->vk.format == VK_FORMAT_D16_UNORM);
1594*61046927SAndroid Build Coastguard Worker    memset(ds, 0, sizeof(*ds));
1595*61046927SAndroid Build Coastguard Worker 
1596*61046927SAndroid Build Coastguard Worker    ds->ac.db_z_info = S_028038_FORMAT(V_028040_Z_16) | S_028038_SW_MODE(surf->u.gfx9.swizzle_mode) |
1597*61046927SAndroid Build Coastguard Worker                       S_028038_ZRANGE_PRECISION(1) | S_028038_TILE_SURFACE_ENABLE(1);
1598*61046927SAndroid Build Coastguard Worker    ds->ac.db_stencil_info = S_02803C_FORMAT(V_028044_STENCIL_INVALID);
1599*61046927SAndroid Build Coastguard Worker 
1600*61046927SAndroid Build Coastguard Worker    ds->ac.db_depth_size = S_02801C_X_MAX(image->vk.extent.width - 1) | S_02801C_Y_MAX(image->vk.extent.height - 1);
1601*61046927SAndroid Build Coastguard Worker 
1602*61046927SAndroid Build Coastguard Worker    ds->ac.u.gfx6.db_htile_data_base = radv_buffer_get_va(htile_buffer->bo) >> 8;
1603*61046927SAndroid Build Coastguard Worker    ds->ac.u.gfx6.db_htile_surface =
1604*61046927SAndroid Build Coastguard Worker       S_028ABC_FULL_CACHE(1) | S_028ABC_PIPE_ALIGNED(1) | S_028ABC_VRS_HTILE_ENCODING(V_028ABC_VRS_HTILE_4BIT_ENCODING);
1605*61046927SAndroid Build Coastguard Worker }
1606*61046927SAndroid Build Coastguard Worker 
1607*61046927SAndroid Build Coastguard Worker void
radv_initialise_ds_surface(const struct radv_device * device,struct radv_ds_buffer_info * ds,struct radv_image_view * iview,VkImageAspectFlags ds_aspects)1608*61046927SAndroid Build Coastguard Worker radv_initialise_ds_surface(const struct radv_device *device, struct radv_ds_buffer_info *ds,
1609*61046927SAndroid Build Coastguard Worker                            struct radv_image_view *iview, VkImageAspectFlags ds_aspects)
1610*61046927SAndroid Build Coastguard Worker {
1611*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
1612*61046927SAndroid Build Coastguard Worker    unsigned level = iview->vk.base_mip_level;
1613*61046927SAndroid Build Coastguard Worker    bool stencil_only = iview->image->vk.format == VK_FORMAT_S8_UINT;
1614*61046927SAndroid Build Coastguard Worker 
1615*61046927SAndroid Build Coastguard Worker    assert(vk_format_get_plane_count(iview->image->vk.format) == 1);
1616*61046927SAndroid Build Coastguard Worker 
1617*61046927SAndroid Build Coastguard Worker    memset(ds, 0, sizeof(*ds));
1618*61046927SAndroid Build Coastguard Worker 
1619*61046927SAndroid Build Coastguard Worker    uint32_t max_slice = radv_surface_max_layer_count(iview) - 1;
1620*61046927SAndroid Build Coastguard Worker 
1621*61046927SAndroid Build Coastguard Worker    /* Recommended value for better performance with 4x and 8x. */
1622*61046927SAndroid Build Coastguard Worker    ds->db_render_override2 = S_028010_DECOMPRESS_Z_ON_FLUSH(iview->image->vk.samples >= 4) |
1623*61046927SAndroid Build Coastguard Worker                              S_028010_CENTROID_COMPUTATION_MODE(pdev->info.gfx_level >= GFX10_3);
1624*61046927SAndroid Build Coastguard Worker 
1625*61046927SAndroid Build Coastguard Worker    const struct ac_ds_state ds_state = {
1626*61046927SAndroid Build Coastguard Worker       .surf = &iview->image->planes[0].surface,
1627*61046927SAndroid Build Coastguard Worker       .va = radv_image_get_va(iview->image, 0),
1628*61046927SAndroid Build Coastguard Worker       .format = vk_format_to_pipe_format(iview->image->vk.format),
1629*61046927SAndroid Build Coastguard Worker       .width = iview->image->vk.extent.width,
1630*61046927SAndroid Build Coastguard Worker       .height = iview->image->vk.extent.height,
1631*61046927SAndroid Build Coastguard Worker       .level = level,
1632*61046927SAndroid Build Coastguard Worker       .num_levels = iview->image->vk.mip_levels,
1633*61046927SAndroid Build Coastguard Worker       .num_samples = iview->image->vk.samples,
1634*61046927SAndroid Build Coastguard Worker       .first_layer = iview->vk.base_array_layer,
1635*61046927SAndroid Build Coastguard Worker       .last_layer = max_slice,
1636*61046927SAndroid Build Coastguard Worker       .stencil_only = stencil_only,
1637*61046927SAndroid Build Coastguard Worker       .z_read_only = !(ds_aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
1638*61046927SAndroid Build Coastguard Worker       .stencil_read_only = !(ds_aspects & VK_IMAGE_ASPECT_STENCIL_BIT),
1639*61046927SAndroid Build Coastguard Worker       .htile_enabled = radv_htile_enabled(iview->image, level),
1640*61046927SAndroid Build Coastguard Worker       .htile_stencil_disabled = radv_image_tile_stencil_disabled(device, iview->image),
1641*61046927SAndroid Build Coastguard Worker       .vrs_enabled = radv_image_has_vrs_htile(device, iview->image),
1642*61046927SAndroid Build Coastguard Worker    };
1643*61046927SAndroid Build Coastguard Worker 
1644*61046927SAndroid Build Coastguard Worker    ac_init_ds_surface(&pdev->info, &ds_state, &ds->ac);
1645*61046927SAndroid Build Coastguard Worker 
1646*61046927SAndroid Build Coastguard Worker    const struct ac_mutable_ds_state mutable_ds_state = {
1647*61046927SAndroid Build Coastguard Worker       .ds = &ds->ac,
1648*61046927SAndroid Build Coastguard Worker       .format = vk_format_to_pipe_format(iview->image->vk.format),
1649*61046927SAndroid Build Coastguard Worker       .tc_compat_htile_enabled = radv_htile_enabled(iview->image, level) && radv_image_is_tc_compat_htile(iview->image),
1650*61046927SAndroid Build Coastguard Worker       .zrange_precision = true,
1651*61046927SAndroid Build Coastguard Worker       .no_d16_compression = true,
1652*61046927SAndroid Build Coastguard Worker    };
1653*61046927SAndroid Build Coastguard Worker 
1654*61046927SAndroid Build Coastguard Worker    ac_set_mutable_ds_surface_fields(&pdev->info, &mutable_ds_state, &ds->ac);
1655*61046927SAndroid Build Coastguard Worker 
1656*61046927SAndroid Build Coastguard Worker    if (pdev->info.gfx_level >= GFX11) {
1657*61046927SAndroid Build Coastguard Worker       radv_gfx11_set_db_render_control(device, iview->image->vk.samples, &ds->db_render_control);
1658*61046927SAndroid Build Coastguard Worker    }
1659*61046927SAndroid Build Coastguard Worker }
1660*61046927SAndroid Build Coastguard Worker 
1661*61046927SAndroid Build Coastguard Worker void
radv_gfx11_set_db_render_control(const struct radv_device * device,unsigned num_samples,unsigned * db_render_control)1662*61046927SAndroid Build Coastguard Worker radv_gfx11_set_db_render_control(const struct radv_device *device, unsigned num_samples, unsigned *db_render_control)
1663*61046927SAndroid Build Coastguard Worker {
1664*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
1665*61046927SAndroid Build Coastguard Worker    unsigned max_allowed_tiles_in_wave = 0;
1666*61046927SAndroid Build Coastguard Worker 
1667*61046927SAndroid Build Coastguard Worker    if (pdev->info.has_dedicated_vram) {
1668*61046927SAndroid Build Coastguard Worker       if (num_samples == 8)
1669*61046927SAndroid Build Coastguard Worker          max_allowed_tiles_in_wave = 6;
1670*61046927SAndroid Build Coastguard Worker       else if (num_samples == 4)
1671*61046927SAndroid Build Coastguard Worker          max_allowed_tiles_in_wave = 13;
1672*61046927SAndroid Build Coastguard Worker       else
1673*61046927SAndroid Build Coastguard Worker          max_allowed_tiles_in_wave = 0;
1674*61046927SAndroid Build Coastguard Worker    } else {
1675*61046927SAndroid Build Coastguard Worker       if (num_samples == 8)
1676*61046927SAndroid Build Coastguard Worker          max_allowed_tiles_in_wave = 7;
1677*61046927SAndroid Build Coastguard Worker       else if (num_samples == 4)
1678*61046927SAndroid Build Coastguard Worker          max_allowed_tiles_in_wave = 15;
1679*61046927SAndroid Build Coastguard Worker       else
1680*61046927SAndroid Build Coastguard Worker          max_allowed_tiles_in_wave = 0;
1681*61046927SAndroid Build Coastguard Worker    }
1682*61046927SAndroid Build Coastguard Worker 
1683*61046927SAndroid Build Coastguard Worker    *db_render_control |= S_028000_MAX_ALLOWED_TILES_IN_WAVE(max_allowed_tiles_in_wave);
1684*61046927SAndroid Build Coastguard Worker }
1685*61046927SAndroid Build Coastguard Worker 
1686*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
radv_GetMemoryFdKHR(VkDevice _device,const VkMemoryGetFdInfoKHR * pGetFdInfo,int * pFD)1687*61046927SAndroid Build Coastguard Worker radv_GetMemoryFdKHR(VkDevice _device, const VkMemoryGetFdInfoKHR *pGetFdInfo, int *pFD)
1688*61046927SAndroid Build Coastguard Worker {
1689*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(radv_device, device, _device);
1690*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(radv_device_memory, memory, pGetFdInfo->memory);
1691*61046927SAndroid Build Coastguard Worker 
1692*61046927SAndroid Build Coastguard Worker    assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR);
1693*61046927SAndroid Build Coastguard Worker 
1694*61046927SAndroid Build Coastguard Worker    /* At the moment, we support only the below handle types. */
1695*61046927SAndroid Build Coastguard Worker    assert(pGetFdInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
1696*61046927SAndroid Build Coastguard Worker           pGetFdInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
1697*61046927SAndroid Build Coastguard Worker 
1698*61046927SAndroid Build Coastguard Worker    bool ret = radv_get_memory_fd(device, memory, pFD);
1699*61046927SAndroid Build Coastguard Worker    if (ret == false)
1700*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
1701*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1702*61046927SAndroid Build Coastguard Worker }
1703*61046927SAndroid Build Coastguard Worker 
1704*61046927SAndroid Build Coastguard Worker static uint32_t
radv_compute_valid_memory_types_attempt(struct radv_physical_device * pdev,enum radeon_bo_domain domains,enum radeon_bo_flag flags,enum radeon_bo_flag ignore_flags)1705*61046927SAndroid Build Coastguard Worker radv_compute_valid_memory_types_attempt(struct radv_physical_device *pdev, enum radeon_bo_domain domains,
1706*61046927SAndroid Build Coastguard Worker                                         enum radeon_bo_flag flags, enum radeon_bo_flag ignore_flags)
1707*61046927SAndroid Build Coastguard Worker {
1708*61046927SAndroid Build Coastguard Worker    /* Don't count GTT/CPU as relevant:
1709*61046927SAndroid Build Coastguard Worker     *
1710*61046927SAndroid Build Coastguard Worker     * - We're not fully consistent between the two.
1711*61046927SAndroid Build Coastguard Worker     * - Sometimes VRAM gets VRAM|GTT.
1712*61046927SAndroid Build Coastguard Worker     */
1713*61046927SAndroid Build Coastguard Worker    const enum radeon_bo_domain relevant_domains = RADEON_DOMAIN_VRAM | RADEON_DOMAIN_GDS | RADEON_DOMAIN_OA;
1714*61046927SAndroid Build Coastguard Worker    uint32_t bits = 0;
1715*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < pdev->memory_properties.memoryTypeCount; ++i) {
1716*61046927SAndroid Build Coastguard Worker       if ((domains & relevant_domains) != (pdev->memory_domains[i] & relevant_domains))
1717*61046927SAndroid Build Coastguard Worker          continue;
1718*61046927SAndroid Build Coastguard Worker 
1719*61046927SAndroid Build Coastguard Worker       if ((flags & ~ignore_flags) != (pdev->memory_flags[i] & ~ignore_flags))
1720*61046927SAndroid Build Coastguard Worker          continue;
1721*61046927SAndroid Build Coastguard Worker 
1722*61046927SAndroid Build Coastguard Worker       bits |= 1u << i;
1723*61046927SAndroid Build Coastguard Worker    }
1724*61046927SAndroid Build Coastguard Worker 
1725*61046927SAndroid Build Coastguard Worker    return bits;
1726*61046927SAndroid Build Coastguard Worker }
1727*61046927SAndroid Build Coastguard Worker 
1728*61046927SAndroid Build Coastguard Worker static uint32_t
radv_compute_valid_memory_types(struct radv_physical_device * pdev,enum radeon_bo_domain domains,enum radeon_bo_flag flags)1729*61046927SAndroid Build Coastguard Worker radv_compute_valid_memory_types(struct radv_physical_device *pdev, enum radeon_bo_domain domains,
1730*61046927SAndroid Build Coastguard Worker                                 enum radeon_bo_flag flags)
1731*61046927SAndroid Build Coastguard Worker {
1732*61046927SAndroid Build Coastguard Worker    enum radeon_bo_flag ignore_flags = ~(RADEON_FLAG_NO_CPU_ACCESS | RADEON_FLAG_GTT_WC);
1733*61046927SAndroid Build Coastguard Worker    uint32_t bits = radv_compute_valid_memory_types_attempt(pdev, domains, flags, ignore_flags);
1734*61046927SAndroid Build Coastguard Worker 
1735*61046927SAndroid Build Coastguard Worker    if (!bits) {
1736*61046927SAndroid Build Coastguard Worker       ignore_flags |= RADEON_FLAG_GTT_WC;
1737*61046927SAndroid Build Coastguard Worker       bits = radv_compute_valid_memory_types_attempt(pdev, domains, flags, ignore_flags);
1738*61046927SAndroid Build Coastguard Worker    }
1739*61046927SAndroid Build Coastguard Worker 
1740*61046927SAndroid Build Coastguard Worker    if (!bits) {
1741*61046927SAndroid Build Coastguard Worker       ignore_flags |= RADEON_FLAG_NO_CPU_ACCESS;
1742*61046927SAndroid Build Coastguard Worker       bits = radv_compute_valid_memory_types_attempt(pdev, domains, flags, ignore_flags);
1743*61046927SAndroid Build Coastguard Worker    }
1744*61046927SAndroid Build Coastguard Worker 
1745*61046927SAndroid Build Coastguard Worker    /* Avoid 32-bit memory types for shared memory. */
1746*61046927SAndroid Build Coastguard Worker    bits &= ~pdev->memory_types_32bit;
1747*61046927SAndroid Build Coastguard Worker 
1748*61046927SAndroid Build Coastguard Worker    return bits;
1749*61046927SAndroid Build Coastguard Worker }
1750*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
radv_GetMemoryFdPropertiesKHR(VkDevice _device,VkExternalMemoryHandleTypeFlagBits handleType,int fd,VkMemoryFdPropertiesKHR * pMemoryFdProperties)1751*61046927SAndroid Build Coastguard Worker radv_GetMemoryFdPropertiesKHR(VkDevice _device, VkExternalMemoryHandleTypeFlagBits handleType, int fd,
1752*61046927SAndroid Build Coastguard Worker                               VkMemoryFdPropertiesKHR *pMemoryFdProperties)
1753*61046927SAndroid Build Coastguard Worker {
1754*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(radv_device, device, _device);
1755*61046927SAndroid Build Coastguard Worker    struct radv_physical_device *pdev = radv_device_physical(device);
1756*61046927SAndroid Build Coastguard Worker 
1757*61046927SAndroid Build Coastguard Worker    switch (handleType) {
1758*61046927SAndroid Build Coastguard Worker    case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: {
1759*61046927SAndroid Build Coastguard Worker       enum radeon_bo_domain domains;
1760*61046927SAndroid Build Coastguard Worker       enum radeon_bo_flag flags;
1761*61046927SAndroid Build Coastguard Worker       if (!device->ws->buffer_get_flags_from_fd(device->ws, fd, &domains, &flags))
1762*61046927SAndroid Build Coastguard Worker          return vk_error(device, VK_ERROR_INVALID_EXTERNAL_HANDLE);
1763*61046927SAndroid Build Coastguard Worker 
1764*61046927SAndroid Build Coastguard Worker       pMemoryFdProperties->memoryTypeBits = radv_compute_valid_memory_types(pdev, domains, flags);
1765*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
1766*61046927SAndroid Build Coastguard Worker    }
1767*61046927SAndroid Build Coastguard Worker    default:
1768*61046927SAndroid Build Coastguard Worker       /* The valid usage section for this function says:
1769*61046927SAndroid Build Coastguard Worker        *
1770*61046927SAndroid Build Coastguard Worker        *    "handleType must not be one of the handle types defined as
1771*61046927SAndroid Build Coastguard Worker        *    opaque."
1772*61046927SAndroid Build Coastguard Worker        *
1773*61046927SAndroid Build Coastguard Worker        * So opaque handle types fall into the default "unsupported" case.
1774*61046927SAndroid Build Coastguard Worker        */
1775*61046927SAndroid Build Coastguard Worker       return vk_error(device, VK_ERROR_INVALID_EXTERNAL_HANDLE);
1776*61046927SAndroid Build Coastguard Worker    }
1777*61046927SAndroid Build Coastguard Worker }
1778*61046927SAndroid Build Coastguard Worker 
1779*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
radv_GetCalibratedTimestampsKHR(VkDevice _device,uint32_t timestampCount,const VkCalibratedTimestampInfoKHR * pTimestampInfos,uint64_t * pTimestamps,uint64_t * pMaxDeviation)1780*61046927SAndroid Build Coastguard Worker radv_GetCalibratedTimestampsKHR(VkDevice _device, uint32_t timestampCount,
1781*61046927SAndroid Build Coastguard Worker                                 const VkCalibratedTimestampInfoKHR *pTimestampInfos, uint64_t *pTimestamps,
1782*61046927SAndroid Build Coastguard Worker                                 uint64_t *pMaxDeviation)
1783*61046927SAndroid Build Coastguard Worker {
1784*61046927SAndroid Build Coastguard Worker #ifndef _WIN32
1785*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(radv_device, device, _device);
1786*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
1787*61046927SAndroid Build Coastguard Worker    uint32_t clock_crystal_freq = pdev->info.clock_crystal_freq;
1788*61046927SAndroid Build Coastguard Worker    int d;
1789*61046927SAndroid Build Coastguard Worker    uint64_t begin, end;
1790*61046927SAndroid Build Coastguard Worker    uint64_t max_clock_period = 0;
1791*61046927SAndroid Build Coastguard Worker 
1792*61046927SAndroid Build Coastguard Worker #ifdef CLOCK_MONOTONIC_RAW
1793*61046927SAndroid Build Coastguard Worker    begin = vk_clock_gettime(CLOCK_MONOTONIC_RAW);
1794*61046927SAndroid Build Coastguard Worker #else
1795*61046927SAndroid Build Coastguard Worker    begin = vk_clock_gettime(CLOCK_MONOTONIC);
1796*61046927SAndroid Build Coastguard Worker #endif
1797*61046927SAndroid Build Coastguard Worker 
1798*61046927SAndroid Build Coastguard Worker    for (d = 0; d < timestampCount; d++) {
1799*61046927SAndroid Build Coastguard Worker       switch (pTimestampInfos[d].timeDomain) {
1800*61046927SAndroid Build Coastguard Worker       case VK_TIME_DOMAIN_DEVICE_KHR:
1801*61046927SAndroid Build Coastguard Worker          pTimestamps[d] = device->ws->query_value(device->ws, RADEON_TIMESTAMP);
1802*61046927SAndroid Build Coastguard Worker          uint64_t device_period = DIV_ROUND_UP(1000000, clock_crystal_freq);
1803*61046927SAndroid Build Coastguard Worker          max_clock_period = MAX2(max_clock_period, device_period);
1804*61046927SAndroid Build Coastguard Worker          break;
1805*61046927SAndroid Build Coastguard Worker       case VK_TIME_DOMAIN_CLOCK_MONOTONIC_KHR:
1806*61046927SAndroid Build Coastguard Worker          pTimestamps[d] = vk_clock_gettime(CLOCK_MONOTONIC);
1807*61046927SAndroid Build Coastguard Worker          max_clock_period = MAX2(max_clock_period, 1);
1808*61046927SAndroid Build Coastguard Worker          break;
1809*61046927SAndroid Build Coastguard Worker 
1810*61046927SAndroid Build Coastguard Worker #ifdef CLOCK_MONOTONIC_RAW
1811*61046927SAndroid Build Coastguard Worker       case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_KHR:
1812*61046927SAndroid Build Coastguard Worker          pTimestamps[d] = begin;
1813*61046927SAndroid Build Coastguard Worker          break;
1814*61046927SAndroid Build Coastguard Worker #endif
1815*61046927SAndroid Build Coastguard Worker       default:
1816*61046927SAndroid Build Coastguard Worker          pTimestamps[d] = 0;
1817*61046927SAndroid Build Coastguard Worker          break;
1818*61046927SAndroid Build Coastguard Worker       }
1819*61046927SAndroid Build Coastguard Worker    }
1820*61046927SAndroid Build Coastguard Worker 
1821*61046927SAndroid Build Coastguard Worker #ifdef CLOCK_MONOTONIC_RAW
1822*61046927SAndroid Build Coastguard Worker    end = vk_clock_gettime(CLOCK_MONOTONIC_RAW);
1823*61046927SAndroid Build Coastguard Worker #else
1824*61046927SAndroid Build Coastguard Worker    end = vk_clock_gettime(CLOCK_MONOTONIC);
1825*61046927SAndroid Build Coastguard Worker #endif
1826*61046927SAndroid Build Coastguard Worker 
1827*61046927SAndroid Build Coastguard Worker    *pMaxDeviation = vk_time_max_deviation(begin, end, max_clock_period);
1828*61046927SAndroid Build Coastguard Worker 
1829*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
1830*61046927SAndroid Build Coastguard Worker #else
1831*61046927SAndroid Build Coastguard Worker    return VK_ERROR_FEATURE_NOT_PRESENT;
1832*61046927SAndroid Build Coastguard Worker #endif
1833*61046927SAndroid Build Coastguard Worker }
1834*61046927SAndroid Build Coastguard Worker 
1835*61046927SAndroid Build Coastguard Worker bool
radv_device_set_pstate(struct radv_device * device,bool enable)1836*61046927SAndroid Build Coastguard Worker radv_device_set_pstate(struct radv_device *device, bool enable)
1837*61046927SAndroid Build Coastguard Worker {
1838*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
1839*61046927SAndroid Build Coastguard Worker    const struct radv_instance *instance = radv_physical_device_instance(pdev);
1840*61046927SAndroid Build Coastguard Worker    struct radeon_winsys *ws = device->ws;
1841*61046927SAndroid Build Coastguard Worker    enum radeon_ctx_pstate pstate = enable ? instance->profile_pstate : RADEON_CTX_PSTATE_NONE;
1842*61046927SAndroid Build Coastguard Worker 
1843*61046927SAndroid Build Coastguard Worker    if (pdev->info.has_stable_pstate) {
1844*61046927SAndroid Build Coastguard Worker       /* pstate is per-device; setting it for one ctx is sufficient.
1845*61046927SAndroid Build Coastguard Worker        * We pick the first initialized one below. */
1846*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < RADV_NUM_HW_CTX; i++)
1847*61046927SAndroid Build Coastguard Worker          if (device->hw_ctx[i])
1848*61046927SAndroid Build Coastguard Worker             return ws->ctx_set_pstate(device->hw_ctx[i], pstate) >= 0;
1849*61046927SAndroid Build Coastguard Worker    }
1850*61046927SAndroid Build Coastguard Worker 
1851*61046927SAndroid Build Coastguard Worker    return true;
1852*61046927SAndroid Build Coastguard Worker }
1853*61046927SAndroid Build Coastguard Worker 
1854*61046927SAndroid Build Coastguard Worker bool
radv_device_acquire_performance_counters(struct radv_device * device)1855*61046927SAndroid Build Coastguard Worker radv_device_acquire_performance_counters(struct radv_device *device)
1856*61046927SAndroid Build Coastguard Worker {
1857*61046927SAndroid Build Coastguard Worker    bool result = true;
1858*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&device->pstate_mtx);
1859*61046927SAndroid Build Coastguard Worker 
1860*61046927SAndroid Build Coastguard Worker    if (device->pstate_cnt == 0) {
1861*61046927SAndroid Build Coastguard Worker       result = radv_device_set_pstate(device, true);
1862*61046927SAndroid Build Coastguard Worker       if (result)
1863*61046927SAndroid Build Coastguard Worker          ++device->pstate_cnt;
1864*61046927SAndroid Build Coastguard Worker    }
1865*61046927SAndroid Build Coastguard Worker 
1866*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&device->pstate_mtx);
1867*61046927SAndroid Build Coastguard Worker    return result;
1868*61046927SAndroid Build Coastguard Worker }
1869*61046927SAndroid Build Coastguard Worker 
1870*61046927SAndroid Build Coastguard Worker void
radv_device_release_performance_counters(struct radv_device * device)1871*61046927SAndroid Build Coastguard Worker radv_device_release_performance_counters(struct radv_device *device)
1872*61046927SAndroid Build Coastguard Worker {
1873*61046927SAndroid Build Coastguard Worker    simple_mtx_lock(&device->pstate_mtx);
1874*61046927SAndroid Build Coastguard Worker 
1875*61046927SAndroid Build Coastguard Worker    if (--device->pstate_cnt == 0)
1876*61046927SAndroid Build Coastguard Worker       radv_device_set_pstate(device, false);
1877*61046927SAndroid Build Coastguard Worker 
1878*61046927SAndroid Build Coastguard Worker    simple_mtx_unlock(&device->pstate_mtx);
1879*61046927SAndroid Build Coastguard Worker }
1880*61046927SAndroid Build Coastguard Worker 
1881*61046927SAndroid Build Coastguard Worker VKAPI_ATTR VkResult VKAPI_CALL
radv_AcquireProfilingLockKHR(VkDevice _device,const VkAcquireProfilingLockInfoKHR * pInfo)1882*61046927SAndroid Build Coastguard Worker radv_AcquireProfilingLockKHR(VkDevice _device, const VkAcquireProfilingLockInfoKHR *pInfo)
1883*61046927SAndroid Build Coastguard Worker {
1884*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(radv_device, device, _device);
1885*61046927SAndroid Build Coastguard Worker    bool result = radv_device_acquire_performance_counters(device);
1886*61046927SAndroid Build Coastguard Worker    return result ? VK_SUCCESS : VK_ERROR_UNKNOWN;
1887*61046927SAndroid Build Coastguard Worker }
1888*61046927SAndroid Build Coastguard Worker 
1889*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
radv_ReleaseProfilingLockKHR(VkDevice _device)1890*61046927SAndroid Build Coastguard Worker radv_ReleaseProfilingLockKHR(VkDevice _device)
1891*61046927SAndroid Build Coastguard Worker {
1892*61046927SAndroid Build Coastguard Worker    VK_FROM_HANDLE(radv_device, device, _device);
1893*61046927SAndroid Build Coastguard Worker    radv_device_release_performance_counters(device);
1894*61046927SAndroid Build Coastguard Worker }
1895*61046927SAndroid Build Coastguard Worker 
1896*61046927SAndroid Build Coastguard Worker VKAPI_ATTR void VKAPI_CALL
radv_GetDeviceImageSubresourceLayoutKHR(VkDevice device,const VkDeviceImageSubresourceInfoKHR * pInfo,VkSubresourceLayout2KHR * pLayout)1897*61046927SAndroid Build Coastguard Worker radv_GetDeviceImageSubresourceLayoutKHR(VkDevice device, const VkDeviceImageSubresourceInfoKHR *pInfo,
1898*61046927SAndroid Build Coastguard Worker                                         VkSubresourceLayout2KHR *pLayout)
1899*61046927SAndroid Build Coastguard Worker {
1900*61046927SAndroid Build Coastguard Worker    UNUSED VkResult result;
1901*61046927SAndroid Build Coastguard Worker    VkImage image;
1902*61046927SAndroid Build Coastguard Worker 
1903*61046927SAndroid Build Coastguard Worker    result =
1904*61046927SAndroid Build Coastguard Worker       radv_image_create(device, &(struct radv_image_create_info){.vk_info = pInfo->pCreateInfo}, NULL, &image, true);
1905*61046927SAndroid Build Coastguard Worker    assert(result == VK_SUCCESS);
1906*61046927SAndroid Build Coastguard Worker 
1907*61046927SAndroid Build Coastguard Worker    radv_GetImageSubresourceLayout2KHR(device, image, pInfo->pSubresource, pLayout);
1908*61046927SAndroid Build Coastguard Worker 
1909*61046927SAndroid Build Coastguard Worker    radv_DestroyImage(device, image, NULL);
1910*61046927SAndroid Build Coastguard Worker }
1911