1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2009 Corbin Simpson
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright © 2011 Marek Olšák <maraeo@gmail.com>
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * USE OR OTHER DEALINGS IN THE SOFTWARE.
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors:
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *      Corbin Simpson <MostAwesomeDude@gmail.com>
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *      Joakim Sindholt <opensource@zhasha.com>
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *      Marek Olšák <maraeo@gmail.com>
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_drm_bo.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_drm_cs.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_drm_public.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipebuffer/pb_bufmgr.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <xf86drm.h>
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdio.h>
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/*
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * this are copy from radeon_drm, once an updated libdrm is released
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * we should bump configure.ac requirement for it and remove the following
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * field
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef RADEON_INFO_TILING_CONFIG
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define RADEON_INFO_TILING_CONFIG 6
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef RADEON_INFO_WANT_HYPERZ
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define RADEON_INFO_WANT_HYPERZ 7
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef RADEON_INFO_WANT_CMASK
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define RADEON_INFO_WANT_CMASK 8
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef RADEON_INFO_CLOCK_CRYSTAL_FREQ
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define RADEON_INFO_CLOCK_CRYSTAL_FREQ 9
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef RADEON_INFO_NUM_BACKENDS
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define RADEON_INFO_NUM_BACKENDS 0xa
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef RADEON_INFO_NUM_TILE_PIPES
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define RADEON_INFO_NUM_TILE_PIPES 0xb
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef RADEON_INFO_BACKEND_MAP
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define RADEON_INFO_BACKEND_MAP 0xd
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef RADEON_INFO_VA_START
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* virtual address start, va < start are reserved by the kernel */
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define RADEON_INFO_VA_START        0x0e
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* maximum size of ib using the virtual memory cs */
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define RADEON_INFO_IB_VM_MAX_SIZE  0x0f
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef RADEON_INFO_MAX_PIPES
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define RADEON_INFO_MAX_PIPES 0x10
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef RADEON_INFO_TIMESTAMP
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define RADEON_INFO_TIMESTAMP 0x11
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Enable/disable feature access for one command stream.
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If enable == TRUE, return TRUE on success.
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Otherwise, return FALSE.
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We basically do the same thing kernel does, because we have to deal
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * with multiple contexts (here command streams) backed by one winsys. */
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean radeon_set_fd_access(struct radeon_drm_cs *applier,
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    struct radeon_drm_cs **owner,
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    pipe_mutex *mutex,
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    unsigned request, boolean enable)
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct drm_radeon_info info;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    unsigned value = enable ? 1 : 0;
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    memset(&info, 0, sizeof(info));
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    pipe_mutex_lock(*mutex);
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Early exit if we are sure the request will fail. */
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (enable) {
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (*owner) {
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            pipe_mutex_unlock(*mutex);
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (*owner != applier) {
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            pipe_mutex_unlock(*mutex);
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Pass through the request to the kernel. */
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    info.value = (unsigned long)&value;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    info.request = request;
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (drmCommandWriteRead(applier->ws->fd, DRM_RADEON_INFO,
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            &info, sizeof(info)) != 0) {
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        pipe_mutex_unlock(*mutex);
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return FALSE;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Update the rights in the winsys. */
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (enable) {
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (value) {
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            *owner = applier;
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fprintf(stderr, "radeon: Acquired Hyper-Z.\n");
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            pipe_mutex_unlock(*mutex);
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return TRUE;
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    } else {
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        *owner = NULL;
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        fprintf(stderr, "radeon: Released Hyper-Z.\n");
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    pipe_mutex_unlock(*mutex);
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return FALSE;
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean radeon_get_drm_value(int fd, unsigned request,
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    const char *errname, uint32_t *out)
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct drm_radeon_info info;
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int retval;
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    memset(&info, 0, sizeof(info));
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    info.value = (unsigned long)out;
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    info.request = request;
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (retval) {
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (errname) {
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            fprintf(stderr, "radeon: Failed to get %s, error number %d\n",
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                    errname, retval);
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return FALSE;
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return TRUE;
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Helper function to do the ioctls needed for setup and init. */
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean do_winsys_init(struct radeon_drm_winsys *ws)
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct drm_radeon_gem_info gem_info;
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int retval;
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    drmVersionPtr version;
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    memset(&gem_info, 0, sizeof(gem_info));
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* We do things in a specific order here.
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     *
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * DRM version first. We need to be sure we're running on a KMS chipset.
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * This is also for some features.
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     *
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * Then, the PCI ID. This is essential and should return usable numbers
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * for all Radeons. If this fails, we probably got handed an FD for some
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * non-Radeon card.
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     *
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * The GEM info is actually bogus on the kernel side, as well as our side
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * (see radeon_gem_info_ioctl in radeon_gem.c) but that's alright because
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * we don't actually use the info for anything yet.
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     *
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * The GB and Z pipe requests should always succeed, but they might not
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * return sensical values for all chipsets, but that's alright because
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * the pipe drivers already know that.
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     */
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Get DRM version. */
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    version = drmGetVersion(ws->fd);
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (version->version_major != 2 ||
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        version->version_minor < 3) {
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        fprintf(stderr, "%s: DRM version is %d.%d.%d but this driver is "
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                "only compatible with 2.3.x (kernel 2.6.34) or later.\n",
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                __FUNCTION__,
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                version->version_major,
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                version->version_minor,
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                version->version_patchlevel);
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        drmFreeVersion(version);
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return FALSE;
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->info.drm_major = version->version_major;
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->info.drm_minor = version->version_minor;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->info.drm_patchlevel = version->version_patchlevel;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    drmFreeVersion(version);
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Get PCI ID. */
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!radeon_get_drm_value(ws->fd, RADEON_INFO_DEVICE_ID, "PCI ID",
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              &ws->info.pci_id))
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return FALSE;
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Check PCI ID. */
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch (ws->info.pci_id) {
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define CHIPSET(pci_id, name, family) case pci_id:
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pci_ids/r300_pci_ids.h"
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#undef CHIPSET
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ws->gen = R300;
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        break;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define CHIPSET(pci_id, name, family) case pci_id:
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pci_ids/r600_pci_ids.h"
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#undef CHIPSET
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ws->gen = R600;
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        break;
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define CHIPSET(pci_id, name, family) case pci_id:
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pci_ids/radeonsi_pci_ids.h"
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#undef CHIPSET
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ws->gen = SI;
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        break;
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    default:
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        fprintf(stderr, "radeon: Invalid PCI ID.\n");
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return FALSE;
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Get GEM info. */
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    retval = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_INFO,
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            &gem_info, sizeof(gem_info));
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (retval) {
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        fprintf(stderr, "radeon: Failed to get MM info, error number %d\n",
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                retval);
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return FALSE;
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->info.gart_size = gem_info.gart_size;
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->info.vram_size = gem_info.vram_size;
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Generation-specific queries. */
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ws->gen == R300) {
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_GB_PIPES,
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  "GB pipe count",
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &ws->info.r300_num_gb_pipes))
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (!radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_Z_PIPES,
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  "Z pipe count",
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &ws->info.r300_num_z_pipes))
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    else if (ws->gen >= R600) {
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (ws->info.drm_minor >= 9 &&
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            !radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_BACKENDS,
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  "num backends",
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                  &ws->info.r600_num_backends))
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        /* get the GPU counter frequency, failure is not fatal */
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        radeon_get_drm_value(ws->fd, RADEON_INFO_CLOCK_CRYSTAL_FREQ, NULL,
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             &ws->info.r600_clock_crystal_freq);
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        radeon_get_drm_value(ws->fd, RADEON_INFO_TILING_CONFIG, NULL,
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                             &ws->info.r600_tiling_config);
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (ws->info.drm_minor >= 11) {
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            radeon_get_drm_value(ws->fd, RADEON_INFO_NUM_TILE_PIPES, NULL,
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                 &ws->info.r600_num_tile_pipes);
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (radeon_get_drm_value(ws->fd, RADEON_INFO_BACKEND_MAP, NULL,
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      &ws->info.r600_backend_map))
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                ws->info.r600_backend_map_valid = TRUE;
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ws->info.r600_virtual_address = FALSE;
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (ws->info.drm_minor >= 13) {
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ws->info.r600_virtual_address = TRUE;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (!radeon_get_drm_value(ws->fd, RADEON_INFO_VA_START, NULL,
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      &ws->info.r600_va_start))
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                ws->info.r600_virtual_address = FALSE;
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (!radeon_get_drm_value(ws->fd, RADEON_INFO_IB_VM_MAX_SIZE, NULL,
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                      &ws->info.r600_ib_vm_max_size))
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                ws->info.r600_virtual_address = FALSE;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        /* Remove this line once the virtual address space feature is fixed. */
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (ws->gen == R600 && !debug_get_bool_option("RADEON_VA", FALSE))
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            ws->info.r600_virtual_address = FALSE;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Get max pipes, this is only needed for compute shaders.  All evergreen+
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org     * chips have at least 2 pipes, so we use 2 as a default. */
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->info.r600_max_pipes = 2;
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_PIPES, NULL,
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         &ws->info.r600_max_pipes);
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return TRUE;
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void radeon_winsys_destroy(struct radeon_winsys *rws)
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    pipe_mutex_destroy(ws->hyperz_owner_mutex);
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    pipe_mutex_destroy(ws->cmask_owner_mutex);
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->cman->destroy(ws->cman);
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->kman->destroy(ws->kman);
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ws->gen >= R600) {
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        radeon_surface_manager_free(ws->surf_man);
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    FREE(rws);
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void radeon_query_info(struct radeon_winsys *rws,
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              struct radeon_info *info)
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    *info = ((struct radeon_drm_winsys *)rws)->info;
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean radeon_cs_request_feature(struct radeon_winsys_cs *rcs,
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         enum radeon_feature_id fid,
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                         boolean enable)
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    switch (fid) {
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case RADEON_FID_R300_HYPERZ_ACCESS:
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (debug_get_bool_option("RADEON_HYPERZ", FALSE)) {
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return radeon_set_fd_access(cs, &cs->ws->hyperz_owner,
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        &cs->ws->hyperz_owner_mutex,
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        RADEON_INFO_WANT_HYPERZ, enable);
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        } else {
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    case RADEON_FID_R300_CMASK_ACCESS:
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (debug_get_bool_option("RADEON_CMASK", FALSE)) {
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return radeon_set_fd_access(cs, &cs->ws->cmask_owner,
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        &cs->ws->cmask_owner_mutex,
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                        RADEON_INFO_WANT_CMASK, enable);
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        } else {
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            return FALSE;
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        }
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return FALSE;
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int radeon_drm_winsys_surface_init(struct radeon_winsys *rws,
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          struct radeon_surface *surf)
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return radeon_surface_init(ws->surf_man, surf);
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int radeon_drm_winsys_surface_best(struct radeon_winsys *rws,
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                          struct radeon_surface *surf)
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return radeon_surface_best(ws->surf_man, surf);
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic uint64_t radeon_query_timestamp(struct radeon_winsys *rws)
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct radeon_drm_winsys *ws = (struct radeon_drm_winsys*)rws;
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    uint64_t ts = 0;
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ws->info.drm_minor < 20 ||
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ws->gen < R600) {
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        assert(0);
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return 0;
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    radeon_get_drm_value(ws->fd, RADEON_INFO_TIMESTAMP, "timestamp",
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         (uint32_t*)&ts);
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return ts;
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct radeon_winsys *radeon_drm_winsys_create(int fd)
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct radeon_drm_winsys *ws = CALLOC_STRUCT(radeon_drm_winsys);
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!ws) {
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        return NULL;
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->fd = fd;
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!do_winsys_init(ws))
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        goto fail;
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Create managers. */
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->kman = radeon_bomgr_create(ws);
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!ws->kman)
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        goto fail;
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->cman = pb_cache_manager_create(ws->kman, 1000000);
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (!ws->cman)
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        goto fail;
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ws->gen >= R600) {
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ws->surf_man = radeon_surface_manager_new(fd);
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        if (!ws->surf_man)
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            goto fail;
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    /* Set functions. */
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->base.destroy = radeon_winsys_destroy;
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->base.query_info = radeon_query_info;
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->base.cs_request_feature = radeon_cs_request_feature;
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->base.surface_init = radeon_drm_winsys_surface_init;
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->base.surface_best = radeon_drm_winsys_surface_best;
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    ws->base.query_timestamp = radeon_query_timestamp;
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    radeon_bomgr_init_functions(ws);
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    radeon_drm_cs_init_functions(ws);
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    pipe_mutex_init(ws->hyperz_owner_mutex);
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    pipe_mutex_init(ws->cmask_owner_mutex);
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return &ws->base;
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfail:
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ws->cman)
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ws->cman->destroy(ws->cman);
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ws->kman)
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        ws->kman->destroy(ws->kman);
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    if (ws->surf_man)
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org        radeon_surface_manager_free(ws->surf_man);
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    FREE(ws);
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    return NULL;
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
453