Define the rest of the object classes.

This commit is contained in:
starfrost013
2025-01-05 00:29:35 +00:00
parent 09fd662928
commit c6f0866509
2 changed files with 548 additions and 18 deletions

View File

@@ -10,7 +10,8 @@
* as well as for later GPUs if they use the same objects.
* Note: These uint32_ts are basically object methods that are being submitted
* They have different names so the user can use them more easily but different versions of the same class can be distinguished
* ALL of these structures HAVE(?) to be a size of exactly 0x2000 bytes because that's what the hashtable expects and they need to actually map
* ALL of these structures HAVE(?) to be a size of exactly 0x2000 bytes because that's what the hashtable expects and they need to actually map into the vram address space
* (they are converted to pointers).
* directly to the PHYSICAL PGRAPH REGISTERS while sitting in RAMHT!!!!.
*
* Also, these class IDs don't relate to the internal architecture of the GPU.
@@ -57,13 +58,22 @@ typedef struct nv3_class_ctx_switch_method_s
} nv3_class_ctx_switch_method_t;
/* 32-bit BGRA format colour for 2D acceleration */
typedef struct nv3_color_32_s
typedef struct nv3_color_bgra_32_s
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
} nv3_color_32_t;
} nv3_color_bgra_32_t;
/* 32-bit ARGB format colour for internal D3D5 stuff */
typedef struct nv3_color_argb_32_s
{
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t a;
} nv3_color_argb_32_t;
/* A4R4G4B4 */
typedef struct nv3_color_16_a4r4g4b4_s
@@ -128,7 +138,7 @@ typedef struct nv3_size_16_s
/* Generic 32-bit colour + 16-bit position */
typedef struct nv3_color_and_position_16_s
{
uint32_t color;
nv3_color_argb_32_t color;
nv3_position_16_t points;
} nv3_color_and_position_16_t;
@@ -248,9 +258,9 @@ typedef struct nv3_object_class_006
uint32_t set_notify; // Set notifier
uint8_t reserved2[0x200];
uint32_t shape; // 0 = 8x8, 1 = 64x1, 2 = 1x64
uint32_t color0; // Some 32-bit format (BGRA?)
uint32_t color1; // BGRA?
uint32_t pattern[2]; // BGRA?
uint32_t color0; // Some 32-bit format (argb?)
uint32_t color1; // argb?
uint32_t pattern[2]; // argb?
uint8_t reserved3[0x1CDF]; // needs to be 0x2000 bytes
} nv3_pattern_t;
@@ -262,11 +272,11 @@ typedef struct nv3_object_class_006
*/
typedef struct nv3_object_class_007
{
nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch)
nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch)
uint8_t reserved[0x100];
uint32_t set_notify; // Set notifier
uint32_t set_notify; // Set notifier
uint8_t reserved2[0x1FC];
uint32_t color; // The colour
nv3_color_argb_32_t color; // The colour
uint8_t reserved3[0xF8];
nv3_position_16_t position[16];
nv3_size_16_t size[16];
@@ -277,9 +287,8 @@ typedef struct nv3_object_class_007
/* In case your points weren't colourful enough */
typedef struct nv3_object_class_008_cpoint_s
{
uint32_t color;
nv3_position_16_t position;
nv3_color_argb_32_t color; // BGRA-format 32-bit color
nv3_position_16_t position; //
} nv3_object_class_008_cpoint_t;
/*
@@ -294,7 +303,7 @@ typedef struct nv3_object_class_008
uint8_t reserved[0x100];
uint32_t set_notify; // Set notifier
uint8_t reserved2[0x1FC];
uint32_t color; // BGRA?
nv3_color_argb_32_t color; // argb?
nv3_position_16_t point[16]; // Boring points
nv3_position_32_t point32[16]; // Allows you to have points with full 32-bit precision
nv3_object_class_008_cpoint_t cpoint[16]; // Allows you to have c o l o r f u l points!
@@ -334,7 +343,7 @@ typedef struct nv3_object_class_009
uint8_t reserved[0x100];
uint32_t set_notify; // Set notifier
uint8_t reserved2[0x1FC];
uint32_t color; // BGRA?
nv3_color_argb_32_t color; // argb?
nv3_object_class_009_line_t line[16]; // List of line points (...)
nv3_object_class_009_line32_t line32[8];
nv3_object_class_009_line_t polyline[32];
@@ -358,7 +367,7 @@ typedef struct nv3_object_class_00A
uint8_t reserved[0x100];
uint32_t set_notify; // Set notifier
uint8_t reserved2[0x1FC];
uint32_t color; // BGRA?
nv3_color_argb_32_t color; // argb?
nv3_object_class_009_line_t line[16]; // List of line points (...)
nv3_object_class_009_line32_t line32[8];
nv3_object_class_009_line_t polyline[32];
@@ -381,7 +390,7 @@ typedef struct nv3_object_class_00B
uint8_t reserved[0x100];
uint32_t set_notify; // Set notifier
uint8_t reserved2[0x1FC];
uint32_t color; // BGRA?
nv3_color_argb_32_t color; // argb?
uint8_t reserved3[0x8];
// The points of the triangle.
nv3_position_16_t points[3];
@@ -512,6 +521,514 @@ typedef struct nv3_object_class_00E
uint8_t reserved4[0x1BE7]; // pad to 0x2000
} nv3_scaled_image_from_memory_t;
// (0x0F does not exist)
/*
Object Class 0x10 (real hardware)
0x?? (drivers)
Also 0x50 in context IDs.
Represents a blit.
*/
typedef struct nv3_object_class_010
{
nv3_class_ctx_switch_method_t set_notify_ctx_dma;
uint8_t reserved[0x100];
uint32_t set_notify;
uint8_t reserved2[0x1F8];
nv3_position_16_t point_in;
nv3_position_16_t point_out;
nv3_size_16_t size;
uint8_t reserved3[0x1CF3];
} nv3_blit_t;
/*
Object Class 0x11 (real hardware)
0x?? (drivers)
Also 0x51 in context IDs.
Represents an image from the cpu (i guess from system memory)
*/
typedef struct nv3_object_class_011
{
nv3_class_ctx_switch_method_t set_notify_ctx_dma;
uint8_t reserved[0x100];
uint32_t set_notify;
uint8_t reserved2[0x1FC];
nv3_position_16_t point;
nv3_size_16_t size;
nv3_size_16_t size_in;
uint8_t reserved3[0xF0];
nv3_color_argb_32_t color[32]; // The colour to use
uint8_t reserved4[0x1B7F];
} nv3_image_t;
/*
Object Class 0x12 (real hardware)
0x?? (drivers)
Also 0x52 in context IDs.
Bitmap from CPU.
It seems the difference is that an image is colour but a
*/
typedef struct nv3_object_class_012
{
nv3_class_ctx_switch_method_t set_notify_ctx_dma;
uint8_t reserved[0x100];
uint32_t set_notify;
uint8_t reserved2[0x200];
nv3_color_argb_32_t color_0;
nv3_color_argb_32_t color_1;
nv3_position_16_t point; // Top left(?) of the bitmap
nv3_size_16_t size;
nv3_size_16_t size_in;
uint32_t monochrome_bitmap[32];
uint8_t reserved4[0x1B7F];
} nv3_bitmap_t;
// 0x13 doesn't exist
/*
Object Class 0x14 (real hardware)
0x?? (drivers)
Also 0x54 in context IDs.
Image Transfer to Memory
It seems the difference is that an image is colour but a bitmap is b&w
*/
typedef struct nv3_object_class_014
{
nv3_class_ctx_switch_method_t set_notify_ctx_dma;
uint8_t reserved[0x100];
uint32_t set_notify;
uint8_t reserved2[0x200];
nv3_position_16_t point;
nv3_size_16_t size;
uint32_t image_pitch; // bytes per row
uint32_t image_start;
uint8_t reserved3[0x1C37];
} nv3_image_to_memory_t;
/*
Object Class 0x15 (real hardware)
0x?? (drivers)
Also 0x55 in context IDs.
Stretched Image from CPU
Seems to be, by the very large color array, the main class used in 2d acceleration.
*/
typedef struct nv3_object_class_015
{
nv3_class_ctx_switch_method_t set_notify_ctx_dma;
uint8_t reserved[0x100];
uint32_t set_notify;
uint8_t reserved2[0x1FC];
nv3_size_16_t size_in;
uint32_t delta_dx_du;
uint32_t delta_dy_dv;
nv3_position_16_t clip_0;
nv3_size_16_t clip_1;
uint32_t point12d4; /* todo: fraction struct */
uint8_t reserved3[0xE4];
uint32_t color[1792];
// no reserve needed
} nv3_stretched_image_from_cpu_t;
// 0x16 invalid
/*
Object Class 0x17 (real hardware)
0x?? (drivers)
Also 0x57 in context IDs.
Direct3D 5.0 accelerated triangle with zeta buffer (Not the same as a Zbuffer...)
This is the final boss of this GPU. True horror stands below.
*/
//
// NV3 D3D5: TEXTURING & PIXEL FORMATS
//
typedef enum nv3_d3d5_texture_pixel_format_e
{
/*
16-Bit Pixel Format
5 bits red, 5 bits green, 5 bits alpha, "boolean" alpha
*/
nv3_d3d5_pixel_format_le_a1r5g5b5 = 0,
/*
15-Bit Pixel Format (represented as 16)
1 bit irrelevant, 5 bits red, 5 bits green, 5 bits alpha
*/
nv3_d3d5_pixel_format_le_x1r5g5b5 = 1,
/*
16-Bit Pixel Format
4 bits alpha, 4 bits red, 4 bits green, 4 bits blue
*/
nv3_d3d5_pixel_format_le_a4r4g4b4 = 2,
/*
16-Bit Pixel Format
5 bits red, 6 bits green, 5 bits blue
(Required nv3tweak...)
*/
nv3_d3d5_pixel_format_le_r5g6b5 = 3,
} nv3_d3d5_texture_pixel_format;
/* Output format
The output pixel format...I
*/
typedef enum nv3_d3d5_output_pixel_format_e
{
/*
32-Bit Pixel Format
8 bits irrelevant, 8 bits red, 8 bits green, 8 bits blue
*/
nv3_d3d5_output_pixel_format_le_x8r8g8b8 = 0,
/*
32-Bit Pixel Format
8 bits irrelevant, 8 bits red, 8 bits green, 8 bits blue
Is this even used?? The riva can't even do 32 bit colour in 3d...
*/
nv3_d3d5_output_pixel_format_le_a8r8g8b8 = 1,
} nv3_d3d5_output_pixel_format;
/* Texture size
NOTE: ONLY 256X256 OR LOWER ARE SUPPORTED! 2048X2048X16 TAKES UP ENTIRE VRAM OF RIVA 128 ZX...
I ASSUME THESE ARE INTERNALLY SCALED DOWN
*/
typedef enum nv3_d3d5_texture_size_e
{
nv3_d3d5_texture_size_1x1 = 0,
nv3_d3d5_texture_size_2x2 = 1,
nv3_d3d5_texture_size_4x4 = 2,
nv3_d3d5_texture_size_8x8 = 3,
nv3_d3d5_texture_size_16x16 = 4,
nv3_d3d5_texture_size_32x32 = 5,
nv3_d3d5_texture_size_64x64 = 6,
nv3_d3d5_texture_size_128x128 = 7,
// Highest size supported natively by hardware?
nv3_d3d5_texture_size_256x256 = 8,
nv3_d3d5_texture_size_512x512 = 9,
nv3_d3d5_texture_size_1024x1024 = 10,
nv3_d3d5_texture_size_2048x2048 = 11,
} nv3_d3d5_texture_size;
/* Texture Wrapping Mode for U/V Coordinate Overflow
*/
typedef enum nv3_d3d5_texture_wrap_mode_e
{
// Map textures in a cylindrical fashion.
nv3_d3d5_texture_wrap_mode_cylindrical = 0,
// Simply wrap back to the start.
nv3_d3d5_texture_wrap_mode_wrap = 1,
// Mirror the texture.
nv3_d3d5_texture_wrap_mode_mirror = 2,
// Clamp to the last border pixel.
nv3_d3d5_texture_wrap_mode_clamp = 3,
} nv3_d3d5_texture_wrap_mode;
/* This is blending but isn't really considered to be it in the GPU for some reason
What do we do with out input texel BEFORE processing it?
*/
typedef enum nv3_d3d5_dest_color_interpretation_e
{
// Do nothing
nv3_d3d5_source_color_normal = 0,
// Invert Colour
nv3_d3d5_source_color_inverse = 1,
// Invert Alpha before Processing
nv3_d3d5_source_color_alpha_inverse = 2,
// Take Alpha as 1
nv3_d3d5_source_color_alpha_one = 3,
} nv3_d3d5_dest_color_interpretation;
// The full texture format structure
typedef struct nv3_d3d5_texture_format_s
{
uint16_t color_key_color_mask;
bool color_key_enabled : 1;
nv3_d3d5_texture_pixel_format color_format : 2;
nv3_d3d5_texture_size size_min : 4;
nv3_d3d5_texture_size size_max : 4;
} nv3_d3d5_texture_format_t;
//
// NV3 D3D5: INTERPOLATION
//
/*
??????
Interpolating between mip levels? (or for texture blending)
*/
typedef enum nv3_d3d5_interpolator_algorithm_e
{
// Zero-order hold interpolation?
nv3_d3d5_interpolator_zoh = 0,
// Zero-order hold (microsoft variant)?
nv3_d3d5_interpolator_zoh_ms = 1,
// Full-order hold interpolation?
nv3_d3d5_interpolator_foh = 2,
} nv3_d3d5_interpolator_algorithm;
//
// NV3 D3D5: Z-BUFFER
//
/* Probably the sorting algorithm */
typedef enum nv3_d3d5_zbuffer_type_e
{
// Sort based on linear distance
nv3_d3d5_zbuffer_linear = 0,
// Sort based on distance from view frustum
nv3_d3d5_zbuffer_screen = 1,
} nv3_d3d5_zbuffer_type;
// NV3 D3D5: WRITE CONTROL (SHARED BETWEEN ZETA BUFFER AND ALPHA)
typedef enum nv3_d3d5_buffer_write_control_e
{
// Never write.
nv3_d3d5_buffer_write_control_never = 0,
// Only write the alpha.
nv3_d3d5_buffer_write_control_alpha = 1,
// Write both alpha and the zeta-buffer.
nv3_d3d5_buffer_write_control_alpha_zeta = 2,
// Write only the zeta-buffer
nv3_d3d5_buffer_write_control_zeta = 3,
// Write everything (alpha+z+zeta?)
nv3_d3d5_buffer_write_control_always = 4,
} nv3_d3d5_buffer_write_control;
//
// NV3 D3D5: BUFFER COMPARISON (SHARED BETWEEN ZETA BUFFER AND ALPHA CONTROL)
//
// Todo: Which direction? (i.e. is less than p1 < p2 or p2 < p1!)
typedef enum nv3_d3d5_buffer_comparison_type_e
{
// !!!ILLEGAL COMPARISON TYPE!!!!
nv3_d3d5_buffer_comparison_illegal = 0,
// The (depth?) test always fails.
nv3_d3d5_buffer_comparison_always_false = 1,
// True if less than fail.
nv3_d3d5_buffer_comparison_less_than = 2,
// The test succeeds if equal.
nv3_d3d5_buffer_comparison_equal = 3,
// The test succeeds if less or equal.
nv3_d3d5_buffer_comparison_less_or_equal = 4,
// The test succeeds if greater.
nv3_d3d5_buffer_comparison_greater = 5,
// The test succeeds if the two elements are equal.
nv3_d3d5_buffer_comparison_not_equal = 6,
// The test succeeds if greater or equal
nv3_d3d5_buffer_comparison_greater_or_equal = 7,
// The test always succeeds.
nv3_d3d5_buffer_comparison_always_true = 8,
} nv3_d3d5_buffer_comparison_type;
//
// NV3 D3D5: BLENDING
//
/* Render Operation for Blending */
typedef enum nv3_d3d5_blend_render_operation_e
{
nv3_d3d5_blend_render_operation_and = 0,
nv3_d3d5_blend_add_with_saturation = 1,
} nv3_d3d5_blend_render_operation;
typedef enum nv3_d3d5_blend_beta_factor_e
{
nv3_d3d5_blend_beta_factor_srcalpha = 0,
nv3_d3d5_blend_beta_factor_zero = 1,
} nv3_d3d5_blend_beta_factor;
typedef enum nv3_d3d5_blend_input0_e
{
nv3_d3d5_blend_input0_srcalpha = 0,
nv3_d3d5_blend_input0_zero = 1,
} nv3_d3d5_blend_input0;
typedef enum nv3_d3d5_blend_input1_e
{
nv3_d3d5_blend_input1_destalpha = 0,
nv3_d3d5_blend_input1_zero = 1,
} nv3_d3d5_blend_input1;
//
// NV3 D3D5: CULLING
//
typedef enum nv3_d3d5_culling_algorithm_e
{
// Don't cull
nv3_d3d5_culling_algorithm_none = 0,
// Cull Clockwise around view frustum?
nv3_d3d5_culling_algorithm_clockwise = 1,
// Cull counterclockwise around view frustum?
nv3_d3d5_culling_algorithm_counterclockwise = 2,
} nv3_d3d5_culling_algorithm;
/* Specular reflection parameters */
typedef struct nv3_d3d5_specular_s
{
uint8_t i0 : 4;
uint8_t i1 : 4;
uint8_t i2 : 4;
uint8_t i3 : 4;
uint8_t i4 : 4;
uint8_t i5 : 4;
uint8_t fog; //table fog emulation?
} nv3_d3d5_specular_t;
//
// NV3 D3D5: MISC
//
typedef struct nv3_d3d5_texture_filter_s
{
uint8_t spread_x;
uint8_t spread_y;
uint8_t mipmap;
uint8_t turbo;
} nv3_d3d5_texture_filter_t;
//
// NV3 D3D5: OUTPUT CONTROL STRUCTURE
//
/* Output Control for D3D5 Triangles */
typedef struct nv3_d3d5_control_out_s
{
nv3_d3d5_interpolator_algorithm ctrl_out_interpolator : 2;
uint8_t reserved : 2;
nv3_d3d5_texture_wrap_mode wrap_u : 2; // Controls wrapping mode of U texture coordinate
nv3_d3d5_texture_wrap_mode wrap_v : 2; // Controls wrapping move of V texture coordinate
nv3_d3d5_output_pixel_format output_pixel_format : 1;
bool reserved2 : 1;
nv3_d3d5_dest_color_interpretation dest_color_interpretation : 2;
nv3_d3d5_culling_algorithm culling_algorithm : 2;
bool reserved3 : 1;
nv3_d3d5_zbuffer_type zbuffer_type : 1;
nv3_d3d5_buffer_comparison_type zeta_buffer_compare : 4;
nv3_d3d5_buffer_write_control zeta_write : 3;
bool reserved4 : 1;
nv3_d3d5_buffer_write_control color_write : 3;
bool reserved5 : 1;
nv3_d3d5_blend_render_operation blend_rop : 1;
nv3_d3d5_blend_input0 blend_input0 : 1;
nv3_d3d5_blend_input1 blend_input1 : 1;
} nv3_d3d5_control_out_t;
typedef struct nv3_d3d5_alpha_control_s
{
uint8_t alpha_key;
nv3_d3d5_buffer_comparison_type zeta_buffer_compare : 4;
uint32_t reserved : 20;
} nv3_d3d5_alpha_control_t;
//
// NV3 D3D5: Triangle Coordinates
//
typedef struct nv3_d3d5_coordinate_s
{
nv3_d3d5_specular_t specular_reflection_parameters;
nv3_color_bgra_32_t color; // YOU HAVE TO FLIP THE ENDIANNESS. NVIDIA??? WHAT???
// Seems more plausible for these specifically to be floats.
// Also makes my life easier...
float x; // X coordinate in 3d space of the triangle
float y; // Y coordinate in 3d space of the triangle
float z; // Z coordinate in 3d space of the triangle
float m; // "Measurement dimension" apparently, allows for more precise measurements. And curves
float u; // U coordinate within texture for the (top left?) of the triangle where sampling starts.
float v; // V coordinate within texture for the (top left?) of the triangle where sampling starts.
} nv3_d3d5_coordinate_t;
typedef struct nv3_object_class_017
{
nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch)
uint8_t reserved[0x100];
uint32_t set_notify; // Set notifier
uint8_t reserved2[0x1FC];
uint32_t texture_offset;
nv3_d3d5_texture_format_t texture_format;
nv3_d3d5_texture_filter_t texture_filter;
nv3_color_argb_32_t fog_color; // Alpha is ignored here!
nv3_d3d5_control_out_t control_out;
nv3_d3d5_alpha_control_t alpha_control;
uint8_t reserved3[0xCE4];
nv3_d3d5_coordinate_t coordinate_points[128]; // The points wer are rendering.
/* No placeholder needed, it really is that long. */
} nv3_d3d5_accelerated_triangle_with_zeta_buffer_t;
/* 0x18, 0x19, 0x1A, 0x1B don't exist */
/* WHY IS THE FORMAT DIFFERENT TO THE REST OF THE GPU?
They are making it look like a bitfield but it's hex?
@@ -535,5 +1052,17 @@ typedef enum nv3_object_class_01C_pixel_format_e
nv3_m2mt_pixel_format_x8g8b8r8 = 0x1,
} nv3_object_class_01C_pixel_format;
typedef struct nv3_object_class_01C
{
nv3_class_ctx_switch_method_t set_notify_ctx_dma; // Set notifier context for DMA (context switch)
uint8_t reserved[0x100];
uint32_t set_notify; // Set notifier
uint8_t reserved2[0x1F8];
nv3_object_class_01C_pixel_format format; // Completely different from everything else
uint32_t pitch; // 16-bit
uint32_t linear_address; // 22-bit: Linear address in vram.
uint8_t reserved3[0x1C3F];
} nv3_image_in_memory_t;
// TODO: PATCHCORDS!!!! TO LINK ALL OF THIS TOGETHER!!!
#pragma pack(pop) // return packing to whatever it was before this disaster

View File

@@ -183,7 +183,6 @@ extern const device_config_t nv3_config[];
#define NV3_PMC_ENABLE_PVIDEO 28
#define NV3_PMC_ENABLE_PVIDEO_ENABLED 0x1
#define NV3_PMC_END 0xfff // overlaps with CIO
#define NV3_CIO_START 0x3b0 // Legacy SVGA Emulation Subsystem
#define NV3_CIO_END 0x3df
@@ -194,8 +193,10 @@ extern const device_config_t nv3_config[];
#define NV3_PBUS_PCI_END 0x18FF // PCI mirror end
#define NV3_PBUS_END 0x1FFF
#define NV3_PFIFO_START 0x2000 // FIFO for DMA Object Submission (uses hashtable to store the objects)
#define NV3_PFIFO_INTR 0x2100 // FIFO - Interrupt Status
#define NV3_PFIFO_INTR_EN 0x2140 // FIFO - Interrupt Enable
#define NV3_PFIFO_END 0x3FFF
#define NV3_PRM_START 0x4000 // Real-Mode Device Support Subsystem
#define NV3_PRM_INTR 0x4100