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