Commit a8f3bf27 authored by Bjorn Astrom's avatar Bjorn Astrom
Browse files

Latest graphics acceleration stuff

parent 4862a794
......@@ -943,6 +943,13 @@ void template_fill_rect(uint32_t color_format, uint16_t rect_x1, uint16_t rect_y
}
}
#define MNTVA_FROM_BPP(d, s) \
if (s == 2) { \
d = MNTVA_COLOR_16BIT565; \
} else if (s == 4) { \
d = MNTVA_COLOR_32BIT; \
}
// Generic graphics acceleration functionality
void acc_clear_buffer(uint32_t addr, uint16_t w, uint16_t h, uint16_t pitch_, uint32_t fg_color, uint32_t color_format_)
{
......@@ -953,12 +960,8 @@ void acc_clear_buffer(uint32_t addr, uint16_t w, uint16_t h, uint16_t pitch_, ui
uint8_t* dp = (uint8_t*)((uint32_t)addr);
uint8_t u8_fg = fg_color >> 24;
uint8_t color_format = 0;
if (color_format_ == 2) {
color_format = MNTVA_COLOR_16BIT565;
} else if (color_format == 4) {
color_format = MNTVA_COLOR_32BIT;
}
uint8_t color_format = MNTVA_COLOR_8BIT;
MNTVA_FROM_BPP(color_format, color_format_)
switch(color_format) {
case MNTVA_COLOR_8BIT:
......@@ -980,8 +983,6 @@ void acc_clear_buffer(uint32_t addr, uint16_t w, uint16_t h, uint16_t pitch_, ui
}
}
extern uint32_t framebuffer, framebuffer_pan_offset;
void acc_flip_to_fb(uint32_t src, uint32_t dest, uint16_t w, uint16_t h, uint16_t pitch_, uint32_t color_format)
{
// This function assumes a flip of a surface with the same dimensions as the frame buffer.
......@@ -1055,3 +1056,160 @@ void acc_blit_rect_16to8(uint32_t src, uint32_t dest, uint16_t x, uint16_t y, ui
sp += src_pitch;
}
}
#define ACC_DRAW_LINE_PIXELS \
for (int y = 0; y < pen_width; y++) { \
for (int x2 = 0; x2 < pen_width; x2++) { \
switch(color_format) { \
case MNTVA_COLOR_8BIT: \
dp[x + x2 + (y * pitch)] = u8_fg; break; \
case MNTVA_COLOR_16BIT565: \
((uint16_t *)dp)[x + x2 + (y * pitch)] = fg_color; break; \
case MNTVA_COLOR_32BIT: \
((uint32_t *)dp)[x + x2 + (y * pitch)] = fg_color; break; \
} \
} \
}
void acc_draw_line(uint32_t dest, uint16_t pitch, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint32_t fg_color, uint8_t bpp, uint8_t pen_width, uint8_t pen_height)
{
uint8_t color_format = MNTVA_COLOR_8BIT;
MNTVA_FROM_BPP(color_format, bpp)
uint8_t u8_fg = fg_color >> 24;
uint8_t* dp = (uint8_t *)((uint32_t)dest + (y1 * pitch));
int32_t line_step = pitch;
int8_t x_reverse = 0;
int16_t dx, dy, dx_abs, dy_abs, ix, iy, x = x1, len;
if (x2 < x1)
x_reverse = 1;
if (y2 < y1)
line_step = -pitch;
dx = x2 - x1;
dy = y2 - y1;
dx_abs = abs(dx);
dy_abs = abs(dy);
ix = dy_abs >> 1;
iy = dx_abs >> 1;
ACC_DRAW_LINE_PIXELS;
if (dx_abs >= dy_abs) {
len = dx_abs;
for (uint16_t i = 0; i < len; i++) {
iy += dy_abs;
if (iy >= dx_abs) {
iy -= dx_abs;
dp += line_step;
}
x += (x_reverse) ? -1 : 1;
ACC_DRAW_LINE_PIXELS;
}
}
else {
len = dy_abs;
for (uint16_t i = 0; i < len; i++) {
ix += dx_abs;
if (ix >= dy_abs) {
ix -= dy_abs;
x += (x_reverse) ? -1 : 1;
}
dp += line_step;
ACC_DRAW_LINE_PIXELS;
}
}
}
void acc_fill_rect(uint32_t dest, uint16_t pitch, int16_t x, int16_t y, int16_t w, int16_t h, uint32_t fg_color, uint8_t bpp)
{
uint8_t color_format = MNTVA_COLOR_8BIT;
MNTVA_FROM_BPP(color_format, bpp)
uint8_t u8_fg = fg_color >> 24;
uint8_t* dp = (uint8_t *)((uint32_t)dest + (x * bpp) + (y * pitch));
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
switch(color_format) {
case MNTVA_COLOR_8BIT:
memset(dp, u8_fg, w);
j = w;
break;
case MNTVA_COLOR_16BIT565:
((uint16_t *)dp)[x] = fg_color;
break;
case MNTVA_COLOR_32BIT:
((uint32_t *)dp)[x] = fg_color;
break;
default:
break;
}
}
dp += pitch;
}
}
#define CHKBLOT(a, b) \
if (a >= 0 && b >= 0 && a < w && b < h)
// DrawPixel(surface, x + x1, y + y1, colour);
// DrawPixel(surface, x - x1, y + y1, colour);
// DrawPixel(surface, x + x1, y - y1, colour);
// DrawPixel(surface, x - x1, y - y1, colour);
// DrawPixel(surface, x + y1, y + x1, colour);
// DrawPixel(surface, x - y1, y + x1, colour);
// DrawPixel(surface, x + y1, y - x1, colour);
// DrawPixel(surface, x - y1, y - x1, colour);
#define BLOTCIRCLE(a, b) \
CHKBLOT((x + x1),(y + y1)) a[(x + x1) + ((y + y1) * pitch)] = b; \
CHKBLOT((x - x1),(y + y1)) a[(x - x1) + ((y + y1) * pitch)] = b; \
CHKBLOT((x + x1),(y - y1)) a[(x + x1) + ((y - y1) * pitch)] = b; \
CHKBLOT((x - x1),(y - y1)) a[(x - x1) + ((y - y1) * pitch)] = b; \
CHKBLOT((x + y1),(y + x1)) a[(x + y1) + ((y + x1) * pitch)] = b; \
CHKBLOT((x - y1),(y + x1)) a[(x - y1) + ((y + x1) * pitch)] = b; \
CHKBLOT((x + y1),(y - x1)) a[(x + y1) + ((y - x1) * pitch)] = b; \
CHKBLOT((x - y1),(y - x1)) a[(x - y1) + ((y - x1) * pitch)] = b;
void acc_draw_circle(uint32_t dest, uint16_t pitch, int16_t x, int16_t y, int16_t r, int16_t w, int16_t h, uint32_t fg_color, uint8_t bpp)
{
uint8_t color_format = MNTVA_COLOR_8BIT;
MNTVA_FROM_BPP(color_format, bpp)
uint8_t u8_fg = fg_color >> 24;
int x1 = r;
int y1 = 0;
int d = 3 - 2 * r;
uint8_t* dp = (uint8_t *)(uint32_t)dest;
while (x1 >= y1) {
y1++;
if (d > 0) {
x1--;
d = d + 4 * (y1 - x1) + 10;
}
else {
d = d + 4 * y1 + 6;
}
switch(color_format) {
case MNTVA_COLOR_8BIT:
BLOTCIRCLE(dp, u8_fg);
break;
case MNTVA_COLOR_16BIT565:
BLOTCIRCLE(((uint16_t *)dp), fg_color);
break;
case MNTVA_COLOR_32BIT:
BLOTCIRCLE(((uint32_t *)dp), fg_color);
break;
default:
break;
}
}
}
\ No newline at end of file
......@@ -55,6 +55,10 @@ void acc_flip_to_fb(uint32_t src, uint32_t dest, uint16_t w, uint16_t h, uint16_
void acc_blit_rect(uint32_t src, uint32_t dest, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t src_pitch, uint16_t dest_pitch, uint8_t draw_mode, uint8_t mask_color);
void acc_blit_rect_16to8(uint32_t src, uint32_t dest, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t src_pitch, uint16_t dest_pitch);
void acc_draw_line(uint32_t dest, uint16_t pitch, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint32_t color, uint8_t bpp, uint8_t pen_width, uint8_t pen_height);
void acc_fill_rect(uint32_t dest, uint16_t pitch, int16_t x, int16_t y, int16_t w, int16_t h, uint32_t fg_color, uint8_t bpp);
void acc_draw_circle(uint32_t dest, uint16_t pitch, int16_t x, int16_t y, int16_t r, int16_t w, int16_t h, uint32_t fg_color, uint8_t bpp);
void *get_color_conversion_table(int index);
/*#define MNTVA_COLOR_8BIT 0
......@@ -512,6 +516,7 @@ struct GFXData {
uint16_t pitch[4];
uint8_t u8_user[8];
uint8_t op, mask, minterm, u8offset;
uint32_t u32_user[8];
uint8_t clut1[768];
uint8_t clut2[768];
uint8_t clut3[768];
......@@ -545,6 +550,9 @@ enum gfx_acc_op {
ACC_OP_ALLOC_SURFACE,
ACC_OP_FREE_SURFACE,
ACC_OP_SET_BPP_CONVERSION_TABLE,
ACC_OP_DRAW_LINE,
ACC_OP_FILL_RECT,
ACC_OP_DRAW_CIRCLE,
ACC_OP_NUM,
};
......
......@@ -64,6 +64,8 @@ typedef u8 uint8_t;
// I2C controller instance
XIicPs Iic;
unsigned int cur_mem_offset = 0x3400000;
int hdmi_ctrl_write_byte(u8 addr, u8 value) {
u8 buffer[2];
buffer[0] = addr;
......@@ -810,6 +812,8 @@ void handle_amiga_reset() {
usb_read_write_num_blocks = 1;
ethernet_send_result = 0;
cur_mem_offset = 0x3500000;
// FIXME there should be more state to be reset
}
......@@ -1068,10 +1072,6 @@ int main() {
int custom_vmode_param = VMODE_PARAM_HRES;
uint8_t debug_dma_op[OP_NUM];
memset(debug_dma_op, 0x00, OP_NUM);
crab = malloc(0x3410000);
crab[0x3400000] = 'a';
while (1) {
u32 zstate = mntzorro_read(MNTZ_BASE_ADDR, MNTZORRO_REG3);
zstate_raw = zstate;
......@@ -1324,9 +1324,17 @@ int main() {
// Generic graphics acceleration
case REG_ZZ_ACC_OP: {
struct GFXData *data = (struct GFXData*)((u32)Z3_SCRATCH_ADDR);
int cf_bpp[MNTVA_COLOR_NUM] = { 1, 2, 4, -8, 2, };
//int cf_bpp[MNTVA_COLOR_NUM] = { 1, 2, 4, -8, 2, };
switch (zdata) {
// SURFACE BLIT OPS
case ACC_OP_NONE: {
SWAP32(data->offset[0]);
SWAP32(data->offset[1]);
printf ("%s: %p - %p\n", data->clut2, (uint8_t*)data->offset[0], (uint8_t*)data->offset[1]);
break;
}
case ACC_OP_BUFFER_CLEAR: {
SWAP16(data->x[0]);
SWAP16(data->y[0]);
......@@ -1372,42 +1380,100 @@ int main() {
}
acc_blit_rect(data->offset[0], data->offset[1], data->x[0], data->y[0], data->x[1] * data->u8_user[0], data->y[1], data->pitch[0], data->pitch[1], data->u8_user[2], data->u8offset);
break;
case ACC_OP_ALLOC_SURFACE: {
// PRIMITIVE OPS
case ACC_OP_DRAW_CIRCLE:
SWAP16(data->x[0]); SWAP16(data->y[0]);
SWAP16(data->x[1]); SWAP16(data->y[1]);
SWAP16(data->x[2]); SWAP16(data->y[2]);
SWAP32(data->offset[0]);
SWAP16(data->pitch[0]);
data->offset[0] += ADDR_ADJ;
acc_draw_circle(data->offset[0], data->pitch[0], data->x[0], data->y[0], data->x[2], data->x[1], data->y[1], data->rgb[0], data->u8_user[0]);
break;
case ACC_OP_DRAW_LINE:
SWAP16(data->x[0]); SWAP16(data->y[0]);
SWAP16(data->x[1]); SWAP16(data->y[1]);
SWAP32(data->offset[0]);
SWAP16(data->pitch[0]);
data->offset[0] += ADDR_ADJ;
//printf("Drawing line from %d,%d to %d,%d...\n", data->x[0], data->y[0], data->x[1], data->y[1]);
acc_draw_line(data->offset[0], data->pitch[0], data->x[0], data->y[0], data->x[1], data->y[1], data->rgb[0], data->u8_user[0], data->u8_user[1], data->u8_user[2]);
break;
case ACC_OP_FILL_RECT:
SWAP16(data->x[0]); SWAP16(data->y[0]);
SWAP16(data->x[1]); SWAP16(data->y[1]);
SWAP32(data->offset[0]);
SWAP16(data->pitch[0]);
data->offset[0] += ADDR_ADJ;
//printf("Filling rect at %d,%d to %d,%d...\n", data->x[0], data->y[0], data->x[0] + data->x[1], data->y[0] + data->y[1]);
acc_fill_rect(data->offset[0], data->pitch[0], data->x[0], data->y[0], data->x[1], data->y[1], data->rgb[0], data->u8_user[0]);
break;
// ALLOC/DATA OPS
case ACC_OP_ALLOC_SURFACE: {
unsigned int sfc_size = 0;
data->offset[0] = 0;
if (data->u8_user[1] == 1) {
SWAP32(data->offset[1]);
sfc_size = data->offset[1];
}
else {
SWAP16(data->x[0]); SWAP16(data->y[0]);
data->offset[0] = 0;
sfc_size = ((data->x[0] * data->u8_user[0]) * data->y[0]);
size_t sfc_size = 0;
}
if (data->u8_user[GFXDATA_U8_DRAWMODE] != 0)
sfc_size = ((data->x[0] * data->u8_user[GFXDATA_U8_DRAWMODE]) * data->y[0]);
else
sfc_size = ((data->x[0] * cf_bpp[data->u8_user[GFXDATA_U8_COLORMODE]]) * data->y[0]);
unsigned int barf = sfc_size % 256;
if (barf)
sfc_size += (256 - barf);
if (data->u8_user[1] == 1) {
printf ("Alloc requested for %d bytes.\n", data->offset[1]);
}
else {
printf ("Alloc requested for %dx%d surface, %.2X bytes per pixel, %d bytes.\n", data->x[0], data->y[0], data->u8_user[0], sfc_size);
}
if (!sfc_size) {
printf("Refusing to allocate 0 bytes for you.\n");
break;
}
printf ("Allocating %dx%d surface, %d bytes per pixel, %d bytes.\n", data->x[0], data->y[0], data->u8_user[GFXDATA_U8_COLORMODE], sfc_size);
uint8_t *p = calloc(1, sfc_size);
printf ("Surface allocated at offset %p, or %p on the Amiga side.\n", p, p - ADDR_ADJ);
data->offset[0] = (uint32_t)(p - ADDR_ADJ);
//uint8_t *p = malloc(sfc_size);
//memset(p, 0x00, sfc_size);
//allocated_surfaces++;
//printf ("Surface allocated at offset %.8X, or %.8X on the Amiga side.\n", cur_mem_offset, cur_mem_offset - ADDR_ADJ);
data->offset[0] = cur_mem_offset - ADDR_ADJ;
memset((void *)cur_mem_offset, 0x00, sfc_size);
cur_mem_offset += sfc_size;
SWAP32(data->offset[0]);
break;
}
case ACC_OP_FREE_SURFACE: {
SWAP32(data->offset[0]);
data->offset[0] += ADDR_ADJ;
printf("Freeing surface at %.8X... maybe.\n", data->offset[0]);
free((void *)data->offset[0]);
void *ape = (void*)data->offset[0];
if (data->u8_user[0]) {
printf("[%s] Freeing surface at %p... Not really.\n", data->clut2, ape);
}
//else
//printf("Freeing surface at %p... Not really.\n", ape);
data->offset[0] = 0;
//free(ape);
//printf(" freed!\n");
break;
}
case ACC_OP_SET_BPP_CONVERSION_TABLE: {
// TODO:
// Add some thing to select table based on source and dest bpp.
// Requires the destination 8bpp palette to be in R3G2B3 format to look "correct" out of the box.
// Requires the destination 8bpp palette to be in R3G3B2 format to look "correct" out of the box.
SWAP32(data->offset[0]);
data->offset[0] += ADDR_ADJ;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment