transparent blit

git-svn-id: svn://kolibrios.org@829 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2008-07-23 10:25:40 +00:00
parent 710a7a5b8b
commit a4d9a318f2
5 changed files with 145 additions and 42 deletions

View File

@ -292,36 +292,62 @@ int CreatePixmap(userpixmap_t *io)
return ERR_OK; 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) int LockPixmap(userpixmap_t *io)
{ {
pixmap_t *pixmap; pixmap_t *pixmap;
size_t size; size_t size;
void *usermap; void *usermap;
dbgprintf("Lock pixmap %x\n", io->pixmap); dbgprintf("Lock pixmap %x\n", io->pixmap);
if(io->pixmap == (pixmap_t*)-1) if(io->pixmap == (pixmap_t*)-1)
return ERR_PARAM; return ERR_PARAM;
else else
pixmap = io->pixmap; pixmap = io->pixmap;
if( (pixmap->flags & 1) == PX_LOCK ) if( (pixmap->flags & 1) == PX_LOCK )
return ERR_PARAM; return ERR_PARAM;
size = (pixmap->pitch*pixmap->width+4095) & ~ 4095; size = (pixmap->pitch*pixmap->width+4095) & ~ 4095;
if (usermap = UserAlloc(size)) if (usermap = UserAlloc(size))
{ {
CommitPages(usermap, ((u32_t)pixmap->raw+rhd.PhisBase)|7|(1<<9), size); CommitPages(usermap, ((u32_t)pixmap->raw+rhd.PhisBase)|7|(1<<9), size);
pixmap->flags |= PX_LOCK; pixmap->flags |= PX_LOCK;
pixmap->usermap = usermap; pixmap->usermap = usermap;
io->usermap = usermap; io->usermap = usermap;
io->pitch = pixmap->pitch; io->pitch = pixmap->pitch;
dbgprintf("map at %x\n", io->usermap); dbgprintf("map at %x\n", io->usermap);
return ERR_OK; return ERR_OK;
} }
else else
return ERR_PARAM; return ERR_PARAM;
}; };
int UnlockPixmap(userpixmap_t *io) int UnlockPixmap(userpixmap_t *io)
@ -400,3 +426,57 @@ int PixBlit(pixblit_t *blit)
safe_sti(ifl); safe_sti(ifl);
return ERR_OK; 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;
}

View File

@ -182,6 +182,17 @@ int _stdcall srv_2d(ioctl_t *io)
return UnlockPixmap((userpixmap_t*)inp); return UnlockPixmap((userpixmap_t*)inp);
break; 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: default:
return ERR_PARAM; return ERR_PARAM;
}; };

View File

@ -386,3 +386,4 @@ typedef enum _PictFormatShort {
PICT_g1 = PICT_FORMAT(1,PICT_TYPE_GRAY,0,0,0,0), PICT_g1 = PICT_FORMAT(1,PICT_TYPE_GRAY,0,0,0,0),
} PictFormatShort; } PictFormatShort;
void dump_mem();

View File

@ -42,23 +42,23 @@
struct mem_block { struct mem_block {
struct mem_block *next; struct mem_block *next;
struct mem_block *prev; struct mem_block *prev;
int start; u32_t start;
int size; size_t size;
}; };
/* Initialize. How to check for an uninitialized heap? /* Initialize. How to check for an uninitialized heap?
*/ */
static int init_heap(struct mem_block **heap, int start, int size) 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) if (!blocks)
return -1; //-ENOMEM; return -1; //-ENOMEM;
*heap = kmalloc(sizeof(**heap)); *heap = malloc(sizeof(**heap));
if (!*heap) if (!*heap)
{ {
kfree(blocks); free(blocks);
return -1; //-ENOMEM; return -1; //-ENOMEM;
} }
@ -68,6 +68,7 @@ static int init_heap(struct mem_block **heap, int start, int size)
__clear(*heap,sizeof(**heap)); __clear(*heap,sizeof(**heap));
(*heap)->next = (*heap)->prev = blocks; (*heap)->next = (*heap)->prev = blocks;
(*heap)->start |= USED_BLOCK;
return 0; 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 */ /* Maybe cut off the end of an existing block */
if (size < p->size) if (size < p->size)
{ {
struct mem_block *newblock = kmalloc(sizeof(*newblock)); struct mem_block *newblock = malloc(sizeof(*newblock));
if (!newblock) if (!newblock)
goto out; goto out;
newblock->start = p->start + size; 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->prev = newblock;
p->next = newblock; p->next = newblock;
p->size = size; p->size = size;
p->start|=1; p->start|=USED_BLOCK;
} }
out: out:
@ -113,6 +114,7 @@ static struct mem_block *alloc_block(struct mem_block *heap, int size)
list_for_each(p, heap) list_for_each(p, heap)
{ {
if ( !(p->start & USED_BLOCK) && size <= p->size) if ( !(p->start & USED_BLOCK) && size <= p->size)
return split_block(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) list_for_each(p, heap)
if ((p->start & ~USED_BLOCK) == start) if ((p->start & ~USED_BLOCK) == start)
return p; return p;
return NULL; return NULL;
} }
@ -147,7 +148,7 @@ static void free_block(struct mem_block *p)
p->size += q->size; p->size += q->size;
p->next = q->next; p->next = q->next;
p->next->prev = p; p->next->prev = p;
kfree(q); free(q);
} }
if ( !(p->prev->start & USED_BLOCK)) if ( !(p->prev->start & USED_BLOCK))
@ -156,7 +157,7 @@ static void free_block(struct mem_block *p)
q->size += p->size; q->size += p->size;
q->next = p->next; q->next = p->next;
q->next->prev = q; 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; struct mem_block *block, **heap;
heap = get_heap(rhdPtr, region); heap = get_heap(rhdPtr, region);
if (!heap || !*heap) if (!heap || !*heap)
return NULL; return NULL;
/* Make things easier on ourselves: all allocations at least /* 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) if (!block)
return -1; return -1;
if ( !(block->start & 1)) if ( !(block->start & USED_BLOCK))
return -1; return -1;
free_block(block); free_block(block);
return 0; 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);
}
}

View File

@ -110,12 +110,7 @@ static inline void UnmapPages(void *mem, size_t size)
:"a" (mem), "c"(size>>12) :"a" (mem), "c"(size>>12)
:"edx" :"edx"
); );
asm volatile ( asm volatile ("":::"eax","ecx");
""
:
:
:"eax","ecx"
);
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -187,8 +182,10 @@ __clear (void * dst, unsigned len)
"rep stosb \n" "rep stosb \n"
:"=c"(tmp),"=D"(tmp) :"=c"(tmp),"=D"(tmp)
:"c"(len),"D"(dst) :"c"(len),"D"(dst)
:"memory","eax","cc" :"eax"
); );
asm volatile ("":::"ecx","edi");
}; };