Partially fix S2SB. Makes Windows 95 behave a lot better!

This commit is contained in:
starfrost013
2025-08-12 20:57:36 +01:00
parent 21299c5ed1
commit d470c90679
8 changed files with 186 additions and 46 deletions

View File

@@ -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);

View File

@@ -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?)

View File

@@ -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);

View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}
*/
}

View File

@@ -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;
}