1b7e1c893Smrg
2b7e1c893Smrg#ifdef HAVE_CONFIG_H
3b7e1c893Smrg#include "config.h"
4b7e1c893Smrg#endif
5b7e1c893Smrg
6b7e1c893Smrg/* Driver data structures */
7b7e1c893Smrg#include "radeon.h"
8b7e1c893Smrg
9b7e1c893Smrg/* Allocates memory, either by resizing the allocation pointed to by mem_struct,
10b7e1c893Smrg * or by freeing mem_struct (if non-NULL) and allocating a new space.  The size
11b7e1c893Smrg * is measured in bytes, and the offset from the beginning of card space is
12b7e1c893Smrg * returned.
13b7e1c893Smrg */
14b7e1c893Smrguint32_t
15b7e1c893Smrgradeon_legacy_allocate_memory(ScrnInfoPtr pScrn,
16b7e1c893Smrg		       void **mem_struct,
17b7e1c893Smrg		       int size,
18ad43ddacSmrg		       int align,
19ad43ddacSmrg		       int domain)
20b7e1c893Smrg{
2168105dcbSveego    ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
22b7e1c893Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
23b7e1c893Smrg    uint32_t offset = 0;
24b7e1c893Smrg
25ad43ddacSmrg#ifdef XF86DRM_MODE
26ad43ddacSmrg    if (info->cs) {
27ad43ddacSmrg	struct radeon_bo *video_bo;
28ad43ddacSmrg
29921a55d8Smrg	if (*mem_struct)
30921a55d8Smrg		radeon_legacy_free_memory(pScrn, *mem_struct);
31921a55d8Smrg
32b13dfe66Smrg	video_bo = radeon_bo_open(info->bufmgr, 0, size, align, domain, 0);
33ad43ddacSmrg
34ad43ddacSmrg	*mem_struct = video_bo;
35ad43ddacSmrg
36ad43ddacSmrg	if (!video_bo)
37ad43ddacSmrg	    return 0;
38ad43ddacSmrg
39ad43ddacSmrg	return (uint32_t)-1;
40ad43ddacSmrg    }
41ad43ddacSmrg#endif
42b7e1c893Smrg#ifdef USE_EXA
43b7e1c893Smrg    if (info->useEXA) {
44b7e1c893Smrg	ExaOffscreenArea *area = *mem_struct;
45b7e1c893Smrg
46b7e1c893Smrg	if (area != NULL) {
47b7e1c893Smrg	    if (area->size >= size)
48b7e1c893Smrg		return area->offset;
49b7e1c893Smrg
50b7e1c893Smrg	    exaOffscreenFree(pScreen, area);
51b7e1c893Smrg	}
52b7e1c893Smrg
53b7e1c893Smrg	area = exaOffscreenAlloc(pScreen, size, align, TRUE,
54b7e1c893Smrg				 NULL, NULL);
55b7e1c893Smrg
56b7e1c893Smrg	*mem_struct = area;
57b7e1c893Smrg	if (area == NULL)
58b7e1c893Smrg	    return 0;
59b7e1c893Smrg	offset = area->offset;
60b7e1c893Smrg    }
61b7e1c893Smrg#endif /* USE_EXA */
62b7e1c893Smrg#ifdef USE_XAA
63b7e1c893Smrg    if (!info->useEXA) {
64b7e1c893Smrg	FBLinearPtr linear = *mem_struct;
65b7e1c893Smrg	int cpp = info->CurrentLayout.bitsPerPixel / 8;
66b7e1c893Smrg
67b7e1c893Smrg	/* XAA allocates in units of pixels at the screen bpp, so adjust size
68b7e1c893Smrg	 * appropriately.
69b7e1c893Smrg	 */
70b7e1c893Smrg	size = (size + cpp - 1) / cpp;
71b7e1c893Smrg	align = (align + cpp - 1) / cpp;
72b7e1c893Smrg
73b7e1c893Smrg	if (linear) {
74b7e1c893Smrg	    if(linear->size >= size)
75b7e1c893Smrg		return linear->offset * cpp;
76b7e1c893Smrg
77b7e1c893Smrg	    if(xf86ResizeOffscreenLinear(linear, size))
78b7e1c893Smrg		return linear->offset * cpp;
79b7e1c893Smrg
80b7e1c893Smrg	    xf86FreeOffscreenLinear(linear);
81b7e1c893Smrg	}
82b7e1c893Smrg
83b7e1c893Smrg	linear = xf86AllocateOffscreenLinear(pScreen, size, align,
84b7e1c893Smrg					     NULL, NULL, NULL);
85b7e1c893Smrg	*mem_struct = linear;
86b7e1c893Smrg
87b7e1c893Smrg	if (!linear) {
88b7e1c893Smrg	    int max_size;
89b7e1c893Smrg
90b7e1c893Smrg	    xf86QueryLargestOffscreenLinear(pScreen, &max_size, align,
91b7e1c893Smrg					    PRIORITY_EXTREME);
92b7e1c893Smrg
93b7e1c893Smrg	    if (max_size < size)
94b7e1c893Smrg		return 0;
95b7e1c893Smrg
96b7e1c893Smrg	    xf86PurgeUnlockedOffscreenAreas(pScreen);
97b7e1c893Smrg	    linear = xf86AllocateOffscreenLinear(pScreen, size, align,
98b7e1c893Smrg						 NULL, NULL, NULL);
99b7e1c893Smrg	    *mem_struct = linear;
100b7e1c893Smrg	    if (!linear)
101b7e1c893Smrg		return 0;
102b7e1c893Smrg	}
103b7e1c893Smrg	offset = linear->offset * cpp;
104b7e1c893Smrg    }
105b7e1c893Smrg#endif /* USE_XAA */
106b7e1c893Smrg
107b7e1c893Smrg    return offset;
108b7e1c893Smrg}
109b7e1c893Smrg
110b7e1c893Smrgvoid
111b7e1c893Smrgradeon_legacy_free_memory(ScrnInfoPtr pScrn,
112b7e1c893Smrg		   void *mem_struct)
113b7e1c893Smrg{
114b7e1c893Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
115ad43ddacSmrg
116ad43ddacSmrg#ifdef XF86DRM_MODE
117ad43ddacSmrg    if (info->cs) {
118ad43ddacSmrg        struct radeon_bo *bo = mem_struct;
119ad43ddacSmrg	radeon_bo_unref(bo);
120ad43ddacSmrg	return;
121ad43ddacSmrg    }
122ad43ddacSmrg#endif
123b7e1c893Smrg#ifdef USE_EXA
12468105dcbSveego    ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
125b7e1c893Smrg
126b7e1c893Smrg    if (info->useEXA) {
127b7e1c893Smrg	ExaOffscreenArea *area = mem_struct;
128b7e1c893Smrg
129b7e1c893Smrg	if (area != NULL)
130b7e1c893Smrg	    exaOffscreenFree(pScreen, area);
131b7e1c893Smrg	area = NULL;
132b7e1c893Smrg    }
133b7e1c893Smrg#endif /* USE_EXA */
134b7e1c893Smrg#ifdef USE_XAA
135b7e1c893Smrg    if (!info->useEXA) {
136b7e1c893Smrg	FBLinearPtr linear = mem_struct;
137b7e1c893Smrg
138b7e1c893Smrg	if (linear != NULL)
139b7e1c893Smrg	    xf86FreeOffscreenLinear(linear);
140b7e1c893Smrg	linear = NULL;
141b7e1c893Smrg    }
142b7e1c893Smrg#endif /* USE_XAA */
143b7e1c893Smrg}
144