Files
86Box/src/include/86box/vid_voodoo_common.h

698 lines
14 KiB
C
Raw Normal View History

/*
2023-01-06 15:36:05 -05:00
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
2023-01-06 15:36:05 -05:00
* This file is part of the 86Box distribution.
*
2023-01-06 15:36:05 -05:00
* Voodoo Graphics, 2, Banshee, 3 emulation.
*
*
*
2023-01-06 15:36:29 -05:00
* Authors: Sarah Walker, <https://pcem-emulator.co.uk/>
2023-01-06 15:36:05 -05:00
* leilei
*
2023-01-06 15:36:05 -05:00
* Copyright 2008-2020 Sarah Walker.
*/
2022-02-18 19:42:21 -05:00
#ifndef VIDEO_VOODOO_COMMON_H
#define VIDEO_VOODOO_COMMON_H
2022-02-18 19:42:21 -05:00
#ifdef CLAMP
# undef CLAMP
#endif
#define CLAMP(x) (((x) < 0) ? 0 : (((x) > 0xff) ? 0xff : (x)))
#define CLAMP16(x) (((x) < 0) ? 0 : (((x) > 0xffff) ? 0xffff : (x)))
#define LOD_MAX 8
#define TEX_DIRTY_SHIFT 10
#define TEX_CACHE_MAX 64
#ifdef __cplusplus
2022-11-19 08:49:04 -05:00
# include <atomic>
using atomic_int = std::atomic<int>;
#else
2022-11-19 08:49:04 -05:00
# include <stdatomic.h>
#endif
enum {
VOODOO_1 = 0,
VOODOO_SB50,
VOODOO_2,
VOODOO_BANSHEE,
VOODOO_3
};
typedef union int_float {
uint32_t i;
float f;
} int_float;
typedef struct rgbvoodoo_t {
2023-05-11 03:02:36 -04:00
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t pad;
} rgbvoodoo_t;
typedef struct rgba8_t {
2023-05-11 03:02:36 -04:00
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
} rgba8_t;
typedef union rgba_u {
struct
{
2023-05-11 03:02:36 -04:00
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
} rgba;
uint32_t u;
} rgba_u;
#define FIFO_SIZE 65536
#define FIFO_MASK (FIFO_SIZE - 1)
#define FIFO_ENTRY_SIZE (1 << 31)
#define FIFO_ENTRIES (voodoo->fifo_write_idx - voodoo->fifo_read_idx)
#define FIFO_FULL ((voodoo->fifo_write_idx - voodoo->fifo_read_idx) >= FIFO_SIZE - 4)
#define FIFO_EMPTY (voodoo->fifo_read_idx == voodoo->fifo_write_idx)
#define FIFO_TYPE 0xff000000
#define FIFO_ADDR 0x00ffffff
enum {
FIFO_INVALID = (0x00 << 24),
FIFO_WRITEL_REG = (0x01 << 24),
FIFO_WRITEW_FB = (0x02 << 24),
FIFO_WRITEL_FB = (0x03 << 24),
FIFO_WRITEL_TEX = (0x04 << 24),
FIFO_WRITEL_2DREG = (0x05 << 24)
};
#define PARAM_SIZE 1024
#define PARAM_MASK (PARAM_SIZE - 1)
#define PARAM_ENTRY_SIZE (1 << 31)
#define PARAM_ENTRIES(x) (voodoo->params_write_idx - voodoo->params_read_idx[x])
#define PARAM_FULL(x) ((voodoo->params_write_idx - voodoo->params_read_idx[x]) >= PARAM_SIZE)
#define PARAM_EMPTY(x) (voodoo->params_read_idx[x] == voodoo->params_write_idx)
typedef struct
{
uint32_t addr_type;
uint32_t val;
} fifo_entry_t;
typedef struct voodoo_params_t {
int command;
2023-05-11 03:02:36 -04:00
int32_t vertexAx;
int32_t vertexAy;
int32_t vertexBx;
int32_t vertexBy;
int32_t vertexCx;
int32_t vertexCy;
uint32_t startR;
uint32_t startG;
uint32_t startB;
uint32_t startZ;
uint32_t startA;
int32_t dBdX;
int32_t dGdX;
int32_t dRdX;
int32_t dAdX;
int32_t dZdX;
int32_t dBdY;
int32_t dGdY;
int32_t dRdY;
int32_t dAdY;
int32_t dZdY;
int64_t startW;
int64_t dWdX;
int64_t dWdY;
struct
{
2023-05-11 03:02:36 -04:00
int64_t startS;
int64_t startT;
int64_t startW;
int64_t p1;
int64_t dSdX;
int64_t dTdX;
int64_t dWdX;
int64_t p2;
int64_t dSdY;
int64_t dTdY;
int64_t dWdY;
int64_t p3;
} tmu[2];
2023-05-11 03:02:36 -04:00
uint32_t color0;
uint32_t color1;
uint32_t fbzMode;
uint32_t fbzColorPath;
uint32_t fogMode;
rgbvoodoo_t fogColor;
struct
{
2023-05-11 03:02:36 -04:00
uint8_t fog;
uint8_t dfog;
} fogTable[64];
uint32_t alphaMode;
uint32_t zaColor;
2023-05-11 03:02:36 -04:00
int chromaKey_r;
int chromaKey_g;
int chromaKey_b;
uint32_t chromaKey;
uint32_t textureMode[2];
uint32_t tLOD[2];
2023-05-11 03:02:36 -04:00
uint32_t texBaseAddr[2];
uint32_t texBaseAddr1[2];
uint32_t texBaseAddr2[2];
uint32_t texBaseAddr38[2];
uint32_t tex_base[2][LOD_MAX + 2];
uint32_t tex_end[2][LOD_MAX + 2];
int tex_width[2];
int tex_w_mask[2][LOD_MAX + 2];
int tex_w_nmask[2][LOD_MAX + 2];
int tex_h_mask[2][LOD_MAX + 2];
int tex_shift[2][LOD_MAX + 2];
int tex_lod[2][LOD_MAX + 2];
int tex_entry[2];
2023-05-11 03:02:36 -04:00
int detail_max[2];
int detail_bias[2];
int detail_scale[2];
2023-05-11 03:02:36 -04:00
uint32_t draw_offset;
uint32_t aux_offset;
int tformat[2];
2023-05-11 03:02:36 -04:00
int clipLeft;
int clipRight;
int clipLowY;
int clipHighY;
int clipLeft1;
int clipRight1;
int clipLowY1;
int clipHighY1;
int sign;
uint32_t front_offset;
uint32_t swapbufferCMD;
uint32_t stipple;
2023-05-11 03:02:36 -04:00
int col_tiled;
int aux_tiled;
int row_width;
int aux_row_width;
} voodoo_params_t;
typedef struct texture_t {
uint32_t base;
uint32_t tLOD;
2023-05-11 03:02:36 -04:00
atomic_int refcount;
atomic_int refcount_r[4];
int is16;
uint32_t palette_checksum;
2023-05-11 03:02:36 -04:00
uint32_t addr_start[4];
uint32_t addr_end[4];
uint32_t *data;
} texture_t;
typedef struct vert_t {
2023-05-11 03:02:36 -04:00
float sVx;
float sVy;
float sRed;
float sGreen;
float sBlue;
float sAlpha;
float sVz;
float sWb;
float sW0;
float sS0;
float sT0;
float sW1;
float sS1;
float sT1;
} vert_t;
typedef struct clip_t {
2023-05-11 03:02:36 -04:00
int x_min;
int x_max;
int y_min;
int y_max;
} clip_t;
typedef struct voodoo_t {
mem_mapping_t mapping;
int pci_enable;
uint8_t dac_data[8];
2023-05-11 03:02:36 -04:00
int dac_reg;
int dac_reg_ff;
uint8_t dac_readdata;
uint16_t dac_pll_regs[16];
float pixel_clock;
uint64_t line_time;
voodoo_params_t params;
2023-05-11 03:02:36 -04:00
uint32_t fbiInit0;
uint32_t fbiInit1;
uint32_t fbiInit2;
uint32_t fbiInit3;
uint32_t fbiInit4;
uint32_t fbiInit5;
uint32_t fbiInit6;
uint32_t fbiInit7; /*Voodoo 2*/
uint32_t initEnable;
uint32_t lfbMode;
uint32_t memBaseAddr;
2023-05-11 03:02:36 -04:00
int_float fvertexAx;
int_float fvertexAy;
int_float fvertexBx;
int_float fvertexBy;
int_float fvertexCx;
int_float fvertexCy;
2023-05-11 03:02:36 -04:00
uint32_t front_offset;
uint32_t back_offset;
2023-05-11 03:02:36 -04:00
uint32_t fb_read_offset;
uint32_t fb_write_offset;
2023-05-11 03:02:36 -04:00
int row_width;
int aux_row_width;
int block_width;
2022-02-20 02:26:27 -05:00
2023-05-11 03:02:36 -04:00
int col_tiled;
int aux_tiled;
2023-05-11 03:02:36 -04:00
uint8_t *fb_mem;
uint8_t *tex_mem[2];
uint16_t *tex_mem_w[2];
int rgb_sel;
uint32_t trexInit1[2];
uint32_t tmuConfig;
mutex_t *swap_mutex;
int swap_count;
2023-05-11 03:02:36 -04:00
int disp_buffer;
int draw_buffer;
pc_timer_t timer;
int line;
svga_t *svga;
uint32_t backPorch;
uint32_t videoDimensions;
2023-05-11 03:02:36 -04:00
uint32_t hSync;
uint32_t vSync;
2023-05-11 03:02:36 -04:00
int h_total;
int v_total;
int v_disp;
int h_disp;
int v_retrace;
struct
{
2023-05-11 03:02:36 -04:00
uint32_t y[4];
uint32_t i[4];
uint32_t q[4];
} nccTable[2][2];
rgba_u palette[2][256];
rgba_u ncc_lookup[2][2][256];
int ncc_dirty[2];
thread_t *fifo_thread;
thread_t *render_thread[4];
event_t *wake_fifo_thread;
event_t *wake_main_thread;
event_t *fifo_not_full_event;
event_t *render_not_full_event[4];
event_t *wake_render_thread[4];
int voodoo_busy;
int render_voodoo_busy[4];
int render_threads;
int odd_even_mask;
2023-05-11 03:02:36 -04:00
int pixel_count[4];
int texel_count[4];
int tri_count;
int frame_count;
int pixel_count_old[4];
int texel_count_old[4];
int wr_count;
int rd_count;
int tex_count;
int retrace_count;
int swap_interval;
uint32_t swap_offset;
int swap_pending;
int bilinear_enabled;
int dithersub_enabled;
int fb_size;
uint32_t fb_mask;
int texture_size;
uint32_t texture_mask;
int dual_tmus;
int type;
fifo_entry_t fifo[FIFO_SIZE];
2023-05-11 03:02:36 -04:00
atomic_int fifo_read_idx;
atomic_int fifo_write_idx;
atomic_int cmd_read;
atomic_int cmd_written;
atomic_int cmd_written_fifo;
voodoo_params_t params_buffer[PARAM_SIZE];
2023-05-11 03:02:36 -04:00
atomic_int params_read_idx[4];
atomic_int params_write_idx;
uint32_t cmdfifo_base;
uint32_t cmdfifo_end;
uint32_t cmdfifo_size;
int cmdfifo_rp;
int cmdfifo_ret_addr;
int cmdfifo_in_sub;
2023-05-11 03:02:36 -04:00
atomic_int cmdfifo_depth_rd;
atomic_int cmdfifo_depth_wr;
atomic_int cmdfifo_enabled;
2023-05-11 03:02:36 -04:00
uint32_t cmdfifo_amin;
uint32_t cmdfifo_amax;
int cmdfifo_holecount;
2022-11-19 08:49:04 -05:00
atomic_uint cmd_status;
uint32_t sSetupMode;
vert_t verts[4];
unsigned int vertex_ages[3];
unsigned int vertex_next_age;
int num_verticies;
int cull_pingpong;
int flush;
int scrfilter;
int scrfilterEnabled;
int scrfilterThreshold;
int scrfilterThresholdOld;
uint32_t last_write_addr;
uint32_t fbiPixelsIn;
uint32_t fbiChromaFail;
uint32_t fbiZFuncFail;
uint32_t fbiAFuncFail;
uint32_t fbiPixelsOut;
uint32_t bltSrcBaseAddr;
uint32_t bltDstBaseAddr;
2023-05-11 03:02:36 -04:00
int bltSrcXYStride;
int bltDstXYStride;
uint32_t bltSrcChromaRange;
uint32_t bltDstChromaRange;
int bltSrcChromaMinR;
int bltSrcChromaMinG;
int bltSrcChromaMinB;
int bltSrcChromaMaxR;
int bltSrcChromaMaxG;
int bltSrcChromaMaxB;
int bltDstChromaMinR;
int bltDstChromaMinG;
int bltDstChromaMinB;
int bltDstChromaMaxR;
int bltDstChromaMaxG;
int bltDstChromaMaxB;
int bltClipRight;
int bltClipLeft;
int bltClipHighY;
int bltClipLowY;
int bltSrcX;
int bltSrcY;
int bltDstX;
int bltDstY;
int bltSizeX;
int bltSizeY;
int bltRop[4];
2023-05-11 03:02:36 -04:00
uint16_t bltColorFg;
uint16_t bltColorBg;
uint32_t bltCommand;
uint32_t leftOverlayBuf;
struct
{
2023-05-11 03:02:36 -04:00
int dst_x;
int dst_y;
int cur_x;
2023-05-11 03:02:36 -04:00
int size_x;
int size_y;
int x_dir;
int y_dir;
int dst_stride;
} blt;
struct
{
2023-05-11 03:02:36 -04:00
uint32_t bresError0;
uint32_t bresError1;
uint32_t clip0Min;
uint32_t clip0Max;
uint32_t clip1Min;
uint32_t clip1Max;
uint32_t colorBack;
uint32_t colorFore;
uint32_t command;
uint32_t commandExtra;
uint32_t dstBaseAddr;
uint32_t dstFormat;
uint32_t dstSize;
uint32_t dstXY;
uint32_t lineStipple;
uint32_t lineStyle;
uint32_t rop;
uint32_t srcBaseAddr;
uint32_t srcFormat;
uint32_t srcSize;
uint32_t srcXY;
uint32_t colorPattern[64];
2023-05-11 03:02:36 -04:00
int bres_error_0;
int bres_error_1;
uint32_t colorPattern8[64];
uint32_t colorPattern16[64];
uint32_t colorPattern24[64];
int cur_x;
int cur_y;
uint32_t dstBaseAddr_tiled;
2023-05-11 03:02:36 -04:00
uint32_t dstColorkeyMin;
uint32_t dstColorkeyMax;
int dstSizeX;
int dstSizeY;
int dstX;
int dstY;
int dst_stride;
2023-05-11 03:02:36 -04:00
int patoff_x;
int patoff_y;
uint8_t rops[4];
uint32_t srcBaseAddr_tiled;
2023-05-11 03:02:36 -04:00
uint32_t srcColorkeyMin;
uint32_t srcColorkeyMax;
int srcSizeX;
int srcSizeY;
int srcX;
int srcY;
int src_stride;
int old_srcX;
/*Used for handling packed 24bpp host data*/
int host_data_remainder;
uint32_t old_host_data;
/*Polyfill coordinates*/
2023-05-11 03:02:36 -04:00
int lx[2];
int rx[2];
int ly[2];
int ry[2];
/*Polyfill state*/
int error[2];
2023-05-11 03:02:36 -04:00
int dx[2];
int dy[2];
int x_inc[2]; /*y_inc is always 1 for polyfill*/
2023-05-11 03:02:36 -04:00
int lx_cur;
int rx_cur;
clip_t clip[2];
uint8_t host_data[16384];
int host_data_count;
2023-05-11 03:02:36 -04:00
int host_data_size_src;
int host_data_size_dest;
int src_stride_src;
int src_stride_dest;
int src_bpp;
2023-05-11 03:02:36 -04:00
int line_pix_pos;
int line_bit_pos;
int line_rep_cnt;
int line_bit_mask_size;
} banshee_blt;
struct
{
uint32_t vidOverlayStartCoords;
uint32_t vidOverlayEndScreenCoords;
2023-05-11 03:02:36 -04:00
uint32_t vidOverlayDudx;
uint32_t vidOverlayDudxOffsetSrcWidth;
uint32_t vidOverlayDvdy;
uint32_t vidOverlayDvdyOffset;
// uint32_t vidDesktopOverlayStride;
2023-05-11 03:02:36 -04:00
int start_x;
int start_y;
int end_x;
int end_y;
int size_x;
int size_y;
int overlay_bytes;
unsigned int src_y;
} overlay;
rgbvoodoo_t clutData[33];
int clutData_dirty;
rgbvoodoo_t clutData256[256];
uint32_t video_16to32[0x10000];
uint8_t dirty_line[2048];
2023-05-11 03:02:36 -04:00
int dirty_line_low;
int dirty_line_high;
2023-05-11 03:02:36 -04:00
int fb_write_buffer;
int fb_draw_buffer;
int buffer_cutoff;
2023-05-11 03:02:36 -04:00
uint32_t tile_base;
uint32_t tile_stride;
int tile_stride_shift;
int tile_x;
int tile_x_real;
int y_origin_swap;
2023-05-11 03:02:36 -04:00
int read_time;
int write_time;
int burst_time;
pc_timer_t wake_timer;
/* screen filter tables */
uint8_t thefilter[256][256];
uint8_t thefilterg[256][256];
uint8_t thefilterb[256][256];
uint16_t purpleline[256][3];
texture_t texture_cache[2][TEX_CACHE_MAX];
uint8_t texture_present[2][16384];
int texture_last_removed;
uint32_t palette_checksum[2];
int palette_dirty[2];
uint64_t time;
int render_time[4];
int force_blit_count;
int can_blit;
mutex_t *force_blit_mutex;
int use_recompiler;
void *codegen_data;
struct voodoo_set_t *set;
2023-05-11 03:02:36 -04:00
uint8_t fifo_thread_run;
uint8_t render_thread_run[4];
2023-05-11 03:02:36 -04:00
uint8_t *vram;
uint8_t *changedvram;
2022-02-20 02:26:27 -05:00
void *p;
uint8_t monitor_index;
} voodoo_t;
typedef struct voodoo_set_t {
voodoo_t *voodoos[2];
mem_mapping_t snoop_mapping;
int nr_cards;
} voodoo_set_t;
2023-05-11 03:02:36 -04:00
extern rgba8_t rgb332[0x100];
extern rgba8_t ai44[0x100];
extern rgba8_t rgb565[0x10000];
extern rgba8_t argb1555[0x10000];
extern rgba8_t argb4444[0x10000];
extern rgba8_t ai88[0x10000];
void voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg);
void voodoo_recalc(voodoo_t *voodoo);
void voodoo_update_ncc(voodoo_t *voodoo, int tmu);
void *voodoo_2d3d_card_init(int type);
void voodoo_card_close(voodoo_t *voodoo);
2022-02-18 19:42:21 -05:00
#endif /*VIDEO_VOODOO_COMMON_H*/