1 /*
2 Copyright (c) 2003 Andreas Robinson, All rights reserved.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8 */
9
10 #include <config.h>
11
12 #include <gfx/convert.h>
13 #include "unichrome.h"
14 #include "uc_state.h"
15 #include "uc_accel.h"
16 #include "uc_hw.h"
17
18 enum uc_state_type {
19 UC_TYPE_UNSUPPORTED,
20 UC_TYPE_2D,
21 UC_TYPE_3D
22 };
23
24 /// GPU selecting functions --------------------------------------------------
25
26 static inline bool
uc_has_dst_format(DFBSurfacePixelFormat format)27 uc_has_dst_format( DFBSurfacePixelFormat format )
28 {
29 switch (format) {
30 case DSPF_ARGB1555:
31 case DSPF_RGB16:
32 case DSPF_RGB32:
33 case DSPF_ARGB:
34 return true;
35
36 default:
37 break;
38 }
39
40 return false;
41 }
42
43 static inline bool
uc_has_src_format_3d(DFBSurfacePixelFormat format)44 uc_has_src_format_3d( DFBSurfacePixelFormat format )
45 {
46 switch (format) {
47 case DSPF_ARGB1555:
48 case DSPF_RGB16:
49 case DSPF_RGB32:
50 case DSPF_ARGB:
51 case DSPF_A8:
52 case DSPF_LUT8:
53 return true;
54
55 default:
56 break;
57 }
58
59 return false;
60 }
61
62 static inline enum uc_state_type
uc_select_drawtype(CardState * state,DFBAccelerationMask accel)63 uc_select_drawtype( CardState* state,
64 DFBAccelerationMask accel )
65 {
66 if (!(state->drawingflags & ~UC_DRAWING_FLAGS_2D) &&
67 !(accel & DFXL_FILLTRIANGLE))
68 return UC_TYPE_2D;
69
70 if (!(state->drawingflags & ~UC_DRAWING_FLAGS_3D))
71 return UC_TYPE_3D;
72
73 return UC_TYPE_UNSUPPORTED;
74 }
75
76 static inline enum uc_state_type
uc_select_blittype(CardState * state,DFBAccelerationMask accel)77 uc_select_blittype( CardState* state,
78 DFBAccelerationMask accel )
79 {
80 if (!(state->blittingflags & ~UC_BLITTING_FLAGS_2D)) {
81 if ((state->source->config.format == state->destination->config.format) &&
82 !((state->blittingflags & DSBLIT_SRC_COLORKEY) &&
83 (state->blittingflags & DSBLIT_DST_COLORKEY)) &&
84 !(accel & (DFXL_STRETCHBLIT | DFXL_TEXTRIANGLES)))
85 return UC_TYPE_2D;
86 }
87
88 if (!(state->blittingflags & ~UC_BLITTING_FLAGS_3D)) {
89 if (uc_has_src_format_3d( state->source->config.format ))
90 return UC_TYPE_3D;
91 }
92
93 return UC_TYPE_UNSUPPORTED;
94 }
95
96 // DirectFB interfacing functions --------------------------------------------
97
uc_check_state(void * drv,void * dev,CardState * state,DFBAccelerationMask accel)98 void uc_check_state(void *drv, void *dev,
99 CardState *state, DFBAccelerationMask accel)
100 {
101 /* Check destination format. */
102 if (!uc_has_dst_format( state->destination->config.format ))
103 return;
104
105 if (DFB_DRAWING_FUNCTION(accel)) {
106 /* Check drawing parameters. */
107 switch (uc_select_drawtype(state, accel)) {
108 case UC_TYPE_2D:
109 state->accel |= UC_DRAWING_FUNCTIONS_2D;
110 break;
111 case UC_TYPE_3D:
112 state->accel |= UC_DRAWING_FUNCTIONS_3D;
113 break;
114 default:
115 return;
116 }
117 }
118 else {
119 /* Check blitting parameters. */
120 switch (uc_select_blittype(state, accel)) {
121 case UC_TYPE_2D:
122 state->accel |= UC_BLITTING_FUNCTIONS_2D;
123 break;
124 case UC_TYPE_3D:
125 state->accel |= UC_BLITTING_FUNCTIONS_3D;
126 break;
127 default:
128 return;
129 }
130 }
131 }
132
uc_set_state(void * drv,void * dev,GraphicsDeviceFuncs * funcs,CardState * state,DFBAccelerationMask accel)133 void uc_set_state(void *drv, void *dev, GraphicsDeviceFuncs *funcs,
134 CardState *state, DFBAccelerationMask accel)
135 {
136 UcDriverData *ucdrv = (UcDriverData*) drv;
137 UcDeviceData *ucdev = (UcDeviceData*) dev;
138 struct uc_fifo *fifo = ucdrv->fifo;
139
140 u32 rop3d = HC_HROP_P;
141 u32 regEnable = HC_HenCW_MASK | HC_HenAW_MASK;
142
143 StateModificationFlags modified = state->mod_hw;
144
145 // Check modified states and update hw
146
147 if (modified & SMF_SOURCE)
148 UC_INVALIDATE( uc_source2d );
149
150 if (modified & (SMF_BLITTING_FLAGS | SMF_SOURCE))
151 UC_INVALIDATE( uc_source3d | uc_texenv );
152
153 if (modified & (SMF_BLITTING_FLAGS | SMF_SRC_COLORKEY | SMF_DST_COLORKEY))
154 UC_INVALIDATE( uc_colorkey2d );
155
156 if (modified & (SMF_COLOR | SMF_DESTINATION | SMF_DRAWING_FLAGS))
157 UC_INVALIDATE( uc_color2d );
158
159 if (modified & (SMF_SRC_BLEND | SMF_DST_BLEND))
160 UC_INVALIDATE( uc_blending_fn );
161
162
163 if (modified & SMF_COLOR)
164 ucdev->color3d = PIXEL_ARGB( state->color.a, state->color.r,
165 state->color.g, state->color.b );
166
167 if (modified & SMF_DRAWING_FLAGS) {
168 if (state->drawingflags & DSDRAW_XOR) {
169 ucdev->draw_rop3d = HC_HROP_DPx;
170 ucdev->draw_rop2d = VIA_ROP_DPx;
171 }
172 else {
173 ucdev->draw_rop3d = HC_HROP_P;
174 ucdev->draw_rop2d = VIA_ROP_P;
175 }
176 }
177
178 ucdev->bflags = state->blittingflags;
179
180 if (modified & SMF_DESTINATION)
181 uc_set_destination(ucdrv, ucdev, state);
182
183 if (modified & SMF_CLIP)
184 uc_set_clip(ucdrv, ucdev, state);
185
186
187 // Select GPU and check remaining states
188
189 if (DFB_DRAWING_FUNCTION(accel)) {
190
191 switch (uc_select_drawtype(state, accel)) {
192 case UC_TYPE_2D:
193 funcs->FillRectangle = uc_fill_rectangle;
194 funcs->DrawRectangle = uc_draw_rectangle;
195 funcs->DrawLine = uc_draw_line;
196
197 uc_set_color_2d(ucdrv, ucdev, state);
198
199 state->set = UC_DRAWING_FUNCTIONS_2D;
200 break;
201
202 case UC_TYPE_3D:
203 funcs->FillRectangle = uc_fill_rectangle_3d;
204 funcs->DrawRectangle = uc_draw_rectangle_3d;
205 funcs->DrawLine = uc_draw_line_3d;
206
207 if (state->drawingflags & DSDRAW_BLEND) {
208 uc_set_blending_fn(ucdrv, ucdev, state);
209 regEnable |= HC_HenABL_MASK;
210 }
211
212 rop3d = ucdev->draw_rop3d;
213
214 state->set = UC_DRAWING_FUNCTIONS_3D;
215 break;
216
217 case UC_TYPE_UNSUPPORTED:
218 D_BUG("Unsupported drawing function!");
219 break;
220 }
221 }
222 else { // DFB_BLITTING_FUNCTION(accel)
223 switch (uc_select_blittype(state, accel)) {
224 case UC_TYPE_2D:
225 uc_set_source_2d(ucdrv, ucdev, state);
226 funcs->Blit = uc_blit;
227
228 uc_set_colorkey_2d(ucdrv, ucdev, state);
229 state->set = UC_BLITTING_FUNCTIONS_2D;
230 break;
231
232 case UC_TYPE_3D:
233 funcs->Blit = uc_blit_3d;
234 uc_set_source_3d(ucdrv, ucdev, state);
235 uc_set_texenv(ucdrv, ucdev, state);
236 uc_set_blending_fn(ucdrv, ucdev, state);
237
238 regEnable |= HC_HenTXMP_MASK | HC_HenTXCH_MASK | HC_HenTXPP_MASK | HC_HenDT_MASK;
239
240 if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL |
241 DSBLIT_BLEND_COLORALPHA))
242 regEnable |= HC_HenABL_MASK;
243
244 state->set = UC_BLITTING_FUNCTIONS_3D;
245 break;
246
247 case UC_TYPE_UNSUPPORTED:
248 D_BUG("Unsupported drawing function!");
249 break;
250 }
251 }
252
253 #ifdef UC_ENABLE_3D
254 UC_FIFO_PREPARE( fifo, 6 );
255 UC_FIFO_ADD_HDR( fifo, HC_ParaType_NotTex << 16 );
256
257 /* Don't know what this does. DRI code always clears it. */
258 UC_FIFO_ADD_3D ( fifo, HC_SubA_HPixGC, 0 );
259
260 UC_FIFO_ADD_3D ( fifo, HC_SubA_HEnable, regEnable );
261 UC_FIFO_ADD_3D ( fifo, HC_SubA_HFBBMSKL, 0xffffff );
262 UC_FIFO_ADD_3D ( fifo, HC_SubA_HROP, rop3d | 0xff );
263 #endif
264
265 UC_FIFO_CHECK(fifo);
266
267 state->mod_hw = 0;
268 }
269
270