diff --git a/doc/nvidia_notes/B = BUFFER. REMEMBER THESE!!!.txt b/doc/nvidia_notes/B = BUFFER. REMEMBER THESE!!!.txt new file mode 100644 index 000000000..e8f183240 --- /dev/null +++ b/doc/nvidia_notes/B = BUFFER. REMEMBER THESE!!!.txt @@ -0,0 +1 @@ +B = BUFFER. REMEMBER THESE!!! \ No newline at end of file diff --git a/doc/nvidia_notes/NV128.xlsx b/doc/nvidia_notes/NV128.xlsx index e293a97eb..1cb14fdcc 100644 Binary files a/doc/nvidia_notes/NV128.xlsx and b/doc/nvidia_notes/NV128.xlsx differ diff --git a/doc/nvidia_notes/NV3 DMA Engine.txt b/doc/nvidia_notes/NV3 DMA Engine.txt index fe2d61508..380e0281e 100644 --- a/doc/nvidia_notes/NV3 DMA Engine.txt +++ b/doc/nvidia_notes/NV3 DMA Engine.txt @@ -49,3 +49,6 @@ call of mthdCreate for ***DRIVER*** CLASS ID: a7b44, check ptr + + + diff --git a/src/include/86box/nv/classes/vid_nv3_classes.h b/src/include/86box/nv/classes/vid_nv3_classes.h index 39c03b295..e1458671e 100644 --- a/src/include/86box/nv/classes/vid_nv3_classes.h +++ b/src/include/86box/nv/classes/vid_nv3_classes.h @@ -1145,17 +1145,17 @@ typedef enum nv3_object_class_01C_pixel_format_e { // Y8P4 // 12-bits (Y8 - Planar YUV 8 bits (Y value only), 4 bits of indexed colour too? - nv3_m2mt_pixel_format_le_y8_p4 = 0x1010000, + nv3_image_in_memory_pixel_format_le_y8_p4 = 0x1010000, // Y16P2 // 16-bits (Y16) - Planar YUV 16 bits (Y value only), 2 bits of indexed colour too? - nv3_m2mt_pixel_format_le_y16_p2 = 0x1010101, + nv3_image_in_memory_pixel_format_le_y16_p2 = 0x1010101, /* 1 unused bit, 555 15-bit format, p2(?) */ - nv3_m2mt_pixel_format_x1r5g5b5_p2 = 0x1000000, + nv3_image_in_memory_pixel_format_x1r5g5b5_p2 = 0x1000000, // X8G8B8R8, 24-bit colour (or 24-bit colour with alpha) - nv3_m2mt_pixel_format_x8g8b8r8 = 0x1, + nv3_image_in_memory_pixel_format_x8g8b8r8 = 0x1, } nv3_object_class_01C_pixel_format; typedef struct nv3_object_class_01C diff --git a/src/include/86box/nv/vid_nv3.h b/src/include/86box/nv/vid_nv3.h index fb080f1cd..49bc8c64e 100644 --- a/src/include/86box/nv/vid_nv3.h +++ b/src/include/86box/nv/vid_nv3.h @@ -14,7 +14,7 @@ * Also check the doc folder for some more notres * * vid_nv3.h: NV3 Architecture Hardware Reference (open-source) - * Last updated: 13 March 2025 (STILL WORKING ON IT!!!) + * Last updated: 17 March 2025 (STILL WORKING ON IT!!!) * * Authors: Connor Hyde * @@ -454,6 +454,8 @@ extern const device_config_t nv3_config[]; #define NV3_PGRAPH_START 0x400000 // Scene graph for 2d/3d rendering...the most important part // PGRAPH Core +#define NV3_PGRAPH_MAX_BUFFERS 4 + // For these debug registers, 0=Disabled, 1=Enabled // Debug 0: General @@ -532,7 +534,25 @@ extern const device_config_t nv3_config[]; #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 // DMA context switcher +#define NV3_PGRAPH_CONTEXT_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_CONTEXT_CONTROL 0x400190 // DMA context control #define NV3_PGRAPH_CONTEXT_USER 0x400194 // Current DMA context state, may rename #define NV3_PGRAPH_CONTEXT_CACHE(i) 0x4001A0+(i*4) // Context Cache @@ -1082,6 +1102,23 @@ typedef struct nv3_pgraph_status_s } nv3_pgraph_status_t; +/* All of this B* stuff is registers at 400630..40065c and 4006a8 in reality, easier to implement it like this + BPixel = Internal Binary Representation of the pixel within the architecture +*/ +#define NV3_BPIXEL_FORMAT 0 +#define NV3_BPIXEL_FORMAT_IS_VALID 2 + +typedef enum nv3_pgraph_bpixel_format_e +{ + // Y16 + bpixel_fmt_y16 = 0, + // 8-bit colour + bpixel_fmt_8bit = 1, + // 16-bit colour + bpixel_fmt_16bit = 2, + // 32-bit colour (BGRA/ARGB) + bpixel_fmt_32bit = 3, +} nv3_pgraph_bpixel_format; // Graphics Subsystem typedef struct nv3_pgraph_s @@ -1126,14 +1163,19 @@ typedef struct nv3_pgraph_s uint32_t beta_factor; nv3_pgraph_dma_settings_t dma_settings; uint8_t rop; // Current GDI Ternary Render Operation + // SURFACE STUFF - PGRAPH CAN OPERATE ON 4 SURFACES/BUFFERS AT A TIME + uint32_t boffset[NV3_PGRAPH_MAX_BUFFERS]; // 22-bit linear VRAM offset for the start of a surface. + uint16_t bpitch[NV3_PGRAPH_MAX_BUFFERS]; // 12-bit linear VRAM offset for the pitch of a surfac.e + uint32_t bpixel[NV3_PGRAPH_MAX_BUFFERS]; // Pixel format for each possible surfaces. + // CLIP nv3_pgraph_clip_misc_settings_t clip_misc_settings; nv3_notifier_t notifier; nv3_position_16_bigy_t clip0_min; nv3_position_16_bigy_t clip0_max; nv3_position_16_bigy_t clip1_min; nv3_position_16_bigy_t clip1_max; - uint32_t fifo_access; - nv3_pgraph_status_t status; + uint32_t fifo_access; // Determines if PGRAPH can access PFIFO. + nv3_pgraph_status_t status; // Current status of the 3D engine. uint32_t trapped_address; uint32_t trapped_data; uint32_t trapped_instance; diff --git a/src/include/86box/utils/video_stdlib.h b/src/include/86box/utils/video_stdlib.h index f8e2ed5af..3605631f1 100644 --- a/src/include/86box/utils/video_stdlib.h +++ b/src/include/86box/utils/video_stdlib.h @@ -17,4 +17,4 @@ /* ROP */ -int32_t video_rop_gdi_ternary(int32_t rop, int32_t dst, int32_t pattern, int32_t src, int32_t out); \ No newline at end of file +int32_t video_rop_gdi_ternary(int32_t rop, int32_t dst, int32_t pattern, int32_t src); \ No newline at end of file diff --git a/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c b/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c index b42583f7a..547ffc441 100644 --- a/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c +++ b/src/video/nv/nv3/classes/nv3_class_01c_image_in_memory.c @@ -30,19 +30,52 @@ 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 = (nv3->pgraph.context_switch >> NV3_PGRAPH_CONTEXT_SWITCH_SRC_BUFFER) & 0x03; + switch (method_id) { + /* Color format of the image */ case NV3_IMAGE_IN_MEMORY_COLOR_FORMAT: + // convert to how the bpixel registers represent surface + uint32_t real_format = 1; + + /* TODO: THIS CODE MIGHT BE NONSENSE + Convert between different internal representations of the pixel format, because Nvidia says: I WANT TO MAKE YOUR LIFE PAIN. + */ + switch (param) + { + case nv3_image_in_memory_pixel_format_x8g8b8r8: + real_format = 3; //32bit + // no change + break; + case nv3_image_in_memory_pixel_format_x1r5g5b5_p2: + real_format = 2; + break; + case nv3_image_in_memory_pixel_format_le_y16_p2: + real_format = 0; + break; + } + + /* Set the format */ + + nv3->pgraph.bpixel[src_buffer_id] = ((real_format & 0x03) | NV3_BPIXEL_FORMAT_IS_VALID); + nv_log("Image in Memory BUF%d COLOR_FORMAT=0x%04x", src_buffer_id, param); + break; /* Pitch - length between scanlines */ case NV3_IMAGE_IN_MEMORY_PITCH: + nv3->pgraph.image_in_memory.pitch = param & 0x1FF0; - nv_log("Image in Memory PITCH=0x%04x", nv3->pgraph.image_in_memory.pitch); + nv3->pgraph.bpitch[src_buffer_id] = param & 0x1FF0; // 12:0 + + nv_log("Image in Memory BUFL%d PITCH=0x%04x", src_buffer_id, nv3->pgraph.bpitch[src_buffer_id]); break; /* Byte offset in GPU VRAM of top left pixel (22:0) */ case NV3_IMAGE_IN_MEMORY_TOP_LEFT_OFFSET: - nv3->pgraph.image_in_memory.linear_address = param & ((1 << NV3_IMAGE_IN_MEMORY_TOP_LEFT_OFFSET_END) - 0x10); - nv_log("Image in Memory TOP_LEFT_OFFSET=0x%08x", nv3->pgraph.image_in_memory.linear_address); + nv3->pgraph.boffset[src_buffer_id] = param & ((1 << NV3_IMAGE_IN_MEMORY_TOP_LEFT_OFFSET_END) - 0x10); + + nv_log("Image in Memory BUF%d TOP_LEFT_OFFSET=0x%08x", src_buffer_id, nv3->pgraph.image_in_memory.linear_address); break; default: nv_log("%s: Invalid or Unimplemented method 0x%04x", nv3_class_names[context.class_id & 0x1F], method_id); diff --git a/src/video/nv/nv3/render/nv3_render_core.c b/src/video/nv/nv3/render/nv3_render_core.c index 426cf2c9d..8b5771f36 100644 --- a/src/video/nv/nv3/render/nv3_render_core.c +++ b/src/video/nv/nv3/render/nv3_render_core.c @@ -27,11 +27,10 @@ #include <86box/video.h> #include <86box/nv/vid_nv.h> #include <86box/nv/vid_nv3.h> -#include <86box/nv/classes/vid_nv3_classes.h> #include <86box/utils/video_stdlib.h> /* Render Core: Performs a ROP */ -void nv3_perform_rop(uint32_t src, uint32_t dst, uint32_t pattern, uint32_t pen, nv3_render_operation_type rop) +uint32_t nv3_perform_rop(uint32_t src, uint32_t dst, uint32_t pattern, nv3_render_operation_type rop) { return video_rop_gdi_ternary(rop, dst, pattern, src); } \ No newline at end of file