#include "accelerant.h"
#include "rage128.h"
static uint32 sCurrentKeyColor = 0;
static uint32 sCurrentKeyMask = 0;
bool
Rage128_DisplayOverlay(const overlay_window* window,
const overlay_buffer* buffer)
{
SharedInfo& si = *gInfo.sharedInfo;
if (window == NULL || buffer == NULL)
return false;
if (buffer->space != B_YCbCr422)
return false;
uint32 keyColor = 0;
uint32 keyMask = 0;
switch (si.displayMode.bitsPerPixel) {
case 15:
keyMask = 0x7fff;
keyColor = (window->blue.value & window->blue.mask) << 0
| (window->green.value & window->green.mask) << 5
| (window->red.value & window->red.mask) << 10;
break;
case 16:
keyMask = 0xffff;
keyColor = (window->blue.value & window->blue.mask) << 0
| (window->green.value & window->green.mask) << 5
| (window->red.value & window->red.mask) << 11;
break;
default:
keyMask = 0xffffffff;
keyColor = (window->blue.value & window->blue.mask) << 0
| (window->green.value & window->green.mask) << 8
| (window->red.value & window->red.mask) << 16
| (window->alpha.value & window->alpha.mask) << 24;
break;
}
if (keyColor != sCurrentKeyColor || keyMask != sCurrentKeyMask)
{
TRACE("Rage128_DisplayOverlay() initializing overlay video\n");
OUTREG(R128_OV0_SCALE_CNTL, 0);
OUTREG(R128_OV0_EXCLUSIVE_HORZ, 0);
OUTREG(R128_OV0_AUTO_FLIP_CNTL, 0);
OUTREG(R128_OV0_FILTER_CNTL, 0x0000000f);
const uint32 brightness = 0;
const uint32 saturation = 16;
OUTREG(R128_OV0_COLOUR_CNTL, brightness | saturation << 8
| saturation << 16);
OUTREG(R128_OV0_GRAPHICS_KEY_MSK, keyMask);
OUTREG(R128_OV0_GRAPHICS_KEY_CLR, keyColor);
OUTREG(R128_OV0_KEY_CNTL, R128_GRAPHIC_KEY_FN_NE);
OUTREG(R128_OV0_TEST, 0);
sCurrentKeyColor = keyColor;
sCurrentKeyMask = keyMask;
}
uint32 ecpDiv;
if (si.displayMode.timing.pixel_clock < 125000)
ecpDiv = 0;
else if (si.displayMode.timing.pixel_clock < 250000)
ecpDiv = 1;
else
ecpDiv = 2;
SetPLLReg(R128_VCLK_ECP_CNTL, ecpDiv << 8, R128_ECP_DIV_MASK);
int32 vertInc = (buffer->height << 20) / window->height;
int32 horzInc = (buffer->width << (12 + ecpDiv)) / window->width;
int32 stepBy = 1;
while (horzInc >= (2 << 12)) {
stepBy++;
horzInc >>= 1;
}
int32 x1 = window->h_start;
int32 y1 = window->v_start;
int32 x2 = window->h_start + window->width;
int32 y2 = window->v_start + window->height;
int32 left = x1;
int32 tmp = (left & 0x0003ffff) + 0x00028000 + (horzInc << 3);
int32 p1_h_accum_init = ((tmp << 4) & 0x000f8000) |
((tmp << 12) & 0xf0000000);
tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (horzInc << 2);
int32 p23_h_accum_init = ((tmp << 4) & 0x000f8000) |
((tmp << 12) & 0x70000000);
tmp = (y1 & 0x0000ffff) + 0x00018000;
int32 p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 0x00000001;
uint32 offset = (uint32)((addr_t)buffer->buffer - si.videoMemAddr);
OUTREG(R128_OV0_REG_LOAD_CNTL, 1);
while (!(INREG(R128_OV0_REG_LOAD_CNTL) & (1 << 3)))
;
OUTREG(R128_OV0_H_INC, horzInc | ((horzInc >> 1) << 16));
OUTREG(R128_OV0_STEP_BY, stepBy | (stepBy << 8));
OUTREG(R128_OV0_Y_X_START, x1 | y1 << 16);
OUTREG(R128_OV0_Y_X_END, x2 | y2 << 16);
OUTREG(R128_OV0_V_INC, vertInc);
OUTREG(R128_OV0_P1_BLANK_LINES_AT_TOP,
0x00000fff | ((buffer->height - 1) << 16));
OUTREG(R128_OV0_VID_BUF_PITCH0_VALUE, buffer->bytes_per_row);
int32 width = window->width;
left = 0;
OUTREG(R128_OV0_P1_X_START_END, (width - 1) | (left << 16));
width >>= 1;
OUTREG(R128_OV0_P2_X_START_END, (width - 1) | (left << 16));
OUTREG(R128_OV0_P3_X_START_END, (width - 1) | (left << 16));
OUTREG(R128_OV0_VID_BUF0_BASE_ADRS, offset);
OUTREG(R128_OV0_P1_V_ACCUM_INIT, p1_v_accum_init);
OUTREG(R128_OV0_P23_V_ACCUM_INIT, 0);
OUTREG(R128_OV0_P1_H_ACCUM_INIT, p1_h_accum_init);
OUTREG(R128_OV0_P23_H_ACCUM_INIT, p23_h_accum_init);
OUTREG(R128_OV0_SCALE_CNTL, 0x41FF8B03);
OUTREG(R128_OV0_REG_LOAD_CNTL, 0);
return true;
}
void
Rage128_StopOverlay(void)
{
OUTREG(R128_OV0_SCALE_CNTL, 0);
sCurrentKeyColor = 0;
sCurrentKeyMask = 0;
}