mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 18:08:20 -07:00
Partially fix S2SB. Makes Windows 95 behave a lot better!
This commit is contained in:
@@ -39,6 +39,9 @@ uint32_t nv3_render_to_chroma(nv3_color_expanded_t expanded);
|
||||
nv3_color_expanded_t nv3_render_expand_color(uint32_t color, nv3_grobj_t grobj); // Convert a colour to full RGB10 format from the current working format.
|
||||
uint32_t nv3_render_downconvert_color(nv3_grobj_t grobj, nv3_color_expanded_t color); // Convert a colour from the current working format to RGB10 format.
|
||||
|
||||
/* ROP */
|
||||
uint8_t nv3_render_translate_nvrop(nv3_grobj_t grobj, uint32_t rop);
|
||||
|
||||
/* Pattern */
|
||||
void nv3_render_set_pattern_color(nv3_color_expanded_t pattern_colour, bool use_color1);
|
||||
|
||||
|
||||
@@ -607,24 +607,58 @@ extern const device_config_t nv3t_config[]; // Confi
|
||||
#define NV3_PGRAPH_INTR_EN_0 0x400140 // Interrupt Control for PGRAPH #1
|
||||
//todo: add what this does
|
||||
#define NV3_PGRAPH_INTR_EN_1 0x400144 // Interrupt Control for PGRAPH #2 (it can receive two at onc)
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH 0x400180 // Holds the current PGRAPH context, switched by context switching
|
||||
#define NV3_PGRAPH_CTX_SWITCH 0x400180 // Holds the current PGRAPH context, switched by context switching
|
||||
|
||||
/* Contextual information for pgraph */
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_COLOR_FORMAT 2 // Holds the current color format used for drawing operations.
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_ALPHA 3 // Holds a boolean if alpha transparency is currently enabled in drawing operations.
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_MONO_FORMAT 8 // Holds the current color format used for monochome drawing operations.
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_DAC_BYPASS 9 // Holds if PRAMDAC should be bypassed, and an external DAC drawn.
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_Z_WRITE 12 // Holds if we should write back to the zbuffer.
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_CHROMA_KEY 13 // Holds the current chroma mask used for drawing operations.
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_PLANE_MASK 14 // Holds the current plane mask used for drawing operations.
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_USER_CLIP 15 // Holds the user-specified clipping information used for drawing operations.
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_SRC_BUFFER 16 // Holds the buffer ID used for drawing operation (i.e. which bpixel/bpitch/boffset index to use)
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER0_ENABLED 20 // Holds a boolean indicating if buffer 0 can be used as the destination for a drawing operation.
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER1_ENABLED 21 // Holds a boolean indicating if buffer 1 can be used as the destination for a drawing operation.
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER2_ENABLED 22 // Holds a boolean indicating if buffer 2 can be used as the destination for a drawing operation.
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER3_ENABLED 23 // Holds a boolean indicating if buffer 3 can be used as the destination for a drawing operation.
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_PATCH_CONFIG 24 // Something to do with an operation to do during a patchcord?
|
||||
#define NV3_PGRAPH_CONTEXT_SWITCH_VOLATILE 31 // HUH
|
||||
#define NV3_PGRAPH_CTX_SWITCH_COLOR_FORMAT 0 // Holds the current color format used for drawing operations.
|
||||
#define NV3_PGRAPH_CTX_SWITCH_ALPHA 3 // Holds a boolean indicating in if alpha transparency is currently enabled in drawing operations.
|
||||
#define NV3_PGRAPH_CTX_SWITCH_MONO_FORMAT 8 // Holds the current color format used for monochome drawing operations.
|
||||
#define NV3_PGRAPH_CTX_SWITCH_DAC_BYPASS 9 // Holds if PRAMDAC should be bypassed, and an external DAC drawn.
|
||||
#define NV3_PGRAPH_CTX_SWITCH_Z_WRITE 12 // Holds if we should write back to the zbuffer.
|
||||
#define NV3_PGRAPH_CTX_SWITCH_CHROMA_KEY 13 // Holds the current chroma mask used for drawing operations.
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PLANE_MASK 14 // Holds the current plane mask used for drawing operations.
|
||||
#define NV3_PGRAPH_CTX_SWITCH_USER_CLIP 15 // Holds the user-specified clipping information used for drawing operations.
|
||||
#define NV3_PGRAPH_CTX_SWITCH_SRC_BUFFER 16 // Holds the buffer ID used for drawing operation (i.e. which bpixel/bpitch/boffset index to use)
|
||||
#define NV3_PGRAPH_CTX_SWITCH_DST_BUFFER0_ENABLED 20 // Holds a boolean indicating if buffer 0 can be used as the destination for a drawing operation.
|
||||
#define NV3_PGRAPH_CTX_SWITCH_DST_BUFFER1_ENABLED 21 // Holds a boolean indicating if buffer 1 can be used as the destination for a drawing operation.
|
||||
#define NV3_PGRAPH_CTX_SWITCH_DST_BUFFER2_ENABLED 22 // Holds a boolean indicating if buffer 2 can be used as the destination for a drawing operation.
|
||||
#define NV3_PGRAPH_CTX_SWITCH_DST_BUFFER3_ENABLED 23 // Holds a boolean indicating if buffer 3 can be used as the destination for a drawing operation.
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG 24 // ROP type
|
||||
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_RSVD0 0x0 // Reserved
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_DST_DST_SRC 0x1
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_DST_SRC_DST 0x2
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_DST_SRC_SRC 0x3
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_DST_DST 0x4
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_DST_SRC 0x5
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_SRC_DST 0x6
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_SRC_SRC0 0x7
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_SRC_SRC1 0x8
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_SRC_PAT 0x9
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_PAT_SRC 0xA
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_PAT_PAT 0xB
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_SRC_SRC 0xC
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_SRC_PAT 0xD
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_PAT_SRC 0xE
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_RSVD1 0xF
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_SRC_DST 0x10
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_DST_SRC 0x11
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_PAT_DST 0x12
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_DST_PAT 0x13
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_DST_PAT_SRC 0x14
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_DST_SRC_PAT 0x15
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_RSVD2 0x16
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_BYPASS 0x17 // Ignore
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD0 0x18
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_SRC_DST 0x19
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_DST_SRC 0x1A
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD1 0x1B
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD2 0x1C
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_SRC 0x1D
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD3 0x1E
|
||||
#define NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD4 0x1F
|
||||
|
||||
#define NV3_PGRAPH_CTX_SWITCH_VOLATILE 31 // HUH
|
||||
|
||||
#define NV3_PGRAPH_CONTEXT_CONTROL 0x400190 // DMA context control
|
||||
#define NV3_PGRAPH_CONTEXT_USER 0x400194 // Current DMA context state, may rename
|
||||
@@ -1166,10 +1200,10 @@ typedef struct nv3_pramdac_s
|
||||
} nv3_pramdac_t;
|
||||
|
||||
/* Holds DMA channel context information */
|
||||
typedef struct nv3_pgraph_context_switch_s
|
||||
typedef struct NV3_PGRAPH_CTX_SWITCH_s
|
||||
{
|
||||
/* TODO */
|
||||
} nv3_pgraph_context_switch_t;
|
||||
} NV3_PGRAPH_CTX_SWITCH_t;
|
||||
|
||||
typedef struct nv3_pgraph_context_control_s
|
||||
{
|
||||
@@ -1251,10 +1285,10 @@ typedef enum nv3_pgraph_bpixel_format_e
|
||||
|
||||
typedef enum nv3_pgraph_destination_buffer_e
|
||||
{
|
||||
pgraph_dest_buffer0 = (1 << NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER0_ENABLED),
|
||||
pgraph_dest_buffer1 = (1 << NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER1_ENABLED),
|
||||
pgraph_dest_buffer2 = (1 << NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER2_ENABLED),
|
||||
pgraph_dest_buffer3 = (1 << NV3_PGRAPH_CONTEXT_SWITCH_DST_BUFFER3_ENABLED),
|
||||
pgraph_dest_buffer0 = (1 << NV3_PGRAPH_CTX_SWITCH_DST_BUFFER0_ENABLED),
|
||||
pgraph_dest_buffer1 = (1 << NV3_PGRAPH_CTX_SWITCH_DST_BUFFER1_ENABLED),
|
||||
pgraph_dest_buffer2 = (1 << NV3_PGRAPH_CTX_SWITCH_DST_BUFFER2_ENABLED),
|
||||
pgraph_dest_buffer3 = (1 << NV3_PGRAPH_CTX_SWITCH_DST_BUFFER3_ENABLED),
|
||||
} nv3_pgraph_destination_buffer;
|
||||
|
||||
// Graphics Subsystem
|
||||
@@ -1273,7 +1307,7 @@ typedef struct nv3_pgraph_s
|
||||
|
||||
uint32_t context_switch; // TODO: Make this a struct, it's just going to be enormous lol.
|
||||
nv3_pgraph_context_control_t context_control;
|
||||
nv3_pgraph_context_switch_t context_user_submit;
|
||||
NV3_PGRAPH_CTX_SWITCH_t context_user_submit;
|
||||
nv3_pgraph_context_user_t context_user;
|
||||
uint32_t context_cache[NV3_PGRAPH_CONTEXT_CACHE_SIZE]; // DMA context cache (nv3_pgraph_context_user_t array?)
|
||||
|
||||
|
||||
@@ -17,4 +17,7 @@
|
||||
|
||||
|
||||
/* ROP */
|
||||
|
||||
#define VIDEO_ROP_SRC_COPY 0xCC
|
||||
|
||||
int32_t video_rop_gdi_ternary(int32_t rop, int32_t src, int32_t dst, int32_t pattern);
|
||||
@@ -31,7 +31,7 @@
|
||||
void nv3_class_01c_method(uint32_t param, uint32_t method_id, nv3_ramin_context_t context, nv3_grobj_t grobj)
|
||||
{
|
||||
/* We need this for a lot of methods, so may as well store it here. */
|
||||
uint32_t src_buffer_id = (grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_SRC_BUFFER) & 0x03;
|
||||
uint32_t src_buffer_id = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_SRC_BUFFER) & 0x03;
|
||||
|
||||
|
||||
switch (method_id)
|
||||
|
||||
@@ -108,11 +108,11 @@ uint32_t nv3_mmio_arbitrate_read(uint32_t address)
|
||||
else
|
||||
{
|
||||
//nvplay stuff
|
||||
#ifdef ENABLE_NV_LOG_ULTRA
|
||||
warning("MMIO read arbitration failed, INVALID address NOT mapped to any GPU subsystem 0x%08x [returning unmapped pattern]\n", address);
|
||||
#else
|
||||
//#ifdef ENABLE_NV_LOG_ULTRA
|
||||
//warning("MMIO read arbitration failed, INVALID address NOT mapped to any GPU subsystem 0x%08x [returning unmapped pattern]\n", address);
|
||||
//#else
|
||||
nv_log("MMIO read arbitration failed, INVALID address NOT mapped to any GPU subsystem 0x%08x [returning unmapped pattern]\n", address);
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
// The real hardware returns a garbage pattern
|
||||
return 0x00;
|
||||
@@ -181,11 +181,11 @@ void nv3_mmio_arbitrate_write(uint32_t address, uint32_t value)
|
||||
else
|
||||
{
|
||||
//nvplay stuff
|
||||
#ifdef ENABLE_NV_LOG_ULTRA
|
||||
warning("MMIO write arbitration failed, INVALID address NOT mapped to any GPU subsystem 0x%08x [returning 0x00]\n", address);
|
||||
#else
|
||||
//#ifdef ENABLE_NV_LOG_ULTRA
|
||||
//warning("MMIO write arbitration failed, INVALID address NOT mapped to any GPU subsystem 0x%08x [returning 0x00]\n", address);
|
||||
//#else
|
||||
nv_log("MMIO write arbitration failed, INVALID address NOT mapped to any GPU subsystem 0x%08x [returning 0x00]\n", address);
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -121,12 +121,12 @@ uint32_t nv3_s2sb_line_buffer[NV3_MAX_HORIZONTAL_SIZE*NV3_MAX_VERTICAL_SIZE] = {
|
||||
|
||||
void nv3_render_blit_screen2screen_for_buffer(nv3_grobj_t grobj, uint32_t dst_buffer)
|
||||
{
|
||||
if (nv3->pgraph.blit.size.x < NV3_MAX_HORIZONTAL_SIZE
|
||||
if (nv3->pgraph.blit.size.x < NV3_MAX_HORIZONTAL_SIZE
|
||||
&& nv3->pgraph.blit.size.y < NV3_MAX_VERTICAL_SIZE)
|
||||
memset(&nv3_s2sb_line_buffer, 0x00, (sizeof(uint32_t) * nv3->pgraph.blit.size.y) * (sizeof(uint32_t) * nv3->pgraph.blit.size.x));
|
||||
|
||||
/* First calculate our source and destination buffer */
|
||||
uint32_t src_buffer = (grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_SRC_BUFFER) & 0x03;
|
||||
uint32_t src_buffer = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_SRC_BUFFER) & 0x03;
|
||||
|
||||
nv3_coord_16_t in_position = nv3->pgraph.blit.point_in;
|
||||
nv3_coord_16_t out_position = nv3->pgraph.blit.point_out;
|
||||
|
||||
@@ -44,7 +44,7 @@ nv3_color_expanded_t nv3_render_expand_color(uint32_t color, nv3_grobj_t grobj)
|
||||
// grobj0 = seems to share the format of PGRAPH_CONTEXT_SWITCH register.
|
||||
|
||||
uint8_t format = (grobj.grobj_0 & 0x07);
|
||||
bool alpha_enabled = (grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_ALPHA) & 0x01;
|
||||
bool alpha_enabled = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_ALPHA) & 0x01;
|
||||
|
||||
nv3_color_expanded_t color_final;
|
||||
// set the pixel format
|
||||
@@ -119,7 +119,7 @@ nv3_color_expanded_t nv3_render_expand_color(uint32_t color, nv3_grobj_t grobj)
|
||||
uint32_t nv3_render_downconvert_color(nv3_grobj_t grobj, nv3_color_expanded_t color)
|
||||
{
|
||||
uint8_t format = (grobj.grobj_0 & 0x07);
|
||||
bool alpha_enabled = (grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_ALPHA) & 0x01;
|
||||
bool alpha_enabled = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_ALPHA) & 0x01;
|
||||
|
||||
nv_log_verbose_only("Downconverting Colour 0x%08x using pgraph_pixel_format 0x%x alpha enabled=%d\n", color, format, alpha_enabled);
|
||||
|
||||
@@ -168,7 +168,7 @@ uint32_t nv3_render_downconvert_color(nv3_grobj_t grobj, nv3_color_expanded_t co
|
||||
/* Runs the chroma key/color key test */
|
||||
bool nv3_render_chroma_test(uint32_t color, nv3_grobj_t grobj)
|
||||
{
|
||||
bool chroma_enabled = ((grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_CHROMA_KEY) & 0x01);
|
||||
bool chroma_enabled = ((grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_CHROMA_KEY) & 0x01);
|
||||
|
||||
if (!chroma_enabled)
|
||||
return true;
|
||||
@@ -239,7 +239,7 @@ uint32_t nv3_render_get_vram_address(nv3_coord_16_t position, nv3_grobj_t grobj)
|
||||
{
|
||||
uint32_t vram_x = position.x;
|
||||
uint32_t vram_y = position.y;
|
||||
uint32_t current_buffer = (grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_SRC_BUFFER) & 0x03;
|
||||
uint32_t current_buffer = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_SRC_BUFFER) & 0x03;
|
||||
|
||||
uint32_t framebuffer_bpp = nv3->nvbase.svga.bpp;
|
||||
|
||||
@@ -359,7 +359,7 @@ uint32_t nv3_render_read_pixel_32(nv3_coord_16_t position, nv3_grobj_t grobj)
|
||||
|
||||
void nv3_render_write_pixel_to_buffer(nv3_coord_16_t position, uint32_t color, nv3_grobj_t grobj, uint32_t buffer)
|
||||
{
|
||||
bool alpha_enabled = (grobj.grobj_0 >> NV3_PGRAPH_CONTEXT_SWITCH_ALPHA) & 0x01;
|
||||
bool alpha_enabled = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_ALPHA) & 0x01;
|
||||
|
||||
int32_t clip_end_x = nv3->pgraph.clip_start.x + nv3->pgraph.clip_size.x;
|
||||
int32_t clip_end_y = nv3->pgraph.clip_start.y + nv3->pgraph.clip_size.y;
|
||||
@@ -428,6 +428,9 @@ void nv3_render_write_pixel_to_buffer(nv3_coord_16_t position, uint32_t color, n
|
||||
We use the pixel format of the destination buffer to achieve this (thanks frostbite2000)
|
||||
*/
|
||||
|
||||
// translate the patch config to GDI rop
|
||||
uint32_t final_rop = nv3_render_translate_nvrop(grobj, nv3->pgraph.rop);
|
||||
|
||||
uint32_t destination_format = (nv3->pgraph.bpixel[buffer]) & 0x03;
|
||||
|
||||
switch (destination_format)
|
||||
@@ -435,7 +438,7 @@ void nv3_render_write_pixel_to_buffer(nv3_coord_16_t position, uint32_t color, n
|
||||
case bpixel_fmt_8bit:
|
||||
rop_src = color & 0xFF;
|
||||
rop_dst = nv3->nvbase.svga.vram[pixel_addr_vram];
|
||||
nv3->nvbase.svga.vram[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, rop_src, rop_dst, rop_pattern) & 0xFF;
|
||||
nv3->nvbase.svga.vram[pixel_addr_vram] = video_rop_gdi_ternary(final_rop, rop_src, rop_dst, rop_pattern) & 0xFF;
|
||||
|
||||
nv3->nvbase.svga.changedvram[pixel_addr_vram >> 12] = changeframecount;
|
||||
|
||||
@@ -464,7 +467,7 @@ void nv3_render_write_pixel_to_buffer(nv3_coord_16_t position, uint32_t color, n
|
||||
|
||||
rop_dst = vram_16[pixel_addr_vram];
|
||||
|
||||
vram_16[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, rop_src, rop_dst, rop_pattern) & 0xFFFF;
|
||||
vram_16[pixel_addr_vram] = video_rop_gdi_ternary(final_rop, rop_src, rop_dst, rop_pattern) & 0xFFFF;
|
||||
|
||||
nv3->nvbase.svga.changedvram[pixel_addr_vram >> 11] = changeframecount;
|
||||
|
||||
@@ -477,7 +480,7 @@ void nv3_render_write_pixel_to_buffer(nv3_coord_16_t position, uint32_t color, n
|
||||
|
||||
rop_src = color;
|
||||
rop_dst = vram_32[pixel_addr_vram];
|
||||
vram_32[pixel_addr_vram] = video_rop_gdi_ternary(nv3->pgraph.rop, rop_src, rop_dst, rop_pattern);
|
||||
vram_32[pixel_addr_vram] = video_rop_gdi_ternary(final_rop, rop_src, rop_dst, rop_pattern);
|
||||
|
||||
nv3->nvbase.svga.changedvram[pixel_addr_vram >> 10] = changeframecount;
|
||||
|
||||
@@ -789,3 +792,100 @@ void nv3_render_32bpp(uint32_t vram_start, nv3_coord_16_t screen_size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Translate an "NV-ROP" into a GDI Ternary ROP
|
||||
uint8_t nv3_render_translate_nvrop(nv3_grobj_t grobj, uint32_t rop)
|
||||
{
|
||||
// Credit to envytools for this function:
|
||||
// https://github.com/envytools/envytools/blob/f102b82381f3f11cee113d16374c87091db039d9/nvhw/pgraph.c
|
||||
// How does one even go about reverse engineering this (I'm sure the behaviour is simpler when you don't have to translate this but...) Marcelina is a legend.
|
||||
|
||||
uint32_t patch_config_rop = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG) & 0x1F;
|
||||
|
||||
/* || patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_RSVD0*/
|
||||
|
||||
// TODO: Blending
|
||||
if (patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_BYPASS) // 0x00 is used for "nothing here" it seems.
|
||||
return VIDEO_ROP_SRC_COPY;
|
||||
|
||||
uint8_t res = 0;
|
||||
|
||||
int32_t swizzle[3];
|
||||
|
||||
if (patch_config_rop < 8) {
|
||||
swizzle[0] = patch_config_rop >> 0 & 1;
|
||||
swizzle[1] = patch_config_rop >> 1 & 1;
|
||||
swizzle[2] = patch_config_rop >> 2 & 1;
|
||||
} else if (patch_config_rop < 0x10) {
|
||||
swizzle[0] = (patch_config_rop >> 0 & 1) + 1;
|
||||
swizzle[1] = (patch_config_rop >> 1 & 1) + 1;
|
||||
swizzle[2] = (patch_config_rop >> 2 & 1) + 1;
|
||||
} else if (patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_SRC_DST) {
|
||||
swizzle[0] = 0, swizzle[1] = 1, swizzle[2] = 2;
|
||||
} else if (patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_DST_SRC) {
|
||||
swizzle[0] = 1, swizzle[1] = 0, swizzle[2] = 2;
|
||||
} else if (patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_PAT_DST) {
|
||||
swizzle[0] = 0, swizzle[1] = 2, swizzle[2] = 1;
|
||||
} else if (patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_DST_PAT) {
|
||||
swizzle[0] = 2, swizzle[1] = 0, swizzle[2] = 1;
|
||||
} else if (patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_DST_PAT_SRC) {
|
||||
swizzle[0] = 1, swizzle[1] = 2, swizzle[2] = 0;
|
||||
} else if (patch_config_rop == NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_DST_SRC_PAT) {
|
||||
swizzle[0] = 2, swizzle[1] = 1, swizzle[2] = 0;
|
||||
} else {
|
||||
warning("NV3 ROP: Invalid patch configuration %02x!", rop);
|
||||
}
|
||||
if (patch_config_rop == 0) {
|
||||
if (rop & 0x01)
|
||||
res |= 0x11;
|
||||
if (rop & 0x16)
|
||||
res |= 0x44;
|
||||
if (rop & 0x68)
|
||||
res |= 0x22;
|
||||
if (rop & 0x80)
|
||||
res |= 0x88;
|
||||
} else if (patch_config_rop == 0xf) {
|
||||
if (rop & 0x01)
|
||||
res |= 0x03;
|
||||
if (rop & 0x16)
|
||||
res |= 0x0c;
|
||||
if (rop & 0x68)
|
||||
res |= 0x30;
|
||||
if (rop & 0x80)
|
||||
res |= 0xc0;
|
||||
} else {
|
||||
int32_t i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
int32_t s0 = i >> swizzle[0] & 1;
|
||||
int32_t s1 = i >> swizzle[1] & 1;
|
||||
int32_t s2 = i >> swizzle[2] & 1;
|
||||
int32_t s = s2 << 2 | s1 << 1 | s0;
|
||||
if (rop >> s & 1)
|
||||
res |= 1 << i;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
||||
/*
|
||||
uint32_t patch_config = (grobj.grobj_0 >> NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG) & 0x1F;
|
||||
|
||||
// Wtf do these even do?
|
||||
switch (patch_config)
|
||||
{
|
||||
// don't do anything
|
||||
case NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_SRC_BYPASS:
|
||||
case NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_RSVD0:
|
||||
case NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_RSVD1:
|
||||
case NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_RSVD2:
|
||||
case NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD0:
|
||||
case NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD1:
|
||||
case NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD2:
|
||||
case NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD3:
|
||||
case NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_BLEND_RSVD4:
|
||||
return src;
|
||||
case NV3_PGRAPH_CTX_SWITCH_PATCH_CONFIG_PAT_SRC_DST: // S2SB
|
||||
break;
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -51,7 +51,7 @@ nv_register_t pgraph_registers[] = {
|
||||
{ NV3_PGRAPH_INTR_EN_0, "PGRAPH Interrupt Enable 0", NULL, NULL },
|
||||
{ NV3_PGRAPH_INTR_1, "PGRAPH Interrupt Status 1", NULL, NULL },
|
||||
{ NV3_PGRAPH_INTR_EN_1, "PGRAPH Interrupt Enable 1", NULL, NULL },
|
||||
{ NV3_PGRAPH_CONTEXT_SWITCH, "PGRAPH DMA Context Switch", NULL, NULL },
|
||||
{ NV3_PGRAPH_CTX_SWITCH, "PGRAPH DMA Context Switch", NULL, NULL },
|
||||
{ NV3_PGRAPH_CONTEXT_CONTROL, "PGRAPH DMA Context Control", NULL, NULL },
|
||||
{ NV3_PGRAPH_CONTEXT_USER, "PGRAPH DMA Context User", NULL, NULL },
|
||||
//{ NV3_PGRAPH_CONTEXT_CACHE(0), "PGRAPH DMA Context Cache", NULL, NULL },
|
||||
@@ -156,7 +156,7 @@ uint32_t nv3_pgraph_read(uint32_t address)
|
||||
// In the future, these will most likely have their own functions...
|
||||
|
||||
// Context Swithcing (THIS IS CONTROLLED BY PFIFO!)
|
||||
case NV3_PGRAPH_CONTEXT_SWITCH:
|
||||
case NV3_PGRAPH_CTX_SWITCH:
|
||||
ret = nv3->pgraph.context_switch;
|
||||
break;
|
||||
case NV3_PGRAPH_CONTEXT_CONTROL:
|
||||
@@ -359,7 +359,7 @@ void nv3_pgraph_write(uint32_t address, uint32_t value)
|
||||
// In the future, these will most likely have their own functions...
|
||||
|
||||
// Context Swithcing (THIS IS CONTROLLED BY PFIFO!)
|
||||
case NV3_PGRAPH_CONTEXT_SWITCH:
|
||||
case NV3_PGRAPH_CTX_SWITCH:
|
||||
nv3->pgraph.context_switch = value;
|
||||
break;
|
||||
case NV3_PGRAPH_CONTEXT_CONTROL:
|
||||
@@ -625,7 +625,7 @@ void nv3_pgraph_submit(uint32_t param, uint16_t method, uint8_t channel, uint8_t
|
||||
switch (method)
|
||||
{
|
||||
default:
|
||||
// Object Method orchestration
|
||||
// Object Method arbitration
|
||||
nv3_pgraph_arbitrate_method(param, method, channel, subchannel, class_id, context);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user