Implemented a dummy M2MF class implementation until I fully understand it. This is enough to get Windows 9x to display something.

This commit is contained in:
starfrost013
2025-03-29 23:25:15 +00:00
parent 4e01ee82c7
commit 0e16ef5498
4 changed files with 80 additions and 4 deletions

View File

@@ -84,6 +84,8 @@ typedef enum nv3_pgraph_class_e
#define NV3_BETA_FACTOR 0x0300
// Chroma Key
// Can't figure out what this is, used in 9x but certainly software, can't find anywhere...
#define NV3_CHROMA_UNKNOWN_0200 0x0200
#define NV3_CHROMA_KEY 0x0304
// Clip
@@ -114,6 +116,25 @@ typedef enum nv3_pgraph_class_e
#define NV3_RECTANGLE_MAX 16
#define NV3_RECTANGLE_END 0x0480
// M2MF
#define NV3_M2MF_IN_CTXDMA_OFFSET 0x030C
#define NV3_M2MF_OUT_CTXDMA_OFFSET 0x0310
#define NV3_M2MF_IN_PITCH 0x0314
#define NV3_M2MF_OUT_PITCH 0x0318
#define NV3_M2MF_SCANLINE_LENGTH_IN_BYTES 0x031C
#define NV3_M2MF_NUM_SCANLINES 0x0320
#define NV3_M2MF_FORMAT 0x0324
// M2MF formats (IN and OUT ORed together)
#define NV3_M2MF_FORMAT_INPUT_INC_1 0x1
#define NV3_M2MF_FORMAT_INPUT_INC_2 0x2
#define NV3_M2MF_FORMAT_INPUT_INC_4 0x4
#define NV3_M2MF_FORMAT_OUTPUT_INC_1 0x100
#define NV3_M2MF_FORMAT_OUTPUT_INC_2 0x200
#define NV3_M2MF_FORMAT_OUTPUT_INC_4 0x400
#define NV3_M2MF_NOTIFY 0x0328
// blit
#define NV3_BLIT_POSITION_IN 0x0300
#define NV3_BLIT_POSITION_OUT 0x0304
@@ -634,8 +655,7 @@ typedef struct nv3_object_class_00D
uint32_t pitch_out;
uint32_t line_length_in; // Stride?
uint32_t line_count;
uint8_t format_input_bits; // 1 2 or 4 to increment by bits
uint8_t format_output_bits; // 1 2 to 4 to increment by bits
uint8_t format; // input increment 1 2 or 4, output increment 1 2 or 4 (represented by << 8)
uint8_t reserved3[2];
uint32_t buffer_notify; // Notify the Buffedr
uint8_t reserved4[0x1CD3];

View File

@@ -32,10 +32,17 @@ void nv3_class_003_method(uint32_t param, uint32_t method_id, nv3_ramin_context_
{
switch (method_id)
{
case NV3_CHROMA_UNKNOWN_0200:
nv_log("Method Execution: Chroma Unknown 0x0200 0x%08x", param);
nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING);
break;
case NV3_CHROMA_KEY:
nv3_color_expanded_t expanded_color = nv3_render_expand_color(param, grobj);
nv3->pgraph.chroma_key = nv3_render_to_chroma(expanded_color);
nv_log("Method Execution: Chroma = 0x%08x", nv3->pgraph.chroma_key);
break;
default:
warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id);

View File

@@ -192,7 +192,7 @@ void nv3_class_00c_method(uint32_t param, uint32_t method_id, nv3_ramin_context_
return;
}
warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id);
nv_log("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id);
nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING);
break;
}

View File

@@ -32,9 +32,58 @@ void nv3_class_00d_method(uint32_t param, uint32_t method_id, nv3_ramin_context_
{
switch (method_id)
{
case NV3_M2MF_IN_CTXDMA_OFFSET:
nv3->pgraph.m2mf.offset_in = param;
nv_log("Method Execution: M2MF Offset In = 0x%08x", param);
break;
case NV3_M2MF_OUT_CTXDMA_OFFSET:
nv3->pgraph.m2mf.offset_out = param;
nv_log("Method Execution: M2MF Offset Out = 0x%08x", param);
break;
case NV3_M2MF_IN_PITCH:
nv3->pgraph.m2mf.pitch_in = param;
nv_log("Method Execution: M2MF Pitch In = 0x%08x", param);
break;
case NV3_M2MF_OUT_PITCH:
nv3->pgraph.m2mf.pitch_out = param;
nv_log("Method Execution: M2MF Pitch Out = 0x%08x", param);
break;
case NV3_M2MF_SCANLINE_LENGTH_IN_BYTES:
nv3->pgraph.m2mf.line_length_in = param;
nv_log("Method Execution: M2MF Scanline Length in Bytes = 0x%08x", param);
break;
case NV3_M2MF_NUM_SCANLINES:
nv3->pgraph.m2mf.line_count = param;
nv_log("Method Execution: M2MF Num Scanlines = 0x%08x", param);
break;
case NV3_M2MF_FORMAT:
nv3->pgraph.m2mf.format = param;
nv_log("Method Execution: M2MF Format = 0x%08x", param);
break;
case NV3_M2MF_NOTIFY:
/* This is technically its own thing, but I don't know if it's ever a problem with how we've designed it */
if (nv3->pgraph.notify_pending)
{
nv_log("M2MF notification with notify_pending already set. param=0x%08x, method=0x%04x, grobj=0x%08x 0x%08x 0x%08x 0x%08x\n");
nv_log("IF THIS IS A DEBUG BUILD, YOU SHOULD SEE A CONTEXT BELOW");
nv3_debug_ramin_print_context_info(param, context);
nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_DOUBLE_NOTIFY);
// disable
nv3->pgraph.notify_pending = false;
nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_DOUBLE_NOTIFY);
/* may need to disable fifo in this state */
return;
}
nv_log("Method Execution: TODO: ACTUALLY IMPLEMENT M2MF!!!!");
// set a notify as pending.
nv3->pgraph.notifier = param;
nv3->pgraph.notify_pending = true;
break;
default:
warning("%s: Invalid or unimplemented method 0x%04x\n", nv3_class_names[context.class_id & 0x1F], method_id);
nv3_pgraph_interrupt_invalid(NV3_PGRAPH_INTR_1_SOFTWARE_METHOD_PENDING);
return;
break;;
}
}