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 "util/bitset.h"
33#include "radv_amdgpu_winsys.h"
34#include "radv_amdgpu_surface.h"
35#include "sid.h"
36
37#include "ac_surface.h"
38
39static int radv_amdgpu_surface_sanity(const struct ac_surf_info *surf_info,
40				      const struct radeon_surf *surf)
41{
42	unsigned type = RADEON_SURF_GET(surf->flags, TYPE);
43
44	if (!surf->blk_w || !surf->blk_h)
45		return -EINVAL;
46
47	switch (type) {
48	case RADEON_SURF_TYPE_1D:
49		if (surf_info->height > 1)
50			return -EINVAL;
51		/* fall through */
52	case RADEON_SURF_TYPE_2D:
53	case RADEON_SURF_TYPE_CUBEMAP:
54		if (surf_info->depth > 1 || surf_info->array_size > 1)
55			return -EINVAL;
56		break;
57	case RADEON_SURF_TYPE_3D:
58		if (surf_info->array_size > 1)
59			return -EINVAL;
60		break;
61	case RADEON_SURF_TYPE_1D_ARRAY:
62		if (surf_info->height > 1)
63			return -EINVAL;
64		/* fall through */
65	case RADEON_SURF_TYPE_2D_ARRAY:
66		if (surf_info->depth > 1)
67			return -EINVAL;
68		break;
69	default:
70		return -EINVAL;
71	}
72	return 0;
73}
74
75static int radv_amdgpu_winsys_surface_init(struct radeon_winsys *_ws,
76					   const struct ac_surf_info *surf_info,
77					   struct radeon_surf *surf)
78{
79	struct radv_amdgpu_winsys *ws = radv_amdgpu_winsys(_ws);
80	unsigned mode, type;
81	int r;
82
83	r = radv_amdgpu_surface_sanity(surf_info, surf);
84	if (r)
85		return r;
86
87	type = RADEON_SURF_GET(surf->flags, TYPE);
88	mode = RADEON_SURF_GET(surf->flags, MODE);
89
90	struct ac_surf_config config;
91
92	memcpy(&config.info, surf_info, sizeof(config.info));
93	config.is_3d = !!(type == RADEON_SURF_TYPE_3D);
94	config.is_cube = !!(type == RADEON_SURF_TYPE_CUBEMAP);
95
96	return ac_compute_surface(ws->addrlib, &ws->info, &config, mode, surf);
97}
98
99void radv_amdgpu_surface_init_functions(struct radv_amdgpu_winsys *ws)
100{
101	ws->base.surface_init = radv_amdgpu_winsys_surface_init;
102}
103