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/unichrome/uc_hwmap.c | 362 ++++++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100755 Source/DirectFB/gfxdrivers/unichrome/uc_hwmap.c (limited to 'Source/DirectFB/gfxdrivers/unichrome/uc_hwmap.c') diff --git a/Source/DirectFB/gfxdrivers/unichrome/uc_hwmap.c b/Source/DirectFB/gfxdrivers/unichrome/uc_hwmap.c new file mode 100755 index 0000000..fe1dc73 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/unichrome/uc_hwmap.c @@ -0,0 +1,362 @@ +/* + 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. +*/ + +// Hardware mapping functions ------------------------------------------------ + +#include + +#include "uc_hw.h" +#include + +/// Map DirectFB blending functions to hardware +void +uc_map_blending_fn( struct uc_hw_alpha *hwalpha, + DFBSurfaceBlendFunction sblend, + DFBSurfaceBlendFunction dblend, + DFBSurfacePixelFormat dst_format ) +{ + bool dst_alpha = DFB_PIXELFORMAT_HAS_ALPHA(dst_format); + + // The HW's blending equation is: + // (Ca * FCa + Cbias + Cb * FCb) << Cshift + + // Set source blending function + + // Ca -- always from source color. + hwalpha->regHABLCsat = HC_HABLCsat_MASK | HC_HABLCa_OPC | HC_HABLCa_Csrc; + // Aa -- always from source alpha. + hwalpha->regHABLAsat = HC_HABLAsat_MASK | HC_HABLAa_OPA | HC_HABLAa_Asrc; + + // FCa and FAa depend on the following condition. + switch (sblend) { + case DSBF_ZERO: + // GL_ZERO -- (0, 0, 0, 0) + hwalpha->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_HABLRCa; + hwalpha->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_HABLFRA; + hwalpha->regHABLRFCa = 0x0; + hwalpha->regHABLRAa = 0x0; + break; + + case DSBF_ONE: + // GL_ONE -- (1, 1, 1, 1) + hwalpha->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_HABLRCa; + hwalpha->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_HABLFRA; + hwalpha->regHABLRFCa = 0x0; + hwalpha->regHABLRAa = 0x0; + break; + + case DSBF_SRCCOLOR: + // GL_SRC_COLOR -- (Rs, Gs, Bs, As) + hwalpha->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_Csrc; + hwalpha->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_Asrc; + break; + + case DSBF_INVSRCCOLOR: + // GL_ONE_MINUS_SRC_COLOR -- (1, 1, 1, 1) - (Rs, Gs, Bs, As) + hwalpha->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_Csrc; + hwalpha->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_Asrc; + break; + + case DSBF_SRCALPHA: + // GL_SRC_ALPHA -- (As, As, As, As) + hwalpha->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_Asrc; + hwalpha->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_Asrc; + break; + + case DSBF_INVSRCALPHA: + // GL_ONE_MINUS_SRC_ALPHA -- (1, 1, 1, 1) - (As, As, As, As) + hwalpha->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_Asrc; + hwalpha->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_Asrc; + break; + + case DSBF_DESTALPHA: + // GL_DST_ALPHA + if (!dst_alpha) { // (1, 1, 1, 1) + hwalpha->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_HABLRCa; + hwalpha->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_HABLFRA; + hwalpha->regHABLRFCa = 0x0; + hwalpha->regHABLRAa = 0x0; + } + else { // (Ad, Ad, Ad, Ad) + hwalpha->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_Adst; + hwalpha->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_Adst; + } + break; + + case DSBF_INVDESTALPHA: + // GL_ONE_MINUS_DST_ALPHA + if (!dst_alpha) { // (1, 1, 1, 1) - (1, 1, 1, 1) = (0, 0, 0, 0) + hwalpha->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_HABLRCa; + hwalpha->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_HABLFRA; + hwalpha->regHABLRFCa = 0x0; + hwalpha->regHABLRAa = 0x0; + } + else { // (1, 1, 1, 1) - (Ad, Ad, Ad, Ad) + hwalpha->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_Adst; + hwalpha->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_Adst; + } + break; + + case DSBF_DESTCOLOR: + // GL_DST_COLOR -- (Rd, Gd, Bd, Ad) + hwalpha->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_Cdst; + hwalpha->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_Adst; + break; + + case DSBF_INVDESTCOLOR: + // GL_ONE_MINUS_DST_COLOR -- (1, 1, 1, 1) - (Rd, Gd, Bd, Ad) + hwalpha->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_Cdst; + hwalpha->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_Adst; + break; + + case DSBF_SRCALPHASAT: + // GL_SRC_ALPHA_SATURATE + if (!dst_alpha) { + // (f, f, f, 1), f = min(As, 1 - Ad) = min(As, 1 - 1) = 0 + // So (f, f, f, 1) = (0, 0, 0, 1) + hwalpha->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_HABLRCa; + hwalpha->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_HABLFRA; + hwalpha->regHABLRFCa = 0x0; + hwalpha->regHABLRAa = 0x0; + } + else { + // (f, f, f, 1), f = min(As, 1 - Ad) + hwalpha->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_mimAsrcInvAdst; + hwalpha->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_HABLFRA; + hwalpha->regHABLRFCa = 0x0; + hwalpha->regHABLRAa = 0x0; + } + break; + + default: + break; + } + + // Set destination blending function + + // Op is add. + // bias is 0. + + hwalpha->regHABLCsat |= HC_HABLCbias_HABLRCbias; + hwalpha->regHABLAsat |= HC_HABLAbias_HABLRAbias; + + // Cb -- always from destination color. + hwalpha->regHABLCop = HC_HABLCb_OPC | HC_HABLCb_Cdst; + // Ab -- always from destination alpha. + hwalpha->regHABLAop = HC_HABLAb_OPA | HC_HABLAb_Adst; + + // FCb -- depends on the following condition. + switch (dblend) { + case DSBF_ZERO: + // GL_ZERO -- (0, 0, 0, 0) + hwalpha->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_HABLRCb; + hwalpha->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_HABLFRA; + hwalpha->regHABLRFCb = 0x0; + hwalpha->regHABLRAb = 0x0; + break; + + case DSBF_ONE: + // GL_ONE -- (1, 1, 1, 1) + hwalpha->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_HABLRCb; + hwalpha->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_HABLFRA; + hwalpha->regHABLRFCb = 0x0; + hwalpha->regHABLRAb = 0x0; + break; + + case DSBF_SRCCOLOR: + // GL_SRC_COLOR -- (Rs, Gs, Bs, As) + hwalpha->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_Csrc; + hwalpha->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_Asrc; + break; + + case DSBF_INVSRCCOLOR: + // GL_ONE_MINUS_SRC_COLOR -- (1, 1, 1, 1) - (Rs, Gs, Bs, As) + hwalpha->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_Csrc; + hwalpha->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_Asrc; + break; + + case DSBF_SRCALPHA: + // GL_SRC_ALPHA -- (As, As, As, As) + hwalpha->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_Asrc; + hwalpha->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_Asrc; + break; + + case DSBF_INVSRCALPHA: + // GL_ONE_MINUS_SRC_ALPHA -- (1, 1, 1, 1) - (As, As, As, As) + hwalpha->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_Asrc; + hwalpha->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_0; + break; + + case DSBF_DESTALPHA: + // GL_DST_ALPHA + if (!dst_alpha) { // (1, 1, 1, 1) + hwalpha->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_HABLRCb; + hwalpha->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_HABLFRA; + hwalpha->regHABLRFCb = 0x0; + hwalpha->regHABLRAb = 0x0; + } + else { // (Ad, Ad, Ad, Ad) + hwalpha->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_Adst; + hwalpha->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_Adst; + } + break; + + case DSBF_INVDESTALPHA: + // GL_ONE_MINUS_DST_ALPHA + if (!dst_alpha) { // (1, 1, 1, 1) - (1, 1, 1, 1) = (0, 0, 0, 0) + hwalpha->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_HABLRCb; + hwalpha->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_HABLFRA; + hwalpha->regHABLRFCb = 0x0; + hwalpha->regHABLRAb = 0x0; + } + else { // (1, 1, 1, 1) - (Ad, Ad, Ad, Ad) + hwalpha->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_Adst; + hwalpha->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_Adst; + } + break; + + case DSBF_DESTCOLOR: + // GL_DST_COLOR -- (Rd, Gd, Bd, Ad) + hwalpha->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_Cdst; + hwalpha->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_Adst; + break; + + case DSBF_INVDESTCOLOR: + // GL_ONE_MINUS_DST_COLOR -- (1, 1, 1, 1) - (Rd, Gd, Bd, Ad) + hwalpha->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_Cdst; + hwalpha->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_Adst; + break; + + case DSBF_SRCALPHASAT: + // Unsupported? + + default: + hwalpha->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_HABLRCb; + hwalpha->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_HABLFRA; + hwalpha->regHABLRFCb = 0x0; + hwalpha->regHABLRAb = 0x0; + break; + } +} + +/// Map DFBSurfaceBlittingFlags to the hardware +void +uc_map_blitflags( struct uc_hw_texture *tex, + DFBSurfaceBlittingFlags bflags, + DFBSurfacePixelFormat sformat, + DFBSurfacePixelFormat dformat ) +{ + bool gotalpha = DFB_PIXELFORMAT_HAS_ALPHA(sformat); + bool invalpha = DFB_PIXELFORMAT_INV_ALPHA(sformat) || + (!DFB_PIXELFORMAT_INV_ALPHA(sformat) && DFB_PIXELFORMAT_INV_ALPHA(dformat)); + + if (bflags & DSBLIT_COLORIZE) { + // Cv0 = Ct*Cf + + // Hw setting: + // Ca = Ct, Cb = Cf, Cop = +, Cc = 0, Cbias = 0, Cshift = No. + + tex->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK | + HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_Tex | + HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_Dif | + HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0; + tex->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add | + HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_0 | + HC_HTXnTBLCshift_No; + tex->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_0; + } + else { + // Cv0 = Ct + + // Hw setting: + // Ca = 0, Cb = 0, Cop = +, Cc = 0, Cbias = Ct, Cshift = No. + + tex->regHTXnTBLCsat_0 = HC_HTXnTBLCsat_MASK | + HC_HTXnTBLCa_TOPC | HC_HTXnTBLCa_0 | + HC_HTXnTBLCb_TOPC | HC_HTXnTBLCb_0 | + HC_HTXnTBLCc_TOPC | HC_HTXnTBLCc_0; + tex->regHTXnTBLCop_0 = HC_HTXnTBLCop_Add | + HC_HTXnTBLCbias_Cbias | HC_HTXnTBLCbias_Tex | + HC_HTXnTBLCshift_No; + tex->regHTXnTBLMPfog_0 = HC_HTXnTBLMPfog_0; + } + + if (bflags & DSBLIT_BLEND_COLORALPHA) { + if ((bflags & DSBLIT_BLEND_ALPHACHANNEL) && gotalpha) { + // Av0 = At*Af + + // Hw setting: + // Aa = At, Ab = Af, Cop = +, Ac = 0, Abias = 0, Ashift = No. + + tex->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK | + HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_Atex | + HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_Adif | + HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA; + tex->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add | + HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No; + tex->regHTXnTBLRAa_0 = 0x0; + tex->regHTXnTBLRFog_0 = 0x0; + } + else { + // (!(bflags & DSBLIT_BLEND_ALPHACHANNEL) && gotalpha) || !gotalpha + // Av0 = Af + + // Hw setting: + // Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = Af, Ashift = No. + + tex->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK | + HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA | + HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA | + HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA; + tex->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add | + HC_HTXnTBLAbias_Adif | HC_HTXnTBLAshift_No; + tex->regHTXnTBLRAa_0 = 0x0; + tex->regHTXnTBLRFog_0 = 0x0; + } + } + else { // !(bflags & DSBLIT_BLEND_COLORALPHA) + if (gotalpha && ((bflags & DSBLIT_BLEND_ALPHACHANNEL) || invalpha)) { + // Av0 = At + + // Hw setting: + // Aa = 0, Ab = 0, Cop = +, Ac = 0, Abias = At, Ashift = No. + + tex->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK | + HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA | + HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA | + HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA; + tex->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add | + HC_HTXnTBLAbias_Atex | HC_HTXnTBLAshift_No; + if (invalpha) + tex->regHTXnTBLCop_0 |= HC_HTXnTBLAbias_Inv; + tex->regHTXnTBLRAa_0 = 0x0; + tex->regHTXnTBLRFog_0 = 0x0; + } + else { // !gotalpha + // Av0 = 1.0 + + // D_BUG warning: I'm guessing where values should go, + // and how big (0xff = 1.0 ?) it should be. + + // Hw setting: + // Aa = 1.0, Ab = 1.0, Cop = -, Ac = 1.0, Abias = 1.0, Ashift = No. + // => Av = Aa*(Ab-Ac) + Abias = 1*(1-1)+1 = 1 + + tex->regHTXnTBLAsat_0 = HC_HTXnTBLAsat_MASK | + HC_HTXnTBLAa_TOPA | HC_HTXnTBLAa_HTXnTBLRA | + HC_HTXnTBLAb_TOPA | HC_HTXnTBLAb_HTXnTBLRA | + HC_HTXnTBLAc_TOPA | HC_HTXnTBLAc_HTXnTBLRA; + tex->regHTXnTBLCop_0 |= HC_HTXnTBLAop_Add | + HC_HTXnTBLAbias_Inv | HC_HTXnTBLAbias_HTXnTBLRAbias | HC_HTXnTBLAshift_No; + tex->regHTXnTBLRAa_0 = 0x0; + tex->regHTXnTBLRFog_0 = 0x0; + } + } +} + -- cgit