diff --git a/programs/system/drivers/ati2d/accel_2d.inc b/programs/system/drivers/ati2d/accel_2d.inc index eb78718567..681d63b7e0 100644 --- a/programs/system/drivers/ati2d/accel_2d.inc +++ b/programs/system/drivers/ati2d/accel_2d.inc @@ -292,36 +292,62 @@ int CreatePixmap(userpixmap_t *io) return ERR_OK; } +int DestroyPixmap( userpixmap_t *io) +{ + pixmap_t *pixmap; + + dbgprintf("Destroy pixmap %x\n", io->pixmap); + + if(io->pixmap == (pixmap_t*)-1) + return ERR_PARAM; + else + pixmap = io->pixmap; + + if( (pixmap->flags & 1) == PX_LOCK ) + UnlockPixmap(io); + + UserFree(pixmap->usermap); + rhd_mem_free(&rhd,RHD_MEM_FB,pixmap->raw); + free(pixmap); + + io->pixmap = NULL; + io->usermap = NULL; + io->format = 0; + io->pitch = 0; + + return ERR_OK; +}; + int LockPixmap(userpixmap_t *io) { - pixmap_t *pixmap; - size_t size; - void *usermap; + pixmap_t *pixmap; + size_t size; + void *usermap; - dbgprintf("Lock pixmap %x\n", io->pixmap); + dbgprintf("Lock pixmap %x\n", io->pixmap); - if(io->pixmap == (pixmap_t*)-1) - return ERR_PARAM; - else - pixmap = io->pixmap; + if(io->pixmap == (pixmap_t*)-1) + return ERR_PARAM; + else + pixmap = io->pixmap; - if( (pixmap->flags & 1) == PX_LOCK ) - return ERR_PARAM; + if( (pixmap->flags & 1) == PX_LOCK ) + return ERR_PARAM; - size = (pixmap->pitch*pixmap->width+4095) & ~ 4095; - if (usermap = UserAlloc(size)) - { - CommitPages(usermap, ((u32_t)pixmap->raw+rhd.PhisBase)|7|(1<<9), size); - pixmap->flags |= PX_LOCK; - pixmap->usermap = usermap; - io->usermap = usermap; - io->pitch = pixmap->pitch; - dbgprintf("map at %x\n", io->usermap); + size = (pixmap->pitch*pixmap->width+4095) & ~ 4095; + if (usermap = UserAlloc(size)) + { + CommitPages(usermap, ((u32_t)pixmap->raw+rhd.PhisBase)|7|(1<<9), size); + pixmap->flags |= PX_LOCK; + pixmap->usermap = usermap; + io->usermap = usermap; + io->pitch = pixmap->pitch; + dbgprintf("map at %x\n", io->usermap); - return ERR_OK; - } - else - return ERR_PARAM; + return ERR_OK; + } + else + return ERR_PARAM; }; int UnlockPixmap(userpixmap_t *io) @@ -400,3 +426,57 @@ int PixBlit(pixblit_t *blit) safe_sti(ifl); return ERR_OK; } + + +int TransBlit(pixblit_t *blit) +{ + + u32 *ring, write; + int w, h; + u32 ifl; + int x0, y0; + + pixmap_t *srcpixmap; + pixmap_t *dstpixmap; + + dbgprintf("Transblit src: %x dst: %x\n",blit->srcpix, blit->dstpix); + + dstpixmap = (blit->dstpix == (void*)-1) ? &scr_pixmap : blit->dstpix ; + srcpixmap = (blit->srcpix == (void*)-1) ? &scr_pixmap : blit->srcpix ; + + //dbgprintf("srcpixmap: %x dstpixmap: %x\n",srcpixmap, dstpixmap); + + //dbgprintf("dst.width: %d dst.height: %d\n", dstpixmap->width,dstpixmap->height); + //dbgprintf("src.width: %d src.height: %d\n", srcpixmap->width,srcpixmap->height); + //dbgprintf("srcpitch: %x dstpitch: %x\n", + // srcpixmap->pitch_offset,dstpixmap->pitch_offset); + + ifl = safe_cli(); + + BEGIN_RING(); + OUT_RING(CP_PACKET3(RADEON_CNTL_TRANBLT, 8)); + + OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | + RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_NONE | + RADEON_GMC_DST_32BPP | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_DP_SRC_SOURCE_MEMORY | + (1 << 30) | R5XX_ROP3_S); + + OUT_RING(srcpixmap->pitch_offset); + OUT_RING(dstpixmap->pitch_offset); + + OUT_RING((2<<24)+5); + OUT_RING(0xFF000000); + OUT_RING(0xFF000000); + + OUT_RING((blit->src_x<<16)|blit->src_y); + OUT_RING((blit->dst_x<<16)|blit->dst_y); + OUT_RING((blit->w<<16)|blit->h); + COMMIT_RING(); + + safe_sti(ifl); + return ERR_OK; +} + diff --git a/programs/system/drivers/ati2d/ati2d.c b/programs/system/drivers/ati2d/ati2d.c index 1ecffae5bd..60b71b9366 100644 --- a/programs/system/drivers/ati2d/ati2d.c +++ b/programs/system/drivers/ati2d/ati2d.c @@ -182,6 +182,17 @@ int _stdcall srv_2d(ioctl_t *io) return UnlockPixmap((userpixmap_t*)inp); break; + case PIXDESTROY: + if(io->inp_size==6) + return DestroyPixmap((userpixmap_t*)inp); + break; + + case TRANSBLIT: + if(io->inp_size==8) + return TransBlit((pixblit_t*)inp); + break; + + default: return ERR_PARAM; }; diff --git a/programs/system/drivers/ati2d/ati2d.h b/programs/system/drivers/ati2d/ati2d.h index 540a95b3c8..37d8c2a2b4 100644 --- a/programs/system/drivers/ati2d/ati2d.h +++ b/programs/system/drivers/ati2d/ati2d.h @@ -386,3 +386,4 @@ typedef enum _PictFormatShort { PICT_g1 = PICT_FORMAT(1,PICT_TYPE_GRAY,0,0,0,0), } PictFormatShort; +void dump_mem(); diff --git a/programs/system/drivers/ati2d/ati_mem.c b/programs/system/drivers/ati2d/ati_mem.c index addc2c60e8..3052d55b8f 100644 --- a/programs/system/drivers/ati2d/ati_mem.c +++ b/programs/system/drivers/ati2d/ati_mem.c @@ -42,23 +42,23 @@ struct mem_block { struct mem_block *next; struct mem_block *prev; - int start; - int size; + u32_t start; + size_t size; }; /* Initialize. How to check for an uninitialized heap? */ static int init_heap(struct mem_block **heap, int start, int size) { - struct mem_block *blocks = kmalloc(sizeof(*blocks)); + struct mem_block *blocks = malloc(sizeof(*blocks)); if (!blocks) return -1; //-ENOMEM; - *heap = kmalloc(sizeof(**heap)); + *heap = malloc(sizeof(**heap)); if (!*heap) { - kfree(blocks); + free(blocks); return -1; //-ENOMEM; } @@ -68,6 +68,7 @@ static int init_heap(struct mem_block **heap, int start, int size) __clear(*heap,sizeof(**heap)); (*heap)->next = (*heap)->prev = blocks; + (*heap)->start |= USED_BLOCK; return 0; } @@ -90,7 +91,7 @@ static struct mem_block *split_block(struct mem_block *p, int size) /* Maybe cut off the end of an existing block */ if (size < p->size) { - struct mem_block *newblock = kmalloc(sizeof(*newblock)); + struct mem_block *newblock = malloc(sizeof(*newblock)); if (!newblock) goto out; newblock->start = p->start + size; @@ -100,7 +101,7 @@ static struct mem_block *split_block(struct mem_block *p, int size) p->next->prev = newblock; p->next = newblock; p->size = size; - p->start|=1; + p->start|=USED_BLOCK; } out: @@ -113,6 +114,7 @@ static struct mem_block *alloc_block(struct mem_block *heap, int size) list_for_each(p, heap) { + if ( !(p->start & USED_BLOCK) && size <= p->size) return split_block(p, size); } @@ -128,7 +130,6 @@ static struct mem_block *find_block(struct mem_block *heap, int start) list_for_each(p, heap) if ((p->start & ~USED_BLOCK) == start) return p; - return NULL; } @@ -147,7 +148,7 @@ static void free_block(struct mem_block *p) p->size += q->size; p->next = q->next; p->next->prev = p; - kfree(q); + free(q); } if ( !(p->prev->start & USED_BLOCK)) @@ -156,7 +157,7 @@ static void free_block(struct mem_block *p) q->size += p->size; q->next = p->next; q->next->prev = q; - kfree(p); + free(p); } } @@ -172,7 +173,7 @@ void *rhd_mem_alloc(RHDPtr rhdPtr,int region, int size) struct mem_block *block, **heap; heap = get_heap(rhdPtr, region); - if (!heap || !*heap) + if (!heap || !*heap) return NULL; /* Make things easier on ourselves: all allocations at least @@ -201,11 +202,24 @@ int rhd_mem_free(RHDPtr rhdPtr, int region, void *offset) if (!block) return -1; - if ( !(block->start & 1)) + if ( !(block->start & USED_BLOCK)) return -1; free_block(block); return 0; } +void dump_mem() +{ + struct mem_block *p; + struct mem_block **heap; + + heap = &rhd.fb_heap; + + list_for_each(p, *heap) + { + dbgprintf("block: %x next: %x prev: %x start: %x size:%x\n", + p,p->next,p->prev,p->start,p->size); + } +} diff --git a/programs/system/drivers/ati2d/common.h b/programs/system/drivers/ati2d/common.h index 3db52d6968..5d818f0432 100644 --- a/programs/system/drivers/ati2d/common.h +++ b/programs/system/drivers/ati2d/common.h @@ -110,12 +110,7 @@ static inline void UnmapPages(void *mem, size_t size) :"a" (mem), "c"(size>>12) :"edx" ); - asm volatile ( - "" - : - : - :"eax","ecx" - ); + asm volatile ("":::"eax","ecx"); } /////////////////////////////////////////////////////////////////////////////// @@ -187,8 +182,10 @@ __clear (void * dst, unsigned len) "rep stosb \n" :"=c"(tmp),"=D"(tmp) :"c"(len),"D"(dst) - :"memory","eax","cc" + :"eax" ); + asm volatile ("":::"ecx","edi"); + };