1/*
2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 *
5 * based on amdgpu winsys.
6 * Copyright © 2011 Marek Olšák <maraeo@gmail.com>
7 * Copyright © 2015 Advanced Micro Devices, Inc.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26 * IN THE SOFTWARE.
27 */
28
29#include <errno.h>
30
31#include "radv_private.h"
32#include "addrlib/addrinterface.h"
33#include "util/bitset.h"
34#include "radv_amdgpu_winsys.h"
35#include "radv_amdgpu_surface.h"
36#include "sid.h"
37
38#ifndef NO_ENTRIES
39#define NO_ENTRIES 32
40#endif
41
42#ifndef NO_MACRO_ENTRIES
43#define NO_MACRO_ENTRIES 16
44#endif
45
46#ifndef CIASICIDGFXENGINE_SOUTHERNISLAND
47#define CIASICIDGFXENGINE_SOUTHERNISLAND 0x0000000A
48#endif
49
50static int radv_amdgpu_surface_sanity(const struct radeon_surf *surf)
51{
52	unsigned type = RADEON_SURF_GET(surf->flags, TYPE);
53
54	if (!(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))
55		return -EINVAL;
56
57	/* all dimension must be at least 1 ! */
58	if (!surf->npix_x || !surf->npix_y || !surf->npix_z ||
59	    !surf->array_size)
60		return -EINVAL;
61
62	if (!surf->blk_w || !surf->blk_h || !surf->blk_d)
63		return -EINVAL;
64
65	switch (surf->nsamples) {
66	case 1:
67	case 2:
68	case 4:
69	case 8:
70		break;
71	default:
72		return -EINVAL;
73	}
74
75	switch (type) {
76	case RADEON_SURF_TYPE_1D:
77		if (surf->npix_y > 1)
78			return -EINVAL;
79		/* fall through */
80	case RADEON_SURF_TYPE_2D:
81	case RADEON_SURF_TYPE_CUBEMAP:
82		if (surf->npix_z > 1 || surf->array_size > 1)
83			return -EINVAL;
84		break;
85	case RADEON_SURF_TYPE_3D:
86		if (surf->array_size > 1)
87			return -EINVAL;
88		break;
89	case RADEON_SURF_TYPE_1D_ARRAY:
90		if (surf->npix_y > 1)
91			return -EINVAL;
92		/* fall through */
93	case RADEON_SURF_TYPE_2D_ARRAY:
94		if (surf->npix_z > 1)
95			return -EINVAL;
96		break;
97	default:
98		return -EINVAL;
99	}
100	return 0;
101}
102
103static void *ADDR_API radv_allocSysMem(const ADDR_ALLOCSYSMEM_INPUT * pInput)
104{
105	return malloc(pInput->sizeInBytes);
106}
107
108static ADDR_E_RETURNCODE ADDR_API radv_freeSysMem(const ADDR_FREESYSMEM_INPUT * pInput)
109{
110	free(pInput->pVirtAddr);
111	return ADDR_OK;
112}
113
114ADDR_HANDLE radv_amdgpu_addr_create(struct amdgpu_gpu_info *amdinfo, int family, int rev_id,
115				    enum chip_class chip_class)
116{
117	ADDR_CREATE_INPUT addrCreateInput = {0};
118	ADDR_CREATE_OUTPUT addrCreateOutput = {0};
119	ADDR_REGISTER_VALUE regValue = {0};
120	ADDR_CREATE_FLAGS createFlags = {{0}};
121	ADDR_E_RETURNCODE addrRet;
122
123	addrCreateInput.size = sizeof(ADDR_CREATE_INPUT);
124	addrCreateOutput.size = sizeof(ADDR_CREATE_OUTPUT);
125
126	regValue.noOfBanks = amdinfo->mc_arb_ramcfg & 0x3;
127	regValue.gbAddrConfig = amdinfo->gb_addr_cfg;
128	regValue.noOfRanks = (amdinfo->mc_arb_ramcfg & 0x4) >> 2;
129
130	regValue.backendDisables = amdinfo->backend_disable[0];
131	regValue.pTileConfig = amdinfo->gb_tile_mode;
132	regValue.noOfEntries = ARRAY_SIZE(amdinfo->gb_tile_mode);
133	if (chip_class == SI) {
134		regValue.pMacroTileConfig = NULL;
135		regValue.noOfMacroEntries = 0;
136	} else {
137		regValue.pMacroTileConfig = amdinfo->gb_macro_tile_mode;
138		regValue.noOfMacroEntries = ARRAY_SIZE(amdinfo->gb_macro_tile_mode);
139	}
140
141	createFlags.value = 0;
142	createFlags.useTileIndex = 1;
143	createFlags.degradeBaseLevel = 1;
144
145	addrCreateInput.chipEngine = CIASICIDGFXENGINE_SOUTHERNISLAND;
146	addrCreateInput.chipFamily = family;
147	addrCreateInput.chipRevision = rev_id;
148	addrCreateInput.createFlags = createFlags;
149	addrCreateInput.callbacks.allocSysMem = radv_allocSysMem;
150	addrCreateInput.callbacks.freeSysMem = radv_freeSysMem;
151	addrCreateInput.callbacks.debugPrint = 0;
152	addrCreateInput.regValue = regValue;
153
154	addrRet = AddrCreate(&addrCreateInput, &addrCreateOutput);
155	if (addrRet != ADDR_OK)
156		return NULL;
157
158	return addrCreateOutput.hLib;
159}
160
161static int radv_compute_level(ADDR_HANDLE addrlib,
162                              struct radeon_surf *surf, bool is_stencil,
163                              unsigned level, unsigned type, bool compressed,
164                              ADDR_COMPUTE_SURFACE_INFO_INPUT *AddrSurfInfoIn,
165                              ADDR_COMPUTE_SURFACE_INFO_OUTPUT *AddrSurfInfoOut,
166                              ADDR_COMPUTE_DCCINFO_INPUT *AddrDccIn,
167                              ADDR_COMPUTE_DCCINFO_OUTPUT *AddrDccOut)
168{
169	struct radeon_surf_level *surf_level;
170	ADDR_E_RETURNCODE ret;
171
172	AddrSurfInfoIn->mipLevel = level;
173	AddrSurfInfoIn->width = u_minify(surf->npix_x, level);
174	AddrSurfInfoIn->height = u_minify(surf->npix_y, level);
175
176	if (type == RADEON_SURF_TYPE_3D)
177		AddrSurfInfoIn->numSlices = u_minify(surf->npix_z, level);
178	else if (type == RADEON_SURF_TYPE_CUBEMAP)
179		AddrSurfInfoIn->numSlices = 6;
180	else
181		AddrSurfInfoIn->numSlices = surf->array_size;
182
183	if (level > 0) {
184		/* Set the base level pitch. This is needed for calculation
185		 * of non-zero levels. */
186		if (is_stencil)
187			AddrSurfInfoIn->basePitch = surf->stencil_level[0].nblk_x;
188		else
189			AddrSurfInfoIn->basePitch = surf->level[0].nblk_x;
190
191		/* Convert blocks to pixels for compressed formats. */
192		if (compressed)
193			AddrSurfInfoIn->basePitch *= surf->blk_w;
194	}
195
196	ret = AddrComputeSurfaceInfo(addrlib,
197				     AddrSurfInfoIn,
198				     AddrSurfInfoOut);
199	if (ret != ADDR_OK)
200		return ret;
201
202	surf_level = is_stencil ? &surf->stencil_level[level] : &surf->level[level];
203	surf_level->offset = align64(surf->bo_size, AddrSurfInfoOut->baseAlign);
204	surf_level->slice_size = AddrSurfInfoOut->sliceSize;
205	surf_level->pitch_bytes = AddrSurfInfoOut->pitch * (is_stencil ? 1 : surf->bpe);
206	surf_level->npix_x = u_minify(surf->npix_x, level);
207	surf_level->npix_y = u_minify(surf->npix_y, level);
208	surf_level->npix_z = u_minify(surf->npix_z, level);
209	surf_level->nblk_x = AddrSurfInfoOut->pitch;
210	surf_level->nblk_y = AddrSurfInfoOut->height;
211	if (type == RADEON_SURF_TYPE_3D)
212		surf_level->nblk_z = AddrSurfInfoOut->depth;
213	else
214		surf_level->nblk_z = 1;
215
216	switch (AddrSurfInfoOut->tileMode) {
217	case ADDR_TM_LINEAR_ALIGNED:
218		surf_level->mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
219		break;
220	case ADDR_TM_1D_TILED_THIN1:
221		surf_level->mode = RADEON_SURF_MODE_1D;
222		break;
223	case ADDR_TM_2D_TILED_THIN1:
224		surf_level->mode = RADEON_SURF_MODE_2D;
225		break;
226	default:
227		assert(0);
228	}
229
230	if (is_stencil)
231		surf->stencil_tiling_index[level] = AddrSurfInfoOut->tileIndex;
232	else
233		surf->tiling_index[level] = AddrSurfInfoOut->tileIndex;
234
235	surf->bo_size = surf_level->offset + AddrSurfInfoOut->surfSize;
236
237	/* Clear DCC fields at the beginning. */
238	surf_level->dcc_offset = 0;
239	surf_level->dcc_enabled = false;
240
241	/* The previous level's flag tells us if we can use DCC for this level. */
242	if (AddrSurfInfoIn->flags.dccCompatible &&
243	    (level == 0 || AddrDccOut->subLvlCompressible)) {
244		AddrDccIn->colorSurfSize = AddrSurfInfoOut->surfSize;
245		AddrDccIn->tileMode = AddrSurfInfoOut->tileMode;
246		AddrDccIn->tileInfo = *AddrSurfInfoOut->pTileInfo;
247		AddrDccIn->tileIndex = AddrSurfInfoOut->tileIndex;
248		AddrDccIn->macroModeIndex = AddrSurfInfoOut->macroModeIndex;
249
250		ret = AddrComputeDccInfo(addrlib,
251					 AddrDccIn,
252					 AddrDccOut);
253
254		if (ret == ADDR_OK) {
255			surf_level->dcc_offset = surf->dcc_size;
256			surf_level->dcc_fast_clear_size = AddrDccOut->dccFastClearSize;
257			surf_level->dcc_enabled = true;
258			surf->dcc_size = surf_level->dcc_offset + AddrDccOut->dccRamSize;
259			surf->dcc_alignment = MAX2(surf->dcc_alignment, AddrDccOut->dccRamBaseAlign);
260		}
261	}
262
263	return 0;
264}
265
266static void radv_set_micro_tile_mode(struct radeon_surf *surf,
267                                     struct radeon_info *info)
268{
269	uint32_t tile_mode = info->si_tile_mode_array[surf->tiling_index[0]];
270
271	if (info->chip_class >= CIK)
272		surf->micro_tile_mode = G_009910_MICRO_TILE_MODE_NEW(tile_mode);
273	else
274		surf->micro_tile_mode = G_009910_MICRO_TILE_MODE(tile_mode);
275}
276
277static unsigned cik_get_macro_tile_index(struct radeon_surf *surf)
278{
279	unsigned index, tileb;
280
281	tileb = 8 * 8 * surf->bpe;
282	tileb = MIN2(surf->tile_split, tileb);
283
284	for (index = 0; tileb > 64; index++)
285		tileb >>= 1;
286
287	assert(index < 16);
288	return index;
289}
290
291static int radv_amdgpu_winsys_surface_init(struct radeon_winsys *_ws,
292					   struct radeon_surf *surf)
293{
294	struct radv_amdgpu_winsys *ws = radv_amdgpu_winsys(_ws);
295	unsigned level, mode, type;
296	bool compressed;
297	ADDR_COMPUTE_SURFACE_INFO_INPUT AddrSurfInfoIn = {0};
298	ADDR_COMPUTE_SURFACE_INFO_OUTPUT AddrSurfInfoOut = {0};
299	ADDR_COMPUTE_DCCINFO_INPUT AddrDccIn = {0};
300	ADDR_COMPUTE_DCCINFO_OUTPUT AddrDccOut = {0};
301	ADDR_TILEINFO AddrTileInfoIn = {0};
302	ADDR_TILEINFO AddrTileInfoOut = {0};
303	int r;
304
305	r = radv_amdgpu_surface_sanity(surf);
306	if (r)
307		return r;
308
309	AddrSurfInfoIn.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT);
310	AddrSurfInfoOut.size = sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT);
311	AddrDccIn.size = sizeof(ADDR_COMPUTE_DCCINFO_INPUT);
312	AddrDccOut.size = sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT);
313	AddrSurfInfoOut.pTileInfo = &AddrTileInfoOut;
314
315	type = RADEON_SURF_GET(surf->flags, TYPE);
316	mode = RADEON_SURF_GET(surf->flags, MODE);
317	compressed = surf->blk_w == 4 && surf->blk_h == 4;
318
319	/* MSAA and FMASK require 2D tiling. */
320	if (surf->nsamples > 1 ||
321	    (surf->flags & RADEON_SURF_FMASK))
322		mode = RADEON_SURF_MODE_2D;
323
324	/* DB doesn't support linear layouts. */
325	if (surf->flags & (RADEON_SURF_Z_OR_SBUFFER) &&
326	    mode < RADEON_SURF_MODE_1D)
327		mode = RADEON_SURF_MODE_1D;
328
329	/* Set the requested tiling mode. */
330	switch (mode) {
331	case RADEON_SURF_MODE_LINEAR_ALIGNED:
332		AddrSurfInfoIn.tileMode = ADDR_TM_LINEAR_ALIGNED;
333		break;
334	case RADEON_SURF_MODE_1D:
335		AddrSurfInfoIn.tileMode = ADDR_TM_1D_TILED_THIN1;
336		break;
337	case RADEON_SURF_MODE_2D:
338		AddrSurfInfoIn.tileMode = ADDR_TM_2D_TILED_THIN1;
339		break;
340	default:
341		assert(0);
342	}
343
344	/* The format must be set correctly for the allocation of compressed
345	 * textures to work. In other cases, setting the bpp is sufficient. */
346	if (compressed) {
347		switch (surf->bpe) {
348		case 8:
349			AddrSurfInfoIn.format = ADDR_FMT_BC1;
350			break;
351		case 16:
352			AddrSurfInfoIn.format = ADDR_FMT_BC3;
353			break;
354		default:
355			assert(0);
356		}
357	} else {
358		AddrDccIn.bpp = AddrSurfInfoIn.bpp = surf->bpe * 8;
359	}
360
361	AddrDccIn.numSamples = AddrSurfInfoIn.numSamples = surf->nsamples;
362	AddrSurfInfoIn.tileIndex = -1;
363
364	/* Set the micro tile type. */
365	if (surf->flags & RADEON_SURF_SCANOUT)
366		AddrSurfInfoIn.tileType = ADDR_DISPLAYABLE;
367	else if (surf->flags & RADEON_SURF_Z_OR_SBUFFER)
368		AddrSurfInfoIn.tileType = ADDR_DEPTH_SAMPLE_ORDER;
369	else
370		AddrSurfInfoIn.tileType = ADDR_NON_DISPLAYABLE;
371
372	AddrSurfInfoIn.flags.color = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER);
373	AddrSurfInfoIn.flags.depth = (surf->flags & RADEON_SURF_ZBUFFER) != 0;
374	AddrSurfInfoIn.flags.cube = type == RADEON_SURF_TYPE_CUBEMAP;
375	AddrSurfInfoIn.flags.display = (surf->flags & RADEON_SURF_SCANOUT) != 0;
376	AddrSurfInfoIn.flags.pow2Pad = surf->last_level > 0;
377	AddrSurfInfoIn.flags.degrade4Space = 1;
378
379	/* DCC notes:
380	 * - If we add MSAA support, keep in mind that CB can't decompress 8bpp
381	 *   with samples >= 4.
382	 * - Mipmapped array textures have low performance (discovered by a closed
383	 *   driver team).
384	 */
385	AddrSurfInfoIn.flags.dccCompatible = !(surf->flags & RADEON_SURF_Z_OR_SBUFFER) &&
386		!(surf->flags & RADEON_SURF_DISABLE_DCC) &&
387		!compressed && AddrDccIn.numSamples <= 1 &&
388		((surf->array_size == 1 && surf->npix_z == 1) ||
389		 surf->last_level == 0);
390
391	AddrSurfInfoIn.flags.noStencil = (surf->flags & RADEON_SURF_SBUFFER) == 0;
392	AddrSurfInfoIn.flags.compressZ = AddrSurfInfoIn.flags.depth;
393
394	/* noStencil = 0 can result in a depth part that is incompatible with
395	 * mipmapped texturing. So set noStencil = 1 when mipmaps are requested (in
396	 * this case, we may end up setting stencil_adjusted).
397	 *
398	 * TODO: update addrlib to a newer version, remove this, and
399	 * use flags.matchStencilTileCfg = 1 as an alternative fix.
400	 */
401	if (surf->last_level > 0)
402		AddrSurfInfoIn.flags.noStencil = 1;
403
404	/* Set preferred macrotile parameters. This is usually required
405	 * for shared resources. This is for 2D tiling only. */
406	if (AddrSurfInfoIn.tileMode >= ADDR_TM_2D_TILED_THIN1 &&
407	    surf->bankw && surf->bankh && surf->mtilea && surf->tile_split) {
408		/* If any of these parameters are incorrect, the calculation
409		 * will fail. */
410		AddrTileInfoIn.banks = surf->num_banks;
411		AddrTileInfoIn.bankWidth = surf->bankw;
412		AddrTileInfoIn.bankHeight = surf->bankh;
413		AddrTileInfoIn.macroAspectRatio = surf->mtilea;
414		AddrTileInfoIn.tileSplitBytes = surf->tile_split;
415		AddrTileInfoIn.pipeConfig = surf->pipe_config + 1; /* +1 compared to GB_TILE_MODE */
416		AddrSurfInfoIn.flags.degrade4Space = 0;
417		AddrSurfInfoIn.pTileInfo = &AddrTileInfoIn;
418
419		/* If AddrSurfInfoIn.pTileInfo is set, Addrlib doesn't set
420		 * the tile index, because we are expected to know it if
421		 * we know the other parameters.
422		 *
423		 * This is something that can easily be fixed in Addrlib.
424		 * For now, just figure it out here.
425		 * Note that only 2D_TILE_THIN1 is handled here.
426		 */
427		assert(!(surf->flags & RADEON_SURF_Z_OR_SBUFFER));
428		assert(AddrSurfInfoIn.tileMode == ADDR_TM_2D_TILED_THIN1);
429
430		if (ws->info.chip_class == SI) {
431			if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE) {
432				if (surf->bpe == 2)
433					AddrSurfInfoIn.tileIndex = 11; /* 16bpp */
434				else
435					AddrSurfInfoIn.tileIndex = 12; /* 32bpp */
436			} else {
437				if (surf->bpe == 1)
438					AddrSurfInfoIn.tileIndex = 14; /* 8bpp */
439				else if (surf->bpe == 2)
440					AddrSurfInfoIn.tileIndex = 15; /* 16bpp */
441				else if (surf->bpe == 4)
442					AddrSurfInfoIn.tileIndex = 16; /* 32bpp */
443				else
444					AddrSurfInfoIn.tileIndex = 17; /* 64bpp (and 128bpp) */
445			}
446		} else {
447			if (AddrSurfInfoIn.tileType == ADDR_DISPLAYABLE)
448				AddrSurfInfoIn.tileIndex = 10; /* 2D displayable */
449			else
450				AddrSurfInfoIn.tileIndex = 14; /* 2D non-displayable */
451			AddrSurfInfoOut.macroModeIndex = cik_get_macro_tile_index(surf);
452		}
453	}
454
455	surf->bo_size = 0;
456	surf->dcc_size = 0;
457	surf->dcc_alignment = 1;
458
459	/* Calculate texture layout information. */
460	for (level = 0; level <= surf->last_level; level++) {
461		r = radv_compute_level(ws->addrlib, surf, false, level, type, compressed,
462				       &AddrSurfInfoIn, &AddrSurfInfoOut, &AddrDccIn, &AddrDccOut);
463		if (r)
464			return r;
465
466		if (level == 0) {
467			surf->bo_alignment = AddrSurfInfoOut.baseAlign;
468			surf->pipe_config = AddrSurfInfoOut.pTileInfo->pipeConfig - 1;
469			radv_set_micro_tile_mode(surf, &ws->info);
470
471			/* For 2D modes only. */
472			if (AddrSurfInfoOut.tileMode >= ADDR_TM_2D_TILED_THIN1) {
473				surf->bankw = AddrSurfInfoOut.pTileInfo->bankWidth;
474				surf->bankh = AddrSurfInfoOut.pTileInfo->bankHeight;
475				surf->mtilea = AddrSurfInfoOut.pTileInfo->macroAspectRatio;
476				surf->tile_split = AddrSurfInfoOut.pTileInfo->tileSplitBytes;
477				surf->num_banks = AddrSurfInfoOut.pTileInfo->banks;
478				surf->macro_tile_index = AddrSurfInfoOut.macroModeIndex;
479			} else {
480				surf->macro_tile_index = 0;
481			}
482		}
483	}
484
485	/* Calculate texture layout information for stencil. */
486	if (surf->flags & RADEON_SURF_SBUFFER) {
487		AddrSurfInfoIn.bpp = 8;
488		AddrSurfInfoIn.flags.depth = 0;
489		AddrSurfInfoIn.flags.stencil = 1;
490		/* This will be ignored if AddrSurfInfoIn.pTileInfo is NULL. */
491		AddrTileInfoIn.tileSplitBytes = surf->stencil_tile_split;
492
493		for (level = 0; level <= surf->last_level; level++) {
494			r = radv_compute_level(ws->addrlib, surf, true, level, type, compressed,
495					       &AddrSurfInfoIn, &AddrSurfInfoOut, &AddrDccIn, &AddrDccOut);
496			if (r)
497				return r;
498
499			/* DB uses the depth pitch for both stencil and depth. */
500			if (surf->stencil_level[level].nblk_x != surf->level[level].nblk_x)
501				surf->stencil_adjusted = true;
502
503			if (level == 0) {
504				/* For 2D modes only. */
505				if (AddrSurfInfoOut.tileMode >= ADDR_TM_2D_TILED_THIN1) {
506					surf->stencil_tile_split =
507						AddrSurfInfoOut.pTileInfo->tileSplitBytes;
508				}
509			}
510		}
511	}
512
513	/* Recalculate the whole DCC miptree size including disabled levels.
514	 * This is what addrlib does, but calling addrlib would be a lot more
515	 * complicated.
516	 */
517#if 0
518	if (surf->dcc_size && surf->last_level > 0) {
519		surf->dcc_size = align64(surf->bo_size >> 8,
520					 ws->info.pipe_interleave_bytes *
521					 ws->info.num_tile_pipes);
522	}
523#endif
524	return 0;
525}
526
527static int radv_amdgpu_winsys_surface_best(struct radeon_winsys *rws,
528					   struct radeon_surf *surf)
529{
530	return 0;
531}
532
533void radv_amdgpu_surface_init_functions(struct radv_amdgpu_winsys *ws)
534{
535	ws->base.surface_init = radv_amdgpu_winsys_surface_init;
536	ws->base.surface_best = radv_amdgpu_winsys_surface_best;
537}
538