BTRFS: Implement BTree::Path and change _Find.
[haiku.git] / src / add-ons / accelerants / radeon / Acceleration.c
blob8c118a19998490cf2f5f4b3b8402a0945ea4a7e2
1 /*
2 Copyright (c) 2002, Thomas Kurschel
5 Part of Radeon accelerant
7 Public functions to provide 2D hardware acceleration
8 */
11 #include "radeon_accelerant.h"
12 #include "GlobalData.h"
13 #include "generic.h"
14 #include "3d_regs.h"
15 #include "2d_regs.h"
16 #include "radeon_regs.h"
17 #include "mmio.h"
18 #include "CP.h"
21 // copy screen to screen
22 // et - ignored
23 // list - list of rectangles
24 // count - number of rectangles
25 void SCREEN_TO_SCREEN_BLIT_DMA(engine_token *et, blit_params *list, uint32 count)
27 virtual_card *vc = ai->vc;
29 SHOW_FLOW0( 4, "" );
31 (void)et;
33 while( count > 0 ) {
34 uint32 sub_count;
36 START_IB();
38 WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_BITBLT_MULTI, count,
39 INDIRECT_BUFFER_SIZE, 3, 2 );
41 *buffer++ = RADEON_GMC_BRUSH_NONE
42 | (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
43 | RADEON_GMC_SRC_DATATYPE_COLOR
44 | RADEON_ROP3_S
45 | RADEON_DP_SRC_SOURCE_MEMORY;
47 for( ; sub_count > 0; --sub_count, ++list ) {
48 *buffer++ = (list->src_left << 16) | list->src_top;
49 *buffer++ = (list->dest_left << 16) | list->dest_top;
50 *buffer++ = ((list->width + 1) << 16) | (list->height + 1);
53 SUBMIT_IB_VC();
56 ++ai->si->engine.count;
59 #define SRC_DSTCOLOR 0x00030000
60 #define DP_SRC_RECT 0x00000200
62 void SCREEN_TO_SCREEN_BLIT_PIO(engine_token *et, blit_params *list, uint32 count)
64 int xdir;
65 int ydir;
66 virtual_card *vc = ai->vc;
68 SHOW_FLOW0( 4, "" );
70 Radeon_WaitForFifo ( ai , 1 );
72 // Setup for Screen to screen blit
73 OUTREG(ai->regs, RADEON_DP_GUI_MASTER_CNTL, (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT
74 | RADEON_GMC_BRUSH_NONE
75 | RADEON_GMC_SRC_DATATYPE_COLOR
76 | RADEON_ROP3_S
77 | RADEON_DP_SRC_SOURCE_MEMORY
78 | RADEON_GMC_SRC_PITCH_OFFSET_CNTL));
81 for( ; count > 0; --count, ++list ) {
83 // make sure there is space in the FIFO for 4 register writes
84 Radeon_WaitForFifo ( ai , 4 );
86 xdir = ((list->src_left < list->dest_left) && (list->src_top == list->dest_top)) ? -1 : 1;
87 ydir = (list->src_top < list->dest_top) ? -1 : 1;
89 if (xdir < 0) list->src_left += list->width , list->dest_left += list->width ;
90 if (ydir < 0) list->src_top += list->height , list->dest_top += list->height ;
92 OUTREG(ai->regs, RADEON_DP_CNTL, ((xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0)
93 | (ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0)));
95 // Tell the engine where the source data resides.
96 OUTREG( ai->regs, RADEON_SRC_Y_X, (list->src_top << 16 ) | list->src_left);
97 OUTREG( ai->regs, RADEON_DST_Y_X, (list->dest_top << 16 ) | list->dest_left);
99 // this is the blt initiator.
100 OUTREG( ai->regs, RADEON_DST_HEIGHT_WIDTH, ((list->height + 1) << 16 ) | (list->width + 1));
104 ++ai->si->engine.count;
105 et = et;
110 // fill rectangles on screen
111 // et - ignored
112 // colorIndex - fill colour
113 // list - list of rectangles
114 // count - number of rectangles
115 void FILL_RECTANGLE_DMA(engine_token *et, uint32 colorIndex,
116 fill_rect_params *list, uint32 count)
118 virtual_card *vc = ai->vc;
120 SHOW_FLOW0( 4, "" );
122 (void)et;
124 while( count > 0 ) {
125 uint32 sub_count;
127 START_IB();
129 WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_PAINT_MULTI, count,
130 INDIRECT_BUFFER_SIZE, 2, 3 );
132 *buffer++ = RADEON_GMC_BRUSH_SOLID_COLOR
133 | (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
134 | RADEON_GMC_SRC_DATATYPE_COLOR
135 | RADEON_ROP3_P;
136 *buffer++ = colorIndex;
138 for( ; sub_count > 0; --sub_count, ++list ) {
139 *buffer++ = (list->left << 16) | list->top;
140 *buffer++ =
141 ((list->right - list->left + 1) << 16) |
142 (list->bottom - list->top + 1);
145 SUBMIT_IB_VC();
148 ++ai->si->engine.count;
152 // fill rectangles on screen
153 // et - ignored
154 // colorIndex - fill colour
155 // list - list of rectangles
156 // count - number of rectangles
157 #define BRUSH_SOLIDCOLOR 0x00000d00
159 void FILL_RECTANGLE_PIO(engine_token *et, uint32 colorIndex, fill_rect_params *list, uint32 count)
161 virtual_card *vc = ai->vc;
163 SHOW_FLOW( 4, "colorIndex", colorIndex);
165 Radeon_WaitForFifo(ai, 3);
166 OUTREG(ai->regs, RADEON_DP_GUI_MASTER_CNTL, ((vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
167 | RADEON_GMC_BRUSH_SOLID_COLOR
168 | RADEON_GMC_SRC_DATATYPE_COLOR
169 | RADEON_ROP3_P));
170 // Set brush colour
171 OUTREG(ai->regs, RADEON_DP_BRUSH_FRGD_CLR, colorIndex);
172 OUTREG(ai->regs, RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM));
174 for( ; count > 0; --count, ++list )
177 Radeon_WaitForFifo(ai, 2);
178 OUTREG(ai->regs, RADEON_DST_Y_X, (list->top << 16) | list->left);
179 OUTREG(ai->regs, RADEON_DST_WIDTH_HEIGHT, ((list->right - list->left + 1) << 16) | (list->bottom - list->top + 1));
182 ++ai->si->engine.count;
183 et = et;
188 // invert rectangle on screen
189 // et - ignored
190 // list - list of rectangles
191 // count - number of rectangles
192 void INVERT_RECTANGLE_DMA(engine_token *et, fill_rect_params *list, uint32 count)
194 virtual_card *vc = ai->vc;
196 SHOW_FLOW0( 4, "" );
198 (void)et;
200 while( count > 0 ) {
201 uint32 sub_count;
203 START_IB();
205 // take core to leave space for ROP reset!
206 WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_PAINT_MULTI, count,
207 INDIRECT_BUFFER_SIZE - 2, 2, 2 );
209 *buffer++ = RADEON_GMC_BRUSH_NONE
210 | (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
211 | RADEON_GMC_SRC_DATATYPE_COLOR
212 | RADEON_ROP3_Dn;
214 for( ; sub_count > 0; --sub_count, ++list ) {
215 *buffer++ = (list->left << 16) | list->top;
216 *buffer++ =
217 ((list->right - list->left + 1) << 16) |
218 (list->bottom - list->top + 1);
221 // we have to reset ROP, else we get garbage during next
222 // CPU access; it looks like some cache coherency/forwarding
223 // problem as it goes away later on; things like flushing the
224 // destination cache or waiting for 2D engine or HDP to become
225 // idle and clean didn't change a thing
226 // (I dont't really understand what exactly happens,
227 // but this code fixes it)
228 *buffer++ = CP_PACKET0( RADEON_DP_GUI_MASTER_CNTL, 1 );
229 *buffer++ = RADEON_GMC_BRUSH_NONE
230 | (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
231 | RADEON_GMC_SRC_DATATYPE_COLOR
232 | RADEON_ROP3_S
233 | RADEON_DP_SRC_SOURCE_MEMORY;
235 SUBMIT_IB_VC();
238 ++ai->si->engine.count;
242 void INVERT_RECTANGLE_PIO(engine_token *et, fill_rect_params *list, uint32 count)
244 virtual_card *vc = ai->vc;
246 SHOW_FLOW0( 4, "" );
248 Radeon_WaitForFifo(ai, 3);
249 OUTREG(ai->regs, RADEON_DP_GUI_MASTER_CNTL, ((vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
250 | RADEON_GMC_BRUSH_NONE
251 | RADEON_GMC_SRC_DATATYPE_COLOR
252 | RADEON_ROP3_Dn
253 | RADEON_DP_SRC_SOURCE_MEMORY));
255 OUTREG(ai->regs, RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM));
257 for( ; count > 0; --count, ++list )
260 Radeon_WaitForFifo(ai, 2);
261 OUTREG(ai->regs, RADEON_DST_Y_X, (list->top << 16) | list->left);
262 OUTREG(ai->regs, RADEON_DST_WIDTH_HEIGHT, ((list->right - list->left + 1) << 16) | (list->bottom - list->top + 1));
265 ++ai->si->engine.count;
266 et = et;
270 // fill horizontal spans on screen
271 // et - ignored
272 // colorIndex - fill colour
273 // list - list of spans
274 // count - number of spans
275 void FILL_SPAN_DMA(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count)
277 virtual_card *vc = ai->vc;
279 SHOW_FLOW0( 4, "" );
281 (void)et;
283 while( count > 0 ) {
284 uint32 sub_count;
286 START_IB();
288 WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_PAINT_MULTI, count,
289 INDIRECT_BUFFER_SIZE , 2, 3 );
291 *buffer++ = RADEON_GMC_BRUSH_SOLID_COLOR
292 | (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
293 | RADEON_GMC_SRC_DATATYPE_COLOR
294 | RADEON_ROP3_P;
295 *buffer++ = colorIndex;
297 for( ; sub_count > 0; --sub_count ) {
298 uint16 y, x, width;
300 y = *list++;
301 x = *list++;
302 width = *list++ - x + 1;
304 *buffer++ = (x << 16) | y;
305 *buffer++ = (width << 16) | 1;
308 SUBMIT_IB_VC();
311 ++ai->si->engine.count;
315 // fill horizontal spans on screen
316 // et - ignored
317 // colorIndex - fill colour
318 // list - list of spans
319 // count - number of spans
320 void FILL_SPAN_PIO(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count)
323 virtual_card *vc = ai->vc;
324 //int offset = 0;
325 uint16 y, x, width;
327 SHOW_FLOW0( 4, "" );
329 Radeon_WaitForFifo( ai , 1);
330 OUTREG( ai->regs, RADEON_DP_GUI_MASTER_CNTL, 0
331 | RADEON_GMC_BRUSH_SOLID_COLOR
332 | (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
333 | RADEON_GMC_SRC_DATATYPE_COLOR
334 | RADEON_ROP3_P);
336 if ( ai->si->asic >= rt_rv200 ) {
337 Radeon_WaitForFifo( ai , 1);
338 OUTREG( ai->regs, RADEON_DST_LINE_PATCOUNT, 0x55 << RADEON_BRES_CNTL_SHIFT);
341 Radeon_WaitForFifo( ai , 1);
342 OUTREG( ai->regs, RADEON_DP_BRUSH_FRGD_CLR, colorIndex);
344 for( ; count > 0; --count ) {
346 Radeon_WaitForFifo( ai , 2);
348 y = *list++;
349 x = *list++;
350 width = *list++ - x + 1;
352 OUTREG( ai->regs, RADEON_DST_LINE_START, (y << 16) | x);
353 OUTREG( ai->regs, RADEON_DST_LINE_END, ((y) << 16) | (x + width));
357 ++ai->si->engine.count;
358 et = et;
362 void SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count)
364 if ( ai->si->acc_dma )
365 SCREEN_TO_SCREEN_BLIT_DMA(et,list,count);
366 else
367 SCREEN_TO_SCREEN_BLIT_PIO(et,list,count);
370 void FILL_RECTANGLE(engine_token *et, uint32 color, fill_rect_params *list, uint32 count)
372 if ( ai->si->acc_dma )
373 FILL_RECTANGLE_DMA(et, color, list, count);
374 else
375 FILL_RECTANGLE_PIO(et, color, list, count);
378 void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count)
380 if ( ai->si->acc_dma )
381 INVERT_RECTANGLE_DMA(et, list, count);
382 else
383 INVERT_RECTANGLE_PIO(et, list, count);
386 void FILL_SPAN(engine_token *et, uint32 color, uint16 *list, uint32 count)
388 if ( ai->si->acc_dma )
389 FILL_SPAN_DMA(et, color, list, count);
390 else
391 FILL_SPAN_PIO(et, color, list, count);
396 // prepare 2D acceleration
397 void Radeon_Init2D( accelerator_info *ai )
399 SHOW_FLOW0( 3, "" );
401 // forget about 3D
402 if ( ai->si->acc_dma ) {
403 START_IB();
404 WRITE_IB_REG( RADEON_RB3D_CNTL, 0 );
405 SUBMIT_IB();
407 else {
408 OUTREG( ai->regs, RADEON_RB3D_CNTL, 0 );
412 // fill state buffer that sets 2D registers up for accelerated operations
413 void Radeon_FillStateBuffer( accelerator_info *ai, uint32 datatype )
415 virtual_card *vc = ai->vc;
416 uint32 pitch_offset;
417 uint32 *buffer = NULL, *buffer_start = NULL;
419 SHOW_FLOW0( 4, "" );
421 // set offset of frame buffer and pitch
422 pitch_offset =
423 ((ai->si->memory[mt_local].virtual_addr_start + vc->fb_offset) >> 10) |
424 ((vc->pitch >> 6) << 22);
426 if ( ai->si->acc_dma ) {
427 // make sure buffer is not used
428 Radeon_InvalidateStateBuffer( ai, vc->state_buffer_idx );
429 buffer = buffer_start = Radeon_GetIndirectBufferPtr( ai, vc->state_buffer_idx );
431 WRITE_IB_REG( RADEON_DEFAULT_OFFSET, pitch_offset );
432 WRITE_IB_REG( RADEON_DST_PITCH_OFFSET, pitch_offset );
433 WRITE_IB_REG( RADEON_SRC_PITCH_OFFSET, pitch_offset );
434 // no sissors
435 WRITE_IB_REG( RADEON_DEFAULT_SC_BOTTOM_RIGHT,
436 (RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX));
438 // general fluff
439 WRITE_IB_REG( RADEON_DP_GUI_MASTER_CNTL,
440 (datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
441 | RADEON_GMC_CLR_CMP_CNTL_DIS
443 | RADEON_GMC_BRUSH_SOLID_COLOR
444 | RADEON_GMC_SRC_DATATYPE_COLOR
446 | RADEON_ROP3_P
447 | RADEON_DP_SRC_SOURCE_MEMORY
448 | RADEON_GMC_WR_MSK_DIS );
450 // most of this init is probably not necessary
451 // as we neither draw lines nor use brushes
452 WRITE_IB_REG( RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
453 WRITE_IB_REG( RADEON_DP_BRUSH_BKGD_CLR, 0x00000000);
454 WRITE_IB_REG( RADEON_DP_SRC_FRGD_CLR, 0xffffffff);
455 WRITE_IB_REG( RADEON_DP_SRC_BKGD_CLR, 0x00000000);
456 WRITE_IB_REG( RADEON_DP_WRITE_MASK, 0xffffffff);
458 // this is required
459 vc->state_buffer_size = buffer - buffer_start;
461 } else {
462 Radeon_WaitForFifo( ai, 10 );
463 OUTREG( ai->regs, RADEON_DEFAULT_OFFSET, pitch_offset );
464 OUTREG( ai->regs, RADEON_DST_PITCH_OFFSET, pitch_offset );
465 OUTREG( ai->regs, RADEON_SRC_PITCH_OFFSET, pitch_offset );
466 // no sissors
467 OUTREG( ai->regs, RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX
468 | RADEON_DEFAULT_SC_BOTTOM_MAX));
469 // general fluff
470 OUTREG( ai->regs, RADEON_DP_GUI_MASTER_CNTL,
471 (datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
472 | RADEON_GMC_CLR_CMP_CNTL_DIS
474 | RADEON_GMC_BRUSH_SOLID_COLOR
475 | RADEON_GMC_SRC_DATATYPE_COLOR
477 | RADEON_ROP3_P
478 | RADEON_DP_SRC_SOURCE_MEMORY
479 | RADEON_GMC_WR_MSK_DIS );
481 // most of this init is probably not necessary
482 // as we neither draw lines nor use brushes
483 OUTREG( ai->regs, RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
484 OUTREG( ai->regs, RADEON_DP_BRUSH_BKGD_CLR, 0x00000000);
485 OUTREG( ai->regs, RADEON_DP_SRC_FRGD_CLR, 0xffffffff);
486 OUTREG( ai->regs, RADEON_DP_SRC_BKGD_CLR, 0x00000000);
487 OUTREG( ai->regs, RADEON_DP_WRITE_MASK, 0xffffffff);
491 ai->si->active_vc = vc->id;
495 // allocate indirect buffer to contain state of virtual card
496 void Radeon_AllocateVirtualCardStateBuffer( accelerator_info *ai )
498 virtual_card *vc = ai->vc;
500 vc->state_buffer_idx = Radeon_AllocIndirectBuffer( ai, false );
501 // mark as being unused
502 vc->state_buffer_size = -1;
506 // free indirect buffer containing state of virtual card
507 void Radeon_FreeVirtualCardStateBuffer( accelerator_info *ai )
509 virtual_card *vc = ai->vc;
511 // make sure it's not used anymore
512 Radeon_InvalidateStateBuffer( ai, vc->state_buffer_idx );
514 // get rid of it
515 Radeon_FreeIndirectBuffer( ai, vc->state_buffer_idx, false );