From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/gfxdrivers/cle266/uc_fifo.c | 198 ++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100755 Source/DirectFB/gfxdrivers/cle266/uc_fifo.c (limited to 'Source/DirectFB/gfxdrivers/cle266/uc_fifo.c') diff --git a/Source/DirectFB/gfxdrivers/cle266/uc_fifo.c b/Source/DirectFB/gfxdrivers/cle266/uc_fifo.c new file mode 100755 index 0000000..cc13433 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/cle266/uc_fifo.c @@ -0,0 +1,198 @@ +/* + Copyright (c) 2003 Andreas Robinson, All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. +*/ + +#include + +#include +#include + +#include + +#include "uc_fifo.h" + +//#define UC_FIFO_DUMP_DATA + +// Private functions --------------------------------------------------------- + +/** + * Pad the FIFO buffer to a 32 byte boundary. Used by uc_flush_agp(). + * @note Equivalent DRI code is in via_ioctl::viaFlushPrimsLocked() + */ + +static void uc_fifo_pad(struct uc_fifo* fifo) +{ + switch (fifo->used & 0x7) + { + case 0: + break; + case 2: + UC_FIFO_ADD(fifo, HALCYON_HEADER2); + UC_FIFO_ADD(fifo, HC_ParaType_NotTex << 16); + UC_FIFO_ADD(fifo, HC_DUMMY); + UC_FIFO_ADD(fifo, HC_DUMMY); + UC_FIFO_ADD(fifo, HC_DUMMY); + UC_FIFO_ADD(fifo, HC_DUMMY); + break; + case 4: + UC_FIFO_ADD(fifo, HALCYON_HEADER2); + UC_FIFO_ADD(fifo, HC_ParaType_NotTex << 16); + UC_FIFO_ADD(fifo, HC_DUMMY); + UC_FIFO_ADD(fifo, HC_DUMMY); + break; + case 6: + UC_FIFO_ADD(fifo, HALCYON_HEADER2); + UC_FIFO_ADD(fifo, HC_ParaType_NotTex << 16); + UC_FIFO_ADD(fifo, HC_DUMMY); + UC_FIFO_ADD(fifo, HC_DUMMY); + UC_FIFO_ADD(fifo, HC_DUMMY); + UC_FIFO_ADD(fifo, HC_DUMMY); + UC_FIFO_ADD(fifo, HC_DUMMY); + UC_FIFO_ADD(fifo, HC_DUMMY); + UC_FIFO_ADD(fifo, HC_DUMMY); + UC_FIFO_ADD(fifo, HC_DUMMY); + break; + default: + break; + } +} + +/** + * Manually write the FIFO buffer to the hardware. + * @note Equivalent DRI code is in via_ioctl::flush_sys() + */ + +void uc_fifo_flush_sys(struct uc_fifo* fifo, volatile void *regs) +{ + u32* p; + u32* q; + + volatile u32* hwregs = regs; + volatile u32* reg_tset = regs + VIA_REG_TRANSET; + volatile u32* reg_tspace = regs + VIA_REG_TRANSPACE; + + int check2Dcmd; + u32 addr; + + p = fifo->buf; + q = fifo->head; + check2Dcmd = 0; + + uc_fifo_pad(fifo); + +#ifdef UC_FIFO_DUMP_DATA + printf("Flushing FIFO ... \n"); +#endif + + while (p != q) { + + if (*p == HALCYON_HEADER2) { + p++; + check2Dcmd = !(*p == HALCYON_SUB_ADDR0); +#ifdef UC_FIFO_DUMP_DATA + printf("tset = 0x%08x\n", *p); +#endif + *reg_tset = *p; + p++; + } + else if (check2Dcmd && ((*p & HALCYON_HEADER1MASK) == HALCYON_HEADER1)) { + addr = (*p) & 0x0000001f; + p++; +#ifdef UC_FIFO_DUMP_DATA + printf("2D (0x%02x) = 0x%x\n", addr << 2, *p); +#endif + *(hwregs + addr) = *p; + p++; + } + else if ((*p & HALCYON_FIREMASK) == HALCYON_FIRECMD) { +#ifdef UC_FIFO_DUMP_DATA + printf("tspace = 0x%08x\n", *p); +#endif + *reg_tspace = *p; + p++; + + if ((p != q) && ((*p & HALCYON_FIREMASK) == HALCYON_FIRECMD)) + p++; + + if ((*p & HALCYON_CMDBMASK) != HC_ACMD_HCmdB) + check2Dcmd = 1; + } + else { +#ifdef UC_FIFO_DUMP_DATA + printf("tspace = 0x%08x\n", *p); +#endif + *reg_tspace = *p; + p++; + } + } + + fifo->head = fifo->buf; + fifo->used = 0; + fifo->prep = 0; +} + +/** Use an AGP transfer to write the FIFO buffer to the hardware. Not implemented. */ +#if 0 +static void uc_fifo_flush_agp(struct uc_fifo* fifo) +{ + // TODO - however, there is no point in doing this, because + // an AGP transfer can require more register writes than + // needed for drawing a single primitive. DirectFB needs to + // adopt a begin/end architecture first, like OpenGL has. + + fifo->head = fifo->buf; + fifo->used = 0; + fifo->prep = 0; +} +#endif + +// Public functions ---------------------------------------------------------- + +/** Create a FIFO. Returns NULL on failure. */ + +struct uc_fifo* uc_fifo_create(FusionSHMPoolShared *pool, size_t size) +{ + struct uc_fifo* fifo; + + size += 32; // Needed for padding. + + fifo = SHCALLOC(pool, 1, sizeof(struct uc_fifo)); + if (!fifo) return NULL; + + // Note: malloc won't work for DMA buffers... + + fifo->buf = SHMALLOC(pool, sizeof(u32) * size); + if (!(fifo->buf)) { + SHFREE(pool, fifo); + return NULL; + } + + fifo->head = fifo->buf; + fifo->used = 0; + fifo->size = (unsigned int) size; + fifo->prep = 0; + + //fifo->flush_sys = uc_fifo_flush_sys; + + //fifo->flush = uc_fifo_flush_sys; + + return fifo; +} + +/** Destroy a FIFO */ + +void uc_fifo_destroy(FusionSHMPoolShared *pool, struct uc_fifo* fifo) +{ + if (fifo) { + if (fifo->buf) { + SHFREE(pool, fifo->buf); + fifo->buf = NULL; + } + SHFREE(pool, fifo); + } +} -- cgit