From b9eda20be54219043e1018e99c9dea04eb8129c8 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Sun, 31 Jan 2010 12:58:13 +0000 Subject: [PATCH] - added H/W blitter support Committed on the Free edition of March Hare Software CVSNT Server. Upgrade to CVS Suite for more features and support: http://march-hare.com/cvsnt/ git-svn-id: http://moon:8086/svn/vhdl/trunk@698 cc03376c-175c-47c8-b038-4cd826a8556b --- lib/CPUs/MIPS/bsp/examples/mips_gfx.c | 224 ++++++++++++++++---------- lib/CPUs/MIPS/bsp/examples/mips_gfx.h | 37 ++++- 2 files changed, 176 insertions(+), 85 deletions(-) diff --git a/lib/CPUs/MIPS/bsp/examples/mips_gfx.c b/lib/CPUs/MIPS/bsp/examples/mips_gfx.c index 185c749..ee06438 100644 --- a/lib/CPUs/MIPS/bsp/examples/mips_gfx.c +++ b/lib/CPUs/MIPS/bsp/examples/mips_gfx.c @@ -4,6 +4,8 @@ #include "libsys.h" #include "mips_gfx.h" +#define USE_HW_BLITTER + // ------------------------------------------------------------- // Functions // ------------------------------------------------------------- @@ -79,6 +81,7 @@ void GFX_DirtyRectInit(buf_t *pBuf, UINT32 w, UINT32 h) { pBuf->w = w; pBuf->h = h; + pBuf->regs = (vga_hw_t*)SYS_VGA_CTRL; GFX_DirtyRectSetClean(pBuf); } @@ -129,6 +132,22 @@ void GFX_DirtyRectCopy(buf_t *pBuf) ymin *= pBuf->w; ymax *= pBuf->w; +#ifdef USE_HW_BLITTER + pSrc = (UINT32*)&pBuf->pLast->pFB[xmin + ymin]; + pDst = (UINT32*)&pBuf->pFB[xmin + ymin]; + + while (pBuf->regs->pVGA_ctrl & SYS_VGA_BIT_BLIT_BSY); + + pBuf->regs->pVGA_src0 = (UINT32)pSrc; + pBuf->regs->pVGA_dst = (UINT32)pDst; + pBuf->regs->pVGA_src0_dimx = (UINT32)4*pBuf->w; + pBuf->regs->pVGA_dst_dimx = (UINT32)4*pBuf->w; + pBuf->regs->pVGA_nx = (UINT32)(pBuf->rect.xmax-pBuf->rect.xmin); + pBuf->regs->pVGA_ny = (UINT32)(pBuf->rect.ymax-pBuf->rect.ymin); + pBuf->regs->pVGA_ctrl |= SYS_VGA_BIT_BLIT_REQ; + +#else + if (!((xmax-xmin)%8)) { for (y=ymin; y < ymax; y += pBuf->w) @@ -155,19 +174,19 @@ void GFX_DirtyRectCopy(buf_t *pBuf) pBuf->pFB[x + y] = pBuf->pLast->pFB[x + y]; } } +#endif + } void GFX_init(gfx_t *pObj) { - UINT32 volatile *pVGA_ctrl = (UINT32*)SYS_VGA_CTRL; - UINT32 volatile *pVGA_moffs_0 = (UINT32*)SYS_VGA_FB_FRONT; - UINT32 volatile *pVGA_moffs_1 = (UINT32*)SYS_VGA_FB_BACK; - int i; buf_t *pBuf; UINT32 w, h, fps; - *pVGA_ctrl &= ~SYS_VGA_BIT_MSTEN; + pObj->regs = (vga_hw_t*)SYS_VGA_CTRL; + + pObj->regs->pVGA_ctrl &= ~SYS_VGA_BIT_MSTEN; w = Screen_get_resx(); h = Screen_get_resy(); @@ -178,7 +197,10 @@ void GFX_init(gfx_t *pObj) pObj->w = w; pObj->h = h; - // Init buffers + // Init background buffer + pObj->pBG = (UINT32*)calloc(w * h, sizeof(buf_t)); + + // Init framebuffers pObj->pBuf = (buf_t*)calloc(1, sizeof(buf_t)); pBuf = pObj->pBuf; pBuf->pFB = (UINT32*)calloc((w+8) * h, sizeof(UINT32)); // w+8 because of dirty rectangle 8 byte min. x-size @@ -202,9 +224,9 @@ void GFX_init(gfx_t *pObj) pBuf = pBuf->pNext; } - *pVGA_moffs_0 = (UINT32)pObj->pBuf->pLast->pFB; - *pVGA_moffs_1 = (UINT32)pObj->pBuf->pLast->pFB; - *pVGA_ctrl |= SYS_VGA_BIT_MSTEN; + pObj->regs->pVGA_front = (UINT32)pObj->pBuf->pLast->pFB; + pObj->regs->pVGA_back = (UINT32)pObj->pBuf->pLast->pFB; + pObj->regs->pVGA_ctrl |= SYS_VGA_BIT_MSTEN; } @@ -214,7 +236,7 @@ void GFX_set_background(gfx_t *pObj, UINT32 *pImage, UINT32 image_nx, UINT32 ima UINT32 off_x, off_y; UINT32 i, j; - UINT32 *pScr, *pImg; + UINT32 *pDst, *pSrc; buf_t *pBuf; if (!pImage) @@ -223,16 +245,26 @@ void GFX_set_background(gfx_t *pObj, UINT32 *pImage, UINT32 image_nx, UINT32 ima off_x = (pObj->w-(image_scale_x*image_nx))/2; off_y = (pObj->h-(image_scale_y*image_ny))/2; - pBuf = pObj->pBuf; - - pScr = ((UINT32*)pBuf->pFB) + pObj->w*off_y + off_x; - pImg = pImage; + pDst = ((UINT32*)pObj->pBG) + pObj->w*off_y + off_x; + pSrc = pImage; for (i=0; i < image_ny*image_nx; i += 8) { - __gfx_block_copy_8(pScr, pImg); - pScr += 8; - pImg += 8; + __gfx_block_copy_8(pDst, pSrc); + pDst += 8; + pSrc += 8; + } + + pBuf = pObj->pBuf; + + pDst = pBuf->pFB; + pSrc = pObj->pBG; + + for (i=0; i < image_ny*image_nx; i += 8) + { + __gfx_block_copy_8(pDst, pSrc); + pDst += 8; + pSrc += 8; } do @@ -247,23 +279,26 @@ void GFX_set_background(gfx_t *pObj, UINT32 *pImage, UINT32 image_nx, UINT32 ima void GFX_frame(gfx_t *pObj, UINT32 sync_mode) { - UINT32 volatile *pVGA_moffs_0 = (UINT32*)SYS_VGA_FB_FRONT; // Wait until back buffer becomes front if (sync_mode == GFX_FRAME_SYNC) { - while(*pVGA_moffs_0 == (UINT32)pObj->pBuf->pFB); + while(pObj->regs->pVGA_front == (UINT32)pObj->pBuf->pFB); } GFX_copy_front2back(pObj); + // Invalidate D-Cache after blitting has finished + while (pObj->regs->pVGA_ctrl & SYS_VGA_BIT_BLIT_BSY); + + DCACHE_invalidate_all(); + } void GFX_show(gfx_t *pObj) { - UINT32 volatile *pVGA_moffs_1 = (UINT32*)SYS_VGA_FB_BACK; - *pVGA_moffs_1 = (UINT32)pObj->pBuf->pFB; + pObj->regs->pVGA_back = (UINT32)pObj->pBuf->pFB; pObj->pBuf = pObj->pBuf->pNext; } @@ -287,10 +322,6 @@ void GFX_copy_front2back(gfx_t *pObj) } } -void GFX_copy_back2front(gfx_t *pObj) -{ -} - void GFX_get_FB_front(gfx_t *pObj, UINT32 **ppFB) { *ppFB = pObj->pBuf->pLast->pFB; @@ -298,59 +329,15 @@ void GFX_get_FB_front(gfx_t *pObj, UINT32 **ppFB) void box_create(box_t *pObj, UINT32 w, UINT32 h) { - pObj->pSave = malloc(w*h*sizeof(UINT32)); pObj->w = w; pObj->h = h; } -void GFX_save(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy) -{ - UINT32 xmin, xmax, ymin, ymax, x, y; - UINT32 *pFB, *pFB_end, *pSave; - - xmin = posx; - xmax = pBox->w + posx; - if (xmax > pObj->w) - xmax = pObj->w; - - ymin = pObj->w*posy; - ymax = pBox->h + posy; - if (ymax > pObj->h) - ymax = pObj->h; - - ymax *= pObj->w; - pSave = pBox->pSave; - - if (!((xmax-xmin)%8)) - { - for (y=ymin; y < ymax; y += pObj->w) - { - pFB = &pObj->pBuf->pFB[xmin + y]; - pFB_end = &pObj->pBuf->pFB[xmax + y]; - while(pFB < pFB_end) - { - __gfx_block_copy_8(pSave, pFB); - pFB += 8; - pSave += 8; - } - } - return; - } - -// fprintf(stderr, "GFX_save(): Slow copy!\n"); - for (y=ymin; y < ymax; y += pObj->w) - { - for (x=xmin; x < xmax; x++) - { - *(pSave++) = pObj->pBuf->pFB[x + y]; - } - } -} - void GFX_restore(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy) { UINT32 xmin, xmax, ymin, ymax, x, y; - UINT32 *pFB, *pFB_end, *pSave; + UINT32 *pDst, *pDst_end; + UINT32 *pSrc, *pSrc_end; buf_t *pBuf; xmin = posx; @@ -374,34 +361,60 @@ void GFX_restore(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy) } pBuf = pObj->pBuf; + x = xmax - xmin + 1; + if (x%2) + x++; + y = ymax - ymin + 1; + if (y%2) + y++; + ymin *= pObj->w; ymax *= pObj->w; - pSave = pBox->pSave; + +#ifdef USE_HW_BLITTER + pSrc = (UINT32*)&pObj->pBG[xmin + ymin]; + pDst = (UINT32*)&pBuf->pFB[xmin + ymin]; + + while (pObj->regs->pVGA_ctrl & SYS_VGA_BIT_BLIT_BSY); + + pObj->regs->pVGA_src0 = (UINT32)pSrc; + pObj->regs->pVGA_dst = (UINT32)pDst; + pObj->regs->pVGA_src0_dimx = (UINT32)4*pObj->w; + pObj->regs->pVGA_dst_dimx = (UINT32)4*pObj->w; + pObj->regs->pVGA_nx = (UINT32)x - 1; + pObj->regs->pVGA_ny = (UINT32)y - 1; + pObj->regs->pVGA_ctrl |= SYS_VGA_BIT_BLIT_REQ; + +#else if (!((xmax-xmin)%8)) { - for (y=ymin; y < ymax; y += pObj->w) + for (y=ymin; y < ymax; y += pBuf->w) { - pFB = &pBuf->pFB[xmin + y]; - pFB_end = &pBuf->pFB[xmax + y]; - while(pFB < pFB_end) + pSrc = &pObj->pBG[xmin + y]; + pSrc_end = &pObj->pBG[xmax + y]; + pDst = &pBuf->pFB[xmin + y]; + pDst_end = &pBuf->pFB[xmax + y]; + while(pDst < pDst_end) { - __gfx_block_copy_8(pFB, pSave); - pFB += 8; - pSave += 8; + __gfx_block_copy_8(pDst, pSrc); + pDst += 8; + pSrc += 8; } } return; } -// fprintf(stderr, "GFX_restore(): Slow copy!\n"); - for (y=ymin; y < ymax; y += pObj->w) +// fprintf(stderr, "GFX_DirtyRectCopy(): Slow copy!\n"); + for (y=ymin; y < ymax; y += pBuf->w) { for (x=xmin; x < xmax; x++) { - pBuf->pFB[x + y] = *(pSave++); + pBuf->pFB[x + y] = pObj->pBG[x + y]; } } +#endif + } void GFX_box_draw(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy, UINT32 color) @@ -434,6 +447,8 @@ void GFX_box_draw(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy, UINT32 col ymin *= pObj->w; ymax *= pObj->w; + while (pObj->regs->pVGA_ctrl & SYS_VGA_BIT_BLIT_BSY); + if (!((xmax-xmin)%8)) { for (y=ymin; y < ymax; y += pObj->w) @@ -459,6 +474,51 @@ void GFX_box_draw(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy, UINT32 col } } +void GFX_box_draw_bg(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy, UINT32 color) +{ + UINT32 xmin, xmax, ymin, ymax, x, y; + UINT32 *pFB, *pFB_end; + + xmin = posx; + xmax = pBox->w + posx; + if (xmax > pObj->w) + xmax = pObj->w; + + ymin = posy; + ymax = pBox->h + posy; + if (ymax > pObj->h) + ymax = pObj->h; + + ymin *= pObj->w; + ymax *= pObj->w; + + while (pObj->regs->pVGA_ctrl & SYS_VGA_BIT_BLIT_BSY); + + if (!((xmax-xmin)%8)) + { + for (y=ymin; y < ymax; y += pObj->w) + { + pFB = &pObj->pBG[xmin + y]; + pFB_end = &pObj->pBG[xmax + y]; + while(pFB < pFB_end) + { + __gfx_block_set_8(pFB, color); + pFB += 8; + } + } + return; + } + +// fprintf(stderr, "GFX_box_draw_bg(): Slow copy!\n"); + for (y=ymin; y < ymax; y += pObj->w) + { + for (x=xmin; x < xmax; x++) + { + pObj->pBG[x + y] = color; + } + } +} + void GFX_box_draw_direct(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy, UINT32 color) { UINT32 xmin, xmax, ymin, ymax, x, y; diff --git a/lib/CPUs/MIPS/bsp/examples/mips_gfx.h b/lib/CPUs/MIPS/bsp/examples/mips_gfx.h index 2ebcdb4..1363e07 100644 --- a/lib/CPUs/MIPS/bsp/examples/mips_gfx.h +++ b/lib/CPUs/MIPS/bsp/examples/mips_gfx.h @@ -13,7 +13,6 @@ typedef struct _sbox_t { UINT32 w, h; - UINT32 *pSave; } box_t; typedef struct _srect_t @@ -22,6 +21,37 @@ typedef struct _srect_t UINT32 ymin, ymax; } rect_t; +typedef struct _svga_hw_t +{ + UINT32 volatile pVGA_ctrl; // 0xA0030000 // R/W + UINT32 volatile pVGA_ascii; // 0xA0030004 // R/W + UINT32 volatile pVGA_posx; // 0xA0030008 // R/W + UINT32 volatile pVGA_posy; // 0xA003000C // R/W + UINT32 volatile pVGA_cgcol; // 0xA0030010 // R/W + UINT32 volatile pVGA_res; // 0xA0030014 // RO + UINT32 volatile pVGA_front; // 0xA0030018 // R/W + UINT32 volatile pVGA_back; // 0xA003001C // R/W + UINT32 volatile pVGA_src0; // 0xA0030020 // R/W + UINT32 volatile pVGA_src0_last; // 0xA0030024 // R/W + UINT32 volatile pVGA_src0_dimx; // 0xA0030028 // R/W + UINT32 volatile pVGA_src0_res; // 0xA003002C // R/W + UINT32 volatile pVGA_src1; // 0xA0030030 // R/W + UINT32 volatile pVGA_src1_last; // 0xA0030034 // R/W + UINT32 volatile pVGA_src1_dimx; // 0xA0030038 // R/W + UINT32 volatile pVGA_src1_res; // 0xA003003C // R/W + UINT32 volatile pVGA_src2; // 0xA0030040 // R/W + UINT32 volatile pVGA_src2_last; // 0xA0030044 // R/W + UINT32 volatile pVGA_src2_dimx; // 0xA0030048 // R/W + UINT32 volatile pVGA_src2_res; // 0xA003004C // R/W + UINT32 volatile pVGA_dst; // 0xA0030050 // R/W + UINT32 volatile pVGA_dst_last; // 0xA0030054 // R/W + UINT32 volatile pVGA_dst_dimx; // 0xA0030058 // R/W + UINT32 volatile pVGA_dst_res; // 0xA003005C // R/W + UINT32 volatile pVGA_nx; // 0xA0030060 // R/W + UINT32 volatile pVGA_ny; // 0xA0030064 // R/W + +} vga_hw_t; + typedef struct _sbuf_t { UINT32 *pFB; @@ -30,6 +60,7 @@ typedef struct _sbuf_t UINT32 is_dirty; rect_t rect; UINT32 w, h; + vga_hw_t *regs; } buf_t; typedef struct _sgfx_t @@ -37,6 +68,7 @@ typedef struct _sgfx_t UINT32 w, h; buf_t *pBuf; UINT32 *pBG; + vga_hw_t *regs; } gfx_t; @@ -50,11 +82,10 @@ void GFX_init(gfx_t *pObj); void GFX_frame(gfx_t *pObj, UINT32 sync_mode); void GFX_show(gfx_t *pObj); void GFX_copy_front2back(gfx_t *pObj); -void GFX_copy_back2front(gfx_t *pObj); void GFX_get_FB_front(gfx_t *pObj, UINT32 **ppFB); void box_create(box_t *pObj, UINT32 w, UINT32 h); -void GFX_save(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy); void GFX_restore(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy); void GFX_box_draw(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy, UINT32 color); +void GFX_box_draw_bg(gfx_t *pObj, box_t *pBox, UINT32 posx, UINT32 posy, UINT32 color); #endif // GFX_H