diff options
Diffstat (limited to 'bltsville/gcbv/mirror/gcbv.c')
-rw-r--r-- | bltsville/gcbv/mirror/gcbv.c | 2008 |
1 files changed, 0 insertions, 2008 deletions
diff --git a/bltsville/gcbv/mirror/gcbv.c b/bltsville/gcbv/mirror/gcbv.c deleted file mode 100644 index 86d656e..0000000 --- a/bltsville/gcbv/mirror/gcbv.c +++ /dev/null @@ -1,2008 +0,0 @@ -/* - * Copyright(c) 2012, - * Texas Instruments, Inc. and Vivante Corporation. - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Vivante Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "gcbv.h" - -#define GCZONE_NONE 0 -#define GCZONE_ALL (~0U) -#define GCZONE_MAPPING (1 << 0) -#define GCZONE_BUFFER (1 << 1) -#define GCZONE_DEST (1 << 2) -#define GCZONE_SRC (1 << 3) -#define GCZONE_MASK (1 << 4) -#define GCZONE_BATCH (1 << 5) -#define GCZONE_BLIT (1 << 6) -#define GCZONE_CACHE (1 << 7) -#define GCZONE_CALLBACK (1 << 8) -#define GCZONE_TEMP (1 << 9) -#define GCZONE_BLEND (1 << 10) - -GCDBG_FILTERDEF(bv, GCZONE_NONE, - "mapping", - "buffer", - "dest", - "source", - "mask", - "batch", - "blit", - "cache", - "callback", - "tempbuffer", - "blending") - - -/******************************************************************************* -** Global driver data access. -*/ - -struct gccontext *get_context(void) -{ - static struct gccontext gccontext; - return &gccontext; -} - - -/******************************************************************************* - * Debugging. - */ - -#if GCDEBUG_ENABLE -#define GCDUMPBATCH(batch) \ - dumpbatch(batch) - -#define GCVERIFYBATCH(changeflags, prevrect, currrect) \ - verify_batch(changeflags, prevrect, currrect) - -static void dumpbatch(struct gcbatch *gcbatch) -{ - struct list_head *gcbufferhead; - struct gcbuffer *gcbuffer; - struct list_head *gcfixuphead; - struct gcfixup *gcfixup; - unsigned int i, size; - - if ((GCDBGFILTER.zone & (GCZONE_BUFFER)) == 0) - return; - - GCDBG(GCZONE_BUFFER, "BATCH DUMP (0x%08X)\n", - (unsigned int) gcbatch); - - list_for_each(gcbufferhead, &gcbatch->buffer) { - gcbuffer = list_entry(gcbufferhead, struct gcbuffer, link); - - list_for_each(gcfixuphead, &gcbuffer->fixup) { - gcfixup = list_entry(gcfixuphead, struct gcfixup, link); - - GCDBG(GCZONE_BUFFER, - " Fixup table @ 0x%08X, count = %d:\n", - (unsigned int) gcfixup, gcfixup->count); - - for (i = 0; i < gcfixup->count; i += 1) { - GCDBG(GCZONE_BUFFER, " [%02d]" - " buffer offset = 0x%08X," - " surface offset = 0x%08X\n", - i, - gcfixup->fixup[i].dataoffset * 4, - gcfixup->fixup[i].surfoffset); - } - } - - size = (unsigned char *) gcbuffer->tail - - (unsigned char *) gcbuffer->head; - GCDUMPBUFFER(GCZONE_BUFFER, gcbuffer->head, 0, size); - } -} - -static void verify_batch(unsigned int changeflags, - struct bvrect *prevrect, - struct bvrect *currrect) -{ - if ((changeflags & 1) == 0) { - /* Origin did not change. */ - if ((prevrect->left != currrect->left) || - (prevrect->top != currrect->top)) { - GCERR("origin changed\n"); - GCERR(" previous = %d,%d\n", - prevrect->left, prevrect->top); - GCERR(" current = %d,%d\n", - currrect->left, currrect->top); - } - } - - if ((changeflags & 2) == 0) { - /* Size did not change. */ - if ((prevrect->width != currrect->width) || - (prevrect->height != currrect->height)) { - GCERR("size changed\n"); - GCERR(" previous = %dx%d\n", - prevrect->width, prevrect->height); - GCERR(" current = %dx%d\n", - currrect->width, currrect->height); - } - } - - prevrect->left = currrect->left; - prevrect->top = currrect->top; - prevrect->width = currrect->width; - prevrect->height = currrect->height; -} -#else -#define GCDUMPBATCH(...) -#define GCVERIFYBATCH(...) -#endif - - -/******************************************************************************* - * Error handling. - */ - -#define BVSETBLTSURFERROR(errorid, errordesc) \ -do { \ - struct gccontext *tmpcontext = get_context(); \ - snprintf(tmpcontext->bverrorstr, sizeof(tmpcontext->bverrorstr), \ - g_surferr[errorid].message, errordesc.id); \ - GCDUMPSTRING("%s(%d): [ERROR] %s\n", __func__, __LINE__, \ - tmpcontext->bverrorstr); \ - bverror = errordesc.base + g_surferr[errorid].offset; \ - bvbltparams->errdesc = tmpcontext->bverrorstr; \ -} while (0) - -#define GCBVERR_DESC 0 -#define GCBVERR_DESC_VERS 1 -#define GCBVERR_DESC_VIRTADDR 2 -#define GCBVERR_TILE 3 -#define GCBVERR_TILE_VERS 4 -#define GCBVERR_TILE_VIRTADDR 5 -#define GCBVERR_GEOM 6 -#define GCBVERR_GEOM_VERS 7 -#define GCBVERR_GEOM_FORMAT 8 - -struct bvsurferrorid { - char *id; - enum bverror base; -}; - -struct bvsurferror { - unsigned int offset; - char *message; -}; - -static struct bvsurferror g_surferr[] = { - /* GCBVERR_DESC */ - { 0, "%s desc structure is not set" }, - - /* GCBVERR_DESC_VERS */ - { 100, "%s desc structure has invalid size" }, - - /* GCBVERR_DESC_VIRTADDR */ - { 200, "%s desc virtual pointer is not set" }, - - /* GCBVERR_TILE: FIXME/TODO define error code */ - { 0, "%s tileparams structure is not set" }, - - /* GCBVERR_TILE_VERS */ - { 3000, "%s tileparams structure has invalid size" }, - - /* GCBVERR_TILE_VIRTADDR: FIXME/TODO define error code */ - { 200, "%s tileparams virtual pointer is not set" }, - - /* GCBVERR_GEOM */ - { 1000, "%s geom structure is not set" }, - - /* GCBVERR_GEOM_VERS */ - { 1100, "%s geom structure has invalid size" }, - - /* GCBVERR_GEOM_FORMAT */ - { 1200, "%s invalid format specified" }, -}; - -static struct bvsurferrorid g_destsurferr = { "dst", BVERR_DSTDESC }; -static struct bvsurferrorid g_src1surferr = { "src1", BVERR_SRC1DESC }; -static struct bvsurferrorid g_src2surferr = { "src2", BVERR_SRC2DESC }; -static struct bvsurferrorid g_masksurferr = { "mask", BVERR_MASKDESC }; - - -/******************************************************************************* - * Callback info management. - */ - -/* BLTsville callback function. */ -struct gccallbackbltsville { - /* Function pointer. */ - void (*fn) (struct bvcallbackerror *err, unsigned long callbackdata); - - /* Callback data. */ - unsigned long data; -}; - -/* Information for freeing a surface. */ -struct gccallbackfreesurface { - /* Pointer to the buffer descriptor. */ - struct bvbuffdesc *desc; - - /* Pointer to the buffer. */ - void *ptr; -}; - -/* Callback information. */ -struct gccallbackinfo { - union { - /* BLTsville callback function. */ - struct gccallbackbltsville callback; - - /* Information for freeing a surface. */ - struct gccallbackfreesurface freesurface; - } info; - - /* Previous/next callback information. */ - struct list_head link; -}; - -static enum bverror get_callbackinfo(struct gccallbackinfo **gccallbackinfo) -{ - enum bverror bverror; - struct gccontext *gccontext = get_context(); - struct gccallbackinfo *temp; - - /* Lock access to callback info lists. */ - GCLOCK(&gccontext->callbacklock); - - if (list_empty(&gccontext->callbackvac)) { - temp = gcalloc(struct gccallbackinfo, - sizeof(struct gccallbackinfo)); - if (temp == NULL) { - bverror = BVERR_OOM; - goto exit; - } - list_add(&temp->link, &gccontext->callbacklist); - } else { - struct list_head *head; - head = gccontext->callbackvac.next; - temp = list_entry(head, struct gccallbackinfo, link); - list_move(head, &gccontext->callbacklist); - } - - *gccallbackinfo = temp; - bverror = BVERR_NONE; - -exit: - /* Unlock access to callback info lists. */ - GCUNLOCK(&gccontext->callbacklock); - - return bverror; -} - -static void free_callback(struct gccallbackinfo *gccallbackinfo) -{ - struct gccontext *gccontext = get_context(); - - /* Lock access to callback info lists. */ - GCLOCK(&gccontext->callbacklock); - - list_move(&gccallbackinfo->link, &gccontext->callbackvac); - - /* Unlock access to callback info lists. */ - GCUNLOCK(&gccontext->callbacklock); -} - -void callbackbltsville(void *callbackinfo) -{ - struct gccallbackinfo *gccallbackinfo; - - GCENTER(GCZONE_CALLBACK); - - gccallbackinfo = (struct gccallbackinfo *) callbackinfo; - GCDBG(GCZONE_CALLBACK, "bltsville_callback = 0x%08X\n", - (unsigned int) gccallbackinfo->info.callback.fn); - GCDBG(GCZONE_CALLBACK, "bltsville_param = 0x%08X\n", - (unsigned int) gccallbackinfo->info.callback.data); - - gccallbackinfo->info.callback.fn(NULL, - gccallbackinfo->info.callback.data); - free_callback(gccallbackinfo); - - GCEXIT(GCZONE_CALLBACK); -} - -void callbackfreesurface(void *callbackinfo) -{ - struct gccallbackinfo *gccallbackinfo; - - GCENTER(GCZONE_CALLBACK); - - gccallbackinfo = (struct gccallbackinfo *) callbackinfo; - GCDBG(GCZONE_CALLBACK, "freeing descriptir @ 0x%08X\n", - (unsigned int) gccallbackinfo->info.freesurface.desc); - GCDBG(GCZONE_CALLBACK, "freeing memory @ 0x%08X\n", - (unsigned int) gccallbackinfo->info.freesurface.ptr); - - free_surface(gccallbackinfo->info.freesurface.desc, - gccallbackinfo->info.freesurface.ptr); - free_callback(gccallbackinfo); - - GCEXIT(GCZONE_CALLBACK); -} - - -/******************************************************************************* - * Temporary buffer management. - */ - -enum bverror allocate_temp(struct bvbltparams *bvbltparams, - unsigned int size) -{ - enum bverror bverror; - struct gccontext *gccontext = get_context(); - - GCENTER(GCZONE_TEMP); - - /* Existing buffer too small? */ - if ((gccontext->tmpbuffdesc != NULL) && - (gccontext->tmpbuffdesc->length < size)) { - GCDBG(GCZONE_TEMP, "freeing current buffer.\n"); - bverror = free_temp(true); - if (bverror != BVERR_NONE) { - bvbltparams->errdesc = gccontext->bverrorstr; - goto exit; - } - } - - /* Allocate new buffer if necessary. */ - if ((size > 0) && (gccontext->tmpbuffdesc == NULL)) { - /* Allocate temporary surface. */ - bverror = allocate_surface(&gccontext->tmpbuffdesc, - &gccontext->tmpbuff, - size); - if (bverror != BVERR_NONE) { - bvbltparams->errdesc = gccontext->bverrorstr; - goto exit; - } - - GCDBG(GCZONE_TEMP, "buffdesc @ 0x%08X\n", - gccontext->tmpbuffdesc); - GCDBG(GCZONE_TEMP, "allocated @ 0x%08X\n", - gccontext->tmpbuff); - GCDBG(GCZONE_TEMP, "size = %d\n", - size); - - /* Map the buffer explicitly. */ - bverror = bv_map(gccontext->tmpbuffdesc); - if (bverror != BVERR_NONE) { - bvbltparams->errdesc = gccontext->bverrorstr; - goto exit; - } - } - - /* Success. */ - bverror = BVERR_NONE; - -exit: - GCEXIT(GCZONE_TEMP); - return bverror; -} - -enum bverror free_temp(bool schedule) -{ - enum bverror bverror; - struct gccontext *gccontext = get_context(); - struct gccallbackinfo *gccallbackinfo; - struct gcicallbackarm gcicallbackarm; - - /* Is the buffer allocated? */ - if (gccontext->tmpbuffdesc == NULL) { - bverror = BVERR_NONE; - goto exit; - } - - /* Unmap the buffer. */ - bverror = bv_unmap(gccontext->tmpbuffdesc); - if (bverror != BVERR_NONE) - goto exit; - - /* Cannot be mapped. */ - if (gccontext->tmpbuffdesc->map != NULL) { - BVSETERROR(BVERR_OOM, "temporary buffer is still mapped"); - goto exit; - } - - /* Free the buffer. */ - if (schedule) { - bverror = get_callbackinfo(&gccallbackinfo); - if (bverror != BVERR_NONE) { - BVSETERROR(BVERR_OOM, - "callback allocation failed"); - goto exit; - } - - gccallbackinfo->info.freesurface.desc = gccontext->tmpbuffdesc; - gccallbackinfo->info.freesurface.ptr = gccontext->tmpbuff; - gcicallbackarm.callback = callbackfreesurface; - gcicallbackarm.callbackparam = gccallbackinfo; - - /* Schedule to free the buffer. */ - gc_callback_wrapper(&gcicallbackarm); - - /* Error? */ - if (gcicallbackarm.gcerror != GCERR_NONE) { - BVSETERROR(BVERR_OOM, "unable to schedule callback"); - goto exit; - } - } else { - /* Free the buffer immediately. */ - free_surface(gccontext->tmpbuffdesc, gccontext->tmpbuff); - } - - /* Reset the buffer descriptor. */ - gccontext->tmpbuffdesc = NULL; - gccontext->tmpbuff = NULL; - -exit: - return bverror; -} - - -/******************************************************************************* - * Program the destination. - */ - -enum bverror set_dst(struct bvbltparams *bvbltparams, - struct gcbatch *batch, - struct bvbuffmap *dstmap) -{ - enum bverror bverror = BVERR_NONE; - struct gcmodst *gcmodst; - - GCENTER(GCZONE_DEST); - - /* Did destination surface change? */ - if ((batch->batchflags & BVBATCH_DST) != 0) { - /* Allocate command buffer. */ - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmodst), - (void **) &gcmodst); - if (bverror != BVERR_NONE) - goto exit; - - /* Add the address fixup. */ - add_fixup(bvbltparams, batch, &gcmodst->address, - batch->dstbyteshift); - - /* Set surface parameters. */ - gcmodst->config_ldst = gcmodst_config_ldst; - gcmodst->address = GET_MAP_HANDLE(dstmap); - gcmodst->stride = bvbltparams->dstgeom->virtstride; - - /* Set surface width and height. */ - gcmodst->rotation.raw = 0; - gcmodst->rotation.reg.surf_width = batch->dstphyswidth; - gcmodst->rotationheight_ldst = gcmodst_rotationheight_ldst; - gcmodst->rotationheight.raw = 0; - gcmodst->rotationheight.reg.height = batch->dstphysheight; - - /* Disable hardware clipping. */ - gcmodst->clip_ldst = gcmodst_clip_ldst; - gcmodst->cliplt.raw = 0; - gcmodst->cliprb.raw = 0; - gcmodst->cliprb.reg.right = GC_CLIP_RESET_RIGHT; - gcmodst->cliprb.reg.bottom = GC_CLIP_RESET_BOTTOM; - } - -exit: - GCEXITARG(GCZONE_DEST, "bv%s = %d\n", - (bverror == BVERR_NONE) ? "result" : "error", bverror); - return bverror; -} - -/******************************************************************************* - * Program blending. - */ - -enum bverror set_blending(struct bvbltparams *bvbltparams, - struct gcbatch *batch, - struct surfaceinfo *srcinfo) -{ - enum bverror bverror = BVERR_NONE; - struct gcmoalphaoff *gcmoalphaoff; - struct gcmoalpha *gcmoalpha; - struct gcmoglobal *gcmoglobal; - struct gcalpha *gca; - - GCENTER(GCZONE_BLEND); - - gca = srcinfo->gca; - if (gca == NULL) { - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoalphaoff), - (void **) &gcmoalphaoff); - if (bverror != BVERR_NONE) - goto exit; - - gcmoalphaoff->control_ldst = gcmoalphaoff_control_ldst[0]; - gcmoalphaoff->control.reg = gcregalpha_off; - - GCDBG(GCZONE_BLEND, "blending disabled.\n"); - } else { - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoalpha), - (void **) &gcmoalpha); - if (bverror != BVERR_NONE) - goto exit; - - gcmoalpha->config_ldst = gcmoalpha_config_ldst; - gcmoalpha->control.reg = gcregalpha_on; - - gcmoalpha->mode.raw = 0; - gcmoalpha->mode.reg.src_global_alpha_mode - = gca->src_global_alpha_mode; - gcmoalpha->mode.reg.dst_global_alpha_mode - = gca->dst_global_alpha_mode; - - gcmoalpha->mode.reg.src_blend - = gca->srcconfig->factor_mode; - gcmoalpha->mode.reg.src_color_reverse - = gca->srcconfig->color_reverse; - - gcmoalpha->mode.reg.dst_blend - = gca->dstconfig->factor_mode; - gcmoalpha->mode.reg.dst_color_reverse - = gca->dstconfig->color_reverse; - - GCDBG(GCZONE_BLEND, "dst blend:\n"); - GCDBG(GCZONE_BLEND, " factor = %d\n", - gcmoalpha->mode.reg.dst_blend); - GCDBG(GCZONE_BLEND, " inverse = %d\n", - gcmoalpha->mode.reg.dst_color_reverse); - - GCDBG(GCZONE_BLEND, "src blend:\n"); - GCDBG(GCZONE_BLEND, " factor = %d\n", - gcmoalpha->mode.reg.src_blend); - GCDBG(GCZONE_BLEND, " inverse = %d\n", - gcmoalpha->mode.reg.src_color_reverse); - - if ((gca->src_global_alpha_mode - != GCREG_GLOBAL_ALPHA_MODE_NORMAL) || - (gca->dst_global_alpha_mode - != GCREG_GLOBAL_ALPHA_MODE_NORMAL)) { - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoglobal), - (void **) &gcmoglobal); - if (bverror != BVERR_NONE) - goto exit; - - gcmoglobal->color_ldst = gcmoglobal_color_ldst; - gcmoglobal->srcglobal.raw = gca->src_global_color; - gcmoglobal->dstglobal.raw = gca->dst_global_color; - } - } - -exit: - GCEXITARG(GCZONE_BLEND, "bv%s = %d\n", - (bverror == BVERR_NONE) ? "result" : "error", bverror); - return bverror; -} - -enum bverror set_blending_index(struct bvbltparams *bvbltparams, - struct gcbatch *batch, - struct surfaceinfo *srcinfo, - unsigned int index) -{ - enum bverror bverror = BVERR_NONE; - struct gcmoalphaoff *gcmoalphaoff; - struct gcmoxsrcalpha *gcmoxsrcalpha; - struct gcmoxsrcglobal *gcmoxsrcglobal; - struct gcalpha *gca; - - GCENTER(GCZONE_BLEND); - - gca = srcinfo->gca; - if (gca == NULL) { - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoalphaoff), - (void **) &gcmoalphaoff); - if (bverror != BVERR_NONE) - goto exit; - - gcmoalphaoff->control_ldst = gcmoalphaoff_control_ldst[index]; - gcmoalphaoff->control.reg = gcregalpha_off; - - GCDBG(GCZONE_BLEND, "blending disabled.\n"); - } else { - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoxsrcalpha), - (void **) &gcmoxsrcalpha); - if (bverror != BVERR_NONE) - goto exit; - - gcmoxsrcalpha->control_ldst = gcmoxsrcalpha_control_ldst[index]; - gcmoxsrcalpha->control.reg = gcregalpha_on; - - gcmoxsrcalpha->mode_ldst = gcmoxsrcalpha_mode_ldst[index]; - gcmoxsrcalpha->mode.raw = 0; - gcmoxsrcalpha->mode.reg.src_global_alpha_mode - = gca->src_global_alpha_mode; - gcmoxsrcalpha->mode.reg.dst_global_alpha_mode - = gca->dst_global_alpha_mode; - - gcmoxsrcalpha->mode.reg.src_blend - = gca->srcconfig->factor_mode; - gcmoxsrcalpha->mode.reg.src_color_reverse - = gca->srcconfig->color_reverse; - - gcmoxsrcalpha->mode.reg.dst_blend - = gca->dstconfig->factor_mode; - gcmoxsrcalpha->mode.reg.dst_color_reverse - = gca->dstconfig->color_reverse; - - GCDBG(GCZONE_BLEND, "dst blend:\n"); - GCDBG(GCZONE_BLEND, " factor = %d\n", - gcmoxsrcalpha->mode.reg.dst_blend); - GCDBG(GCZONE_BLEND, " inverse = %d\n", - gcmoxsrcalpha->mode.reg.dst_color_reverse); - - GCDBG(GCZONE_BLEND, "src blend:\n"); - GCDBG(GCZONE_BLEND, " factor = %d\n", - gcmoxsrcalpha->mode.reg.src_blend); - GCDBG(GCZONE_BLEND, " inverse = %d\n", - gcmoxsrcalpha->mode.reg.src_color_reverse); - - if ((gca->src_global_alpha_mode - != GCREG_GLOBAL_ALPHA_MODE_NORMAL) || - (gca->dst_global_alpha_mode - != GCREG_GLOBAL_ALPHA_MODE_NORMAL)) { - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoxsrcglobal), - (void **) &gcmoxsrcglobal); - if (bverror != BVERR_NONE) - goto exit; - - gcmoxsrcglobal->srcglobal_ldst - = gcmoxsrcglobal_srcglobal_ldst[index]; - gcmoxsrcglobal->srcglobal.raw = gca->src_global_color; - - gcmoxsrcglobal->dstglobal_ldst - = gcmoxsrcglobal_dstglobal_ldst[index]; - gcmoxsrcglobal->dstglobal.raw = gca->dst_global_color; - } - } - -exit: - GCEXITARG(GCZONE_BLEND, "bv%s = %d\n", - (bverror == BVERR_NONE) ? "result" : "error", bverror); - return bverror; -} - -/******************************************************************************* - * Program YUV source. - */ - -void set_computeyuv(struct surfaceinfo *srcinfo, int x, int y) -{ - int pixalign, bytealign; - unsigned int height1, size1; - unsigned int height2, size2; - unsigned int origin; - int ssX, ssY; - - GCENTER(GCZONE_SRC); - - /* Compute base address alignment. */ - pixalign = get_pixel_offset(srcinfo, 0); - bytealign = (pixalign * (int) srcinfo->format.bitspp) / 8; - - /* Determine the physical height of the first plane. */ - height1 = ((srcinfo->angle % 2) == 0) - ? srcinfo->geom->height - : srcinfo->geom->width; - - /* Determine the size of the first plane. */ - size1 = srcinfo->geom->virtstride * height1; - - /* Determine the stride of the second plane. */ - srcinfo->stride2 = srcinfo->geom->virtstride - / srcinfo->format.cs.yuv.xsample; - - /* Determine subsample pixel position. */ - ssX = x / srcinfo->format.cs.yuv.xsample; - ssY = y / srcinfo->format.cs.yuv.ysample; - - switch (srcinfo->format.cs.yuv.planecount) { - case 2: - /* U and V are interleaved in one plane. */ - ssX *= 2; - srcinfo->stride2 *= 2; - - /* Determnine the origin offset. */ - origin = ssY * srcinfo->stride2 + ssX; - - /* Compute the alignment of the second plane. */ - srcinfo->bytealign2 = bytealign + size1 + origin; - - GCDBG(GCZONE_SRC, "plane2 offset (bytes) = 0x%08X\n", - srcinfo->bytealign2); - GCDBG(GCZONE_SRC, "plane2 stride = %d\n", - srcinfo->stride2); - break; - - case 3: - /* Determine the physical height of the U/V planes. */ - height2 = height1 / srcinfo->format.cs.yuv.ysample; - - /* Determine the size of the U/V planes. */ - size2 = srcinfo->stride2 * height2; - - /* Determnine the origin offset. */ - origin = ssY * srcinfo->stride2 + ssX; - - /* Compute the alignment of the U/V planes. */ - srcinfo->bytealign2 = bytealign + size1 + origin; - srcinfo->bytealign3 = bytealign + size1 + size2 + origin; - - /* Determine the stride of the U/V planes. */ - srcinfo->stride3 = srcinfo->stride2; - - GCDBG(GCZONE_SRC, "plane2 offset (bytes) = 0x%08X\n", - srcinfo->bytealign2); - GCDBG(GCZONE_SRC, "plane2 stride = %d\n", - srcinfo->stride2); - GCDBG(GCZONE_SRC, "plane3 offset (bytes) = 0x%08X\n", - srcinfo->bytealign3); - GCDBG(GCZONE_SRC, "plane3 stride = %d\n", - srcinfo->stride3); - break; - } - - GCEXIT(GCZONE_SRC); -} - -enum bverror set_yuvsrc(struct bvbltparams *bvbltparams, - struct gcbatch *batch, - struct surfaceinfo *srcinfo, - struct bvbuffmap *srcmap) -{ - enum bverror bverror = BVERR_NONE; - struct gcmoyuv1 *gcmoyuv1; - struct gcmoyuv2 *gcmoyuv2; - struct gcmoyuv3 *gcmoyuv3; - - GCENTER(GCZONE_SRC); - - GCDBG(GCZONE_SRC, "plane count %d.\n", - srcinfo->format.cs.yuv.planecount); - - switch (srcinfo->format.cs.yuv.planecount) { - case 1: - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoyuv1), - (void **) &gcmoyuv1); - if (bverror != BVERR_NONE) - goto exit; - - /* Set YUV parameters. */ - gcmoyuv1->pectrl_ldst = gcmoyuv_pectrl_ldst; - gcmoyuv1->pectrl.raw = 0; - gcmoyuv1->pectrl.reg.standard - = srcinfo->format.cs.yuv.std; - gcmoyuv1->pectrl.reg.swizzle - = srcinfo->format.swizzle; - gcmoyuv1->pectrl.reg.convert - = GCREG_PE_CONTROL_YUVRGB_DISABLED; - break; - - case 2: - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoyuv2), - (void **) &gcmoyuv2); - if (bverror != BVERR_NONE) - goto exit; - - /* Set YUV parameters. */ - gcmoyuv2->pectrl_ldst = gcmoyuv_pectrl_ldst; - gcmoyuv2->pectrl.raw = 0; - gcmoyuv2->pectrl.reg.standard - = srcinfo->format.cs.yuv.std; - gcmoyuv2->pectrl.reg.swizzle - = srcinfo->format.swizzle; - gcmoyuv2->pectrl.reg.convert - = GCREG_PE_CONTROL_YUVRGB_DISABLED; - - /* Program U/V plane. */ - add_fixup(bvbltparams, batch, &gcmoyuv2->uplaneaddress, - srcinfo->bytealign2); - gcmoyuv2->plane_ldst = gcmoyuv2_plane_ldst; - gcmoyuv2->uplaneaddress = GET_MAP_HANDLE(srcmap); - gcmoyuv2->uplanestride = srcinfo->stride2; - break; - - case 3: - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoyuv3), - (void **) &gcmoyuv3); - if (bverror != BVERR_NONE) - goto exit; - - /* Set YUV parameters. */ - gcmoyuv3->pectrl_ldst = gcmoyuv_pectrl_ldst; - gcmoyuv3->pectrl.raw = 0; - gcmoyuv3->pectrl.reg.standard - = srcinfo->format.cs.yuv.std; - gcmoyuv3->pectrl.reg.swizzle - = srcinfo->format.swizzle; - gcmoyuv3->pectrl.reg.convert - = GCREG_PE_CONTROL_YUVRGB_DISABLED; - - /* Program U/V planes. */ - add_fixup(bvbltparams, batch, &gcmoyuv3->uplaneaddress, - srcinfo->bytealign2); - add_fixup(bvbltparams, batch, &gcmoyuv3->vplaneaddress, - srcinfo->bytealign3); - gcmoyuv3->plane_ldst = gcmoyuv3_plane_ldst; - gcmoyuv3->uplaneaddress = GET_MAP_HANDLE(srcmap); - gcmoyuv3->uplanestride = srcinfo->stride2; - gcmoyuv3->vplaneaddress = GET_MAP_HANDLE(srcmap); - gcmoyuv3->vplanestride = srcinfo->stride3; - break; - - default: - GCERR("invlaid plane count %d.\n", - srcinfo->format.cs.yuv.planecount); - } - -exit: - GCEXITARG(GCZONE_SRC, "bv%s = %d\n", - (bverror == BVERR_NONE) ? "result" : "error", bverror); - return bverror; -} - -enum bverror set_yuvsrc_index(struct bvbltparams *bvbltparams, - struct gcbatch *batch, - struct surfaceinfo *srcinfo, - struct bvbuffmap *srcmap, - unsigned int index) -{ - enum bverror bverror = BVERR_NONE; - struct gcmoxsrcyuv1 *gcmoxsrcyuv1; - struct gcmoxsrcyuv2 *gcmoxsrcyuv2; - struct gcmoxsrcyuv3 *gcmoxsrcyuv3; - - GCENTER(GCZONE_SRC); - - GCDBG(GCZONE_SRC, "plane count %d.\n", - srcinfo->format.cs.yuv.planecount); - - switch (srcinfo->format.cs.yuv.planecount) { - case 1: - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoxsrcyuv1), - (void **) &gcmoxsrcyuv1); - if (bverror != BVERR_NONE) - goto exit; - - /* Set YUV parameters. */ - gcmoxsrcyuv1->pectrl_ldst - = gcmoxsrcyuv_pectrl_ldst[index]; - gcmoxsrcyuv1->pectrl.raw = 0; - gcmoxsrcyuv1->pectrl.reg.standard - = srcinfo->format.cs.yuv.std; - gcmoxsrcyuv1->pectrl.reg.swizzle - = srcinfo->format.swizzle; - gcmoxsrcyuv1->pectrl.reg.convert - = GCREG_PE_CONTROL_YUVRGB_DISABLED; - break; - - case 2: - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoxsrcyuv2), - (void **) &gcmoxsrcyuv2); - if (bverror != BVERR_NONE) - goto exit; - - /* Set YUV parameters. */ - gcmoxsrcyuv2->pectrl_ldst - = gcmoxsrcyuv_pectrl_ldst[index]; - gcmoxsrcyuv2->pectrl.raw = 0; - gcmoxsrcyuv2->pectrl.reg.standard - = srcinfo->format.cs.yuv.std; - gcmoxsrcyuv2->pectrl.reg.swizzle - = srcinfo->format.swizzle; - gcmoxsrcyuv2->pectrl.reg.convert - = GCREG_PE_CONTROL_YUVRGB_DISABLED; - - /* Program U/V plane. */ - add_fixup(bvbltparams, batch, &gcmoxsrcyuv2->uplaneaddress, - srcinfo->bytealign2); - gcmoxsrcyuv2->uplaneaddress_ldst - = gcmoxsrcyuv_uplaneaddress_ldst[index]; - gcmoxsrcyuv2->uplaneaddress = GET_MAP_HANDLE(srcmap); - gcmoxsrcyuv2->uplanestride_ldst - = gcmoxsrcyuv_uplanestride_ldst[index]; - gcmoxsrcyuv2->uplanestride = srcinfo->stride2; - break; - - case 3: - bverror = claim_buffer(bvbltparams, batch, - sizeof(struct gcmoxsrcyuv3), - (void **) &gcmoxsrcyuv3); - if (bverror != BVERR_NONE) - goto exit; - - /* Set YUV parameters. */ - gcmoxsrcyuv3->pectrl_ldst - = gcmoxsrcyuv_pectrl_ldst[index]; - gcmoxsrcyuv3->pectrl.raw = 0; - gcmoxsrcyuv3->pectrl.reg.standard - = srcinfo->format.cs.yuv.std; - gcmoxsrcyuv3->pectrl.reg.swizzle - = srcinfo->format.swizzle; - gcmoxsrcyuv3->pectrl.reg.convert - = GCREG_PE_CONTROL_YUVRGB_DISABLED; - - /* Program U/V planes. */ - add_fixup(bvbltparams, batch, &gcmoxsrcyuv3->uplaneaddress, - srcinfo->bytealign2); - add_fixup(bvbltparams, batch, &gcmoxsrcyuv3->vplaneaddress, - srcinfo->bytealign3); - gcmoxsrcyuv3->uplaneaddress_ldst - = gcmoxsrcyuv_uplaneaddress_ldst[index]; - gcmoxsrcyuv3->uplaneaddress = GET_MAP_HANDLE(srcmap); - gcmoxsrcyuv3->uplanestride_ldst - = gcmoxsrcyuv_uplanestride_ldst[index]; - gcmoxsrcyuv3->uplanestride = srcinfo->stride2; - gcmoxsrcyuv3->vplaneaddress_ldst - = gcmoxsrcyuv_vplaneaddress_ldst[index]; - gcmoxsrcyuv3->vplaneaddress = GET_MAP_HANDLE(srcmap); - gcmoxsrcyuv3->vplanestride_ldst - = gcmoxsrcyuv_vplanestride_ldst[index]; - gcmoxsrcyuv3->vplanestride = srcinfo->stride3; - break; - - default: - GCERR("invlaid plane count %d.\n", - srcinfo->format.cs.yuv.planecount); - } - -exit: - GCEXITARG(GCZONE_SRC, "bv%s = %d\n", - (bverror == BVERR_NONE) ? "result" : "error", bverror); - return bverror; -} - -/******************************************************************************* - * Surface compare and validation. - */ - -static inline bool equal_rects(struct bvrect *rect1, struct bvrect *rect2) -{ - if (rect1->left != rect2->left) - return false; - - if (rect1->top != rect2->top) - return false; - - if (rect1->width != rect2->width) - return false; - - if (rect1->height != rect2->height) - return false; - - return true; -} - -/* The function verifies whether the two buffer descriptors and rectangles - define the same physical area. */ -static bool same_phys_area(struct bvbuffdesc *surf1, struct bvrect *rect1, - struct bvbuffdesc *surf2, struct bvrect *rect2) -{ - struct bvphysdesc *physdesc1; - struct bvphysdesc *physdesc2; - - /* If pointers are the same, things are much easier. */ - if (surf1 == surf2) - /* Compare the rectangles. For simplicity we don't consider - cases with partially overlapping rectangles at this time. */ - return equal_rects(rect1, rect2); - - /* Assume diffrent areas if the types are different. */ - if (surf1->auxtype != surf2->auxtype) - return false; - - if (surf1->auxtype == BVAT_PHYSDESC) { - physdesc1 = (struct bvphysdesc *) surf1->auxptr; - physdesc2 = (struct bvphysdesc *) surf2->auxptr; - - /* Same physical descriptor? */ - if (physdesc1 == physdesc2) - return equal_rects(rect1, rect2); - - /* Same page array? */ - if (physdesc1->pagearray == physdesc2->pagearray) - return equal_rects(rect1, rect2); - - /* Pageoffsets must match since different buffers - * can share the same first page (eg nv12). - */ - if (physdesc1->pageoffset != physdesc2->pageoffset) - return false; - - /* Assume the same surface if first pages match. */ - if (physdesc1->pagearray[0] == physdesc2->pagearray[0]) - return equal_rects(rect1, rect2); - - } else { - if (surf1->virtaddr == surf2->virtaddr) - return equal_rects(rect1, rect2); - } - - return false; -} - -static int verify_surface(unsigned int tile, - union bvinbuff *surf, - struct bvsurfgeom *geom) -{ - if (tile) { - if (surf->tileparams == NULL) - return GCBVERR_TILE; - - if (surf->tileparams->structsize < - STRUCTSIZE(surf->tileparams, srcheight)) - return GCBVERR_TILE_VERS; - - /* FIXME/TODO */ - return GCBVERR_TILE; - } else { - if (surf->desc == NULL) - return GCBVERR_DESC; - - if (surf->desc->structsize < STRUCTSIZE(surf->desc, map)) - return GCBVERR_DESC_VERS; - } - - if (geom == NULL) - return GCBVERR_GEOM; - - if (geom->structsize < STRUCTSIZE(geom, palette)) - return GCBVERR_GEOM_VERS; - - /* Validation successful. */ - return -1; -} - - -/******************************************************************************* - * Library constructor and destructor. - */ - -void bv_init(void) -{ - struct gccontext *gccontext = get_context(); - struct gcicaps gcicaps; - unsigned i, j; - - GCDBG_REGISTER(bv); - GCDBG_REGISTER(parser); - GCDBG_REGISTER(map); - GCDBG_REGISTER(buffer); - GCDBG_REGISTER(fill); - GCDBG_REGISTER(blit); - GCDBG_REGISTER(filter); - - GCLOCK_INIT(&gccontext->batchlock); - GCLOCK_INIT(&gccontext->bufferlock); - GCLOCK_INIT(&gccontext->fixuplock); - GCLOCK_INIT(&gccontext->maplock); - GCLOCK_INIT(&gccontext->callbacklock); - - INIT_LIST_HEAD(&gccontext->unmapvac); - INIT_LIST_HEAD(&gccontext->buffervac); - INIT_LIST_HEAD(&gccontext->fixupvac); - INIT_LIST_HEAD(&gccontext->batchvac); - INIT_LIST_HEAD(&gccontext->callbacklist); - INIT_LIST_HEAD(&gccontext->callbackvac); - - /* Initialize the filter cache. */ - for (i = 0; i < GC_FILTER_COUNT; i += 1) - for (j = 0; j < GC_TAP_COUNT; j += 1) - INIT_LIST_HEAD(&gccontext->filtercache[i][j].list); - - /* Query hardware caps. */ - gc_getcaps_wrapper(&gcicaps); - if (gcicaps.gcerror == GCERR_NONE) { - gccontext->gcmodel = gcicaps.gcmodel; - gccontext->gcrevision = gcicaps.gcrevision; - gccontext->gcdate = gcicaps.gcdate; - gccontext->gctime = gcicaps.gctime; - gccontext->gcfeatures = gcicaps.gcfeatures; - gccontext->gcfeatures0 = gcicaps.gcfeatures0; - gccontext->gcfeatures1 = gcicaps.gcfeatures1; - gccontext->gcfeatures2 = gcicaps.gcfeatures2; - gccontext->gcfeatures3 = gcicaps.gcfeatures3; - } -} - -void bv_exit(void) -{ - struct gccontext *gccontext = get_context(); - struct bvbuffmap *bvbuffmap; - struct list_head *head; - struct gcschedunmap *gcschedunmap; - struct gcbuffer *gcbuffer; - struct gcfixup *gcfixup; - struct gcbatch *gcbatch; - struct gccallbackinfo *gccallbackinfo; - - while (gccontext->buffmapvac != NULL) { - bvbuffmap = gccontext->buffmapvac; - gccontext->buffmapvac = bvbuffmap->nextmap; - gcfree(bvbuffmap); - } - - while (!list_empty(&gccontext->unmapvac)) { - head = gccontext->unmapvac.next; - gcschedunmap = list_entry(head, struct gcschedunmap, link); - list_del(head); - gcfree(gcschedunmap); - } - - while (!list_empty(&gccontext->buffervac)) { - head = gccontext->buffervac.next; - gcbuffer = list_entry(head, struct gcbuffer, link); - list_del(head); - gcfree(gcbuffer); - } - - while (!list_empty(&gccontext->fixupvac)) { - head = gccontext->fixupvac.next; - gcfixup = list_entry(head, struct gcfixup, link); - list_del(head); - gcfree(gcfixup); - } - - while (!list_empty(&gccontext->batchvac)) { - head = gccontext->batchvac.next; - gcbatch = list_entry(head, struct gcbatch, link); - list_del(head); - gcfree(gcbatch); - } - - while (!list_empty(&gccontext->callbacklist)) { - head = gccontext->callbacklist.next; - list_move(head, &gccontext->callbackvac); - } - - while (!list_empty(&gccontext->callbackvac)) { - head = gccontext->callbackvac.next; - gccallbackinfo = list_entry(head, struct gccallbackinfo, link); - list_del(head); - gcfree(gccallbackinfo); - } - - free_temp(false); -} - - -/******************************************************************************* - * Library API. - */ - -enum bverror bv_map(struct bvbuffdesc *bvbuffdesc) -{ - enum bverror bverror; - struct bvbuffmap *bvbuffmap; - - GCENTERARG(GCZONE_MAPPING, "bvbuffdesc = 0x%08X\n", - (unsigned int) bvbuffdesc); - - if (bvbuffdesc == NULL) { - BVSETERROR(BVERR_BUFFERDESC, "bvbuffdesc is NULL"); - goto exit; - } - - if (bvbuffdesc->structsize < STRUCTSIZE(bvbuffdesc, map)) { - BVSETERROR(BVERR_BUFFERDESC_VERS, "argument has invalid size"); - goto exit; - } - - bverror = do_map(bvbuffdesc, NULL, &bvbuffmap); - -exit: - GCEXITARG(GCZONE_MAPPING, "bv%s = %d\n", - (bverror == BVERR_NONE) ? "result" : "error", bverror); - return bverror; -} - -enum bverror bv_unmap(struct bvbuffdesc *bvbuffdesc) -{ - enum bverror bverror = BVERR_NONE; - enum bverror otherbverror = BVERR_NONE; - struct gccontext *gccontext = get_context(); - struct bvbuffmap *prev = NULL; - struct bvbuffmap *bvbuffmap; - struct bvbuffmapinfo *bvbuffmapinfo; - struct gcimap gcimap; - - GCENTERARG(GCZONE_MAPPING, "bvbuffdesc = 0x%08X\n", - (unsigned int) bvbuffdesc); - - /* Lock access to the mapping list. */ - GCLOCK(&gccontext->maplock); - - if (bvbuffdesc == NULL) { - BVSETERROR(BVERR_BUFFERDESC, "bvbuffdesc is NULL"); - goto exit; - } - - if (bvbuffdesc->structsize < STRUCTSIZE(bvbuffdesc, map)) { - BVSETERROR(BVERR_BUFFERDESC_VERS, "argument has invalid size"); - goto exit; - } - - /* Is the buffer mapped? */ - bvbuffmap = bvbuffdesc->map; - if (bvbuffmap == NULL) { - GCDBG(GCZONE_MAPPING, "buffer isn't mapped.\n"); - goto exit; - } - - /* Try to find our mapping. */ - while (bvbuffmap != NULL) { - if (bvbuffmap->bv_unmap == bv_unmap) - break; - prev = bvbuffmap; - bvbuffmap = bvbuffmap->nextmap; - } - - /* Are there other implementations? */ - if ((prev != NULL) || (bvbuffmap->nextmap != NULL)) { - GCDBG(GCZONE_MAPPING, - "have mappings from other implementations.\n"); - - /* Was our mapping found? */ - if (bvbuffmap == NULL) { - GCDBG(GCZONE_MAPPING, - "no mapping from our implementation.\n"); - - /* No, call other implementations. */ - bverror = bvbuffdesc->map->bv_unmap(bvbuffdesc); - goto exit; - } - - if (bvbuffmap->structsize - < STRUCTSIZE(bvbuffmap, nextmap)) { - BVSETERROR(BVERR_BUFFERDESC_VERS, - "unsupported bvbuffdesc version"); - goto exit; - } - - /* Remove our mapping. */ - if (prev == NULL) - bvbuffdesc->map = bvbuffmap->nextmap; - else - prev->nextmap = bvbuffmap->nextmap; - - /* Call other implementation. */ - otherbverror = bvbuffdesc->map->bv_unmap(bvbuffdesc); - - /* Add our mapping back. */ - bvbuffmap->nextmap = bvbuffdesc->map; - bvbuffdesc->map = bvbuffmap; - prev = NULL; - } else { - GCDBG(GCZONE_MAPPING, - "no mappings from other implementations.\n"); - } - - /* Get the info structure. */ - bvbuffmapinfo = (struct bvbuffmapinfo *) bvbuffmap->handle; - - GCDBG(GCZONE_MAPPING, "bvbuffmap = 0x%08X\n", (unsigned int) bvbuffmap); - GCDBG(GCZONE_MAPPING, "handle = 0x%08X\n", bvbuffmapinfo->handle); - - /* Explicit unmapping. */ - if (bvbuffmapinfo->usermap == 0) - GCERR("explicit count is already zero.\n"); - bvbuffmapinfo->usermap = 0; - - GCDBG(GCZONE_MAPPING, "explicit count = %d\n", - bvbuffmapinfo->usermap); - GCDBG(GCZONE_MAPPING, "implicit count = %d\n", - bvbuffmapinfo->automap); - - /* Do we have implicit mappings? */ - if (bvbuffmapinfo->automap > 0) { - GCDBG(GCZONE_MAPPING, "have implicit unmappings.\n"); - goto exit; - } - - /* Unmap the buffer. */ - memset(&gcimap, 0, sizeof(gcimap)); - gcimap.handle = bvbuffmapinfo->handle; - gc_unmap_wrapper(&gcimap); - if (gcimap.gcerror != GCERR_NONE) { - BVSETERROR(BVERR_OOM, "unable to free gccore memory"); - goto exit; - } - - /* Remove from the buffer descriptor list. */ - if (prev == NULL) - bvbuffdesc->map = bvbuffmap->nextmap; - else - prev->nextmap = bvbuffmap->nextmap; - - /* Invalidate the record. */ - bvbuffmap->structsize = 0; - - /* Add to the vacant list. */ - bvbuffmap->nextmap = gccontext->buffmapvac; - gccontext->buffmapvac = bvbuffmap; - -exit: - /* Unlock access to the mapping list. */ - GCUNLOCK(&gccontext->maplock); - - GCEXITARG(GCZONE_MAPPING, "bv%s = %d\n", - (bverror == BVERR_NONE) ? "result" : "error", bverror); - return bverror; -} - -enum bverror bv_blt(struct bvbltparams *bvbltparams) -{ - enum bverror bverror = BVERR_NONE; - struct gccontext *gccontext = get_context(); - struct gcalpha *gca = NULL; - struct gcalpha _gca; - unsigned int op, type, blend, format; - unsigned int batchexec = 0; - bool nop = false; - struct gcbatch *gcbatch; - struct bvrect *dstrect; - int src1used, src2used, maskused; - struct surfaceinfo srcinfo[2]; - struct bvrect *srcrect[2]; - unsigned short rop; - struct gcicommit gcicommit; - int i, srccount, res; - - GCENTERARG(GCZONE_BLIT, "bvbltparams = 0x%08X\n", - (unsigned int) bvbltparams); - - /* Verify blt parameters structure. */ - if (bvbltparams == NULL) { - BVSETERROR(BVERR_BLTPARAMS_VERS, "bvbltparams is NULL"); - goto exit; - } - - if (bvbltparams->structsize < STRUCTSIZE(bvbltparams, callbackdata)) { - BVSETERROR(BVERR_BLTPARAMS_VERS, "argument has invalid size"); - goto exit; - } - - /* Reset the error message. */ - bvbltparams->errdesc = NULL; - - /* Verify the destination parameters structure. */ - res = verify_surface(0, (union bvinbuff *) &bvbltparams->dstdesc, - bvbltparams->dstgeom); - if (res != -1) { - BVSETBLTSURFERROR(res, g_destsurferr); - goto exit; - } - - /* Extract the operation flags. */ - op = (bvbltparams->flags & BVFLAG_OP_MASK) >> BVFLAG_OP_SHIFT; - type = (bvbltparams->flags & BVFLAG_BATCH_MASK) >> BVFLAG_BATCH_SHIFT; - GCDBG(GCZONE_BLIT, "op = %d\n", op); - GCDBG(GCZONE_BLIT, "type = %d\n", type); - - switch (type) { - case (BVFLAG_BATCH_NONE >> BVFLAG_BATCH_SHIFT): - bverror = allocate_batch(bvbltparams, &gcbatch); - if (bverror != BVERR_NONE) { - bvbltparams->errdesc = gccontext->bverrorstr; - goto exit; - } - - batchexec = 1; - gcbatch->batchflags = 0x7FFFFFFF; - - GCDBG(GCZONE_BATCH, "BVFLAG_BATCH_NONE(0x%08X)\n", - (unsigned int) gcbatch); - break; - - case (BVFLAG_BATCH_BEGIN >> BVFLAG_BATCH_SHIFT): - bverror = allocate_batch(bvbltparams, &gcbatch); - if (bverror != BVERR_NONE) { - bvbltparams->errdesc = gccontext->bverrorstr; - goto exit; - } - - bvbltparams->batch = (struct bvbatch *) gcbatch; - - batchexec = 0; - bvbltparams->batchflags = - gcbatch->batchflags = 0x7FFFFFFF; - - GCDBG(GCZONE_BATCH, "BVFLAG_BATCH_BEGIN(0x%08X)\n", - (unsigned int) gcbatch); - break; - - case (BVFLAG_BATCH_CONTINUE >> BVFLAG_BATCH_SHIFT): - gcbatch = (struct gcbatch *) bvbltparams->batch; - if (gcbatch == NULL) { - BVSETBLTERROR(BVERR_BATCH, "batch is not initialized"); - goto exit; - } - - if (gcbatch->structsize < STRUCTSIZE(gcbatch, unmap)) { - BVSETBLTERROR(BVERR_BATCH, "invalid batch"); - goto exit; - } - - batchexec = 0; - gcbatch->batchflags = bvbltparams->batchflags; - - GCDBG(GCZONE_BATCH, "BVFLAG_BATCH_CONTINUE(0x%08X)\n", - (unsigned int) gcbatch); - break; - - case (BVFLAG_BATCH_END >> BVFLAG_BATCH_SHIFT): - gcbatch = (struct gcbatch *) bvbltparams->batch; - if (gcbatch == NULL) { - BVSETBLTERROR(BVERR_BATCH, "batch is not initialized"); - goto exit; - } - - if (gcbatch->structsize < STRUCTSIZE(gcbatch, unmap)) { - BVSETBLTERROR(BVERR_BATCH, "invalid batch"); - goto exit; - } - - batchexec = 1; - nop = (bvbltparams->batchflags & BVBATCH_ENDNOP) != 0; - gcbatch->batchflags = bvbltparams->batchflags; - - GCDBG(GCZONE_BATCH, "BVFLAG_BATCH_END(0x%08X)\n", - (unsigned int) gcbatch); - break; - - default: - BVSETBLTERROR(BVERR_BATCH, "unrecognized batch type"); - goto exit; - } - - GCDBG(GCZONE_BATCH, "batchflags=0x%08X\n", - (unsigned int) gcbatch->batchflags); - - if (!nop) { - /* Get a shortcut to the destination rectangle. */ - dstrect = &bvbltparams->dstrect; - - /* Verify the batch change flags. */ - GCVERIFYBATCH(gcbatch->batchflags >> 12, - &gcbatch->prevdstrect, dstrect); - - switch (op) { - case (BVFLAG_ROP >> BVFLAG_OP_SHIFT): - GCDBG(GCZONE_BLIT, "BVFLAG_ROP\n"); - - rop = bvbltparams->op.rop; - src1used = ((rop & 0xCCCC) >> 2) - ^ (rop & 0x3333); - src2used = ((rop & 0xF0F0) >> 4) - ^ (rop & 0x0F0F); - maskused = ((rop & 0xFF00) >> 8) - ^ (rop & 0x00FF); - break; - - case (BVFLAG_BLEND >> BVFLAG_OP_SHIFT): - GCDBG(GCZONE_BLIT, "BVFLAG_BLEND\n"); - - blend = bvbltparams->op.blend; - format = (blend & BVBLENDDEF_FORMAT_MASK) - >> BVBLENDDEF_FORMAT_SHIFT; - - bverror = parse_blend(bvbltparams, blend, &_gca); - if (bverror != BVERR_NONE) - goto exit; - - gca = &_gca; - - switch (format) { - case (BVBLENDDEF_FORMAT_CLASSIC - >> BVBLENDDEF_FORMAT_SHIFT): - src1used = gca->src1used; - src2used = gca->src2used; - maskused = blend & BVBLENDDEF_REMOTE; - break; - - default: - BVSETBLTERROR(BVERR_BLEND, - "unrecognized blend format"); - goto exit; - } - break; - - case (BVFLAG_FILTER >> BVFLAG_OP_SHIFT): - GCDBG(GCZONE_BLIT, "BVFLAG_FILTER\n"); - BVSETBLTERROR(BVERR_OP, - "filter operation not supported"); - goto exit; - - default: - BVSETBLTERROR(BVERR_OP, "unrecognized operation"); - goto exit; - } - - /* Reset the number of sources. */ - srccount = 0; - - /* Verify the src1 parameters structure. */ - if (src1used) { - GCDBG(GCZONE_SRC, "source #1: used\n"); - res = verify_surface( - bvbltparams->flags & BVBATCH_TILE_SRC1, - &bvbltparams->src1, bvbltparams->src1geom); - if (res != -1) { - BVSETBLTSURFERROR(res, g_src1surferr); - goto exit; - } - - /* Verify the batch change flags. */ - GCVERIFYBATCH(gcbatch->batchflags >> 14, - &gcbatch->prevsrc1rect, - &bvbltparams->src1rect); - - /* Same as the destination? */ - if (same_phys_area(bvbltparams->src1.desc, - &bvbltparams->src1rect, - bvbltparams->dstdesc, - dstrect)) { - GCDBG(GCZONE_BLIT, " same as destination\n"); - } else { - srcinfo[srccount].index = 0; - srcinfo[srccount].buf = bvbltparams->src1; - srcinfo[srccount].geom = bvbltparams->src1geom; - srcinfo[srccount].newgeom - = gcbatch->batchflags - & BVBATCH_SRC1; - srcinfo[srccount].newrect - = gcbatch->batchflags - & (BVBATCH_SRC1RECT_ORIGIN | - BVBATCH_SRC1RECT_SIZE); - srcrect[srccount] = &bvbltparams->src1rect; - - bverror = parse_source(bvbltparams, gcbatch, - &bvbltparams->src1rect, - &srcinfo[srccount]); - if (bverror != BVERR_NONE) - goto exit; - - srccount += 1; - } - } - - /* Verify the src2 parameters structure. */ - if (src2used) { - GCDBG(GCZONE_SRC, "source #2: used\n"); - res = verify_surface( - bvbltparams->flags & BVBATCH_TILE_SRC2, - &bvbltparams->src2, bvbltparams->src2geom); - if (res != -1) { - BVSETBLTSURFERROR(res, g_src2surferr); - goto exit; - } - - /* Verify the batch change flags. */ - GCVERIFYBATCH(gcbatch->batchflags >> 16, - &gcbatch->prevsrc2rect, - &bvbltparams->src2rect); - - /* Same as the destination? */ - if (same_phys_area(bvbltparams->src2.desc, - &bvbltparams->src2rect, - bvbltparams->dstdesc, - dstrect)) { - GCDBG(GCZONE_BLIT, " same as destination\n"); - } else { - srcinfo[srccount].index = 1; - srcinfo[srccount].buf = bvbltparams->src2; - srcinfo[srccount].geom = bvbltparams->src2geom; - srcinfo[srccount].newgeom - = gcbatch->batchflags - & BVBATCH_SRC2; - srcinfo[srccount].newrect - = gcbatch->batchflags - & (BVBATCH_SRC2RECT_ORIGIN | - BVBATCH_SRC2RECT_SIZE); - srcrect[srccount] = &bvbltparams->src2rect; - - bverror = parse_source(bvbltparams, gcbatch, - &bvbltparams->src2rect, - &srcinfo[srccount]); - if (bverror != BVERR_NONE) - goto exit; - - srccount += 1; - } - } - - /* Verify the mask parameters structure. */ - if (maskused) { - GCDBG(GCZONE_MASK, "mask: used\n"); - res = verify_surface( - bvbltparams->flags & BVBATCH_TILE_MASK, - &bvbltparams->mask, bvbltparams->maskgeom); - if (res != -1) { - BVSETBLTSURFERROR(res, g_masksurferr); - goto exit; - } - - /* Verify the batch change flags. */ - GCVERIFYBATCH(gcbatch->batchflags >> 18, - &gcbatch->prevmaskrect, - &bvbltparams->maskrect); - - BVSETBLTERROR(BVERR_OP, - "operation with mask not supported"); - goto exit; - } - - GCDBG(GCZONE_BLIT, "srccount = %d\n", srccount); - - if (srccount == 0) { - BVSETBLTERROR(BVERR_OP, - "operation not supported"); - goto exit; - } else { - for (i = 0; i < srccount; i += 1) { - int srcw, srch; - GCDBG(GCZONE_BLIT, - "processing source %d.\n", - srcinfo[i].index + 1); - - if (gca == NULL) { - GCDBG(GCZONE_BLIT, - " blending disabled.\n"); - srcinfo[i].rop = bvbltparams->op.rop; - srcinfo[i].gca = NULL; - } else if ((i + 1) != srccount) { - GCDBG(GCZONE_BLIT, - " disabling blending for " - "the first source.\n"); - srcinfo[i].rop = 0xCC; - srcinfo[i].gca = NULL; - } else { - GCDBG(GCZONE_BLIT, - " enabling blending.\n"); - srcinfo[i].rop = 0xCC; - srcinfo[i].gca = gca; - - if (srccount == 1) { - gca->srcconfig = gca->k1; - gca->dstconfig = gca->k2; - } else { - gca->srcconfig = gca->k2; - gca->dstconfig = gca->k1; - } - } - - GCDBG(GCZONE_BLIT, " srcsize %dx%d.\n", - srcrect[i]->width, srcrect[i]->height); - GCDBG(GCZONE_BLIT, " dstsize %dx%d.\n", - dstrect->width, dstrect->height); - - srcw = srcrect[i]->width; - srch = srcrect[i]->height; - if ((srcw == 1) && (srch == 1) && - (bvbltparams->src1.desc->virtaddr)) { - GCDBG(GCZONE_BLIT, " op: fill.\n"); - bverror = do_fill(bvbltparams, - gcbatch, - &srcinfo[i]); - } else if ((srcw == dstrect->width) && - (srch == dstrect->height)) { - GCDBG(GCZONE_BLIT, " op: bitblit.\n"); - bverror = do_blit(bvbltparams, - gcbatch, - &srcinfo[i]); - } else { - GCDBG(GCZONE_BLIT, " op: filter.\n"); - bverror = do_filter(bvbltparams, - gcbatch, - &srcinfo[i]); - } - - if (bverror != BVERR_NONE) - goto exit; - } - } - } - - if (batchexec) { - struct gcmoflush *flush; - - GCDBG(GCZONE_BLIT, "preparing to submit the batch.\n"); - - /* Finalize the current operation. */ - bverror = gcbatch->batchend(bvbltparams, gcbatch); - if (bverror != BVERR_NONE) - goto exit; - - /* Add PE flush. */ - GCDBG(GCZONE_BLIT, "appending the flush.\n"); - bverror = claim_buffer(bvbltparams, gcbatch, - sizeof(struct gcmoflush), - (void **) &flush); - if (bverror != BVERR_NONE) - goto exit; - - flush->flush_ldst = gcmoflush_flush_ldst; - flush->flush.reg = gcregflush_pe2D; - - /* Process asynchronous operation. */ - if ((bvbltparams->flags & BVFLAG_ASYNC) == 0) { - GCDBG(GCZONE_BLIT, "synchronous batch.\n"); - gcicommit.callback = NULL; - gcicommit.callbackparam = NULL; - gcicommit.asynchronous = false; - } else { - struct gccallbackinfo *gccallbackinfo; - - GCDBG(GCZONE_BLIT, "asynchronous batch (0x%08X):\n", - bvbltparams->flags); - - if (bvbltparams->callbackfn == NULL) { - GCDBG(GCZONE_BLIT, "no callback given.\n"); - gcicommit.callback = NULL; - gcicommit.callbackparam = NULL; - } else { - bverror = get_callbackinfo(&gccallbackinfo); - if (bverror != BVERR_NONE) { - BVSETBLTERROR(BVERR_OOM, - "callback allocation " - "failed"); - goto exit; - } - - gccallbackinfo->info.callback.fn - = bvbltparams->callbackfn; - gccallbackinfo->info.callback.data - = bvbltparams->callbackdata; - - gcicommit.callback = callbackbltsville; - gcicommit.callbackparam = gccallbackinfo; - - GCDBG(GCZONE_BLIT, - "gcbv_callback = 0x%08X\n", - (unsigned int) gcicommit.callback); - GCDBG(GCZONE_BLIT, - "gcbv_param = 0x%08X\n", - (unsigned int) gcicommit.callbackparam); - GCDBG(GCZONE_BLIT, - "bltsville_callback = 0x%08X\n", - (unsigned int) - gccallbackinfo->info.callback.fn); - GCDBG(GCZONE_BLIT, - "bltsville_param = 0x%08X\n", - (unsigned int) - gccallbackinfo->info.callback.data); - } - - gcicommit.asynchronous = true; - } - - /* Process scheduled unmappings. */ - do_unmap_implicit(gcbatch); - - INIT_LIST_HEAD(&gcicommit.unmap); - list_splice_init(&gcbatch->unmap, &gcicommit.unmap); - - /* Pass the batch for execution. */ - GCDUMPBATCH(gcbatch); - - gcicommit.gcerror = GCERR_NONE; - gcicommit.entrypipe = GCPIPE_2D; - gcicommit.exitpipe = GCPIPE_2D; - - INIT_LIST_HEAD(&gcicommit.buffer); - list_splice_init(&gcbatch->buffer, &gcicommit.buffer); - - GCDBG(GCZONE_BLIT, "submitting the batch.\n"); - gc_commit_wrapper(&gcicommit); - - /* Move the lists back to the batch. */ - list_splice_init(&gcicommit.buffer, &gcbatch->buffer); - list_splice_init(&gcicommit.unmap, &gcbatch->unmap); - - /* Error? */ - if (gcicommit.gcerror != GCERR_NONE) { - switch (gcicommit.gcerror) { - case GCERR_OODM: - case GCERR_CTX_ALLOC: - BVSETBLTERROR(BVERR_OOM, - "unable to allocate gccore " - "memory"); - goto exit; - default: - BVSETBLTERROR(BVERR_RSRC, - "gccore error"); - - goto exit; - } - } - - GCDBG(GCZONE_BLIT, "batch is submitted.\n"); - } - -exit: - if ((gcbatch != NULL) && batchexec) { - free_batch(gcbatch); - bvbltparams->batch = NULL; - } - - GCEXITARG(GCZONE_BLIT, "bv%s = %d\n", - (bverror == BVERR_NONE) ? "result" : "error", bverror); - return bverror; -} - -enum bverror bv_cache(struct bvcopparams *copparams) -{ - enum bverror bverror = BVERR_NONE; - unsigned int bytespp = 0; /* bytes per pixel */ - unsigned long vert_offset, horiz_offset; - unsigned int true_width, true_height; - - struct c2dmrgn rgn[3]; - int container_size = 0; - - unsigned long subsample; - unsigned long vendor; - unsigned long layout; - unsigned long size; - unsigned long container; - - subsample = copparams->geom->format & OCDFMTDEF_SUBSAMPLE_MASK; - vendor = copparams->geom->format & OCDFMTDEF_VENDOR_MASK; - layout = copparams->geom->format & OCDFMTDEF_LAYOUT_MASK; - size = copparams->geom->format & OCDFMTDEF_COMPONENTSIZEMINUS1_MASK; - container = copparams->geom->format & OCDFMTDEF_CONTAINER_MASK; - - if (vendor != OCDFMTDEF_VENDOR_ALL) { - bverror = BVERR_FORMAT; - goto exit; - } - - if (copparams->geom->orientation % 180 != 0) { - true_width = copparams->rect->height; - true_height = copparams->rect->width; - } else { - true_width = copparams->rect->width; - true_height = copparams->rect->height; - } - - switch (container) { - case OCDFMTDEF_CONTAINER_8BIT: - container_size = 8; - break; - - case OCDFMTDEF_CONTAINER_16BIT: - container_size = 16; - break; - - case OCDFMTDEF_CONTAINER_24BIT: - container_size = 24; - break; - - case OCDFMTDEF_CONTAINER_32BIT: - container_size = 32; - break; - - case OCDFMTDEF_CONTAINER_48BIT: - container_size = 48; - break; - - case OCDFMTDEF_CONTAINER_64BIT: - container_size = 64; - break; - } - - switch (layout) { - case OCDFMTDEF_PACKED: - switch (subsample) { - case OCDFMTDEF_SUBSAMPLE_NONE: - if (size >= 8) { - bytespp = container_size / 8; - } else { - GCERR("format not supported.\n"); - bverror = BVERR_FORMAT; - goto exit; - } - break; - - case OCDFMTDEF_SUBSAMPLE_422_YCbCr: - bytespp = (container_size / 2) / 8; - break; - - default: - bverror = BVERR_FORMAT; - goto exit; - } - - rgn[0].span = true_width * bytespp; - rgn[0].lines = true_height; - rgn[0].stride = copparams->geom->virtstride; - horiz_offset = copparams->rect->left * bytespp; - vert_offset = copparams->rect->top; - - rgn[0].start = (void *) ((unsigned long) - copparams->desc->virtaddr + - vert_offset * rgn[0].stride + - horiz_offset); - - gcbvcacheop(1, rgn, copparams->cacheop); - break; - - case OCDFMTDEF_2_PLANE_YCbCr: - /* 1 byte per pixel */ - rgn[0].span = true_width; - rgn[0].lines = true_height; - rgn[0].stride = copparams->geom->virtstride; - rgn[0].start = (void *) - ((unsigned long) copparams->desc->virtaddr + - copparams->rect->top * rgn[0].stride + - copparams->rect->left); - - rgn[1].span = true_width; - rgn[1].lines = true_height / 2; - rgn[1].stride = copparams->geom->virtstride; - rgn[1].start = rgn[0].start + - copparams->geom->height * rgn[0].stride; - - GCDBG(GCZONE_CACHE, - "virtaddr %p start[0] 0x%08x start[1] 0x%08x\n", - copparams->desc->virtaddr, rgn[0].start, rgn[1].start); - - gcbvcacheop(2, rgn, copparams->cacheop); - break; - - default: - GCERR("format 0x%x (%d) not supported.\n", - copparams->geom->format, copparams->geom->format); - bverror = BVERR_FORMAT; - break; - } - -exit: - if (bverror != BVERR_NONE) - GCERR("bverror = %d\n", bverror); - - return bverror; -} |