wip prep commit in lieu of gfx subsystem update changes.
[AROS.git] / workbench / hidds / radeon / bitmap.c
blob788c713febc1b6a9d852c602726ad4904361a5f1
1 /*
2 Copyright © 2003-2017, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 0
7 #include "bitmap.h"
8 #include <exec/types.h>
9 #include <proto/exec.h>
10 #include <aros/debug.h>
11 #include <exec/memory.h>
12 #include <exec/memheaderext.h>
14 LONG bfffo(ULONG val, UBYTE bitoffset)
16 val &= (0xffffffff >> bitoffset);
17 if (val)
18 return __builtin_clz(val);
19 else
20 return 32;
23 LONG bfflo(ULONG val, UBYTE bitoffset)
25 val &= (0xffffffff << (31-bitoffset));
26 if (val)
27 return 31-__builtin_ctz(val);
28 else
29 return -1;
32 LONG bfffz(ULONG val, UBYTE bitoffset)
34 return bfffo(~val, bitoffset);
37 LONG bfflz(ULONG val, UBYTE bitoffset)
39 return bfflo(~val, bitoffset);
42 ULONG bfset(ULONG data, UBYTE bitoffset, UBYTE bits)
44 ULONG mask = ~((1 << (32 - bits)) - 1);
45 mask >>= bitoffset;
46 return data | mask;
49 ULONG bfclr(ULONG data, UBYTE bitoffset, UBYTE bits)
51 ULONG mask = ~((1 << (32 - bits)) - 1);
52 mask >>= bitoffset;
53 return data & ~mask;
56 ULONG bfcnto(ULONG v)
58 ULONG const w = v - ((v >> 1) & 0x55555555); // temp
59 ULONG const x = (w & 0x33333333) + ((w >> 2) & 0x33333333); // temp
60 ULONG const c = ((x + ((x >> 4) & 0xF0F0F0F)) * 0x1010101) >> 24; // count
62 return c;
65 ULONG bfcntz(ULONG v)
67 return bfcnto(~v);
70 LONG bmffo(ULONG *bitmap, ULONG longs, LONG bitoffset)
72 ULONG *scan = bitmap;
73 ULONG err = 32*longs;
74 int longoffset, bit;
76 longoffset = bitoffset >> 5;
77 longs -= longoffset;
78 scan += longoffset;
80 bitoffset = bitoffset & 0x1F;
82 if (bitoffset != 0) {
83 if ((bit = bfffo(*scan, bitoffset)) < 32) {
84 return (bit + ((scan - bitmap) << 5));
86 scan++;
87 longs--;
90 while (longs-- > 0) {
91 if (*scan++ != 0) {
92 scan--;
93 return (bfffo(*scan,0) + ((scan - bitmap) << 5));
97 return (err);
100 LONG bmffz(ULONG *bitmap, ULONG longs, LONG bitoffset)
102 ULONG *scan = bitmap;
103 ULONG err = 32*longs;
104 int longoffset, bit;
106 longoffset = bitoffset >> 5;
107 longs -= longoffset;
108 scan += longoffset;
110 bitoffset = bitoffset & 0x1F;
112 if (bitoffset != 0) {
113 if ((bit = bfffz(*scan, bitoffset)) < 32) {
114 return (bit + ((scan - bitmap) << 5));
116 scan++;
117 longs--;
120 while (longs-- > 0) {
121 if (*scan++ != 0xFFFFFFFF) {
122 scan--;
123 return (bfffz(*scan,0) + ((scan - bitmap) << 5));
127 return (err);
130 LONG bmclr(ULONG *bitmap, ULONG longs, LONG bitoffset, LONG bits)
132 ULONG *scan = bitmap;
133 int longoffset;
134 int orgbits = bits;
136 longoffset = bitoffset >> 5;
137 longs -= longoffset;
138 scan += longoffset;
140 bitoffset = bitoffset & 0x1F;
142 if (bitoffset != 0) {
143 if (bits < 32) {
144 *scan = bfclr(*scan, bitoffset, bits);
145 } else {
146 *scan = bfclr(*scan, bitoffset, 32);
148 scan++;
149 longs--;
150 bits -= 32 - bitoffset;
153 while (bits > 0 && longs-- > 0) {
154 if (bits > 31) {
155 *scan++ = 0;
156 } else {
157 *scan = bfclr(*scan, 0, bits);
159 bits -= 32;
162 if (bits <= 0) {
163 return (orgbits);
165 return (orgbits - bits);
168 LONG bmset(ULONG *bitmap, ULONG longs, LONG bitoffset, LONG bits)
170 ULONG *scan = bitmap;
171 int longoffset;
172 int orgbits = bits;
174 longoffset = bitoffset >> 5;
175 longs -= longoffset;
176 scan += longoffset;
178 bitoffset = bitoffset & 0x1F;
180 if (bitoffset != 0) {
181 if (bits < 32) {
182 *scan = (bfset((*scan), bitoffset, bits));
183 } else {
184 *scan = (bfset((*scan), bitoffset, 32));
186 scan++;
187 longs--;
188 bits -= 32 - bitoffset;
191 while (bits > 0 && longs-- > 0) {
192 if (bits > 31) {
193 *scan++ = 0xFFFFFFFF;
194 } else {
195 *scan = (bfset((*scan), 0, bits));
197 bits -= 32;
200 if (bits <= 0) {
201 return (orgbits);
203 return (orgbits - bits);
206 int bmtstz(ULONG *bitmap, ULONG bitoffset, LONG bits)
208 LONG longoffset = bitoffset >> 5;
209 ULONG *scan = bitmap;
210 ULONG mask;
212 scan += longoffset;
213 bitoffset &= 0x1f;
215 if (bitoffset != 0)
217 if ((bits + bitoffset) < 32)
219 mask = (0xffffffff >> bitoffset) & (0xffffffff << (32 - (bits+bitoffset)));
220 bits=0;
222 else
224 mask = (0xffffffff >> bitoffset);
225 bits -= (32-bitoffset);
227 if ((mask & (*scan++)) != 0)
228 return 0;
231 while (bits > 0)
233 if (bits >= 32)
235 mask=0xffffffff;
236 bits -= 32;
238 else
240 mask = 0xffffffff << (32-bits);
241 bits = 0;
243 if ((mask & (*scan++)) != 0)
244 return 0;
247 return 1;
250 ULONG bmcnto(ULONG *bitmap, LONG bitoffset, LONG bits)
252 LONG longoffset = bitoffset >> 5;
253 ULONG *scan = bitmap;
254 ULONG count = 0;
255 ULONG mask;
257 scan += longoffset;
258 bitoffset &= 0x1f;
260 if (bitoffset != 0)
262 if ((bits + bitoffset) < 32)
264 mask = (0xffffffff >> bitoffset) & (0xffffffff << (32 - (bits+bitoffset)));
265 bits=0;
267 else
269 mask = (0xffffffff >> bitoffset);
270 bits -= (32-bitoffset);
272 count += bfcnto(*scan++ & mask);
275 while (bits > 0)
277 if (bits >= 32)
279 mask=0xffffffff;
280 bits -= 32;
282 else
284 mask = 0xffffffff << (32-bits);
285 bits = 0;
287 count += bfcnto(*scan++ & mask);
290 return count;
293 ULONG bmcntz(ULONG *bitmap, LONG bitoffset, LONG bits)
295 LONG longoffset = bitoffset >> 5;
296 ULONG *scan = bitmap;
297 ULONG count = 0;
298 ULONG mask;
300 scan += longoffset;
301 bitoffset &= 0x1f;
303 if (bitoffset != 0)
305 if ((bits + bitoffset) < 32)
307 mask = ~((0xffffffff >> bitoffset) & (0xffffffff << (32 - (bits+bitoffset))));
308 bits=0;
310 else
312 mask = ~(0xffffffff >> bitoffset);
313 bits -= (32-bitoffset);
316 count += bfcntz(*scan++ | mask);
319 while (bits > 0)
321 if (bits >= 32)
323 mask=0;
324 bits -= 32;
326 else
328 mask = ~(0xffffffff << (32-bits));
329 bits = 0;
332 count += bfcntz(*scan++ | mask);
335 return count;
338 void *mh_Alloc(struct MemHeaderExt *mhe, IPTR size, ULONG *flags)
340 return NULL;
343 void mh_Free(struct MemHeaderExt *mhe, APTR mem, IPTR size)
347 void *mh_AllocAbs(struct MemHeaderExt *mhe, IPTR size, APTR mem)
349 return NULL;
352 void *mh_ReAlloc(struct MemHeaderExt *mhe, APTR old, IPTR size)
354 return NULL;
357 IPTR mh_Avail(struct MemHeaderExt *mhe, ULONG flags)
359 struct ati_staticdata *sd = (APTR)mhe->mhe_UserData;
360 IPTR size = 0;
362 // Forbid();
364 ObtainSemaphore(&sd->CardMemLock);
366 if (flags & MEMF_TOTAL)
367 size = sd->Card.FbUsableSize;
368 else if (flags & MEMF_LARGEST)
370 ULONG ptr;
372 ptr = bmffz(sd->CardMemBmp, sd->CardMemSize, 0);
374 while (ptr < (sd->CardMemSize << 5))
376 ULONG tmpptr = bmffo(sd->CardMemBmp, sd->CardMemSize, ptr);
378 if ((tmpptr - ptr) > size)
379 size = tmpptr - ptr;
381 ptr = bmffz(sd->CardMemBmp, sd->CardMemSize, tmpptr);
384 size <<= 10;
386 else
387 size = bmcntz(sd->CardMemBmp, 0, sd->Card.FbUsableSize >> 10) << 10;
389 // Permit();
391 ReleaseSemaphore(&sd->CardMemLock);
393 return size;
396 void BitmapInit(struct ati_staticdata *sd)
399 * If Radeon chip has some video memory, create a bitmap representing all allocations.
400 * Divide whole memory into 1KB chunks
402 if (sd->Card.FbUsableSize)
404 sd->CardMemBmp = AllocPooled(sd->memPool, sd->Card.FbUsableSize >> 13);
406 sd->managedMem.mhe_MemHeader.mh_Node.ln_Type = NT_MEMORY;
407 sd->managedMem.mhe_MemHeader.mh_Node.ln_Name = "Radeon VRAM";
408 sd->managedMem.mhe_MemHeader.mh_Node.ln_Pri = -128;
409 sd->managedMem.mhe_MemHeader.mh_Attributes = MEMF_CHIP | MEMF_MANAGED | MEMF_PUBLIC;
411 sd->managedMem.mhe_UserData = sd;
413 sd->managedMem.mhe_Alloc = mh_Alloc;
414 sd->managedMem.mhe_Free = mh_Free;
415 sd->managedMem.mhe_AllocAbs = mh_AllocAbs;
416 sd->managedMem.mhe_ReAlloc = mh_ReAlloc;
417 sd->managedMem.mhe_Avail = mh_Avail;
419 Disable();
420 AddTail(&SysBase->MemList, (struct Node *)&sd->managedMem);
421 Enable();
424 /* Number of ULONG's in bitmap */
425 sd->CardMemSize = sd->Card.FbUsableSize >> 15;
427 bug("[ATIBMP] Bitmap at %p, size %d bytes (%d bits)\n", sd->CardMemBmp, sd->CardMemSize << 2, sd->Card.FbUsableSize >> 10);
430 void BitmapFree(struct ati_staticdata *sd, ULONG ptr, ULONG size)
432 if (ptr + size < sd->Card.FbUsableSize)
434 bmclr(sd->CardMemBmp, sd->CardMemSize, ptr >> 10, (size + 1023) >> 10);
438 ULONG BitmapAlloc(struct ati_staticdata *sd, ULONG size)
440 ULONG ptr;
441 size = (size + 1023) >> 10;
443 ptr = bmffz(sd->CardMemBmp, sd->CardMemSize, 0);
445 D(bug("[ATIBMP] BitmapAlloc(%d)\n", size));
447 while (ptr <= (sd->CardMemSize << 5) + size)
449 D(bug("[ATIBMP] ptr=%08x\n", ptr));
451 if (bmtstz(sd->CardMemBmp, ptr, size))
453 bmset(sd->CardMemBmp, sd->CardMemSize, ptr, size);
454 break;
457 ptr = bmffo(sd->CardMemBmp, sd->CardMemSize, ptr);
458 ptr = bmffz(sd->CardMemBmp, sd->CardMemSize, ptr);
461 if (ptr > (sd->CardMemSize << 5) - size)
462 ptr = 0xffffffff;
463 else
464 ptr <<= 10;
466 return ptr;