1d6c0b56eSmrg/* Copyright © 2014 Advanced Micro Devices, Inc.
2d6c0b56eSmrg *
3d6c0b56eSmrg * Permission is hereby granted, free of charge, to any person
4d6c0b56eSmrg * obtaining a copy of this software and associated documentation
5d6c0b56eSmrg * files (the "Software"), to deal in the Software without
6d6c0b56eSmrg * restriction, including without limitation the rights to use, copy,
7d6c0b56eSmrg * modify, merge, publish, distribute, sublicense, and/or sell copies
8d6c0b56eSmrg * of the Software, and to permit persons to whom the Software is
9d6c0b56eSmrg * furnished to do so, subject to the following conditions:
10d6c0b56eSmrg *
11d6c0b56eSmrg * The above copyright notice and this permission notice (including
12d6c0b56eSmrg * the next paragraph) shall be included in all copies or substantial
13d6c0b56eSmrg * portions of the Software.
14d6c0b56eSmrg *
15d6c0b56eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16d6c0b56eSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17d6c0b56eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18d6c0b56eSmrg * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19d6c0b56eSmrg * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20d6c0b56eSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21d6c0b56eSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22d6c0b56eSmrg * DEALINGS IN THE SOFTWARE.
23d6c0b56eSmrg */
24d6c0b56eSmrg
25d6c0b56eSmrg#ifdef HAVE_CONFIG_H
26d6c0b56eSmrg#include "config.h"
27d6c0b56eSmrg#endif
28d6c0b56eSmrg
29d6c0b56eSmrg#include <xf86.h>
30d6c0b56eSmrg#include "amdgpu_pixmap.h"
31d6c0b56eSmrg#include "amdgpu_bo_helper.h"
32d6c0b56eSmrg
33d6c0b56eSmrgstatic PixmapPtr
34d6c0b56eSmrgamdgpu_pixmap_create(ScreenPtr screen, int w, int h, int depth,	unsigned usage)
35d6c0b56eSmrg{
36d6c0b56eSmrg	ScrnInfoPtr scrn;
37d6c0b56eSmrg	struct amdgpu_pixmap *priv;
38d6c0b56eSmrg	PixmapPtr pixmap;
39d6c0b56eSmrg	AMDGPUInfoPtr info;
40d6c0b56eSmrg
41e49c54bcSmrg	/* only DRI2 pixmap is supported */
42d6c0b56eSmrg	if (!(usage & AMDGPU_CREATE_PIXMAP_DRI2))
43d6c0b56eSmrg		return fbCreatePixmap(screen, w, h, depth, usage);
44d6c0b56eSmrg
45d6c0b56eSmrg	if (w > 32767 || h > 32767)
46d6c0b56eSmrg		return NullPixmap;
47d6c0b56eSmrg
48d6c0b56eSmrg	if (depth == 1)
49d6c0b56eSmrg		return fbCreatePixmap(screen, w, h, depth, usage);
50d6c0b56eSmrg
51d6c0b56eSmrg	pixmap = fbCreatePixmap(screen, 0, 0, depth, usage);
52d6c0b56eSmrg	if (pixmap == NullPixmap)
53d6c0b56eSmrg		return pixmap;
54d6c0b56eSmrg
55d6c0b56eSmrg	if (w && h) {
56d6c0b56eSmrg		int stride;
57d6c0b56eSmrg
58d6c0b56eSmrg		priv = calloc(1, sizeof(struct amdgpu_pixmap));
5935d5b7c7Smrg		if (!priv)
60d6c0b56eSmrg			goto fallback_pixmap;
61d6c0b56eSmrg
62d6c0b56eSmrg		scrn = xf86ScreenToScrn(screen);
63d6c0b56eSmrg		info = AMDGPUPTR(scrn);
64d6c0b56eSmrg		if (!info->use_glamor)
65d6c0b56eSmrg			usage |= AMDGPU_CREATE_PIXMAP_LINEAR;
66d6c0b56eSmrg		priv->bo = amdgpu_alloc_pixmap_bo(scrn, w, h, depth, usage,
67d6c0b56eSmrg						  pixmap->drawable.bitsPerPixel,
68d6c0b56eSmrg						  &stride);
69d6c0b56eSmrg		if (!priv->bo)
70d6c0b56eSmrg			goto fallback_priv;
71d6c0b56eSmrg
72d6c0b56eSmrg		amdgpu_set_pixmap_private(pixmap, priv);
73d6c0b56eSmrg
74d6c0b56eSmrg		if (amdgpu_bo_map(scrn, priv->bo)) {
75d6c0b56eSmrg			ErrorF("Failed to mmap the bo\n");
76d6c0b56eSmrg			goto fallback_bo;
77d6c0b56eSmrg		}
78d6c0b56eSmrg
79d6c0b56eSmrg		screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride,
80d6c0b56eSmrg					   priv->bo->cpu_ptr);
81d6c0b56eSmrg	}
82d6c0b56eSmrg
83d6c0b56eSmrg	return pixmap;
84d6c0b56eSmrg
85d6c0b56eSmrgfallback_bo:
86d6c0b56eSmrg	amdgpu_bo_unref(&priv->bo);
87d6c0b56eSmrgfallback_priv:
88d6c0b56eSmrg	free(priv);
89d6c0b56eSmrgfallback_pixmap:
90d6c0b56eSmrg	fbDestroyPixmap(pixmap);
91d6c0b56eSmrg	return fbCreatePixmap(screen, w, h, depth, usage);
92d6c0b56eSmrg}
93d6c0b56eSmrg
94d6c0b56eSmrgstatic Bool amdgpu_pixmap_destroy(PixmapPtr pixmap)
95d6c0b56eSmrg{
96d6c0b56eSmrg	if (pixmap->refcnt == 1) {
97d6c0b56eSmrg		amdgpu_set_pixmap_bo(pixmap, NULL);
98d6c0b56eSmrg	}
99d6c0b56eSmrg	fbDestroyPixmap(pixmap);
100d6c0b56eSmrg	return TRUE;
101d6c0b56eSmrg}
102d6c0b56eSmrg
103d6c0b56eSmrg/* This should only be called when glamor is disabled */
104d6c0b56eSmrgBool amdgpu_pixmap_init(ScreenPtr screen)
105d6c0b56eSmrg{
106d6c0b56eSmrg	if (!dixRegisterPrivateKey(&amdgpu_pixmap_index, PRIVATE_PIXMAP, 0))
107d6c0b56eSmrg		return FALSE;
108d6c0b56eSmrg
109d6c0b56eSmrg	screen->CreatePixmap = amdgpu_pixmap_create;
110d6c0b56eSmrg	screen->DestroyPixmap = amdgpu_pixmap_destroy;
111d6c0b56eSmrg	return TRUE;
112d6c0b56eSmrg}
113