|
|
1.1 root 1: #! /bin/sh
2:
3: # $Id: fb-xlat-auto.sh,v 1.5 2003/09/29 11:42:56 fredette Exp $
4:
5: # generic/fb-xlat-auto.sh - automatically generates C code
6: # for many framebuffer translation functions:
7:
8: #
9: # Copyright (c) 2003 Matt Fredette
10: # All rights reserved.
11: #
12: # Redistribution and use in source and binary forms, with or without
13: # modification, are permitted provided that the following conditions
14: # are met:
15: # 1. Redistributions of source code must retain the above copyright
16: # notice, this list of conditions and the following disclaimer.
17: # 2. Redistributions in binary form must reproduce the above copyright
18: # notice, this list of conditions and the following disclaimer in the
19: # documentation and/or other materials provided with the distribution.
20: # 3. All advertising materials mentioning features or use of this software
21: # must display the following acknowledgement:
22: # This product includes software developed by Matt Fredette.
23: # 4. The name of the author may not be used to endorse or promote products
24: # derived from this software without specific prior written permission.
25: #
26: # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27: # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28: # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29: # DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
30: # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31: # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32: # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33: # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34: # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35: # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: # POSSIBILITY OF SUCH DAMAGE.
37: #
38:
39: # this script generates one or more C functions. each function
40: # translates an image from a source image format into a destination
41: # image format, optionally halving or doubling the image size in the
42: # process.
43: #
44: # the source and destination image formats are represented by "keys",
45: # strings that describe the different attributes of a format.
46: #
47: # a source image format key has the form: WxHdDbBsSpPoO[_X]
48: #
49: # a destination image format key has the form: dDbBsSpPoO
50: #
51: # all of the lowercase letters and underscores are literals, and all
52: # of the uppercase letters represent attribute values. the different
53: # attributes are:
54: #
55: # W is the width of the source image. if zero, the generated function
56: # will be able to translate source images of any width, but it will be
57: # suboptimal. if nonzero, the generated function will only be able to
58: # translate source images of that width, but it will have some
59: # optimization. this attribute is only used in source keys, since the
60: # destination width is always the scaled source width.
61: #
62: # H is the height of the source image. if zero, the generated
63: # function will be able to translate source images of any height, but
64: # it will be suboptimal. if nonzero, the generated function will only
65: # be able to translate source images of that height, but it will have
66: # some optimization. this attribute is only used in source keys,
67: # since the destination height is always the scaled source height.
68: #
69: # D is the color (d)epth, in bits, of the source/destination image.
70: # if zero, the generated function will be able to handle
71: # source/destination images of any depth, but it will be suboptimal.
72: # if nonzero, the generated function will only be able to handle
73: # source/destination images of that depth, but it will have some
74: # optimization.
75: #
76: # B is the (b)its-per-pixel of the source/destination image. this
77: # must be at least as large as the depth, and it may be larger. if
78: # zero, the generated function will be able to handle
79: # source/destination images of any bits-per-pixel, but it will be
80: # suboptimal. if nonzero, the generated function will only be able to
81: # handle source/destination images of that bits-per-pixel, but it will
82: # have some optimization.
83: #
84: # S is the (s)kip-x-bits of the source/destination image. this is the
85: # number of bits at the beginning of each image scanline that are not
86: # displayed. if an underscore, the generated function will be able to
87: # handle source/destination images with any skip-x-bits, but it will
88: # be suboptimal. if not an underscore, the generated function will
89: # only be able to handle source/destination images with that many
90: # skip-x-bits, but it will have some optimization.
91: #
92: # P is the (p)adding of the source/destination image. this is how
93: # many bits each image scanline is padded to. if zero, the generated
94: # function will be able to handle source/destination images with any
95: # padding, but it will be suboptimal. if nonzero, the generated
96: # function will only be able to handle source/destination images with
97: # that padding, but it will have some optimization.
98: #
99: # O is the byte and bit (o)rder of the source/destination image. this
100: # is always m or l for most- or least-significant, respectively.
101: # there is no "any" wildcard value. this script cannot handle image
102: # formats where a word-unit of pixels has one order for its bytes in
103: # memory, but the opposite order for its pixels within the word-unit.
104: #
105: # X is the optional scaling. it is `h' to halve the source image,
106: # or `d' to double it. this attribute is only used in source keys.
107:
108: # this script generates a set of functions for the product of all
109: # source image formats and all destination image formats.
110: #
111: # "all source image formats" includes all source image formats given
112: # on the command line, plus:
113: #
114: # the "any" source image format, unscaled
115: # the "any" source image format, halved
116: # the "any" source image format, doubled
117: #
118: # "all destination image formats" includes all destination
119: # image formats given on the command line, plus:
120: #
121: # the "any" destination image format
122: #
123: src_all=
124: dst_all=
125: for order in m l; do
126: src_key="0x0d0b0s_p0o${order}"
127: src_all="${src_all} ${src_key} ${src_key}_h ${src_key}_d"
128: dst_all="${dst_all} d0b0s_p0o${order}"
129: done
130:
131: which=
132: for arg
133: do
134: case $arg in
135: src|dst) which=$arg ;;
136: *)
137: if test "x${which}" != x; then
138: eval "${which}_all=\"$arg \$${which}_all\""
139: fi
140: ;;
141: esac
142: done
143:
144: PROG=`basename $0`
145: cat <<EOF
146: /* automatically generated by $PROG, do not edit! */
147:
148: /*
149: * Copyright (c) 2003 Matt Fredette
150: * All rights reserved.
151: *
152: * Redistribution and use in source and binary forms, with or without
153: * modification, are permitted provided that the following conditions
154: * are met:
155: * 1. Redistributions of source code must retain the above copyright
156: * notice, this list of conditions and the following disclaimer.
157: * 2. Redistributions in binary form must reproduce the above copyright
158: * notice, this list of conditions and the following disclaimer in the
159: * documentation and/or other materials provided with the distribution.
160: * 3. All advertising materials mentioning features or use of this software
161: * must display the following acknowledgement:
162: * This product includes software developed by Matt Fredette.
163: * 4. The name of the author may not be used to endorse or promote products
164: * derived from this software without specific prior written permission.
165: *
166: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
167: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
168: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
169: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
170: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
171: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
172: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
173: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
174: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
175: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
176: * POSSIBILITY OF SUCH DAMAGE.
177: */
178:
179: _TME_RCSID("\$Id: fb-xlat-auto.sh,v 1.5 2003/09/29 11:42:56 fredette Exp $");
180:
181: /* the central feature of these translation functions is the "bit
182: FIFO", a first-in, first-out stream of bits. source bit FIFOs are
183: used to read pixel bits out of source images, and destination bit
184: FIFOs are used to write pixel bits into destination images.
185:
186: a bit FIFO has a visible part and an invisible part.
187:
188: the visible part of a bit FIFO is 32 bits wide, meaning the
189: translation code can read (for a source bit FIFO) or write (for a
190: destination bit FIFO) up to 32 bits of pixel data before a bit
191: FIFO shift.
192:
193: the invisible part of a source bit FIFO contains pixel bits that
194: have already been read from the source image memory, but that have
195: yet to be shifted in to the visible part.
196:
197: the invisible part of a destination bit FIFO contains the pixel
198: bits that have been shifted out of the visible part, but that have
199: yet to be written to the destination image memory.
200:
201: depending on various attributes of an image format, it may be
202: possible for the translation code to always read or write the
203: entire 32 visible bits of a bit FIFO at a time, and as a result
204: always shift the bit FIFO 32 bits at a time. this is desirable
205: because it minimizes bit FIFO shifts.
206:
207: when this does happen, it may also be the case that the visible
208: part of the bit FIFO always perfectly corresponds to an aligned
209: 32-bit word in the image buffer.
210:
211: this is the optimal situation, as it makes it unnecessary to track
212: the invisible part in C local variables at all - each 32-bit FIFO
213: shift of a source bit FIFO just reads the next 32-bit word directly
214: into the visible part, and each 32-bit FIFO shift of a destination
215: bit FIFO just writes the next 32-bit word directly out of the
216: visible part.
217:
218: within the visible part of a bit FIFO, which bits belong to which
219: pixels depends on the "order" of the image format. most-significant
220: (big-endian) images have earlier (more to the left on the screen)
221: pixels in more-significant bit positions. least-significant
222: (little-endian) images have earlier pixels in less-significant bit
223: bit positions.
224:
225: bit significance *within* a pixel never depends on image order.
226: once the bits belonging to a pixel have been identified according
227: to image order, the least significant bit in that pixel's value is
228: always the bit with the least absolute value.
229:
230: some pictures may help explain this better. each picture shows the
231: 32 bit visible part of a bit FIFO, with the bits marked from 0
232: (least significant) to 31 (most significant). all of these
233: examples are for a two-bit-deep/two-bits-per-pixel image, and in
234: the visible part sixteen pixels are numbered. lesser numbered
235: pixels are earlier (more to the left on the screen). some of the
236: invisible part is also shown, along with the direction that the bit
237: FIFO shifts in:
238:
239: a source bit FIFO for a little-endian source image with two bits
240: per pixel looks like:
241:
242: |
243: | 31 30 29 28 7 6 5 4 3 2 1 0
244: --+--+--+--+--+--+|+--+--+--+--+- --+--+--+--+--+--+--+--+
245: .. p18 | p17 | p16 ||| p15 | p14 | .. p3 | p2 | p1 | p0 |
246: --+--+--+--+--+--+|+--+--+--+--+- --+--+--+--+--+--+--+--+
247: |
248: invisible part | visible part
249:
250: shift -> shift -> shift -> shift -> shift ->
251:
252: a source bit FIFO for a big-endian source image with two bits per
253: pixel looks like:
254:
255: |
256: 31 30 29 28 27 26 25 26 4 3 2 1 0 |
257: +--+--+--+--+--+--+--+-- -+--+--+--+--+|+--+--+--+--+--+--
258: | p0 | p1 | p2 | p3 .. | p14 | p15 ||| p16 | p17 | p18 ..
259: +--+--+--+--+--+--+--+-- -+--+--+--+--+|+--+--+--+--+--+--
260: |
261: visible part | invisible part
262:
263: <- shift <- shift <- shift <- shift <- shift
264:
265: a destination bit FIFO for a little-endian destination image with
266: two bits per pixel looks like:
267:
268: |
269: 31 30 29 28 27 26 25 26 4 3 2 1 0 |
270: +--+--+--+--+--+--+--+-- -+--+--+--+--+|+--+--+--+--+--+--
271: | p23 | p22 | p21 | p20 .. | p9 | p8 ||| p7 | p6 | p5 ..
272: +--+--+--+--+--+--+--+-- -+--+--+--+--+|+--+--+--+--+--+--
273: |
274: visible part | invisible part
275:
276: shift -> shift -> shift -> shift -> shift ->
277:
278: a destination bit FIFO for a big-endian destination image with
279: two bits per pixel looks like:
280:
281: |
282: | 31 30 29 28 7 6 5 4 3 2 1 0
283: --+--+--+--+--+--+|+--+--+--+--+- --+--+--+--+--+--+--+--+
284: .. p5 | p6 | p7 ||| p8 | p9 | .. p20 | p21 | p22 | p23 |
285: --+--+--+--+--+--+|+--+--+--+--+- --+--+--+--+--+--+--+--+
286: |
287: invisible part | visible part
288:
289: <- shift <- shift <- shift <- shift <- shift
290:
291: each translation function has at least one source bit FIFO and at
292: least one destination bit FIFO. the general idea is to read source
293: pixel value(s) from the source image, map those source pixel
294: value(s) somehow into destination pixel value(s), and write those
295: destination pixel value(s) to the destination image.
296:
297: translation functions that do not scale the image have exactly one
298: source bit FIFO and exactly one destination bit FIFO. one pixel
299: read from the source bit FIFO becomes one pixel written to the
300: destination bit FIFO.
301:
302: translation functions that halve the image size have two source bit
303: FIFOs and one destination bit FIFO. one source bit FIFO sources
304: bits from an even-numbered scanline, and the other sources bits from
305: an odd-numbered scanline. four pixels read from the source bit
306: FIFOs - two from each source bit FIFO, making a 2x2 square - become
307: one pixel written to the destination bit FIFO.
308:
309: translation functions that double the image size have one source
310: bit FIFO and two destination bit FIFOs. one destination bit FIFO
311: sinks bits for an even-numbered scanline, and the other sinks bits
312: for an odd-numbered scanline. one pixel read from the source bit
313: FIFO becomes four pixels written to the destination bit FIFOs -
314: two to each destination bit FIFO, making a 2x2 square.
315:
316: translation functions don't necessarily always translate the entire
317: source image into the entire destination image. instead, the buffer
318: holding the current source image is expected to be twice as large as
319: necessary (plus some overhead), with the second half of the buffer
320: holding a copy of the last translated ("old") source image.
321:
322: before setting up and translating pixels using bit FIFOs, a
323: translation function treats the the current and old source images as
324: an array of aligned 32-bit words and compares them. if it finds no
325: 32-bit word that has changed, no translation is done and the
326: function returns.
327:
328: otherwise, initial source pixel x and y coordinates are derived from
329: the offset of the 32-bit word that failed comparison, and the source
330: primary bit FIFO is primed. if this translation function halves the
331: image size, the source secondary bit FIFO is primed from the same x
332: coordinate on the "other" (think y ^ 1) scanline.
333:
334: then, initial destination pixel x and y coordinates are derived from
335: the initial source x and y coordinates, and the destination primary
336: bit FIFO is primed. if this translation function doubles the image
337: size, the destination secondary bit FIFO is primed from the same x
338: coordinate on the "other" (think y ^ 1) scanline.
339:
340: as mentioned previously, the buffer holding the current source image
341: is expected to be twice as large as necessary (plus some overhead),
342: with the second half of the buffer holding a copy of the last
343: translated ("old") source image.
344:
345: this "overhead" is approximately two extra scanlines worth of data,
346: that is initialized to all-bits-zero and must always remain zero.
347: this extra data is present at the end of both the current ("new")
348: and last translated ("old") source images.
349:
350: these extra, always-blank scanlines guarantee that the pixel
351: translation loop terminates. the pixel translation loop *never*
352: checks for the end of the image buffer. instead, it terminates only
353: after it has read in TME_FB_XLAT_RUN consecutive aligned 32-bit
354: words that have *not* changed between the new and old source images.
355: this small amount of extra memory overhead simplifies the pixel
356: translation loop, because it doesn't have to worry about going past
357: the end of the actual image.
358: */
359:
360:
361: /* macros: */
362:
363: /* given a 32-bit aligned pointer into the current source image, this
364: returns the corresponding 32-bit aligned pointer in the last
365: translated ("old") source image. since the old source image
366: follows the current source image, this is simple pointer arithmetic
367: using src_bypb: */
368: #define TME_FB_XLAT_SRC_OLD(raw) \\
369: ((tme_uint32_t *) (((tme_uint8_t *) (raw)) + src_bypb))
370:
371: /* when the fast, aligned 32-bit word comparison loop finds a word
372: that has changed in the source image, pixels are translated until
373: TME_FB_XLAT_RUN consecutive aligned 32-bit words are processed that
374: have *not* changed in the source image, at which point the fast
375: comparison loop resumes.
376:
377: the idea is that after you've started translating pixels, once the
378: FIFO shift operation has read TME_FB_XLAT_RUN consecutive raw,
379: unchanged 32-bit words, all of the pixels from previous, changed
380: 32-bit words have been translated and shifted out of the source bit
381: FIFO(s), and all bits remaining in the source bit FIFO(s) are for
382: pixels in those unchanged 32-bit words. since the pixels are
383: unchanged, pixel translation can stop, and the entire state of the
384: source bit FIFO(s) can be discarded.
385:
386: so, each time a raw, changed 32-bit word is read, xlat_run is
387: reloaded with TME_FB_XLAT_RUN, and each time 32 bits worth of
388: source image pixels are processed, it is decremented. when it
389: reaches zero, the source bit FIFO(s) are discarded, the destination
390: bit FIFO(s) are flushed, the pixel translation loop breaks and the
391: fast comparison loop continues: */
392: #define TME_FB_XLAT_RUN (2)
393:
394: /* this shifts a source FIFO: */
395: #define TME_FB_XLAT_SHIFT_SRC(unaligned, fifo, next, bits, shift, raw, order)\\
396: do { \\
397: \\
398: /* if the source FIFO may not be 32-bit aligned: */ \\
399: if (unaligned) { \\
400: \\
401: /* we must be shifting between 1 and 32 bits: */ \\
402: assert ((shift) >= 1 && (shift) <= 32); \\
403: \\
404: /* the FIFO must have more than 32 bits in it already: */ \\
405: assert (bits > 32); \\
406: \\
407: /* shift the FIFO: */ \\
408: if ((shift) == 32) { \\
409: fifo = next; \\
410: } \\
411: else if (order == TME_ENDIAN_BIG) { \\
412: fifo = (fifo << ((shift) & 31)) | (next >> (32 - (shift)));\\
413: next <<= ((shift) & 31); \\
414: } \\
415: else { \\
416: fifo = (fifo >> ((shift) & 31)) | (next << (32 - (shift)));\\
417: next >>= ((shift) & 31); \\
418: } \\
419: bits -= (shift); \\
420: \\
421: /* if we have a new 32-bit word to read: */ \\
422: if (bits <= 32) { \\
423: next = *raw; \\
424: if (*TME_FB_XLAT_SRC_OLD(raw) != next) { \\
425: *TME_FB_XLAT_SRC_OLD(raw) = next; \\
426: xlat_run = TME_FB_XLAT_RUN; \\
427: } \\
428: raw++; \\
429: next = (order == TME_ENDIAN_BIG \\
430: ? tme_betoh_u32(next) \\
431: : tme_letoh_u32(next)); \\
432: \\
433: /* before the load, if there were fewer than 32 bits \\
434: remaining in the FIFO, shift bits from the word \\
435: we just loaded into their proper positions: */ \\
436: if (bits < 32) { \\
437: if (order == TME_ENDIAN_BIG) { \\
438: fifo |= (next >> bits); \\
439: next <<= (32 - bits); \\
440: } \\
441: else { \\
442: fifo |= (next << bits); \\
443: next >>= (32 - bits); \\
444: } \\
445: } \\
446: \\
447: /* there are now 32 more bits in the FIFO: */ \\
448: bits += 32; \\
449: } \\
450: } \\
451: \\
452: /* otherwise, if the source FIFO is always 32-bit aligned: */ \\
453: else { \\
454: \\
455: /* we must be shifting exactly 32 bits: */ \\
456: assert((shift) == 32); \\
457: \\
458: /* load the next 32-bit word: */ \\
459: fifo = *raw; \\
460: if (*TME_FB_XLAT_SRC_OLD(raw) != fifo) { \\
461: *TME_FB_XLAT_SRC_OLD(raw) = fifo; \\
462: xlat_run = TME_FB_XLAT_RUN; \\
463: } \\
464: raw++; \\
465: fifo = (order == TME_ENDIAN_BIG \\
466: ? tme_betoh_u32(fifo) \\
467: : tme_letoh_u32(fifo)); \\
468: } \\
469: } while (/* CONSTCOND */ 0)
470:
471: /* this shifts a destination FIFO: */
472: #define TME_FB_XLAT_SHIFT_DST(unaligned, fifo, next, bits, shift, raw, order)\\
473: do { \\
474: \\
475: /* if the destination FIFO may not be 32-bit aligned: */ \\
476: if (unaligned) { \\
477: \\
478: /* we must be shifting between 1 and 32 bits: */ \\
479: assert ((shift) >= 1 && (shift) <= 32); \\
480: \\
481: /* the FIFO must have fewer than 32 bits in it: */ \\
482: assert (bits < 32); \\
483: \\
484: /* shift the FIFO: */ \\
485: if (order == TME_ENDIAN_BIG) { \\
486: next |= (fifo >> bits); \\
487: fifo <<= (32 - bits); \\
488: } \\
489: else { \\
490: next |= (fifo << bits); \\
491: fifo >>= (32 - bits); \\
492: } \\
493: bits += (shift); \\
494: \\
495: /* if we have a completed 32-bit word to write: */ \\
496: if (bits >= 32) { \\
497: *(raw++) = (order == TME_ENDIAN_BIG \\
498: ? tme_htobe_u32(next) \\
499: : tme_htole_u32(next)); \\
500: bits -= 32; \\
501: assert(bits != 0 || fifo == 0); \\
502: next = fifo; \\
503: } \\
504: } \\
505: \\
506: /* the destination FIFO is always 32-bit aligned: */ \\
507: else { \\
508: \\
509: /* we must be shifting exactly 32 bits: */ \\
510: assert((shift) == 32); \\
511: \\
512: /* store the next 32-bit word: */ \\
513: *(raw++) = (order == TME_ENDIAN_BIG \\
514: ? tme_htobe_u32(fifo) \\
515: : tme_htole_u32(fifo)); \\
516: \\
517: } \\
518: \\
519: /* clear the writable part of the FIFO: */ \\
520: fifo = 0; \\
521: } while (/* CONSTCOND */ 0)
522: EOF
523:
524: # the next function number:
525: xlat_next=0
526: xlat_array=
527:
528: # permute over the source possibilities:
529: for src_key in ${src_all}; do
530:
531: # take apart the source possibility:
532: src_parts=${src_key}
533:
534: # get the width:
535: width=`echo ${src_parts} | sed -e 's/^\([0-9][0-9]*\)\(.*\)$/\1/'`
536: src_parts=`echo ${src_parts} | sed -e 's/^\([0-9][0-9]*\)\(.*\)$/\2/'`
537:
538: # get the height:
539: height=`echo ${src_parts} | sed -e 's/^x\([0-9][0-9]*\)\(.*\)$/\1/'`
540: src_parts=`echo ${src_parts} | sed -e 's/^x\([0-9][0-9]*\)\(.*\)$/\2/'`
541:
542: # get the source depth:
543: src_depth=`echo ${src_parts} | sed -e 's/^d\([0-9][0-9]*\)\(.*\)$/\1/'`
544: src_parts=`echo ${src_parts} | sed -e 's/^d\([0-9][0-9]*\)\(.*\)$/\2/'`
545:
546: # get the source bits per pixel:
547: src_bipp=`echo ${src_parts} | sed -e 's/^b\([0-9][0-9]*\)\(.*\)$/\1/'`
548: src_parts=`echo ${src_parts} | sed -e 's/^b\([0-9][0-9]*\)\(.*\)$/\2/'`
549:
550: # get the source skip pixel count:
551: src_skipx=`echo ${src_parts} | sed -e 's/^s\([_0-9][0-9]*\)\(.*\)$/\1/'`
552: src_parts=`echo ${src_parts} | sed -e 's/^s\([_0-9][0-9]*\)\(.*\)$/\2/'`
553:
554: # get the source scanline pad:
555: src_pad=`echo ${src_parts} | sed -e 's/^p\([0-9][0-9]*\)\(.*\)$/\1/'`
556: src_parts=`echo ${src_parts} | sed -e 's/^p\([0-9][0-9]*\)\(.*\)$/\2/'`
557:
558: # get the source "order" - i.e., byte order and leftmost (first)
559: # pixel significance:
560: src_order=`echo ${src_parts} | sed -e 's/^o\([ml]\)\(.*\)$/\1/'`
561: src_parts=`echo ${src_parts} | sed -e 's/^o\([ml]\)\(.*\)$/\2/'`
562:
563: # get the source scaling:
564: scale="${src_parts}_"
565:
566: # permute over the destination possibilities:
567: for dst_key in ${dst_all}; do
568:
569: # take apart the destination possibility:
570: dst_parts=${dst_key}
571:
572: # get the destination depth:
573: dst_depth=`echo ${dst_parts} | sed -e 's/^d\([0-9][0-9]*\)\(.*\)$/\1/'`
574: dst_parts=`echo ${dst_parts} | sed -e 's/^d\([0-9][0-9]*\)\(.*\)$/\2/'`
575:
576: # get the destination bits per pixel:
577: dst_bipp=`echo ${dst_parts} | sed -e 's/^b\([0-9][0-9]*\)\(.*\)$/\1/'`
578: dst_parts=`echo ${dst_parts} | sed -e 's/^b\([0-9][0-9]*\)\(.*\)$/\2/'`
579:
580: # get the destination skip pixel count:
581: dst_skipx=`echo ${dst_parts} | sed -e 's/^s\([_0-9][0-9]*\)\(.*\)$/\1/'`
582: dst_parts=`echo ${dst_parts} | sed -e 's/^s\([_0-9][0-9]*\)\(.*\)$/\2/'`
583:
584: # get the destination scanline pad:
585: dst_pad=`echo ${dst_parts} | sed -e 's/^p\([0-9][0-9]*\)\(.*\)$/\1/'`
586: dst_parts=`echo ${dst_parts} | sed -e 's/^p\([0-9][0-9]*\)\(.*\)$/\2/'`
587:
588: # get the destination "order" - i.e., byte order and leftmost
589: # (first) pixel significance:
590: dst_order=`echo ${dst_parts} | sed -e 's/^o\([ml]\)\(.*\)$/\1/'`
591: dst_parts=`echo ${dst_parts} | sed -e 's/^o\([ml]\)\(.*\)$/\2/'`
592:
593: # when both source and destination depth are known, ignore
594: # this permutation if the source depth is greater:
595: if test $src_depth != 0 \
596: && test $dst_depth != 0 \
597: && test `expr ${src_depth} \> ${dst_depth}` = 1; then
598: continue
599: fi
600:
601: # allocate the xlat number:
602: xlat=${xlat_next}
603: xlat_next=`expr ${xlat_next} + 1`
604: xlat_info="tme_fb_xlat${xlat}"
605:
606: # start the function:
607: echo ""
608: echo "/* this translates frame buffer contents from this source format:"
609: case "${width}x${height}" in
610: 0x0) echo -n " any dimensions" ;;
611: *x0) echo -n " width $width, any height" ;;
612: 0x*) echo -n " any width, height ${height}" ;;
613: *) echo -n " ${width}x${height}" ;;
614: esac
615: xlat_info="${xlat_info}, ${width}, ${height}"
616: case ${scale} in
617: _h_) echo " (image will be halved)" ; value="HALF" ;;
618: _d_) echo " (image will be doubled)" ; value="DOUBLE" ;;
619: *) echo "" ; value="NONE" ;;
620: esac
621: xlat_info="${xlat_info}, TME_FB_XLAT_SCALE_${value}"
622: echo -n " "
623: case ${src_depth} in
624: 0) echo -n "any depth" ;;
625: 1) echo -n "1 bit deep" ;;
626: *) echo -n "${src_depth} bits deep" ;;
627: esac
628: xlat_info="${xlat_info}, ${src_depth}"
629: case ${src_bipp} in
630: 0) echo -n ", any bits per pixel" ;;
631: 1) echo -n ", 1 bit per pixel" ;;
632: *) echo -n ", ${src_bipp} bits per pixel" ;;
633: esac
634: xlat_info="${xlat_info}, ${src_bipp}"
635: case ${src_skipx} in
636: _) echo -n ", any number of pixels skipped" ; value="-1";;
637: *) echo -n ", ${src_skipx} pixels skipped" ; value=${src_skipx} ;;
638: esac
639: xlat_info="${xlat_info}, ${value}"
640: case ${src_pad} in
641: 0) echo -n ", any scanline padding" ;;
642: *) echo -n ", ${src_pad}-bit scanline padding" ;;
643: esac
644: xlat_info="${xlat_info}, ${src_pad}"
645: case ${src_order} in
646: m) echo -n ", MSB-first" ; value="BIG" ;;
647: l) echo -n ", LSB-first" ; value="LITTLE" ;;
648: esac
649: xlat_info="${xlat_info}, TME_ENDIAN_${value}"
650: echo ""
651: echo " to this destination format:"
652: echo -n " "
653: case ${dst_depth} in
654: 0) echo -n "any depth" ;;
655: 1) echo -n "1 bit deep" ;;
656: *) echo -n "${dst_depth} bits deep" ;;
657: esac
658: xlat_info="${xlat_info}, ${dst_depth}"
659: case ${dst_bipp} in
660: 0) echo -n ", any bits per pixel" ;;
661: 1) echo -n ", 1 bit per pixel" ;;
662: *) echo -n ", ${dst_bipp} bits per pixel" ;;
663: esac
664: xlat_info="${xlat_info}, ${dst_bipp}"
665: case ${dst_skipx} in
666: _) echo -n ", any number of pixels skipped" ; value="-1";;
667: *) echo -n ", ${dst_skipx} pixels skipped" ; value=${dst_skipx} ;;
668: esac
669: xlat_info="${xlat_info}, ${value}"
670: case ${dst_pad} in
671: 0) echo -n ", any scanline padding" ;;
672: *) echo -n ", ${dst_pad}-bit scanline padding" ;;
673: esac
674: xlat_info="${xlat_info}, ${dst_pad}"
675: case ${dst_order} in
676: m) echo -n ", MSB-first" ; value="BIG" ;;
677: l) echo -n ", LSB-first" ; value="LITTLE" ;;
678: esac
679: xlat_info="${xlat_info}, TME_ENDIAN_${value}"
680: save_IFS=$IFS
681: IFS=
682: xlat_array="${xlat_array}
683: { $xlat_info }, "
684: IFS=$save_IFS
685: echo ""
686: echo "*/"
687: echo "static int"
688: echo "tme_fb_xlat${xlat}(struct tme_fb_connection *src,"
689: echo " struct tme_fb_connection *dst)"
690: echo "{"
691: undef_macros=
692:
693: echo ""
694: echo " /* whenever possible we define macros instead of declaring"
695: echo " variables, for optimization: */"
696:
697: echo ""
698: echo " /* declare src_x and src_y. these are the current translation"
699: echo " coordinates in the source image: */"
700: echo " unsigned int src_x, src_y;"
701:
702: echo ""
703: echo " /* declare dst_x and dst_y. these are the current translation"
704: echo " coordinates in the destination image. since this function"
705: if test $scale = _; then
706: echo " does not scale the image, these coordinates are always"
707: echo " the same as the coordinates in the source image: */"
708: echo "#define dst_x (src_x)"
709: echo "#define dst_y (src_y)"
710: undef_macros="${undef_macros} dst_x dst_y"
711: scale_op=
712: scale_math=
713: else
714: if test $scale = _h_; then
715: scale_op='/'
716: scale_name='halves'
717: else
718: scale_op='*'
719: scale_name='doubles'
720: fi
721: scale_math=" ${scale_op} 2"
722: echo " ${scale_name} the image, the coordinates in the destination image"
723: echo " are always the coordinates in the source image${scale_math}: */"
724: echo " unsigned int dst_x, dst_y;"
725: fi
726:
727: echo ""
728: echo " /* declare pixel. this holds a single pixel value being translated"
729: echo " for the destination image: */"
730: echo " tme_uint32_t pixel;"
731:
732: if test $scale = _h_ && test $src_depth != 1; then
733: echo ""
734: echo " /* since this function halves the source image, and this"
735: echo " image isn't grayscale, we need to read all pixels in the"
736: echo " 2x2 square in the source image into separate variables"
737: echo " and then make a decision about how to map those four"
738: echo " pixels into one color value for the destination pixel."
739: echo " the above \"pixel\" will hold one of the four pixels,"
740: echo " and these three variables will hold the others: */"
741: echo " tme_uint32_t src_pixel1, src_pixel2, src_pixel3;"
742: fi
743:
744: echo ""
745: echo " /* declare src_width and dst_width. these are in terms of pixels: */"
746: value="(src_width${scale_math})"
747: if test ${width} = 0; then
748: echo " const unsigned int src_width = src->tme_fb_connection_width;"
749: if test $scale != _; then
750: echo " const unsigned int dst_width = ${value};"
751: else
752: echo "#define dst_width ${value}"
753: undef_macros="${undef_macros} dst_width"
754: fi
755: else
756: echo "#define src_width (${width})"
757: echo "#define dst_width ${value}"
758: undef_macros="${undef_macros} src_width dst_width"
759: fi
760:
761: echo ""
762: echo " /* declare src_depth, the source pixel depth, which is in"
763: echo " terms of bits. declare src_mask, which is the corresponding"
764: echo " mask of one bits: */"
765: value="(0xffffffff >> (32 - src_depth))"
766: if test ${src_depth} = 0; then
767: echo " const unsigned int src_depth = src->tme_fb_connection_depth;"
768: echo " const tme_uint32_t src_mask = ${value};"
769: else
770: echo "#define src_depth (${src_depth})"
771: echo "#define src_mask ${value}"
772: undef_macros="${undef_macros} src_depth src_mask"
773: fi
774:
775: echo ""
776: echo " /* declare src_bipp and dst_bipp. these are the bits-per-pixel"
777: echo " values for the source and destination images: */"
778: if test ${src_bipp} = 0; then
779: echo " const unsigned int src_bipp = src->tme_fb_connection_bits_per_pixel;"
780: else
781: echo "#define src_bipp (${src_bipp})"
782: undef_macros="${undef_macros} src_bipp"
783: fi
784: if test ${dst_bipp} = 0; then
785: echo " const unsigned int dst_bipp = dst->tme_fb_connection_bits_per_pixel;"
786: else
787: echo "#define dst_bipp (${dst_bipp})"
788: undef_macros="${undef_macros} dst_bipp"
789: fi
790:
791: echo ""
792: echo " /* declare src_skipx and dst_skipx. these are the counts of"
793: echo " undisplayed pixels at the beginning of each scanline in the"
794: echo " source and destination images: */"
795: if test ${src_skipx} = _; then
796: echo " const unsigned int src_skipx = src->tme_fb_connection_skipx;"
797: else
798: echo "#define src_skipx (${src_skipx})"
799: undef_macros="${undef_macros} src_skipx"
800: fi
801: if test ${dst_skipx} = _; then
802: echo " const unsigned int dst_skipx = dst->tme_fb_connection_skipx;"
803: else
804: echo "#define dst_skipx (${dst_skipx})"
805: undef_macros="${undef_macros} dst_skipx"
806: fi
807:
808: echo ""
809: echo " /* declare src_pad and dst_pad. these are the paddings, in bits,"
810: echo " of each scanline in the source and destination images: */"
811: if test ${src_pad} = 0; then
812: echo " const unsigned int src_pad = src->tme_fb_connection_scanline_pad;"
813: else
814: echo "#define src_pad (${src_pad})"
815: undef_macros="${undef_macros} src_pad"
816: fi
817: if test ${dst_pad} = 0; then
818: echo " const unsigned int dst_pad = dst->tme_fb_connection_scanline_pad;"
819: else
820: echo "#define dst_pad (${dst_pad})"
821: undef_macros="${undef_macros} dst_pad"
822: fi
823:
824: echo ""
825: echo " /* declare src_order and dst_order. these are the bit and byte"
826: echo " orders (either TME_ENDIAN_BIG or TME_ENDIAN_LITTLE) of the"
827: echo " source and destination images. since these values profoundly"
828: echo " affect optimization, they are always constant: */"
829: if test ${src_order} = m; then value=BIG; else value=LITTLE; fi
830: echo "#define src_order (TME_ENDIAN_${value})"
831: undef_macros="${undef_macros} src_order"
832: if test ${dst_order} = m; then value=BIG; else value=LITTLE; fi
833: echo "#define dst_order (TME_ENDIAN_${value})"
834: undef_macros="${undef_macros} dst_order"
835:
836: echo ""
837: echo " /* declare src_bypl and dst_bypl. these are the bytes per scanline"
838: echo " in the source and destination images. these values are calculated"
839: echo " from the count of undisplayed and displayed pixels per scanline,"
840: echo " the number of bits per pixel, and the scanline padding: */"
841: value="(((((src_skipx + src_width) * src_bipp) + (src_pad - 1)) & -src_pad) / 8)"
842: if test ${src_skipx} = _ || test ${width} = 0 || test ${src_bipp} = 0 || test ${src_pad} = 0; then
843: echo " const unsigned int src_bypl = ${value};"
844: src_bypl_var=true
845: else
846: echo "#define src_bypl ${value}"
847: undef_macros="${undef_macros} src_bypl"
848: src_bypl_var=false
849: fi
850: value="(((((dst_skipx + dst_width) * dst_bipp) + (dst_pad - 1)) & -dst_pad) / 8)"
851: if test ${dst_skipx} = _ || test ${width} = 0 || test ${dst_bipp} = 0 || test ${dst_pad} = 0; then
852: echo " const unsigned int dst_bypl = ${value};"
853: dst_bypl_var=true
854: else
855: echo "#define dst_bypl ${value}"
856: undef_macros="${undef_macros} dst_bypl"
857: dst_bypl_var=false
858: fi
859:
860: echo ""
861: echo " /* declare src_packed and dst_packed. these are nonzero iff"
862: echo " every last bit in a scanline belongs to a displayed pixel."
863: echo " put another way, this is zero iff a scanline has undisplayed"
864: echo " pixels at its beginning or padding bits at its end. when"
865: echo " a source image or destination image is packed, translation"
866: echo " doesn't have to worry about skipping FIFO bits to get to"
867: echo " bits belonging to displayed pixels: */"
868: value="((src_width * src_bipp) == (src_bypl * 8))"
869: if $src_bypl_var; then
870: echo " const unsigned int src_packed = ${value};"
871: else
872: echo "#define src_packed ${value}"
873: undef_macros="${undef_macros} src_packed"
874: fi
875: value="((dst_width * dst_bipp) == (dst_bypl * 8))"
876: if $dst_bypl_var; then
877: echo " const unsigned int dst_packed = ${value};"
878: else
879: echo "#define dst_packed ${value}"
880: undef_macros="${undef_macros} dst_packed"
881: fi
882:
883: echo ""
884: echo " /* declare src_bypb and src_bypb_real. src_bypb is the bytes"
885: echo " per source image buffer with the \"translation termination"
886: echo " overhead\" of approximately two extra scanlines. src_bypb_real"
887: echo " is the real bytes per source image buffer with no overhead."
888: echo " both values are padded to a multiple of 4 bytes (32 bits): */"
889: if test ${height} = 0; then
890: value="src->tme_fb_connection_height"
891: else
892: value="${height}"
893: fi
894: value_real="(((${value} * src_bypl) + 3) & -4)"
895: value="((src_bypb_real + (src_bypl * 2)) & -4)"
896: if test ${height} = 0 || $src_bypl_var; then
897: echo " const unsigned int src_bypb_real = ${value_real};"
898: echo " const unsigned int src_bypb = ${value};"
899: else
900: echo "#define src_bypb_real ${value_real}"
901: echo "#define src_bypb ${value}"
902: undef_macros="${undef_macros} src_bypb_real src_bypb"
903: fi
904:
905: echo ""
906: echo " /* declare the source primary bit FIFO:"
907: echo ""
908: echo " src_raw0 points to the next aligned 32-bit word to be"
909: echo " read from the image buffer."
910: echo ""
911: echo " src_fifo0 is the visible part of the bit FIFO."
912: echo ""
913: echo " src_fifo0_next and src_fifo0_bits are only used when the"
914: echo " visible part of the bit FIFO is not guaranteed to always"
915: echo " correspond to an aligned 32-bit word in the image buffer."
916: echo " src_fifo0_next is the invisible part of the bit FIFO,"
917: echo " and src_fifo0_bits tracks the total number of bits in the"
918: echo " visible and invisible parts of the FIFO. */"
919: echo " const tme_uint32_t *src_raw0;"
920: echo " tme_uint32_t src_fifo0, src_fifo0_next;"
921: echo " unsigned int src_fifo0_bits;"
922:
923: if test ${scale} = _h_; then
924: echo ""
925: echo " /* since this function ${scale_name} the image, declare the"
926: echo " source secondary bit FIFO. these variables work in "
927: echo " exactly the same way that their primary counterparts do: */"
928: echo " const tme_uint32_t *src_raw1;"
929: echo " tme_uint32_t src_fifo1, src_fifo1_next;"
930: echo " unsigned int src_fifo1_bits;"
931: fi
932:
933: echo ""
934: echo " /* declare the destination primary bit FIFO:"
935: echo ""
936: echo " dst_raw0 points to the next aligned 32-bit word to be"
937: echo " written into the image buffer."
938: echo ""
939: echo " dst_fifo0 is the visible part of the bit FIFO."
940: echo ""
941: echo " dst_fifo0_next and dst_fifo0_bits are only used when the"
942: echo " visible part of the bit FIFO is not guaranteed to always"
943: echo " correspond to an aligned 32-bit word in the image buffer."
944: echo " dst_fifo0_next is the invisible part of the bit FIFO,"
945: echo " and dst_fifo0_bits tracks the total number of bits in the"
946: echo " invisible part of the FIFO. */"
947: echo " tme_uint32_t *dst_raw0;"
948: echo " tme_uint32_t dst_fifo0, dst_fifo0_next;"
949: echo " unsigned int dst_fifo0_bits;"
950:
951: if test ${scale} = _d_; then
952: echo ""
953: echo " /* since this function ${scale_name} the image, declare"
954: echo " the destination secondary bit FIFO. these variables work"
955: echo " in exactly the same way that their primary counterparts"
956: echo " do: */"
957: echo " tme_uint32_t *dst_raw1;"
958: echo " tme_uint32_t dst_fifo1, dst_fifo1_next;"
959: echo " unsigned int dst_fifo1_bits;"
960: fi
961:
962: echo ""
963: echo " /* declare src_off and dst_off. these are used when priming a"
964: echo " source or destination bit FIFO, to identify an initial aligned"
965: echo " 32-bit word in the source or destination image buffer, and an"
966: echo " initial bit offset within that word: */"
967: echo " unsigned int src_off, dst_off;"
968:
969: echo ""
970: echo " /* declare src_fifo0_may_be_unaligned. this is zero iff all"
971: echo " aligned 32-bit words in the source buffer contain a whole"
972: echo " number of displayed pixels. this is *not* so if the source"
973: echo " buffer is not packed, or if there are 24 bits per pixel -"
974: echo " in this last case, it is possible for a pixel value to cross"
975: echo " a 32-bit boundary: */"
976: value="(!src_packed || (src_bipp == 24))"
977: if $src_bypl_var; then
978: echo " const unsigned int src_fifo0_may_be_unaligned = ${value};"
979: else
980: echo "#define src_fifo0_may_be_unaligned ${value}"
981: undef_macros="${undef_macros} src_fifo0_may_be_unaligned"
982: fi
983:
984: if test $scale = _h_; then
985: echo ""
986: echo " /* declare src_fifo1_may_be_unaligned. this is zero iff all"
987: echo " aligned 32-bit words in the source buffer contain a"
988: echo " whole number of displayed pixels, *and* for every aligned"
989: echo " 32-bit word on one scanline all other scanlines have an"
990: echo " aligned 32-bit word corresponding to the same x coordinate: */"
991: value="(src_fifo0_may_be_unaligned || (src_bypl & 3))"
992: if $src_bypl_var; then
993: echo " const unsigned int src_fifo1_may_be_unaligned = ${value};"
994: else
995: echo "#define src_fifo1_may_be_unaligned ${value}"
996: undef_macros="${undef_macros} src_fifo1_may_be_unaligned"
997: fi
998: fi
999:
1000: echo ""
1001: echo " /* declare dst_fifo0_may_be_unaligned. this is zero iff"
1002: echo " src_fifo0_may_be_unaligned is zero, dst_bypl is 32-bit aligned"
1003: echo " and we can guarantee that any initial dst_x will correspond to"
1004: echo " an aligned 32-bit word in the destination buffer. the motivation"
1005: echo " is to only prime and shift the destination primary bit FIFO if"
1006: echo " absolutely necessary."
1007: echo ""
1008: echo " since we require that src_fifo0_may_be_unaligned is zero, we"
1009: echo " know that the initial src_x = (Z * 32) / src_bipp for "
1010: echo " some Z. we also have the initial dst_x = src_x${scale_math}."
1011: echo " the initial destination bit offset will then be:"
1012: echo ""
1013: echo " (dst_skipx + dst_x) * dst_bipp"
1014: echo " = (dst_skipx * dst_bipp) + (dst_x * dst_bipp)"
1015: echo ""
1016: echo " if we additionally require that (dst_skipx * dst_bipp)"
1017: echo " be 32-bit aligned, this reduces things to:"
1018: echo ""
1019: echo " dst_x * dst_bipp"
1020: echo " = (src_x${scale_math}) * dst_bipp"
1021: echo " = (((Z * 32) / src_bipp)${scale_math}) * dst_bipp"
1022: echo ""
1023: echo " which will be a multiple of 32 iff:"
1024: echo ""
1025: echo " ((1 / src_bipp)${scale_math}) * dst_bipp >= 1 and integral"
1026: echo " */"
1027: denom="src_bipp"
1028: numer="dst_bipp"
1029: case $scale in
1030: _) ;;
1031: _h_) denom="(${denom} * 2)" ;;
1032: _d_) numer="(${numer} * 2)" ;;
1033: esac
1034: value="(src_fifo0_may_be_unaligned || !dst_packed || (dst_bipp == 24) || (dst_bypl % 4) || ((dst_skipx * dst_bipp) % 32) || (${numer} % ${denom}))"
1035: if $src_bypl_var || $dst_bypl_var; then
1036: echo " const unsigned int dst_fifo0_may_be_unaligned = ${value};"
1037: else
1038: echo "#define dst_fifo0_may_be_unaligned ${value}"
1039: undef_macros="${undef_macros} dst_fifo0_may_be_unaligned"
1040: fi
1041:
1042: if test $scale = _d_; then
1043: echo ""
1044: echo " /* declare dst_fifo1_may_be_unaligned. this is zero iff all"
1045: echo " 32-bit aligned values in the destination buffer contain a"
1046: echo " whole number of displayed pixels, and for every 32-bit"
1047: echo " aligned value on one scanline all other scanlines have a"
1048: echo " 32-bit aligned value corresponding to the same x coordinate: */"
1049: value="(dst_fifo0_may_be_unaligned || (dst_bypl & 3))"
1050: if $src_bypl_var || $dst_bypl_var; then
1051: echo " const unsigned int dst_fifo1_may_be_unaligned = ${value};"
1052: else
1053: echo "#define dst_fifo1_may_be_unaligned ${value}"
1054: undef_macros="${undef_macros} dst_fifo1_may_be_unaligned"
1055: fi
1056: fi
1057:
1058: echo ""
1059: echo " /* declare src_raw0_end. when treating the source image as"
1060: echo " an array of aligned 32-bit words, this variable holds the"
1061: echo " address of the first word after the real source image."
1062: echo " if the fast, aligned 32-bit word comparison loop passes"
1063: echo " this point, the entire source image has been processed and"
1064: echo " the function terminates: */"
1065: echo " const tme_uint32_t *src_raw0_end;"
1066:
1067: echo ""
1068: echo " /* declare xlat_run. see the comment for the TME_FB_XLAT_RUN"
1069: echo " macro for an explanation of what this variable does: */"
1070: echo " int xlat_run;"
1071:
1072: echo ""
1073: echo " /* this silences gcc -Wuninitialized: */"
1074: echo " src_fifo0_next = 0;"
1075: echo " src_fifo0_bits = 0;"
1076: if test ${scale} = _h_; then
1077: echo " src_fifo1_next = 0;"
1078: echo " src_fifo1_bits = 0;"
1079: fi
1080: echo " dst_fifo0_next = 0;"
1081: echo " dst_fifo0_bits = 0;"
1082: if test ${scale} = _d_; then
1083: echo " dst_fifo1_next = 0;"
1084: echo " dst_fifo1_bits = 0;"
1085: fi
1086:
1087: echo ""
1088: echo " /* initialize src_raw0 and src_raw0_end for the fast aligned 32-bit"
1089: echo " word comparison loop. on entry to (and when continuing) that loop,"
1090: echo " src_raw0 always points to the aligned 32-bit word *before* the"
1091: echo " next word to check. src_raw0_end always points after the last"
1092: echo " word to check."
1093: echo ""
1094: echo " src_raw0 is actually part of the source primary bit FIFO, which"
1095: echo " is good, because when the fast comparison fails on a word, src_raw0"
1096: echo " is already primed and ready to work for that bit FIFO: */"
1097: echo " src_raw0 = ((const tme_uint32_t *) src->tme_fb_connection_buffer) - 1;"
1098: echo " src_raw0_end = (const tme_uint32_t *) (src->tme_fb_connection_buffer + src_bypb_real);"
1099:
1100: echo ""
1101: echo " /* initialize xlat_run to -1. it can never go negative inside the"
1102: echo " pixel translation loop, so if xlat_run stays negative for the"
1103: echo " entire translation, it means that the source image hasn't changed"
1104: echo " since the last translation. this information is returned to the"
1105: echo " caller to hopefully save more work in updating the display: */"
1106: echo " xlat_run = -1;"
1107:
1108: echo ""
1109: echo " /* this is the main translation loop, which contains the fast aligned"
1110: echo " 32-bit word comparison loop, and the pixel translation loop: */"
1111: echo " for (;;) {"
1112:
1113: echo ""
1114: echo " /* this is the fast aligned 32-bit word comparison loop. it"
1115: echo " terminates either when a word fails comparison, or when the"
1116: echo " entire source image has been compared. the if test that"
1117: echo " follows checks for the latter case and breaks the main"
1118: echo " translation loop: */"
1119: echo " for (; (++src_raw0 < src_raw0_end"
1120: echo " && *src_raw0 == *TME_FB_XLAT_SRC_OLD(src_raw0)); );"
1121: echo " if (src_raw0 >= src_raw0_end) {"
1122: echo " break;"
1123: echo " }"
1124:
1125: echo ""
1126: echo " /* calculate the byte offset into the source buffer of the"
1127: echo " 32-bit word that failed comparison: */"
1128: echo " src_off = ((tme_uint8_t *) src_raw0) - src->tme_fb_connection_buffer;"
1129:
1130: echo ""
1131: echo " /* calculate the source y pixel coordinate, and reduce"
1132: echo " src_off from the byte offset into the buffer to the"
1133: echo " byte offset into that scanline: */"
1134: echo " src_y = src_off / src_bypl;"
1135: echo " src_off = src_off % src_bypl;"
1136:
1137: echo ""
1138: echo " /* while translating pixels, we use one or more \"bit FIFOs\","
1139: echo " each composed of one or more 32-bit integers. we load these"
1140: echo " FIFOs 32 bits at a time. */"
1141: echo ""
1142: echo " /* prime the visible part of the source primary bit FIFO: */"
1143: echo " src_fifo0 = *src_raw0;"
1144: echo " *TME_FB_XLAT_SRC_OLD(src_raw0) = src_fifo0;"
1145: echo " src_raw0++;"
1146: echo " src_fifo0 = ((src_order == TME_ENDIAN_BIG)"
1147: echo " ? tme_betoh_u32(src_fifo0)"
1148: echo " : tme_letoh_u32(src_fifo0));"
1149: echo ""
1150: echo " /* if the source primary bit FIFO may be unaligned: */"
1151: echo " if (src_fifo0_may_be_unaligned) {"
1152: echo ""
1153: echo " /* prime the invisible part of the source primary bit FIFO and"
1154: echo " assume that we will not have to shift it to finish: */"
1155: echo " src_fifo0_next = *src_raw0;"
1156: echo " *TME_FB_XLAT_SRC_OLD(src_raw0) = src_fifo0_next;"
1157: echo " src_raw0++;"
1158: echo " src_fifo0_next = ((src_order == TME_ENDIAN_BIG)"
1159: echo " ? tme_betoh_u32(src_fifo0_next)"
1160: echo " : tme_letoh_u32(src_fifo0_next));"
1161: echo " src_fifo0_bits = 0;"
1162: echo ""
1163: echo " /* if there are pixels that need to be skipped, the first 32 bits"
1164: echo " we loaded into the FIFO may have first bits that belong to"
1165: echo " those undisplayed (skipped) pixels. it is *not* possible for"
1166: echo " it to have first bits that belong to the scanline pad; there"
1167: echo " might be pad bits in the *middle* of the first 32 bits, but any"
1168: echo " first bits *must* belong to pixels, displayed or not: */"
1169: echo " if (src_skipx > 0"
1170: echo " && (src_off * 8) < (src_skipx * src_bipp)) {"
1171: echo ""
1172: echo " /* see how many bits we will need to skip: */"
1173: echo " src_fifo0_bits = (src_skipx * src_bipp) - (src_off * 8);"
1174: echo ""
1175: echo " /* if it is more than 31 bits, this is an entire 32 bits of"
1176: echo " undisplayed pixels. just advance: */"
1177: echo " if (src_fifo0_bits > 31) {"
1178: echo " src_raw0--;"
1179: echo " continue;"
1180: echo " }"
1181: echo ""
1182: echo " /* set the source x coordinate to zero: */"
1183: echo " src_x = 0;"
1184: echo " }"
1185: echo ""
1186: echo " /* otherwise, the first 32 bits we load will have first bits for"
1187: echo " a displayable pixel: */"
1188: echo " else {"
1189: echo ""
1190: echo " /* if the source bits per pixel is 24, calculate the number of"
1191: echo " bytes *before* the original src_raw0 of any split pixel, and"
1192: echo " subtract this from src_off, to leave src_off as the byte offset"
1193: echo " into the scanline of the beginning of a pixel: */"
1194: echo " if (src_bipp == 24) {"
1195: echo " src_fifo0_bits = (src_off % 3);"
1196: echo " src_off -= src_fifo0_bits;"
1197: echo ""
1198: echo " /* if this is a split pixel, we need to prime the source primary"
1199: echo " bit FIFO starting with the part *before* the original src_raw0."
1200: echo " we do not have to copy to the old; it passed comparison: */"
1201: echo " if (src_fifo0_bits) {"
1202: echo " src_raw0--;"
1203: echo " src_fifo0_next = src_fifo0;"
1204: echo " src_fifo0 = ((src_order == TME_ENDIAN_BIG)"
1205: echo " ? tme_betoh_u32(*(src_raw0 - 2))"
1206: echo " : tme_letoh_u32(*(src_raw0 - 2)));"
1207: echo " }"
1208: echo " }"
1209: echo ""
1210: echo " /* calculate the source x coordinate: */"
1211: echo " src_x = ((src_off * 8) / src_bipp) - src_skipx;"
1212: echo " }"
1213: echo ""
1214: echo " /* do any shifting to finish priming the source primary FIFO: */"
1215: echo " if (src_fifo0_bits) {"
1216: echo " if (src_order == TME_ENDIAN_BIG) {"
1217: echo " src_fifo0 = (src_fifo0 << src_fifo0_bits) | (src_fifo0_next >> (32 - src_fifo0_bits));"
1218: echo " src_fifo0_next <<= src_fifo0_bits;"
1219: echo " }"
1220: echo " else {"
1221: echo " src_fifo0 = (src_fifo0 >> src_fifo0_bits) | (src_fifo0_next << (32 - src_fifo0_bits));"
1222: echo " src_fifo0_next >>= src_fifo0_bits;"
1223: echo " }"
1224: echo " }"
1225: echo " src_fifo0_bits = 64 - src_fifo0_bits;"
1226: echo " }"
1227: echo ""
1228: echo " /* otherwise, the source primary FIFO is aligned: */"
1229: echo " else {"
1230: echo " src_x = ((src_off * 8) / src_bipp) - src_skipx;"
1231: echo " }"
1232:
1233: if test $scale = _h_; then
1234: echo ""
1235: echo " /* when halving the image, we have a source secondary bit "
1236: echo " FIFO, providing pixel values at the same source x coordinate"
1237: echo " but on the \"other\" line. prime the source secondary"
1238: echo " bit FIFO: */"
1239: echo " if (src_fifo1_may_be_unaligned) {"
1240: echo ""
1241: echo " /* calculate the bit offset into the source buffer of"
1242: echo " this exact same pixel on the other line: */"
1243: echo " src_off = ((src_y ^ 1) * src_bypl * 8) + ((src_skipx + src_x) * src_bipp);"
1244: echo ""
1245: echo " /* calculate how many bits offset from a 32-bit boundary the pixel is: */"
1246: echo " src_fifo1_bits = src_off % 32;"
1247: echo ""
1248: echo " /* set src_raw1: */"
1249: echo " src_raw1 = (const tme_uint32_t *)"
1250: echo " (src->tme_fb_connection_buffer"
1251: echo " + ((src_off - src_fifo1_bits) / 8));"
1252: echo ""
1253: echo " /* actually prime the FIFO by loading the first two words and"
1254: echo " shifting off any offset bits: */"
1255: echo " src_fifo1 = *src_raw1;"
1256: echo " *TME_FB_XLAT_SRC_OLD(src_raw1) = src_fifo1;"
1257: echo " src_raw1++;"
1258: echo " src_fifo1_next = *src_raw1;"
1259: echo " *TME_FB_XLAT_SRC_OLD(src_raw1) = src_fifo1_next;"
1260: echo " src_raw1++;"
1261: echo " if (src_order == TME_ENDIAN_BIG) {"
1262: echo " src_fifo1 = tme_betoh_u32(src_fifo1);"
1263: echo " src_fifo1_next = tme_betoh_u32(src_fifo1_next);"
1264: echo " if (src_fifo1_bits) {"
1265: echo " src_fifo1 = (src_fifo1 << src_fifo1_bits) | (src_fifo1_next >> (32 - src_fifo1_bits));"
1266: echo " src_fifo1_next <<= src_fifo1_bits;"
1267: echo " }"
1268: echo " }"
1269: echo " else {"
1270: echo " src_fifo1 = tme_letoh_u32(src_fifo1);"
1271: echo " src_fifo1_next = tme_letoh_u32(src_fifo1_next);"
1272: echo " if (src_fifo1_bits) {"
1273: echo " src_fifo1 = (src_fifo1 >> src_fifo1_bits) | (src_fifo1_next << (32 - src_fifo1_bits));"
1274: echo " src_fifo1_next >>= src_fifo1_bits;"
1275: echo " }"
1276: echo " }"
1277: echo " src_fifo1_bits = 64 - src_fifo1_bits;"
1278: echo " }"
1279: echo ""
1280: echo " /* otherwise the source secondary FIFO is aligned: */"
1281: echo " else {"
1282: echo " src_raw1 = (const tme_uint32_t *)"
1283: echo " (((tme_uint8_t *) src_raw0)"
1284: echo " + (("
1285: echo " /* if src_y is even, this addend is now src_bypl * 4,"
1286: echo " else if src_y is odd, this addend is now src_bypl * 2: */"
1287: echo " ((src_bypl * 4) >> (src_y & 1))"
1288: echo " /* if src_y is even, this addend is now src_bypl,"
1289: echo " else if src_y is odd, this addend is now -src_bypl: */"
1290: echo " - (src_bypl * 3))"
1291: echo " /* this -4 compensates for src_raw0 already having"
1292: echo " been advanced by one: */"
1293: echo " - 4));"
1294: echo " src_fifo1 = *src_raw1;"
1295: echo " *TME_FB_XLAT_SRC_OLD(src_raw1) = src_fifo1;"
1296: echo " src_raw1++;"
1297: echo " src_fifo1 = ((src_order == TME_ENDIAN_BIG)"
1298: echo " ? tme_betoh_u32(src_fifo1)"
1299: echo " : tme_letoh_u32(src_fifo1));"
1300: echo " }"
1301: fi
1302:
1303: if test $scale != _; then
1304: echo ""
1305: echo " /* calculate the destination coordinates: */"
1306: echo " dst_y = src_y${scale_math};"
1307: echo " dst_x = src_x${scale_math};"
1308: fi
1309:
1310: echo ""
1311: echo " /* prime the destination primary bit FIFO: */"
1312: echo " dst_fifo0 = 0;"
1313: echo " if (dst_fifo0_may_be_unaligned) {"
1314: echo ""
1315: echo " /* calculate the bit offset into the destination buffer of"
1316: echo " the destination pixel: */"
1317: echo " dst_off = (dst_y * dst_bypl * 8) + ((dst_skipx + dst_x) * dst_bipp);"
1318: echo ""
1319: echo " /* calculate the number of bits that will be in the primed FIFO: */"
1320: echo " dst_fifo0_bits = dst_off % 32;"
1321: echo ""
1322: echo " /* set dst_raw0: */"
1323: echo " dst_raw0 = (tme_uint32_t *)"
1324: echo " (dst->tme_fb_connection_buffer"
1325: echo " + ((dst_off - dst_fifo0_bits) / 8));"
1326: echo ""
1327: echo " /* prime the primary destination FIFO: */"
1328: echo " dst_fifo0_next = 0;"
1329: echo " if (dst_fifo0_bits) {"
1330: echo " dst_fifo0_next = (src_order == TME_ENDIAN_BIG"
1331: echo " ? (tme_betoh_u32(*dst_raw0) & (0xffffffffUL << (32 - dst_fifo0_bits)))"
1332: echo " : (tme_letoh_u32(*dst_raw0) & (0xffffffffUL >> (32 - dst_fifo0_bits))));"
1333: echo " }"
1334: echo " }"
1335: echo ""
1336: echo " /* otherwise the destination primary FIFO is aligned: */"
1337: echo " else {"
1338: echo " dst_off = (dst_y * dst_bypl) + (((dst_skipx + dst_x) * dst_bipp) / 8);"
1339: echo " dst_raw0 = (tme_uint32_t *) (dst->tme_fb_connection_buffer + dst_off);"
1340: echo " }"
1341:
1342: if test $scale = _d_; then
1343: echo ""
1344: echo " /* when doubling the image, we have a destination secondary bit "
1345: echo " FIFO, for pixel values at the same source x coordinate"
1346: echo " but on the \"other\" line. prime the destination secondary"
1347: echo " bit FIFO: */"
1348: echo " dst_fifo1 = 0;"
1349: echo " if (dst_fifo1_may_be_unaligned) {"
1350: echo ""
1351: echo " /* calculate the bit offset into the destination buffer of"
1352: echo " the destination pixel: */"
1353: echo " dst_off = ((dst_y + 1) * dst_bypl * 8) + ((dst_skipx + dst_x) * dst_bipp);"
1354: echo ""
1355: echo " /* calculate the number of bits that will be in the primed FIFO: */"
1356: echo " dst_fifo1_bits = dst_off % 32;"
1357: echo ""
1358: echo " /* set dst_raw1: */"
1359: echo " dst_raw1 = (tme_uint32_t *)"
1360: echo " (dst->tme_fb_connection_buffer"
1361: echo " + ((dst_off - dst_fifo1_bits) / 8));"
1362: echo ""
1363: echo " /* prime the primary destination FIFO: */"
1364: echo " dst_fifo1_next = 0;"
1365: echo " if (dst_fifo1_bits) {"
1366: echo " dst_fifo1_next = (src_order == TME_ENDIAN_BIG"
1367: echo " ? (tme_betoh_u32(*dst_raw1) & (0xffffffffUL << (32 - dst_fifo1_bits)))"
1368: echo " : (tme_letoh_u32(*dst_raw1) & (0xffffffffUL >> (32 - dst_fifo1_bits))));"
1369: echo " }"
1370: echo " }"
1371: echo ""
1372: echo " /* otherwise, the destination secondary FIFO is aligned: */"
1373: echo " else {"
1374: echo " dst_raw1 = (tme_uint32_t *)"
1375: echo " (((tme_uint8_t *) dst_raw0)"
1376: echo " + dst_bypl);"
1377: echo " }"
1378: fi
1379:
1380: # we want to unroll the pixel translation loop to read as many
1381: # source pixels as possible out of the source bit FIFOs and
1382: # write as many destination pixels as possible into the
1383: # destination bit FIFOs before shifting them.
1384: #
1385: # it is very common to want to unroll the translation loop a
1386: # different number of times on source and destination pixels,
1387: # so we always unroll the maximum possible, tracking within
1388: # each unrolled iteration the relative unrolled iteration for
1389: # the source and destination bit FIFOs.
1390: #
1391:
1392: # src_unroll and dst_unroll are the number of times we will
1393: # unroll the translation loop on source and destination
1394: # pixels, respectively. assume no unrolling:
1395: #
1396: src_unroll=1
1397: dst_unroll=1
1398:
1399: # src_iter_scale is the number of source pixels read out of a
1400: # source bit FIFO in one unrolled iteration of the translation
1401: # loop. if this function halves the source image, this is
1402: # two, otherwise this is one.
1403: #
1404: # dst_iter_scale is the number of destination pixels written
1405: # to a destination bit FIFO in one unrolled iteration of the
1406: # translation loop. if this function doubles the source
1407: # image, this is two, otherwise this is one.
1408: #
1409: # src_fifo_shift is the number of bits that the source bit
1410: # FIFO(s) must be shifted after all unrolled iterations on
1411: # source pixels. assume no unrolling, so if this function
1412: # halves the source image and src_bipp is less than 24, two
1413: # pixels' bits must be shifted, otherwise one pixel's bits
1414: # must be shifted.
1415: #
1416: # dst_fifo_shift is the number of bits that the destination bit
1417: # FIFO(s) must be shifted after all unrolled iterations on
1418: # destination pixels. we are assuming no unrolling, so if this
1419: # function doubles the source image and dst_bipp is less than
1420: # 24, two pixels' bits must be shifted, otherwise one pixel's
1421: # bits must be shifted:
1422: #
1423: if test $scale = _h_; then
1424: src_iter_scale=2
1425: src_fifo_shift="(src_bipp < 24 ? (src_bipp * 2) : src_bipp)"
1426: else
1427: src_iter_scale=1
1428: src_fifo_shift="src_bipp"
1429: fi
1430: if test $scale = _d_; then
1431: dst_iter_scale=2
1432: dst_fifo_shift="(dst_bipp < 24 ? (dst_bipp * 2) : dst_bipp)"
1433: else
1434: dst_iter_scale=1
1435: dst_fifo_shift="dst_bipp"
1436: fi
1437:
1438: # if src_bipp is known now, see how many times we can unroll the
1439: # translation loop on source pixels:
1440: #
1441: if test ${src_bipp} != 0; then
1442:
1443: # in general, we can unroll once for each pixel in the
1444: # visible part of a source bit FIFO:
1445: #
1446: src_unroll=`expr 32 / ${src_bipp}`
1447:
1448: # if this function halves the source image, we can unroll
1449: # half as many times:
1450: #
1451: src_unroll=`expr ${src_unroll} / ${src_iter_scale}`
1452:
1453: # if we think we can unroll zero times, this means that
1454: # src_bipp is greater than 16 and this function halves the
1455: # source image - the zero is telling us that two whole
1456: # pixels cannot fit in the visible part of a source bit
1457: # FIFO. so we unroll once on source pixels, and shift
1458: # only one pixel's bits after the unrolling (the halving
1459: # code will be shifting one pixel's worth of bits to get
1460: # to the next pixel it has to read):
1461: #
1462: if test ${src_unroll} = 0; then
1463: src_unroll=1
1464: src_fifo_shift=${src_bipp}
1465:
1466: # otherwise, we will be shifting the entire visible part
1467: # of the source bit FIFO(s) after all unrolled iterations:
1468: #
1469: else
1470: src_fifo_shift=32
1471: fi
1472:
1473: echo ""
1474: echo " /* since src_bipp is known at code-generation time, the"
1475: echo " pixel translation loop is unrolled to translate all"
1476: echo " source pixels in the 32-bit visible part of the source"
1477: echo " bit FIFO(s) before shifting."
1478: echo ""
1479: echo " in this case, src_bipp is known to be ${src_bipp}, so "`expr ${src_unroll} \* ${src_iter_scale}`" pixels will"
1480: echo " be read out of the source bit FIFO(s) before shifting, and"
1481: echo " when the source bit FIFO(s) are shifted, they are shifted"
1482: echo " ${src_fifo_shift} bits at a time: */"
1483: fi
1484:
1485: # if dst_bipp is known now, see how many times we can unroll the
1486: # translation loop on destination pixels:
1487: #
1488: if test ${dst_bipp} != 0; then
1489:
1490: # in general, we can unroll once for each pixel in the
1491: # visible part of a destination bit FIFO:
1492: #
1493: dst_unroll=`expr 32 / ${dst_bipp}`
1494:
1495: # if this function doubles the source image, we can unroll
1496: # half as many times:
1497: #
1498: dst_unroll=`expr ${dst_unroll} / ${dst_iter_scale}`
1499:
1500: # if we think we can unroll zero times, this means that
1501: # dst_bipp is greater than 16 and this function doubles the
1502: # source image - the zero is telling us that two whole
1503: # pixels cannot fit in the visible part of a destination bit
1504: # FIFO. so we unroll once on destination pixels, and shift
1505: # only one pixel's bits after the unrolling (the doubling
1506: # code will be shifting one pixel's worth of bits to get
1507: # out the first pixel it has to write):
1508: #
1509: if test ${dst_unroll} = 0; then
1510: dst_unroll=1
1511: dst_fifo_shift=${dst_bipp}
1512:
1513: # otherwise, we will be shifting the entire visible part
1514: # of the source bit FIFO(s) after all unrolled iterations:
1515: #
1516: else
1517: dst_fifo_shift=32
1518: fi
1519:
1520: echo ""
1521: echo " /* since dst_bipp is known at code-generation time, the pixel"
1522: echo " translation loop is unrolled to translate all destination"
1523: echo " pixels in the 32-bit visible part of the destination bit"
1524: echo " FIFO(s) before shifting."
1525: echo ""
1526: echo " in this case, dst_bipp is known to be ${dst_bipp}, so "`expr ${dst_unroll} \* ${dst_iter_scale}`" pixels will"
1527: echo " be written into the destination bit FIFO(s) before shifting,"
1528: echo " and when the destination bit FIFO(s) are shifted, they are"
1529: echo " shifted ${dst_fifo_shift} bits at a time: */"
1530: fi
1531:
1532: # unroll the translation loop the maximum number amount of times:
1533: #
1534: if test `expr ${src_unroll} \> ${dst_unroll}` = 1; then
1535: unroll=${src_unroll}
1536: else
1537: unroll=${dst_unroll}
1538: fi
1539:
1540: echo ""
1541: echo " /* src_unroll = ${src_unroll}, src_iter_scale = ${src_iter_scale}"
1542: echo " dst_unroll = ${dst_unroll}, dst_iter_scale = ${dst_iter_scale} */"
1543: echo " for (xlat_run = TME_FB_XLAT_RUN;"
1544: echo " xlat_run > 0; ) {"
1545: iter=0
1546:
1547: while test `expr ${iter} \< ${unroll}` = 1; do
1548: echo ""
1549: echo " /* iter #${iter} */"
1550: echo ""
1551: iter_next=`expr ${iter} + 1`
1552:
1553: # the number of bits to skip in a source FIFO to get to
1554: # this iteration's pixel:
1555: src_shift=`expr ${iter} % ${src_unroll}`
1556: src_shift='('`expr ${src_shift} \* ${src_iter_scale}`' * src_bipp)'
1557:
1558: echo " /* get a pixel from the source primary FIFO: */"
1559: echo " pixel ="
1560: echo " ((src_fifo0"
1561: echo " >> (src_order == TME_ENDIAN_BIG"
1562: echo " ? (32 - (src_bipp + ${src_shift}))"
1563: echo " : ${src_shift}))"
1564: echo " & src_mask);"
1565:
1566: if test $scale = _; then
1567:
1568: echo ""
1569: echo " /* map the pixel value from source to destination: */"
1570: echo " if (src_depth == 1) {"
1571: echo " pixel = dst->tme_fb_connection_depth1_map[pixel];"
1572: echo " }"
1573:
1574: elif test $scale = _h_; then
1575:
1576: echo ""
1577: echo " /* get a second pixel, from the source secondary FIFO: */"
1578: if test $src_depth != 1; then
1579: echo " src_pixel1 ="
1580: else
1581: echo " pixel +="
1582: fi
1583: echo " ((src_fifo1"
1584: echo " >> (src_order == TME_ENDIAN_BIG"
1585: echo " ? (32 - (src_bipp + ${src_shift}))"
1586: echo " : ${src_shift}))"
1587: echo " & src_mask);"
1588:
1589: echo ""
1590: echo " /* get third and fourth pixels, from the source primary"
1591: echo " FIFO and source secondary FIFO, respectively. if"
1592: echo " src_bipp is 24 or greater, these pixels are not yet"
1593: echo " entirely in the first parts of the FIFOs, so we need"
1594: echo " to shift: */"
1595: echo " if (src_bipp >= 24) {"
1596: echo " TME_FB_XLAT_SHIFT_SRC(src_fifo0_may_be_unaligned,"
1597: echo " src_fifo0,"
1598: echo " src_fifo0_next,"
1599: echo " src_fifo0_bits,"
1600: echo " src_bipp,"
1601: echo " src_raw0,"
1602: echo " src_order);"
1603: echo " TME_FB_XLAT_SHIFT_SRC(src_fifo1_may_be_unaligned,"
1604: echo " src_fifo1,"
1605: echo " src_fifo1_next,"
1606: echo " src_fifo1_bits,"
1607: echo " src_bipp,"
1608: echo " src_raw1,"
1609: echo " src_order);"
1610: if test $src_depth != 1; then
1611: echo " src_pixel2 ="
1612: else
1613: echo " pixel +="
1614: fi
1615: echo " ((src_fifo0"
1616: echo " >> (src_order == TME_ENDIAN_BIG"
1617: echo " ? (32 - (src_bipp + ${src_shift}))"
1618: echo " : ${src_shift}))"
1619: echo " & src_mask);"
1620: if test $src_depth != 1; then
1621: echo " src_pixel3 ="
1622: else
1623: echo " pixel +="
1624: fi
1625: echo " ((src_fifo1"
1626: echo " >> (src_order == TME_ENDIAN_BIG"
1627: echo " ? (32 - (src_bipp + ${src_shift}))"
1628: echo " : ${src_shift}))"
1629: echo " & src_mask);"
1630: echo " }"
1631: echo ""
1632: echo " /* otherwise, src_pixel2 and src_pixel3 are already in the"
1633: echo " visible parts of the source bit FIFOs; we just have to"
1634: echo " reach over the pixels we already read to get at them: */"
1635: echo " else {"
1636: if test $src_depth != 1; then
1637: echo " src_pixel2 ="
1638: else
1639: echo " pixel +="
1640: fi
1641: echo " ((src_fifo0"
1642: echo " >> (src_order == TME_ENDIAN_BIG"
1643: echo " ? (32 - (src_bipp + (${src_shift} + src_bipp)))"
1644: echo " : (${src_shift} + src_bipp)))"
1645: echo " & src_mask);"
1646: if test $src_depth != 1; then
1647: echo " src_pixel3 ="
1648: else
1649: echo " pixel +="
1650: fi
1651: echo " ((src_fifo1"
1652: echo " >> (src_order == TME_ENDIAN_BIG"
1653: echo " ? (32 - (src_bipp + (${src_shift} + src_bipp)))"
1654: echo " : (${src_shift} + src_bipp)))"
1655: echo " & src_mask);"
1656: echo " }"
1657:
1658: echo ""
1659: echo " /* map all four src_pixels into dst_pixel."
1660: echo " if src_depth is one, this is simple - add all of the"
1661: echo " single-bit pixel values together and look up the"
1662: echo " destination pixel value for that intensity: */"
1663: if test $src_depth = 1; then
1664: echo " pixel = dst->tme_fb_connection_depth1_map[pixel];"
1665: else
1666: echo " if (src_depth == 1) {"
1667: echo " pixel = dst->tme_fb_connection_depth1_map[pixel"
1668: echo " + src_pixel1"
1669: echo " + src_pixel2"
1670: echo " + src_pixel3];"
1671: echo " }"
1672: echo ""
1673: echo " /* otherwise, this is trickier - we need to get the"
1674: echo " R, G, and B values for all four pixels, average"
1675: echo " them together, and look up the (closest) destination"
1676: echo " pixel value for the resulting color: */"
1677: echo " else {"
1678: echo " /* TBD: */"
1679: echo " abort();"
1680: echo " }"
1681: fi
1682: fi
1683:
1684: echo ""
1685: if test $scale = _h_; then
1686:
1687: echo " /* if we just read the last pixels on these"
1688: echo " source scanlines: */"
1689: if test `expr ${iter_next} % ${src_unroll}` = 0; then
1690: echo " if ((src_x +="
1691: echo " (src_packed"
1692: echo " ? `expr ${src_unroll} \* 2`"
1693: echo " : 2))"
1694: echo " == src_width) {"
1695: else
1696: echo " if (!src_packed"
1697: echo " && (src_x += 2) == src_width) {"
1698: fi
1699: echo ""
1700: echo " /* we need to rapidly shift the source FIFOs"
1701: echo " to skip not only pad bits and undisplayed"
1702: echo " pixels on the next line, but actually the"
1703: echo " *entire* next line."
1704: echo ""
1705: echo " note that this sounds like when we're done,"
1706: echo " the bits at the fronts of the FIFOs will be"
1707: echo " the *first* pixels on the next scanlines."
1708: echo ""
1709: echo " but the bits at the fronts of the FIFOs now"
1710: echo " are the *last* pixels on the current scanlines -"
1711: echo " they haven't been shifted off yet. so when"
1712: echo " we're done, we want one pixel's worth of bits"
1713: echo " in the FIFOs before the first pixel on the"
1714: echo " next scanlines: */"
1715: echo ""
1716: echo " /* calculate the number of bits that we need"
1717: echo " to shift the source primary FIFO, after"
1718: echo " discarding any bits in it now: */"
1719: echo " src_off = ((src_bypl * 8) - (src_width * src_bipp)) + (src_bypl * 8);"
1720: echo " src_off -= (src_fifo0_may_be_unaligned"
1721: echo " ? src_fifo0_bits"
1722: echo " : 32);"
1723: echo ""
1724: echo " /* rapidly advance src_raw0 by the number of"
1725: echo " whole 32-bit words. this will leave it pointing"
1726: echo " to the 32-bit word that has the first bit that"
1727: echo " we want to end up as the first bit in the source"
1728: echo " primary FIFO: */"
1729: echo " src_raw0 += (src_off / 32);"
1730: echo ""
1731: echo " /* reprime the source primary FIFO: */"
1732: echo " src_fifo0 = *src_raw0;"
1733: echo " *TME_FB_XLAT_SRC_OLD(src_raw0) = src_fifo0;"
1734: echo " src_raw0++;"
1735: echo " src_fifo0 = ((src_order == TME_ENDIAN_BIG)"
1736: echo " ? tme_betoh_u32(src_fifo0)"
1737: echo " : tme_letoh_u32(src_fifo0));"
1738: echo ""
1739: echo " /* if the source primary FIFO may be unaligned: */"
1740: echo " if (src_fifo0_may_be_unaligned) {"
1741: echo ""
1742: echo " /* reprime the top half of the FIFO, leaving a"
1743: echo " total of 64 bits in it: */"
1744: echo " src_fifo0_next = *src_raw0;"
1745: echo " *TME_FB_XLAT_SRC_OLD(src_raw0) = src_fifo0_next;"
1746: echo " src_raw0++;"
1747: echo " src_fifo0_next = ((src_order == TME_ENDIAN_BIG)"
1748: echo " ? tme_betoh_u32(src_fifo0_next)"
1749: echo " : tme_letoh_u32(src_fifo0_next));"
1750: echo " src_fifo0_bits = 64;"
1751: echo ""
1752: echo " /* if we have to shift off bits left over"
1753: echo " from rapidly advancing whole 32-bit words: */"
1754: echo " src_off %= 32;"
1755: echo " if (src_off > 0) {"
1756: echo " TME_FB_XLAT_SHIFT_SRC(src_fifo0_may_be_unaligned,"
1757: echo " src_fifo0,"
1758: echo " src_fifo0_next,"
1759: echo " src_fifo0_bits,"
1760: echo " src_off,"
1761: echo " src_raw0,"
1762: echo " src_order);"
1763: echo " }"
1764: echo " }"
1765: echo ""
1766: echo " /* otherwise, the source primary FIFO is always aligned: */"
1767: echo " else {"
1768: echo " assert ((src_off % 32) == 0);"
1769: echo " }"
1770: echo ""
1771: echo " /* calculate the number of bits that we need"
1772: echo " to shift the source secondary FIFO, after"
1773: echo " discarding any bits in it now: */"
1774: echo " src_off = ((src_bypl * 8) - (src_width * src_bipp)) + (src_bypl * 8);"
1775: echo " src_off -= (src_fifo1_may_be_unaligned"
1776: echo " ? src_fifo1_bits"
1777: echo " : 32);"
1778: echo ""
1779: echo " /* rapidly advance src_raw1 by the number of"
1780: echo " whole 32-bit words. this will leave it pointing"
1781: echo " to the 32-bit word that has the first bit that"
1782: echo " we want to end up as the first bit in the source"
1783: echo " secondary FIFO: */"
1784: echo " src_raw1 += (src_off / 32);"
1785: echo ""
1786: echo " /* reprime the source secondary FIFO: */"
1787: echo " src_fifo1 = *src_raw1;"
1788: echo " *TME_FB_XLAT_SRC_OLD(src_raw1) = src_fifo1;"
1789: echo " src_raw1++;"
1790: echo " src_fifo1 = ((src_order == TME_ENDIAN_BIG)"
1791: echo " ? tme_betoh_u32(src_fifo1)"
1792: echo " : tme_letoh_u32(src_fifo1));"
1793: echo ""
1794: echo " /* if the source secondary FIFO may be unaligned: */"
1795: echo " if (src_fifo1_may_be_unaligned) {"
1796: echo ""
1797: echo " /* reprime the top half of the FIFO, leaving a"
1798: echo " total of 64 bits in it: */"
1799: echo " src_fifo1_next = *src_raw1;"
1800: echo " *TME_FB_XLAT_SRC_OLD(src_raw1) = src_fifo1_next;"
1801: echo " src_raw1++;"
1802: echo " src_fifo1_next = ((src_order == TME_ENDIAN_BIG)"
1803: echo " ? tme_betoh_u32(src_fifo1_next)"
1804: echo " : tme_letoh_u32(src_fifo1_next));"
1805: echo " src_fifo1_bits = 64;"
1806: echo ""
1807: echo " /* if we have to shift off bits left over"
1808: echo " from rapidly advancing whole 32-bit words: */"
1809: echo " src_off %= 32;"
1810: echo " if (src_off > 0) {"
1811: echo " TME_FB_XLAT_SHIFT_SRC(src_fifo1_may_be_unaligned,"
1812: echo " src_fifo1,"
1813: echo " src_fifo1_next,"
1814: echo " src_fifo1_bits,"
1815: echo " src_off,"
1816: echo " src_raw1,"
1817: echo " src_order);"
1818: echo " }"
1819: echo " }"
1820: echo ""
1821: echo " /* otherwise, the source secondary FIFO is always aligned: */"
1822: echo " else {"
1823: echo " assert ((src_off % 32) == 0);"
1824: echo " }"
1825: echo ""
1826: echo " /* we are now on the first pixel of the next scanline: */"
1827: echo " src_x = 0;"
1828: echo " }"
1829: else
1830: echo " /* if the source buffer is not packed, and we just"
1831: echo " read the last pixel on this source scanline: */"
1832: echo " if (!src_packed"
1833: echo " && ++src_x == src_width) {"
1834: echo ""
1835: echo " /* calculate the number of bits between the"
1836: echo " last bit of the last pixel and the first bit"
1837: echo " of the first displayed pixel on the next"
1838: echo " scanline. this is equal to the number of"
1839: echo " pad bits plus bits for undisplayed pixels: */"
1840: echo " src_off = ((src_bypl * 8) - (src_width * src_bipp));"
1841: echo ""
1842: echo " /* while there are bits to shift: */"
1843: echo " for (; src_off > 0; src_off -= TME_MIN(src_off, 32)) {"
1844: echo ""
1845: echo " /* shift the source primary FIFO: */"
1846: echo " TME_FB_XLAT_SHIFT_SRC(src_fifo0_may_be_unaligned,"
1847: echo " src_fifo0,"
1848: echo " src_fifo0_next,"
1849: echo " src_fifo0_bits,"
1850: echo " TME_MIN(src_off, 32),"
1851: echo " src_raw0,"
1852: echo " src_order);"
1853: echo " }"
1854: echo ""
1855: echo " /* we are now on the first pixel of the next scanline: */"
1856: echo " src_x = 0;"
1857: echo " }"
1858: fi
1859:
1860: if test `expr ${iter_next} % ${src_unroll}` = 0; then
1861: echo ""
1862: echo " /* shift the source primary FIFO: */"
1863: echo " TME_FB_XLAT_SHIFT_SRC(src_fifo0_may_be_unaligned,"
1864: echo " src_fifo0,"
1865: echo " src_fifo0_next,"
1866: echo " src_fifo0_bits,"
1867: echo " ${src_fifo_shift},"
1868: echo " src_raw0,"
1869: echo " src_order);"
1870: if test $scale = _h_; then
1871: echo ""
1872: echo " /* shift the source secondary FIFO: */"
1873: echo " TME_FB_XLAT_SHIFT_SRC(src_fifo1_may_be_unaligned,"
1874: echo " src_fifo1,"
1875: echo " src_fifo1_next,"
1876: echo " src_fifo1_bits,"
1877: echo " ${src_fifo_shift},"
1878: echo " src_raw1,"
1879: echo " src_order);"
1880: fi
1881: echo " xlat_run--;"
1882: fi
1883:
1884: # the number of bits to skip in a destination FIFO to get to
1885: # this iteration's pixel:
1886: dst_shift=`expr ${iter} % ${dst_unroll}`
1887: dst_shift='('`expr ${dst_shift} \* ${dst_iter_scale}`' * dst_bipp)'
1888:
1889: echo ""
1890: echo " /* put the pixel into the destination primary FIFO: */"
1891: echo " dst_fifo0 |="
1892: echo " (pixel"
1893: echo " << (dst_order == TME_ENDIAN_BIG"
1894: echo " ? ((32 - dst_bipp) - ${dst_shift})"
1895: echo " : ${dst_shift}));"
1896:
1897: if test $scale = _d_; then
1898:
1899: echo ""
1900: echo " /* put the pixel into the destination secondary FIFO: */"
1901: echo " dst_fifo1 |="
1902: echo " (pixel"
1903: echo " << (dst_order == TME_ENDIAN_BIG"
1904: echo " ? ((32 - dst_bipp) - ${dst_shift})"
1905: echo " : ${dst_shift}));"
1906:
1907: echo ""
1908: echo " /* put the pixel into both FIFOs again. if"
1909: echo " dst_bipp is 24 or greater, the FIFOs can"
1910: echo " not entirely take these further pixels,"
1911: echo " so we need to shift: */"
1912: echo " if (dst_bipp >= 24) {"
1913: echo " TME_FB_XLAT_SHIFT_DST(dst_fifo0_may_be_unaligned,"
1914: echo " dst_fifo0,"
1915: echo " dst_fifo0_next,"
1916: echo " dst_fifo0_bits,"
1917: echo " dst_bipp,"
1918: echo " dst_raw0,"
1919: echo " dst_order);"
1920: echo " TME_FB_XLAT_SHIFT_DST(dst_fifo1_may_be_unaligned,"
1921: echo " dst_fifo1,"
1922: echo " dst_fifo1_next,"
1923: echo " dst_fifo1_bits,"
1924: echo " dst_bipp,"
1925: echo " dst_raw1,"
1926: echo " dst_order);"
1927: echo " dst_fifo0 |="
1928: echo " (pixel"
1929: echo " << (dst_order == TME_ENDIAN_BIG"
1930: echo " ? ((32 - dst_bipp) - ${dst_shift})"
1931: echo " : ${dst_shift}));"
1932: echo " dst_fifo1 |="
1933: echo " (pixel"
1934: echo " << (dst_order == TME_ENDIAN_BIG"
1935: echo " ? ((32 - dst_bipp) - ${dst_shift})"
1936: echo " : ${dst_shift}));"
1937: echo " }"
1938: echo ""
1939: echo " /* otherwise, the FIFOs can take these further pixels: */"
1940: echo " else {"
1941: echo " dst_fifo0 |="
1942: echo " (pixel"
1943: echo " << (dst_order == TME_ENDIAN_BIG"
1944: echo " ? ((32 - dst_bipp) - (${dst_shift} + dst_bipp))"
1945: echo " : (${dst_shift} + dst_bipp)));"
1946: echo " dst_fifo1 |="
1947: echo " (pixel"
1948: echo " << (dst_order == TME_ENDIAN_BIG"
1949: echo " ? ((32 - dst_bipp) - (${dst_shift} + dst_bipp))"
1950: echo " : (${dst_shift} + dst_bipp)));"
1951: echo " }"
1952: fi
1953:
1954: echo ""
1955: echo " /* if the destination buffer is not packed, and we just"
1956: echo " wrote the last pixel on this destination scanline: */"
1957: if test $scale = _d_; then value=2; else value=1; fi
1958: echo " if (!dst_packed"
1959: echo " && (dst_x += ${value}) == dst_width) {"
1960: echo ""
1961: echo " /* calculate the number of bits between the"
1962: echo " last bit of the last pixel and the first bit"
1963: echo " of the first displayed pixel on the next"
1964: echo " scanline. this is equal to the number of"
1965: echo " pad bits plus bits for undisplayed pixels: */"
1966: echo " dst_off = ((dst_bypl * 8) - (dst_width * dst_bipp));"
1967: echo ""
1968: echo " /* while there are bits to shift: */"
1969: echo " for (; dst_off > 0; dst_off -= TME_MIN(dst_off, 32)) {"
1970: echo ""
1971: echo " /* shift the destination primary FIFO: */"
1972: echo " TME_FB_XLAT_SHIFT_DST(dst_fifo0_may_be_unaligned,"
1973: echo " dst_fifo0,"
1974: echo " dst_fifo0_next,"
1975: echo " dst_fifo0_bits,"
1976: echo " TME_MIN(dst_off, 32),"
1977: echo " dst_raw0,"
1978: echo " dst_order);"
1979: if test $scale = _d_; then
1980: echo ""
1981: echo " /* shift the destination secondary FIFO: */"
1982: echo " TME_FB_XLAT_SHIFT_DST(dst_fifo1_may_be_unaligned,"
1983: echo " dst_fifo1,"
1984: echo " dst_fifo1_next,"
1985: echo " dst_fifo1_bits,"
1986: echo " TME_MIN(dst_off, 32),"
1987: echo " dst_raw1,"
1988: echo " dst_order);"
1989: fi
1990: echo " }"
1991: echo ""
1992: echo " /* we are now on the first pixel of the next scanline: */"
1993: echo " dst_x = 0;"
1994: echo " }"
1995:
1996: if test `expr ${iter_next} % ${dst_unroll}` = 0; then
1997: echo ""
1998: echo " /* shift the destination primary FIFO: */"
1999: echo " TME_FB_XLAT_SHIFT_DST(dst_fifo0_may_be_unaligned,"
2000: echo " dst_fifo0,"
2001: echo " dst_fifo0_next,"
2002: echo " dst_fifo0_bits,"
2003: echo " ${dst_fifo_shift},"
2004: echo " dst_raw0,"
2005: echo " dst_order);"
2006: if test $scale = _d_; then
2007: echo ""
2008: echo " /* shift the destination secondary FIFO: */"
2009: echo " TME_FB_XLAT_SHIFT_DST(dst_fifo1_may_be_unaligned,"
2010: echo " dst_fifo1,"
2011: echo " dst_fifo1_next,"
2012: echo " dst_fifo1_bits,"
2013: echo " ${dst_fifo_shift},"
2014: echo " dst_raw1,"
2015: echo " dst_order);"
2016: fi
2017: fi
2018:
2019: iter=${iter_next}
2020: done
2021: echo ""
2022: echo " }"
2023:
2024: if test `expr ${iter} % ${dst_unroll}` != 0; then
2025: echo "$PROG internal error - the last iter did not shift the destination FIFOs ($iter and $dst_unroll)" 1>&2
2026: exit 1
2027: fi
2028:
2029: echo ""
2030: echo " /* if the destination FIFOs may be unaligned, there"
2031: echo " may be bits left in the FIFO that we need to flush: */"
2032: echo " if (dst_fifo0_may_be_unaligned"
2033: echo " && dst_fifo0_bits > 0) {"
2034: echo " dst_fifo0 = *dst_raw0;"
2035: echo " if (dst_order == TME_ENDIAN_BIG) {"
2036: echo " dst_fifo0_next |= (tme_betoh_u32(dst_fifo0) & (0xffffffff >> dst_fifo0_bits));"
2037: echo " dst_fifo0_next = tme_htobe_u32(dst_fifo0_next);"
2038: echo " }"
2039: echo " else {"
2040: echo " dst_fifo0_next |= (tme_letoh_u32(dst_fifo0) & (0xffffffff << dst_fifo0_bits));"
2041: echo " dst_fifo0_next = tme_htole_u32(dst_fifo0_next);"
2042: echo " }"
2043: echo " *dst_raw0 = dst_fifo0;"
2044: echo " }"
2045: if test $scale = _d_; then
2046: echo " if (dst_fifo1_may_be_unaligned"
2047: echo " && dst_fifo1_bits > 0) {"
2048: echo " dst_fifo1 = *dst_raw1;"
2049: echo " if (dst_order == TME_ENDIAN_BIG) {"
2050: echo " dst_fifo1_next |= (tme_betoh_u32(dst_fifo1) & (0xffffffff >> dst_fifo1_bits));"
2051: echo " dst_fifo1_next = tme_htobe_u32(dst_fifo1_next);"
2052: echo " }"
2053: echo " else {"
2054: echo " dst_fifo1_next |= (tme_letoh_u32(dst_fifo1) & (0xffffffff << dst_fifo1_bits));"
2055: echo " dst_fifo1_next = tme_htole_u32(dst_fifo1_next);"
2056: echo " }"
2057: echo " *dst_raw1 = dst_fifo1;"
2058: echo " }"
2059: fi
2060:
2061: echo ""
2062: echo " /* loop back to compare more 32-bit words: */"
2063: echo " src_raw0--;"
2064: echo " }"
2065:
2066: echo ""
2067: echo " /* return nonzero iff we did some translating: */"
2068: echo " return (xlat_run >= 0);"
2069:
2070: echo ""
2071: for macro in ${undef_macros}; do
2072: echo "#undef ${macro}"
2073: done
2074: echo "}"
2075:
2076: done
2077: done
2078:
2079: echo ""
2080: echo "/* the xlat function array: */"
2081: echo "static const struct tme_fb_xlat tme_fb_xlats[] = {$xlat_array
2082: };"
2083:
2084: # done:
2085: exit 0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.