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