summaryrefslogtreecommitdiff
path: root/Source/DirectFB/gfxdrivers/unichrome/uc_hwmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/gfxdrivers/unichrome/uc_hwmap.c')
-rwxr-xr-xSource/DirectFB/gfxdrivers/unichrome/uc_hwmap.c362
1 files changed, 362 insertions, 0 deletions
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 <config.h>
+
+#include "uc_hw.h"
+#include <gfx/convert.h>
+
+/// 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;
+ }
+ }
+}
+