1 #ifdef SH7722_DEBUG_BLT
2 #define DIRECT_ENABLE_DEBUG
3 #endif
4
5
6 #include <config.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10
11 #include <sys/mman.h>
12 #include <fcntl.h>
13 #include <sys/ioctl.h>
14 #include <malloc.h>
15 #include <errno.h>
16
17 #include <asm/types.h>
18
19 #include <directfb.h>
20
21 #include <direct/debug.h>
22 #include <direct/mem.h>
23 #include <direct/memcpy.h>
24 #include <direct/messages.h>
25 #include <direct/util.h>
26
27 #include <core/coredefs.h>
28 #include <core/coretypes.h>
29
30 #include <core/state.h>
31 #include <core/gfxcard.h>
32 #include <core/surface.h>
33 #include <core/surface_buffer.h>
34
35 #include <gfx/convert.h>
36
37 #include "sh7722.h"
38 #include "sh7722_blt.h"
39
40
41 D_DEBUG_DOMAIN( SH7722_BLT, "SH7722/BLT", "Renesas SH7722 Drawing Engine" );
42
43 D_DEBUG_DOMAIN( SH7722_StartStop, "SH7722/StartStop", "Renesas SH7722 Drawing Start/Stop" );
44
45 /*
46 * State validation flags.
47 *
48 * There's no prefix because of the macros below.
49 */
50 enum {
51 DEST = 0x00000001,
52 CLIP = 0x00000002,
53 DEST_CLIP = 0x00000003,
54
55 SOURCE = 0x00000010,
56 MASK = 0x00000020,
57
58 COLOR = 0x00000100,
59
60 COLOR_KEY = 0x00001000,
61 COLOR_CHANGE = 0x00002000,
62
63 BLENDING = 0x00010000,
64
65 MATRIX = 0x00100000,
66
67 BLIT_OP = 0x01000000,
68
69 ALL = 0x01113133
70 };
71
72 /*
73 * Map pixel formats.
74 */
75 static int pixel_formats[DFB_NUM_PIXELFORMATS];
76
initialization(void)77 __attribute__((constructor)) static void initialization( void )
78 {
79 D_DEBUG_AT( SH7722_BLT, "%s()\n", __FUNCTION__ );
80
81 pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_RGB32) ] = 0;
82 pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_ARGB) ] = 0;
83 pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_RGB16) ] = 1;
84 pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_RGB555) ] = 2;
85 pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_ARGB1555)] = 3;
86 pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_ARGB4444)] = 4;
87 pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_RGB444) ] = 4;
88 pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_RGB18) ] = 6;
89 pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_ARGB1666)] = 6;
90 pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_ARGB6666)] = 6;
91 pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_RGB24) ] = 7;
92 pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_A1) ] = 8;
93 pixel_formats[DFB_PIXELFORMAT_INDEX(DSPF_A8) ] = 10;
94 }
95
96 /*
97 * State handling macros.
98 */
99
100 #define SH7722_VALIDATE(flags) do { sdev->v_flags |= (flags); } while (0)
101 #define SH7722_INVALIDATE(flags) do { sdev->v_flags &= ~(flags); } while (0)
102
103 #define SH7722_CHECK_VALIDATE(flag) do { \
104 if ((sdev->v_flags & flag) != flag) \
105 sh7722_validate_##flag( sdrv, sdev, state ); \
106 } while (0)
107
108 #define DUMP_INFO() D_DEBUG_AT( SH7722_BLT, " -> %srunning, hw %d-%d, next %d-%d - %svalid\n", \
109 sdrv->gfx_shared->hw_running ? "" : "not ", \
110 sdrv->gfx_shared->hw_start, \
111 sdrv->gfx_shared->hw_end, \
112 sdrv->gfx_shared->next_start, \
113 sdrv->gfx_shared->next_end, \
114 sdrv->gfx_shared->next_valid ? "" : "not " );
115
116 #define AA_COEF 133
117
118 /**********************************************************************************************************************/
119
120 static bool sh7722FillRectangle ( void *drv, void *dev, DFBRectangle *rect );
121 static bool sh7722FillRectangleMatrixAA( void *drv, void *dev, DFBRectangle *rect );
122
123 static bool sh7722DrawRectangle ( void *drv, void *dev, DFBRectangle *rect );
124 static bool sh7722DrawRectangleMatrixAA( void *drv, void *dev, DFBRectangle *rect );
125
126 static bool sh7722DrawLine ( void *drv, void *dev, DFBRegion *line );
127 static bool sh7722DrawLineMatrix ( void *drv, void *dev, DFBRegion *line );
128 static bool sh7722DrawLineAA ( void *drv, void *dev, DFBRegion *line );
129
130 /**********************************************************************************************************************/
131
132 static inline bool
check_blend_functions(const CardState * state)133 check_blend_functions( const CardState *state )
134 {
135 switch (state->src_blend) {
136 case DSBF_ZERO:
137 case DSBF_ONE:
138 case DSBF_DESTCOLOR:
139 case DSBF_INVDESTCOLOR:
140 case DSBF_SRCALPHA:
141 case DSBF_INVSRCALPHA:
142 case DSBF_DESTALPHA:
143 case DSBF_INVDESTALPHA:
144 return true;
145
146 default:
147 break;
148 }
149 switch (state->dst_blend) {
150 case DSBF_ZERO:
151 case DSBF_ONE:
152 case DSBF_SRCCOLOR:
153 case DSBF_INVSRCCOLOR:
154 case DSBF_SRCALPHA:
155 case DSBF_INVSRCALPHA:
156 case DSBF_DESTALPHA:
157 case DSBF_INVDESTALPHA:
158 return true;
159
160 default:
161 break;
162 }
163
164 return false;
165 }
166
167 /**********************************************************************************************************************/
168
169 static inline bool
start_hardware(SH7722DriverData * sdrv)170 start_hardware( SH7722DriverData *sdrv )
171 {
172 SH772xGfxSharedArea *shared = sdrv->gfx_shared;
173
174 D_DEBUG_AT( SH7722_BLT, "%s()\n", __FUNCTION__ );
175
176 DUMP_INFO();
177
178 if (shared->hw_running || !shared->next_valid || shared->next_end == shared->next_start)
179 return false;
180
181 shared->hw_running = true;
182 shared->hw_start = shared->next_start;
183 shared->hw_end = shared->next_end;
184
185 shared->next_start = shared->next_end = (shared->hw_end + 1 + 3) & ~3;
186 shared->next_valid = false;
187
188 shared->num_words += shared->hw_end - shared->hw_start;
189
190 shared->num_starts++;
191
192 DUMP_INFO();
193
194 D_ASSERT( shared->buffer[shared->hw_end] == 0xF0000000 );
195
196 SH7722_TDG_SETREG32( sdrv, BEM_HC_DMA_ADR, shared->buffer_phys + shared->hw_start*4 );
197 SH7722_TDG_SETREG32( sdrv, BEM_HC_DMA_START, 1 );
198
199 return true;
200 }
201
202 __attribute__((noinline))
203 static void
flush_prepared(SH7722DriverData * sdrv)204 flush_prepared( SH7722DriverData *sdrv )
205 {
206 SH772xGfxSharedArea *shared = sdrv->gfx_shared;
207 unsigned int timeout = 2;
208
209 D_DEBUG_AT( SH7722_BLT, "%s()\n", __FUNCTION__ );
210
211 DUMP_INFO();
212
213 D_ASSERT( sdrv->prep_num < SH772xGFX_BUFFER_WORDS );
214 D_ASSERT( sdrv->prep_num <= D_ARRAY_SIZE(sdrv->prep_buf) );
215
216 /* Something prepared? */
217 while (sdrv->prep_num) {
218 int next_end;
219
220 /* Mark shared information as invalid. From this point on the interrupt handler
221 * will not continue with the next block, and we'll start the hardware ourself. */
222 shared->next_valid = false;
223
224 /* Check if there's enough space at the end.
225 * Wait until hardware has started next block before it gets too big. */
226 if (shared->next_end + sdrv->prep_num >= SH772xGFX_BUFFER_WORDS ||
227 shared->next_end - shared->next_start >= SH772xGFX_BUFFER_WORDS/4)
228 {
229 /* If there's no next block waiting, start at the beginning. */
230 if (shared->next_start == shared->next_end)
231 shared->next_start = shared->next_end = 0;
232 else {
233 D_ASSERT( shared->buffer[shared->hw_end] == 0xF0000000 );
234
235 /* Mark area as valid again. */
236 shared->next_valid = true;
237
238 /* Start in case it got idle while doing the checks. */
239 if (!start_hardware( sdrv )) {
240 /*
241 * Hardware has not been started (still running).
242 * Check for timeout. */
243 if (!timeout--) {
244 D_ERROR( "SH7722/Blt: Timeout waiting for processing!\n" );
245 direct_log_printf( NULL, " -> %srunning, hw %d-%d, next %d-%d - %svalid\n", \
246 sdrv->gfx_shared->hw_running ? "" : "not ", \
247 sdrv->gfx_shared->hw_start, \
248 sdrv->gfx_shared->hw_end, \
249 sdrv->gfx_shared->next_start, \
250 sdrv->gfx_shared->next_end, \
251 sdrv->gfx_shared->next_valid ? "" : "not " );
252 D_ASSERT( shared->buffer[shared->hw_end] == 0xF0000000 );
253 sh7722EngineReset( sdrv, sdrv->dev );
254 }
255
256 /* Wait til next block is started. */
257 ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_WAIT_NEXT );
258 }
259
260 /* Start over with the checks. */
261 continue;
262 }
263 }
264
265 /* We are appending in case there was already a next block. */
266 next_end = shared->next_end + sdrv->prep_num;
267
268 /* Reset the timeout counter. */
269 timeout = 2;
270
271 /* While the hardware is running... */
272 while (shared->hw_running) {
273 D_ASSERT( shared->buffer[shared->hw_end] == 0xF0000000 );
274
275 /* ...make sure we don't over lap with its current buffer, otherwise wait. */
276 if (shared->hw_start > next_end || shared->hw_end < shared->next_start)
277 break;
278
279 /* Check for timeout. */
280 if (!timeout--) {
281 D_ERROR( "SH7722/Blt: Timeout waiting for space!\n" );
282 direct_log_printf( NULL, " -> %srunning, hw %d-%d, next %d-%d - %svalid\n", \
283 sdrv->gfx_shared->hw_running ? "" : "not ", \
284 sdrv->gfx_shared->hw_start, \
285 sdrv->gfx_shared->hw_end, \
286 sdrv->gfx_shared->next_start, \
287 sdrv->gfx_shared->next_end, \
288 sdrv->gfx_shared->next_valid ? "" : "not " );
289 D_ASSERT( shared->buffer[shared->hw_end] == 0xF0000000 );
290 sh7722EngineReset( sdrv, sdrv->dev );
291 }
292
293 /* Wait til next block is started. */
294 ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_WAIT_NEXT );
295 }
296
297 /* Copy from local to shared buffer. */
298 direct_memcpy( (void*) &shared->buffer[shared->next_end], &sdrv->prep_buf[0], sdrv->prep_num * sizeof(__u32) );
299
300 /* Terminate the block. */
301 shared->buffer[next_end] = 0xF0000000;
302
303 /* Update next block information and mark valid. */
304 shared->next_end = next_end;
305 shared->next_valid = true;
306
307 /* Reset local counter. */
308 sdrv->prep_num = 0;
309 }
310
311 /* Start in case it is idle. */
312 start_hardware( sdrv );
313 }
314
315 static inline __u32 *
start_buffer(SH7722DriverData * sdrv,int space)316 start_buffer( SH7722DriverData *sdrv,
317 int space )
318 {
319 /* Check for space in local buffer. */
320 if (sdrv->prep_num + space > SH7722GFX_MAX_PREPARE) {
321 /* Flush local buffer. */
322 flush_prepared( sdrv );
323
324 D_ASSERT( sdrv->prep_num == 0 );
325 }
326
327 /* Return next write position. */
328 return &sdrv->prep_buf[sdrv->prep_num];
329 }
330
331 static inline void
submit_buffer(SH7722DriverData * sdrv,int entries)332 submit_buffer( SH7722DriverData *sdrv,
333 int entries )
334 {
335 D_ASSERT( sdrv->prep_num + entries <= SH7722GFX_MAX_PREPARE );
336
337 /* Increment next write position. */
338 sdrv->prep_num += entries;
339 }
340
341 /**********************************************************************************************************************/
342
343 static inline void
sh7722_validate_DEST_CLIP(SH7722DriverData * sdrv,SH7722DeviceData * sdev,CardState * state)344 sh7722_validate_DEST_CLIP( SH7722DriverData *sdrv,
345 SH7722DeviceData *sdev,
346 CardState *state )
347 {
348 __u32 *prep = start_buffer( sdrv, 10 );
349
350 D_DEBUG_AT( SH7722_BLT, "%s( 0x%08lx [%d] - %4d,%4d-%4dx%4d )\n", __FUNCTION__,
351 state->dst.phys, state->dst.pitch, DFB_RECTANGLE_VALS_FROM_REGION( &state->clip ) );
352
353 /* Set clip. */
354 prep[0] = BEM_PE_SC0_MIN;
355 prep[1] = SH7722_XY( state->clip.x1, state->clip.y1 );
356
357 prep[2] = BEM_PE_SC0_MAX;
358 prep[3] = SH7722_XY( state->clip.x2, state->clip.y2 );
359
360 /* Only clip? */
361 if (sdev->v_flags & DEST) {
362 submit_buffer( sdrv, 4 );
363 }
364 else {
365 CoreSurface *surface = state->destination;
366 CoreSurfaceBuffer *buffer = state->dst.buffer;
367
368 sdev->dst_phys = state->dst.phys;
369 sdev->dst_pitch = state->dst.pitch;
370 sdev->dst_bpp = DFB_BYTES_PER_PIXEL( buffer->format );
371 sdev->dst_index = DFB_PIXELFORMAT_INDEX( buffer->format ) % DFB_NUM_PIXELFORMATS;
372
373 /* Set destination. */
374 prep[4] = BEM_PE_DST;
375 prep[5] = pixel_formats[sdev->dst_index];
376
377 prep[6] = BEM_PE_DST_BASE;
378 prep[7] = sdev->dst_phys;
379
380 prep[8] = BEM_PE_DST_SIZE;
381 prep[9] = SH7722_XY( sdev->dst_pitch / sdev->dst_bpp, surface->config.size.h );
382
383 submit_buffer( sdrv, 10 );
384 }
385
386 /* Set the flags. */
387 SH7722_VALIDATE( DEST_CLIP );
388 }
389
390 static inline void
sh7722_validate_SOURCE(SH7722DriverData * sdrv,SH7722DeviceData * sdev,CardState * state)391 sh7722_validate_SOURCE( SH7722DriverData *sdrv,
392 SH7722DeviceData *sdev,
393 CardState *state )
394 {
395 CoreSurface *surface = state->source;
396 CoreSurfaceBuffer *buffer = state->src.buffer;
397 __u32 *prep = start_buffer( sdrv, 6 );
398
399 sdev->src_phys = state->src.phys;
400 sdev->src_pitch = state->src.pitch;
401 sdev->src_bpp = DFB_BYTES_PER_PIXEL( buffer->format );
402 sdev->src_index = DFB_PIXELFORMAT_INDEX( buffer->format ) % DFB_NUM_PIXELFORMATS;
403
404 /* Set source. */
405 prep[0] = BEM_TE_SRC;
406 prep[1] = pixel_formats[sdev->src_index];
407
408 prep[2] = BEM_TE_SRC_BASE;
409 prep[3] = sdev->src_phys;
410
411 prep[4] = BEM_TE_SRC_SIZE;
412 prep[5] = SH7722_XY( sdev->src_pitch / sdev->src_bpp, surface->config.size.h );
413
414 submit_buffer( sdrv, 6 );
415
416 /* Set the flag. */
417 SH7722_VALIDATE( SOURCE );
418 }
419
420 __attribute__((noinline))
421 static void
sh7722_validate_MASK(SH7722DriverData * sdrv,SH7722DeviceData * sdev,CardState * state)422 sh7722_validate_MASK( SH7722DriverData *sdrv,
423 SH7722DeviceData *sdev,
424 CardState *state )
425 {
426 CoreSurface *surface = state->source_mask;
427 CoreSurfaceBuffer *buffer = state->src_mask.buffer;
428 __u32 *prep = start_buffer( sdrv, 6 );
429
430 sdev->mask_phys = state->src_mask.phys;
431 sdev->mask_pitch = state->src_mask.pitch;
432 sdev->mask_format = buffer->format;
433 sdev->mask_index = DFB_PIXELFORMAT_INDEX( buffer->format ) % DFB_NUM_PIXELFORMATS;
434 sdev->mask_offset = state->src_mask_offset;
435 sdev->mask_flags = state->src_mask_flags;
436
437 /* Set mask. */
438 prep[0] = BEM_TE_MASK;
439 prep[1] = TE_MASK_ENABLE | pixel_formats[sdev->mask_index];
440
441 prep[2] = BEM_TE_MASK_SIZE;
442 prep[3] = SH7722_XY( sdev->mask_pitch / DFB_BYTES_PER_PIXEL(sdev->mask_format), surface->config.size.h );
443
444 prep[4] = BEM_TE_MASK_BASE;
445 prep[5] = sdev->mask_phys + sdev->mask_pitch * sdev->mask_offset.y +
446 DFB_BYTES_PER_LINE( sdev->mask_format, sdev->mask_offset.x );
447
448 submit_buffer( sdrv, 6 );
449
450 /* Set the flag. */
451 SH7722_VALIDATE( MASK );
452 }
453
454 static inline void
sh7722_validate_COLOR(SH7722DriverData * sdrv,SH7722DeviceData * sdev,CardState * state)455 sh7722_validate_COLOR( SH7722DriverData *sdrv,
456 SH7722DeviceData *sdev,
457 CardState *state )
458 {
459 __u32 *prep = start_buffer( sdrv, 4 );
460
461 prep[0] = BEM_BE_COLOR1;
462 prep[1] = PIXEL_ARGB( state->color.a,
463 state->color.r,
464 state->color.g,
465 state->color.b );
466
467 prep[2] = BEM_WR_FGC;
468 prep[3] = prep[1];
469
470 submit_buffer( sdrv, 4 );
471
472 /* Set the flag. */
473 SH7722_VALIDATE( COLOR );
474 }
475
476 __attribute__((noinline))
477 static void
sh7722_validate_COLOR_KEY(SH7722DriverData * sdrv,SH7722DeviceData * sdev,CardState * state)478 sh7722_validate_COLOR_KEY( SH7722DriverData *sdrv,
479 SH7722DeviceData *sdev,
480 CardState *state )
481 {
482 CoreSurfaceBuffer *buffer = state->src.buffer;
483 __u32 *prep = start_buffer( sdrv, 4 );
484
485 prep[0] = BEM_PE_CKEY;
486 prep[1] = CKEY_EXCLUDE_ALPHA | CKEY_EXCLUDE_UNUSED | CKEY_B_ENABLE;
487
488 prep[2] = BEM_PE_CKEY_B;
489
490 switch (buffer->format) {
491 case DSPF_ARGB:
492 case DSPF_RGB32:
493 prep[3] = state->src_colorkey;
494 break;
495
496 case DSPF_RGB16:
497 prep[3] = RGB16_TO_RGB32( state->src_colorkey );
498 break;
499
500 case DSPF_ARGB1555:
501 case DSPF_RGB555:
502 prep[3] = ARGB1555_TO_RGB32( state->src_colorkey );
503 break;
504
505 case DSPF_ARGB4444:
506 case DSPF_RGB444:
507 prep[3] = ARGB4444_TO_RGB32( state->src_colorkey );
508 break;
509
510 default:
511 D_BUG( "unexpected pixelformat" );
512 }
513
514 submit_buffer( sdrv, 4 );
515
516 /* Set the flag. */
517 SH7722_VALIDATE( COLOR_KEY );
518 }
519
520 /* let compiler decide here :) */
521 static void
sh7722_validate_COLOR_CHANGE(SH7722DriverData * sdrv,SH7722DeviceData * sdev,CardState * state)522 sh7722_validate_COLOR_CHANGE( SH7722DriverData *sdrv,
523 SH7722DeviceData *sdev,
524 CardState *state )
525 {
526 __u32 *prep = start_buffer( sdrv, 6 );
527
528 prep[0] = BEM_PE_COLORCHANGE;
529 prep[1] = COLORCHANGE_COMPARE_FIRST | COLORCHANGE_EXCLUDE_UNUSED;
530
531 prep[2] = BEM_PE_COLORCHANGE_0;
532 prep[3] = 0xffffff;
533
534 prep[4] = BEM_PE_COLORCHANGE_1;
535 prep[5] = PIXEL_ARGB( state->color.a,
536 state->color.r,
537 state->color.g,
538 state->color.b );
539
540 submit_buffer( sdrv, 6 );
541
542 /* Set the flag. */
543 SH7722_VALIDATE( COLOR_CHANGE );
544 }
545
546 /* DSBF_UNKNOWN = 0 */
547 /* BLE_DSTF_ZERO = 0 DSBF_ZERO = 1 */
548 /* BLE_DSTF_ONE = 1 DSBF_ONE = 2 */
549 /* BLE_DSTF_SRC = 2 DSBF_SRCCOLOR = 3 */
550 /* BLE_DSTF_1_SRC = 3 DSBF_INVSRCCOLOR = 4 */
551 /* BLE_DSTF_SRC_A = 4 DSBF_SRCALPHA = 5 */
552 /* BLE_DSTF_1_SRC_A = 5 DSBF_INVSRCALPHA = 6 */
553 /* BLE_DSTF_DST_A = 6 DSBF_DESTALPHA = 7 */
554 /* BLE_DSTF_1_DST_A = 7 DSBF_INVDESTALPHA = 8 */
555 /* DSBF_DESTCOLOR = 9 */
556 /* Hey, matches!!? :-P DSBF_INVDESTCOLOR = 10 */
557 /* DSBF_SRCALPHASAT = 11 */
558
559 static inline void
sh7722_validate_BLENDING(SH7722DriverData * sdrv,SH7722DeviceData * sdev,CardState * state)560 sh7722_validate_BLENDING( SH7722DriverData *sdrv,
561 SH7722DeviceData *sdev,
562 CardState *state )
563 {
564 __u32 *prep = start_buffer( sdrv, 2 );
565
566 sdev->ble_dstf = (state->dst_blend - 1) & 7;
567 sdev->ble_srcf = ((state->src_blend - 1) & 7) << 4;
568
569 prep[0] = BEM_PE_FIXEDALPHA;
570 prep[1] = (state->color.a << 24) | (state->color.a << 16);
571
572 submit_buffer( sdrv, 2 );
573
574 /* Set the flag. */
575 SH7722_VALIDATE( BLENDING );
576 }
577
578 __attribute__((noinline))
579 static void
sh7722_validate_MATRIX(SH7722DriverData * sdrv,SH7722DeviceData * sdev,CardState * state)580 sh7722_validate_MATRIX( SH7722DriverData *sdrv,
581 SH7722DeviceData *sdev,
582 CardState *state )
583 {
584 __u32 *prep = start_buffer( sdrv, 12 );
585
586 prep[0] = BEM_BE_MATRIX_A;
587 prep[1] = state->matrix[0];
588
589 prep[2] = BEM_BE_MATRIX_B;
590 prep[3] = state->matrix[1];
591
592 prep[4] = BEM_BE_MATRIX_C;
593 prep[5] = state->matrix[2];
594
595 prep[6] = BEM_BE_MATRIX_D;
596 prep[7] = state->matrix[3];
597
598 prep[8] = BEM_BE_MATRIX_E;
599 prep[9] = state->matrix[4];
600
601 prep[10] = BEM_BE_MATRIX_F;
602 prep[11] = state->matrix[5];
603
604 submit_buffer( sdrv, 12 );
605
606 /* Keep for CPU transformation of lines. */
607 direct_memcpy( sdev->matrix, state->matrix, sizeof(s32) * 6 );
608
609 /* Set the flag. */
610 SH7722_VALIDATE( MATRIX );
611 }
612
613 static inline void
sh7722_validate_BLIT_OP(SH7722DriverData * sdrv,SH7722DeviceData * sdev,CardState * state)614 sh7722_validate_BLIT_OP( SH7722DriverData *sdrv,
615 SH7722DeviceData *sdev,
616 CardState *state )
617 {
618 __u32 *prep = start_buffer( sdrv, 2 );
619
620 prep[0] = BEM_PE_OPERATION;
621 prep[1] = BLE_FUNC_NONE;
622
623 if (state->blittingflags & DSBLIT_XOR)
624 prep[1] |= BLE_ROP_XOR;
625
626 if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
627 prep[1] |= BLE_FUNC_AxB_plus_CxD | sdev->ble_srcf | sdev->ble_dstf;
628
629 switch (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
630 case DSBLIT_BLEND_ALPHACHANNEL:
631 prep[1] |= BLE_SRCA_SOURCE_ALPHA;
632 break;
633
634 case DSBLIT_BLEND_COLORALPHA:
635 prep[1] |= BLE_SRCA_FIXED;
636 break;
637 }
638 }
639 else if (state->blittingflags & DSBLIT_SRC_MASK_ALPHA)
640 prep[1] |= BLE_FUNC_AxB_plus_CxD | BLE_SRCA_ALPHA_CHANNEL | BLE_SRCF_SRC_A | BLE_DSTF_1_SRC_A;
641
642 submit_buffer( sdrv, 2 );
643
644 /* Set the flag. */
645 SH7722_VALIDATE( BLIT_OP );
646 }
647
648 /**********************************************************************************************************************/
649
650 __attribute__((noinline))
651 static void
invalidate_ckey(SH7722DriverData * sdrv,SH7722DeviceData * sdev)652 invalidate_ckey( SH7722DriverData *sdrv, SH7722DeviceData *sdev )
653 {
654 __u32 *prep = start_buffer( sdrv, 4 );
655
656 prep[0] = BEM_PE_CKEY;
657 prep[1] = 0;
658
659 prep[2] = BEM_PE_CKEY_B;
660 prep[3] = 0;
661
662 submit_buffer( sdrv, 4 );
663
664 sdev->ckey_b_enabled = false;
665
666 SH7722_INVALIDATE( COLOR_KEY );
667 }
668
669 __attribute__((noinline))
670 static void
invalidate_color_change(SH7722DriverData * sdrv,SH7722DeviceData * sdev)671 invalidate_color_change( SH7722DriverData *sdrv, SH7722DeviceData *sdev )
672 {
673 __u32 *prep = start_buffer( sdrv, 2 );
674
675 prep[0] = BEM_PE_COLORCHANGE;
676 prep[1] = COLORCHANGE_DISABLE;
677
678 submit_buffer( sdrv, 2 );
679
680 sdev->color_change_enabled = false;
681
682 SH7722_INVALIDATE( COLOR_CHANGE );
683 }
684
685 __attribute__((noinline))
686 static void
invalidate_mask(SH7722DriverData * sdrv,SH7722DeviceData * sdev)687 invalidate_mask( SH7722DriverData *sdrv, SH7722DeviceData *sdev )
688 {
689 u32 *prep = start_buffer( sdrv, 2 );
690
691 prep[0] = BEM_TE_MASK;
692 prep[1] = TE_MASK_DISABLE;
693
694 submit_buffer( sdrv, 2 );
695
696 sdev->mask_enabled = false;
697
698 SH7722_INVALIDATE( MASK );
699 }
700
701 /**********************************************************************************************************************/
702
703 DFBResult
sh7722EngineSync(void * drv,void * dev)704 sh7722EngineSync( void *drv, void *dev )
705 {
706 DFBResult ret = DFB_OK;
707 SH7722DriverData *sdrv = drv;
708 SH772xGfxSharedArea *shared = sdrv->gfx_shared;
709
710 D_DEBUG_AT( SH7722_BLT, "%s()\n", __FUNCTION__ );
711
712 DUMP_INFO();
713
714 while (shared->hw_running && ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_WAIT_IDLE ) < 0) {
715 if (errno == EINTR)
716 continue;
717
718 ret = errno2result( errno );
719 D_PERROR( "SH7722/BLT: SH7722GFX_IOCTL_WAIT_IDLE failed!\n" );
720
721 direct_log_printf( NULL, " -> %srunning, hw %d-%d, next %d-%d - %svalid\n", \
722 sdrv->gfx_shared->hw_running ? "" : "not ", \
723 sdrv->gfx_shared->hw_start, \
724 sdrv->gfx_shared->hw_end, \
725 sdrv->gfx_shared->next_start, \
726 sdrv->gfx_shared->next_end, \
727 sdrv->gfx_shared->next_valid ? "" : "not " );
728
729 break;
730 }
731
732 if (ret == DFB_OK) {
733 D_ASSERT( !shared->hw_running );
734 D_ASSERT( !shared->next_valid );
735 }
736
737 return ret;
738 }
739
740 void
sh7722EngineReset(void * drv,void * dev)741 sh7722EngineReset( void *drv, void *dev )
742 {
743 SH7722DriverData *sdrv = drv;
744 SH7722DeviceData *sdev = dev;
745 __u32 *prep;
746
747 D_DEBUG_AT( SH7722_BLT, "%s()\n", __FUNCTION__ );
748
749 DUMP_INFO();
750
751 ioctl( sdrv->gfx_fd, SH772xGFX_IOCTL_RESET );
752
753 prep = start_buffer( sdrv, 20 );
754
755 prep[0] = BEM_PE_OPERATION;
756 prep[1] = 0x00000000;
757
758 prep[2] = BEM_PE_COLORCHANGE;
759 prep[3] = 0x00000000;
760
761 prep[4] = BEM_PE_CKEY;
762 prep[5] = 0x00000000;
763
764 prep[6] = BEM_PE_CKEY_B;
765 prep[7] = 0;
766
767 prep[8] = BEM_PE_FIXEDALPHA;
768 prep[9] = 0x80000000;
769
770 prep[10] = BEM_TE_SRC_CNV;
771 prep[11] = 0x00100010; /* full conversion of Ad, As, Cd and Cs */
772
773 prep[12] = BEM_TE_FILTER;
774 prep[13] = 0x00000000; /* 0 = nearest, 3 = up bilinear / down average */
775
776 prep[14] = BEM_PE_SC;
777 prep[15] = 0x00000001; /* enable clipping */
778
779 prep[16] = BEM_BE_ORIGIN;
780 prep[17] = SH7722_XY( 0, 0 );
781
782 prep[18] = BEM_TE_MASK_CNV;
783 prep[19] = 2;
784
785 submit_buffer( sdrv, 20 );
786
787 sdev->ckey_b_enabled = false;
788 sdev->color_change_enabled = false;
789 sdev->mask_enabled = false;
790 }
791
792 void
sh7722EmitCommands(void * drv,void * dev)793 sh7722EmitCommands( void *drv, void *dev )
794 {
795 SH7722DriverData *sdrv = drv;
796
797 D_DEBUG_AT( SH7722_BLT, "%s()\n", __FUNCTION__ );
798
799 flush_prepared( sdrv );
800 }
801
802 void
sh7722FlushTextureCache(void * drv,void * dev)803 sh7722FlushTextureCache( void *drv, void *dev )
804 {
805 SH7722DriverData *sdrv = drv;
806 __u32 *prep = start_buffer( sdrv, 4 );
807
808 D_DEBUG_AT( SH7722_BLT, "%s()\n", __FUNCTION__ );
809
810 DUMP_INFO();
811
812 prep[0] = BEM_PE_CACHE;
813 prep[1] = 2;
814
815 prep[2] = BEM_TE_INVALID;
816 prep[3] = 1;
817
818 submit_buffer( sdrv, 4 );
819 }
820
821 /**********************************************************************************************************************/
822
823 void
sh7722CheckState(void * drv,void * dev,CardState * state,DFBAccelerationMask accel)824 sh7722CheckState( void *drv,
825 void *dev,
826 CardState *state,
827 DFBAccelerationMask accel )
828 {
829 D_DEBUG_AT( SH7722_BLT, "%s( %p, 0x%08x )\n", __FUNCTION__, state, accel );
830
831 /* Return if the desired function is not supported at all. */
832 if (accel & ~(SH7722_SUPPORTED_DRAWINGFUNCTIONS | SH7722_SUPPORTED_BLITTINGFUNCTIONS))
833 return;
834
835 /* Return if the destination format is not supported. */
836 switch (state->destination->config.format) {
837 case DSPF_ARGB:
838 case DSPF_RGB32:
839 case DSPF_RGB16:
840 case DSPF_ARGB1555:
841 case DSPF_RGB555:
842 case DSPF_ARGB4444:
843 case DSPF_RGB444:
844 break;
845 default:
846 return;
847 }
848
849 /* Check if drawing or blitting is requested. */
850 if (DFB_DRAWING_FUNCTION( accel )) {
851 /* Return if unsupported drawing flags are set. */
852 if (state->drawingflags & ~SH7722_SUPPORTED_DRAWINGFLAGS)
853 return;
854
855 /* Return if blending with unsupported blend functions is requested. */
856 if (state->drawingflags & DSDRAW_BLEND) {
857 /* Check blend functions. */
858 if (!check_blend_functions( state ))
859 return;
860
861 /* XOR only without blending. */
862 if (state->drawingflags & DSDRAW_XOR)
863 return;
864 }
865
866 /* Enable acceleration of drawing functions. */
867 state->accel |= SH7722_SUPPORTED_DRAWINGFUNCTIONS;
868 }
869 else {
870 DFBSurfaceBlittingFlags flags = state->blittingflags;
871
872 /* Return if unsupported blitting flags are set. */
873 if (flags & ~SH7722_SUPPORTED_BLITTINGFLAGS)
874 return;
875
876 /* Return if the source format is not supported. */
877 switch (state->source->config.format) {
878 case DSPF_ARGB:
879 case DSPF_RGB32:
880 case DSPF_RGB16:
881 case DSPF_ARGB1555:
882 case DSPF_RGB555:
883 case DSPF_ARGB4444:
884 case DSPF_RGB444:
885 break;
886
887 default:
888 return;
889 }
890
891 /* Return if blending with unsupported blend functions is requested. */
892 if (flags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
893 /* Check blend functions. */
894 if (!check_blend_functions( state ))
895 return;
896 }
897
898 /* XOR only without blending etc. */
899 if (flags & DSBLIT_XOR &&
900 flags & ~(DSBLIT_SRC_COLORKEY | DSBLIT_ROTATE180 | DSBLIT_XOR))
901 return;
902
903 /* Return if colorizing for non-font surfaces is requested. */
904 if ((flags & DSBLIT_COLORIZE) && !(state->source->type & CSTF_FONT))
905 return;
906
907 /* Return if blending with both alpha channel and value is requested. */
908 if (D_FLAGS_ARE_SET( flags, DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA))
909 return;
910
911 /* Mask checking. */
912 if (flags & DSBLIT_SRC_MASK_ALPHA) {
913 if (!state->source_mask)
914 return;
915
916 /* Return if the source mask format is not supported. */
917 switch (state->source_mask->config.format) {
918 case DSPF_A1:
919 case DSPF_A8:
920 break;
921
922 default:
923 return;
924 }
925 }
926
927 /* Enable acceleration of blitting functions. */
928 state->accel |= SH7722_SUPPORTED_BLITTINGFUNCTIONS;
929 }
930 }
931
932 /*
933 * Make sure that the hardware is programmed for execution of 'accel' according to the 'state'.
934 */
935 void
sh7722SetState(void * drv,void * dev,GraphicsDeviceFuncs * funcs,CardState * state,DFBAccelerationMask accel)936 sh7722SetState( void *drv,
937 void *dev,
938 GraphicsDeviceFuncs *funcs,
939 CardState *state,
940 DFBAccelerationMask accel )
941 {
942 SH7722DriverData *sdrv = drv;
943 SH7722DeviceData *sdev = dev;
944 StateModificationFlags modified = state->mod_hw;
945
946 D_DEBUG_AT( SH7722_BLT, "%s( %p, 0x%08x ) <- modified 0x%08x\n",
947 __FUNCTION__, state, accel, modified );
948 DUMP_INFO();
949
950 /*
951 * 1) Invalidate hardware states
952 *
953 * Each modification to the hw independent state invalidates one or more hardware states.
954 */
955
956 /* Simply invalidate all? */
957 if (modified == SMF_ALL) {
958 SH7722_INVALIDATE( ALL );
959 }
960 else if (modified) {
961 /* Invalidate destination registers. */
962 if (modified & SMF_DESTINATION)
963 SH7722_INVALIDATE( DEST );
964
965 /* Invalidate clipping registers. */
966 if (modified & SMF_CLIP)
967 SH7722_INVALIDATE( CLIP );
968
969 /* Invalidate source registers. */
970 if (modified & SMF_SOURCE)
971 SH7722_INVALIDATE( SOURCE | COLOR_KEY );
972 else if (modified & SMF_SRC_COLORKEY)
973 SH7722_INVALIDATE( COLOR_KEY );
974
975 /* Invalidate mask registers. */
976 if (modified & (SMF_SOURCE_MASK | SMF_SOURCE_MASK_VALS))
977 SH7722_INVALIDATE( MASK );
978
979 /* Invalidate color registers. */
980 if (modified & SMF_COLOR)
981 SH7722_INVALIDATE( BLENDING | COLOR | COLOR_CHANGE );
982 else if (modified & (SMF_SRC_BLEND | SMF_SRC_BLEND))
983 SH7722_INVALIDATE( BLENDING );
984
985 /* Invalidate matrix registers. */
986 if (modified & SMF_MATRIX)
987 SH7722_INVALIDATE( MATRIX );
988
989 /* Invalidate blitting operation. */
990 if (modified & SMF_BLITTING_FLAGS)
991 SH7722_INVALIDATE( BLIT_OP );
992 }
993
994 /*
995 * 2) Validate hardware states
996 *
997 * Each function has its own set of states that need to be validated.
998 */
999
1000 /* Always requiring valid destination and clip. */
1001 SH7722_CHECK_VALIDATE( DEST_CLIP );
1002
1003 /* Use transformation matrix? */
1004 if (state->render_options & DSRO_MATRIX)
1005 SH7722_CHECK_VALIDATE( MATRIX );
1006
1007 /* Depending on the function... */
1008 switch (accel) {
1009 case DFXL_FILLRECTANGLE:
1010 case DFXL_FILLTRIANGLE:
1011 case DFXL_DRAWRECTANGLE:
1012 case DFXL_DRAWLINE:
1013 /* ...require valid color. */
1014 SH7722_CHECK_VALIDATE( COLOR );
1015
1016 /* Use blending? */
1017 if (state->drawingflags & DSDRAW_BLEND) {
1018 /* need valid source and destination blend factors */
1019 SH7722_CHECK_VALIDATE( BLENDING );
1020 }
1021
1022 /* Clear old ckeys */
1023 if (sdev->ckey_b_enabled)
1024 invalidate_ckey( sdrv, sdev );
1025
1026 /* Clear old mask */
1027 if (sdev->mask_enabled)
1028 invalidate_mask( sdrv, sdev );
1029
1030 /* Choose function. */
1031 switch (accel) {
1032 case DFXL_FILLRECTANGLE:
1033 if (state->render_options & (DSRO_MATRIX | DSRO_ANTIALIAS))
1034 funcs->FillRectangle = sh7722FillRectangleMatrixAA;
1035 else
1036 funcs->FillRectangle = sh7722FillRectangle;
1037 break;
1038
1039 case DFXL_DRAWRECTANGLE:
1040 if (state->render_options & (DSRO_MATRIX | DSRO_ANTIALIAS))
1041 funcs->DrawRectangle = sh7722DrawRectangleMatrixAA;
1042 else
1043 funcs->DrawRectangle = sh7722DrawRectangle;
1044 break;
1045
1046 case DFXL_DRAWLINE:
1047 if (state->render_options & DSRO_ANTIALIAS)
1048 funcs->DrawLine = sh7722DrawLineAA;
1049 else if (state->render_options & DSRO_MATRIX)
1050 funcs->DrawLine = sh7722DrawLineMatrix;
1051 else
1052 funcs->DrawLine = sh7722DrawLine;
1053 break;
1054
1055 default:
1056 break;
1057 }
1058
1059 /*
1060 * 3) Tell which functions can be called without further validation, i.e. SetState()
1061 *
1062 * When the hw independent state is changed, this collection is reset.
1063 */
1064 state->set = SH7722_SUPPORTED_DRAWINGFUNCTIONS;
1065 break;
1066
1067 case DFXL_BLIT:
1068 case DFXL_STRETCHBLIT:
1069 /* ...require valid source. */
1070 SH7722_CHECK_VALIDATE( SOURCE );
1071
1072 /* Use blending? */
1073 if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) {
1074 /* need valid source and destination blend factors */
1075 SH7722_CHECK_VALIDATE( BLENDING );
1076 }
1077
1078 /* Use color keying? */
1079 if (state->blittingflags & DSBLIT_SRC_COLORKEY) {
1080 /* Need valid color key settings (enabling). */
1081 SH7722_CHECK_VALIDATE( COLOR_KEY );
1082
1083 sdev->ckey_b_enabled = true;
1084 }
1085 /* Disable color keying? */
1086 else if (sdev->ckey_b_enabled)
1087 invalidate_ckey( sdrv, sdev );
1088
1089 /* Use color change? */
1090 if (state->blittingflags & DSBLIT_COLORIZE) {
1091 /* Need valid color change settings (enabling). */
1092 SH7722_CHECK_VALIDATE( COLOR_CHANGE );
1093
1094 sdev->color_change_enabled = true;
1095 }
1096 /* Disable color change? */
1097 else if (sdev->color_change_enabled)
1098 invalidate_color_change( sdrv, sdev );
1099
1100 /* Use mask? */
1101 if (state->blittingflags & DSBLIT_SRC_MASK_ALPHA) {
1102 /* need valid mask */
1103 SH7722_CHECK_VALIDATE( MASK );
1104
1105 sdev->mask_enabled = true;
1106 }
1107 /* Disable mask? */
1108 else if (sdev->mask_enabled)
1109 invalidate_mask( sdrv, sdev );
1110
1111 SH7722_CHECK_VALIDATE( BLIT_OP );
1112
1113 /*
1114 * 3) Tell which functions can be called without further validation, i.e. SetState()
1115 *
1116 * When the hw independent state is changed, this collection is reset.
1117 */
1118 state->set = SH7722_SUPPORTED_BLITTINGFUNCTIONS;
1119 break;
1120
1121 default:
1122 D_BUG( "unexpected drawing/blitting function" );
1123 break;
1124 }
1125
1126 sdev->dflags = state->drawingflags;
1127 sdev->bflags = state->blittingflags;
1128 sdev->render_options = state->render_options;
1129 sdev->color = state->color;
1130
1131 /*
1132 * 4) Clear modification flags
1133 *
1134 * All flags have been evaluated in 1) and remembered for further validation.
1135 * If the hw independent state is not modified, this function won't get called
1136 * for subsequent rendering functions, unless they aren't defined by 3).
1137 */
1138 state->mod_hw = 0;
1139 }
1140
1141 /**********************************************************************************************************************/
1142
1143 static inline void
draw_rectangle(SH7722DriverData * sdrv,SH7722DeviceData * sdev,int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,bool antialias,bool full)1144 draw_rectangle( SH7722DriverData *sdrv,
1145 SH7722DeviceData *sdev,
1146 int x1, int y1,
1147 int x2, int y2,
1148 int x3, int y3,
1149 int x4, int y4,
1150 bool antialias,
1151 bool full )
1152 {
1153 u32 ctrl = antialias ? WR_CTRL_ANTIALIAS : 0;
1154 u32 *prep = start_buffer( sdrv, full ? 24 : 12 );
1155
1156 if (antialias) {
1157 prep[0] = BEM_WR_FGC;
1158 prep[1] = PIXEL_ARGB( (sdev->color.a * AA_COEF) >> 8,
1159 (sdev->color.r * AA_COEF) >> 8,
1160 (sdev->color.g * AA_COEF) >> 8,
1161 (sdev->color.b * AA_COEF) >> 8 );
1162
1163 prep[2] = BEM_PE_FIXEDALPHA;
1164 prep[3] = (sdev->color.a * AA_COEF) << 16;
1165 }
1166 else {
1167 prep[0] = BEM_WR_FGC;
1168 prep[1] = PIXEL_ARGB( sdev->color.a,
1169 sdev->color.r,
1170 sdev->color.g,
1171 sdev->color.b );
1172
1173 prep[2] = BEM_PE_FIXEDALPHA;
1174 prep[3] = (sdev->color.a << 24) << (sdev->color.a << 16);
1175 }
1176
1177 prep[4] = BEM_WR_V1;
1178 prep[5] = SH7722_XY( x1, y1 );
1179
1180 prep[6] = BEM_WR_V2;
1181 prep[7] = SH7722_XY( x2, y2 );
1182
1183 prep[8] = BEM_PE_OPERATION;
1184 prep[9] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
1185 sdev->ble_srcf |
1186 BLE_SRCA_FIXED |
1187 sdev->ble_dstf)
1188 :
1189 (antialias ?
1190 (BLE_FUNC_AxB_plus_CxD |
1191 BLE_SRCF_ONE |
1192 BLE_SRCA_FIXED |
1193 BLE_DSTF_1_SRC_A) : BLE_FUNC_NONE
1194 );
1195
1196 if (sdev->dflags & DSDRAW_XOR)
1197 prep[9] |= BLE_ROP_XOR;
1198
1199 prep[10] = BEM_WR_CTRL;
1200 prep[11] = WR_CTRL_LINE | ctrl;
1201
1202 if (full) {
1203 prep[12] = BEM_WR_V2;
1204 prep[13] = SH7722_XY( x3, y3 );
1205 prep[14] = BEM_WR_CTRL;
1206 prep[15] = WR_CTRL_POLYLINE | ctrl;
1207
1208 prep[16] = BEM_WR_V2;
1209 prep[17] = SH7722_XY( x4, y4 );
1210 prep[18] = BEM_WR_CTRL;
1211 prep[19] = WR_CTRL_POLYLINE | ctrl;
1212
1213 prep[20] = BEM_WR_V2;
1214 prep[21] = SH7722_XY( x1, y1 );
1215 prep[22] = BEM_WR_CTRL;
1216 prep[23] = WR_CTRL_POLYLINE | ctrl;
1217
1218 submit_buffer( sdrv, 24 );
1219 }
1220 else {
1221 prep[7] = SH7722_XY( x3, y3 );
1222 prep[11] |= WR_CTRL_ENDPOINT;
1223
1224 submit_buffer( sdrv, 12 );
1225 }
1226 }
1227
1228 /*
1229 * Render a filled rectangle using the current hardware state.
1230 */
1231 static bool
sh7722FillRectangle(void * drv,void * dev,DFBRectangle * rect)1232 sh7722FillRectangle( void *drv, void *dev, DFBRectangle *rect )
1233 {
1234 SH7722DriverData *sdrv = drv;
1235 SH7722DeviceData *sdev = dev;
1236 __u32 *prep = start_buffer( sdrv, 8 );
1237
1238 D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__,
1239 DFB_RECTANGLE_VALS( rect ) );
1240 DUMP_INFO();
1241
1242 prep[0] = BEM_BE_V1;
1243 prep[1] = SH7722_XY( rect->x, rect->y );
1244
1245 prep[2] = BEM_BE_V2;
1246 prep[3] = SH7722_XY( rect->w, rect->h );
1247
1248 prep[4] = BEM_PE_OPERATION;
1249 prep[5] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
1250 sdev->ble_srcf |
1251 BLE_SRCA_FIXED |
1252 sdev->ble_dstf) : BLE_FUNC_NONE;
1253
1254 if (sdev->dflags & DSDRAW_XOR)
1255 prep[5] |= BLE_ROP_XOR;
1256
1257 prep[6] = BEM_BE_CTRL;
1258 prep[7] = BE_CTRL_RECTANGLE | BE_CTRL_SCANMODE_LINE;
1259
1260 submit_buffer( sdrv, 8 );
1261
1262 return true;
1263 }
1264
1265 /*
1266 * This version sends a quadrangle to have all four edges transformed.
1267 */
1268 static bool
sh7722FillRectangleMatrixAA(void * drv,void * dev,DFBRectangle * rect)1269 sh7722FillRectangleMatrixAA( void *drv, void *dev, DFBRectangle *rect )
1270 {
1271 SH7722DriverData *sdrv = drv;
1272 SH7722DeviceData *sdev = dev;
1273 __u32 *prep;
1274
1275 D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__,
1276 DFB_RECTANGLE_VALS( rect ) );
1277 DUMP_INFO();
1278
1279
1280 if (sdev->render_options & DSRO_ANTIALIAS) {
1281 int x1 = rect->x;
1282 int y1 = rect->y;
1283 int x2 = rect->x + rect->w;
1284 int y2 = rect->y;
1285 int x3 = rect->x + rect->w;
1286 int y3 = rect->y + rect->h;
1287 int x4 = rect->x;
1288 int y4 = rect->y + rect->h;
1289
1290 if (sdev->render_options & DSRO_MATRIX) {
1291 int t;
1292
1293 t = ((x1 * sdev->matrix[0]) +
1294 (y1 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1295 y1 = ((x1 * sdev->matrix[3]) +
1296 (y1 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1297 x1 = t;
1298
1299 t = ((x2 * sdev->matrix[0]) +
1300 (y2 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1301 y2 = ((x2 * sdev->matrix[3]) +
1302 (y2 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1303 x2 = t;
1304
1305 t = ((x3 * sdev->matrix[0]) +
1306 (y3 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1307 y3 = ((x3 * sdev->matrix[3]) +
1308 (y3 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1309 x3 = t;
1310
1311 t = ((x4 * sdev->matrix[0]) +
1312 (y4 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1313 y4 = ((x4 * sdev->matrix[3]) +
1314 (y4 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1315 x4 = t;
1316 }
1317
1318 prep = start_buffer( sdrv, 28 );
1319
1320 prep[0] = BEM_WR_FGC;
1321 prep[1] = PIXEL_ARGB( (sdev->color.a * AA_COEF) >> 8,
1322 (sdev->color.r * AA_COEF) >> 8,
1323 (sdev->color.g * AA_COEF) >> 8,
1324 (sdev->color.b * AA_COEF) >> 8 );
1325
1326 prep[2] = BEM_PE_FIXEDALPHA;
1327 prep[3] = (sdev->color.a * AA_COEF) << 16;
1328
1329 prep[4] = BEM_WR_V1;
1330 prep[5] = SH7722_XY( x1, y1 );
1331
1332 prep[6] = BEM_WR_V2;
1333 prep[7] = SH7722_XY( x2, y2 );
1334
1335 prep[8] = BEM_PE_OPERATION;
1336 prep[9] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
1337 sdev->ble_srcf |
1338 BLE_SRCA_FIXED |
1339 sdev->ble_dstf)
1340 :
1341 (BLE_FUNC_AxB_plus_CxD |
1342 BLE_SRCF_ONE |
1343 BLE_SRCA_FIXED |
1344 BLE_DSTF_1_SRC_A);
1345
1346 if (sdev->dflags & DSDRAW_XOR)
1347 prep[9] |= BLE_ROP_XOR;
1348
1349 prep[10] = BEM_WR_CTRL;
1350 prep[11] = WR_CTRL_LINE | WR_CTRL_ANTIALIAS;
1351
1352 if (rect->h > 1 && rect->w > 1) {
1353 prep[12] = BEM_WR_V2;
1354 prep[13] = SH7722_XY( x3, y3 );
1355 prep[14] = BEM_WR_CTRL;
1356 prep[15] = WR_CTRL_POLYLINE | WR_CTRL_ANTIALIAS;
1357
1358 prep[16] = BEM_WR_V2;
1359 prep[17] = SH7722_XY( x4, y4 );
1360 prep[18] = BEM_WR_CTRL;
1361 prep[19] = WR_CTRL_POLYLINE | WR_CTRL_ANTIALIAS;
1362
1363 prep[20] = BEM_WR_V2;
1364 prep[21] = SH7722_XY( x1, y1 );
1365 prep[22] = BEM_WR_CTRL;
1366 prep[23] = WR_CTRL_POLYLINE | WR_CTRL_ANTIALIAS;
1367
1368 prep[24] = BEM_WR_FGC;
1369 prep[25] = PIXEL_ARGB( sdev->color.a,
1370 sdev->color.r,
1371 sdev->color.g,
1372 sdev->color.b );
1373
1374 prep[26] = BEM_PE_FIXEDALPHA;
1375 prep[27] = (sdev->color.a << 24) << (sdev->color.a << 16);
1376
1377 submit_buffer( sdrv, 28 );
1378 }
1379 else {
1380 prep[7] = SH7722_XY( x3, y3 );
1381 prep[11] |= WR_CTRL_ENDPOINT;
1382
1383 prep[12] = BEM_WR_FGC;
1384 prep[13] = PIXEL_ARGB( sdev->color.a,
1385 sdev->color.r,
1386 sdev->color.g,
1387 sdev->color.b );
1388
1389 prep[14] = BEM_PE_FIXEDALPHA;
1390 prep[15] = (sdev->color.a << 24) << (sdev->color.a << 16);
1391
1392 submit_buffer( sdrv, 16 );
1393 }
1394 }
1395
1396
1397 prep = start_buffer( sdrv, 12 );
1398
1399 prep[0] = BEM_BE_V1;
1400 prep[1] = SH7722_XY( rect->x, rect->y );
1401
1402 prep[2] = BEM_BE_V2;
1403 prep[3] = SH7722_XY( rect->x, rect->y + rect->h );
1404
1405 prep[4] = BEM_BE_V3;
1406 prep[5] = SH7722_XY( rect->x + rect->w, rect->y );
1407
1408 prep[6] = BEM_BE_V4;
1409 prep[7] = SH7722_XY( rect->x + rect->w, rect->y + rect->h );
1410
1411 prep[8] = BEM_PE_OPERATION;
1412 prep[9] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
1413 sdev->ble_srcf |
1414 BLE_SRCA_FIXED |
1415 sdev->ble_dstf) : BLE_FUNC_NONE;
1416
1417 if (sdev->dflags & DSDRAW_XOR)
1418 prep[9] |= BLE_ROP_XOR;
1419
1420 prep[10] = BEM_BE_CTRL;
1421
1422 if (sdev->render_options & DSRO_MATRIX)
1423 prep[11] = BE_CTRL_QUADRANGLE | BE_CTRL_SCANMODE_4x4 |
1424 BE_CTRL_MATRIX | BE_CTRL_FIXMODE_16_16;// | BE_CTRL_ORIGIN;
1425 else
1426 prep[11] = BE_CTRL_QUADRANGLE | BE_CTRL_SCANMODE_LINE;
1427
1428 submit_buffer( sdrv, 12 );
1429
1430 return true;
1431 }
1432
1433 /*
1434 * Render a filled triangle using the current hardware state.
1435 */
1436 bool
sh7722FillTriangle(void * drv,void * dev,DFBTriangle * tri)1437 sh7722FillTriangle( void *drv, void *dev, DFBTriangle *tri )
1438 {
1439 SH7722DriverData *sdrv = drv;
1440 SH7722DeviceData *sdev = dev;
1441 __u32 *prep;
1442
1443 D_DEBUG_AT( SH7722_BLT, "%s( %d,%d - %d,%d - %d,%d )\n", __FUNCTION__,
1444 tri->x1, tri->y1, tri->x2, tri->y2, tri->x3, tri->y3 );
1445 DUMP_INFO();
1446
1447
1448 if (sdev->render_options & DSRO_ANTIALIAS) {
1449 int x1, y1;
1450 int x2, y2;
1451 int x3, y3;
1452
1453 if (sdev->render_options & DSRO_MATRIX) {
1454 x1 = ((tri->x1 * sdev->matrix[0]) +
1455 (tri->y1 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1456 y1 = ((tri->x1 * sdev->matrix[3]) +
1457 (tri->y1 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1458
1459 x2 = ((tri->x2 * sdev->matrix[0]) +
1460 (tri->y2 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1461 y2 = ((tri->x2 * sdev->matrix[3]) +
1462 (tri->y2 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1463
1464 x3 = ((tri->x3 * sdev->matrix[0]) +
1465 (tri->y3 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1466 y3 = ((tri->x3 * sdev->matrix[3]) +
1467 (tri->y3 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1468 }
1469 else {
1470 x1 = tri->x1;
1471 y1 = tri->y1;
1472 x2 = tri->x2;
1473 y2 = tri->y2;
1474 x3 = tri->x3;
1475 y3 = tri->y3;
1476 }
1477
1478 prep = start_buffer( sdrv, 24 );
1479
1480 prep[0] = BEM_WR_FGC;
1481 prep[1] = PIXEL_ARGB( (sdev->color.a * AA_COEF) >> 8,
1482 (sdev->color.r * AA_COEF) >> 8,
1483 (sdev->color.g * AA_COEF) >> 8,
1484 (sdev->color.b * AA_COEF) >> 8 );
1485
1486 prep[2] = BEM_PE_FIXEDALPHA;
1487 prep[3] = (sdev->color.a * AA_COEF) << 16;
1488
1489 prep[4] = BEM_WR_V1;
1490 prep[5] = SH7722_XY( x1, y1 );
1491
1492 prep[6] = BEM_WR_V2;
1493 prep[7] = SH7722_XY( x2, y2 );
1494
1495 prep[8] = BEM_PE_OPERATION;
1496 prep[9] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
1497 sdev->ble_srcf |
1498 BLE_SRCA_FIXED |
1499 sdev->ble_dstf)
1500 :
1501 (BLE_FUNC_AxB_plus_CxD |
1502 BLE_SRCF_ONE |
1503 BLE_SRCA_FIXED |
1504 BLE_DSTF_1_SRC_A);
1505
1506 if (sdev->dflags & DSDRAW_XOR)
1507 prep[9] |= BLE_ROP_XOR;
1508
1509 prep[10] = BEM_WR_CTRL;
1510 prep[11] = WR_CTRL_LINE | WR_CTRL_ANTIALIAS;
1511
1512 prep[12] = BEM_WR_V2;
1513 prep[13] = SH7722_XY( x3, y3 );
1514 prep[14] = BEM_WR_CTRL;
1515 prep[15] = WR_CTRL_POLYLINE | WR_CTRL_ANTIALIAS;
1516
1517 prep[16] = BEM_WR_V2;
1518 prep[17] = SH7722_XY( x1, y1 );
1519 prep[18] = BEM_WR_CTRL;
1520 prep[19] = WR_CTRL_POLYLINE | WR_CTRL_ANTIALIAS;
1521
1522 prep[20] = BEM_WR_FGC;
1523 prep[21] = PIXEL_ARGB( sdev->color.a,
1524 sdev->color.r,
1525 sdev->color.g,
1526 sdev->color.b );
1527
1528 prep[22] = BEM_PE_FIXEDALPHA;
1529 prep[23] = (sdev->color.a << 24) << (sdev->color.a << 16);
1530
1531 submit_buffer( sdrv, 24 );
1532 }
1533
1534
1535 prep = start_buffer( sdrv, 12 );
1536
1537 prep[0] = BEM_BE_V1;
1538 prep[1] = SH7722_XY( tri->x1, tri->y1 );
1539
1540 prep[2] = BEM_BE_V2;
1541 prep[3] = SH7722_XY( tri->x2, tri->y2 );
1542
1543 prep[4] = BEM_BE_V3;
1544 prep[5] = SH7722_XY( tri->x3, tri->y3 );
1545
1546 prep[6] = BEM_BE_V4;
1547 prep[7] = SH7722_XY( tri->x3, tri->y3 );
1548
1549 prep[8] = BEM_PE_OPERATION;
1550 prep[9] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
1551 sdev->ble_srcf |
1552 BLE_SRCA_FIXED |
1553 sdev->ble_dstf) : BLE_FUNC_NONE;
1554
1555 if (sdev->dflags & DSDRAW_XOR)
1556 prep[9] |= BLE_ROP_XOR;
1557
1558 prep[10] = BEM_BE_CTRL;
1559 prep[11] = BE_CTRL_QUADRANGLE | BE_CTRL_SCANMODE_LINE;
1560
1561 if (sdev->render_options & DSRO_MATRIX)
1562 prep[11] |= BE_CTRL_MATRIX | BE_CTRL_FIXMODE_16_16;// | BE_CTRL_ORIGIN;
1563
1564 submit_buffer( sdrv, 12 );
1565
1566 return true;
1567 }
1568
1569 /*
1570 * Render rectangle outlines using the current hardware state.
1571 */
1572 static bool
sh7722DrawRectangle(void * drv,void * dev,DFBRectangle * rect)1573 sh7722DrawRectangle( void *drv, void *dev, DFBRectangle *rect )
1574 {
1575 SH7722DriverData *sdrv = drv;
1576 SH7722DeviceData *sdev = dev;
1577 __u32 *prep = start_buffer( sdrv, 20 );
1578
1579 int x1 = rect->x;
1580 int y1 = rect->y;
1581 int x2 = rect->x + rect->w;
1582 int y2 = rect->y + rect->h;
1583
1584 D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__,
1585 DFB_RECTANGLE_VALS( rect ) );
1586 DUMP_INFO();
1587
1588 prep[0] = BEM_WR_V1;
1589 prep[1] = (y1 << 16) | x1;
1590
1591 prep[2] = BEM_WR_V2;
1592 prep[3] = (y1 << 16) | x2;
1593
1594 prep[4] = BEM_PE_OPERATION;
1595 prep[5] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
1596 sdev->ble_srcf |
1597 BLE_SRCA_FIXED |
1598 sdev->ble_dstf) : BLE_FUNC_NONE;
1599
1600 if (sdev->dflags & DSDRAW_XOR)
1601 prep[5] |= BLE_ROP_XOR;
1602
1603 prep[6] = BEM_WR_CTRL;
1604 prep[7] = WR_CTRL_LINE;
1605
1606 if (rect->h > 1 && rect->w > 1) {
1607 prep[8] = BEM_WR_V2;
1608 prep[9] = (y2 << 16) | x2;
1609 prep[10] = BEM_WR_CTRL;
1610 prep[11] = WR_CTRL_POLYLINE;
1611
1612 prep[12] = BEM_WR_V2;
1613 prep[13] = (y2 << 16) | x1;
1614 prep[14] = BEM_WR_CTRL;
1615 prep[15] = WR_CTRL_POLYLINE;
1616
1617 prep[16] = BEM_WR_V2;
1618 prep[17] = (y1 << 16) | x1;
1619 prep[18] = BEM_WR_CTRL;
1620 prep[19] = WR_CTRL_POLYLINE;
1621
1622 submit_buffer( sdrv, 20 );
1623 }
1624 else {
1625 prep[3] = (y2 << 16) | x2;
1626 prep[7] |= WR_CTRL_ENDPOINT;
1627
1628 submit_buffer( sdrv, 8 );
1629 }
1630
1631 return true;
1632 }
1633
1634 static bool
sh7722DrawRectangleMatrixAA(void * drv,void * dev,DFBRectangle * rect)1635 sh7722DrawRectangleMatrixAA( void *drv, void *dev, DFBRectangle *rect )
1636 {
1637 SH7722DriverData *sdrv = drv;
1638 SH7722DeviceData *sdev = dev;
1639
1640 int x1 = rect->x;
1641 int y1 = rect->y;
1642 int x2 = rect->x + rect->w;
1643 int y2 = rect->y;
1644 int x3 = rect->x + rect->w;
1645 int y3 = rect->y + rect->h;
1646 int x4 = rect->x;
1647 int y4 = rect->y + rect->h;
1648
1649 D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__,
1650 DFB_RECTANGLE_VALS( rect ) );
1651 DUMP_INFO();
1652
1653 if (sdev->render_options & DSRO_MATRIX) {
1654 int t;
1655
1656 t = ((x1 * sdev->matrix[0]) +
1657 (y1 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1658 y1 = ((x1 * sdev->matrix[3]) +
1659 (y1 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1660 x1 = t;
1661
1662 t = ((x2 * sdev->matrix[0]) +
1663 (y2 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1664 y2 = ((x2 * sdev->matrix[3]) +
1665 (y2 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1666 x2 = t;
1667
1668 t = ((x3 * sdev->matrix[0]) +
1669 (y3 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1670 y3 = ((x3 * sdev->matrix[3]) +
1671 (y3 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1672 x3 = t;
1673
1674 t = ((x4 * sdev->matrix[0]) +
1675 (y4 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1676 y4 = ((x4 * sdev->matrix[3]) +
1677 (y4 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1678 x4 = t;
1679 }
1680
1681 if (sdev->render_options & DSRO_ANTIALIAS)
1682 draw_rectangle( sdrv, sdev, x1, y1, x2, y2, x3, y3, x4, y4, true, rect->h > 1 && rect->w > 1 );
1683
1684 draw_rectangle( sdrv, sdev, x1, y1, x2, y2, x3, y3, x4, y4, false, rect->h > 1 && rect->w > 1 );
1685
1686 return true;
1687 }
1688
1689 /*
1690 * Render a line using the current hardware state.
1691 */
1692 static bool
sh7722DrawLine(void * drv,void * dev,DFBRegion * line)1693 sh7722DrawLine( void *drv, void *dev, DFBRegion *line )
1694 {
1695 SH7722DriverData *sdrv = drv;
1696 SH7722DeviceData *sdev = dev;
1697 __u32 *prep = start_buffer( sdrv, 8 );
1698
1699 D_DEBUG_AT( SH7722_BLT, "%s( %d, %d -> %d, %d )\n", __FUNCTION__,
1700 DFB_REGION_VALS( line ) );
1701 DUMP_INFO();
1702
1703 prep[0] = BEM_WR_V1;
1704 prep[1] = SH7722_XY( line->x1, line->y1 );
1705
1706 prep[2] = BEM_WR_V2;
1707 prep[3] = SH7722_XY( line->x2, line->y2 );
1708
1709 prep[4] = BEM_PE_OPERATION;
1710 prep[5] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
1711 sdev->ble_srcf |
1712 BLE_SRCA_FIXED |
1713 sdev->ble_dstf) : BLE_FUNC_NONE;
1714
1715 if (sdev->dflags & DSDRAW_XOR)
1716 prep[5] |= BLE_ROP_XOR;
1717
1718 prep[6] = BEM_WR_CTRL;
1719 prep[7] = WR_CTRL_LINE | WR_CTRL_ENDPOINT;
1720
1721 submit_buffer( sdrv, 8 );
1722
1723 return true;
1724 }
1725
1726 static bool
sh7722DrawLineMatrix(void * drv,void * dev,DFBRegion * line)1727 sh7722DrawLineMatrix( void *drv, void *dev, DFBRegion *line )
1728 {
1729 SH7722DriverData *sdrv = drv;
1730 SH7722DeviceData *sdev = dev;
1731 __u32 *prep = start_buffer( sdrv, 8 );
1732
1733 D_DEBUG_AT( SH7722_BLT, "%s( %d, %d -> %d, %d )\n", __FUNCTION__,
1734 DFB_REGION_VALS( line ) );
1735 DUMP_INFO();
1736
1737 int x1 = ((line->x1 * sdev->matrix[0]) +
1738 (line->y1 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1739 int y1 = ((line->x1 * sdev->matrix[3]) +
1740 (line->y1 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1741
1742 int x2 = ((line->x2 * sdev->matrix[0]) +
1743 (line->y2 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1744 int y2 = ((line->x2 * sdev->matrix[3]) +
1745 (line->y2 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1746
1747 prep[0] = BEM_WR_V1;
1748 prep[1] = SH7722_XY( x1, y1 );
1749
1750 prep[2] = BEM_WR_V2;
1751 prep[3] = SH7722_XY( x2, y2 );
1752
1753 prep[4] = BEM_PE_OPERATION;
1754 prep[5] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
1755 sdev->ble_srcf |
1756 BLE_SRCA_FIXED |
1757 sdev->ble_dstf) : BLE_FUNC_NONE;
1758
1759 if (sdev->dflags & DSDRAW_XOR)
1760 prep[5] |= BLE_ROP_XOR;
1761
1762 prep[6] = BEM_WR_CTRL;
1763 prep[7] = WR_CTRL_LINE | WR_CTRL_ENDPOINT;
1764
1765 submit_buffer( sdrv, 8 );
1766
1767 return true;
1768 }
1769
1770 static bool
sh7722DrawLineAA(void * drv,void * dev,DFBRegion * line)1771 sh7722DrawLineAA( void *drv, void *dev, DFBRegion *line )
1772 {
1773 SH7722DriverData *sdrv = drv;
1774 SH7722DeviceData *sdev = dev;
1775 __u32 *prep = start_buffer( sdrv, 24 );
1776 int x1, y1;
1777 int x2, y2;
1778
1779 D_DEBUG_AT( SH7722_BLT, "%s( %d, %d -> %d, %d )\n", __FUNCTION__,
1780 DFB_REGION_VALS( line ) );
1781 DUMP_INFO();
1782
1783 if (sdev->render_options & DSRO_MATRIX) {
1784 x1 = ((line->x1 * sdev->matrix[0]) +
1785 (line->y1 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1786 y1 = ((line->x1 * sdev->matrix[3]) +
1787 (line->y1 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1788
1789 x2 = ((line->x2 * sdev->matrix[0]) +
1790 (line->y2 * sdev->matrix[1]) + sdev->matrix[2]) >> 16;
1791 y2 = ((line->x2 * sdev->matrix[3]) +
1792 (line->y2 * sdev->matrix[4]) + sdev->matrix[5]) >> 16;
1793 }
1794 else {
1795 x1 = line->x1;
1796 y1 = line->y1;
1797 x2 = line->x2;
1798 y2 = line->y2;
1799 }
1800
1801 prep[0] = BEM_WR_FGC;
1802 prep[1] = PIXEL_ARGB( (sdev->color.a * AA_COEF) >> 8,
1803 (sdev->color.r * AA_COEF) >> 8,
1804 (sdev->color.g * AA_COEF) >> 8,
1805 (sdev->color.b * AA_COEF) >> 8 );
1806
1807 prep[2] = BEM_PE_FIXEDALPHA;
1808 prep[3] = (sdev->color.a * AA_COEF) << 16;
1809
1810 prep[4] = BEM_WR_V1;
1811 prep[5] = SH7722_XY( x1, y1 );
1812
1813 prep[6] = BEM_WR_V2;
1814 prep[7] = SH7722_XY( x2, y2 );
1815
1816 prep[8] = BEM_PE_OPERATION;
1817 prep[9] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
1818 sdev->ble_srcf |
1819 BLE_SRCA_FIXED |
1820 sdev->ble_dstf)
1821 :
1822 (BLE_FUNC_AxB_plus_CxD |
1823 BLE_SRCF_ONE |
1824 BLE_SRCA_FIXED |
1825 BLE_DSTF_1_SRC_A);
1826
1827 if (sdev->dflags & DSDRAW_XOR)
1828 prep[9] |= BLE_ROP_XOR;
1829
1830 prep[10] = BEM_WR_CTRL;
1831 prep[11] = WR_CTRL_LINE | WR_CTRL_ENDPOINT | WR_CTRL_ANTIALIAS;
1832
1833
1834
1835 prep[12] = BEM_WR_FGC;
1836 prep[13] = PIXEL_ARGB( sdev->color.a,
1837 sdev->color.r,
1838 sdev->color.g,
1839 sdev->color.b );
1840
1841 prep[14] = BEM_PE_FIXEDALPHA;
1842 prep[15] = (sdev->color.a << 24) | (sdev->color.a << 16);
1843
1844 prep[16] = BEM_WR_V1;
1845 prep[17] = SH7722_XY( x1, y1 );
1846
1847 prep[18] = BEM_WR_V2;
1848 prep[19] = SH7722_XY( x2, y2 );
1849
1850 prep[20] = BEM_PE_OPERATION;
1851 prep[21] = (sdev->dflags & DSDRAW_BLEND) ? (BLE_FUNC_AxB_plus_CxD |
1852 sdev->ble_srcf |
1853 BLE_SRCA_FIXED |
1854 sdev->ble_dstf) : BLE_FUNC_NONE;
1855
1856 if (sdev->dflags & DSDRAW_XOR)
1857 prep[21] |= BLE_ROP_XOR;
1858
1859 prep[22] = BEM_WR_CTRL;
1860 prep[23] = WR_CTRL_LINE | WR_CTRL_ENDPOINT;
1861
1862
1863 submit_buffer( sdrv, 24 );
1864
1865 return true;
1866 }
1867
1868 /*
1869 * Common implementation for Blit() and StretchBlit().
1870 */
1871 static inline bool
sh7722DoBlit(SH7722DriverData * sdrv,SH7722DeviceData * sdev,DFBRectangle * rect,int x,int y,int w,int h)1872 sh7722DoBlit( SH7722DriverData *sdrv, SH7722DeviceData *sdev,
1873 DFBRectangle *rect, int x, int y, int w, int h )
1874 {
1875 int num = 8;
1876 __u32 *prep = start_buffer( sdrv, 12 );
1877
1878 D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d -> %d, %d - %dx%d )\n", __FUNCTION__,
1879 DFB_RECTANGLE_VALS( rect ), x, y, w, h );
1880 DUMP_INFO();
1881
1882 prep[0] = BEM_BE_SRC_LOC;
1883
1884 /* Stencil mode needs a workaround, because the hardware always adds the source location. */
1885 if (sdev->bflags & DSBLIT_SRC_MASK_ALPHA && sdev->mask_flags & DSMF_STENCIL)
1886 prep[1] = SH7722_XY( 0, 0 );
1887 else
1888 prep[1] = SH7722_XY( rect->x, rect->y );
1889
1890 prep[2] = BEM_BE_SRC_SIZE;
1891 prep[3] = SH7722_XY( rect->w, rect->h );
1892
1893 prep[4] = BEM_BE_V1;
1894 prep[5] = SH7722_XY( x, y );
1895
1896 prep[6] = BEM_BE_V2;
1897 prep[7] = SH7722_XY( w, h );
1898
1899 /* Stencil mode needs a workaround, because the hardware always adds the source location. */
1900 if (sdev->bflags & DSBLIT_SRC_MASK_ALPHA && sdev->mask_flags & DSMF_STENCIL) {
1901 prep[num++] = BEM_TE_SRC_BASE;
1902 prep[num++] = sdev->src_phys + sdev->src_pitch * rect->y + sdev->src_bpp * rect->x;
1903
1904 SH7722_INVALIDATE( SOURCE );
1905 }
1906
1907 prep[num++] = BEM_BE_CTRL;
1908 prep[num++] = BE_CTRL_RECTANGLE | BE_CTRL_TEXTURE | BE_CTRL_SCANMODE_LINE;
1909
1910 if (sdev->bflags & DSBLIT_ROTATE180)
1911 prep[num-1] |= BE_FLIP_BOTH;
1912 else if (rect->w == w && rect->h == h) /* No blit direction handling for StretchBlit(). */
1913 prep[num-1] |= BE_CTRL_BLTDIR_AUTOMATIC;
1914
1915 submit_buffer( sdrv, num );
1916
1917 return true;
1918 }
1919
1920 /*
1921 * This version sends a quadrangle to have all four edges transformed.
1922 */
1923 __attribute__((noinline))
1924 static bool
sh7722DoBlitM(SH7722DriverData * sdrv,SH7722DeviceData * sdev,DFBRectangle * rect,int x1,int y1,int x2,int y2)1925 sh7722DoBlitM( SH7722DriverData *sdrv, SH7722DeviceData *sdev,
1926 DFBRectangle *rect, int x1, int y1, int x2, int y2 )
1927 {
1928 int num = 12;
1929 __u32 *prep = start_buffer( sdrv, 16 );
1930
1931 D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d -> %d, %d - %d, %d )\n", __FUNCTION__,
1932 DFB_RECTANGLE_VALS( rect ), x1, y1, x2, y2 );
1933 DUMP_INFO();
1934
1935 prep[0] = BEM_BE_SRC_LOC;
1936
1937 /* Stencil mode needs a workaround, because the hardware always adds the source location. */
1938 if (sdev->bflags & DSBLIT_SRC_MASK_ALPHA && sdev->mask_flags & DSMF_STENCIL)
1939 prep[1] = SH7722_XY( 0, 0 );
1940 else
1941 prep[1] = SH7722_XY( rect->x, rect->y );
1942
1943 prep[2] = BEM_BE_SRC_SIZE;
1944 prep[3] = SH7722_XY( rect->w, rect->h );
1945
1946 prep[4] = BEM_BE_V1;
1947 prep[5] = SH7722_XY( x1, y1 );
1948
1949 prep[6] = BEM_BE_V2;
1950 prep[7] = SH7722_XY( x1, y2 );
1951
1952 prep[8] = BEM_BE_V3;
1953 prep[9] = SH7722_XY( x2, y1 );
1954
1955 prep[10] = BEM_BE_V4;
1956 prep[11] = SH7722_XY( x2, y2 );
1957
1958 /* Stencil mode needs a workaround, because the hardware always adds the source location. */
1959 if (sdev->bflags & DSBLIT_SRC_MASK_ALPHA && sdev->mask_flags & DSMF_STENCIL) {
1960 prep[num++] = BEM_TE_SRC_BASE;
1961 prep[num++] = sdev->src_phys + sdev->src_pitch * rect->y + sdev->src_bpp * rect->x;
1962
1963 SH7722_INVALIDATE( SOURCE );
1964 }
1965
1966 prep[num++] = BEM_BE_CTRL;
1967 prep[num++] = BE_CTRL_QUADRANGLE | BE_CTRL_TEXTURE | BE_CTRL_SCANMODE_4x4 |
1968 BE_CTRL_MATRIX | BE_CTRL_FIXMODE_16_16;// | BE_CTRL_ORIGIN;
1969
1970 if (sdev->bflags & DSBLIT_ROTATE180)
1971 prep[num-1] |= BE_FLIP_BOTH;
1972
1973 submit_buffer( sdrv, num );
1974
1975 return true;
1976 }
1977
1978 /*
1979 * Blit a rectangle using the current hardware state.
1980 */
1981 bool
sh7722Blit(void * drv,void * dev,DFBRectangle * rect,int x,int y)1982 sh7722Blit( void *drv, void *dev, DFBRectangle *rect, int x, int y )
1983 {
1984 SH7722DriverData *sdrv = drv;
1985 SH7722DeviceData *sdev = dev;
1986
1987 D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d -> %d, %d )\n",
1988 __FUNCTION__, DFB_RECTANGLE_VALS( rect ), x, y );
1989
1990 if (sdev->render_options & DSRO_MATRIX)
1991 return sh7722DoBlitM( sdrv, sdev, rect, DFB_REGION_VALS_FROM_RECTANGLE_VALS( x, y, rect->w, rect->h ) );
1992
1993 return sh7722DoBlit( sdrv, sdev, rect, x, y, rect->w, rect->h );
1994 }
1995
1996 /*
1997 * StretchBlit a rectangle using the current hardware state.
1998 */
1999 bool
sh7722StretchBlit(void * drv,void * dev,DFBRectangle * srect,DFBRectangle * drect)2000 sh7722StretchBlit( void *drv, void *dev, DFBRectangle *srect, DFBRectangle *drect )
2001 {
2002 SH7722DriverData *sdrv = drv;
2003 SH7722DeviceData *sdev = dev;
2004
2005 D_DEBUG_AT( SH7722_BLT, "%s( %d, %d - %dx%d -> %d, %d - %dx%d )\n",
2006 __FUNCTION__, DFB_RECTANGLE_VALS( srect ), DFB_RECTANGLE_VALS( drect ) );
2007
2008 if (sdev->render_options & DSRO_MATRIX)
2009 return sh7722DoBlitM( sdrv, sdev, srect, DFB_REGION_VALS_FROM_RECTANGLE( drect ) );
2010
2011 return sh7722DoBlit( sdrv, sdev, srect, drect->x, drect->y, drect->w, drect->h );
2012 }
2013
2014