Merge pull request #3928 from Cacodemon345/mga-busmastering-fixes

MGA: Implement gamma correction for 24+ bpp modes
This commit is contained in:
Miran Grča
2023-12-23 20:48:54 +01:00
committed by GitHub
4 changed files with 55 additions and 33 deletions

View File

@@ -268,6 +268,9 @@ typedef struct svga_t {
/* Pointer to monitor */
monitor_t *monitor;
/* Enable LUT mapping of >= 24 bpp modes. */
int lut_map;
void * dev8514;
void * xga;
} svga_t;

View File

@@ -32,6 +32,9 @@ using atomic_int = std::atomic_int;
#define makecol(r, g, b) ((b) | ((g) << 8) | ((r) << 16))
#define makecol32(r, g, b) ((b) | ((g) << 8) | ((r) << 16))
#define getcolr(color) (((color) >> 16) & 0xFF)
#define getcolg(color) (((color) >> 8) & 0xFF)
#define getcolb(color) ((color) & 0xFF)
enum {
VID_NONE = 0,

View File

@@ -914,6 +914,7 @@ mystique_recalctimings(svga_t *svga)
svga->hdisp = (svga->crtc[1] + 1) << 3;
svga->hdisp_time = svga->hdisp;
svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4);
svga->lut_map = 1;
if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) {
svga->rowoffset <<= 1;
@@ -992,6 +993,7 @@ mystique_recalctimings(svga_t *svga)
} else {
svga->packed_chain4 = 0;
svga->line_compare = NULL;
svga->lut_map = 0;
if (mystique->type >= MGA_1064SG)
svga->bpp = 8;
else

View File

@@ -30,6 +30,20 @@
#include <86box/vid_svga_render.h>
#include <86box/vid_svga_render_remap.h>
static inline uint32_t
lookup_lut_ram(svga_t* svga, uint32_t val)
{
if (!svga->lut_map)
return val;
uint8_t r = getcolr(svga->pallook[getcolr(val)]);
uint8_t g = getcolg(svga->pallook[getcolg(val)]);
uint8_t b = getcolb(svga->pallook[getcolb(val)]);
return makecol32(r, g, b) | (val & 0xFF000000);
}
#define lookup_lut(val) lookup_lut_ram(svga, val)
void
svga_render_null(svga_t *svga)
{
@@ -1422,7 +1436,7 @@ svga_render_24bpp_lowres(svga_t *svga)
fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
svga->ma += 3;
svga->ma &= svga->vram_display_mask;
svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = fg;
svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = lookup_lut(fg);
}
}
} else {
@@ -1441,10 +1455,10 @@ svga_render_24bpp_lowres(svga_t *svga)
dat1 = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
dat2 = *(uint32_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]);
p[0] = p[1] = dat0 & 0xffffff;
p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16);
p[6] = p[7] = dat2 >> 8;
p[0] = p[1] = lookup_lut(dat0 & 0xffffff);
p[2] = p[3] = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8));
p[4] = p[5] = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16));
p[6] = p[7] = lookup_lut(dat2 >> 8);
svga->ma += 12;
}
@@ -1457,10 +1471,10 @@ svga_render_24bpp_lowres(svga_t *svga)
addr = svga->remap_func(svga, svga->ma + 8);
dat2 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]);
p[0] = p[1] = dat0 & 0xffffff;
p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16);
p[6] = p[7] = dat2 >> 8;
p[0] = p[1] = lookup_lut(dat0 & 0xffffff);
p[2] = p[3] = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8));
p[4] = p[5] = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16));
p[6] = p[7] = lookup_lut(dat2 >> 8);
svga->ma += 12;
}
@@ -1495,16 +1509,16 @@ svga_render_24bpp_highres(svga_t *svga)
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) {
dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]);
p[x] = dat & 0xffffff;
p[x] = lookup_lut(dat & 0xffffff);
dat = *(uint32_t *) (&svga->vram[(svga->ma + 3) & svga->vram_display_mask]);
p[x + 1] = dat & 0xffffff;
p[x + 1] = lookup_lut(dat & 0xffffff);
dat = *(uint32_t *) (&svga->vram[(svga->ma + 6) & svga->vram_display_mask]);
p[x + 2] = dat & 0xffffff;
p[x + 2] = lookup_lut(dat & 0xffffff);
dat = *(uint32_t *) (&svga->vram[(svga->ma + 9) & svga->vram_display_mask]);
p[x + 3] = dat & 0xffffff;
p[x + 3] = lookup_lut(dat & 0xffffff);
svga->ma += 12;
}
@@ -1526,10 +1540,10 @@ svga_render_24bpp_highres(svga_t *svga)
dat1 = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]);
dat2 = *(uint32_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]);
*p++ = dat0 & 0xffffff;
*p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
*p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16);
*p++ = dat2 >> 8;
*p++ = lookup_lut(dat0 & 0xffffff);
*p++ = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8));
*p++ = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16));
*p++ = lookup_lut(dat2 >> 8);
svga->ma += 12;
}
@@ -1542,10 +1556,10 @@ svga_render_24bpp_highres(svga_t *svga)
addr = svga->remap_func(svga, svga->ma + 8);
dat2 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]);
*p++ = dat0 & 0xffffff;
*p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8);
*p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16);
*p++ = dat2 >> 8;
*p++ = lookup_lut(dat0 & 0xffffff);
*p++ = lookup_lut((dat0 >> 24) | ((dat1 & 0xffff) << 8));
*p++ = lookup_lut((dat1 >> 16) | ((dat2 & 0xff) << 16));
*p++ = lookup_lut(dat2 >> 8);
svga->ma += 12;
}
@@ -1577,7 +1591,7 @@ svga_render_32bpp_lowres(svga_t *svga)
dat = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16);
svga->ma += 4;
svga->ma &= svga->vram_display_mask;
svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = dat;
svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = svga->monitor->target_buffer->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = lookup_lut(dat);
}
}
} else {
@@ -1593,16 +1607,16 @@ svga_render_32bpp_lowres(svga_t *svga)
if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
*p++ = dat & 0xffffff;
*p++ = dat & 0xffffff;
*p++ = lookup_lut(dat & 0xffffff);
*p++ = lookup_lut(dat & 0xffffff);
}
svga->ma += (x * 4);
} else {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
addr = svga->remap_func(svga, svga->ma);
dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]);
*p++ = dat & 0xffffff;
*p++ = dat & 0xffffff;
*p++ = lookup_lut(dat & 0xffffff);
*p++ = lookup_lut(dat & 0xffffff);
svga->ma += 4;
}
svga->ma &= svga->vram_display_mask;
@@ -1633,7 +1647,7 @@ svga_render_32bpp_highres(svga_t *svga)
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
p[x] = dat & 0xffffff;
p[x] = lookup_lut(dat & 0xffffff);
}
svga->ma += 4;
svga->ma &= svga->vram_display_mask;
@@ -1651,14 +1665,14 @@ svga_render_32bpp_highres(svga_t *svga)
if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
*p++ = dat & 0xffffff;
*p++ = lookup_lut(dat & 0xffffff);
}
svga->ma += (x * 4);
} else {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
addr = svga->remap_func(svga, svga->ma);
dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]);
*p++ = dat & 0xffffff;
*p++ = lookup_lut(dat & 0xffffff);
svga->ma += 4;
}
@@ -1692,14 +1706,14 @@ svga_render_ABGR8888_highres(svga_t *svga)
if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
*p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
*p++ = lookup_lut(((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16));
}
svga->ma += x * 4;
} else {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
addr = svga->remap_func(svga, svga->ma);
dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]);
*p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16);
*p++ = lookup_lut(((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16));
svga->ma += 4;
}
@@ -1732,14 +1746,14 @@ svga_render_RGBA8888_highres(svga_t *svga)
if (!svga->remap_required) {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
*p++ = dat >> 8;
*p++ = lookup_lut(dat >> 8);
}
svga->ma += (x * 4);
} else {
for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) {
addr = svga->remap_func(svga, svga->ma);
dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]);
*p++ = dat >> 8;
*p++ = lookup_lut(dat >> 8);
svga->ma += 4;
}