#include "radeon_accelerant.h"
#include "GlobalData.h"
#include "generic.h"
#include "3d_regs.h"
#include "2d_regs.h"
#include "radeon_regs.h"
#include "mmio.h"
#include "CP.h"
void SCREEN_TO_SCREEN_BLIT_DMA(engine_token *et, blit_params *list, uint32 count)
{
virtual_card *vc = ai->vc;
SHOW_FLOW0( 4, "" );
(void)et;
while( count > 0 ) {
uint32 sub_count;
START_IB();
WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_BITBLT_MULTI, count,
INDIRECT_BUFFER_SIZE, 3, 2 );
*buffer++ = RADEON_GMC_BRUSH_NONE
| (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_S
| RADEON_DP_SRC_SOURCE_MEMORY;
for( ; sub_count > 0; --sub_count, ++list ) {
*buffer++ = (list->src_left << 16) | list->src_top;
*buffer++ = (list->dest_left << 16) | list->dest_top;
*buffer++ = ((list->width + 1) << 16) | (list->height + 1);
}
SUBMIT_IB_VC();
}
++ai->si->engine.count;
}
#define SRC_DSTCOLOR 0x00030000
#define DP_SRC_RECT 0x00000200
void SCREEN_TO_SCREEN_BLIT_PIO(engine_token *et, blit_params *list, uint32 count)
{
int xdir;
int ydir;
virtual_card *vc = ai->vc;
SHOW_FLOW0( 4, "" );
Radeon_WaitForFifo ( ai , 1 );
OUTREG(ai->regs, RADEON_DP_GUI_MASTER_CNTL, (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT
| RADEON_GMC_BRUSH_NONE
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_S
| RADEON_DP_SRC_SOURCE_MEMORY
| RADEON_GMC_SRC_PITCH_OFFSET_CNTL));
for( ; count > 0; --count, ++list ) {
Radeon_WaitForFifo ( ai , 4 );
xdir = ((list->src_left < list->dest_left) && (list->src_top == list->dest_top)) ? -1 : 1;
ydir = (list->src_top < list->dest_top) ? -1 : 1;
if (xdir < 0) list->src_left += list->width , list->dest_left += list->width ;
if (ydir < 0) list->src_top += list->height , list->dest_top += list->height ;
OUTREG(ai->regs, RADEON_DP_CNTL, ((xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0)
| (ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0)));
OUTREG( ai->regs, RADEON_SRC_Y_X, (list->src_top << 16 ) | list->src_left);
OUTREG( ai->regs, RADEON_DST_Y_X, (list->dest_top << 16 ) | list->dest_left);
OUTREG( ai->regs, RADEON_DST_HEIGHT_WIDTH, ((list->height + 1) << 16 ) | (list->width + 1));
}
++ai->si->engine.count;
(void)et;
}
void FILL_RECTANGLE_DMA(engine_token *et, uint32 colorIndex,
fill_rect_params *list, uint32 count)
{
virtual_card *vc = ai->vc;
SHOW_FLOW0( 4, "" );
(void)et;
while( count > 0 ) {
uint32 sub_count;
START_IB();
WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_PAINT_MULTI, count,
INDIRECT_BUFFER_SIZE, 2, 3 );
*buffer++ = RADEON_GMC_BRUSH_SOLID_COLOR
| (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P;
*buffer++ = colorIndex;
for( ; sub_count > 0; --sub_count, ++list ) {
*buffer++ = (list->left << 16) | list->top;
*buffer++ =
((list->right - list->left + 1) << 16) |
(list->bottom - list->top + 1);
}
SUBMIT_IB_VC();
}
++ai->si->engine.count;
}
#define BRUSH_SOLIDCOLOR 0x00000d00
void FILL_RECTANGLE_PIO(engine_token *et, uint32 colorIndex, fill_rect_params *list, uint32 count)
{
virtual_card *vc = ai->vc;
SHOW_FLOW( 4, "colorIndex", colorIndex);
Radeon_WaitForFifo(ai, 3);
OUTREG(ai->regs, RADEON_DP_GUI_MASTER_CNTL, ((vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_BRUSH_SOLID_COLOR
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P));
OUTREG(ai->regs, RADEON_DP_BRUSH_FRGD_CLR, colorIndex);
OUTREG(ai->regs, RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM));
for( ; count > 0; --count, ++list )
{
Radeon_WaitForFifo(ai, 2);
OUTREG(ai->regs, RADEON_DST_Y_X, (list->top << 16) | list->left);
OUTREG(ai->regs, RADEON_DST_WIDTH_HEIGHT, ((list->right - list->left + 1) << 16) | (list->bottom - list->top + 1));
}
++ai->si->engine.count;
(void)et;
}
void INVERT_RECTANGLE_DMA(engine_token *et, fill_rect_params *list, uint32 count)
{
virtual_card *vc = ai->vc;
SHOW_FLOW0( 4, "" );
(void)et;
while( count > 0 ) {
uint32 sub_count;
START_IB();
WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_PAINT_MULTI, count,
INDIRECT_BUFFER_SIZE - 2, 2, 2 );
*buffer++ = RADEON_GMC_BRUSH_NONE
| (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_Dn;
for( ; sub_count > 0; --sub_count, ++list ) {
*buffer++ = (list->left << 16) | list->top;
*buffer++ =
((list->right - list->left + 1) << 16) |
(list->bottom - list->top + 1);
}
*buffer++ = CP_PACKET0( RADEON_DP_GUI_MASTER_CNTL, 1 );
*buffer++ = RADEON_GMC_BRUSH_NONE
| (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_S
| RADEON_DP_SRC_SOURCE_MEMORY;
SUBMIT_IB_VC();
}
++ai->si->engine.count;
}
void INVERT_RECTANGLE_PIO(engine_token *et, fill_rect_params *list, uint32 count)
{
virtual_card *vc = ai->vc;
SHOW_FLOW0( 4, "" );
Radeon_WaitForFifo(ai, 3);
OUTREG(ai->regs, RADEON_DP_GUI_MASTER_CNTL, ((vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_BRUSH_NONE
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_Dn
| RADEON_DP_SRC_SOURCE_MEMORY));
OUTREG(ai->regs, RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT | RADEON_DST_Y_TOP_TO_BOTTOM));
for( ; count > 0; --count, ++list )
{
Radeon_WaitForFifo(ai, 2);
OUTREG(ai->regs, RADEON_DST_Y_X, (list->top << 16) | list->left);
OUTREG(ai->regs, RADEON_DST_WIDTH_HEIGHT, ((list->right - list->left + 1) << 16) | (list->bottom - list->top + 1));
}
++ai->si->engine.count;
(void)et;
}
void FILL_SPAN_DMA(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count)
{
virtual_card *vc = ai->vc;
SHOW_FLOW0( 4, "" );
(void)et;
while( count > 0 ) {
uint32 sub_count;
START_IB();
WRITE_IB_PACKET3_HEAD( RADEON_CP_PACKET3_CNTL_PAINT_MULTI, count,
INDIRECT_BUFFER_SIZE , 2, 3 );
*buffer++ = RADEON_GMC_BRUSH_SOLID_COLOR
| (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P;
*buffer++ = colorIndex;
for( ; sub_count > 0; --sub_count ) {
uint16 y, x, width;
y = *list++;
x = *list++;
width = *list++ - x + 1;
*buffer++ = (x << 16) | y;
*buffer++ = (width << 16) | 1;
}
SUBMIT_IB_VC();
}
++ai->si->engine.count;
}
void FILL_SPAN_PIO(engine_token *et, uint32 colorIndex, uint16 *list, uint32 count)
{
virtual_card *vc = ai->vc;
uint16 y, x, width;
SHOW_FLOW0( 4, "" );
Radeon_WaitForFifo( ai , 1);
OUTREG( ai->regs, RADEON_DP_GUI_MASTER_CNTL, 0
| RADEON_GMC_BRUSH_SOLID_COLOR
| (vc->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P);
if ( ai->si->asic >= rt_rv200 ) {
Radeon_WaitForFifo( ai , 1);
OUTREG( ai->regs, RADEON_DST_LINE_PATCOUNT, 0x55 << RADEON_BRES_CNTL_SHIFT);
}
Radeon_WaitForFifo( ai , 1);
OUTREG( ai->regs, RADEON_DP_BRUSH_FRGD_CLR, colorIndex);
for( ; count > 0; --count ) {
Radeon_WaitForFifo( ai , 2);
y = *list++;
x = *list++;
width = *list++ - x + 1;
OUTREG( ai->regs, RADEON_DST_LINE_START, (y << 16) | x);
OUTREG( ai->regs, RADEON_DST_LINE_END, ((y) << 16) | (x + width));
}
++ai->si->engine.count;
(void)et;
}
void SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count)
{
if ( ai->si->acc_dma )
SCREEN_TO_SCREEN_BLIT_DMA(et,list,count);
else
SCREEN_TO_SCREEN_BLIT_PIO(et,list,count);
}
void FILL_RECTANGLE(engine_token *et, uint32 color, fill_rect_params *list, uint32 count)
{
if ( ai->si->acc_dma )
FILL_RECTANGLE_DMA(et, color, list, count);
else
FILL_RECTANGLE_PIO(et, color, list, count);
}
void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count)
{
if ( ai->si->acc_dma )
INVERT_RECTANGLE_DMA(et, list, count);
else
INVERT_RECTANGLE_PIO(et, list, count);
}
void FILL_SPAN(engine_token *et, uint32 color, uint16 *list, uint32 count)
{
if ( ai->si->acc_dma )
FILL_SPAN_DMA(et, color, list, count);
else
FILL_SPAN_PIO(et, color, list, count);
}
void Radeon_Init2D( accelerator_info *ai )
{
SHOW_FLOW0( 3, "" );
if ( ai->si->acc_dma ) {
START_IB();
WRITE_IB_REG( RADEON_RB3D_CNTL, 0 );
SUBMIT_IB();
}
else {
OUTREG( ai->regs, RADEON_RB3D_CNTL, 0 );
}
}
void Radeon_FillStateBuffer( accelerator_info *ai, uint32 datatype )
{
virtual_card *vc = ai->vc;
uint32 pitch_offset;
uint32 *buffer = NULL, *buffer_start = NULL;
SHOW_FLOW0( 4, "" );
pitch_offset =
((ai->si->memory[mt_local].virtual_addr_start + vc->fb_offset) >> 10) |
((vc->pitch >> 6) << 22);
if ( ai->si->acc_dma ) {
Radeon_InvalidateStateBuffer( ai, vc->state_buffer_idx );
buffer = buffer_start = Radeon_GetIndirectBufferPtr( ai, vc->state_buffer_idx );
WRITE_IB_REG( RADEON_DEFAULT_OFFSET, pitch_offset );
WRITE_IB_REG( RADEON_DST_PITCH_OFFSET, pitch_offset );
WRITE_IB_REG( RADEON_SRC_PITCH_OFFSET, pitch_offset );
WRITE_IB_REG( RADEON_DEFAULT_SC_BOTTOM_RIGHT,
(RADEON_DEFAULT_SC_RIGHT_MAX | RADEON_DEFAULT_SC_BOTTOM_MAX));
WRITE_IB_REG( RADEON_DP_GUI_MASTER_CNTL,
(datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_BRUSH_SOLID_COLOR
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P
| RADEON_DP_SRC_SOURCE_MEMORY
| RADEON_GMC_WR_MSK_DIS );
WRITE_IB_REG( RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
WRITE_IB_REG( RADEON_DP_BRUSH_BKGD_CLR, 0x00000000);
WRITE_IB_REG( RADEON_DP_SRC_FRGD_CLR, 0xffffffff);
WRITE_IB_REG( RADEON_DP_SRC_BKGD_CLR, 0x00000000);
WRITE_IB_REG( RADEON_DP_WRITE_MASK, 0xffffffff);
vc->state_buffer_size = buffer - buffer_start;
} else {
Radeon_WaitForFifo( ai, 10 );
OUTREG( ai->regs, RADEON_DEFAULT_OFFSET, pitch_offset );
OUTREG( ai->regs, RADEON_DST_PITCH_OFFSET, pitch_offset );
OUTREG( ai->regs, RADEON_SRC_PITCH_OFFSET, pitch_offset );
OUTREG( ai->regs, RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX
| RADEON_DEFAULT_SC_BOTTOM_MAX));
OUTREG( ai->regs, RADEON_DP_GUI_MASTER_CNTL,
(datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
| RADEON_GMC_CLR_CMP_CNTL_DIS
| RADEON_GMC_BRUSH_SOLID_COLOR
| RADEON_GMC_SRC_DATATYPE_COLOR
| RADEON_ROP3_P
| RADEON_DP_SRC_SOURCE_MEMORY
| RADEON_GMC_WR_MSK_DIS );
OUTREG( ai->regs, RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff);
OUTREG( ai->regs, RADEON_DP_BRUSH_BKGD_CLR, 0x00000000);
OUTREG( ai->regs, RADEON_DP_SRC_FRGD_CLR, 0xffffffff);
OUTREG( ai->regs, RADEON_DP_SRC_BKGD_CLR, 0x00000000);
OUTREG( ai->regs, RADEON_DP_WRITE_MASK, 0xffffffff);
}
ai->si->active_vc = vc->id;
}
void Radeon_AllocateVirtualCardStateBuffer( accelerator_info *ai )
{
virtual_card *vc = ai->vc;
vc->state_buffer_idx = Radeon_AllocIndirectBuffer( ai, false );
vc->state_buffer_size = -1;
}
void Radeon_FreeVirtualCardStateBuffer( accelerator_info *ai )
{
virtual_card *vc = ai->vc;
Radeon_InvalidateStateBuffer( ai, vc->state_buffer_idx );
Radeon_FreeIndirectBuffer( ai, vc->state_buffer_idx, false );
}