summaryrefslogtreecommitdiff
path: root/Source/DirectFB/gfxdrivers/cle266/uc_hwset.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/gfxdrivers/cle266/uc_hwset.c')
-rwxr-xr-xSource/DirectFB/gfxdrivers/cle266/uc_hwset.c419
1 files changed, 419 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/cle266/uc_hwset.c b/Source/DirectFB/gfxdrivers/cle266/uc_hwset.c
new file mode 100755
index 0000000..8ba9d09
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/cle266/uc_hwset.c
@@ -0,0 +1,419 @@
+/*
+ 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 setting functions ------------------------------------------------
+
+#include <config.h>
+
+#include "uc_hw.h"
+#include <core/state.h>
+#include <core/palette.h>
+#include <gfx/convert.h>
+
+/// Integer 2-logarithm, y = log2(x), where x and y are integers.
+#define ILOG2(x,y) ILOG2_PORTABLE(x,y)
+
+#define ILOG2_PORTABLE(x,y) \
+ do { \
+ unsigned int i = 0; \
+ y = x; \
+ while (y != 0) { \
+ i++; \
+ y = y >> 1; \
+ } \
+ y = i-1; \
+ } while (0)
+
+#define ILOG2_X86(x,y) // TODO - use BSR (bit scan reverse) instruction
+
+/// Set alpha blending function (3D)
+void
+uc_set_blending_fn( UcDriverData *ucdrv,
+ UcDeviceData *ucdev,
+ CardState *state )
+{
+ struct uc_fifo *fifo = ucdrv->fifo;
+ struct uc_hw_alpha *hwalpha = &ucdev->hwalpha;
+
+ if (UC_IS_VALID( uc_blending_fn ))
+ return;
+
+ uc_map_blending_fn( hwalpha, state->src_blend, state->dst_blend,
+ state->destination->config.format );
+
+ UC_FIFO_PREPARE( fifo, 14 );
+ UC_FIFO_ADD_HDR( fifo, HC_ParaType_NotTex << 16 );
+
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HABLCsat, hwalpha->regHABLCsat );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HABLCop, hwalpha->regHABLCop );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HABLAsat, hwalpha->regHABLAsat );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HABLAop, hwalpha->regHABLAop );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HABLRCa, hwalpha->regHABLRCa );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HABLRFCa, hwalpha->regHABLRFCa );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HABLRCbias, hwalpha->regHABLRCbias );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HABLRCb, hwalpha->regHABLRCb );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HABLRFCb, hwalpha->regHABLRFCb );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HABLRAa, hwalpha->regHABLRAa );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HABLRAb, hwalpha->regHABLRAb );
+
+ UC_FIFO_PAD_EVEN( fifo );
+
+ UC_FIFO_CHECK( fifo );
+
+ UC_VALIDATE( uc_blending_fn );
+}
+
+/// Set texture environment (3D)
+void
+uc_set_texenv( UcDriverData *ucdrv,
+ UcDeviceData *ucdev,
+ CardState *state )
+{
+ struct uc_fifo *fifo = ucdrv->fifo;
+ struct uc_hw_texture *hwtex = &ucdev->hwtex;
+
+ if (UC_IS_VALID( uc_texenv ))
+ return;
+
+ uc_map_blitflags( hwtex, state->blittingflags, state->source->config.format );
+
+ // Texture mapping method
+ hwtex->regHTXnTB = HC_HTXnFLSs_Linear | HC_HTXnFLTs_Linear |
+ HC_HTXnFLSe_Linear | HC_HTXnFLTe_Linear;
+
+ hwtex->regHTXnMPMD = HC_HTXnMPMD_Sclamp | HC_HTXnMPMD_Tclamp;
+
+ UC_FIFO_PREPARE( fifo, 12 );
+ UC_FIFO_ADD_HDR( fifo, (HC_ParaType_Tex << 16) | (HC_SubType_Tex0 << 24) );
+
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnTB, hwtex->regHTXnTB );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnMPMD, hwtex->regHTXnMPMD );
+
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnTBLCsat, hwtex->regHTXnTBLCsat_0 );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnTBLCop, hwtex->regHTXnTBLCop_0 );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnTBLMPfog, hwtex->regHTXnTBLMPfog_0 );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnTBLAsat, hwtex->regHTXnTBLAsat_0 );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnTBLRCb, hwtex->regHTXnTBLRCb_0 );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnTBLRAa, hwtex->regHTXnTBLRAa_0 );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnTBLRFog, hwtex->regHTXnTBLRFog_0 );
+
+ UC_FIFO_PAD_EVEN( fifo );
+
+ UC_FIFO_CHECK( fifo );
+
+ UC_VALIDATE( uc_texenv );
+}
+
+/// Set clipping rectangle (2D and 3D)
+void
+uc_set_clip( UcDriverData *ucdrv,
+ UcDeviceData *ucdev,
+ CardState *state )
+{
+ struct uc_fifo *fifo = ucdrv->fifo;
+
+ if (DFB_REGION_EQUAL( ucdev->clip, state->clip ))
+ return;
+
+ UC_FIFO_PREPARE( fifo, 8 );
+ UC_FIFO_ADD_HDR( fifo, HC_ParaType_NotTex << 16 );
+
+#ifdef UC_ENABLE_3D
+
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HClipTB,
+ (RS12(state->clip.y1) << 12) | RS12(state->clip.y2+1) );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HClipLR,
+ (RS12(state->clip.x1) << 12) | RS12(state->clip.x2+1) );
+
+#endif
+
+ UC_FIFO_ADD_2D ( fifo, VIA_REG_CLIPTL,
+ (RS16(state->clip.y1) << 16) | RS16(state->clip.x1) );
+ UC_FIFO_ADD_2D ( fifo, VIA_REG_CLIPBR,
+ (RS16(state->clip.y2) << 16) | RS16(state->clip.x2) );
+
+ UC_FIFO_CHECK( fifo );
+
+ ucdev->clip = state->clip;
+}
+
+/// Set destination (2D and 3D)
+void
+uc_set_destination( UcDriverData *ucdrv,
+ UcDeviceData *ucdev,
+ CardState *state )
+{
+ struct uc_fifo *fifo = ucdrv->fifo;
+
+ CoreSurface *destination = state->destination;
+
+ DFBSurfacePixelFormat dst_format = destination->config.format;
+ int dst_offset = state->dst.offset;
+ int dst_pitch = state->dst.pitch;
+ int dst_bpp = DFB_BYTES_PER_PIXEL( dst_format );
+
+
+ /* Save FIFO space and CPU cycles. */
+ if (ucdev->dst_format == dst_format &&
+ ucdev->dst_offset == dst_offset &&
+ ucdev->dst_pitch == dst_pitch)
+ return;
+
+ // 2D engine setting
+
+ ucdev->pitch = (ucdev->pitch & 0x7fff) | (((dst_pitch >> 3) & 0x7fff) << 16);
+
+ UC_FIFO_PREPARE( fifo, 12 );
+ UC_FIFO_ADD_HDR( fifo, HC_ParaType_NotTex << 16 );
+
+
+ UC_FIFO_ADD_2D ( fifo, VIA_REG_PITCH, (VIA_PITCH_ENABLE | ucdev->pitch) );
+ UC_FIFO_ADD_2D ( fifo, VIA_REG_DSTBASE, (dst_offset >> 3) );
+ UC_FIFO_ADD_2D ( fifo, VIA_REG_GEMODE, (dst_bpp - 1) << 8 );
+
+#ifdef UC_ENABLE_3D
+ // 3D engine setting
+
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HDBBasL, dst_offset & 0xffffff );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HDBBasH, dst_offset >> 24 );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HDBFM, (uc_map_dst_format( dst_format ) |
+ (dst_pitch & HC_HDBPit_MASK) |
+ HC_HDBLoc_Local) );
+
+ UC_FIFO_PAD_EVEN(fifo);
+#endif
+
+ UC_FIFO_CHECK( fifo );
+
+ ucdev->dst_format = dst_format;
+ ucdev->dst_offset = dst_offset;
+ ucdev->dst_pitch = dst_pitch;
+}
+
+/// Set new source (2D)
+void
+uc_set_source_2d( UcDriverData *ucdrv,
+ UcDeviceData *ucdev,
+ CardState *state )
+{
+ struct uc_fifo *fifo = ucdrv->fifo;
+
+ if (UC_IS_VALID( uc_source2d ))
+ return;
+
+ ucdev->pitch &= 0x7fff0000;
+ ucdev->pitch |= (state->src.pitch >> 3) & 0x7fff;
+
+ UC_FIFO_PREPARE( fifo, 6 );
+ UC_FIFO_ADD_HDR( fifo, HC_ParaType_NotTex << 16 );
+
+ UC_FIFO_ADD_2D ( fifo, VIA_REG_SRCBASE, state->src.offset >> 3 );
+ UC_FIFO_ADD_2D ( fifo, VIA_REG_PITCH, VIA_PITCH_ENABLE | ucdev->pitch );
+
+ UC_FIFO_CHECK( fifo );
+
+ UC_VALIDATE( uc_source2d );
+}
+
+/// Set new source (3D)
+void
+uc_set_source_3d( UcDriverData *ucdrv,
+ UcDeviceData *ucdev,
+ CardState *state )
+{
+ struct uc_fifo *fifo = ucdrv->fifo;
+ struct uc_hw_texture *hwtex = &ucdev->hwtex;
+
+ CoreSurface *source = state->source;
+
+ int src_height, src_offset, src_pitch;
+
+ if (UC_IS_VALID( uc_source3d ))
+ return;
+
+ src_height = source->config.size.h;
+ src_offset = state->src.offset;
+ src_pitch = state->src.pitch;
+
+ /*
+ * TODO: Check if we can set the odd/even field as L1/L2 texture and select
+ * between L0/L1/L2 upon blit. Otherwise we depend on SMF_BLITTINGFLAGS ;(
+ */
+
+ if (state->blittingflags & DSBLIT_DEINTERLACE) {
+ if (source->field)
+ src_offset += src_pitch;
+
+ src_height >>= 1;
+ src_pitch <<= 1;
+ }
+
+ ucdev->field = source->field;
+
+ // Round texture size up to nearest
+ // value evenly divisible by 2^n
+
+ ILOG2(source->config.size.w, hwtex->we);
+ hwtex->l2w = 1 << hwtex->we;
+ if (hwtex->l2w < source->config.size.w) {
+ hwtex->we++;
+ hwtex->l2w <<= 1;
+ }
+
+ ILOG2(src_height, hwtex->he);
+ hwtex->l2h = 1 << hwtex->he;
+ if (hwtex->l2h < src_height) {
+ hwtex->he++;
+ hwtex->l2h <<= 1;
+ }
+
+ hwtex->format = uc_map_src_format_3d( source->config.format );
+
+ UC_FIFO_PREPARE( fifo, 10);
+
+ UC_FIFO_ADD_HDR( fifo, (HC_ParaType_Tex << 16) | (HC_SubType_Tex0 << 24));
+
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnFM, HC_HTXnLoc_Local | hwtex->format );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnL0OS, (0 << HC_HTXnLVmax_SHIFT) );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnL0_5WE, hwtex->we );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnL0_5HE, hwtex->he );
+
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnL012BasH, (src_offset >> 24) & 0xff );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnL0BasL, (src_offset ) & 0xffffff );
+ UC_FIFO_ADD_3D ( fifo, HC_SubA_HTXnL0Pit, (HC_HTXnEnPit_MASK | src_pitch) );
+
+ UC_FIFO_PAD_EVEN( fifo );
+
+ UC_FIFO_CHECK( fifo );
+
+ // Upload the palette of a 256 color texture.
+
+ if (hwtex->format == HC_HTXnFM_Index8) {
+ int i, num;
+ DFBColor *colors;
+
+ UC_FIFO_PREPARE( fifo, 258 );
+
+ UC_FIFO_ADD_HDR( fifo, ((HC_ParaType_Palette << 16) |
+ (HC_SubType_TexPalette0 << 24)) );
+
+ colors = source->palette->entries;
+ num = source->palette->num_entries;
+
+ if (num > 256)
+ num = 256;
+
+ /* What about the last entry? -- dok */
+ for (i = 0; i < num; i++)
+ UC_FIFO_ADD( fifo, PIXEL_ARGB(colors[i].a, colors[i].r,
+ colors[i].g, colors[i].b) );
+
+ for (; i < 256; i++)
+ UC_FIFO_ADD( fifo, 0 );
+
+ UC_FIFO_CHECK( fifo );
+ }
+
+ UC_VALIDATE( uc_source3d );
+}
+
+/// Set either destination color key, or fill color, as needed. (2D)
+void
+uc_set_color_2d( UcDriverData *ucdrv,
+ UcDeviceData *ucdev,
+ CardState *state )
+{
+ struct uc_fifo *fifo = ucdrv->fifo;
+ u32 color = 0;
+
+ if (UC_IS_VALID( uc_color2d ))
+ return;
+
+ switch (state->destination->config.format) {
+ case DSPF_ARGB1555:
+ color = PIXEL_ARGB1555( state->color.a,
+ state->color.r,
+ state->color.g,
+ state->color.b );
+ color |= color << 16;
+ break;
+
+ case DSPF_RGB16:
+ color = PIXEL_RGB16( state->color.r,
+ state->color.g,
+ state->color.b);
+ color |= color << 16;
+ break;
+
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ color = PIXEL_ARGB( state->color.a,
+ state->color.r,
+ state->color.g,
+ state->color.b );
+ break;
+
+ default:
+ D_BUG( "unexpected pixel format" );
+ }
+
+
+ UC_FIFO_PREPARE( fifo, 8 );
+ UC_FIFO_ADD_HDR( fifo, HC_ParaType_NotTex << 16 );
+
+ // Opaque line drawing needs this
+ UC_FIFO_ADD_2D( fifo, VIA_REG_MONOPAT0, 0xff );
+
+ UC_FIFO_ADD_2D( fifo, VIA_REG_KEYCONTROL, 0 );
+ UC_FIFO_ADD_2D( fifo, VIA_REG_FGCOLOR, color );
+
+ UC_FIFO_CHECK( fifo );
+
+ UC_VALIDATE( uc_color2d );
+ UC_INVALIDATE( uc_colorkey2d );
+}
+
+void
+uc_set_colorkey_2d( UcDriverData *ucdrv,
+ UcDeviceData *ucdev,
+ CardState *state )
+{
+ struct uc_fifo *fifo = ucdrv->fifo;
+
+ if (UC_IS_VALID( uc_colorkey2d ))
+ return;
+
+ if (state->blittingflags & DSBLIT_SRC_COLORKEY) {
+ UC_FIFO_PREPARE( fifo, 6 );
+ UC_FIFO_ADD_HDR( fifo, HC_ParaType_NotTex << 16 );
+
+ UC_FIFO_ADD_2D ( fifo, VIA_REG_KEYCONTROL, VIA_KEY_ENABLE_SRCKEY );
+ UC_FIFO_ADD_2D ( fifo, VIA_REG_BGCOLOR, state->src_colorkey );
+ }
+ else if (state->blittingflags & DSBLIT_DST_COLORKEY) {
+ UC_FIFO_PREPARE( fifo, 6 );
+ UC_FIFO_ADD_HDR( fifo, HC_ParaType_NotTex << 16 );
+
+ UC_FIFO_ADD_2D ( fifo, VIA_REG_KEYCONTROL,
+ VIA_KEY_ENABLE_DSTKEY | VIA_KEY_INVERT_KEY );
+ UC_FIFO_ADD_2D ( fifo, VIA_REG_FGCOLOR, state->dst_colorkey );
+ }
+ else {
+ UC_FIFO_PREPARE( fifo, 4 );
+ UC_FIFO_ADD_HDR( fifo, HC_ParaType_NotTex << 16 );
+
+ UC_FIFO_ADD_2D ( fifo, VIA_REG_KEYCONTROL, 0 );
+ }
+
+ UC_FIFO_CHECK( fifo );
+
+ UC_VALIDATE( uc_colorkey2d );
+ UC_INVALIDATE( uc_color2d );
+}
+