1
/* Copyright (c) 2005 Advanced Micro Devices, Inc.
3
* Permission is hereby granted, free of charge, to any person obtaining a copy
4
* of this software and associated documentation files (the "Software"), to
5
* deal in the Software without restriction, including without limitation the
6
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
* sell copies of the Software, and to permit persons to whom the Software is
8
* furnished to do so, subject to the following conditions:
10
* The above copyright notice and this permission notice shall be included in
11
* all copies or substantial portions of the Software.
13
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* Neither the name of the Advanced Micro Devices, Inc. nor the names of its
22
* contributors may be used to endorse or promote products derived from this
23
* software without specific prior written permission.
27
* This file contains routines to program the 2D acceleration hardware for
28
* the second generation graphics unit.
30
* Basic rendering routines (common to all Geode processors):
32
* gfx_set_solid_pattern
33
* gfx_set_mono_pattern
34
* gfx_set_color_pattern
35
* gfx_set_solid_source
37
* gfx_set_raster_operation
39
* gfx_color_pattern_fill
40
* gfx_screen_to_screen_blt
41
* gfx_screen_to_screen_xblt
42
* gfx_color_bitmap_to_screen_blt
43
* gfx_color_bitmap_to_screen_xblt
44
* gfx_mono_bitmap_to_screen_blt
48
* Extended rendering routines for second generation functionality:
49
* gfx2_set_source_stride
50
* gfx2_set_destination_stride
51
* gfx2_set_pattern_origins
52
* gfx2_set_source_transparency
54
* gfx2_set_alpha_value
56
* gfx2_color_pattern_fill
57
* gfx2_screen_to_screen_blt
58
* gfx2_mono_expand_blt
59
* gfx2_color_bitmap_to_screen_blt
60
* gfx2_mono_bitmap_to_screen_blt
65
#define GU2_WAIT_PENDING \
66
while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING)
67
#define GU2_WAIT_BUSY \
68
while(READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY)
69
#define GU2_WAIT_HALF_EMPTY \
70
while(!(READ_GP32(MGP_BLT_STATUS) & MGP_BS_HALF_EMPTY))
72
/* PATTERN SWIZZLES */
74
#define WORD_SWIZZLE(x) (((x) << 16) | ((x) >> 16))
75
#define BYTE_SWIZZLE(x) (((x) << 24) | ((x) >> 24) | (((x) << 8) & \
76
0x00FF0000) | (((x) >> 8) & 0x0000FF00))
78
/* GLOBAL VARIABLES USED BY THE RENDERING ROUTINES */
80
unsigned long gu2_bpp;
81
unsigned long gu2_pitch = 1280;
82
unsigned long gu2_src_pitch = 1280;
83
unsigned long gu2_dst_pitch = 1280;
84
unsigned long gu2_xshift = 1;
85
unsigned long gu2_pattern_origin = 0;
86
unsigned long gu2_rop32;
87
unsigned long gu2_alpha32 = 0;
88
unsigned long gu2_alpha_value = 0;
89
unsigned long gu2_alpha_mode = 0;
90
unsigned long gu2_alpha_active = 0;
91
unsigned short gu2_alpha_blt_mode = 0;
92
unsigned short gu2_alpha_vec_mode = 0;
93
unsigned short gu2_blt_mode = 0;
94
unsigned short gu2_vector_mode = 0;
95
unsigned short gu2_bm_throttle = 0;
96
unsigned short gu2_vm_throttle = 0;
97
int gu2_current_line = 0;
100
void gfx_reset_pitch(unsigned short pitch);
102
/*---------------------------------------------------------------------------
103
* GFX_RESET_PITCH (PRIVATE ROUTINE - NOT PART OF API)
105
* This routine resets all pitches in the graphics engine to one value.
106
*---------------------------------------------------------------------------
108
#if GFX_2DACCEL_DYNAMIC
110
gu2_reset_pitch(unsigned short pitch)
113
gfx_reset_pitch(unsigned short pitch)
117
gu2_dst_pitch = pitch;
118
gu2_src_pitch = pitch;
121
/*---------------------------------------------------------------------------
124
* This routine sets the bits per pixel value in the graphics engine.
125
* It is also stored in the static variable "gu2_bpp" to use in the future
126
* calls to the rendering routines. That variable contains the hardware
127
* specific value to load into the MGP_RASTER_MODE register.
128
*---------------------------------------------------------------------------
130
#if GFX_2DACCEL_DYNAMIC
132
gu2_set_bpp(unsigned short bpp)
135
gfx_set_bpp(unsigned short bpp)
140
/* COVERT TO BPP/FORMAT VALUE */
141
/* Save in global to combine with ROP later. */
142
/* Could write register here and then use byte access for */
143
/* the ROP, but would need to set other 24 bits to make */
144
/* sure all are set to their appropriate values. */
148
gu2_bpp = MGP_RM_BPPFMT_332;
152
gu2_bpp = MGP_RM_BPPFMT_4444;
156
gu2_bpp = MGP_RM_BPPFMT_1555;
160
gu2_bpp = MGP_RM_BPPFMT_565;
164
gu2_bpp = MGP_RM_BPPFMT_8888;
169
/* SET INITIAL ROP BASED ONLY ON BPP */
170
/* Needs to be set before loading any pattern or source colors. */
171
/* We must wait for BUSY because these bits are not pipelined */
172
/* in the hardware. */
175
WRITE_GP32(MGP_RASTER_MODE, gu2_bpp);
179
*---------------------------------------------------------------------------
180
* GFX_SET_SOLID_SOURCE
182
* This routine is used to specify a solid source color. For the Xfree96
183
* display driver, the source color is used to specify a planemask and the
184
* ROP is adjusted accordingly.
185
*---------------------------------------------------------------------------
187
#if GFX_2DACCEL_DYNAMIC
189
gu2_set_solid_source(unsigned long color)
192
gfx_set_solid_source(unsigned long color)
195
/* CLEAR TRANSPARENCY FLAG */
199
/* WRITE REGISTERS TO SPECIFY SOURCE COLOR */
202
WRITE_GP32(MGP_SRC_COLOR_FG, color);
206
*---------------------------------------------------------------------------
207
* GFX_SET_MONO_SOURCE
209
* This routine is used to specify the monochrome source colors.
210
* It must be called *after* loading any pattern data (those routines
211
* clear the source flags).
212
*---------------------------------------------------------------------------
214
#if GFX_2DACCEL_DYNAMIC
216
gu2_set_mono_source(unsigned long bgcolor, unsigned long fgcolor,
217
unsigned short transparent)
220
gfx_set_mono_source(unsigned long bgcolor, unsigned long fgcolor,
221
unsigned short transparent)
224
/* SET TRANSPARENCY FLAG */
226
GFXsourceFlags = transparent ? MGP_RM_SRC_TRANS : 0;
228
/* WRITE COLOR VALUES */
231
WRITE_GP32(MGP_SRC_COLOR_FG, fgcolor);
232
WRITE_GP32(MGP_SRC_COLOR_BG, bgcolor);
236
*---------------------------------------------------------------------------
237
* GFX_SET_SOLID_PATTERN
239
* This routine is used to specify a solid pattern color. It is called
240
* before performing solid rectangle fills or more complicated BLTs that
241
* use a solid pattern color.
243
* The driver should always call "gfx_load_raster_operation" after a call
244
* to this routine to make sure that the pattern flags are set appropriately.
245
*---------------------------------------------------------------------------
247
#if GFX_2DACCEL_DYNAMIC
249
gu2_set_solid_pattern(unsigned long color)
252
gfx_set_solid_pattern(unsigned long color)
255
/* CLEAR TRANSPARENCY FLAG */
259
/* SET PATTERN FLAGS */
263
/* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */
266
WRITE_GP32(MGP_RASTER_MODE, gu2_bpp);
267
WRITE_GP32(MGP_PAT_COLOR_0, color);
271
*---------------------------------------------------------------------------
272
* GFX_SET_MONO_PATTERN
274
* This routine is used to specify a monochrome pattern.
275
*---------------------------------------------------------------------------
277
#if GFX_2DACCEL_DYNAMIC
279
gu2_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor,
280
unsigned long data0, unsigned long data1,
281
unsigned char transparent)
284
gfx_set_mono_pattern(unsigned long bgcolor, unsigned long fgcolor,
285
unsigned long data0, unsigned long data1,
286
unsigned char transparent)
289
/* CLEAR TRANSPARENCY FLAG */
293
/* SET PATTERN FLAGS */
296
GFXpatternFlags = MGP_RM_PAT_MONO | MGP_RM_PAT_TRANS;
298
GFXpatternFlags = MGP_RM_PAT_MONO;
300
/* POLL UNTIL ABLE TO WRITE THE PATTERN COLOR */
303
WRITE_GP32(MGP_RASTER_MODE, gu2_bpp | GFXpatternFlags);
304
WRITE_GP32(MGP_PAT_COLOR_0, bgcolor);
305
WRITE_GP32(MGP_PAT_COLOR_1, fgcolor);
306
WRITE_GP32(MGP_PAT_DATA_0, data0);
307
WRITE_GP32(MGP_PAT_DATA_1, data1);
311
*---------------------------------------------------------------------------
312
* GFX_SET_COLOR_PATTERN
314
* This routine is used to specify a color pattern.
315
*---------------------------------------------------------------------------
317
#if GFX_2DACCEL_DYNAMIC
319
gu2_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor,
320
unsigned long data0, unsigned long data1,
321
unsigned long data2, unsigned long data3,
322
unsigned char transparent)
325
gfx_set_color_pattern(unsigned long bgcolor, unsigned long fgcolor,
326
unsigned long data0, unsigned long data1,
327
unsigned long data2, unsigned long data3,
328
unsigned char transparent)
335
*---------------------------------------------------------------------------
336
* GFX_LOAD_COLOR_PATTERN_LINE
338
* This routine is used to load a single line of a 8x8 color pattern.
339
*--------------------------------------------------------------------------- */
340
#if GFX_2DACCEL_DYNAMIC
342
gu2_load_color_pattern_line(short y, unsigned long *pattern_8x8)
345
gfx_load_color_pattern_line(short y, unsigned long *pattern_8x8)
348
unsigned long temp1, temp2, temp3, temp4;
350
/* CLEAR TRANSPARENCY FLAG */
354
/* SET PATTERN FLAGS */
356
GFXpatternFlags = MGP_RM_PAT_COLOR;
358
/* OVERRIDE THE RASTER MODE REGISTER */
359
/* If the pattern format is set to anything but color */
360
/* before loading the registers, some of the data will */
361
/* be duplicated according to the current mode. */
364
WRITE_GP32(MGP_RASTER_MODE,
365
(gu2_rop32 & ~MGP_RM_PAT_FLAGS) | MGP_RM_PAT_COLOR);
367
/* LOAD THE PATTERN DATA */
368
/* This routine is designed to work in tandem with gfx_pattern_fill. */
369
/* It is used for cases when multiple BLTs with color pattern data */
370
/* are desired on the same line. It would be inefficient to */
371
/* repeatedly call gfx_color_pattern_fill for each single-line BLT. */
372
/* So, we will simply replicate the pattern data across all available */
373
/* lines such that the pattern y origin plays no part in the BLT. */
377
if (gu2_xshift == 0) {
378
pattern_8x8 += (y & 7) << 1;
379
temp1 = BYTE_SWIZZLE(pattern_8x8[0]);
380
temp2 = BYTE_SWIZZLE(pattern_8x8[1]);
381
WRITE_GP32(MGP_PAT_DATA_1, temp1);
382
WRITE_GP32(MGP_PAT_DATA_0, temp2);
383
WRITE_GP32(MGP_PAT_COLOR_1, temp1);
384
WRITE_GP32(MGP_PAT_COLOR_0, temp2);
387
WRITE_GP32(MGP_PAT_COLOR_3, temp1);
388
WRITE_GP32(MGP_PAT_COLOR_2, temp2);
389
WRITE_GP32(MGP_PAT_COLOR_5, temp1);
390
WRITE_GP32(MGP_PAT_COLOR_4, temp2);
392
else if (gu2_xshift == 1) {
393
pattern_8x8 += (y & 7) << 2;
394
temp1 = WORD_SWIZZLE(pattern_8x8[0]);
395
temp2 = WORD_SWIZZLE(pattern_8x8[1]);
396
temp3 = WORD_SWIZZLE(pattern_8x8[2]);
397
temp4 = WORD_SWIZZLE(pattern_8x8[3]);
399
WRITE_GP32(MGP_PAT_COLOR_1, temp1);
400
WRITE_GP32(MGP_PAT_COLOR_0, temp2);
401
WRITE_GP32(MGP_PAT_DATA_1, temp3);
402
WRITE_GP32(MGP_PAT_DATA_0, temp4);
405
WRITE_GP32(MGP_PAT_COLOR_5, temp1);
406
WRITE_GP32(MGP_PAT_COLOR_4, temp2);
407
WRITE_GP32(MGP_PAT_COLOR_3, temp3);
408
WRITE_GP32(MGP_PAT_COLOR_2, temp4);
411
pattern_8x8 += (y & 7) << 3;
413
WRITE_GP32(MGP_PAT_COLOR_1, pattern_8x8[4]);
414
WRITE_GP32(MGP_PAT_COLOR_0, pattern_8x8[5]);
415
WRITE_GP32(MGP_PAT_DATA_1, pattern_8x8[6]);
416
WRITE_GP32(MGP_PAT_DATA_0, pattern_8x8[7]);
419
WRITE_GP32(MGP_PAT_COLOR_5, pattern_8x8[0]);
420
WRITE_GP32(MGP_PAT_COLOR_4, pattern_8x8[1]);
421
WRITE_GP32(MGP_PAT_COLOR_3, pattern_8x8[2]);
422
WRITE_GP32(MGP_PAT_COLOR_2, pattern_8x8[3]);
427
*---------------------------------------------------------------------------
428
* GFX_SET_RASTER_OPERATION
430
* This routine loads the specified raster operation. It sets the pattern
431
* flags appropriately.
432
*---------------------------------------------------------------------------
434
#if GFX_2DACCEL_DYNAMIC
436
gu2_set_raster_operation(unsigned char rop)
439
gfx_set_raster_operation(unsigned char rop)
444
/* DISABLE ALPHA BLENDING */
446
gu2_alpha_active = 0;
448
/* GENERATE 32-BIT VERSION OF ROP WITH PATTERN FLAGS */
450
gu2_rop32 = (unsigned long) rop | GFXpatternFlags | gu2_bpp;
452
/* CHECK IF SOURCE FLAGS SHOULD BE MERGED */
454
if ((rop & 0x33) ^ ((rop >> 2) & 0x33))
455
gu2_rop32 |= GFXsourceFlags;
459
/* SET FLAG INDICATING ROP REQUIRES DESTINATION DATA */
460
/* True if even bits (0:2:4:6) do not equal the corresponding */
461
/* even bits (1:3:5:7). */
463
if ((rop & 0x55) ^ ((rop >> 1) & 0x55)) {
464
gu2_blt_mode |= MGP_BM_DST_REQ;
465
gu2_vector_mode = MGP_VM_DST_REQ;
473
*----------------------------------------------------------------------------
476
* This routine is used to fill a rectangular region. The pattern must
477
* be previously loaded using one of GFX_load_*_pattern routines. Also, the
478
* raster operation must be previously specified using the
479
* "GFX_load_raster_operation" routine.
481
* X screen X position (left)
482
* Y screen Y position (top)
483
* WIDTH width of rectangle, in pixels
484
* HEIGHT height of rectangle, in scanlines
485
*----------------------------------------------------------------------------
487
#if GFX_2DACCEL_DYNAMIC
489
gu2_pattern_fill(unsigned short x, unsigned short y,
490
unsigned short width, unsigned short height)
493
gfx_pattern_fill(unsigned short x, unsigned short y,
494
unsigned short width, unsigned short height)
497
unsigned long offset = 0, size;
499
size = (((unsigned long) width) << 16) | height;
501
/* CALCULATE STARTING OFFSET */
503
offset = (unsigned long) y *gu2_pitch + (((unsigned long) x) << gu2_xshift);
505
/* CHECK IF PATTERN ORIGINS NEED TO BE SET */
507
if (GFXpatternFlags) {
508
/* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */
510
offset |= ((unsigned long) (x & 7)) << 26;
511
offset |= ((unsigned long) (y & 7)) << 29;
514
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
515
/* Put off poll for as long as possible (do most calculations first). */
518
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
519
WRITE_GP32(MGP_DST_OFFSET, offset);
520
WRITE_GP32(MGP_WID_HEIGHT, size);
521
WRITE_GP32(MGP_STRIDE, gu2_pitch);
522
WRITE_GP32(MGP_BLT_MODE, gu2_blt_mode);
526
*----------------------------------------------------------------------------
527
* GFX_COLOR_PATTERN_FILL
529
* This routine is used to render a rectangle using the current raster
530
* operation and the specified color pattern. It allows an 8x8 color
531
* pattern to be rendered without multiple calls to the gfx_set_color_pattern
532
* and gfx_pattern_fill routines.
534
* X screen X position (left)
535
* Y screen Y position (top)
536
* WIDTH width of rectangle, in pixels
537
* HEIGHT height of rectangle, in scanlines
538
* *PATTERN pointer to 8x8 color pattern data
539
*----------------------------------------------------------------------------
541
#if GFX_2DACCEL_DYNAMIC
543
gu2_color_pattern_fill(unsigned short x, unsigned short y,
544
unsigned short width, unsigned short height,
545
unsigned long *pattern)
548
gfx_color_pattern_fill(unsigned short x, unsigned short y,
549
unsigned short width, unsigned short height,
550
unsigned long *pattern)
553
/* CALL GFX2 ROUTINE TO AVOID DUPLICATION OF CODE */
555
unsigned long offset = (unsigned long) y * gu2_pitch +
556
(((unsigned long) x) << gu2_xshift);
557
unsigned long origin = gu2_pattern_origin;
558
unsigned long pitch = gu2_dst_pitch;
560
gfx2_set_pattern_origin(x, y);
561
gfx2_set_destination_stride((unsigned short) gu2_pitch);
562
gfx2_color_pattern_fill(offset, width, height, pattern);
564
/* RESTORE GFX2 VALUES */
566
gu2_pattern_origin = origin;
567
gu2_dst_pitch = pitch;
571
*----------------------------------------------------------------------------
572
* SCREEN TO SCREEN BLT
574
* This routine should be used to perform a screen to screen BLT when the
575
* ROP does not require destination data.
577
* SRCX screen X position to copy from
578
* SRCY screen Y position to copy from
579
* DSTX screen X position to copy to
580
* DSTY screen Y position to copy to
581
* WIDTH width of rectangle, in pixels
582
* HEIGHT height of rectangle, in scanlines
583
*----------------------------------------------------------------------------
585
#if GFX_2DACCEL_DYNAMIC
587
gu2_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
588
unsigned short dstx, unsigned short dsty,
589
unsigned short width, unsigned short height)
592
gfx_screen_to_screen_blt(unsigned short srcx, unsigned short srcy,
593
unsigned short dstx, unsigned short dsty,
594
unsigned short width, unsigned short height)
597
unsigned long srcoffset, dstoffset, size;
598
unsigned short blt_mode;
600
size = (((unsigned long) width) << 16) | height;
602
/* CALCULATE THE DIRECTION OF THE BLT */
604
blt_mode = (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK) | MGP_BM_SRC_FB;
606
blt_mode |= MGP_BM_NEG_XDIR;
611
blt_mode |= MGP_BM_NEG_YDIR;
616
/* CALCULATE STARTING OFFSETS */
618
srcoffset = (unsigned long) srcy *gu2_pitch +
619
(((unsigned long) srcx) << gu2_xshift);
620
dstoffset = ((unsigned long) dsty * gu2_pitch +
621
(((unsigned long) dstx) << gu2_xshift)) & 0xFFFFFF;
623
/* MERGE PATTERN INFORMATION */
624
/* This must be done after the x and y coordinates have been updated, */
625
/* as the x and y pattern origins correspond to the first ROPed pixel. */
627
if (GFXpatternFlags) {
628
/* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */
630
dstoffset |= ((unsigned long) (dstx & 7)) << 26;
631
dstoffset |= ((unsigned long) (dsty & 7)) << 29;
634
/* TURN INTO BYTE ADDRESS IF NEGATIVE X DIRECTION */
635
/* This is a quirk of the hardware. */
637
if (blt_mode & MGP_BM_NEG_XDIR) {
638
srcoffset += (1 << gu2_xshift) - 1;
639
dstoffset += (1 << gu2_xshift) - 1;
642
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
643
/* Put off poll for as long as possible (do most calculations first). */
646
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
647
WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
648
WRITE_GP32(MGP_DST_OFFSET, dstoffset);
649
WRITE_GP32(MGP_WID_HEIGHT, size);
650
WRITE_GP32(MGP_STRIDE, gu2_pitch | (gu2_pitch << 16));
651
WRITE_GP16(MGP_BLT_MODE, blt_mode);
655
*----------------------------------------------------------------------------
656
* SCREEN TO SCREEN TRANSPARENT BLT
658
* This routine should be used to perform a screen to screen BLT when a
659
* specified color should by transparent. The only supported ROP is SRCCOPY.
661
* SRCX screen X position to copy from
662
* SRCY screen Y position to copy from
663
* DSTX screen X position to copy to
664
* DSTY screen Y position to copy to
665
* WIDTH width of rectangle, in pixels
666
* HEIGHT height of rectangle, in scanlines
667
* COLOR transparent color
668
*----------------------------------------------------------------------------
670
#if GFX_2DACCEL_DYNAMIC
672
gu2_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy,
673
unsigned short dstx, unsigned short dsty,
674
unsigned short width, unsigned short height,
678
gfx_screen_to_screen_xblt(unsigned short srcx, unsigned short srcy,
679
unsigned short dstx, unsigned short dsty,
680
unsigned short width, unsigned short height,
686
/* SAVE ORIGINAL RASTER MODE SETTINGS */
690
/* WRITE REGISTERS TO SPECIFY COLOR TRANSPARENCY */
691
/* Match GU1 implementation that only allows SRCCOPY for the ROP. */
694
WRITE_GP32(MGP_SRC_COLOR_FG, color);
695
WRITE_GP32(MGP_SRC_COLOR_BG, 0xFFFFFFFF);
697
/* SET GLOBAL RASTER SETTINGS */
698
/* This is needed, as the screen-to-screen BLT */
699
/* routine will overwrite the raster mode register. */
701
gu2_rop32 = gu2_bpp | MGP_RM_SRC_TRANS | 0xCC;
703
/* CALL NORMAL SCREEN TO SCREEN BLT ROUTINE */
705
gfx_screen_to_screen_blt(srcx, srcy, dstx, dsty, width, height);
707
/* RESTORE GLOBAL RASTER SETTINGS */
713
*----------------------------------------------------------------------------
714
* COLOR BITMAP TO SCREEN BLT
716
* This routine transfers color bitmap data to the screen.
718
* SRCX X offset within source bitmap
719
* SRCY Y offset within source bitmap
720
* DSTX screen X position to render data
721
* DSTY screen Y position to render data
722
* WIDTH width of rectangle, in pixels
723
* HEIGHT height of rectangle, in scanlines
724
* *DATA pointer to bitmap data
725
* PITCH pitch of bitmap data (bytes between scanlines)
727
* Transparency is handled by another routine.
728
*----------------------------------------------------------------------------
731
#if GFX_2DACCEL_DYNAMIC
733
gu2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
734
unsigned short dstx, unsigned short dsty,
735
unsigned short width, unsigned short height,
736
unsigned char *data, long pitch)
739
gfx_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
740
unsigned short dstx, unsigned short dsty,
741
unsigned short width, unsigned short height,
742
unsigned char *data, long pitch)
745
unsigned long dstoffset, srcoffset, size, bytes;
746
unsigned long offset, temp_offset;
747
unsigned long dword_bytes, bytes_extra;
748
unsigned short blt_mode;
750
blt_mode = (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK) | MGP_BM_SRC_FB;
751
size = (((unsigned long) width) << 16) | 1;
753
/* CALCULATE STARTING OFFSETS */
755
offset = (unsigned long) srcy *pitch + ((unsigned long) srcx << gu2_xshift);
757
dstoffset = (unsigned long) dsty *gu2_pitch +
758
(((unsigned long) dstx) << gu2_xshift);
760
/* CHECK IF PATTERN ORIGINS NEED TO BE SET */
762
if (GFXpatternFlags) {
763
/* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */
765
dstoffset |= ((unsigned long) (dstx & 7)) << 26;
766
dstoffset |= ((unsigned long) (dsty & 7)) << 29;
769
bytes = width << gu2_xshift;
770
dword_bytes = bytes & ~0x3L;
771
bytes_extra = bytes & 0x3L;
773
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
774
/* Put off poll for as long as possible (do most calculations first). */
775
/* The source offset is always 0 since we allow misaligned dword reads. */
776
/* We must wait for BLT busy because the GP may be executing a screen */
777
/* to screen BLT from the scratchpad area. */
780
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
781
WRITE_GP32(MGP_WID_HEIGHT, size);
782
WRITE_GP32(MGP_STRIDE, gu2_pitch);
784
/* WRITE DATA ONE LINE AT A TIME */
785
/* For speed reasons, data is written to an offscreen scratch area and then */
786
/* BLTed using a screen to screen BLT. This is similar to the GX1 BLT buffers, but */
787
/* slightly more efficient in that we can queue up data while the GP is rendering */
791
temp_offset = offset;
792
srcoffset = gfx_gx2_scratch_base;
793
if (gu2_current_line)
797
WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
798
WRITE_GP32(MGP_DST_OFFSET, dstoffset);
799
dstoffset += gu2_pitch;
800
dstoffset += 0x20000000;
802
WRITE_FRAME_BUFFER_STRING32(srcoffset, dword_bytes, data, temp_offset);
804
temp_offset += dword_bytes;
805
srcoffset += dword_bytes;
806
WRITE_FRAME_BUFFER_STRING8(srcoffset, bytes_extra, data,
809
WRITE_GP16(MGP_BLT_MODE, blt_mode);
811
gu2_current_line = 1 - gu2_current_line;
816
*----------------------------------------------------------------------------
817
* COLOR BITMAP TO SCREEN TRANSPARENT BLT
819
* This routine transfers color bitmap data to the screen with transparency.
820
* The transparent color is specified. The only supported ROP is SRCCOPY,
821
* meaning that transparency cannot be applied if the ROP requires
822
* destination data (this is a hardware restriction).
824
* SRCX X offset within source bitmap
825
* SRCY Y offset within source bitmap
826
* DSTX screen X position to render data
827
* DSTY screen Y position to render data
828
* WIDTH width of rectangle, in pixels
829
* HEIGHT height of rectangle, in scanlines
830
* *DATA pointer to bitmap data
831
* PITCH pitch of bitmap data (bytes between scanlines)
832
* COLOR transparent color
833
*----------------------------------------------------------------------------
835
#if GFX_2DACCEL_DYNAMIC
837
gu2_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy,
838
unsigned short dstx, unsigned short dsty,
839
unsigned short width, unsigned short height,
840
unsigned char *data, long pitch,
844
gfx_color_bitmap_to_screen_xblt(unsigned short srcx, unsigned short srcy,
845
unsigned short dstx, unsigned short dsty,
846
unsigned short width, unsigned short height,
847
unsigned char *data, long pitch,
853
/* SAVE EXISTING RASTER MODE SETTINGS */
857
/* WRITE REGISTERS TO SPECIFY COLOR TRANSPARENCY */
858
/* Match GU1 implementation that only allows SRCCOPY for the ROP. */
861
WRITE_GP32(MGP_SRC_COLOR_FG, color);
862
WRITE_GP32(MGP_SRC_COLOR_BG, 0xFFFFFFFF);
864
/* SET GLOBAL RASTER SETTINGS */
865
/* This is needed, as the screen-to-screen BLT */
866
/* routine will overwrite the raster mode register. */
868
gu2_rop32 = gu2_bpp | MGP_RM_SRC_TRANS | 0xCC;
870
/* CALL NORMAL COLOR BITMAP TO SCREEN BLT ROUTINE */
872
gfx_color_bitmap_to_screen_blt(srcx, srcy, dstx, dsty, width, height,
875
/* RESTORE RASTER SETTINGS */
881
*----------------------------------------------------------------------------
882
* MONOCHROME BITMAP TO SCREEN BLT
884
* This routine transfers monochrome bitmap data to the screen.
886
* SRCX X offset within source bitmap
887
* SRCY Y offset within source bitmap
888
* DSTX screen X position to render data
889
* DSTY screen Y position to render data
890
* WIDTH width of rectangle, in pixels
891
* HEIGHT height of rectangle, in scanlines
892
* *DATA pointer to bitmap data
893
* PITCH pitch of bitmap data (bytes between scanlines)
894
*----------------------------------------------------------------------------
896
#if GFX_2DACCEL_DYNAMIC
898
gu2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
899
unsigned short dstx, unsigned short dsty,
900
unsigned short width, unsigned short height,
901
unsigned char *data, short pitch)
904
gfx_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
905
unsigned short dstx, unsigned short dsty,
906
unsigned short width, unsigned short height,
907
unsigned char *data, short pitch)
910
unsigned long dstoffset, size, bytes;
911
unsigned long offset, temp_offset, temp1 = 0, temp2 = 0;
912
unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra;
913
unsigned long shift = 0;
915
size = (((unsigned long) width) << 16) | height;
917
/* CALCULATE STARTING OFFSETS */
919
offset = (unsigned long) srcy *pitch + ((unsigned long) srcx >> 3);
921
dstoffset = (unsigned long) dsty *gu2_pitch +
922
(((unsigned long) dstx) << gu2_xshift);
924
/* CHECK IF PATTERN ORIGINS NEED TO BE SET */
926
if (GFXpatternFlags) {
927
/* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */
929
dstoffset |= ((unsigned long) (dstx & 7)) << 26;
930
dstoffset |= ((unsigned long) (dsty & 7)) << 29;
933
bytes = ((srcx & 7) + width + 7) >> 3;
934
fifo_lines = bytes >> 5;
935
dwords_extra = (bytes & 0x0000001Cl) >> 2;
936
bytes_extra = bytes & 0x00000003l;
938
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
939
/* Put off poll for as long as possible (do most calculations first). */
940
/* The source offset is always 0 since we allow misaligned dword reads. */
941
/* Need to wait for busy instead of pending, since hardware clears */
942
/* the host data FIFO at the beginning of a BLT. */
945
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
946
WRITE_GP32(MGP_SRC_OFFSET, ((unsigned long) srcx & 7) << 26);
947
WRITE_GP32(MGP_DST_OFFSET, dstoffset);
948
WRITE_GP32(MGP_WID_HEIGHT, size);
949
WRITE_GP32(MGP_STRIDE, gu2_pitch);
950
WRITE_GP16(MGP_BLT_MODE,
951
(gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK) | MGP_BM_SRC_HOST |
954
/* WAIT FOR BLT TO BE LATCHED */
958
/* WRITE ALL OF THE DATA TO THE HOST SOURCE REGISTER */
961
temp_offset = offset;
963
/* WRITE ALL FULL FIFO LINES */
965
for (i = 0; i < fifo_lines; i++) {
967
WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset,
972
/* WRITE ALL FULL DWORDS */
976
WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data,
978
temp_offset += (dwords_extra << 2);
981
/* WRITE REMAINING BYTES */
985
WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data,
986
temp_offset, temp1, temp2);
992
/*---------------------------------------------------------------------------
995
* This routine is similar to the gfx_mono_bitmap_to_screen_blt routine
996
* but assumes that source data is byte-packed.
997
*---------------------------------------------------------------------------
999
#if GFX_2DACCEL_DYNAMIC
1001
gu2_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width,
1002
unsigned short height, unsigned char *data)
1005
gfx_text_blt(unsigned short dstx, unsigned short dsty, unsigned short width,
1006
unsigned short height, unsigned char *data)
1009
unsigned long size, bytes;
1010
unsigned long dstoffset, temp1 = 0, temp2 = 0, temp_offset = 0;
1011
unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra;
1012
unsigned long shift;
1014
size = (((unsigned long) width) << 16) | height;
1016
dstoffset = (unsigned long) dsty *gu2_pitch +
1017
(((unsigned long) dstx) << gu2_xshift);
1019
/* CHECK IF PATTERN ORIGINS NEED TO BE SET */
1021
if (GFXpatternFlags) {
1022
/* COMBINE X AND Y PATTERN ORIGINS WITH OFFSET */
1024
dstoffset |= ((unsigned long) (dstx & 7)) << 26;
1025
dstoffset |= ((unsigned long) (dsty & 7)) << 29;
1028
/* CALCULATE STARTING OFFSETS */
1030
bytes = ((width + 7) >> 3) * height;
1031
fifo_lines = bytes >> 5;
1032
dwords_extra = (bytes & 0x0000001Cl) >> 2;
1033
bytes_extra = bytes & 0x00000003l;
1035
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
1038
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
1039
WRITE_GP32(MGP_SRC_OFFSET, 0);
1040
WRITE_GP32(MGP_DST_OFFSET, dstoffset);
1041
WRITE_GP32(MGP_WID_HEIGHT, size);
1042
WRITE_GP32(MGP_STRIDE, gu2_pitch);
1043
WRITE_GP16(MGP_BLT_MODE,
1044
(gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK) | MGP_BM_SRC_HOST |
1045
MGP_BM_SRC_BP_MONO);
1047
/* WAIT FOR BLT TO BE LATCHED */
1051
/* WRITE ALL FULL FIFO LINES */
1053
for (i = 0; i < fifo_lines; i++) {
1054
GU2_WAIT_HALF_EMPTY;
1055
WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1);
1059
/* WRITE ALL FULL DWORDS */
1061
if (dwords_extra || bytes_extra) {
1062
GU2_WAIT_HALF_EMPTY;
1064
WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data,
1065
temp_offset, temp1);
1066
temp_offset += (dwords_extra << 2);
1070
WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data,
1071
temp_offset, temp1, temp2);
1077
*----------------------------------------------------------------------------
1080
* This routine draws a vector using the specified Bresenham parameters.
1081
* Currently this file does not support a routine that accepts the two
1082
* endpoints of a vector and calculates the Bresenham parameters. If it
1083
* ever does, this routine is still required for vectors that have been
1086
* X screen X position to start vector
1087
* Y screen Y position to start vector
1088
* LENGTH length of the vector, in pixels
1089
* INITERR Bresenham initial error term
1090
* AXIALERR Bresenham axial error term
1091
* DIAGERR Bresenham diagonal error term
1092
* FLAGS VM_YMAJOR, VM_MAJOR_INC, VM_MINOR_INC
1093
*----------------------------------------------------------------------------
1095
#if GFX_2DACCEL_DYNAMIC
1097
gu2_bresenham_line(unsigned short x, unsigned short y,
1098
unsigned short length, unsigned short initerr,
1099
unsigned short axialerr, unsigned short diagerr,
1100
unsigned short flags)
1103
gfx_bresenham_line(unsigned short x, unsigned short y,
1104
unsigned short length, unsigned short initerr,
1105
unsigned short axialerr, unsigned short diagerr,
1106
unsigned short flags)
1109
unsigned long offset;
1110
unsigned long data1 = (((unsigned long) axialerr) << 16) | diagerr;
1111
unsigned long data2 = (((unsigned long) length) << 16) | initerr;
1112
unsigned short vector_mode = gu2_vector_mode | flags;
1114
/* CALCULATE STARTING OFFSET */
1116
offset = (unsigned long) y *gu2_pitch + (((unsigned long) x) << gu2_xshift);
1118
/* CHECK NULL LENGTH */
1123
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
1124
/* Put off poll for as long as possible (do most calculations first). */
1127
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
1128
WRITE_GP32(MGP_DST_OFFSET, offset);
1129
WRITE_GP32(MGP_VEC_ERR, data1);
1130
WRITE_GP32(MGP_VEC_LEN, data2);
1131
WRITE_GP32(MGP_STRIDE, gu2_pitch);
1132
WRITE_GP32(MGP_VECTOR_MODE, vector_mode);
1135
/*---------------------------------------------------------------------------
1136
* GFX_WAIT_UNTIL_IDLE
1138
* This routine waits until the graphics engine is idle. This is required
1139
* before allowing direct access to the frame buffer.
1140
*---------------------------------------------------------------------------
1142
#if GFX_2DACCEL_DYNAMIC
1144
gu2_wait_until_idle(void)
1147
gfx_wait_until_idle(void)
1150
while (READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_BUSY);
1153
/*---------------------------------------------------------------------------
1154
* GFX_TEST_BLT_PENDING
1156
* This routine returns 1 if a BLT is pending, meaning that a call to
1157
* perform a rendering operation would stall. Otherwise it returns 0.
1158
* It is used by Darwin during random testing to only start a BLT
1159
* operation when it knows the Durango routines won't spin on graphics
1160
* (so Darwin can continue to do frame buffer reads and writes).
1161
*---------------------------------------------------------------------------
1163
#if GFX_2DACCEL_DYNAMIC
1165
gu2_test_blt_pending(void)
1168
gfx_test_blt_pending(void)
1171
if (READ_GP32(MGP_BLT_STATUS) & MGP_BS_BLT_PENDING)
1176
/*---------------------------------------------------------------------------
1177
* NEW ROUTINES FOR REDCLOUD
1178
*---------------------------------------------------------------------------
1181
/*---------------------------------------------------------------------------
1182
* GFX2_SET_SOURCE_STRIDE
1184
* This routine sets the stride to be used in successive screen to screen
1185
* BLTs (used by gfx2_screen_to_screen_blt and gfx2_mono_expand_blt).
1186
*---------------------------------------------------------------------------
1188
#if GFX_2DACCEL_DYNAMIC
1190
gu22_set_source_stride(unsigned short stride)
1193
gfx2_set_source_stride(unsigned short stride)
1196
/* SAVE STRIDE TO BE USED LATER */
1198
gu2_src_pitch = (unsigned long) stride;
1201
/*---------------------------------------------------------------------------
1202
* GFX2_SET_DESTINATION_STRIDE
1204
* This routine sets the stride used when rendering to the screen.
1205
*---------------------------------------------------------------------------
1207
#if GFX_2DACCEL_DYNAMIC
1209
gu22_set_destination_stride(unsigned short stride)
1212
gfx2_set_destination_stride(unsigned short stride)
1215
/* SAVE STRIDE TO BE USED LATER */
1217
gu2_dst_pitch = (unsigned long) stride;
1220
/*---------------------------------------------------------------------------
1221
* GFX2_SET_PATTERN_ORIGIN
1223
* This routine sets the origin within an 8x8 pattern. It is needed if
1224
* using a monochrome or color pattern (not used for a solid pattern).
1225
*---------------------------------------------------------------------------
1227
#if GFX_2DACCEL_DYNAMIC
1229
gu22_set_pattern_origin(int x, int y)
1232
gfx2_set_pattern_origin(int x, int y)
1235
/* STORE IN FORMAT THAT CAN BE COMBINED WITH THE DESTINATION OFFSET */
1237
gu2_pattern_origin = (((unsigned long) (x & 7)) << 26) |
1238
(((unsigned long) (y & 7)) << 29);
1241
/*---------------------------------------------------------------------------
1242
* GFX2_SET_SOURCE_TRANSPARENCY
1244
* This routine sets the source transparency color and mask to be used
1245
* in future rendering operations. If both the color and mask are set
1246
* to zero (normally completely transparent), those values indicate that
1247
* transparency should be disabled.
1248
*---------------------------------------------------------------------------
1250
#if GFX_2DACCEL_DYNAMIC
1252
gu22_set_source_transparency(unsigned long color, unsigned long mask)
1255
gfx2_set_source_transparency(unsigned long color, unsigned long mask)
1258
/* WRITE REGISTERS TO SPECIFY COLOR TRANSPARENCY */
1261
WRITE_GP32(MGP_SRC_COLOR_FG, color);
1262
WRITE_GP32(MGP_SRC_COLOR_BG, mask);
1264
/* SET TRANSPARENCY FLAG */
1266
GFXsourceFlags = (color || mask) ? MGP_RM_SRC_TRANS : 0;
1269
/*---------------------------------------------------------------------------
1270
* GFX2_SET_ALPHA_MODE
1272
* This routine sets the alpha blending mode to be used in successive
1273
* rendering operations.
1274
*---------------------------------------------------------------------------
1276
#if GFX_2DACCEL_DYNAMIC
1278
gu22_set_alpha_mode(int mode)
1281
gfx2_set_alpha_mode(int mode)
1284
/* SAVE ALPHA MODE FOR LATER */
1286
gu2_alpha_mode = mode;
1289
/*---------------------------------------------------------------------------
1290
* GFX2_SET_ALPHA_VALUE
1292
* This routine sets the alpha value to be used with certain alpha blending
1293
* modes (ALPHA_MODE_BLEND).
1294
*---------------------------------------------------------------------------
1296
#if GFX_2DACCEL_DYNAMIC
1298
gu22_set_alpha_value(unsigned char value)
1301
gfx2_set_alpha_value(unsigned char value)
1304
/* SAVE ALPHA VALUE TO BE USED LATER */
1306
gu2_alpha_value = (unsigned long) value;
1308
/* SET GLOBAL FLAG */
1309
/* gfx2_* routines will use this flag to program alpha values */
1310
/* appropriately. Normal gfx_* routines will always write */
1311
/* the current ROP settings. In this way, the alpha mode */
1312
/* affects only second generation routines. */
1314
gu2_alpha_active = 1;
1316
switch (gu2_alpha_mode) {
1317
case ALPHA_MODE_BLEND:
1319
/* GENERATE 32-BIT VERSION OF RASTER MODE REGISTER */
1320
/* Pattern data is not involved in the operation. */
1322
gu2_alpha32 = gu2_alpha_value | gu2_bpp;
1324
/* HANDLE SPECIAL CASES FOR ENDPOINTS */
1325
/* The 8-bit hardware alpha value is always */
1326
/* interpreted as a fraction. Consequently, there */
1327
/* is no way to use values of 255 or 0 to exclude */
1328
/* one of the inputs. */
1330
switch (gu2_alpha_value) {
1331
/* DESTINATION ONLY */
1332
/* Operation is alpha * A, where A is destination */
1333
/* and alpha is 1. */
1337
gu2_alpha32 |= MGP_RM_SELECT_ALPHA_1 |
1338
MGP_RM_ALPHA_TIMES_A |
1339
MGP_RM_ALPHA_TO_RGB | MGP_RM_DEST_FROM_CHAN_A;
1343
/* Operation is alpha * A, where A is source and */
1348
gu2_alpha32 |= MGP_RM_SELECT_ALPHA_1 |
1349
MGP_RM_ALPHA_TO_RGB | MGP_RM_ALPHA_TIMES_A;
1353
/* Operation is alpha * A + (1 - alpha) * B; */
1354
/* A is source, B is destination and alpha is the */
1355
/* programmed 8-bit value. */
1359
gu2_alpha32 |= MGP_RM_SELECT_ALPHA_R |
1360
MGP_RM_ALPHA_TO_RGB | MGP_RM_ALPHA_A_PLUS_BETA_B;
1364
/* CHECK IF SOURCE INFORMATION SHOULD BE MERGED */
1365
/* Alpha value of 0 indicates destination only. */
1367
if (gu2_alpha_value != 0)
1368
gu2_alpha32 |= GFXsourceFlags;
1370
/* SET FLAG FOR DESTINATION DATA IF NECESSARY */
1371
/* Alpha value of 255 indicates no destination */
1373
if (gu2_alpha_value != 255) {
1374
gu2_alpha_blt_mode = MGP_BM_DST_REQ;
1375
gu2_alpha_vec_mode = MGP_VM_DST_REQ;
1382
/*---------------------------------------------------------------------------
1385
* This routine is similar to the gfx_pattern_fill routine, but allows the
1386
* use of an arbitrary destination stride. The rendering position is
1387
* also specified as an offset instead of an (x,y) position.
1388
*---------------------------------------------------------------------------
1390
#if GFX_2DACCEL_DYNAMIC
1392
gu22_pattern_fill(unsigned long dstoffset, unsigned short width,
1393
unsigned short height)
1396
gfx2_pattern_fill(unsigned long dstoffset, unsigned short width,
1397
unsigned short height)
1402
size = (((unsigned long) width) << 16) | height;
1404
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
1405
/* Put off poll for as long as possible (do most calculations first). */
1408
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
1409
WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
1410
WRITE_GP32(MGP_WID_HEIGHT, size);
1411
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
1412
WRITE_GP32(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
1413
gu2_bm_throttle = 0;
1414
gu2_vm_throttle = 0;
1417
/*---------------------------------------------------------------------------
1418
* GFX2_COLOR_PATTERN_FILL
1420
* This routine is used to render a rectangle using the current raster
1421
* operation and the specified color pattern. It allows an 8x8 color
1422
* pattern to be rendered without multiple calls to the gfx_set_color_pattern
1423
* and gfx_pattern_fill routines.
1424
*---------------------------------------------------------------------------
1426
#if GFX_2DACCEL_DYNAMIC
1428
gu22_color_pattern_fill(unsigned long dstoffset, unsigned short width,
1429
unsigned short height, unsigned long *pattern)
1432
gfx2_color_pattern_fill(unsigned long dstoffset, unsigned short width,
1433
unsigned short height, unsigned long *pattern)
1437
unsigned long lines, size, patxorigin, patoffset;
1439
/* ONLY USE HW PATTERN ORIGIN FOR THE X DIRECTION */
1440
/* Y direction handled by referencing proper location in pattern data. */
1442
patxorigin = (gu2_pattern_origin) & 0x1C000000;
1444
/* OVERRIDE PATTERN FLAGS IN ROP TO FORCE COLOR PATTERN */
1447
WRITE_GP32(MGP_RASTER_MODE,
1448
(gu2_rop32 & ~MGP_RM_PAT_FLAGS) | MGP_RM_PAT_COLOR);
1450
/* ATTEMPT TO OPTIMIZE */
1451
/* If possible, we can perform the pattern fill in only a few passes */
1452
/* This is performed by multiplying the pitch by an appropriate amount. */
1453
/* Consequently, if the multiplied pitch exceeds 16 bits, this */
1454
/* optimization is impossible. */
1456
if ((gu2_dst_pitch << (gu2_xshift + 1)) <= 0xFFFF) {
1457
/* HANDLE VARIOUS COLOR DEPTHS DIFFERENTLY */
1459
switch (gu2_xshift) {
1462
/* TWO PASSES FOR 8 BPP */
1463
/* Render every other line per pass by doubling the pitch. */
1465
patoffset = (gu2_pattern_origin >> 28) & 0x0E;
1466
for (pass = 0; pass < 2; pass++) {
1467
/* CAN WRITE SOME PATTERN REGISTERS WHILE "PENDING" */
1470
WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
1471
lines = (height + 1 - pass) >> 1;
1474
size = (((unsigned long) width) << 16) | lines;
1475
WRITE_GP32(MGP_WID_HEIGHT, size);
1476
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 1);
1477
WRITE_GP32(MGP_PAT_DATA_1, BYTE_SWIZZLE(pattern[patoffset]));
1478
WRITE_GP32(MGP_PAT_DATA_0,
1479
BYTE_SWIZZLE(pattern[patoffset + 1]));
1480
patoffset = (patoffset + 4) & 0x0E;
1481
WRITE_GP32(MGP_PAT_COLOR_1, BYTE_SWIZZLE(pattern[patoffset]));
1482
WRITE_GP32(MGP_PAT_COLOR_0,
1483
BYTE_SWIZZLE(pattern[patoffset + 1]));
1484
patoffset = (patoffset + 4) & 0x0E;
1486
/* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */
1487
/* Those registers are not pipelined. */
1490
WRITE_GP32(MGP_PAT_COLOR_3, BYTE_SWIZZLE(pattern[patoffset]));
1491
WRITE_GP32(MGP_PAT_COLOR_2,
1492
BYTE_SWIZZLE(pattern[patoffset + 1]));
1493
patoffset = (patoffset + 4) & 0x0E;
1494
WRITE_GP32(MGP_PAT_COLOR_5, BYTE_SWIZZLE(pattern[patoffset]));
1495
WRITE_GP32(MGP_PAT_COLOR_4,
1496
BYTE_SWIZZLE(pattern[patoffset + 1]));
1497
WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
1498
gu2_bm_throttle = 0;
1499
gu2_vm_throttle = 0;
1501
/* ADJUST FOR NEXT PASS */
1503
dstoffset += gu2_dst_pitch;
1504
patoffset = (patoffset + 6) & 0x0E;
1508
case 1: /* 12, 15, OR 16 BPP */
1510
/* FOUR PASSES FOR 16 BPP */
1511
/* Render every 4th line per pass by quadrupling the pitch. */
1513
patoffset = (gu2_pattern_origin >> 27) & 0x1C;
1514
for (pass = 0; pass < 4; pass++) {
1515
/* CAN WRITE SOME PATTERN REGISTERS WHILE "PENDING" */
1518
WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
1519
lines = (height + 3 - pass) >> 2;
1522
size = (((unsigned long) width) << 16) | lines;
1523
WRITE_GP32(MGP_WID_HEIGHT, size);
1524
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 2);
1525
WRITE_GP32(MGP_PAT_COLOR_1, WORD_SWIZZLE(pattern[patoffset]));
1526
WRITE_GP32(MGP_PAT_COLOR_0,
1527
WORD_SWIZZLE(pattern[patoffset + 1]));
1528
WRITE_GP32(MGP_PAT_DATA_1,
1529
WORD_SWIZZLE(pattern[patoffset + 2]));
1530
WRITE_GP32(MGP_PAT_DATA_0,
1531
WORD_SWIZZLE(pattern[patoffset + 3]));
1532
patoffset = (patoffset + 16) & 0x1C;
1534
/* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */
1535
/* Those registers are not pipelined. */
1538
WRITE_GP32(MGP_PAT_COLOR_5, WORD_SWIZZLE(pattern[patoffset]));
1539
WRITE_GP32(MGP_PAT_COLOR_4,
1540
WORD_SWIZZLE(pattern[patoffset + 1]));
1541
WRITE_GP32(MGP_PAT_COLOR_3,
1542
WORD_SWIZZLE(pattern[patoffset + 2]));
1543
WRITE_GP32(MGP_PAT_COLOR_2,
1544
WORD_SWIZZLE(pattern[patoffset + 3]));
1545
WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
1546
gu2_bm_throttle = 0;
1547
gu2_vm_throttle = 0;
1549
/* ADJUST FOR NEXT PASS */
1551
dstoffset += gu2_dst_pitch;
1552
patoffset = (patoffset + 20) & 0x1C;
1556
case 2: /* 32 BPP */
1558
/* EIGHT PASSES FOR 32 BPP */
1559
/* Render every 8th line per pass by setting pitch * 8. */
1561
patoffset = (gu2_pattern_origin >> 26) & 0x38;
1562
for (pass = 0; pass < 8; pass++) {
1563
/* CAN WRITE SOME PATTERN REGISTERS WHILE "PENDING" */
1566
WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
1567
lines = (height + 7 - pass) >> 3;
1570
size = (((unsigned long) width) << 16) | lines;
1571
WRITE_GP32(MGP_WID_HEIGHT, size);
1572
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch << 3);
1573
WRITE_GP32(MGP_PAT_COLOR_1, pattern[patoffset + 4]);
1574
WRITE_GP32(MGP_PAT_COLOR_0, pattern[patoffset + 5]);
1575
WRITE_GP32(MGP_PAT_DATA_1, pattern[patoffset + 6]);
1576
WRITE_GP32(MGP_PAT_DATA_0, pattern[patoffset + 7]);
1578
/* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */
1579
/* Those registers are not pipelined. */
1582
WRITE_GP32(MGP_PAT_COLOR_5, pattern[patoffset]);
1583
WRITE_GP32(MGP_PAT_COLOR_4, pattern[patoffset + 1]);
1584
WRITE_GP32(MGP_PAT_COLOR_3, pattern[patoffset + 2]);
1585
WRITE_GP32(MGP_PAT_COLOR_2, pattern[patoffset + 3]);
1586
WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
1587
gu2_bm_throttle = 0;
1588
gu2_vm_throttle = 0;
1590
/* ADJUST FOR NEXT PASS */
1592
dstoffset += gu2_dst_pitch;
1593
patoffset = (patoffset + 8) & 0x38;
1600
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
1602
switch (gu2_xshift) {
1603
case 0: /* 8 BPP - 4 LINES PER PASS */
1605
patoffset = (gu2_pattern_origin >> 28) & 0x0E;
1607
lines = height > 4 ? 4 : height;
1609
/* CAN WRITE SOME REGISTERS WHILE PENDING */
1611
WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
1612
WRITE_GP32(MGP_WID_HEIGHT,
1613
(((unsigned long) width) << 16) | lines);
1614
WRITE_GP32(MGP_PAT_DATA_1, BYTE_SWIZZLE(pattern[patoffset]));
1615
WRITE_GP32(MGP_PAT_DATA_0,
1616
BYTE_SWIZZLE(pattern[patoffset + 1]));
1617
patoffset = (patoffset + 2) & 0x0E;
1618
WRITE_GP32(MGP_PAT_COLOR_1, BYTE_SWIZZLE(pattern[patoffset]));
1619
WRITE_GP32(MGP_PAT_COLOR_0,
1620
BYTE_SWIZZLE(pattern[patoffset + 1]));
1621
patoffset = (patoffset + 2) & 0x0E;
1623
/* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */
1624
/* Those registers are not pipelined. */
1627
WRITE_GP32(MGP_PAT_COLOR_3, BYTE_SWIZZLE(pattern[patoffset]));
1628
WRITE_GP32(MGP_PAT_COLOR_2,
1629
BYTE_SWIZZLE(pattern[patoffset + 1]));
1630
patoffset = (patoffset + 2) & 0x0E;
1631
WRITE_GP32(MGP_PAT_COLOR_5, BYTE_SWIZZLE(pattern[patoffset]));
1632
WRITE_GP32(MGP_PAT_COLOR_4,
1633
BYTE_SWIZZLE(pattern[patoffset + 1]));
1634
patoffset = (patoffset + 2) & 0x0E;
1635
WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
1637
/* ADJUST FOR NEXT PASS */
1639
dstoffset += gu2_dst_pitch << 2;
1640
height -= (unsigned short) lines;
1644
case 1: /* 12, 15 AND 16 BPP - 2 LINES PER PASS */
1646
patoffset = (gu2_pattern_origin >> 27) & 0x1C;
1648
lines = height > 2 ? 2 : height;
1650
/* CAN WRITE SOME REGISTERS WHILE PENDING */
1652
WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
1653
WRITE_GP32(MGP_WID_HEIGHT,
1654
(((unsigned long) width) << 16) | lines);
1655
WRITE_GP32(MGP_PAT_COLOR_1, WORD_SWIZZLE(pattern[patoffset]));
1656
WRITE_GP32(MGP_PAT_COLOR_0,
1657
WORD_SWIZZLE(pattern[patoffset + 1]));
1658
WRITE_GP32(MGP_PAT_DATA_1,
1659
WORD_SWIZZLE(pattern[patoffset + 2]));
1660
WRITE_GP32(MGP_PAT_DATA_0,
1661
WORD_SWIZZLE(pattern[patoffset + 3]));
1662
patoffset = (patoffset + 4) & 0x1C;
1664
/* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */
1665
/* Those registers are not pipelined. */
1668
WRITE_GP32(MGP_PAT_COLOR_5, WORD_SWIZZLE(pattern[patoffset]));
1669
WRITE_GP32(MGP_PAT_COLOR_4,
1670
WORD_SWIZZLE(pattern[patoffset + 1]));
1671
WRITE_GP32(MGP_PAT_COLOR_3,
1672
WORD_SWIZZLE(pattern[patoffset + 2]));
1673
WRITE_GP32(MGP_PAT_COLOR_2,
1674
WORD_SWIZZLE(pattern[patoffset + 3]));
1675
patoffset = (patoffset + 4) & 0x1C;
1676
WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
1678
/* ADJUST FOR NEXT PASS */
1680
dstoffset += gu2_dst_pitch << 1;
1681
height -= (unsigned short) lines;
1685
case 2: /* 32 BPP - 1 LINE PER PASS */
1687
patoffset = (gu2_pattern_origin >> 26) & 0x38;
1689
/* CAN WRITE SOME REGISTERS WHILE PENDING */
1691
WRITE_GP32(MGP_DST_OFFSET, dstoffset | patxorigin);
1692
WRITE_GP32(MGP_WID_HEIGHT,
1693
(((unsigned long) width) << 16) | 1l);
1694
WRITE_GP32(MGP_PAT_COLOR_1, pattern[patoffset + 4]);
1695
WRITE_GP32(MGP_PAT_COLOR_0, pattern[patoffset + 5]);
1696
WRITE_GP32(MGP_PAT_DATA_1, pattern[patoffset + 6]);
1697
WRITE_GP32(MGP_PAT_DATA_0, pattern[patoffset + 7]);
1699
/* NEED TO WAIT UNTIL IDLE FOR COLORS 2 THROUGH 5 */
1700
/* Those registers are not pipelined. */
1703
WRITE_GP32(MGP_PAT_COLOR_5, pattern[patoffset]);
1704
WRITE_GP32(MGP_PAT_COLOR_4, pattern[patoffset + 1]);
1705
WRITE_GP32(MGP_PAT_COLOR_3, pattern[patoffset + 2]);
1706
WRITE_GP32(MGP_PAT_COLOR_2, pattern[patoffset + 3]);
1707
patoffset = (patoffset + 8) & 0x38;
1708
WRITE_GP16(MGP_BLT_MODE, gu2_blt_mode | gu2_bm_throttle);
1710
/* ADJUST FOR NEXT PASS */
1712
dstoffset += gu2_dst_pitch;
1722
/*---------------------------------------------------------------------------
1723
* GFX2_SCREEN_TO_SCREEN_BLT
1725
* This routine is similar to the gfx_screen_to_screen_blt routine but
1726
* allows the use of arbitrary source and destination strides and alpha
1727
* blending. It also allows the use of an arbitrary ROP with transparency.
1728
*---------------------------------------------------------------------------
1730
#if GFX_2DACCEL_DYNAMIC
1732
gu22_screen_to_screen_blt(unsigned long srcoffset, unsigned long dstoffset,
1733
unsigned short width, unsigned short height,
1737
gfx2_screen_to_screen_blt(unsigned long srcoffset, unsigned long dstoffset,
1738
unsigned short width, unsigned short height,
1742
unsigned long size, xbytes;
1743
unsigned short blt_mode;
1745
size = (((unsigned long) width) << 16) | height;
1747
/* USE ALPHA SETTINGS, IF REQUESTED */
1749
if (gu2_alpha_active)
1750
blt_mode = gu2_alpha_blt_mode | MGP_BM_SRC_FB;
1753
blt_mode = (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK) | MGP_BM_SRC_FB;
1755
/* CALCULATE THE DIRECTION OF THE BLT */
1756
/* Using offsets, so flags from the calling routine are needed. */
1759
xbytes = (width - 1) << gu2_xshift;
1760
srcoffset += xbytes;
1761
dstoffset += xbytes;
1762
blt_mode |= MGP_BM_NEG_XDIR;
1765
srcoffset += (height - 1) * gu2_src_pitch;
1766
dstoffset += (height - 1) * gu2_dst_pitch;
1767
blt_mode |= MGP_BM_NEG_YDIR;
1770
/* TURN INTO BYTE ADDRESS IF NEGATIVE X DIRECTION */
1771
/* This is a quirk of the hardware. */
1773
if (blt_mode & MGP_BM_NEG_XDIR) {
1774
srcoffset += (1 << gu2_xshift) - 1;
1775
dstoffset += (1 << gu2_xshift) - 1;
1778
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
1779
/* Put off poll for as long as possible (do most calculations first). */
1783
if (gu2_alpha_active) {
1784
WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
1787
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
1790
WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
1791
WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
1792
WRITE_GP32(MGP_WID_HEIGHT, size);
1793
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch | (gu2_src_pitch << 16));
1794
WRITE_GP16(MGP_BLT_MODE, blt_mode | gu2_bm_throttle);
1795
gu2_bm_throttle = 0;
1796
gu2_vm_throttle = 0;
1799
/*---------------------------------------------------------------------------
1800
* GFX2_MONO_EXPAND_BLT
1802
* This routine is similar to the gfx2_screen_to_screen_blt routine but
1803
* expands monochrome data stored in graphics memory.
1804
* WARNING: This routine assumes that the regions in graphics memory
1805
* will not overlap, and therefore does not check the BLT direction.
1806
*---------------------------------------------------------------------------
1808
#if GFX_2DACCEL_DYNAMIC
1810
gu22_mono_expand_blt(unsigned long srcbase, unsigned short srcx,
1811
unsigned short srcy, unsigned long dstoffset,
1812
unsigned short width, unsigned short height,
1816
gfx2_mono_expand_blt(unsigned long srcbase, unsigned short srcx,
1817
unsigned short srcy, unsigned long dstoffset,
1818
unsigned short width, unsigned short height,
1822
unsigned long size, srcoffset;
1823
unsigned short blt_mode;
1825
size = (((unsigned long) width) << 16) | height;
1827
/* CALCULATE SOURCE OFFSET */
1829
srcoffset = srcbase + (unsigned long) srcy *gu2_src_pitch;
1831
srcoffset += srcx >> 3;
1832
srcoffset |= ((unsigned long) srcx & 7) << 26;
1834
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
1835
/* Put off poll for as long as possible (do most calculations first). */
1839
if (gu2_alpha_active) {
1840
blt_mode = gu2_alpha_blt_mode;
1842
WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
1845
blt_mode = (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK);
1847
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
1851
blt_mode |= MGP_BM_SRC_FB | MGP_BM_SRC_BP_MONO | gu2_bm_throttle;
1853
blt_mode |= MGP_BM_SRC_FB | MGP_BM_SRC_MONO | gu2_bm_throttle;
1855
WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
1856
WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
1857
WRITE_GP32(MGP_WID_HEIGHT, size);
1858
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch | (gu2_src_pitch << 16));
1859
WRITE_GP16(MGP_BLT_MODE, blt_mode);
1860
gu2_bm_throttle = 0;
1861
gu2_vm_throttle = 0;
1864
/*---------------------------------------------------------------------------
1865
* GFX2_COLOR_BITMAP_TO_SCREEN_BLT
1867
* This routine is similar to the gfx_color_bitmap_to_screen_blt routine
1868
* but allows the use of an arbitrary destination stride and alpha blending.
1869
* It also allows the use of an arbitrary ROP with transparency.
1870
*---------------------------------------------------------------------------
1872
#if GFX_2DACCEL_DYNAMIC
1874
gu22_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
1875
unsigned long dstoffset, unsigned short width,
1876
unsigned short height, unsigned char *data,
1880
gfx2_color_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
1881
unsigned long dstoffset, unsigned short width,
1882
unsigned short height, unsigned char *data,
1886
unsigned long size, bytes;
1887
unsigned long offset, temp_offset;
1888
unsigned long srcoffset, dword_bytes, bytes_extra;
1889
unsigned short blt_mode;
1891
size = (((unsigned long) width) << 16) | 1;
1893
/* CALCULATE STARTING OFFSETS */
1895
offset = (unsigned long) srcy *pitch + ((unsigned long) srcx << gu2_xshift);
1897
dstoffset |= gu2_pattern_origin;
1899
bytes = width << gu2_xshift;
1900
dword_bytes = bytes & ~0x3L;
1901
bytes_extra = bytes & 0x3L;
1903
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
1904
/* Put off poll for as long as possible (do most calculations first). */
1905
/* The source offset is always 0 since we allow misaligned dword reads. */
1906
/* We must wait for BLT busy because the GP may be executing a screen */
1907
/* to screen BLT from the scratchpad area. */
1911
if (gu2_alpha_active) {
1912
blt_mode = gu2_alpha_blt_mode;
1914
WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
1917
blt_mode = (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK);
1919
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
1921
blt_mode |= MGP_BM_SRC_FB | gu2_bm_throttle;
1922
gu2_bm_throttle = 0;
1923
gu2_vm_throttle = 0;
1925
WRITE_GP32(MGP_WID_HEIGHT, size);
1927
/* WRITE DATA ONE LINE AT A TIME */
1928
/* For speed reasons, data is written to an offscreen scratch area and
1929
* then BLTed using a screen to screen BLT. This is similar to the GX1 BLT
1930
* buffers, but slightly more efficient in that we can queue up data while
1931
* the GP is rendering a line.
1935
temp_offset = offset;
1936
srcoffset = gfx_gx2_scratch_base;
1937
if (gu2_current_line)
1941
WRITE_GP32(MGP_SRC_OFFSET, srcoffset);
1942
WRITE_GP32(MGP_DST_OFFSET, dstoffset);
1943
dstoffset += gu2_dst_pitch;
1944
dstoffset += 0x20000000;
1946
WRITE_FRAME_BUFFER_STRING32(srcoffset, dword_bytes, data, temp_offset);
1948
temp_offset += dword_bytes;
1949
srcoffset += dword_bytes;
1950
WRITE_FRAME_BUFFER_STRING8(srcoffset, bytes_extra, data,
1953
WRITE_GP16(MGP_BLT_MODE, blt_mode);
1955
gu2_current_line = 1 - gu2_current_line;
1959
/*---------------------------------------------------------------------------
1962
* This routine is similar to the gfx2_mono_bitmap_to_screen_blt routine
1963
* but assumes that source data is byte-packed.
1964
*---------------------------------------------------------------------------
1966
#if GFX_2DACCEL_DYNAMIC
1968
gu22_text_blt(unsigned long dstoffset, unsigned short width,
1969
unsigned short height, unsigned char *data)
1972
gfx2_text_blt(unsigned long dstoffset, unsigned short width,
1973
unsigned short height, unsigned char *data)
1976
unsigned long size, bytes;
1977
unsigned long temp1 = 0, temp2 = 0, temp_offset = 0;
1978
unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra;
1979
unsigned long shift;
1980
unsigned short blt_mode;
1982
size = (((unsigned long) width) << 16) | height;
1984
/* CALCULATE STARTING OFFSETS */
1986
bytes = ((width + 7) >> 3) * height;
1987
fifo_lines = bytes >> 5;
1988
dwords_extra = (bytes & 0x0000001Cl) >> 2;
1989
bytes_extra = bytes & 0x00000003l;
1991
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
1995
if (gu2_alpha_active) {
1996
blt_mode = gu2_alpha_blt_mode;
1998
WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
2001
blt_mode = (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK);
2003
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
2006
WRITE_GP32(MGP_SRC_OFFSET, 0);
2007
WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
2008
WRITE_GP32(MGP_WID_HEIGHT, size);
2009
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
2010
WRITE_GP16(MGP_BLT_MODE, blt_mode | MGP_BM_SRC_HOST |
2011
MGP_BM_SRC_BP_MONO | gu2_bm_throttle);
2012
gu2_bm_throttle = 0;
2013
gu2_vm_throttle = 0;
2015
/* WAIT FOR BLT TO BE LATCHED */
2019
/* WRITE ALL FULL FIFO LINES */
2021
for (i = 0; i < fifo_lines; i++) {
2022
GU2_WAIT_HALF_EMPTY;
2023
WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset, temp1);
2027
/* WRITE ALL FULL DWORDS */
2029
if (dwords_extra || bytes_extra) {
2030
GU2_WAIT_HALF_EMPTY;
2032
WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data,
2033
temp_offset, temp1);
2034
temp_offset += (dwords_extra << 2);
2038
WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data,
2039
temp_offset, temp1, temp2);
2044
/*---------------------------------------------------------------------------
2045
* GFX2_MONO_BITMAP_TO_SCREEN_BLT
2047
* This routine is similar to the gfx_mono_bitmap_to_screen_blt routine
2048
* but allows the use of an arbitrary destination stride and alpha blending.
2049
*---------------------------------------------------------------------------
2051
#if GFX_2DACCEL_DYNAMIC
2053
gu22_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
2054
unsigned long dstoffset, unsigned short width,
2055
unsigned short height, unsigned char *data,
2059
gfx2_mono_bitmap_to_screen_blt(unsigned short srcx, unsigned short srcy,
2060
unsigned long dstoffset, unsigned short width,
2061
unsigned short height, unsigned char *data,
2065
unsigned long size, bytes;
2066
unsigned long offset, temp_offset, temp1 = 0, temp2 = 0;
2067
unsigned long i, j = 0, fifo_lines, dwords_extra, bytes_extra;
2068
unsigned long shift = 0;
2069
unsigned short blt_mode;
2071
size = (((unsigned long) width) << 16) | height;
2073
/* CALCULATE STARTING OFFSETS */
2075
offset = (unsigned long) srcy *pitch + ((unsigned long) srcx >> 3);
2077
bytes = ((srcx & 7) + width + 7) >> 3;
2078
fifo_lines = bytes >> 5;
2079
dwords_extra = (bytes & 0x0000001Cl) >> 2;
2080
bytes_extra = bytes & 0x00000003l;
2082
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
2086
if (gu2_alpha_active) {
2087
blt_mode = gu2_alpha_blt_mode;
2089
WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
2092
blt_mode = (gu2_blt_mode & ~MGP_BM_SRC_TYPE_MASK);
2094
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32 | GFXsourceFlags);
2097
WRITE_GP32(MGP_SRC_OFFSET, ((unsigned long) srcx & 7) << 26);
2098
WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
2099
WRITE_GP32(MGP_WID_HEIGHT, size);
2100
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
2101
WRITE_GP16(MGP_BLT_MODE, blt_mode | MGP_BM_SRC_HOST |
2102
MGP_BM_SRC_MONO | gu2_bm_throttle);
2103
gu2_bm_throttle = 0;
2104
gu2_vm_throttle = 0;
2106
/* WAIT FOR BLT TO BE LATCHED */
2110
/* WRITE ALL OF THE DATA TO THE HOST SOURCE REGISTER */
2113
temp_offset = offset;
2115
/* WRITE ALL FULL FIFO LINES */
2117
for (i = 0; i < fifo_lines; i++) {
2118
GU2_WAIT_HALF_EMPTY;
2119
WRITE_GPREG_STRING32(MGP_HST_SOURCE, 8, j, data, temp_offset,
2124
/* WRITE ALL FULL DWORDS */
2126
GU2_WAIT_HALF_EMPTY;
2128
WRITE_GPREG_STRING32(MGP_HST_SOURCE, dwords_extra, i, data,
2129
temp_offset, temp1);
2130
temp_offset += (dwords_extra << 2);
2132
/* WRITE REMAINING BYTES */
2136
WRITE_GPREG_STRING8(MGP_HST_SOURCE, bytes_extra, shift, i, data,
2137
temp_offset, temp1, temp2);
2143
/*---------------------------------------------------------------------------
2144
* GFX2_BRESENHAM_LINE
2146
* This routine is similar to the gfx_bresenam_line routine but allows
2147
* the use of an arbitrary destination stride.
2148
*---------------------------------------------------------------------------
2150
#if GFX_2DACCEL_DYNAMIC
2152
gu22_bresenham_line(unsigned long dstoffset,
2153
unsigned short length, unsigned short initerr,
2154
unsigned short axialerr, unsigned short diagerr,
2155
unsigned short flags)
2158
gfx2_bresenham_line(unsigned long dstoffset,
2159
unsigned short length, unsigned short initerr,
2160
unsigned short axialerr, unsigned short diagerr,
2161
unsigned short flags)
2164
unsigned long vector_mode = gu2_vector_mode | flags;
2165
unsigned long data1 = (((unsigned long) axialerr) << 16) | diagerr;
2166
unsigned long data2 = (((unsigned long) length) << 16) | initerr;
2168
/* CHECK NULL LENGTH */
2173
/* POLL UNTIL ABLE TO WRITE TO THE REGISTERS */
2174
/* Put off poll for as long as possible (do most calculations first). */
2178
if (gu2_alpha_active) {
2179
vector_mode = gu2_alpha_vec_mode | flags;
2181
WRITE_GP32(MGP_RASTER_MODE, gu2_alpha32);
2184
WRITE_GP32(MGP_RASTER_MODE, gu2_rop32);
2186
WRITE_GP32(MGP_DST_OFFSET, dstoffset | gu2_pattern_origin);
2187
WRITE_GP32(MGP_VEC_ERR, data1);
2188
WRITE_GP32(MGP_VEC_LEN, data2);
2189
WRITE_GP32(MGP_STRIDE, gu2_dst_pitch);
2190
WRITE_GP32(MGP_VECTOR_MODE, vector_mode | gu2_vm_throttle);
2191
gu2_bm_throttle = 0;
2192
gu2_vm_throttle = 0;
2195
/*---------------------------------------------------------------------------
2196
* GFX2_SYNC_TO_VBLANK
2198
* This routine sets a flag to synchronize the next rendering routine to
2199
* VBLANK. The flag is cleared by the rendering routine.
2200
*---------------------------------------------------------------------------
2202
#if GFX_2DACCEL_DYNAMIC
2204
gu22_sync_to_vblank(void)
2207
gfx2_sync_to_vblank(void)
2210
/* SET FLAGS TO THROTTLE NEXT RENDERING ROUTINE */
2212
gu2_bm_throttle = MGP_BM_THROTTLE;
2213
gu2_vm_throttle = MGP_VM_THROTTLE;