summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/includes/xbox_nv2a.h
blob: 970db40f534c79c024950eb02e7abcb24f3c36cf (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
                       
                                    


                                                







                                 

                

























































                                                                             
                               







                                             
                                 












                         



                              
                       






                       



                                   
                         
                            



                                                
                                           





                                        


                            










                                                                           

                                                        





































                                                                                        
                                
















                                                                                 
                                                                               

       




























                                      
                                    
                                           
                           


                                       


                                                




                                     
                                                                            
                          
                              
                           
                                                         




















































































































                                                  








                                       
 

                                             
                         

          
                                                                                                             




                                                    
                                                  

                                                


                                                    
                                              
                                           
                                      
                                       
                                    
                                        


                                                                   

                                           
                                                        
                                           
                                                          

                                             
                                                          

                                  


                                                         
                                         
                                                               
                                

                                                                     
                                                  
                                                        

                                                               


                                                        

                                      



                                              


                                                                       
                                            
                                                       
                                                      
                                      

                                           


                                          
                                   
                                         
                                              

                                          

                                                                                    


                                                                         


                                          
                                                   
                                                                                                                
                                 
                                                                                                    
 


                                                                                                                                     
 








                                                                                                                                               


















                                                                                                               



                                                                
                                  


                                               
                                                                
                                                                             
                                             
                               
                                                                             
                                                                               
                                                                             
                                                                                            
                                                                                               
                                                                                                             
                                                                                                       
                                                                                                             
                                                                                            
                                                                                            
                                                                   




                                                                                                                                                                        
                                                 

                
                                        
                        



                                                                                                                                         

                         








                                     
                                                    
                                     
                                      

                                    

                                   


                                    
                                      


                                                      
                                    
                                     
                                   

                                   



                                          
                                    
                                               






                                  
                                       
                               

                                    












                                 
                     
                                    
                                      
                                  
                                        

                              
                                                                                                   

                                  
                               
                                                                                                          
                                                                                           

                                                                    
 




































































































                                                         
                                
                   
                            


                                                    
                                
                                      
                            
                                
                                          

                                  
                                        

                         


                                         
                              


                                                     
                             
                                       
                                        
                

                                              
                                      
                                       
                                   














                                                 
                                

                                    

                                    



                                       

                               
  

                                   
// license:BSD-3-Clause
// copyright-holders:Samuele Zannoli
/*
 * geforce 3d (NV2A) vertex program disassembler
 */
#ifndef MAME_INCLUDES_XBOX_NV2A_H
#define MAME_INCLUDES_XBOX_NV2A_H

#pragma once

#include "machine/pic8259.h"
#include "video/poly.h"

#include <mutex>

class vertex_program_disassembler {
	static const char *srctypes[];
	static const char *scaops[];
	static const int scapar2[];
	static const char *vecops[];
	static const int vecpar2[];
	static const char *vecouts[];
	static const char compchar[];
	int o[6];
	int state;

	struct sourcefields
	{
		int Sign;
		int SwizzleX;
		int SwizzleY;
		int SwizzleZ;
		int SwizzleW;
		int TempIndex;
		int ParameterType;
	};

	struct fields
	{
		int ScaOperation;
		int VecOperation;
		int SourceConstantIndex;
		int InputIndex;
		sourcefields src[3];
		int VecTempWriteMask;
		int VecTempIndex;
		int ScaTempWriteMask;
		int OutputWriteMask;
		int OutputSelect;
		int OutputIndex;
		int MultiplexerControl;
		int Usea0x;
		int EndOfProgram;
	};
	fields f;

	void decodefields(unsigned int *dwords, int offset, fields &decoded);
	int disassemble_mask(int mask, char *s);
	int disassemble_swizzle(sourcefields f, char *s);
	int disassemble_source(sourcefields f, fields fi, char *s);
	int disassemble_output(fields f, char *s);
	int output_types(fields f, int *o);
public:
	vertex_program_disassembler() { state = 0; }
	int disassemble(unsigned int *instruction, char *line);
};

/*
 * geforce 3d (NV2A) vertex structure
 */
struct vertex_nv {
	union {
		float fv[4];
		uint32_t iv[4];
	} attribute[16];
};

/*
 * geforce 3d (NV2A) vertex program simulator
 */
class vertex_program_simulator {
public:
	enum VectorialOperation {
		VecNOP=0,
		VecMOV,
		VecMUL,
		VecADD,
		VecMAD,
		VecDP3,
		VecDPH,
		VecDP4,
		VecDST,
		VecMIN,
		VecMAX,
		VecSLT,
		VecSGE,
		VecARL
	};
	enum ScalarOperation {
		ScaNOP=0,
		ScaIMV,
		ScaRCP,
		ScaRCC,
		ScaRSQ,
		ScaEXP,
		ScaLOG,
		ScaLIT
	};
	vertex_program_simulator();
	// input vertex
	vertex_nv *input;
	// input parameters
	struct constant {
		float fv[4];
		void iv(int idx, uint32_t value)
		{
			union
			{
				uint32_t i;
				float f;
			} cnv;

			cnv.i = value;
			fv[idx] = cnv.f;
		}
	} c_constant[192];
	union temp {
		float fv[4];
	} r_temp[32];
	// output vertex
	vertex_nv *output;
	// instructions
	struct instruction {
		unsigned int i[4];
		int modified;
		struct decoded {
			int SwizzleA[4], SignA, ParameterTypeA, TempIndexA;
			int SwizzleB[4], SignB, ParameterTypeB, TempIndexB;
			int SwizzleC[4], SignC, ParameterTypeC, TempIndexC;
			VectorialOperation VecOperation;
			ScalarOperation ScaOperation;
			int OutputWriteMask, MultiplexerControl;
			int VecTempWriteMask, ScaTempWriteMask;
			int VecTempIndex, OutputIndex;
			int InputIndex;
			int SourceConstantIndex;
			int OutputSelect;
			int Usea0x;
			int EndOfProgram;
		} d;
	} op[256];
public:
	void set_data(vertex_nv *in, vertex_nv *out);
	void reset();
	int step();
	void decode_instruction(int address);
	void execute();
	void jump(int address);
	void process(int address, vertex_nv *in, vertex_nv *out, int count);
	int status();
private:
	void initialize_outputs();
	void initialize_temps();
	void initialize_constants();
	void generate_input(float t[4], int sign, int type, int temp, int swizzle[4]);
	void compute_vectorial_operation(float t[4], int instruction, float par[3 * 4]);
	void compute_scalar_operation(float t[4], int instruction, float par[3 * 4]);

	int ip;
	int a0x;
};

class nv2a_renderer; // forward declaration
struct nvidia_object_data
{
	nv2a_renderer *data;
};

/*
 * geforce 3d (NV2A) accelerator
 */
/* very simplified view
there is a set of context objects

context objects are stored in RAMIN
each context object is identified by an handle stored in RAMHT

each context object can be assigned to a channel
to assign you give to the channel an handle for the object

offset in ramht=(((((handle >> 11) xor handle) >> 11) xor handle) & 0x7ff)*8
offset in ramht contains the handle itself
offset in ramht+4 contains in the lower 16 bits the offset in RAMIN divided by 16

objects have methods used to do drawing
most methods set parameters, others actually draw
*/
class nv2a_renderer : public poly_manager<double, nvidia_object_data, 13, 8192>
{
public:
	enum class VERTEX_PARAMETER {
		PARAM_COLOR_B = 0,
		PARAM_COLOR_G = 1,
		PARAM_COLOR_R = 2,
		PARAM_COLOR_A = 3,
		PARAM_TEXTURE0_U = 4,
		PARAM_TEXTURE0_V = 5,
		PARAM_TEXTURE1_U = 6,
		PARAM_TEXTURE1_V = 7,
		PARAM_TEXTURE2_U = 8,
		PARAM_TEXTURE2_V = 9,
		PARAM_TEXTURE3_U = 10,
		PARAM_TEXTURE3_V = 11,
		PARAM_Z = 12
	};
	enum class NV2A_BEGIN_END {
		STOP = 0,
		POINTS = 1,
		LINES = 2,
		LINE_LOOP = 3,
		LINE_STRIP = 4,
		TRIANGLES = 5,
		TRIANGLE_STRIP = 6,
		TRIANGLE_FAN = 7,
		QUADS = 8,
		QUAD_STRIP = 9,
		POLYGON = 10
	};
	enum class NV2A_VERTEX_ATTR {
		POS = 0, // position
		WEIGHT = 1, // blend weight
		NORMAL = 2,
		COLOR0 = 3, // diffuse
		COLOR1 = 4, // specular
		FOG = 5,
		BACKCOLOR0 = 7, // back diffuse
		BACKCOLOR1 = 8, // back specular
		TEX0 = 9, // texture coordinate
		TEX1 = 10,
		TEX2 = 11,
		TEX3 = 12
	};
	enum class NV2A_VTXBUF_TYPE {
		UBYTE_D3D = 0, // what is the difference with opengl UBYTE ?
		FLOAT = 2,
		UBYTE_OGL = 4,
		USHORT = 5,
		FLOAT_PACKED = 6 // used for vertex color
	};
	enum class NV2A_TEX_FORMAT {
		L8 = 0x0,
		I8 = 0x1,
		A1R5G5B5 = 0x2,
		A4R4G4B4 = 0x4,
		R5G6B5 = 0x5,
		A8R8G8B8 = 0x6,
		X8R8G8B8 = 0x7,
		INDEX8 = 0xb,
		DXT1 = 0xc,
		DXT3 = 0xe,
		DXT5 = 0xf,
		A1R5G5B5_RECT = 0x10,
		R5G6B5_RECT = 0x11,
		A8R8G8B8_RECT = 0x12,
		L8_RECT = 0x13,
		DSDT8_RECT = 0x17,
		A8L8 = 0x1a,
		I8_RECT = 0x1b,
		A4R4G4B4_RECT = 0x1d,
		R8G8B8_RECT = 0x1e,
		A8L8_RECT = 0x20,
		Z24 = 0x2a,
		Z24_RECT = 0x2b,
		Z16 = 0x2c,
		Z16_RECT = 0x2d,
		DSDT8 = 0x28,
		HILO16 = 0x33,
		HILO16_RECT = 0x36,
		HILO8 = 0x44,
		SIGNED_HILO8 = 0x45,
		HILO8_RECT = 0x46,
		SIGNED_HILO8_RECT = 0x47
	};
	enum class NV2A_LOGIC_OP {
		CLEAR = 0x1500,
		AND = 0x1501,
		AND_REVERSE = 0x1502,
		COPY = 0x1503,
		AND_INVERTED = 0x1504,
		NOOP = 0x1505,
		XOR = 0x1506,
		OR = 0x1507,
		NOR = 0x1508,
		EQUIV = 0x1509,
		INVERT = 0x150a,
		OR_REVERSE = 0x150b,
		COPY_INVERTED = 0x150c,
		OR_INVERTED = 0x150d,
		NAND = 0x150e,
		SET = 0x150f
	};
	enum class NV2A_BLEND_EQUATION {
		FUNC_ADD = 0x8006,
		MIN = 0x8007,
		MAX = 0x8008,
		FUNC_SUBTRACT = 0x800a,
		FUNC_REVERSE_SUBTRACT = 0x80b
	};
	enum class NV2A_BLEND_FACTOR {
		ZERO = 0x0000,
		ONE = 0x0001,
		SRC_COLOR = 0x0300,
		ONE_MINUS_SRC_COLOR = 0x0301,
		SRC_ALPHA = 0x0302,
		ONE_MINUS_SRC_ALPHA = 0x0303,
		DST_ALPHA = 0x0304,
		ONE_MINUS_DST_ALPHA = 0x0305,
		DST_COLOR = 0x0306,
		ONE_MINUS_DST_COLOR = 0x0307,
		SRC_ALPHA_SATURATE = 0x0308,
		CONSTANT_COLOR = 0x8001,
		ONE_MINUS_CONSTANT_COLOR = 0x8002,
		CONSTANT_ALPHA = 0x8003,
		ONE_MINUS_CONSTANT_ALPHA = 0x8004
	};
	enum class NV2A_COMPARISON_OP {
		NEVER = 0x0200,
		LESS = 0x0201,
		EQUAL = 0x0202,
		LEQUAL = 0x0203,
		GREATER = 0x0204,
		NOTEQUAL = 0x0205,
		GEQUAL = 0x0206,
		ALWAYS = 0x0207
	};
	enum class NV2A_STENCIL_OP {
		ZEROOP = 0x0000,
		INVERTOP = 0x150a,
		KEEP = 0x1e00,
		REPLACE = 0x1e01,
		INCR = 0x1e02,
		DECR = 0x1e03,
		INCR_WRAP = 0x8507,
		DECR_WRAP = 0x8508
	};
	enum class NV2A_RT_TYPE {
		LINEAR = 1,
		SWIZZLED = 2
	};
	enum class NV2A_RT_DEPTH_FORMAT {
		Z16 = 0x0001,
		Z24S8 = 0x0002
	};
	enum class NV2A_COLOR_FORMAT {
		X1R5G5B5_Z1R5G5B5 = 1,
		X1R5G5B5_X1R5G5B5 = 2,
		R5G6B5 = 3,
		X8R8G8B8_Z8R8G8B8 = 4,
		X8R8G8B8_X8R8G8B8 = 5,
		X1A7R8G8B8_Z1A7R8G8B8 = 6,
		X1A7R8G8B8_X1A7R8G8B8 = 7,
		A8R8G8B8 = 8,
		B8 = 9,
		G8B8 = 10
	};
	enum class NV2A_GL_FRONT_FACE {
		CW = 0x0900,
		CCW = 0x0901
	};
	enum class NV2A_GL_CULL_FACE {
		FRONT = 0x0404,
		BACK = 0x0405,
		FRONT_AND_BACK = 0x0408
	};

	struct nv2avertex_t : public vertex_t
	{
		double w;
	};

	nv2a_renderer(running_machine &machine) : poly_manager<double, nvidia_object_data, 13, 8192>(machine)
	{
		memset(channel, 0, sizeof(channel));
		memset(pfifo, 0, sizeof(pfifo));
		memset(pcrtc, 0, sizeof(pcrtc));
		memset(pmc, 0, sizeof(pmc));
		memset(pgraph, 0, sizeof(pgraph));
		memset(ramin, 0, sizeof(ramin));
		computedilated();
		objectdata = &(object_data_alloc());
		objectdata->data = this;
		combiner.used = 0;
		enabled_vertex_attributes = 0;
		primitives_total_count = 0;
		indexesleft_count = 0;
		triangles_bfculled = 0;
		vertex_pipeline = 4;
		color_mask = 0xffffffff;
		backface_culling_enabled = false;
		backface_culling_winding = NV2A_GL_FRONT_FACE::CCW;
		backface_culling_culled = NV2A_GL_CULL_FACE::BACK;
		alpha_test_enabled = false;
		alpha_reference = 0;
		alpha_func = NV2A_COMPARISON_OP::ALWAYS;
		depth_test_enabled = false;
		depth_function = NV2A_COMPARISON_OP::LESS;
		depth_write_enabled = false;
		stencil_test_enabled = false;
		stencil_func = NV2A_COMPARISON_OP::ALWAYS;
		stencil_ref = 0;
		stencil_mask = -1;
		stencil_op_fail = NV2A_STENCIL_OP::KEEP;
		stencil_op_zfail = NV2A_STENCIL_OP::KEEP;
		stencil_op_zpass = NV2A_STENCIL_OP::KEEP;
		blending_enabled = false;
		blend_equation = NV2A_BLEND_EQUATION::FUNC_ADD;
		blend_color = 0;
		blend_function_destination = NV2A_BLEND_FACTOR::ZERO;
		blend_function_source = NV2A_BLEND_FACTOR::ONE;
		logical_operation_enabled = false;
		logical_operation = NV2A_LOGIC_OP::COPY;
		for (int n = 0; n < 8; n++)
			clippingwindows[n].set(0, 0, 640, 480);
		limits_rendertarget.set(0, 0, 640, 480);
		pitch_rendertarget = 0;
		pitch_depthbuffer = 0;
		size_rendertarget = 0;
		size_depthbuffer = 0;
		log2height_rendertarget = 0;
		log2width_rendertarget = 0;
		dilate_rendertarget = 0;
		antialiasing_rendertarget = 0;
		type_rendertarget = NV2A_RT_TYPE::LINEAR;
		depthformat_rendertarget = NV2A_RT_DEPTH_FORMAT::Z24S8;
		colorformat_rendertarget = NV2A_COLOR_FORMAT::A8R8G8B8;
		bytespixel_rendertarget = 4;
		clear_rendertarget.set(0, 0, 639, 479);
		primitive_type = NV2A_BEGIN_END::STOP;
		antialias_control = 0;
		supersample_factor_x = 1.0;
		supersample_factor_y = 1.0;
		rendertarget = nullptr;
		depthbuffer = nullptr;
		displayedtarget = nullptr;
		puller_waiting = 0;
		debug_grab_texttype = -1;
		debug_grab_textfile = nullptr;
		enable_waitvblank = true;
		enable_clipping_w = false;
		memset(vertex_attribute_words, 0, sizeof(vertex_attribute_words));
		memset(vertex_attribute_offset, 0, sizeof(vertex_attribute_offset));
		memset(&persistvertexattr, 0, sizeof(persistvertexattr));
		for (int n = 0; n < 16; n++)
			persistvertexattr.attribute[n].fv[3] = 1;
	}
	DECLARE_READ32_MEMBER(geforce_r);
	DECLARE_WRITE32_MEMBER(geforce_w);
	DECLARE_WRITE_LINE_MEMBER(vblank_callback);
	uint32_t screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
	bool update_interrupts();
	void set_irq_callbaclk(std::function<void(int state)> callback) { irq_callback = callback; }

	void render_texture_simple(int32_t scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
	void render_color(int32_t scanline, const extent_t &extent, const nvidia_object_data &extradata, int threadid);
	void render_register_combiners(int32_t scanline, const extent_t &extent, const nvidia_object_data &objectdata, int threadid);

	int geforce_commandkind(uint32_t word);
	uint32_t geforce_object_offset(uint32_t handle);
	void geforce_read_dma_object(uint32_t handle, uint32_t &offset, uint32_t &size);
	void geforce_assign_object(address_space &space, uint32_t chanel, uint32_t subchannel, uint32_t address);
	int geforce_exec_method(address_space &space, uint32_t channel, uint32_t subchannel, uint32_t method, uint32_t address, int &countlen);
	uint32_t texture_get_texel(int number, int x, int y);
	uint8_t *read_pixel(int x, int y, int32_t c[4]);
	void write_pixel(int x, int y, uint32_t color, int depth);
	void combiner_initialize_registers(uint32_t argb8[6]);
	void combiner_initialize_stage(int stage_number);
	void combiner_initialize_final();
	void combiner_map_input(int stage_number); // map combiner registers to variables A..D
	void combiner_map_output(int stage_number); // map combiner calculation results to combiner registers
	void combiner_map_final_input(); // map final combiner registers to variables A..F
	void combiner_final_output(); // generate final combiner output
	float combiner_map_input_select(int code, int index); // get component index in register code
	float *combiner_map_input_select3(int code); // get pointer to register code
	float *combiner_map_output_select3(int code); // get pointer to register code for output
	float combiner_map_input_function(int code, float value); // apply input mapping function code to value
	void combiner_map_input_function3(int code, float *data); // apply input mapping function code to data
	void combiner_function_AB(float result[4]);
	void combiner_function_AdotB(float result[4]);
	void combiner_function_CD(float result[4]);
	void combiner_function_CdotD(float result[4]);
	void combiner_function_ABmuxCD(float result[4]);
	void combiner_function_ABsumCD(float result[4]);
	void combiner_compute_rgb_outputs(int index);
	void combiner_compute_a_outputs(int index);
	void combiner_argb8_float(uint32_t color, float reg[4]);
	uint32_t combiner_float_argb8(float reg[4]);
	uint32_t dilate0(uint32_t value, int bits);
	uint32_t dilate1(uint32_t value, int bits);
	void computedilated(void);
	bool toggle_register_combiners_usage();
	bool toggle_wait_vblank_support();
	bool toggle_clipping_w_support();
	void debug_grab_texture(int type, const char *filename);
	void debug_grab_vertex_program_slot(int slot, uint32_t *instruction);
	void start(address_space *cpu_space);
	void savestate_items();
	void compute_supersample_factors(float &horizontal, float &vertical);
	void compute_limits_rendertarget(uint32_t chanel, uint32_t subchannel);
	void compute_size_rendertarget(uint32_t chanel, uint32_t subchannel);
	void extract_packed_float(uint32_t data, float &first, float &second, float &third);
	void read_vertex(address_space & space, offs_t address, vertex_nv &vertex, int attrib);
	int read_vertices_0x180x(address_space & space, vertex_nv *destination, uint32_t address, int limit);
	int read_vertices_0x1810(address_space & space, vertex_nv *destination, int offset, int limit);
	int read_vertices_0x1818(address_space & space, vertex_nv *destination, uint32_t address, int limit);
	void convert_vertices_poly(vertex_nv *source, nv2avertex_t *destination, int count);
	void assemble_primitive(vertex_nv *source, int count, render_delegate &renderspans);
	int clip_triangle_w(nv2avertex_t *vi[3], nv2avertex_t *vo);
	uint32_t render_triangle_clipping(const rectangle &cliprect, render_delegate callback, int paramcount, nv2avertex_t &_v1, nv2avertex_t &_v2, nv2avertex_t &_v3);
	uint32_t render_triangle_culling(const rectangle &cliprect, render_delegate callback, int paramcount, nv2avertex_t &_v1, nv2avertex_t &_v2, nv2avertex_t &_v3);
	void clear_render_target(int what, uint32_t value);
	void clear_depth_buffer(int what, uint32_t value);
	inline uint8_t *direct_access_ptr(offs_t address);
	TIMER_CALLBACK_MEMBER(puller_timer_work);

	struct {
		uint32_t regs[0x80 / 4];
		struct {
			uint32_t objhandle;
			uint32_t objclass;
			uint32_t method[0x2000 / 4];
			// int execute_method(address_space & space, uint32_t method, uint32_t address, int &countlen); // for the future
		} object;
	} channel[32][8];
	uint32_t pfifo[0x2000 / 4];
	uint32_t pcrtc[0x1000 / 4];
	uint32_t pmc[0x1000 / 4];
	uint32_t pgraph[0x2000 / 4];
	uint32_t ramin[0x100000 / 4];
	uint32_t dma_offset[2];
	uint32_t dma_size[2];
	uint8_t *basemempointer;
	uint8_t *topmempointer;
	std::function<void(int state)> irq_callback;
	rectangle clippingwindows[8];
	rectangle limits_rendertarget;
	uint32_t pitch_rendertarget;
	uint32_t pitch_depthbuffer;
	uint32_t size_rendertarget;
	uint32_t size_depthbuffer;
	int log2height_rendertarget;
	int log2width_rendertarget;
	int dilate_rendertarget;
	int antialiasing_rendertarget;
	NV2A_RT_TYPE type_rendertarget;
	NV2A_RT_DEPTH_FORMAT depthformat_rendertarget;
	NV2A_COLOR_FORMAT colorformat_rendertarget;
	int bytespixel_rendertarget;
	rectangle clear_rendertarget;
	uint32_t antialias_control;
	float supersample_factor_x;
	float supersample_factor_y;
	uint32_t *rendertarget;
	uint32_t *depthbuffer;
	uint32_t *displayedtarget;
	uint32_t vertexbuffer_address[16];
	int vertexbuffer_stride[16];
	NV2A_VTXBUF_TYPE vertexbuffer_kind[16];
	int vertexbuffer_size[16];
	struct {
		int enabled;
		int sizeu;
		int sizev;
		int sizew;
		int dilate;
		NV2A_TEX_FORMAT format;
		bool rectangle;
		int rectangle_pitch;
		void *buffer;
		int dma0;
		int dma1;
		int cubic;
		int noborder;
		int dims;
		int mipmap;
		int colorkey;
		int imagefield;
		int aniso;
		int mipmapmaxlod;
		int mipmapminlod;
		int rectheight;
		int rectwidth;
	} texture[4];
	uint32_t triangles_bfculled;
	NV2A_BEGIN_END primitive_type;
	uint32_t primitives_count;
	uint32_t primitives_total_count;
	int indexesleft_count;
	int indexesleft_first;
	uint32_t vertex_indexes[1024]; // vertex indices sent by the software to the 3d accelerator
	int vertex_count;
	unsigned int vertex_first;
	int vertex_accumulated;
	vertex_nv vertex_software[1024+2]; // vertex attributes sent by the software to the 3d accelerator
	nv2avertex_t vertex_xy[1024+2]; // vertex attributes computed by the 3d accelerator
	vertex_nv persistvertexattr; // persistent vertex attributes
	render_delegate render_spans_callback;

	struct {
		float variable_A[4]; // 0=R 1=G 2=B 3=A
		float variable_B[4];
		float variable_C[4];
		float variable_D[4];
		float variable_E[4];
		float variable_F[4];
		float variable_G;
		float variable_EF[4];
		float variable_sumclamp[4];
		float function_RGBop1[4]; // 0=R 1=G 2=B
		float function_RGBop2[4];
		float function_RGBop3[4];
		float function_Aop1;
		float function_Aop2;
		float function_Aop3;
		float register_primarycolor[4]; // rw
		float register_secondarycolor[4];
		float register_texture0color[4];
		float register_texture1color[4];
		float register_texture2color[4];
		float register_texture3color[4];
		float register_color0[4];
		float register_color1[4];
		float register_spare0[4];
		float register_spare1[4];
		float register_fogcolor[4]; // ro
		float register_zero[4];
		float output[4];
		struct {
			float register_constantcolor0[4];
			float register_constantcolor1[4];
			int mapin_aA_input;
			int mapin_aA_component;
			int mapin_aA_mapping;
			int mapin_aB_input;
			int mapin_aB_component;
			int mapin_aB_mapping;
			int mapin_aC_input;
			int mapin_aC_component;
			int mapin_aC_mapping;
			int mapin_aD_input;
			int mapin_aD_component;
			int mapin_aD_mapping;
			int mapin_rgbA_input;
			int mapin_rgbA_component;
			int mapin_rgbA_mapping;
			int mapin_rgbB_input;
			int mapin_rgbB_component;
			int mapin_rgbB_mapping;
			int mapin_rgbC_input;
			int mapin_rgbC_component;
			int mapin_rgbC_mapping;
			int mapin_rgbD_input;
			int mapin_rgbD_component;
			int mapin_rgbD_mapping;
			int mapout_aCD_output;
			int mapout_aAB_output;
			int mapout_aSUM_output;
			int mapout_aCD_dotproduct;
			int mapout_aAB_dotproduct;
			int mapout_a_muxsum;
			int mapout_a_bias;
			int mapout_a_scale;
			int mapout_rgbCD_output;
			int mapout_rgbAB_output;
			int mapout_rgbSUM_output;
			int mapout_rgbCD_dotproduct;
			int mapout_rgbAB_dotproduct;
			int mapout_rgb_muxsum;
			int mapout_rgb_bias;
			int mapout_rgb_scale;
		} stage[8];
		struct {
			float register_constantcolor0[4];
			float register_constantcolor1[4];
			int color_sum_clamp;
			int mapin_rgbA_input;
			int mapin_rgbA_component;
			int mapin_rgbA_mapping;
			int mapin_rgbB_input;
			int mapin_rgbB_component;
			int mapin_rgbB_mapping;
			int mapin_rgbC_input;
			int mapin_rgbC_component;
			int mapin_rgbC_mapping;
			int mapin_rgbD_input;
			int mapin_rgbD_component;
			int mapin_rgbD_mapping;
			int mapin_rgbE_input;
			int mapin_rgbE_component;
			int mapin_rgbE_mapping;
			int mapin_rgbF_input;
			int mapin_rgbF_component;
			int mapin_rgbF_mapping;
			int mapin_aG_input;
			int mapin_aG_component;
			int mapin_aG_mapping;
		} final;
		int stages;
		int used;
		std::mutex lock;
	} combiner;
	uint32_t color_mask;
	bool backface_culling_enabled;
	NV2A_GL_FRONT_FACE backface_culling_winding;
	NV2A_GL_CULL_FACE backface_culling_culled;
	bool alpha_test_enabled;
	NV2A_COMPARISON_OP alpha_func;
	int alpha_reference;
	bool depth_test_enabled;
	NV2A_COMPARISON_OP depth_function;
	bool depth_write_enabled;
	bool stencil_test_enabled;
	NV2A_COMPARISON_OP stencil_func;
	int stencil_ref;
	int stencil_mask;
	NV2A_STENCIL_OP stencil_op_fail;
	NV2A_STENCIL_OP stencil_op_zfail;
	NV2A_STENCIL_OP stencil_op_zpass;
	bool blending_enabled;
	NV2A_BLEND_EQUATION blend_equation;
	NV2A_BLEND_FACTOR blend_function_source;
	NV2A_BLEND_FACTOR blend_function_destination;
	uint32_t blend_color;
	bool logical_operation_enabled;
	NV2A_LOGIC_OP logical_operation;
	struct {
		float modelview[4][4];
		float modelview_inverse[4][4];
		float composite[4][4];
		float projection[4][4];
		float translate[4];
		float scale[4];
	} matrix;
	struct {
		vertex_program_simulator exec;
		int instructions;
		int upload_instruction_index;
		int upload_instruction_component;
		int start_instruction;
		int upload_parameter_index;
		int upload_parameter_component;
	} vertexprogram;
	int vertex_pipeline;
	int enabled_vertex_attributes;
	int vertex_attribute_words[16];
	int vertex_attribute_offset[16];
	emu_timer *puller_timer;
	int puller_waiting;
	address_space *puller_space;
	uint32_t dilated0[16][2048];
	uint32_t dilated1[16][2048];
	int dilatechose[256];
	nvidia_object_data *objectdata;
	int debug_grab_texttype;
	char *debug_grab_textfile;
	bool enable_waitvblank;
	bool enable_clipping_w;
};

#endif // MAME_INCLUDES_XBOX_NV2A_H