mirror of
https://github.com/phabrics/Run-Sun3-SunOS-4.1.1.git
synced 2026-04-29 11:02:59 -04:00
2601 lines
108 KiB
Bash
2601 lines
108 KiB
Bash
#! /bin/sh
|
|
|
|
# $Id: fb-xlat-auto.sh,v 1.12 2009/08/30 21:51:53 fredette Exp $
|
|
|
|
# generic/fb-xlat-auto.sh - automatically generates C code
|
|
# for many framebuffer translation functions:
|
|
|
|
#
|
|
# Copyright (c) 2003, 2005 Matt Fredette
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. 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.
|
|
# 3. All advertising materials mentioning features or use of this software
|
|
# must display the following acknowledgement:
|
|
# This product includes software developed by Matt Fredette.
|
|
# 4. The name of the author may not be used to endorse or promote products
|
|
# derived from this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
|
#
|
|
|
|
# this script generates one or more C functions. each function
|
|
# translates an image from a source image format into a destination
|
|
# image format, optionally halving or doubling the image size in the
|
|
# process.
|
|
#
|
|
# the source and destination image formats are represented by "keys",
|
|
# strings that describe the different attributes of a format.
|
|
#
|
|
# a source image format key has the form: WxHdDbBsSpPoO[cC][mMS][_rR_gG_bB][_X]
|
|
#
|
|
# a destination image format key has the form: dDbBsSpPoO[mM][_rR_gG_bB]
|
|
#
|
|
# all of the lowercase letters and underscores are literals, and all
|
|
# of the uppercase letters represent attribute values. the different
|
|
# attributes are:
|
|
#
|
|
# W is the width of the source image. if zero, the generated function
|
|
# will be able to translate source images of any width, but it will be
|
|
# suboptimal. if nonzero, the generated function will only be able to
|
|
# translate source images of that width, but it will have some
|
|
# optimization. this attribute is only used in source keys, since the
|
|
# destination width is always the scaled source width.
|
|
#
|
|
# H is the height of the source image. if zero, the generated
|
|
# function will be able to translate source images of any height, but
|
|
# it will be suboptimal. if nonzero, the generated function will only
|
|
# be able to translate source images of that height, but it will have
|
|
# some optimization. this attribute is only used in source keys,
|
|
# since the destination height is always the scaled source height.
|
|
#
|
|
# D is the color (d)epth, in bits, of the source/destination image.
|
|
# if zero, the generated function will be able to handle
|
|
# source/destination images of any depth, but it will be suboptimal.
|
|
# if nonzero, the generated function will only be able to handle
|
|
# source/destination images of that depth, but it will have some
|
|
# optimization.
|
|
#
|
|
# B is the (b)its-per-pixel of the source/destination image. this
|
|
# must be at least as large as the depth, and it may be larger. if
|
|
# zero, the generated function will be able to handle
|
|
# source/destination images of any bits-per-pixel, but it will be
|
|
# suboptimal. if nonzero, the generated function will only be able to
|
|
# handle source/destination images of that bits-per-pixel, but it will
|
|
# have some optimization.
|
|
#
|
|
# S is the (s)kip-x-bits of the source/destination image. this is the
|
|
# number of bits at the beginning of each image scanline that are not
|
|
# displayed. if an underscore, the generated function will be able to
|
|
# handle source/destination images with any skip-x-bits, but it will
|
|
# be suboptimal. if not an underscore, the generated function will
|
|
# only be able to handle source/destination images with that many
|
|
# skip-x-bits, but it will have some optimization.
|
|
#
|
|
# P is the (p)adding of the source/destination image. this is how
|
|
# many bits each image scanline is padded to. if zero, the generated
|
|
# function will be able to handle source/destination images with any
|
|
# padding, but it will be suboptimal. if nonzero, the generated
|
|
# function will only be able to handle source/destination images with
|
|
# that padding, but it will have some optimization.
|
|
#
|
|
# O is the byte and bit (o)rder of the source/destination image. this
|
|
# is always m or l for most- or least-significant, respectively.
|
|
# there is no "any" wildcard value. this script cannot handle image
|
|
# formats where a word-unit of pixels has one order for its bytes in
|
|
# memory, but the opposite order for its pixels within the word-unit.
|
|
#
|
|
# C is the optional class. it is 'm' for a monochrome (grayscale) image,
|
|
# and 'c' for a color image. if not given, an image with a depth of
|
|
# one is considered monochrome, and any other image is considered color.
|
|
#
|
|
# M is the optional mapping type. it is 'l' for a monochrome image
|
|
# that linearly maps pixels into intensities and for a color image
|
|
# that linearly maps pixel subfields into intensities. it is 'i' for
|
|
# images that index pixels or pixel subfields into intensities. if
|
|
# not given, monochrome images and color images with subfields are
|
|
# assumed to be linear, and color images without subfields are assumed
|
|
# to be indexed.
|
|
#
|
|
# S is the optional mapping size. if the mapping type is given, this
|
|
# must be given, and it is the size of the mapping range - i.e., the
|
|
# number of bits per intensity. if the mapping type is not given, and
|
|
# the image is linearly mapped monochrome, the mapping size is assumed
|
|
# to be the same as the image depth.
|
|
#
|
|
# R, G, and B are the optional subfield masks. if an image's pixels
|
|
# can be decomposed into subfields for red, green, and blue, these are
|
|
# the masks for the subfields.
|
|
#
|
|
# X is the optional scaling. it is `h' to halve the source image,
|
|
# or `d' to double it. this attribute is only used in source keys.
|
|
|
|
# this script generates a set of functions for the product of all
|
|
# source image formats and all destination image formats.
|
|
#
|
|
# "all source image formats" includes all source image formats given
|
|
# on the command line, plus:
|
|
#
|
|
# the "any" source image format, unscaled
|
|
# the "any" source image format, halved
|
|
# the "any" source image format, doubled
|
|
#
|
|
# "all destination image formats" includes all destination
|
|
# image formats given on the command line, plus:
|
|
#
|
|
# the "any" destination image format
|
|
#
|
|
src_all=
|
|
dst_all=
|
|
for order in m l; do
|
|
src_key="0x0d0b0s_p0o${order}_r0x0_g0x0_b0x0"
|
|
src_all="${src_all} ${src_key} ${src_key}_h ${src_key}_d"
|
|
dst_all="${dst_all} d0b0s_p0o${order}_r0x0_g0x0_b0x0"
|
|
done
|
|
|
|
which=
|
|
for arg
|
|
do
|
|
case $arg in
|
|
src|dst) which=$arg ;;
|
|
*)
|
|
if test "x${which}" != x; then
|
|
eval "${which}_all=\"$arg \$${which}_all\""
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
|
|
PROG=`basename $0`
|
|
cat <<EOF
|
|
/* automatically generated by $PROG, do not edit! */
|
|
|
|
/*
|
|
* Copyright (c) 2003, 2005 Matt Fredette
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. 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.
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed by Matt Fredette.
|
|
* 4. The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
|
*/
|
|
|
|
_TME_RCSID("\$Id: fb-xlat-auto.sh,v 1.12 2009/08/30 21:51:53 fredette Exp $");
|
|
|
|
/* the central feature of these translation functions is the "bit
|
|
FIFO", a first-in, first-out stream of bits. source bit FIFOs are
|
|
used to read pixel bits out of source images, and destination bit
|
|
FIFOs are used to write pixel bits into destination images.
|
|
|
|
a bit FIFO has a visible part and an invisible part.
|
|
|
|
the visible part of a bit FIFO is 32 bits wide, meaning the
|
|
translation code can read (for a source bit FIFO) or write (for a
|
|
destination bit FIFO) up to 32 bits of pixel data before a bit
|
|
FIFO shift.
|
|
|
|
the invisible part of a source bit FIFO contains pixel bits that
|
|
have already been read from the source image memory, but that have
|
|
yet to be shifted in to the visible part.
|
|
|
|
the invisible part of a destination bit FIFO contains the pixel
|
|
bits that have been shifted out of the visible part, but that have
|
|
yet to be written to the destination image memory.
|
|
|
|
depending on various attributes of an image format, it may be
|
|
possible for the translation code to always read or write the
|
|
entire 32 visible bits of a bit FIFO at a time, and as a result
|
|
always shift the bit FIFO 32 bits at a time. this is desirable
|
|
because it minimizes bit FIFO shifts.
|
|
|
|
when this does happen, it may also be the case that the visible
|
|
part of the bit FIFO always perfectly corresponds to an aligned
|
|
32-bit word in the image buffer.
|
|
|
|
this is the optimal situation, as it makes it unnecessary to track
|
|
the invisible part in C local variables at all - each 32-bit FIFO
|
|
shift of a source bit FIFO just reads the next 32-bit word directly
|
|
into the visible part, and each 32-bit FIFO shift of a destination
|
|
bit FIFO just writes the next 32-bit word directly out of the
|
|
visible part.
|
|
|
|
within the visible part of a bit FIFO, which bits belong to which
|
|
pixels depends on the "order" of the image format. most-significant
|
|
(big-endian) images have earlier (more to the left on the screen)
|
|
pixels in more-significant bit positions. least-significant
|
|
(little-endian) images have earlier pixels in less-significant bit
|
|
bit positions.
|
|
|
|
bit significance *within* a pixel never depends on image order.
|
|
once the bits belonging to a pixel have been identified according
|
|
to image order, the least significant bit in that pixel's value is
|
|
always the bit with the least absolute value.
|
|
|
|
some pictures may help explain this better. each picture shows the
|
|
32 bit visible part of a bit FIFO, with the bits marked from 0
|
|
(least significant) to 31 (most significant). all of these
|
|
examples are for a two-bit-deep/two-bits-per-pixel image, and in
|
|
the visible part sixteen pixels are numbered. lesser numbered
|
|
pixels are earlier (more to the left on the screen). some of the
|
|
invisible part is also shown, along with the direction that the bit
|
|
FIFO shifts in:
|
|
|
|
a source bit FIFO for a little-endian source image with two bits
|
|
per pixel looks like:
|
|
|
|
|
|
|
| 31 30 29 28 7 6 5 4 3 2 1 0
|
|
--+--+--+--+--+--+|+--+--+--+--+- --+--+--+--+--+--+--+--+
|
|
.. p18 | p17 | p16 ||| p15 | p14 | .. p3 | p2 | p1 | p0 |
|
|
--+--+--+--+--+--+|+--+--+--+--+- --+--+--+--+--+--+--+--+
|
|
|
|
|
invisible part | visible part
|
|
|
|
shift -> shift -> shift -> shift -> shift ->
|
|
|
|
a source bit FIFO for a big-endian source image with two bits per
|
|
pixel looks like:
|
|
|
|
|
|
|
31 30 29 28 27 26 25 26 4 3 2 1 0 |
|
|
+--+--+--+--+--+--+--+-- -+--+--+--+--+|+--+--+--+--+--+--
|
|
| p0 | p1 | p2 | p3 .. | p14 | p15 ||| p16 | p17 | p18 ..
|
|
+--+--+--+--+--+--+--+-- -+--+--+--+--+|+--+--+--+--+--+--
|
|
|
|
|
visible part | invisible part
|
|
|
|
<- shift <- shift <- shift <- shift <- shift
|
|
|
|
a destination bit FIFO for a little-endian destination image with
|
|
two bits per pixel looks like:
|
|
|
|
|
|
|
31 30 29 28 27 26 25 26 4 3 2 1 0 |
|
|
+--+--+--+--+--+--+--+-- -+--+--+--+--+|+--+--+--+--+--+--
|
|
| p23 | p22 | p21 | p20 .. | p9 | p8 ||| p7 | p6 | p5 ..
|
|
+--+--+--+--+--+--+--+-- -+--+--+--+--+|+--+--+--+--+--+--
|
|
|
|
|
visible part | invisible part
|
|
|
|
shift -> shift -> shift -> shift -> shift ->
|
|
|
|
a destination bit FIFO for a big-endian destination image with
|
|
two bits per pixel looks like:
|
|
|
|
|
|
|
| 31 30 29 28 7 6 5 4 3 2 1 0
|
|
--+--+--+--+--+--+|+--+--+--+--+- --+--+--+--+--+--+--+--+
|
|
.. p5 | p6 | p7 ||| p8 | p9 | .. p20 | p21 | p22 | p23 |
|
|
--+--+--+--+--+--+|+--+--+--+--+- --+--+--+--+--+--+--+--+
|
|
|
|
|
invisible part | visible part
|
|
|
|
<- shift <- shift <- shift <- shift <- shift
|
|
|
|
each translation function has at least one source bit FIFO and at
|
|
least one destination bit FIFO. the general idea is to read source
|
|
pixel value(s) from the source image, map those source pixel
|
|
value(s) somehow into destination pixel value(s), and write those
|
|
destination pixel value(s) to the destination image.
|
|
|
|
translation functions that do not scale the image have exactly one
|
|
source bit FIFO and exactly one destination bit FIFO. one pixel
|
|
read from the source bit FIFO becomes one pixel written to the
|
|
destination bit FIFO.
|
|
|
|
translation functions that halve the image size have two source bit
|
|
FIFOs and one destination bit FIFO. one source bit FIFO sources
|
|
bits from an even-numbered scanline, and the other sources bits from
|
|
an odd-numbered scanline. four pixels read from the source bit
|
|
FIFOs - two from each source bit FIFO, making a 2x2 square - become
|
|
one pixel written to the destination bit FIFO.
|
|
|
|
translation functions that double the image size have one source
|
|
bit FIFO and two destination bit FIFOs. one destination bit FIFO
|
|
sinks bits for an even-numbered scanline, and the other sinks bits
|
|
for an odd-numbered scanline. one pixel read from the source bit
|
|
FIFO becomes four pixels written to the destination bit FIFOs -
|
|
two to each destination bit FIFO, making a 2x2 square.
|
|
|
|
translation functions don't necessarily always translate the entire
|
|
source image into the entire destination image. instead, the buffer
|
|
holding the current source image is expected to be twice as large as
|
|
necessary (plus some overhead), with the second half of the buffer
|
|
holding a copy of the last translated ("old") source image.
|
|
|
|
before setting up and translating pixels using bit FIFOs, a
|
|
translation function treats the the current and old source images as
|
|
an array of aligned 32-bit words and compares them. if it finds no
|
|
32-bit word that has changed, no translation is done and the
|
|
function returns.
|
|
|
|
otherwise, initial source pixel x and y coordinates are derived from
|
|
the offset of the 32-bit word that failed comparison, and the source
|
|
primary bit FIFO is primed. if this translation function halves the
|
|
image size, the source secondary bit FIFO is primed from the same x
|
|
coordinate on the "other" (think y ^ 1) scanline.
|
|
|
|
then, initial destination pixel x and y coordinates are derived from
|
|
the initial source x and y coordinates, and the destination primary
|
|
bit FIFO is primed. if this translation function doubles the image
|
|
size, the destination secondary bit FIFO is primed from the same x
|
|
coordinate on the "other" (think y ^ 1) scanline.
|
|
|
|
as mentioned previously, the buffer holding the current source image
|
|
is expected to be twice as large as necessary (plus some overhead),
|
|
with the second half of the buffer holding a copy of the last
|
|
translated ("old") source image.
|
|
|
|
this "overhead" is approximately two extra scanlines worth of data,
|
|
that is initialized to all-bits-zero and must always remain zero.
|
|
this extra data is present at the end of both the current ("new")
|
|
and last translated ("old") source images.
|
|
|
|
these extra, always-blank scanlines guarantee that the pixel
|
|
translation loop terminates. the pixel translation loop *never*
|
|
checks for the end of the image buffer. instead, it terminates only
|
|
after it has read in TME_FB_XLAT_RUN consecutive aligned 32-bit
|
|
words that have *not* changed between the new and old source images.
|
|
this small amount of extra memory overhead simplifies the pixel
|
|
translation loop, because it doesn't have to worry about going past
|
|
the end of the actual image.
|
|
*/
|
|
|
|
|
|
/* macros: */
|
|
|
|
/* given a 32-bit aligned pointer into the current source image, this
|
|
returns the corresponding 32-bit aligned pointer in the last
|
|
translated ("old") source image. since the old source image
|
|
follows the current source image, this is simple pointer arithmetic
|
|
using src_bypb: */
|
|
#define TME_FB_XLAT_SRC_OLD(raw) \\
|
|
((tme_uint32_t *) (((tme_uint8_t *) (raw)) + src_bypb))
|
|
|
|
/* when the fast, aligned 32-bit word comparison loop finds a word
|
|
that has changed in the source image, pixels are translated until
|
|
TME_FB_XLAT_RUN consecutive aligned 32-bit words are processed that
|
|
have *not* changed in the source image, at which point the fast
|
|
comparison loop resumes.
|
|
|
|
the idea is that after you've started translating pixels, once the
|
|
FIFO shift operation has read TME_FB_XLAT_RUN consecutive raw,
|
|
unchanged 32-bit words, all of the pixels from previous, changed
|
|
32-bit words have been translated and shifted out of the source bit
|
|
FIFO(s), and all bits remaining in the source bit FIFO(s) are for
|
|
pixels in those unchanged 32-bit words. since the pixels are
|
|
unchanged, pixel translation can stop, and the entire state of the
|
|
source bit FIFO(s) can be discarded.
|
|
|
|
so, each time a raw, changed 32-bit word is read, xlat_run is
|
|
reloaded with TME_FB_XLAT_RUN, and each time 32 bits worth of
|
|
source image pixels are processed, it is decremented. when it
|
|
reaches zero, the source bit FIFO(s) are discarded, the destination
|
|
bit FIFO(s) are flushed, the pixel translation loop breaks and the
|
|
fast comparison loop continues: */
|
|
#define TME_FB_XLAT_RUN (2)
|
|
|
|
/* this shifts a source FIFO: */
|
|
#define TME_FB_XLAT_SHIFT_SRC(unaligned, fifo, next, bits, shift, raw, order)\\
|
|
do { \\
|
|
\\
|
|
/* if the source FIFO may not be 32-bit aligned: */ \\
|
|
if (unaligned) { \\
|
|
\\
|
|
/* we must be shifting between 1 and 32 bits: */ \\
|
|
assert ((shift) >= 1 && (shift) <= 32); \\
|
|
\\
|
|
/* the FIFO must have more than 32 bits in it already: */ \\
|
|
assert (bits > 32); \\
|
|
\\
|
|
/* shift the FIFO: */ \\
|
|
if ((shift) == 32) { \\
|
|
fifo = next; \\
|
|
} \\
|
|
else if (order == TME_ENDIAN_BIG) { \\
|
|
fifo = (fifo << ((shift) & 31)) | (next >> (32 - (shift)));\\
|
|
next <<= ((shift) & 31); \\
|
|
} \\
|
|
else { \\
|
|
fifo = (fifo >> ((shift) & 31)) | (next << (32 - (shift)));\\
|
|
next >>= ((shift) & 31); \\
|
|
} \\
|
|
bits -= (shift); \\
|
|
\\
|
|
/* if we have a new 32-bit word to read: */ \\
|
|
if (bits <= 32) { \\
|
|
next = *raw; \\
|
|
if (*TME_FB_XLAT_SRC_OLD(raw) != next) { \\
|
|
*TME_FB_XLAT_SRC_OLD(raw) = next; \\
|
|
xlat_run = TME_FB_XLAT_RUN; \\
|
|
} \\
|
|
raw++; \\
|
|
next = (order == TME_ENDIAN_BIG \\
|
|
? tme_betoh_u32(next) \\
|
|
: tme_letoh_u32(next)); \\
|
|
\\
|
|
/* before the load, if there were fewer than 32 bits \\
|
|
remaining in the FIFO, shift bits from the word \\
|
|
we just loaded into their proper positions: */ \\
|
|
if (bits < 32) { \\
|
|
if (order == TME_ENDIAN_BIG) { \\
|
|
fifo |= (next >> bits); \\
|
|
next <<= (32 - bits); \\
|
|
} \\
|
|
else { \\
|
|
fifo |= (next << bits); \\
|
|
next >>= (32 - bits); \\
|
|
} \\
|
|
} \\
|
|
\\
|
|
/* there are now 32 more bits in the FIFO: */ \\
|
|
bits += 32; \\
|
|
} \\
|
|
} \\
|
|
\\
|
|
/* otherwise, if the source FIFO is always 32-bit aligned: */ \\
|
|
else { \\
|
|
\\
|
|
/* we must be shifting exactly 32 bits: */ \\
|
|
assert((shift) == 32); \\
|
|
\\
|
|
/* load the next 32-bit word: */ \\
|
|
fifo = *raw; \\
|
|
if (*TME_FB_XLAT_SRC_OLD(raw) != fifo) { \\
|
|
*TME_FB_XLAT_SRC_OLD(raw) = fifo; \\
|
|
xlat_run = TME_FB_XLAT_RUN; \\
|
|
} \\
|
|
raw++; \\
|
|
fifo = (order == TME_ENDIAN_BIG \\
|
|
? tme_betoh_u32(fifo) \\
|
|
: tme_letoh_u32(fifo)); \\
|
|
} \\
|
|
} while (/* CONSTCOND */ 0)
|
|
|
|
/* this shifts a destination FIFO: */
|
|
#define TME_FB_XLAT_SHIFT_DST(unaligned, fifo, next, bits, shift, raw, order)\\
|
|
do { \\
|
|
\\
|
|
/* if the destination FIFO may not be 32-bit aligned: */ \\
|
|
if (unaligned) { \\
|
|
\\
|
|
/* we must be shifting between 1 and 32 bits: */ \\
|
|
assert ((shift) >= 1 && (shift) <= 32); \\
|
|
\\
|
|
/* the FIFO must have fewer than 32 bits in it: */ \\
|
|
assert (bits < 32); \\
|
|
\\
|
|
/* shift the FIFO: */ \\
|
|
if (order == TME_ENDIAN_BIG) { \\
|
|
next |= (fifo >> bits); \\
|
|
fifo <<= (32 - bits); \\
|
|
} \\
|
|
else { \\
|
|
next |= (fifo << bits); \\
|
|
fifo >>= (32 - bits); \\
|
|
} \\
|
|
if (SHIFTMAX_INT32_T < 32 && bits == 0) { \\
|
|
fifo = 0; \\
|
|
} \\
|
|
bits += (shift); \\
|
|
\\
|
|
/* if we have a completed 32-bit word to write: */ \\
|
|
if (bits >= 32) { \\
|
|
*(raw++) = (order == TME_ENDIAN_BIG \\
|
|
? tme_htobe_u32(next) \\
|
|
: tme_htole_u32(next)); \\
|
|
bits -= 32; \\
|
|
assert(bits != 0 || fifo == 0); \\
|
|
next = fifo; \\
|
|
} \\
|
|
} \\
|
|
\\
|
|
/* the destination FIFO is always 32-bit aligned: */ \\
|
|
else { \\
|
|
\\
|
|
/* we must be shifting exactly 32 bits: */ \\
|
|
assert((shift) == 32); \\
|
|
\\
|
|
/* store the next 32-bit word: */ \\
|
|
*(raw++) = (order == TME_ENDIAN_BIG \\
|
|
? tme_htobe_u32(fifo) \\
|
|
: tme_htole_u32(fifo)); \\
|
|
\\
|
|
} \\
|
|
\\
|
|
/* clear the writable part of the FIFO: */ \\
|
|
fifo = 0; \\
|
|
} while (/* CONSTCOND */ 0)
|
|
|
|
/* _TME_FB_XLAT_MAP_LINEAR_SCALE gives the factor needed to scale a
|
|
masked value up or down to a given size in bits. for example, if a
|
|
value's mask is 0xf800 (a five bit mask), and the value needs to be
|
|
scaled up to seven bits, this gives an factor of four. if a
|
|
value's mask is 0x7e0 (a six bit mask), and the value needs to be
|
|
scaled down to three bits, this gives a factor of eight: */
|
|
#define _TME_FB_XLAT_MAP_LINEAR_SCALE(mask_in, mask_out) \\
|
|
(TME_FB_XLAT_MAP_BASE_MASK(mask_in) \\
|
|
^ TME_FB_XLAT_MAP_BASE_MASK(mask_out))
|
|
#define TME_FB_XLAT_MAP_LINEAR_SCALE(mask_in, mask_out) \\
|
|
(_TME_FB_XLAT_MAP_LINEAR_SCALE(mask_in, mask_out) \\
|
|
? (TME_FB_XLAT_MAP_BASE_MASK(_TME_FB_XLAT_MAP_LINEAR_SCALE(mask_in, mask_out))\\
|
|
+ 1) \\
|
|
: 1)
|
|
|
|
/* this linearly maps a value from one mask to another: */
|
|
#define _TME_FB_XLAT_MAP_LINEAR(value, mask_in, mask_out) \\
|
|
\\
|
|
/* if the value does not need to be scaled up: */ \\
|
|
(((TME_FB_XLAT_MAP_BASE_MASK(mask_out) \\
|
|
<= TME_FB_XLAT_MAP_BASE_MASK(mask_in)) \\
|
|
? \\
|
|
\\
|
|
/* extract the value and scale it down: */ \\
|
|
(TME_FIELD_MASK_EXTRACTU(value, mask_in) \\
|
|
/ TME_FB_XLAT_MAP_LINEAR_SCALE(mask_in, mask_out)) \\
|
|
\\
|
|
/* otherwise, the value needs to be scaled up: */ \\
|
|
: \\
|
|
\\
|
|
/* extract the value: */ \\
|
|
((TME_FIELD_MASK_EXTRACTU(value, mask_in) \\
|
|
\\
|
|
/* scale it up: */ \\
|
|
* TME_FB_XLAT_MAP_LINEAR_SCALE(mask_in, mask_out)) \\
|
|
\\
|
|
/* if the least significant bit of the value is set, add \\
|
|
in the scale minus one. this makes the linear mapping \\
|
|
at least cover the entire range: */ \\
|
|
+ (((value / \\
|
|
_TME_FIELD_MASK_FACTOR(mask_in)) \\
|
|
& 1) \\
|
|
* (TME_FB_XLAT_MAP_LINEAR_SCALE(mask_in, mask_out) \\
|
|
- 1)))) \\
|
|
\\
|
|
/* finally, shift the value into position: */ \\
|
|
* _TME_FIELD_MASK_FACTOR(mask_out))
|
|
|
|
/* this indexes a value: */
|
|
#define _TME_FB_XLAT_MAP_INDEX(value, mask_out, index) \\
|
|
\\
|
|
/* intensities are either stored as 8 or 16 bits: */ \\
|
|
(((TME_FB_XLAT_MAP_BASE_MASK(mask_out) <= 0xff) \\
|
|
? ((const tme_uint8_t *) (index))[(value)] \\
|
|
: ((const tme_uint16_t *) (index))[(value)]) \\
|
|
\\
|
|
/* shift the value into position: */ \\
|
|
* _TME_FIELD_MASK_FACTOR(mask_out))
|
|
|
|
/* this maps one subfield or intensity value into another subfield or
|
|
intensity value: */
|
|
#define TME_FB_XLAT_MAP(value, mask_in, mask_out, indexed, index)\\
|
|
\\
|
|
/* do the linear mapping or the index mapping: */ \\
|
|
((!(indexed)) \\
|
|
? _TME_FB_XLAT_MAP_LINEAR(value, mask_in, mask_out) \\
|
|
: _TME_FB_XLAT_MAP_INDEX(TME_FIELD_MASK_EXTRACTU(value, mask_in), mask_out, index))
|
|
EOF
|
|
|
|
# the next function number:
|
|
xlat_next=0
|
|
xlat_array=
|
|
|
|
# permute over the source possibilities:
|
|
for src_key in ${src_all}; do
|
|
|
|
# take apart the source possibility:
|
|
src_parts=${src_key}
|
|
|
|
# get the width:
|
|
width=`echo ${src_parts} | sed -e 's/^\([0-9][0-9]*\)\(.*\)$/\1/'`
|
|
src_parts=`echo ${src_parts} | sed -e 's/^\([0-9][0-9]*\)\(.*\)$/\2/'`
|
|
|
|
# get the height:
|
|
height=`echo ${src_parts} | sed -e 's/^x\([0-9][0-9]*\)\(.*\)$/\1/'`
|
|
src_parts=`echo ${src_parts} | sed -e 's/^x\([0-9][0-9]*\)\(.*\)$/\2/'`
|
|
|
|
# get the source depth:
|
|
src_depth=`echo ${src_parts} | sed -e 's/^d\([0-9][0-9]*\)\(.*\)$/\1/'`
|
|
src_parts=`echo ${src_parts} | sed -e 's/^d\([0-9][0-9]*\)\(.*\)$/\2/'`
|
|
|
|
# get the source bits per pixel:
|
|
src_bipp=`echo ${src_parts} | sed -e 's/^b\([0-9][0-9]*\)\(.*\)$/\1/'`
|
|
src_parts=`echo ${src_parts} | sed -e 's/^b\([0-9][0-9]*\)\(.*\)$/\2/'`
|
|
|
|
# get the source skip pixel count:
|
|
src_skipx=`echo ${src_parts} | sed -e 's/^s\([_0-9][0-9]*\)\(.*\)$/\1/'`
|
|
src_parts=`echo ${src_parts} | sed -e 's/^s\([_0-9][0-9]*\)\(.*\)$/\2/'`
|
|
|
|
# get the source scanline pad:
|
|
src_pad=`echo ${src_parts} | sed -e 's/^p\([0-9][0-9]*\)\(.*\)$/\1/'`
|
|
src_parts=`echo ${src_parts} | sed -e 's/^p\([0-9][0-9]*\)\(.*\)$/\2/'`
|
|
|
|
# get the source "order" - i.e., byte order and leftmost (first)
|
|
# pixel significance:
|
|
src_order=`echo ${src_parts} | sed -e 's/^o\([ml]\)\(.*\)$/\1/'`
|
|
src_parts=`echo ${src_parts} | sed -e 's/^o\([ml]\)\(.*\)$/\2/'`
|
|
|
|
# get the optional source "class" - monochrome or color:
|
|
src_class=`echo ${src_parts} | sed -e 's/^c\([mc]\)\(.*\)$/\1/'`
|
|
if test "x${src_class}" = "x${src_parts}"; then src_class= ; fi
|
|
src_parts=`echo ${src_parts} | sed -e 's/^c\([mc]\)\(.*\)$/\2/'`
|
|
|
|
# get the optional source pixel mapping - linear or indexed, and
|
|
# the optional number of bits in the map range:
|
|
src_map=`echo ${src_parts} | sed -e 's/^m\([li]\)\([0-9]*\)\(.*\)$/\1/'`
|
|
src_map_bits=`echo ${src_parts} | sed -e 's/^m\([li]\)\([0-9]*\)\(.*\)$/\2/'`
|
|
if test "x${src_map}" = "x${src_parts}"; then src_map= ; src_map_bits= ; fi
|
|
src_parts=`echo ${src_parts} | sed -e 's/^m\([li]\)\([0-9]*\)\(.*\)$/\3/'`
|
|
|
|
# get the optional source pixel subfield masks:
|
|
src_mask_g= ; src_mask_r= ; src_mask_b=
|
|
while true; do
|
|
src_mask=`echo ${src_parts} | sed -e 's/^\(_[rgb]\)\(0x[0-9A-Fa-f][0-9A-Fa-f]*\)\(.*\)$/src_mask\1=\2/'`
|
|
if test "x${src_mask}" = "x${src_parts}"; then break; fi
|
|
eval ${src_mask}
|
|
src_parts=`echo ${src_parts} | sed -e 's/^\(_[rgb]\)\(0x[0-9A-Fa-f][0-9A-Fa-f]*\)\(.*\)$/\3/'`
|
|
done
|
|
|
|
# get the source scaling:
|
|
scale="${src_parts}_"
|
|
|
|
# if the source class is not given, but the source depth is
|
|
# known, assume monochrome if the source depth is one, else
|
|
# assume color:
|
|
#
|
|
if test "x${src_class}" = x; then
|
|
case "${src_depth}" in
|
|
0) src_class= ;;
|
|
1) src_class=m ;;
|
|
*) src_class=c ;;
|
|
esac
|
|
fi
|
|
|
|
# if the source mapping type is not given:
|
|
#
|
|
if test "x${src_map}" = x; then
|
|
|
|
# if the source class is known as color:
|
|
#
|
|
if test "x${src_class}" = "xc"; then
|
|
|
|
# if it is known that there are not any subfield masks, assume an indexed
|
|
# mapping, else if it is known that there are subfield masks, assume a
|
|
# linear mapping:
|
|
#
|
|
case "x${src_mask_r}" in
|
|
x0x0) ;;
|
|
x) src_map=i ;;
|
|
*) src_map=l ;;
|
|
esac
|
|
|
|
# if the source class is known as monochrome:
|
|
#
|
|
elif test "x${src_class}" = "xm"; then
|
|
|
|
# assume a linear mapping:
|
|
#
|
|
src_map=l
|
|
fi
|
|
fi
|
|
|
|
# if the size of the source mapping range in bits is not given:
|
|
#
|
|
if test "x${src_map_bits}" = x; then
|
|
|
|
# if the source class is known as mono and the source mapping
|
|
# type is known as linear, assume that the source depth is the
|
|
# size of the mapping range in bits:
|
|
#
|
|
if test "x${src_class}" = xm && test "x${src_map}" = xl; then
|
|
src_map_bits=${src_depth}
|
|
|
|
# otherwise, set the size of the mapping range to zero to indicate
|
|
# unknown:
|
|
#
|
|
else
|
|
src_map_bits=0
|
|
fi
|
|
fi
|
|
|
|
# permute over the destination possibilities:
|
|
for dst_key in ${dst_all}; do
|
|
|
|
# take apart the destination possibility:
|
|
dst_parts=${dst_key}
|
|
|
|
# get the destination depth:
|
|
dst_depth=`echo ${dst_parts} | sed -e 's/^d\([0-9][0-9]*\)\(.*\)$/\1/'`
|
|
dst_parts=`echo ${dst_parts} | sed -e 's/^d\([0-9][0-9]*\)\(.*\)$/\2/'`
|
|
|
|
# get the destination bits per pixel:
|
|
dst_bipp=`echo ${dst_parts} | sed -e 's/^b\([0-9][0-9]*\)\(.*\)$/\1/'`
|
|
dst_parts=`echo ${dst_parts} | sed -e 's/^b\([0-9][0-9]*\)\(.*\)$/\2/'`
|
|
|
|
# get the destination skip pixel count:
|
|
dst_skipx=`echo ${dst_parts} | sed -e 's/^s\([_0-9][0-9]*\)\(.*\)$/\1/'`
|
|
dst_parts=`echo ${dst_parts} | sed -e 's/^s\([_0-9][0-9]*\)\(.*\)$/\2/'`
|
|
|
|
# get the destination scanline pad:
|
|
dst_pad=`echo ${dst_parts} | sed -e 's/^p\([0-9][0-9]*\)\(.*\)$/\1/'`
|
|
dst_parts=`echo ${dst_parts} | sed -e 's/^p\([0-9][0-9]*\)\(.*\)$/\2/'`
|
|
|
|
# get the destination "order" - i.e., byte order and leftmost
|
|
# (first) pixel significance:
|
|
dst_order=`echo ${dst_parts} | sed -e 's/^o\([ml]\)\(.*\)$/\1/'`
|
|
dst_parts=`echo ${dst_parts} | sed -e 's/^o\([ml]\)\(.*\)$/\2/'`
|
|
|
|
# get the optional destination pixel mapping - linear or indexed:
|
|
dst_map=`echo ${dst_parts} | sed -e 's/^m\([li]\)\(.*\)$/\1/'`
|
|
if test "x${dst_map}" = "x${dst_parts}"; then dst_map= ; fi
|
|
dst_parts=`echo ${dst_parts} | sed -e 's/^m\([li]\)\(.*\)$/\2/'`
|
|
|
|
# get the optional destination pixel subfield masks:
|
|
dst_mask_g= ; dst_mask_r= ; dst_mask_b=
|
|
while true; do
|
|
dst_mask=`echo ${dst_parts} | sed -e 's/^\(_[rgb]\)\(0x[0-9A-Fa-f][0-9A-Fa-f]*\)\(.*\)$/dst_mask\1=\2/'`
|
|
if test "x${dst_mask}" = "x${dst_parts}"; then break; fi
|
|
eval ${dst_mask}
|
|
dst_parts=`echo ${dst_parts} | sed -e 's/^\(_[rgb]\)\(0x[0-9A-Fa-f][0-9A-Fa-f]*\)\(.*\)$/\3/'`
|
|
done
|
|
|
|
# allocate the xlat number:
|
|
xlat=${xlat_next}
|
|
xlat_next=`expr ${xlat_next} + 1`
|
|
xlat_info="tme_fb_xlat${xlat}"
|
|
|
|
# start the function:
|
|
echo ""
|
|
echo "/* this translates frame buffer contents from this source format:"
|
|
case "${width}x${height}" in
|
|
0x0) echo -n " any dimensions" ;;
|
|
*x0) echo -n " width $width, any height" ;;
|
|
0x*) echo -n " any width, height ${height}" ;;
|
|
*) echo -n " ${width}x${height}" ;;
|
|
esac
|
|
xlat_info="${xlat_info}, ${width}, ${height}"
|
|
case ${scale} in
|
|
_h_) echo " (image will be halved)" ; value="HALF" ;;
|
|
_d_) echo " (image will be doubled)" ; value="DOUBLE" ;;
|
|
*) echo "" ; value="NONE" ;;
|
|
esac
|
|
xlat_info="${xlat_info}, TME_FB_XLAT_SCALE_${value}"
|
|
echo -n " "
|
|
case ${src_depth} in
|
|
0) echo -n "any depth" ;;
|
|
1) echo -n "1 bit deep" ;;
|
|
*) echo -n "${src_depth} bits deep" ;;
|
|
esac
|
|
xlat_info="${xlat_info}, ${src_depth}"
|
|
case ${src_bipp} in
|
|
0) echo -n ", any bits per pixel" ;;
|
|
1) echo -n ", 1 bit per pixel" ;;
|
|
*) echo -n ", ${src_bipp} bits per pixel" ;;
|
|
esac
|
|
xlat_info="${xlat_info}, ${src_bipp}"
|
|
case ${src_skipx} in
|
|
_) echo -n ", any number of pixels skipped" ; value="-1";;
|
|
*) echo -n ", ${src_skipx} pixels skipped" ; value=${src_skipx} ;;
|
|
esac
|
|
xlat_info="${xlat_info}, ${value}"
|
|
case ${src_pad} in
|
|
0) echo -n ", any scanline padding" ;;
|
|
*) echo -n ", ${src_pad}-bit scanline padding" ;;
|
|
esac
|
|
xlat_info="${xlat_info}, ${src_pad}"
|
|
case ${src_order} in
|
|
m) echo -n ", MSB-first" ; value="BIG" ;;
|
|
l) echo -n ", LSB-first" ; value="LITTLE" ;;
|
|
esac
|
|
xlat_info="${xlat_info}, TME_ENDIAN_${value}"
|
|
case "x${src_class}" in
|
|
xm) echo -n ", monochrome" ; value="MONOCHROME" ;;
|
|
xc) echo -n ", color" ; value="COLOR" ;;
|
|
*) echo -n ", either color or monochrome" ; value="ANY" ;;
|
|
esac
|
|
xlat_info="${xlat_info}, TME_FB_XLAT_CLASS_${value}"
|
|
case "x${src_map}" in
|
|
xl) echo -n ", linearly mapped pixels" ; value="LINEAR" ;;
|
|
xi) echo -n ", index mapped pixels" ; value="INDEX" ;;
|
|
*) echo -n ", any pixel mapping" ; value="ANY" ;;
|
|
esac
|
|
xlat_info="${xlat_info}, TME_FB_XLAT_MAP_${value}"
|
|
value=${src_map_bits}
|
|
case "${src_map_bits}" in
|
|
0) echo -n ", any bits per mapped intensity" ;;
|
|
1) echo -n ", 1 bit per mapped intensity" ;;
|
|
*) echo -n ", ${src_map_bits} bits per mapped intensity" ;;
|
|
esac
|
|
xlat_info="${xlat_info}, ${value}"
|
|
for primary in g r b; do
|
|
eval "src_mask=\$src_mask_${primary}"
|
|
case "x${src_mask}" in
|
|
x) echo -n ", no ${primary} mask" ; value=0 ;;
|
|
x0x0) echo -n ", any ${primary} mask" ; value=TME_FB_XLAT_MASK_ANY ;;
|
|
*) echo -n ", a ${primary} mask of ${src_mask}" ; value=${src_mask} ;;
|
|
esac
|
|
xlat_info="${xlat_info}, ${value}"
|
|
done
|
|
echo ""
|
|
echo " to this destination format:"
|
|
echo -n " "
|
|
case ${dst_depth} in
|
|
0) echo -n "any depth" ;;
|
|
1) echo -n "1 bit deep" ;;
|
|
*) echo -n "${dst_depth} bits deep" ;;
|
|
esac
|
|
xlat_info="${xlat_info}, ${dst_depth}"
|
|
case ${dst_bipp} in
|
|
0) echo -n ", any bits per pixel" ;;
|
|
1) echo -n ", 1 bit per pixel" ;;
|
|
*) echo -n ", ${dst_bipp} bits per pixel" ;;
|
|
esac
|
|
xlat_info="${xlat_info}, ${dst_bipp}"
|
|
case ${dst_skipx} in
|
|
_) echo -n ", any number of pixels skipped" ; value="-1";;
|
|
*) echo -n ", ${dst_skipx} pixels skipped" ; value=${dst_skipx} ;;
|
|
esac
|
|
xlat_info="${xlat_info}, ${value}"
|
|
case ${dst_pad} in
|
|
0) echo -n ", any scanline padding" ;;
|
|
*) echo -n ", ${dst_pad}-bit scanline padding" ;;
|
|
esac
|
|
xlat_info="${xlat_info}, ${dst_pad}"
|
|
case ${dst_order} in
|
|
m) echo -n ", MSB-first" ; value="BIG" ;;
|
|
l) echo -n ", LSB-first" ; value="LITTLE" ;;
|
|
esac
|
|
xlat_info="${xlat_info}, TME_ENDIAN_${value}"
|
|
case "x${dst_map}" in
|
|
xl) echo -n ", linearly mapped pixels" ; value="LINEAR" ;;
|
|
xi) echo -n ", index mapped pixels" ; value="INDEX" ;;
|
|
*) echo -n ", any pixel mapping" ; value="ANY" ;;
|
|
esac
|
|
xlat_info="${xlat_info}, TME_FB_XLAT_MAP_${value}"
|
|
for primary in g r b; do
|
|
eval "dst_mask=\$dst_mask_${primary}"
|
|
case "x${dst_mask}" in
|
|
x) echo -n ", no ${primary} mask" ; value=0 ;;
|
|
x0x0) echo -n ", any ${primary} mask" ; value=TME_FB_XLAT_MASK_ANY ;;
|
|
*) echo -n ", a ${primary} mask of ${dst_mask}" ; value=${dst_mask} ;;
|
|
esac
|
|
xlat_info="${xlat_info}, ${value}"
|
|
done
|
|
save_IFS=$IFS
|
|
IFS=
|
|
xlat_array="${xlat_array}
|
|
{ $xlat_info }, "
|
|
IFS=$save_IFS
|
|
echo ""
|
|
echo "*/"
|
|
echo "static int"
|
|
echo "tme_fb_xlat${xlat}(struct tme_fb_connection *src,"
|
|
echo " struct tme_fb_connection *dst)"
|
|
echo "{"
|
|
undef_macros=
|
|
|
|
echo ""
|
|
echo " /* whenever possible we define macros instead of declaring"
|
|
echo " variables, for optimization: */"
|
|
|
|
echo ""
|
|
echo " /* declare src_x and src_y. these are the current translation"
|
|
echo " coordinates in the source image: */"
|
|
echo " unsigned int src_x, src_y;"
|
|
|
|
echo ""
|
|
echo " /* declare dst_x and dst_y. these are the current translation"
|
|
echo " coordinates in the destination image. since this function"
|
|
if test $scale = _; then
|
|
echo " does not scale the image, these coordinates are always"
|
|
echo " the same as the coordinates in the source image: */"
|
|
echo "#define dst_x (src_x)"
|
|
echo "#define dst_y (src_y)"
|
|
undef_macros="${undef_macros} dst_x dst_y"
|
|
scale_op=
|
|
scale_math=
|
|
else
|
|
if test $scale = _h_; then
|
|
scale_op='/'
|
|
scale_name='halves'
|
|
else
|
|
scale_op='*'
|
|
scale_name='doubles'
|
|
fi
|
|
scale_math=" ${scale_op} 2"
|
|
echo " ${scale_name} the image, the coordinates in the destination image"
|
|
echo " are always the coordinates in the source image${scale_math}: */"
|
|
echo " unsigned int dst_x, dst_y;"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare pixel. this holds a single pixel value being translated"
|
|
echo " for the destination image: */"
|
|
echo " tme_uint32_t pixel;"
|
|
|
|
echo ""
|
|
echo " /* declare src_width and dst_width. these are in terms of pixels: */"
|
|
value="(src_width${scale_math})"
|
|
if test ${width} = 0; then
|
|
echo " const unsigned int src_width = src->tme_fb_connection_width;"
|
|
if test $scale != _; then
|
|
echo " const unsigned int dst_width = ${value};"
|
|
else
|
|
echo "#define dst_width ${value}"
|
|
undef_macros="${undef_macros} dst_width"
|
|
fi
|
|
else
|
|
echo "#define src_width (${width})"
|
|
echo "#define dst_width ${value}"
|
|
undef_macros="${undef_macros} src_width dst_width"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare src_depth, the source pixel depth, which is in"
|
|
echo " terms of bits. declare src_mask, which is the corresponding"
|
|
echo " mask of one bits: */"
|
|
value="(0xffffffff >> (32 - src_depth))"
|
|
if test ${src_depth} = 0; then
|
|
echo " const unsigned int src_depth = src->tme_fb_connection_depth;"
|
|
echo " const tme_uint32_t src_mask = ${value};"
|
|
else
|
|
echo "#define src_depth (${src_depth})"
|
|
echo "#define src_mask ${value}"
|
|
undef_macros="${undef_macros} src_depth src_mask"
|
|
fi
|
|
|
|
# if we are halving, or if source pixels may have subfields,
|
|
# we may need to deal with intensities:
|
|
#
|
|
if test ${scale} = _h_ || test "x${src_mask_g}" != x; then
|
|
|
|
echo ""
|
|
echo " /* declare src_indexed. this is nonzero if source pixel subfields"
|
|
echo " are index-mapped into intensities: */"
|
|
if test "x${src_map}" = x; then
|
|
echo " const unsigned int src_indexed = (src->tme_fb_connection_map_g != NULL);"
|
|
else
|
|
if test "x${src_map}" = xi; then value=TRUE; else value=FALSE; fi
|
|
echo "#define src_indexed (${value})"
|
|
undef_macros="${undef_macros} src_indexed"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare src_mask_i, which is the mask for a source intensity: */"
|
|
if test "${src_map_bits}" = 0; then
|
|
echo " const tme_uint32_t src_mask_i = (0xffffffff >> (32 - src->tme_fb_connection_map_bits));"
|
|
else
|
|
echo "#define src_mask_i (0xffffffff >> (32 - ${src_map_bits}))"
|
|
undef_macros="${undef_macros} src_mask_i"
|
|
fi
|
|
|
|
if test "x${src_class}" != xm; then
|
|
echo ""
|
|
echo " /* declare dst_indexed. this is nonzero if intensities are index-mapped"
|
|
echo " into destination pixel subfields: */"
|
|
if test "x${dst_map}" = x; then
|
|
echo " const unsigned int dst_indexed = (dst->tme_fb_connection_map_g != NULL);"
|
|
else
|
|
if test "x${dst_map}" = xi; then value=TRUE; else value=FALSE; fi
|
|
echo "#define dst_indexed (${value})"
|
|
undef_macros="${undef_macros} dst_indexed"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare dst_masks_default. this is nonzero if the destination"
|
|
echo " subfield masks are the default: */"
|
|
if test "x${dst_mask_g}" = "x0x0"; then
|
|
echo " const unsigned int dst_masks_default = (dst->tme_fb_connection_mask_g == 0);"
|
|
else
|
|
if test "x${dst_mask_g}" = x; then value=TRUE; else value=FALSE; fi
|
|
echo "#define dst_masks_default (${value})"
|
|
undef_macros="${undef_macros} dst_masks_default"
|
|
fi
|
|
fi
|
|
|
|
for primary in g r b; do
|
|
primary_cap=`echo ${primary} | tr a-z A-Z`
|
|
echo ""
|
|
echo " /* declare src_mask_${primary}, the mask for the ${primary} subfield in a source pixel: */"
|
|
eval "src_mask=\$src_mask_${primary}"
|
|
if test "x${src_mask}" = x0x0; then
|
|
echo " const tme_uint32_t src_mask_${primary}"
|
|
echo " = (src->tme_fb_connection_mask_${primary} != 0"
|
|
echo " ? src->tme_fb_connection_mask_${primary}"
|
|
echo " : src_mask);"
|
|
else
|
|
if test "x${src_mask}" = x; then src_mask="src_mask"; fi
|
|
echo "#define src_mask_${primary} (${src_mask})"
|
|
undef_macros="${undef_macros} src_mask_${primary}"
|
|
fi
|
|
echo ""
|
|
echo " /* declare value_${primary}, the intensity value for the ${primary} subfield in a pixel: */"
|
|
echo " tme_uint32_t value_${primary};"
|
|
if test "x${src_class}" = xm; then break; fi
|
|
echo ""
|
|
echo " /* declare dst_mask_${primary}, the mask for the ${primary} subfield in a destination pixel: */"
|
|
eval "dst_mask=\$dst_mask_${primary}"
|
|
if test "x${dst_mask}" = x0x0; then
|
|
echo " const tme_uint32_t dst_mask_${primary}"
|
|
echo " = (dst->tme_fb_connection_mask_${primary} != 0"
|
|
echo " ? dst->tme_fb_connection_mask_${primary}"
|
|
echo " : TME_FB_XLAT_MASK_DEFAULT_${primary_cap});"
|
|
else
|
|
if test "x${dst_mask}" = x; then dst_mask="TME_FB_XLAT_MASK_DEFAULT_${primary_cap}"; fi
|
|
echo "#define dst_mask_${primary} (${dst_mask})"
|
|
undef_macros="${undef_macros} dst_mask_${primary}"
|
|
fi
|
|
done
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare src_bipp and dst_bipp. these are the bits-per-pixel"
|
|
echo " values for the source and destination images: */"
|
|
if test ${src_bipp} = 0; then
|
|
echo " const unsigned int src_bipp = src->tme_fb_connection_bits_per_pixel;"
|
|
else
|
|
echo "#define src_bipp (${src_bipp})"
|
|
undef_macros="${undef_macros} src_bipp"
|
|
fi
|
|
if test ${dst_bipp} = 0; then
|
|
echo " const unsigned int dst_bipp = dst->tme_fb_connection_bits_per_pixel;"
|
|
else
|
|
echo "#define dst_bipp (${dst_bipp})"
|
|
undef_macros="${undef_macros} dst_bipp"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare src_skipx and dst_skipx. these are the counts of"
|
|
echo " undisplayed pixels at the beginning of each scanline in the"
|
|
echo " source and destination images: */"
|
|
if test ${src_skipx} = _; then
|
|
echo " const unsigned int src_skipx = src->tme_fb_connection_skipx;"
|
|
else
|
|
echo "#define src_skipx (${src_skipx})"
|
|
undef_macros="${undef_macros} src_skipx"
|
|
fi
|
|
if test ${dst_skipx} = _; then
|
|
echo " const unsigned int dst_skipx = dst->tme_fb_connection_skipx;"
|
|
else
|
|
echo "#define dst_skipx (${dst_skipx})"
|
|
undef_macros="${undef_macros} dst_skipx"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare src_pad and dst_pad. these are the paddings, in bits,"
|
|
echo " of each scanline in the source and destination images: */"
|
|
if test ${src_pad} = 0; then
|
|
echo " const unsigned int src_pad = src->tme_fb_connection_scanline_pad;"
|
|
else
|
|
echo "#define src_pad (${src_pad})"
|
|
undef_macros="${undef_macros} src_pad"
|
|
fi
|
|
if test ${dst_pad} = 0; then
|
|
echo " const unsigned int dst_pad = dst->tme_fb_connection_scanline_pad;"
|
|
else
|
|
echo "#define dst_pad (${dst_pad})"
|
|
undef_macros="${undef_macros} dst_pad"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare src_order and dst_order. these are the bit and byte"
|
|
echo " orders (either TME_ENDIAN_BIG or TME_ENDIAN_LITTLE) of the"
|
|
echo " source and destination images. since these values profoundly"
|
|
echo " affect optimization, they are always constant: */"
|
|
if test ${src_order} = m; then value=BIG; else value=LITTLE; fi
|
|
echo "#define src_order (TME_ENDIAN_${value})"
|
|
undef_macros="${undef_macros} src_order"
|
|
if test ${dst_order} = m; then value=BIG; else value=LITTLE; fi
|
|
echo "#define dst_order (TME_ENDIAN_${value})"
|
|
undef_macros="${undef_macros} dst_order"
|
|
|
|
echo ""
|
|
echo " /* declare src_bypl and dst_bypl. these are the bytes per scanline"
|
|
echo " in the source and destination images. these values are calculated"
|
|
echo " from the count of undisplayed and displayed pixels per scanline,"
|
|
echo " the number of bits per pixel, and the scanline padding: */"
|
|
value="(((((src_skipx + src_width) * src_bipp) + (src_pad - 1)) & -src_pad) / 8)"
|
|
if test ${src_skipx} = _ || test ${width} = 0 || test ${src_bipp} = 0 || test ${src_pad} = 0; then
|
|
echo " const unsigned int src_bypl = ${value};"
|
|
src_bypl_var=true
|
|
else
|
|
echo "#define src_bypl ${value}"
|
|
undef_macros="${undef_macros} src_bypl"
|
|
src_bypl_var=false
|
|
fi
|
|
value="(((((dst_skipx + dst_width) * dst_bipp) + (dst_pad - 1)) & -dst_pad) / 8)"
|
|
if test ${dst_skipx} = _ || test ${width} = 0 || test ${dst_bipp} = 0 || test ${dst_pad} = 0; then
|
|
echo " const unsigned int dst_bypl = ${value};"
|
|
dst_bypl_var=true
|
|
else
|
|
echo "#define dst_bypl ${value}"
|
|
undef_macros="${undef_macros} dst_bypl"
|
|
dst_bypl_var=false
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare src_packed and dst_packed. these are nonzero iff"
|
|
echo " every last bit in a scanline belongs to a displayed pixel."
|
|
echo " put another way, this is zero iff a scanline has undisplayed"
|
|
echo " pixels at its beginning or padding bits at its end. when"
|
|
echo " a source image or destination image is packed, translation"
|
|
echo " doesn't have to worry about skipping FIFO bits to get to"
|
|
echo " bits belonging to displayed pixels: */"
|
|
value="((src_width * src_bipp) == (src_bypl * 8))"
|
|
if $src_bypl_var; then
|
|
echo " const unsigned int src_packed = ${value};"
|
|
else
|
|
echo "#define src_packed ${value}"
|
|
undef_macros="${undef_macros} src_packed"
|
|
fi
|
|
value="((dst_width * dst_bipp) == (dst_bypl * 8))"
|
|
if $dst_bypl_var; then
|
|
echo " const unsigned int dst_packed = ${value};"
|
|
else
|
|
echo "#define dst_packed ${value}"
|
|
undef_macros="${undef_macros} dst_packed"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare src_bypb and src_bypb_real. src_bypb is the bytes"
|
|
echo " per source image buffer with the \"translation termination"
|
|
echo " overhead\" of approximately two extra scanlines. src_bypb_real"
|
|
echo " is the real bytes per source image buffer with no overhead."
|
|
echo " both values are padded to a multiple of 4 bytes (32 bits): */"
|
|
if test ${height} = 0; then
|
|
value="src->tme_fb_connection_height"
|
|
else
|
|
value="${height}"
|
|
fi
|
|
value_real="(((${value} * src_bypl) + 3) & -4)"
|
|
value="((src_bypb_real + (src_bypl * 2)) & -4)"
|
|
if test ${height} = 0 || $src_bypl_var; then
|
|
echo " const unsigned int src_bypb_real = ${value_real};"
|
|
echo " const unsigned int src_bypb = ${value};"
|
|
else
|
|
echo "#define src_bypb_real ${value_real}"
|
|
echo "#define src_bypb ${value}"
|
|
undef_macros="${undef_macros} src_bypb_real src_bypb"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare the source primary bit FIFO:"
|
|
echo ""
|
|
echo " src_raw0 points to the next aligned 32-bit word to be"
|
|
echo " read from the image buffer."
|
|
echo ""
|
|
echo " src_fifo0 is the visible part of the bit FIFO."
|
|
echo ""
|
|
echo " src_fifo0_next and src_fifo0_bits are only used when the"
|
|
echo " visible part of the bit FIFO is not guaranteed to always"
|
|
echo " correspond to an aligned 32-bit word in the image buffer."
|
|
echo " src_fifo0_next is the invisible part of the bit FIFO,"
|
|
echo " and src_fifo0_bits tracks the total number of bits in the"
|
|
echo " visible and invisible parts of the FIFO. */"
|
|
echo " const tme_uint32_t *src_raw0;"
|
|
echo " tme_uint32_t src_fifo0, src_fifo0_next;"
|
|
echo " unsigned int src_fifo0_bits;"
|
|
|
|
if test ${scale} = _h_; then
|
|
echo ""
|
|
echo " /* since this function ${scale_name} the image, declare the"
|
|
echo " source secondary bit FIFO. these variables work in "
|
|
echo " exactly the same way that their primary counterparts do: */"
|
|
echo " const tme_uint32_t *src_raw1;"
|
|
echo " tme_uint32_t src_fifo1, src_fifo1_next;"
|
|
echo " unsigned int src_fifo1_bits;"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare the destination primary bit FIFO:"
|
|
echo ""
|
|
echo " dst_raw0 points to the next aligned 32-bit word to be"
|
|
echo " written into the image buffer."
|
|
echo ""
|
|
echo " dst_fifo0 is the visible part of the bit FIFO."
|
|
echo ""
|
|
echo " dst_fifo0_next and dst_fifo0_bits are only used when the"
|
|
echo " visible part of the bit FIFO is not guaranteed to always"
|
|
echo " correspond to an aligned 32-bit word in the image buffer."
|
|
echo " dst_fifo0_next is the invisible part of the bit FIFO,"
|
|
echo " and dst_fifo0_bits tracks the total number of bits in the"
|
|
echo " invisible part of the FIFO. */"
|
|
echo " tme_uint32_t *dst_raw0;"
|
|
echo " tme_uint32_t dst_fifo0, dst_fifo0_next;"
|
|
echo " unsigned int dst_fifo0_bits;"
|
|
|
|
if test ${scale} = _d_; then
|
|
echo ""
|
|
echo " /* since this function ${scale_name} the image, declare"
|
|
echo " the destination secondary bit FIFO. these variables work"
|
|
echo " in exactly the same way that their primary counterparts"
|
|
echo " do: */"
|
|
echo " tme_uint32_t *dst_raw1;"
|
|
echo " tme_uint32_t dst_fifo1, dst_fifo1_next;"
|
|
echo " unsigned int dst_fifo1_bits;"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare src_off and dst_off. these are used when priming a"
|
|
echo " source or destination bit FIFO, to identify an initial aligned"
|
|
echo " 32-bit word in the source or destination image buffer, and an"
|
|
echo " initial bit offset within that word: */"
|
|
echo " unsigned int src_off, dst_off;"
|
|
|
|
echo ""
|
|
echo " /* declare src_fifo0_may_be_unaligned. this is zero iff all"
|
|
echo " aligned 32-bit words in the source buffer contain a whole"
|
|
echo " number of displayed pixels, and at *all times during the"
|
|
echo " translation* the visible part of the bit FIFO is guaranteed"
|
|
echo " to correspond to an aligned 32-bit word in the image buffer."
|
|
echo ""
|
|
echo " this is *not* so if any of the following are true:"
|
|
echo ""
|
|
echo " - the source bits-per-pixel value is not known at compile"
|
|
echo " time. in this case, we can't unroll the translation loop"
|
|
echo " for source pixels, and are forced to shift the FIFO after"
|
|
echo " each one."
|
|
echo ""
|
|
echo " - if the source image is not packed. in this case, there may"
|
|
echo " be undisplayed pixels in the FIFO, which we will need to"
|
|
echo " shift out."
|
|
echo ""
|
|
echo " - if there are 24 bits per source pixel. in this case, a"
|
|
echo " source pixel may cross a 32-bit boundary: */"
|
|
src_fifo0_may_be_unaligned_var=false
|
|
if test ${src_bipp} = 0; then
|
|
value=TRUE
|
|
else
|
|
value="(!src_packed || (src_bipp == 24))"
|
|
src_fifo0_may_be_unaligned_var=${src_bypl_var}
|
|
fi
|
|
if $src_fifo0_may_be_unaligned_var; then
|
|
echo " const unsigned int src_fifo0_may_be_unaligned = ${value};"
|
|
else
|
|
echo "#define src_fifo0_may_be_unaligned ${value}"
|
|
undef_macros="${undef_macros} src_fifo0_may_be_unaligned"
|
|
fi
|
|
|
|
if test $scale = _h_; then
|
|
echo ""
|
|
echo " /* declare src_fifo1_may_be_unaligned. this is zero iff all"
|
|
echo " aligned 32-bit words in the source buffer contain a"
|
|
echo " whole number of displayed pixels, *and* for every aligned"
|
|
echo " 32-bit word on one scanline all other scanlines have an"
|
|
echo " aligned 32-bit word corresponding to the same x coordinate: */"
|
|
value="(src_fifo0_may_be_unaligned || (src_bypl & 3))"
|
|
if $src_bypl_var; then
|
|
echo " const unsigned int src_fifo1_may_be_unaligned = ${value};"
|
|
else
|
|
echo "#define src_fifo1_may_be_unaligned ${value}"
|
|
undef_macros="${undef_macros} src_fifo1_may_be_unaligned"
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare dst_fifo0_may_be_unaligned. this is zero iff all"
|
|
echo " aligned 32-bit words in the destination buffer contain a whole"
|
|
echo " number of displayed pixels, and at *all times during the"
|
|
echo " translation* the visible part of the bit FIFO is guaranteed"
|
|
echo " to correspond to an aligned 32-bit word in the image buffer."
|
|
echo ""
|
|
echo " this is *not* so if any of the following are true:"
|
|
echo ""
|
|
echo " - the destination bits-per-pixel value is not known at compile"
|
|
echo " time. in this case, we can't unroll the translation loop"
|
|
echo " for destination pixels, and are forced to shift the FIFO"
|
|
echo " after each one."
|
|
echo ""
|
|
echo " - if src_fifo0_may_be_unaligned is true. in this case, we"
|
|
echo " definitely can't guarantee that any initial dst_x will"
|
|
echo " correspond to an aligned 32-bit word in the destination buffer."
|
|
echo ""
|
|
echo " - if the destination image is not packed. in this case, there may"
|
|
echo " be undisplayed pixels in the FIFO, which we will need to"
|
|
echo " shift out."
|
|
echo ""
|
|
echo " - if there are 24 bits per destination pixel. in this case,"
|
|
echo " a destination pixel may cross a 32-bit boundary."
|
|
echo ""
|
|
echo " - if a possible initial dst_x doesn't correspond to an aligned"
|
|
echo " 32-bit word in the destination buffer. for this last one:"
|
|
echo ""
|
|
echo " since we require that src_fifo0_may_be_unaligned is zero, we"
|
|
echo " know that the initial src_x = (Z * 32) / src_bipp for "
|
|
echo " some Z. we also have the initial dst_x = src_x${scale_math}."
|
|
echo " the initial destination bit offset will then be:"
|
|
echo ""
|
|
echo " (dst_skipx + dst_x) * dst_bipp"
|
|
echo " = (dst_skipx * dst_bipp) + (dst_x * dst_bipp)"
|
|
echo ""
|
|
echo " if we additionally require that (dst_skipx * dst_bipp)"
|
|
echo " be 32-bit aligned, this reduces things to:"
|
|
echo ""
|
|
echo " dst_x * dst_bipp"
|
|
echo " = (src_x${scale_math}) * dst_bipp"
|
|
echo " = (((Z * 32) / src_bipp)${scale_math}) * dst_bipp"
|
|
echo ""
|
|
echo " which will be a multiple of 32 iff:"
|
|
echo ""
|
|
echo " ((1 / src_bipp)${scale_math}) * dst_bipp >= 1 and integral"
|
|
echo ""
|
|
echo " or, equivalently:"
|
|
echo ""
|
|
denom="src_bipp"
|
|
numer="dst_bipp"
|
|
case $scale in
|
|
_) ;;
|
|
_h_) denom="(${denom} * 2)" ;;
|
|
_d_) numer="(${numer} * 2)" ;;
|
|
esac
|
|
echo " (${numer} % ${denom}) == 0"
|
|
echo " */"
|
|
dst_fifo0_may_be_unaligned_var=false
|
|
if test ${dst_bipp} = 0; then
|
|
value=TRUE
|
|
else
|
|
value="(src_fifo0_may_be_unaligned || !dst_packed || (dst_bipp == 24) || (dst_bypl % 4) || ((dst_skipx * dst_bipp) % 32) || (${numer} % ${denom}))"
|
|
if $src_bypl_var || $dst_bypl_var; then
|
|
dst_fifo0_may_be_unaligned_var=true
|
|
fi
|
|
fi
|
|
if $dst_fifo0_may_be_unaligned_var; then
|
|
echo " const unsigned int dst_fifo0_may_be_unaligned = ${value};"
|
|
else
|
|
echo "#define dst_fifo0_may_be_unaligned ${value}"
|
|
undef_macros="${undef_macros} dst_fifo0_may_be_unaligned"
|
|
fi
|
|
|
|
if test $scale = _d_; then
|
|
echo ""
|
|
echo " /* declare dst_fifo1_may_be_unaligned. this is zero iff all"
|
|
echo " 32-bit aligned values in the destination buffer contain a"
|
|
echo " whole number of displayed pixels, and for every 32-bit"
|
|
echo " aligned value on one scanline all other scanlines have a"
|
|
echo " 32-bit aligned value corresponding to the same x coordinate: */"
|
|
value="(dst_fifo0_may_be_unaligned || (dst_bypl & 3))"
|
|
if $src_bypl_var || $dst_bypl_var; then
|
|
echo " const unsigned int dst_fifo1_may_be_unaligned = ${value};"
|
|
else
|
|
echo "#define dst_fifo1_may_be_unaligned ${value}"
|
|
undef_macros="${undef_macros} dst_fifo1_may_be_unaligned"
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* declare src_offset_updated_first and src_offset_updated_last,"
|
|
echo " which hold the offsets of the first and last updated bytes in"
|
|
echo " the source image: */"
|
|
echo " tme_uint32_t src_offset_updated_first;"
|
|
echo " tme_uint32_t src_offset_updated_last;"
|
|
|
|
echo ""
|
|
echo " /* declare src_raw0_end. when treating the source image as"
|
|
echo " an array of aligned 32-bit words, this variable holds the"
|
|
echo " address of the first word after the real source image."
|
|
echo " if the fast, aligned 32-bit word comparison loop passes"
|
|
echo " this point, the entire source image has been processed and"
|
|
echo " the function terminates: */"
|
|
echo " const tme_uint32_t *src_raw0_end;"
|
|
|
|
echo ""
|
|
echo " /* declare xlat_run. see the comment for the TME_FB_XLAT_RUN"
|
|
echo " macro for an explanation of what this variable does: */"
|
|
echo " int xlat_run;"
|
|
|
|
echo ""
|
|
echo " /* this silences gcc -Wuninitialized: */"
|
|
echo " src_fifo0_next = 0;"
|
|
echo " src_fifo0_bits = 0;"
|
|
if test ${scale} = _h_; then
|
|
echo " src_fifo1_next = 0;"
|
|
echo " src_fifo1_bits = 0;"
|
|
fi
|
|
echo " dst_fifo0_next = 0;"
|
|
echo " dst_fifo0_bits = 0;"
|
|
if test ${scale} = _d_; then
|
|
echo " dst_fifo1_next = 0;"
|
|
echo " dst_fifo1_bits = 0;"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* initialize src_raw0 and src_raw0_end for the fast aligned 32-bit"
|
|
echo " word comparison loop. on entry to (and when continuing) that loop,"
|
|
echo " src_raw0 always points to the aligned 32-bit word *before* the"
|
|
echo " next word to check. src_raw0_end always points after the last"
|
|
echo " word to check."
|
|
echo ""
|
|
echo " src_raw0 is actually part of the source primary bit FIFO, which"
|
|
echo " is good, because when the fast comparison fails on a word, src_raw0"
|
|
echo " is already primed and ready to work for that bit FIFO: */"
|
|
echo " src_offset_updated_first = src->tme_fb_connection_offset_updated_first;"
|
|
echo " src_offset_updated_last = TME_MIN(src->tme_fb_connection_offset_updated_last, src_bypb_real - 1);"
|
|
echo " src->tme_fb_connection_offset_updated_first = 0;"
|
|
echo " src->tme_fb_connection_offset_updated_last = src_bypb_real - 1;"
|
|
echo " if (src_offset_updated_first > src_offset_updated_last) {"
|
|
echo " return (FALSE);"
|
|
echo " }"
|
|
echo " src_raw0"
|
|
echo " = (((const tme_uint32_t *)"
|
|
echo " (src->tme_fb_connection_buffer"
|
|
echo " + (src_offset_updated_first"
|
|
echo " & (0 - (tme_uint32_t) sizeof(tme_uint32_t)))))"
|
|
echo " -1);"
|
|
echo " src_raw0_end"
|
|
echo " = ((const tme_uint32_t *)"
|
|
echo " (src->tme_fb_connection_buffer"
|
|
echo " + src_offset_updated_last"
|
|
echo " + 1));"
|
|
|
|
echo ""
|
|
echo " /* initialize xlat_run to -1. it can never go negative inside the"
|
|
echo " pixel translation loop, so if xlat_run stays negative for the"
|
|
echo " entire translation, it means that the source image hasn't changed"
|
|
echo " since the last translation. this information is returned to the"
|
|
echo " caller to hopefully save more work in updating the display: */"
|
|
echo " xlat_run = -1;"
|
|
|
|
echo ""
|
|
echo " /* this is the main translation loop, which contains the fast aligned"
|
|
echo " 32-bit word comparison loop, and the pixel translation loop: */"
|
|
echo " for (;;) {"
|
|
|
|
echo ""
|
|
echo " /* this is the fast aligned 32-bit word comparison loop. it"
|
|
echo " terminates either when a word fails comparison, or when the"
|
|
echo " entire source image has been compared. the if test that"
|
|
echo " follows checks for the latter case and breaks the main"
|
|
echo " translation loop: */"
|
|
echo " for (; (++src_raw0 < src_raw0_end"
|
|
echo " && *src_raw0 == *TME_FB_XLAT_SRC_OLD(src_raw0)); );"
|
|
echo " if (src_raw0 >= src_raw0_end) {"
|
|
echo " break;"
|
|
echo " }"
|
|
|
|
echo ""
|
|
echo " /* calculate the byte offset into the source buffer of the"
|
|
echo " 32-bit word that failed comparison: */"
|
|
echo " src_off = ((tme_uint8_t *) src_raw0) - src->tme_fb_connection_buffer;"
|
|
|
|
echo ""
|
|
echo " /* calculate the source y pixel coordinate, and reduce"
|
|
echo " src_off from the byte offset into the buffer to the"
|
|
echo " byte offset into that scanline: */"
|
|
echo " src_y = src_off / src_bypl;"
|
|
echo " src_off = src_off % src_bypl;"
|
|
|
|
echo ""
|
|
echo " /* while translating pixels, we use one or more \"bit FIFOs\","
|
|
echo " each composed of one or more 32-bit integers. we load these"
|
|
echo " FIFOs 32 bits at a time. */"
|
|
echo ""
|
|
echo " /* prime the visible part of the source primary bit FIFO: */"
|
|
echo " src_fifo0 = *src_raw0;"
|
|
echo " *TME_FB_XLAT_SRC_OLD(src_raw0) = src_fifo0;"
|
|
echo " src_raw0++;"
|
|
echo " src_fifo0 = ((src_order == TME_ENDIAN_BIG)"
|
|
echo " ? tme_betoh_u32(src_fifo0)"
|
|
echo " : tme_letoh_u32(src_fifo0));"
|
|
echo ""
|
|
echo " /* if the source primary bit FIFO may be unaligned: */"
|
|
echo " if (src_fifo0_may_be_unaligned) {"
|
|
echo ""
|
|
echo " /* prime the invisible part of the source primary bit FIFO and"
|
|
echo " assume that we will not have to shift it to finish: */"
|
|
echo " src_fifo0_next = *src_raw0;"
|
|
echo " *TME_FB_XLAT_SRC_OLD(src_raw0) = src_fifo0_next;"
|
|
echo " src_raw0++;"
|
|
echo " src_fifo0_next = ((src_order == TME_ENDIAN_BIG)"
|
|
echo " ? tme_betoh_u32(src_fifo0_next)"
|
|
echo " : tme_letoh_u32(src_fifo0_next));"
|
|
echo " src_fifo0_bits = 0;"
|
|
echo ""
|
|
echo " /* if there are pixels that need to be skipped, the first 32 bits"
|
|
echo " we loaded into the FIFO may have first bits that belong to"
|
|
echo " those undisplayed (skipped) pixels. it is *not* possible for"
|
|
echo " it to have first bits that belong to the scanline pad; there"
|
|
echo " might be pad bits in the *middle* of the first 32 bits, but any"
|
|
echo " first bits *must* belong to pixels, displayed or not: */"
|
|
echo " if (src_skipx > 0"
|
|
echo " && (src_off * 8) < (src_skipx * src_bipp)) {"
|
|
echo ""
|
|
echo " /* see how many bits we will need to skip: */"
|
|
echo " src_fifo0_bits = (src_skipx * src_bipp) - (src_off * 8);"
|
|
echo ""
|
|
echo " /* if it is more than 31 bits, this is an entire 32 bits of"
|
|
echo " undisplayed pixels. just advance: */"
|
|
echo " if (src_fifo0_bits > 31) {"
|
|
echo " src_raw0--;"
|
|
echo " continue;"
|
|
echo " }"
|
|
echo ""
|
|
echo " /* set the source x coordinate to zero: */"
|
|
echo " src_x = 0;"
|
|
echo " }"
|
|
echo ""
|
|
echo " /* otherwise, the first 32 bits we load will have first bits for"
|
|
echo " a displayable pixel: */"
|
|
echo " else {"
|
|
echo ""
|
|
echo " /* if the source bits per pixel is 24, calculate the number of"
|
|
echo " bytes *before* the original src_raw0 of any split pixel, and"
|
|
echo " subtract this from src_off, to leave src_off as the byte offset"
|
|
echo " into the scanline of the beginning of a pixel: */"
|
|
echo " if (src_bipp == 24) {"
|
|
echo " src_fifo0_bits = (src_off % 3);"
|
|
echo " src_off -= src_fifo0_bits;"
|
|
echo ""
|
|
echo " /* if this is a split pixel, we need to prime the source primary"
|
|
echo " bit FIFO starting with the part *before* the original src_raw0."
|
|
echo " we do not have to copy to the old; it passed comparison: */"
|
|
echo " if (src_fifo0_bits) {"
|
|
echo " src_raw0--;"
|
|
echo " src_fifo0_next = src_fifo0;"
|
|
echo " src_fifo0 = ((src_order == TME_ENDIAN_BIG)"
|
|
echo " ? tme_betoh_u32(*(src_raw0 - 2))"
|
|
echo " : tme_letoh_u32(*(src_raw0 - 2)));"
|
|
echo " }"
|
|
echo " }"
|
|
echo ""
|
|
echo " /* calculate the source x coordinate: */"
|
|
echo " src_x = ((src_off * 8) / src_bipp) - src_skipx;"
|
|
echo " }"
|
|
echo ""
|
|
echo " /* do any shifting to finish priming the source primary FIFO: */"
|
|
echo " if (src_fifo0_bits) {"
|
|
echo " if (src_order == TME_ENDIAN_BIG) {"
|
|
echo " src_fifo0 = (src_fifo0 << src_fifo0_bits) | (src_fifo0_next >> (32 - src_fifo0_bits));"
|
|
echo " src_fifo0_next <<= src_fifo0_bits;"
|
|
echo " }"
|
|
echo " else {"
|
|
echo " src_fifo0 = (src_fifo0 >> src_fifo0_bits) | (src_fifo0_next << (32 - src_fifo0_bits));"
|
|
echo " src_fifo0_next >>= src_fifo0_bits;"
|
|
echo " }"
|
|
echo " }"
|
|
echo " src_fifo0_bits = 64 - src_fifo0_bits;"
|
|
echo " }"
|
|
echo ""
|
|
echo " /* otherwise, the source primary FIFO is aligned: */"
|
|
echo " else {"
|
|
echo " src_x = ((src_off * 8) / src_bipp) - src_skipx;"
|
|
echo " }"
|
|
|
|
if test $scale = _h_; then
|
|
echo ""
|
|
echo " /* when halving the image, we have a source secondary bit "
|
|
echo " FIFO, providing pixel values at the same source x coordinate"
|
|
echo " but on the \"other\" line. prime the source secondary"
|
|
echo " bit FIFO: */"
|
|
echo " if (src_fifo1_may_be_unaligned) {"
|
|
echo ""
|
|
echo " /* calculate the bit offset into the source buffer of"
|
|
echo " this exact same pixel on the other line: */"
|
|
echo " src_off = ((src_y ^ 1) * src_bypl * 8) + ((src_skipx + src_x) * src_bipp);"
|
|
echo ""
|
|
echo " /* calculate how many bits offset from a 32-bit boundary the pixel is: */"
|
|
echo " src_fifo1_bits = src_off % 32;"
|
|
echo ""
|
|
echo " /* set src_raw1: */"
|
|
echo " src_raw1 = (const tme_uint32_t *)"
|
|
echo " (src->tme_fb_connection_buffer"
|
|
echo " + ((src_off - src_fifo1_bits) / 8));"
|
|
echo ""
|
|
echo " /* actually prime the FIFO by loading the first two words and"
|
|
echo " shifting off any offset bits: */"
|
|
echo " src_fifo1 = *src_raw1;"
|
|
echo " *TME_FB_XLAT_SRC_OLD(src_raw1) = src_fifo1;"
|
|
echo " src_raw1++;"
|
|
echo " src_fifo1_next = *src_raw1;"
|
|
echo " *TME_FB_XLAT_SRC_OLD(src_raw1) = src_fifo1_next;"
|
|
echo " src_raw1++;"
|
|
echo " if (src_order == TME_ENDIAN_BIG) {"
|
|
echo " src_fifo1 = tme_betoh_u32(src_fifo1);"
|
|
echo " src_fifo1_next = tme_betoh_u32(src_fifo1_next);"
|
|
echo " if (src_fifo1_bits) {"
|
|
echo " src_fifo1 = (src_fifo1 << src_fifo1_bits) | (src_fifo1_next >> (32 - src_fifo1_bits));"
|
|
echo " src_fifo1_next <<= src_fifo1_bits;"
|
|
echo " }"
|
|
echo " }"
|
|
echo " else {"
|
|
echo " src_fifo1 = tme_letoh_u32(src_fifo1);"
|
|
echo " src_fifo1_next = tme_letoh_u32(src_fifo1_next);"
|
|
echo " if (src_fifo1_bits) {"
|
|
echo " src_fifo1 = (src_fifo1 >> src_fifo1_bits) | (src_fifo1_next << (32 - src_fifo1_bits));"
|
|
echo " src_fifo1_next >>= src_fifo1_bits;"
|
|
echo " }"
|
|
echo " }"
|
|
echo " src_fifo1_bits = 64 - src_fifo1_bits;"
|
|
echo " }"
|
|
echo ""
|
|
echo " /* otherwise the source secondary FIFO is aligned: */"
|
|
echo " else {"
|
|
echo " src_raw1 = (const tme_uint32_t *)"
|
|
echo " (((tme_uint8_t *) src_raw0)"
|
|
echo " + (("
|
|
echo " /* if src_y is even, this addend is now src_bypl * 4,"
|
|
echo " else if src_y is odd, this addend is now src_bypl * 2: */"
|
|
echo " ((src_bypl * 4) >> (src_y & 1))"
|
|
echo " /* if src_y is even, this addend is now src_bypl,"
|
|
echo " else if src_y is odd, this addend is now -src_bypl: */"
|
|
echo " - (src_bypl * 3))"
|
|
echo " /* this -4 compensates for src_raw0 already having"
|
|
echo " been advanced by one: */"
|
|
echo " - 4));"
|
|
echo " src_fifo1 = *src_raw1;"
|
|
echo " *TME_FB_XLAT_SRC_OLD(src_raw1) = src_fifo1;"
|
|
echo " src_raw1++;"
|
|
echo " src_fifo1 = ((src_order == TME_ENDIAN_BIG)"
|
|
echo " ? tme_betoh_u32(src_fifo1)"
|
|
echo " : tme_letoh_u32(src_fifo1));"
|
|
echo " }"
|
|
fi
|
|
|
|
if test $scale != _; then
|
|
echo ""
|
|
echo " /* calculate the destination coordinates: */"
|
|
echo " dst_y = src_y${scale_math};"
|
|
echo " dst_x = src_x${scale_math};"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* prime the destination primary bit FIFO: */"
|
|
echo " dst_fifo0 = 0;"
|
|
echo " if (dst_fifo0_may_be_unaligned) {"
|
|
echo ""
|
|
echo " /* calculate the bit offset into the destination buffer of"
|
|
echo " the destination pixel: */"
|
|
echo " dst_off = (dst_y * dst_bypl * 8) + ((dst_skipx + dst_x) * dst_bipp);"
|
|
echo ""
|
|
echo " /* calculate the number of bits that will be in the primed FIFO: */"
|
|
echo " dst_fifo0_bits = dst_off % 32;"
|
|
echo ""
|
|
echo " /* set dst_raw0: */"
|
|
echo " dst_raw0 = (tme_uint32_t *)"
|
|
echo " (dst->tme_fb_connection_buffer"
|
|
echo " + ((dst_off - dst_fifo0_bits) / 8));"
|
|
echo ""
|
|
echo " /* prime the primary destination FIFO: */"
|
|
echo " dst_fifo0_next = 0;"
|
|
echo " if (dst_fifo0_bits) {"
|
|
echo " dst_fifo0_next = (src_order == TME_ENDIAN_BIG"
|
|
echo " ? (tme_betoh_u32(*dst_raw0) & (0xffffffffUL << (32 - dst_fifo0_bits)))"
|
|
echo " : (tme_letoh_u32(*dst_raw0) & (0xffffffffUL >> (32 - dst_fifo0_bits))));"
|
|
echo " }"
|
|
echo " }"
|
|
echo ""
|
|
echo " /* otherwise the destination primary FIFO is aligned: */"
|
|
echo " else {"
|
|
echo " dst_off = (dst_y * dst_bypl) + (((dst_skipx + dst_x) * dst_bipp) / 8);"
|
|
echo " dst_raw0 = (tme_uint32_t *) (dst->tme_fb_connection_buffer + dst_off);"
|
|
echo " }"
|
|
|
|
if test $scale = _d_; then
|
|
echo ""
|
|
echo " /* when doubling the image, we have a destination secondary bit "
|
|
echo " FIFO, for pixel values at the same source x coordinate"
|
|
echo " but on the \"other\" line. prime the destination secondary"
|
|
echo " bit FIFO: */"
|
|
echo " dst_fifo1 = 0;"
|
|
echo " if (dst_fifo1_may_be_unaligned) {"
|
|
echo ""
|
|
echo " /* calculate the bit offset into the destination buffer of"
|
|
echo " the destination pixel: */"
|
|
echo " dst_off = ((dst_y + 1) * dst_bypl * 8) + ((dst_skipx + dst_x) * dst_bipp);"
|
|
echo ""
|
|
echo " /* calculate the number of bits that will be in the primed FIFO: */"
|
|
echo " dst_fifo1_bits = dst_off % 32;"
|
|
echo ""
|
|
echo " /* set dst_raw1: */"
|
|
echo " dst_raw1 = (tme_uint32_t *)"
|
|
echo " (dst->tme_fb_connection_buffer"
|
|
echo " + ((dst_off - dst_fifo1_bits) / 8));"
|
|
echo ""
|
|
echo " /* prime the primary destination FIFO: */"
|
|
echo " dst_fifo1_next = 0;"
|
|
echo " if (dst_fifo1_bits) {"
|
|
echo " dst_fifo1_next = (src_order == TME_ENDIAN_BIG"
|
|
echo " ? (tme_betoh_u32(*dst_raw1) & (0xffffffffUL << (32 - dst_fifo1_bits)))"
|
|
echo " : (tme_letoh_u32(*dst_raw1) & (0xffffffffUL >> (32 - dst_fifo1_bits))));"
|
|
echo " }"
|
|
echo " }"
|
|
echo ""
|
|
echo " /* otherwise, the destination secondary FIFO is aligned: */"
|
|
echo " else {"
|
|
echo " dst_raw1 = (tme_uint32_t *)"
|
|
echo " (((tme_uint8_t *) dst_raw0)"
|
|
echo " + dst_bypl);"
|
|
echo " }"
|
|
fi
|
|
|
|
# we want to unroll the pixel translation loop to read as many
|
|
# source pixels as possible out of the source bit FIFOs and
|
|
# write as many destination pixels as possible into the
|
|
# destination bit FIFOs before shifting them.
|
|
#
|
|
# it is very common to want to unroll the translation loop a
|
|
# different number of times on source and destination pixels,
|
|
# so we always unroll the maximum possible, tracking within
|
|
# each unrolled iteration the relative unrolled iteration for
|
|
# the source and destination bit FIFOs.
|
|
#
|
|
|
|
# src_unroll and dst_unroll are the number of times we will
|
|
# unroll the translation loop on source and destination
|
|
# pixels, respectively. assume no unrolling:
|
|
#
|
|
src_unroll=1
|
|
dst_unroll=1
|
|
|
|
# src_iter_scale is the number of source pixels read out of a
|
|
# source bit FIFO in one unrolled iteration of the translation
|
|
# loop. if this function halves the source image, this is
|
|
# two, otherwise this is one.
|
|
#
|
|
# dst_iter_scale is the number of destination pixels written
|
|
# to a destination bit FIFO in one unrolled iteration of the
|
|
# translation loop. if this function doubles the source
|
|
# image, this is two, otherwise this is one.
|
|
#
|
|
# src_fifo_shift is the number of bits that the source bit
|
|
# FIFO(s) must be shifted after all unrolled iterations on
|
|
# source pixels. assume no unrolling, so if this function
|
|
# halves the source image and src_bipp is less than 24, two
|
|
# pixels' bits must be shifted, otherwise one pixel's bits
|
|
# must be shifted.
|
|
#
|
|
# dst_fifo_shift is the number of bits that the destination bit
|
|
# FIFO(s) must be shifted after all unrolled iterations on
|
|
# destination pixels. we are assuming no unrolling, so if this
|
|
# function doubles the source image and dst_bipp is less than
|
|
# 24, two pixels' bits must be shifted, otherwise one pixel's
|
|
# bits must be shifted:
|
|
#
|
|
if test $scale = _h_; then
|
|
src_iter_scale=2
|
|
src_fifo_shift="(src_bipp < 24 ? (src_bipp * 2) : src_bipp)"
|
|
else
|
|
src_iter_scale=1
|
|
src_fifo_shift="src_bipp"
|
|
fi
|
|
if test $scale = _d_; then
|
|
dst_iter_scale=2
|
|
dst_fifo_shift="(dst_bipp < 24 ? (dst_bipp * 2) : dst_bipp)"
|
|
else
|
|
dst_iter_scale=1
|
|
dst_fifo_shift="dst_bipp"
|
|
fi
|
|
|
|
# if src_bipp is known now, see how many times we can unroll the
|
|
# translation loop on source pixels:
|
|
#
|
|
if test ${src_bipp} != 0; then
|
|
|
|
# in general, we can unroll once for each pixel in the
|
|
# visible part of a source bit FIFO:
|
|
#
|
|
src_unroll=`expr 32 / ${src_bipp}`
|
|
|
|
# if this function halves the source image, we can unroll
|
|
# half as many times:
|
|
#
|
|
src_unroll=`expr ${src_unroll} / ${src_iter_scale}`
|
|
|
|
# if we think we can unroll zero times, this means that
|
|
# src_bipp is greater than 16 and this function halves the
|
|
# source image - the zero is telling us that two whole
|
|
# pixels cannot fit in the visible part of a source bit
|
|
# FIFO. so we unroll once on source pixels, and shift
|
|
# only one pixel's bits after the unrolling (the halving
|
|
# code will be shifting one pixel's worth of bits to get
|
|
# to the next pixel it has to read):
|
|
#
|
|
if test ${src_unroll} = 0; then
|
|
src_unroll=1
|
|
src_fifo_shift=${src_bipp}
|
|
|
|
# otherwise, we will be shifting the entire visible part
|
|
# of the source bit FIFO(s) after all unrolled iterations:
|
|
#
|
|
else
|
|
src_fifo_shift=32
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* since src_bipp is known at code-generation time, the"
|
|
echo " pixel translation loop is unrolled to translate all"
|
|
echo " source pixels in the 32-bit visible part of the source"
|
|
echo " bit FIFO(s) before shifting."
|
|
echo ""
|
|
echo " in this case, src_bipp is known to be ${src_bipp}, so "`expr ${src_unroll} \* ${src_iter_scale}`" pixels will"
|
|
echo " be read out of the source bit FIFO(s) before shifting, and"
|
|
echo " when the source bit FIFO(s) are shifted, they are shifted"
|
|
echo " ${src_fifo_shift} bits at a time: */"
|
|
fi
|
|
|
|
# if dst_bipp is known now, see how many times we can unroll the
|
|
# translation loop on destination pixels:
|
|
#
|
|
if test ${dst_bipp} != 0; then
|
|
|
|
# in general, we can unroll once for each pixel in the
|
|
# visible part of a destination bit FIFO:
|
|
#
|
|
dst_unroll=`expr 32 / ${dst_bipp}`
|
|
|
|
# if this function doubles the source image, we can unroll
|
|
# half as many times:
|
|
#
|
|
dst_unroll=`expr ${dst_unroll} / ${dst_iter_scale}`
|
|
|
|
# if we think we can unroll zero times, this means that
|
|
# dst_bipp is greater than 16 and this function doubles the
|
|
# source image - the zero is telling us that two whole
|
|
# pixels cannot fit in the visible part of a destination bit
|
|
# FIFO. so we unroll once on destination pixels, and shift
|
|
# only one pixel's bits after the unrolling (the doubling
|
|
# code will be shifting one pixel's worth of bits to get
|
|
# out the first pixel it has to write):
|
|
#
|
|
if test ${dst_unroll} = 0; then
|
|
dst_unroll=1
|
|
dst_fifo_shift=${dst_bipp}
|
|
|
|
# otherwise, we will be shifting the entire visible part
|
|
# of the source bit FIFO(s) after all unrolled iterations:
|
|
#
|
|
else
|
|
dst_fifo_shift=32
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* since dst_bipp is known at code-generation time, the pixel"
|
|
echo " translation loop is unrolled to translate all destination"
|
|
echo " pixels in the 32-bit visible part of the destination bit"
|
|
echo " FIFO(s) before shifting."
|
|
echo ""
|
|
echo " in this case, dst_bipp is known to be ${dst_bipp}, so "`expr ${dst_unroll} \* ${dst_iter_scale}`" pixels will"
|
|
echo " be written into the destination bit FIFO(s) before shifting,"
|
|
echo " and when the destination bit FIFO(s) are shifted, they are"
|
|
echo " shifted ${dst_fifo_shift} bits at a time: */"
|
|
fi
|
|
|
|
# unroll the translation loop the maximum number amount of times:
|
|
#
|
|
if test `expr ${src_unroll} \> ${dst_unroll}` = 1; then
|
|
unroll=${src_unroll}
|
|
else
|
|
unroll=${dst_unroll}
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* src_unroll = ${src_unroll}, src_iter_scale = ${src_iter_scale}"
|
|
echo " dst_unroll = ${dst_unroll}, dst_iter_scale = ${dst_iter_scale} */"
|
|
echo " for (xlat_run = TME_FB_XLAT_RUN;"
|
|
echo " xlat_run > 0; ) {"
|
|
iter=0
|
|
|
|
while test `expr ${iter} \< ${unroll}` = 1; do
|
|
echo ""
|
|
echo " /* iter #${iter} */"
|
|
echo ""
|
|
iter_next=`expr ${iter} + 1`
|
|
|
|
# the number of bits to skip in a source FIFO to get to
|
|
# this iteration's pixel:
|
|
src_shift=`expr ${iter} % ${src_unroll}`
|
|
src_shift='('`expr ${src_shift} \* ${src_iter_scale}`' * src_bipp)'
|
|
|
|
echo " /* get a pixel from the source primary FIFO: */"
|
|
echo " pixel ="
|
|
echo " ((src_fifo0"
|
|
echo " >> (src_order == TME_ENDIAN_BIG"
|
|
echo " ? (32 - (src_bipp + ${src_shift}))"
|
|
echo " : ${src_shift})));"
|
|
indent0=X
|
|
|
|
if test $scale != _h_; then
|
|
|
|
if test "x${src_mask_g}" = x; then
|
|
echo ""
|
|
echo " /* since source pixels are known at compile time to"
|
|
echo " not have subfields, map the source pixel into the"
|
|
echo " destination pixel: */"
|
|
echo " pixel = dst->tme_fb_connection_map_pixel[pixel & src_mask];"
|
|
else
|
|
echo ""
|
|
echo " /* if the source depth is within the threshold for pixel"
|
|
echo " mapping, or if source pixels don't have subfields,"
|
|
echo " map the source pixel into the destination pixel: */"
|
|
echo " if (src_mask <= TME_FB_XLAT_MAP_INDEX_MASK_MAX"
|
|
echo " || src_mask_g == src_mask) {"
|
|
echo " pixel = dst->tme_fb_connection_map_pixel[pixel & src_mask];"
|
|
echo " }"
|
|
echo ""
|
|
echo " /* otherwise, we will decompose this source pixel"
|
|
echo " and then compose the destination pixel: */"
|
|
echo " else {"
|
|
echo ""
|
|
echo " /* map the pixel subfields into intensities: */"
|
|
echo " value_g = TME_FB_XLAT_MAP(pixel, src_mask_g, src_mask_i, src_indexed, src->tme_fb_connection_map_g);"
|
|
if test "x${src_class}" != xm; then
|
|
echo " value_r = TME_FB_XLAT_MAP(pixel, src_mask_r, src_mask_i, src_indexed, src->tme_fb_connection_map_r);"
|
|
echo " value_b = TME_FB_XLAT_MAP(pixel, src_mask_b, src_mask_i, src_indexed, src->tme_fb_connection_map_b);"
|
|
fi
|
|
indent0=" "
|
|
src_mask_i=src_mask_i
|
|
src_mask_i_max=TME_FB_XLAT_MAP_INDEX_MASK_MAX
|
|
fi
|
|
|
|
else
|
|
|
|
echo ""
|
|
echo " /* map the pixel subfields into intensities: */"
|
|
echo " value_g = TME_FB_XLAT_MAP(pixel, src_mask_g, src_mask_i, src_indexed, src->tme_fb_connection_map_g);"
|
|
if test "x${src_class}" != xm; then
|
|
echo " value_r = TME_FB_XLAT_MAP(pixel, src_mask_r, src_mask_i, src_indexed, src->tme_fb_connection_map_r);"
|
|
echo " value_b = TME_FB_XLAT_MAP(pixel, src_mask_b, src_mask_i, src_indexed, src->tme_fb_connection_map_b);"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* get a second pixel, from the source secondary FIFO: */"
|
|
echo " pixel ="
|
|
echo " ((src_fifo1"
|
|
echo " >> (src_order == TME_ENDIAN_BIG"
|
|
echo " ? (32 - (src_bipp + ${src_shift}))"
|
|
echo " : ${src_shift})));"
|
|
|
|
echo ""
|
|
echo " /* map the pixel subfields into intensities and accumulate them: */"
|
|
echo " value_g += TME_FB_XLAT_MAP(pixel, src_mask_g, src_mask_i, src_indexed, src->tme_fb_connection_map_g);"
|
|
if test "x${src_class}" != xm; then
|
|
echo " value_r += TME_FB_XLAT_MAP(pixel, src_mask_r, src_mask_i, src_indexed, src->tme_fb_connection_map_r);"
|
|
echo " value_b += TME_FB_XLAT_MAP(pixel, src_mask_b, src_mask_i, src_indexed, src->tme_fb_connection_map_b);"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* get third and fourth pixels, from the source primary"
|
|
echo " FIFO and source secondary FIFO, respectively. if"
|
|
echo " src_bipp is 24 or greater, these pixels are not yet"
|
|
echo " entirely in the first parts of the FIFOs, so we need"
|
|
echo " to shift: */"
|
|
echo " if (src_bipp >= 24) {"
|
|
echo " TME_FB_XLAT_SHIFT_SRC(src_fifo0_may_be_unaligned,"
|
|
echo " src_fifo0,"
|
|
echo " src_fifo0_next,"
|
|
echo " src_fifo0_bits,"
|
|
echo " src_bipp,"
|
|
echo " src_raw0,"
|
|
echo " src_order);"
|
|
echo " TME_FB_XLAT_SHIFT_SRC(src_fifo1_may_be_unaligned,"
|
|
echo " src_fifo1,"
|
|
echo " src_fifo1_next,"
|
|
echo " src_fifo1_bits,"
|
|
echo " src_bipp,"
|
|
echo " src_raw1,"
|
|
echo " src_order);"
|
|
echo " pixel ="
|
|
echo " ((src_fifo0"
|
|
echo " >> (src_order == TME_ENDIAN_BIG"
|
|
echo " ? (32 - (src_bipp + ${src_shift}))"
|
|
echo " : ${src_shift})));"
|
|
|
|
echo ""
|
|
echo " /* map the pixel subfields into intensities and accumulate them: */"
|
|
echo " value_g += TME_FB_XLAT_MAP(pixel, src_mask_g, src_mask_i, src_indexed, src->tme_fb_connection_map_g);"
|
|
if test "x${src_class}" != xm; then
|
|
echo " value_r += TME_FB_XLAT_MAP(pixel, src_mask_r, src_mask_i, src_indexed, src->tme_fb_connection_map_r);"
|
|
echo " value_b += TME_FB_XLAT_MAP(pixel, src_mask_b, src_mask_i, src_indexed, src->tme_fb_connection_map_b);"
|
|
fi
|
|
echo ""
|
|
|
|
echo " pixel ="
|
|
echo " ((src_fifo1"
|
|
echo " >> (src_order == TME_ENDIAN_BIG"
|
|
echo " ? (32 - (src_bipp + ${src_shift}))"
|
|
echo " : ${src_shift})));"
|
|
|
|
echo ""
|
|
echo " /* map the pixel subfields into intensities and accumulate them: */"
|
|
echo " value_g += TME_FB_XLAT_MAP(pixel, src_mask_g, src_mask_i, src_indexed, src->tme_fb_connection_map_g);"
|
|
if test "x${src_class}" != xm; then
|
|
echo " value_r += TME_FB_XLAT_MAP(pixel, src_mask_r, src_mask_i, src_indexed, src->tme_fb_connection_map_r);"
|
|
echo " value_b += TME_FB_XLAT_MAP(pixel, src_mask_b, src_mask_i, src_indexed, src->tme_fb_connection_map_b);"
|
|
fi
|
|
echo " }"
|
|
echo ""
|
|
echo " /* otherwise, the third and fourth pixels are already in the"
|
|
echo " visible parts of the source bit FIFOs; we just have to"
|
|
echo " reach over the pixels we already read to get at them: */"
|
|
echo " else {"
|
|
echo " pixel ="
|
|
echo " ((src_fifo0"
|
|
echo " >> (src_order == TME_ENDIAN_BIG"
|
|
echo " ? (32 - (src_bipp + (${src_shift} + src_bipp)))"
|
|
echo " : (${src_shift} + src_bipp))));"
|
|
echo ""
|
|
echo " /* map the pixel subfields into intensities and accumulate them: */"
|
|
echo " value_g += TME_FB_XLAT_MAP(pixel, src_mask_g, src_mask_i, src_indexed, src->tme_fb_connection_map_g);"
|
|
if test "x${src_class}" != xm; then
|
|
echo " value_r += TME_FB_XLAT_MAP(pixel, src_mask_r, src_mask_i, src_indexed, src->tme_fb_connection_map_r);"
|
|
echo " value_b += TME_FB_XLAT_MAP(pixel, src_mask_b, src_mask_i, src_indexed, src->tme_fb_connection_map_b);"
|
|
fi
|
|
echo ""
|
|
echo " pixel ="
|
|
echo " ((src_fifo1"
|
|
echo " >> (src_order == TME_ENDIAN_BIG"
|
|
echo " ? (32 - (src_bipp + (${src_shift} + src_bipp)))"
|
|
echo " : (${src_shift} + src_bipp))));"
|
|
echo ""
|
|
echo " /* map the pixel subfields into intensities and accumulate them: */"
|
|
echo " value_g += TME_FB_XLAT_MAP(pixel, src_mask_g, src_mask_i, src_indexed, src->tme_fb_connection_map_g);"
|
|
if test "x${src_class}" != xm; then
|
|
echo " value_r += TME_FB_XLAT_MAP(pixel, src_mask_r, src_mask_i, src_indexed, src->tme_fb_connection_map_r);"
|
|
echo " value_b += TME_FB_XLAT_MAP(pixel, src_mask_b, src_mask_i, src_indexed, src->tme_fb_connection_map_b);"
|
|
fi
|
|
echo " }"
|
|
indent0=
|
|
src_mask_i='((src_mask_i * 4) + 3)'
|
|
src_mask_i_max='(TME_FB_XLAT_MAP_INDEX_MASK_MAX / 4)'
|
|
fi
|
|
|
|
# if we may have intensities:
|
|
#
|
|
if test "X${indent0}" != XX; then
|
|
echo ""
|
|
indent1=X
|
|
case "x${src_class}" in
|
|
xm)
|
|
echo "${indent0} /* since the source_class is known as monochrome at code-generation"
|
|
echo "${indent0} time, we map the green intensity directly into a pixel. we may have"
|
|
echo "${indent0} to scale the intensity to be in the lookup range: */"
|
|
echo "${indent0} if (src_mask_i > ${src_mask_i_max}) {"
|
|
echo "${indent0} value_g /= TME_FB_XLAT_MAP_LINEAR_SCALE(${src_mask_i}, TME_FB_XLAT_MAP_INDEX_MASK_MAX);"
|
|
echo "${indent0} }"
|
|
echo "${indent0} pixel = dst->tme_fb_connection_map_pixel[value_g];"
|
|
;;
|
|
x)
|
|
echo "${indent0} /* if the source class is monochrome, we map the green intensity"
|
|
echo "${indent0} directly into a pixel. we may have to scale the intensity"
|
|
echo "${indent0} to be in the lookup range: */"
|
|
echo "${indent0} if (src->tme_fb_connection_class == TME_FB_XLAT_CLASS_MONOCHROME) {"
|
|
echo "${indent0} if (src_mask_i > ${src_mask_i_max}) {"
|
|
echo "${indent0} value_g /= TME_FB_XLAT_MAP_LINEAR_SCALE(${src_mask_i}, TME_FB_XLAT_MAP_INDEX_MASK_MAX);"
|
|
echo "${indent0} }"
|
|
echo "${indent0} pixel = dst->tme_fb_connection_map_pixel[value_g];"
|
|
echo "${indent0} }"
|
|
echo ""
|
|
echo "${indent0} /* otherwise, we have to consider all three intensities: */"
|
|
echo "${indent0} else {"
|
|
indent1="${indent0} "
|
|
;;
|
|
*)
|
|
echo "${indent0} /* we have to consider all three intensities: */"
|
|
indent1="${indent0}"
|
|
esac
|
|
|
|
if test "X${indent1}" != "XX"; then
|
|
echo ""
|
|
echo "${indent1} /* if destination intensities are indexed: */"
|
|
echo "${indent1} if (dst_indexed) {"
|
|
echo ""
|
|
echo "${indent1} /* we may have to scale the intensities to be in the lookup range: */"
|
|
echo "${indent1} if (src_mask_i > ${src_mask_i_max}) {"
|
|
echo "${indent1} value_g /= TME_FB_XLAT_MAP_LINEAR_SCALE(${src_mask_i}, TME_FB_XLAT_MAP_INDEX_MASK_MAX);"
|
|
echo "${indent1} value_r /= TME_FB_XLAT_MAP_LINEAR_SCALE(${src_mask_i}, TME_FB_XLAT_MAP_INDEX_MASK_MAX);"
|
|
echo "${indent1} value_b /= TME_FB_XLAT_MAP_LINEAR_SCALE(${src_mask_i}, TME_FB_XLAT_MAP_INDEX_MASK_MAX);"
|
|
echo "${indent1} }"
|
|
echo ""
|
|
echo "${indent1} /* form the pixel: */"
|
|
echo "${indent1} pixel = _TME_FB_XLAT_MAP_INDEX(value_g, dst_mask_g, dst->tme_fb_connection_map_g);"
|
|
echo "${indent1} pixel |= _TME_FB_XLAT_MAP_INDEX(value_r, dst_mask_r, dst->tme_fb_connection_map_r);"
|
|
echo "${indent1} pixel |= _TME_FB_XLAT_MAP_INDEX(value_b, dst_mask_b, dst->tme_fb_connection_map_b);"
|
|
echo "${indent1} }"
|
|
echo ""
|
|
echo "${indent1} /* otherwise, destination intensities are linear: */"
|
|
echo "${indent1} else {"
|
|
echo ""
|
|
echo "${indent1} /* form the pixel: */"
|
|
echo "${indent1} pixel = _TME_FB_XLAT_MAP_LINEAR(value_g, ${src_mask_i}, dst_mask_g);"
|
|
echo "${indent1} pixel |= _TME_FB_XLAT_MAP_LINEAR(value_r, ${src_mask_i}, dst_mask_r);"
|
|
echo "${indent1} pixel |= _TME_FB_XLAT_MAP_LINEAR(value_b, ${src_mask_i}, dst_mask_b);"
|
|
echo ""
|
|
echo "${indent1} /* if destination pixels are indexed: */"
|
|
echo "${indent1} if (dst_masks_default) {"
|
|
echo "${indent1} pixel = dst->tme_fb_connection_map_pixel[pixel];"
|
|
echo "${indent1} }"
|
|
echo "${indent1} }"
|
|
|
|
if test "X${indent1}" != "X${indent0}"; then
|
|
echo "${indent0} }"
|
|
fi
|
|
if test "X${indent0}" != X; then
|
|
echo "${indent0} }"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
if test $scale = _h_; then
|
|
|
|
echo " /* if we just read the last pixels on these"
|
|
echo " source scanlines: */"
|
|
if test `expr ${iter_next} % ${src_unroll}` = 0; then
|
|
echo " if ((src_x +="
|
|
echo " (src_packed"
|
|
echo " ? `expr ${src_unroll} \* 2`"
|
|
echo " : 2))"
|
|
echo " == src_width) {"
|
|
else
|
|
echo " if (!src_packed"
|
|
echo " && (src_x += 2) == src_width) {"
|
|
fi
|
|
echo ""
|
|
echo " /* we need to rapidly shift the source FIFOs"
|
|
echo " to skip not only pad bits and undisplayed"
|
|
echo " pixels on the next line, but actually the"
|
|
echo " *entire* next line."
|
|
echo ""
|
|
echo " note that this sounds like when we're done,"
|
|
echo " the bits at the fronts of the FIFOs will be"
|
|
echo " the *first* pixels on the next scanlines."
|
|
echo ""
|
|
echo " but the bits at the fronts of the FIFOs now"
|
|
echo " are the *last* pixels on the current scanlines -"
|
|
echo " they haven't been shifted off yet. so when"
|
|
echo " we're done, we want one pixel's worth of bits"
|
|
echo " in the FIFOs before the first pixel on the"
|
|
echo " next scanlines: */"
|
|
echo ""
|
|
echo " /* calculate the number of bits that we need"
|
|
echo " to shift the source primary FIFO, after"
|
|
echo " discarding any bits in it now: */"
|
|
echo " src_off = ((src_bypl * 8) - (src_width * src_bipp)) + (src_bypl * 8);"
|
|
echo " src_off -= (src_fifo0_may_be_unaligned"
|
|
echo " ? src_fifo0_bits"
|
|
echo " : 32);"
|
|
echo ""
|
|
echo " /* rapidly advance src_raw0 by the number of"
|
|
echo " whole 32-bit words. this will leave it pointing"
|
|
echo " to the 32-bit word that has the first bit that"
|
|
echo " we want to end up as the first bit in the source"
|
|
echo " primary FIFO: */"
|
|
echo " src_raw0 += (src_off / 32);"
|
|
echo ""
|
|
echo " /* reprime the source primary FIFO: */"
|
|
echo " src_fifo0 = *src_raw0;"
|
|
echo " *TME_FB_XLAT_SRC_OLD(src_raw0) = src_fifo0;"
|
|
echo " src_raw0++;"
|
|
echo " src_fifo0 = ((src_order == TME_ENDIAN_BIG)"
|
|
echo " ? tme_betoh_u32(src_fifo0)"
|
|
echo " : tme_letoh_u32(src_fifo0));"
|
|
echo ""
|
|
echo " /* if the source primary FIFO may be unaligned: */"
|
|
echo " if (src_fifo0_may_be_unaligned) {"
|
|
echo ""
|
|
echo " /* reprime the top half of the FIFO, leaving a"
|
|
echo " total of 64 bits in it: */"
|
|
echo " src_fifo0_next = *src_raw0;"
|
|
echo " *TME_FB_XLAT_SRC_OLD(src_raw0) = src_fifo0_next;"
|
|
echo " src_raw0++;"
|
|
echo " src_fifo0_next = ((src_order == TME_ENDIAN_BIG)"
|
|
echo " ? tme_betoh_u32(src_fifo0_next)"
|
|
echo " : tme_letoh_u32(src_fifo0_next));"
|
|
echo " src_fifo0_bits = 64;"
|
|
echo ""
|
|
echo " /* if we have to shift off bits left over"
|
|
echo " from rapidly advancing whole 32-bit words: */"
|
|
echo " src_off %= 32;"
|
|
echo " if (src_off > 0) {"
|
|
echo " TME_FB_XLAT_SHIFT_SRC(TRUE,"
|
|
echo " src_fifo0,"
|
|
echo " src_fifo0_next,"
|
|
echo " src_fifo0_bits,"
|
|
echo " src_off,"
|
|
echo " src_raw0,"
|
|
echo " src_order);"
|
|
echo " }"
|
|
echo " }"
|
|
echo ""
|
|
echo " /* otherwise, the source primary FIFO is always aligned: */"
|
|
echo " else {"
|
|
echo " assert ((src_off % 32) == 0);"
|
|
echo " }"
|
|
echo ""
|
|
echo " /* calculate the number of bits that we need"
|
|
echo " to shift the source secondary FIFO, after"
|
|
echo " discarding any bits in it now: */"
|
|
echo " src_off = ((src_bypl * 8) - (src_width * src_bipp)) + (src_bypl * 8);"
|
|
echo " src_off -= (src_fifo1_may_be_unaligned"
|
|
echo " ? src_fifo1_bits"
|
|
echo " : 32);"
|
|
echo ""
|
|
echo " /* rapidly advance src_raw1 by the number of"
|
|
echo " whole 32-bit words. this will leave it pointing"
|
|
echo " to the 32-bit word that has the first bit that"
|
|
echo " we want to end up as the first bit in the source"
|
|
echo " secondary FIFO: */"
|
|
echo " src_raw1 += (src_off / 32);"
|
|
echo ""
|
|
echo " /* reprime the source secondary FIFO: */"
|
|
echo " src_fifo1 = *src_raw1;"
|
|
echo " *TME_FB_XLAT_SRC_OLD(src_raw1) = src_fifo1;"
|
|
echo " src_raw1++;"
|
|
echo " src_fifo1 = ((src_order == TME_ENDIAN_BIG)"
|
|
echo " ? tme_betoh_u32(src_fifo1)"
|
|
echo " : tme_letoh_u32(src_fifo1));"
|
|
echo ""
|
|
echo " /* if the source secondary FIFO may be unaligned: */"
|
|
echo " if (src_fifo1_may_be_unaligned) {"
|
|
echo ""
|
|
echo " /* reprime the top half of the FIFO, leaving a"
|
|
echo " total of 64 bits in it: */"
|
|
echo " src_fifo1_next = *src_raw1;"
|
|
echo " *TME_FB_XLAT_SRC_OLD(src_raw1) = src_fifo1_next;"
|
|
echo " src_raw1++;"
|
|
echo " src_fifo1_next = ((src_order == TME_ENDIAN_BIG)"
|
|
echo " ? tme_betoh_u32(src_fifo1_next)"
|
|
echo " : tme_letoh_u32(src_fifo1_next));"
|
|
echo " src_fifo1_bits = 64;"
|
|
echo ""
|
|
echo " /* if we have to shift off bits left over"
|
|
echo " from rapidly advancing whole 32-bit words: */"
|
|
echo " src_off %= 32;"
|
|
echo " if (src_off > 0) {"
|
|
echo " TME_FB_XLAT_SHIFT_SRC(TRUE,"
|
|
echo " src_fifo1,"
|
|
echo " src_fifo1_next,"
|
|
echo " src_fifo1_bits,"
|
|
echo " src_off,"
|
|
echo " src_raw1,"
|
|
echo " src_order);"
|
|
echo " }"
|
|
echo " }"
|
|
echo ""
|
|
echo " /* otherwise, the source secondary FIFO is always aligned: */"
|
|
echo " else {"
|
|
echo " assert ((src_off % 32) == 0);"
|
|
echo " }"
|
|
echo ""
|
|
echo " /* we are now on the first pixel of the next scanline: */"
|
|
echo " src_x = 0;"
|
|
echo " }"
|
|
else
|
|
echo " /* if the source buffer is not packed, and we just"
|
|
echo " read the last pixel on this source scanline: */"
|
|
echo " if (!src_packed"
|
|
echo " && ++src_x == src_width) {"
|
|
echo ""
|
|
echo " /* calculate the number of bits between the"
|
|
echo " last bit of the last pixel and the first bit"
|
|
echo " of the first displayed pixel on the next"
|
|
echo " scanline. this is equal to the number of"
|
|
echo " pad bits plus bits for undisplayed pixels: */"
|
|
echo " src_off = ((src_bypl * 8) - (src_width * src_bipp));"
|
|
echo ""
|
|
echo " /* while there are bits to shift: */"
|
|
echo " for (; src_off > 0; src_off -= TME_MIN(src_off, 32)) {"
|
|
echo ""
|
|
echo " /* shift the source primary FIFO: */"
|
|
echo " TME_FB_XLAT_SHIFT_SRC(src_fifo0_may_be_unaligned,"
|
|
echo " src_fifo0,"
|
|
echo " src_fifo0_next,"
|
|
echo " src_fifo0_bits,"
|
|
echo " TME_MIN(src_off, 32),"
|
|
echo " src_raw0,"
|
|
echo " src_order);"
|
|
echo " }"
|
|
echo ""
|
|
echo " /* we are now on the first pixel of the next scanline: */"
|
|
echo " src_x = 0;"
|
|
echo " }"
|
|
fi
|
|
|
|
if test `expr ${iter_next} % ${src_unroll}` = 0; then
|
|
|
|
echo ""
|
|
if test "${src_fifo_shift}" = 32; then
|
|
echo " /* we've just translated another 32-bit word of the"
|
|
echo " source image, so decrement xlat_run: */"
|
|
echo " xlat_run--;"
|
|
else
|
|
echo " /* if we've just finished translating another 32-bit"
|
|
echo " word of the source image, decrement xlat_run: */"
|
|
echo " if (src_fifo0_bits <= 32 + ${src_fifo_shift}) {"
|
|
echo " xlat_run--;"
|
|
echo " }"
|
|
fi
|
|
echo ""
|
|
echo " /* shift the source primary FIFO: */"
|
|
echo " TME_FB_XLAT_SHIFT_SRC(src_fifo0_may_be_unaligned,"
|
|
echo " src_fifo0,"
|
|
echo " src_fifo0_next,"
|
|
echo " src_fifo0_bits,"
|
|
echo " ${src_fifo_shift},"
|
|
echo " src_raw0,"
|
|
echo " src_order);"
|
|
if test $scale = _h_; then
|
|
echo ""
|
|
echo " /* shift the source secondary FIFO: */"
|
|
echo " TME_FB_XLAT_SHIFT_SRC(src_fifo1_may_be_unaligned,"
|
|
echo " src_fifo1,"
|
|
echo " src_fifo1_next,"
|
|
echo " src_fifo1_bits,"
|
|
echo " ${src_fifo_shift},"
|
|
echo " src_raw1,"
|
|
echo " src_order);"
|
|
fi
|
|
fi
|
|
|
|
# the number of bits to skip in a destination FIFO to get to
|
|
# this iteration's pixel:
|
|
dst_shift=`expr ${iter} % ${dst_unroll}`
|
|
dst_shift='('`expr ${dst_shift} \* ${dst_iter_scale}`' * dst_bipp)'
|
|
|
|
echo ""
|
|
echo " /* put the pixel into the destination primary FIFO: */"
|
|
echo " dst_fifo0 |="
|
|
echo " (pixel"
|
|
echo " << (dst_order == TME_ENDIAN_BIG"
|
|
echo " ? ((32 - dst_bipp) - ${dst_shift})"
|
|
echo " : ${dst_shift}));"
|
|
|
|
if test $scale = _d_; then
|
|
|
|
echo ""
|
|
echo " /* put the pixel into the destination secondary FIFO: */"
|
|
echo " dst_fifo1 |="
|
|
echo " (pixel"
|
|
echo " << (dst_order == TME_ENDIAN_BIG"
|
|
echo " ? ((32 - dst_bipp) - ${dst_shift})"
|
|
echo " : ${dst_shift}));"
|
|
|
|
echo ""
|
|
if test `expr ${dst_bipp} \>= 24` = 1; then
|
|
echo " /* put the pixel into both FIFOs again. in"
|
|
echo " this case, dst_bipp is known to be ${dst_bipp},"
|
|
echo " meaning the FIFOs cannot entirely take these"
|
|
echo " further pixels, so we need to shift the FIFOs: */"
|
|
indent0=""
|
|
indent1=X
|
|
elif test ${dst_bipp} = 0; then
|
|
echo " /* put the pixel into both FIFOs again. if"
|
|
echo " dst_bipp is 24 or greater, the FIFOs can"
|
|
echo " not entirely take these further pixels,"
|
|
echo " so we need to shift the FIFOs: */"
|
|
echo " if (dst_bipp >= 24) {"
|
|
indent0=" "
|
|
indent1=" "
|
|
else
|
|
echo " /* put the pixel into both FIFOs again. in"
|
|
echo " this case, dst_bipp is known to be ${dst_bipp},"
|
|
echo " meaning the FIFOs can take these further pixels"
|
|
echo " without shifting the FIFOs, as long as we shift"
|
|
echo " the pixels one pixel further: */"
|
|
indent0=X
|
|
indent1=""
|
|
fi
|
|
if test "X${indent0}" != "XX"; then
|
|
echo "${indent0} TME_FB_XLAT_SHIFT_DST(dst_fifo0_may_be_unaligned,"
|
|
echo "${indent0} dst_fifo0,"
|
|
echo "${indent0} dst_fifo0_next,"
|
|
echo "${indent0} dst_fifo0_bits,"
|
|
echo "${indent0} dst_bipp,"
|
|
echo "${indent0} dst_raw0,"
|
|
echo "${indent0} dst_order);"
|
|
echo "${indent0} TME_FB_XLAT_SHIFT_DST(dst_fifo1_may_be_unaligned,"
|
|
echo "${indent0} dst_fifo1,"
|
|
echo "${indent0} dst_fifo1_next,"
|
|
echo "${indent0} dst_fifo1_bits,"
|
|
echo "${indent0} dst_bipp,"
|
|
echo "${indent0} dst_raw1,"
|
|
echo "${indent0} dst_order);"
|
|
echo ""
|
|
echo "${indent0} /* now that we've shifted by dst_bipp, we can"
|
|
echo "${indent0} put the further pixels exactly where the"
|
|
echo "${indent0} first pixels went in the FIFOs: */"
|
|
echo "${indent0} dst_fifo0 |="
|
|
echo "${indent0} (pixel"
|
|
echo "${indent0} << (dst_order == TME_ENDIAN_BIG"
|
|
echo "${indent0} ? ((32 - dst_bipp) - ${dst_shift})"
|
|
echo "${indent0} : ${dst_shift}));"
|
|
echo "${indent0} dst_fifo1 |="
|
|
echo "${indent0} (pixel"
|
|
echo "${indent0} << (dst_order == TME_ENDIAN_BIG"
|
|
echo "${indent0} ? ((32 - dst_bipp) - ${dst_shift})"
|
|
echo "${indent0} : ${dst_shift}));"
|
|
fi
|
|
if test ${dst_bipp} = 0; then
|
|
echo " }"
|
|
echo ""
|
|
echo " /* otherwise, the FIFOs can take these further pixels,"
|
|
echo " as long as we shift the pixels one pixel further: */"
|
|
echo " else {"
|
|
fi
|
|
if test "X${indent1}" != "XX"; then
|
|
echo "${indent1} dst_fifo0 |="
|
|
echo "${indent1} (pixel"
|
|
echo "${indent1} << (dst_order == TME_ENDIAN_BIG"
|
|
echo "${indent1} ? ((32 - dst_bipp) - (${dst_shift} + dst_bipp))"
|
|
echo "${indent1} : (${dst_shift} + dst_bipp)));"
|
|
echo "${indent1} dst_fifo1 |="
|
|
echo "${indent1} (pixel"
|
|
echo "${indent1} << (dst_order == TME_ENDIAN_BIG"
|
|
echo "${indent1} ? ((32 - dst_bipp) - (${dst_shift} + dst_bipp))"
|
|
echo "${indent1} : (${dst_shift} + dst_bipp)));"
|
|
fi
|
|
if test ${dst_bipp} = 0; then
|
|
echo " }"
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* if the destination buffer is not packed, and we just"
|
|
echo " wrote the last pixel on this destination scanline: */"
|
|
if test $scale = _d_; then value=2; else value=1; fi
|
|
echo " if (!dst_packed"
|
|
echo " && (dst_x += ${value}) == dst_width) {"
|
|
echo ""
|
|
echo " /* calculate the number of bits between the"
|
|
echo " last bit of the last pixel and the first bit"
|
|
echo " of the first displayed pixel on the next"
|
|
echo " scanline. this is equal to the number of"
|
|
echo " pad bits plus bits for undisplayed pixels: */"
|
|
echo " dst_off = ((dst_bypl * 8) - (dst_width * dst_bipp));"
|
|
echo ""
|
|
echo " /* while there are bits to shift: */"
|
|
echo " for (; dst_off > 0; dst_off -= TME_MIN(dst_off, 32)) {"
|
|
echo ""
|
|
echo " /* shift the destination primary FIFO: */"
|
|
echo " TME_FB_XLAT_SHIFT_DST(dst_fifo0_may_be_unaligned,"
|
|
echo " dst_fifo0,"
|
|
echo " dst_fifo0_next,"
|
|
echo " dst_fifo0_bits,"
|
|
echo " TME_MIN(dst_off, 32),"
|
|
echo " dst_raw0,"
|
|
echo " dst_order);"
|
|
if test $scale = _d_; then
|
|
echo ""
|
|
echo " /* shift the destination secondary FIFO: */"
|
|
echo " TME_FB_XLAT_SHIFT_DST(dst_fifo1_may_be_unaligned,"
|
|
echo " dst_fifo1,"
|
|
echo " dst_fifo1_next,"
|
|
echo " dst_fifo1_bits,"
|
|
echo " TME_MIN(dst_off, 32),"
|
|
echo " dst_raw1,"
|
|
echo " dst_order);"
|
|
fi
|
|
echo " }"
|
|
echo ""
|
|
echo " /* we are now on the first pixel of the next scanline: */"
|
|
echo " dst_x = 0;"
|
|
echo " }"
|
|
|
|
if test `expr ${iter_next} % ${dst_unroll}` = 0; then
|
|
echo ""
|
|
echo " /* shift the destination primary FIFO: */"
|
|
echo " TME_FB_XLAT_SHIFT_DST(dst_fifo0_may_be_unaligned,"
|
|
echo " dst_fifo0,"
|
|
echo " dst_fifo0_next,"
|
|
echo " dst_fifo0_bits,"
|
|
echo " ${dst_fifo_shift},"
|
|
echo " dst_raw0,"
|
|
echo " dst_order);"
|
|
if test $scale = _d_; then
|
|
echo ""
|
|
echo " /* shift the destination secondary FIFO: */"
|
|
echo " TME_FB_XLAT_SHIFT_DST(dst_fifo1_may_be_unaligned,"
|
|
echo " dst_fifo1,"
|
|
echo " dst_fifo1_next,"
|
|
echo " dst_fifo1_bits,"
|
|
echo " ${dst_fifo_shift},"
|
|
echo " dst_raw1,"
|
|
echo " dst_order);"
|
|
fi
|
|
fi
|
|
|
|
iter=${iter_next}
|
|
done
|
|
echo ""
|
|
echo " }"
|
|
|
|
if test `expr ${iter} % ${dst_unroll}` != 0; then
|
|
echo "$PROG internal error - the last iter did not shift the destination FIFOs ($iter and $dst_unroll)" 1>&2
|
|
exit 1
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* if the destination FIFOs may be unaligned, there"
|
|
echo " may be bits left in the FIFO that we need to flush: */"
|
|
echo " if (dst_fifo0_may_be_unaligned"
|
|
echo " && dst_fifo0_bits > 0) {"
|
|
echo " dst_fifo0 = *dst_raw0;"
|
|
echo " if (dst_order == TME_ENDIAN_BIG) {"
|
|
echo " dst_fifo0_next |= (tme_betoh_u32(dst_fifo0) & (0xffffffff >> dst_fifo0_bits));"
|
|
echo " dst_fifo0_next = tme_htobe_u32(dst_fifo0_next);"
|
|
echo " }"
|
|
echo " else {"
|
|
echo " dst_fifo0_next |= (tme_letoh_u32(dst_fifo0) & (0xffffffff << dst_fifo0_bits));"
|
|
echo " dst_fifo0_next = tme_htole_u32(dst_fifo0_next);"
|
|
echo " }"
|
|
echo " *dst_raw0 = dst_fifo0;"
|
|
echo " }"
|
|
if test $scale = _d_; then
|
|
echo " if (dst_fifo1_may_be_unaligned"
|
|
echo " && dst_fifo1_bits > 0) {"
|
|
echo " dst_fifo1 = *dst_raw1;"
|
|
echo " if (dst_order == TME_ENDIAN_BIG) {"
|
|
echo " dst_fifo1_next |= (tme_betoh_u32(dst_fifo1) & (0xffffffff >> dst_fifo1_bits));"
|
|
echo " dst_fifo1_next = tme_htobe_u32(dst_fifo1_next);"
|
|
echo " }"
|
|
echo " else {"
|
|
echo " dst_fifo1_next |= (tme_letoh_u32(dst_fifo1) & (0xffffffff << dst_fifo1_bits));"
|
|
echo " dst_fifo1_next = tme_htole_u32(dst_fifo1_next);"
|
|
echo " }"
|
|
echo " *dst_raw1 = dst_fifo1;"
|
|
echo " }"
|
|
fi
|
|
|
|
echo ""
|
|
echo " /* loop back to compare more 32-bit words: */"
|
|
echo " src_raw0--;"
|
|
echo " }"
|
|
|
|
echo ""
|
|
echo " /* return nonzero iff we did some translating: */"
|
|
echo " return (xlat_run >= 0);"
|
|
|
|
echo ""
|
|
for macro in ${undef_macros}; do
|
|
echo "#undef ${macro}"
|
|
done
|
|
echo "}"
|
|
|
|
done
|
|
done
|
|
|
|
echo ""
|
|
echo "/* the xlat function array: */"
|
|
echo "static const struct tme_fb_xlat tme_fb_xlats[] = {$xlat_array
|
|
};"
|
|
|
|
# done:
|
|
exit 0
|