xref: /haiku/src/add-ons/accelerants/3dfx/3dfx_draw.cpp (revision fd9fa13896676181d9ce408f3843e96f26c592c6)
1 /*
2 	Copyright 2010 Haiku, Inc.  All rights reserved.
3 	Distributed under the terms of the MIT license.
4 
5 	Authors:
6 	Gerald Zajac
7 */
8 
9 
10 #include "accelerant.h"
11 #include "3dfx.h"
12 
13 
14 // Constants for the DST_FORMAT register based upon the color depth.
15 
16 static const uint32 fmtColorDepth[] = {
17 	0x10000,		// 1 byte/pixel
18 	0x30000,		// 2 bytes/pixel
19 	0x50000,		// 3 bytes/pixel (not used)
20 	0x50000			// 4 bytes/pixel
21 };
22 
23 
24 void
TDFX_FillRectangle(engine_token * et,uint32 color,fill_rect_params * list,uint32 count)25 TDFX_FillRectangle(engine_token* et, uint32 color, fill_rect_params* list,
26 	uint32 count)
27 {
28 	(void)et;		// avoid compiler warning for unused arg
29 
30 	DisplayModeEx& mode = gInfo.sharedInfo->displayMode;
31 	uint32 fmt = mode.bytesPerRow | fmtColorDepth[mode.bytesPerPixel - 1];
32 
33 	TDFX_WaitForFifo(3);
34 	OUTREG32(DST_FORMAT, fmt);
35 	OUTREG32(COLOR_BACK, color);
36 	OUTREG32(COLOR_FORE, color);
37 
38 	while (count--) {
39 		int x = list->left;
40 		int y = list->top;
41 		int w = list->right - x + 1;
42 		int h = list->bottom - y + 1;
43 
44 		TDFX_WaitForFifo(3);
45 		OUTREG32(DST_SIZE, w | (h << 16));
46 		OUTREG32(DST_XY,   x | (y << 16));
47 		OUTREG32(CMD_2D, RECTANGLE_FILL | CMD_2D_GO | (ROP_COPY << 24));
48 
49 		list++;
50 	}
51 }
52 
53 
54 void
TDFX_FillSpan(engine_token * et,uint32 color,uint16 * list,uint32 count)55 TDFX_FillSpan(engine_token* et, uint32 color, uint16* list, uint32 count)
56 {
57 	(void)et;		// avoid compiler warning for unused arg
58 
59 	DisplayModeEx& mode = gInfo.sharedInfo->displayMode;
60 	uint32 fmt = mode.bytesPerRow | fmtColorDepth[mode.bytesPerPixel - 1];
61 
62 	TDFX_WaitForFifo(3);
63 	OUTREG32(DST_FORMAT, fmt);
64 	OUTREG32(COLOR_BACK, color);
65 	OUTREG32(COLOR_FORE, color);
66 
67 	while (count--) {
68 		int y = *list++;
69 		int x = *list++;
70 		int w = *list++ - x + 1;
71 
72 		if (w <= 0)
73 			continue;	// discard span with zero or negative width
74 
75 		TDFX_WaitForFifo(3);
76 		OUTREG32(DST_SIZE, w | (1 << 16));
77 		OUTREG32(DST_XY,   x | (y << 16));
78 		OUTREG32(CMD_2D, RECTANGLE_FILL | CMD_2D_GO | (ROP_COPY << 24));
79 	}
80 }
81 
82 
83 void
TDFX_InvertRectangle(engine_token * et,fill_rect_params * list,uint32 count)84 TDFX_InvertRectangle(engine_token* et, fill_rect_params* list, uint32 count)
85 {
86 	(void)et;		// avoid compiler warning for unused arg
87 
88 	DisplayModeEx& mode = gInfo.sharedInfo->displayMode;
89 	uint32 fmt = mode.bytesPerRow | fmtColorDepth[mode.bytesPerPixel - 1];
90 
91 	TDFX_WaitForFifo(1);
92 	OUTREG32(DST_FORMAT, fmt);
93 
94 	while (count--) {
95 		int x = list->left;
96 		int y = list->top;
97 		int w = list->right - x + 1;
98 		int h = list->bottom - y + 1;
99 
100 		TDFX_WaitForFifo(3);
101 		OUTREG32(DST_SIZE, w | (h << 16));
102 		OUTREG32(DST_XY,   x | (y << 16));
103 		OUTREG32(CMD_2D, RECTANGLE_FILL | CMD_2D_GO | (ROP_INVERT << 24));
104 
105 		list++;
106 	}
107 }
108 
109 
110 void
TDFX_ScreenToScreenBlit(engine_token * et,blit_params * list,uint32 count)111 TDFX_ScreenToScreenBlit(engine_token* et, blit_params* list, uint32 count)
112 {
113 	(void)et;		// avoid compiler warning for unused arg
114 
115 	DisplayModeEx& mode = gInfo.sharedInfo->displayMode;
116 	uint32 fmt = mode.bytesPerRow | fmtColorDepth[mode.bytesPerPixel - 1];
117 
118 	TDFX_WaitForFifo(2);
119 	OUTREG32(DST_FORMAT, fmt);
120 	OUTREG32(SRC_FORMAT, fmt);
121 
122 	while (count--) {
123 		int src_x = list->src_left;
124 		int src_y = list->src_top;
125 		int dest_x = list->dest_left;
126 		int dest_y = list->dest_top;
127 		int width = list->width;
128 		int height = list->height;
129 
130 		uint32 cmd = SCRN_TO_SCRN_BLIT | CMD_2D_GO | (ROP_COPY << 24);
131 
132 		if (src_x <= dest_x) {
133 			cmd |= X_RIGHT_TO_LEFT;
134 			src_x += width;
135 			dest_x += width;
136 		}
137 
138 		if (src_y <= dest_y) {
139 			cmd |= Y_BOTTOM_TO_TOP;
140 			src_y += height;
141 			dest_y += height;
142 		}
143 
144 		TDFX_WaitForFifo(4);
145 		OUTREG32(SRC_XY, src_x | (src_y << 16));
146 		OUTREG32(DST_SIZE, (width + 1) | ((height + 1) << 16));
147 		OUTREG32(DST_XY, dest_x | (dest_y << 16));
148 		OUTREG32(CMD_2D, cmd);
149 
150 		list++;
151 	}
152 }
153