ac/surface: add a wrapper structure to hold ADDR_HANDLE
[mesa.git] / src / amd / vulkan / winsys / amdgpu / radv_amdgpu_winsys.c
1 /*
2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 * based on amdgpu winsys.
5 * Copyright © 2011 Marek Olšák <maraeo@gmail.com>
6 * Copyright © 2015 Advanced Micro Devices, Inc.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * IN THE SOFTWARE.
26 */
27 #include "radv_amdgpu_winsys.h"
28 #include "radv_amdgpu_winsys_public.h"
29 #include "radv_amdgpu_surface.h"
30 #include "radv_debug.h"
31 #include "ac_surface.h"
32 #include "xf86drm.h"
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include "drm-uapi/amdgpu_drm.h"
37 #include <assert.h>
38 #include "radv_amdgpu_cs.h"
39 #include "radv_amdgpu_bo.h"
40 #include "radv_amdgpu_surface.h"
41
42 static bool
43 do_winsys_init(struct radv_amdgpu_winsys *ws, int fd)
44 {
45 if (!ac_query_gpu_info(fd, ws->dev, &ws->info, &ws->amdinfo))
46 return false;
47
48 /* LLVM 9.0 is required for GFX10. */
49 if (ws->info.chip_class == GFX10 && LLVM_VERSION_MAJOR < 9) {
50 fprintf(stderr, "radv: Navi family support requires LLVM 9 or higher\n");
51 return false;
52 }
53
54 /* temporary */
55 ws->info.use_display_dcc_unaligned = false;
56 ws->info.use_display_dcc_with_retile_blit = false;
57
58 ws->addrlib = ac_addrlib_create(&ws->info, &ws->amdinfo, &ws->info.max_alignment);
59 if (!ws->addrlib) {
60 fprintf(stderr, "amdgpu: Cannot create addrlib.\n");
61 return false;
62 }
63
64 ws->info.num_rings[RING_DMA] = MIN2(ws->info.num_rings[RING_DMA], MAX_RINGS_PER_TYPE);
65 ws->info.num_rings[RING_COMPUTE] = MIN2(ws->info.num_rings[RING_COMPUTE], MAX_RINGS_PER_TYPE);
66
67 ws->use_ib_bos = ws->info.chip_class >= GFX7;
68 return true;
69 }
70
71 static void radv_amdgpu_winsys_query_info(struct radeon_winsys *rws,
72 struct radeon_info *info)
73 {
74 *info = ((struct radv_amdgpu_winsys *)rws)->info;
75 }
76
77 static uint64_t radv_amdgpu_winsys_query_value(struct radeon_winsys *rws,
78 enum radeon_value_id value)
79 {
80 struct radv_amdgpu_winsys *ws = (struct radv_amdgpu_winsys *)rws;
81 struct amdgpu_heap_info heap;
82 uint64_t retval = 0;
83
84 switch (value) {
85 case RADEON_ALLOCATED_VRAM:
86 return ws->allocated_vram;
87 case RADEON_ALLOCATED_VRAM_VIS:
88 return ws->allocated_vram_vis;
89 case RADEON_ALLOCATED_GTT:
90 return ws->allocated_gtt;
91 case RADEON_TIMESTAMP:
92 amdgpu_query_info(ws->dev, AMDGPU_INFO_TIMESTAMP, 8, &retval);
93 return retval;
94 case RADEON_NUM_BYTES_MOVED:
95 amdgpu_query_info(ws->dev, AMDGPU_INFO_NUM_BYTES_MOVED,
96 8, &retval);
97 return retval;
98 case RADEON_NUM_EVICTIONS:
99 amdgpu_query_info(ws->dev, AMDGPU_INFO_NUM_EVICTIONS,
100 8, &retval);
101 return retval;
102 case RADEON_NUM_VRAM_CPU_PAGE_FAULTS:
103 amdgpu_query_info(ws->dev, AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS,
104 8, &retval);
105 return retval;
106 case RADEON_VRAM_USAGE:
107 amdgpu_query_heap_info(ws->dev, AMDGPU_GEM_DOMAIN_VRAM,
108 0, &heap);
109 return heap.heap_usage;
110 case RADEON_VRAM_VIS_USAGE:
111 amdgpu_query_heap_info(ws->dev, AMDGPU_GEM_DOMAIN_VRAM,
112 AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
113 &heap);
114 return heap.heap_usage;
115 case RADEON_GTT_USAGE:
116 amdgpu_query_heap_info(ws->dev, AMDGPU_GEM_DOMAIN_GTT,
117 0, &heap);
118 return heap.heap_usage;
119 case RADEON_GPU_TEMPERATURE:
120 amdgpu_query_sensor_info(ws->dev, AMDGPU_INFO_SENSOR_GPU_TEMP,
121 4, &retval);
122 return retval;
123 case RADEON_CURRENT_SCLK:
124 amdgpu_query_sensor_info(ws->dev, AMDGPU_INFO_SENSOR_GFX_SCLK,
125 4, &retval);
126 return retval;
127 case RADEON_CURRENT_MCLK:
128 amdgpu_query_sensor_info(ws->dev, AMDGPU_INFO_SENSOR_GFX_MCLK,
129 4, &retval);
130 return retval;
131 default:
132 unreachable("invalid query value");
133 }
134
135 return 0;
136 }
137
138 static bool radv_amdgpu_winsys_read_registers(struct radeon_winsys *rws,
139 unsigned reg_offset,
140 unsigned num_registers, uint32_t *out)
141 {
142 struct radv_amdgpu_winsys *ws = (struct radv_amdgpu_winsys*)rws;
143
144 return amdgpu_read_mm_registers(ws->dev, reg_offset / 4, num_registers,
145 0xffffffff, 0, out) == 0;
146 }
147
148 static const char *radv_amdgpu_winsys_get_chip_name(struct radeon_winsys *rws)
149 {
150 amdgpu_device_handle dev = ((struct radv_amdgpu_winsys *)rws)->dev;
151
152 return amdgpu_get_marketing_name(dev);
153 }
154
155 static void radv_amdgpu_winsys_destroy(struct radeon_winsys *rws)
156 {
157 struct radv_amdgpu_winsys *ws = (struct radv_amdgpu_winsys*)rws;
158
159 ac_addrlib_destroy(ws->addrlib);
160 amdgpu_device_deinitialize(ws->dev);
161 FREE(rws);
162 }
163
164 struct radeon_winsys *
165 radv_amdgpu_winsys_create(int fd, uint64_t debug_flags, uint64_t perftest_flags)
166 {
167 uint32_t drm_major, drm_minor, r;
168 amdgpu_device_handle dev;
169 struct radv_amdgpu_winsys *ws;
170
171 r = amdgpu_device_initialize(fd, &drm_major, &drm_minor, &dev);
172 if (r)
173 return NULL;
174
175 ws = calloc(1, sizeof(struct radv_amdgpu_winsys));
176 if (!ws)
177 goto fail;
178
179 ws->dev = dev;
180 ws->info.drm_major = drm_major;
181 ws->info.drm_minor = drm_minor;
182 if (!do_winsys_init(ws, fd))
183 goto winsys_fail;
184
185 ws->debug_all_bos = !!(debug_flags & RADV_DEBUG_ALL_BOS);
186 if (debug_flags & RADV_DEBUG_NO_IBS)
187 ws->use_ib_bos = false;
188
189 ws->use_local_bos = perftest_flags & RADV_PERFTEST_LOCAL_BOS;
190 ws->zero_all_vram_allocs = debug_flags & RADV_DEBUG_ZERO_VRAM;
191 list_inithead(&ws->global_bo_list);
192 pthread_mutex_init(&ws->global_bo_list_lock, NULL);
193 ws->base.query_info = radv_amdgpu_winsys_query_info;
194 ws->base.query_value = radv_amdgpu_winsys_query_value;
195 ws->base.read_registers = radv_amdgpu_winsys_read_registers;
196 ws->base.get_chip_name = radv_amdgpu_winsys_get_chip_name;
197 ws->base.destroy = radv_amdgpu_winsys_destroy;
198 radv_amdgpu_bo_init_functions(ws);
199 radv_amdgpu_cs_init_functions(ws);
200 radv_amdgpu_surface_init_functions(ws);
201
202 return &ws->base;
203
204 winsys_fail:
205 free(ws);
206 fail:
207 amdgpu_device_deinitialize(dev);
208 return NULL;
209 }