1 // license:BSD-3-Clause
2 // copyright-holders:Samuele Zannoli
3 /*
4  * geforce 3d (NV2A) vertex program disassembler
5  */
6 #ifndef MAME_INCLUDES_XBOX_NV2A_H
7 #define MAME_INCLUDES_XBOX_NV2A_H
8 
9 #pragma once
10 
11 #include "machine/pic8259.h"
12 #include "video/poly.h"
13 
14 class vertex_program_disassembler {
15 	static char const *const srctypes[];
16 	static char const *const scaops[];
17 	static int const scapar2[];
18 	static char const *const vecops[];
19 	static int const vecpar2[];
20 	static char const *const vecouts[];
21 	static char const compchar[];
22 	int o[6];
23 	int state;
24 
25 	struct sourcefields
26 	{
27 		int Sign;
28 		int SwizzleX;
29 		int SwizzleY;
30 		int SwizzleZ;
31 		int SwizzleW;
32 		int TempIndex;
33 		int ParameterType;
34 	};
35 
36 	struct fields
37 	{
38 		int ScaOperation;
39 		int VecOperation;
40 		int SourceConstantIndex;
41 		int InputIndex;
42 		sourcefields src[3];
43 		int VecTempWriteMask;
44 		int VecTempIndex;
45 		int ScaTempWriteMask;
46 		int OutputWriteMask;
47 		int OutputSelect;
48 		int OutputIndex;
49 		int MultiplexerControl;
50 		int Usea0x;
51 		int EndOfProgram;
52 	};
53 	fields f;
54 
55 	void decodefields(unsigned int *dwords, int offset, fields &decoded);
56 	int disassemble_mask(int mask, char *s);
57 	int disassemble_swizzle(sourcefields f, char *s);
58 	int disassemble_source(sourcefields f, fields fi, char *s);
59 	int disassemble_output(fields f, char *s);
60 	int output_types(fields f, int *o);
61 public:
vertex_program_disassembler()62 	vertex_program_disassembler() { state = 0; }
63 	int disassemble(unsigned int *instruction, char *line);
64 };
65 
66 /*
67  * geforce 3d (NV2A) vertex structure
68  */
69 struct vertex_nv {
70 	union {
71 		float fv[4];
72 		uint32_t iv[4];
73 	} attribute[16];
74 };
75 
76 /*
77  * geforce 3d (NV2A) vertex program simulator
78  */
79 class vertex_program_simulator {
80 public:
81 	enum VectorialOperation {
82 		VecNOP=0,
83 		VecMOV,
84 		VecMUL,
85 		VecADD,
86 		VecMAD,
87 		VecDP3,
88 		VecDPH,
89 		VecDP4,
90 		VecDST,
91 		VecMIN,
92 		VecMAX,
93 		VecSLT,
94 		VecSGE,
95 		VecARL
96 	};
97 	enum ScalarOperation {
98 		ScaNOP=0,
99 		ScaIMV,
100 		ScaRCP,
101 		ScaRCC,
102 		ScaRSQ,
103 		ScaEXP,
104 		ScaLOG,
105 		ScaLIT
106 	};
107 	vertex_program_simulator();
108 	// input vertex
109 	vertex_nv *input;
110 	// input parameters
111 	struct constant {
112 		float fv[4];
ivconstant113 		void iv(int idx, uint32_t value)
114 		{
115 			union
116 			{
117 				uint32_t i;
118 				float f;
119 			} cnv;
120 
121 			cnv.i = value;
122 			fv[idx] = cnv.f;
123 		}
124 	} c_constant[192];
125 	union temp {
126 		float fv[4];
127 	} r_register[32];
128 	// output vertex
129 	vertex_nv *output;
130 	// instructions
131 	struct instruction {
132 		unsigned int i[4];
133 		int modified;
134 		struct decoded {
135 			int SwizzleA[4], NegateA, ParameterTypeA, TempIndexA;
136 			int SwizzleB[4], NegateB, ParameterTypeB, TempIndexB;
137 			int SwizzleC[4], NegateC, ParameterTypeC, TempIndexC;
138 			VectorialOperation VecOperation;
139 			ScalarOperation ScaOperation;
140 			int OutputWriteMask, MultiplexerControl;
141 			int VecTempWriteMask, ScaTempWriteMask;
142 			int VecTempIndex, OutputIndex;
143 			int InputIndex;
144 			int SourceConstantIndex;
145 			int OutputSelect;
146 			int Usea0x;
147 			int EndOfProgram;
148 		} d;
149 	} op[256];
150 public:
151 	void set_data(vertex_nv *in, vertex_nv *out);
152 	void reset();
153 	int step();
154 	void decode_instruction(int address);
155 	void execute();
156 	void jump(int address);
157 	void process(int address, vertex_nv *in, vertex_nv *out, int count);
158 	int status();
159 private:
160 	void initialize_outputs();
161 	void initialize_temps();
162 	void initialize_constants();
163 	void generate_input(float t[4], int sign, int type, int temp, int swizzle[4]);
164 	void compute_vectorial_operation(float t[4], int instruction, float par[3 * 4]);
165 	void compute_scalar_operation(float t[4], int instruction, float par[3 * 4]);
166 	void assign_output(int index, float t[4], int mask);
167 	void assign_register(int index, float t[4], int mask);
168 	void assign_constant(int index, float t[4], int mask);
169 
170 	int ip;
171 	int a0x;
172 };
173 
174 struct Combiner {
175 	enum class InputRegister {
176 		Zero = 0,
177 		Color0,
178 		Color1,
179 		FogColor,
180 		PrimaryColor,
181 		SecondaryColor,
182 		Texture0Color = 8,
183 		Texture1Color,
184 		Texture2Color,
185 		Texture3Color,
186 		Spare0,
187 		Spare1,
188 		SumClamp,
189 		EF
190 	};
191 	enum class MapFunction {
192 		UnsignedIdentity = 0,
193 		UnsignedInvert,
194 		ExpandNormal,
195 		ExpandNegate,
196 		HalfBiasNormal,
197 		HalfBiasNegate,
198 		SignedIdentyty,
199 		SignedNegate
200 	};
201 	struct {
202 		struct {
203 			float A[4]; // 0=R 1=G 2=B 3=A
204 			float B[4];
205 			float C[4];
206 			float D[4];
207 			float E[4];
208 			float F[4];
209 			float G;
210 			float EF[4];
211 			float sumclamp[4];
212 		} variables;
213 		struct {
214 			float RGBop1[4]; // 0=R 1=G 2=B
215 			float RGBop2[4];
216 			float RGBop3[4];
217 			float Aop1;
218 			float Aop2;
219 			float Aop3;
220 		} functions;
221 		struct {
222 			float primarycolor[4]; // rw
223 			float secondarycolor[4];
224 			float texture0color[4];
225 			float texture1color[4];
226 			float texture2color[4];
227 			float texture3color[4];
228 			float color0[4];
229 			float color1[4];
230 			float spare0[4];
231 			float spare1[4];
232 			float fogcolor[4]; // ro
233 			float zero[4];
234 		} registers;
235 		float output[4];
236 	} work[WORK_MAX_THREADS];
237 	struct {
238 		struct {
239 			float constantcolor0[4];
240 			float constantcolor1[4];
241 			struct {
242 				InputRegister A_input;
243 				int A_component;
244 				MapFunction A_mapping;
245 				InputRegister B_input;
246 				int B_component;
247 				MapFunction B_mapping;
248 				InputRegister C_input;
249 				int C_component;
250 				MapFunction C_mapping;
251 				InputRegister D_input;
252 				int D_component;
253 				MapFunction D_mapping;
254 			} mapin_alpha;
255 			struct {
256 				InputRegister A_input;
257 				int A_component;
258 				MapFunction A_mapping;
259 				InputRegister B_input;
260 				int B_component;
261 				MapFunction B_mapping;
262 				InputRegister C_input;
263 				int C_component;
264 				MapFunction C_mapping;
265 				InputRegister D_input;
266 				int D_component;
267 				MapFunction D_mapping;
268 			} mapin_rgb;
269 			struct {
270 				InputRegister CD_output;
271 				InputRegister AB_output;
272 				InputRegister SUM_output;
273 				int CD_dotproduct;
274 				int AB_dotproduct;
275 				int muxsum;
276 				int bias;
277 				int scale;
278 			} mapout_alpha;
279 			struct {
280 				InputRegister CD_output;
281 				InputRegister AB_output;
282 				InputRegister SUM_output;
283 				int CD_dotproduct;
284 				int AB_dotproduct;
285 				int muxsum;
286 				int bias;
287 				int scale;
288 			} mapout_rgb;
289 		} stage[8];
290 		struct {
291 			float constantcolor0[4];
292 			float constantcolor1[4];
293 			int color_sum_clamp;
294 			struct {
295 				InputRegister G_input;
296 				int G_component;
297 				MapFunction G_mapping;
298 			} mapin_alpha;
299 			struct {
300 				InputRegister A_input;
301 				int A_component;
302 				MapFunction A_mapping;
303 				InputRegister B_input;
304 				int B_component;
305 				MapFunction B_mapping;
306 				InputRegister C_input;
307 				int C_component;
308 				MapFunction C_mapping;
309 				InputRegister D_input;
310 				int D_component;
311 				MapFunction D_mapping;
312 				InputRegister E_input;
313 				int E_component;
314 				MapFunction E_mapping;
315 				InputRegister F_input;
316 				int F_component;
317 				MapFunction F_mapping;
318 			} mapin_rgb;
319 		} final;
320 		int stages;
321 	} setup;
322 	int used;
323 };
324 
325 class nv2a_renderer; // forward declaration
326 struct nvidia_object_data
327 {
328 	nv2a_renderer *data;
329 };
330 
331 /*
332  * geforce 3d (NV2A) accelerator
333  */
334 /* very simplified view
335 there is a set of context objects
336 
337 context objects are stored in RAMIN
338 each context object is identified by an handle stored in RAMHT
339 
340 each context object can be assigned to a channel
341 to assign you give to the channel an handle for the object
342 
343 offset in ramht=(((((handle >> 11) xor handle) >> 11) xor handle) & 0x7ff)*8
344 offset in ramht contains the handle itself
345 offset in ramht+4 contains in the lower 16 bits the offset in RAMIN divided by 16
346 
347 objects have methods used to do drawing
348 most methods set parameters, others actually draw
349 */
350 
351 class nv2a_rasterizer : public poly_manager<double, nvidia_object_data, 26, 8192>
352 {
353 public:
nv2a_rasterizer(running_machine & machine)354 	nv2a_rasterizer(running_machine &machine) : poly_manager<double, nvidia_object_data, 26, 8192>(machine)
355 	{
356 	}
357 };
358 
359 class nv2a_renderer
360 {
361 public:
362 	enum class VERTEX_PARAMETER {
363 		PARAM_COLOR_B = 0,
364 		PARAM_COLOR_G,
365 		PARAM_COLOR_R,
366 		PARAM_COLOR_A,
367 		PARAM_TEXTURE0_S,
368 		PARAM_TEXTURE0_T,
369 		PARAM_TEXTURE0_R,
370 		PARAM_TEXTURE0_Q,
371 		PARAM_TEXTURE1_S,
372 		PARAM_TEXTURE1_T,
373 		PARAM_TEXTURE1_R,
374 		PARAM_TEXTURE1_Q,
375 		PARAM_TEXTURE2_S,
376 		PARAM_TEXTURE2_T,
377 		PARAM_TEXTURE2_R,
378 		PARAM_TEXTURE2_Q,
379 		PARAM_TEXTURE3_S,
380 		PARAM_TEXTURE3_T,
381 		PARAM_TEXTURE3_R,
382 		PARAM_TEXTURE3_Q,
383 		PARAM_SECONDARY_COLOR_B,
384 		PARAM_SECONDARY_COLOR_G,
385 		PARAM_SECONDARY_COLOR_R,
386 		PARAM_SECONDARY_COLOR_A,
387 		PARAM_Z,
388 		PARAM_1W,
389 		ALL
390 	};
391 	enum class NV2A_BEGIN_END {
392 		STOP = 0,
393 		POINTS = 1,
394 		LINES = 2,
395 		LINE_LOOP = 3,
396 		LINE_STRIP = 4,
397 		TRIANGLES = 5,
398 		TRIANGLE_STRIP = 6,
399 		TRIANGLE_FAN = 7,
400 		QUADS = 8,
401 		QUAD_STRIP = 9,
402 		POLYGON = 10
403 	};
404 	enum class NV2A_VERTEX_ATTR {
405 		POS = 0, // position
406 		WEIGHT = 1, // blend weight
407 		NORMAL = 2,
408 		COLOR0 = 3, // diffuse
409 		COLOR1 = 4, // specular
410 		FOG = 5,
411 		BACKCOLOR0 = 7, // back diffuse
412 		BACKCOLOR1 = 8, // back specular
413 		TEX0 = 9, // texture coordinate
414 		TEX1 = 10,
415 		TEX2 = 11,
416 		TEX3 = 12
417 	};
418 	enum class NV2A_VTXBUF_TYPE {
419 		UBYTE_D3D = 0, // what is the difference with opengl UBYTE ?
420 		FLOAT = 2,
421 		UBYTE_OGL = 4,
422 		USHORT = 5,
423 		FLOAT_PACKED = 6 // used for vertex color
424 	};
425 	enum class NV2A_TEX_FORMAT {
426 		L8 = 0x0,
427 		I8 = 0x1,
428 		A1R5G5B5 = 0x2,
429 		A4R4G4B4 = 0x4,
430 		R5G6B5 = 0x5,
431 		A8R8G8B8 = 0x6,
432 		X8R8G8B8 = 0x7,
433 		INDEX8 = 0xb,
434 		DXT1 = 0xc,
435 		DXT3 = 0xe,
436 		DXT5 = 0xf,
437 		A1R5G5B5_RECT = 0x10,
438 		R5G6B5_RECT = 0x11,
439 		A8R8G8B8_RECT = 0x12,
440 		L8_RECT = 0x13,
441 		DSDT8_RECT = 0x17,
442 		A8 = 0x19,
443 		A8L8 = 0x1a,
444 		I8_RECT = 0x1b,
445 		A4R4G4B4_RECT = 0x1d,
446 		R8G8B8_RECT = 0x1e,
447 		A8L8_RECT = 0x20,
448 		Z24 = 0x2a,
449 		Z24_RECT = 0x2b,
450 		Z16 = 0x2c,
451 		Z16_RECT = 0x2d,
452 		DSDT8 = 0x28,
453 		HILO16 = 0x33,
454 		HILO16_RECT = 0x36,
455 		HILO8 = 0x44,
456 		SIGNED_HILO8 = 0x45,
457 		HILO8_RECT = 0x46,
458 		SIGNED_HILO8_RECT = 0x47
459 	};
460 	enum class NV2A_LOGIC_OP {
461 		CLEAR = 0x1500,
462 		AND = 0x1501,
463 		AND_REVERSE = 0x1502,
464 		COPY = 0x1503,
465 		AND_INVERTED = 0x1504,
466 		NOOP = 0x1505,
467 		XOR = 0x1506,
468 		OR = 0x1507,
469 		NOR = 0x1508,
470 		EQUIV = 0x1509,
471 		INVERT = 0x150a,
472 		OR_REVERSE = 0x150b,
473 		COPY_INVERTED = 0x150c,
474 		OR_INVERTED = 0x150d,
475 		NAND = 0x150e,
476 		SET = 0x150f
477 	};
478 	enum class NV2A_BLEND_EQUATION {
479 		FUNC_ADD = 0x8006,
480 		MIN = 0x8007,
481 		MAX = 0x8008,
482 		FUNC_SUBTRACT = 0x800a,
483 		FUNC_REVERSE_SUBTRACT = 0x80b
484 	};
485 	enum class NV2A_BLEND_FACTOR {
486 		ZERO = 0x0000,
487 		ONE = 0x0001,
488 		SRC_COLOR = 0x0300,
489 		ONE_MINUS_SRC_COLOR = 0x0301,
490 		SRC_ALPHA = 0x0302,
491 		ONE_MINUS_SRC_ALPHA = 0x0303,
492 		DST_ALPHA = 0x0304,
493 		ONE_MINUS_DST_ALPHA = 0x0305,
494 		DST_COLOR = 0x0306,
495 		ONE_MINUS_DST_COLOR = 0x0307,
496 		SRC_ALPHA_SATURATE = 0x0308,
497 		CONSTANT_COLOR = 0x8001,
498 		ONE_MINUS_CONSTANT_COLOR = 0x8002,
499 		CONSTANT_ALPHA = 0x8003,
500 		ONE_MINUS_CONSTANT_ALPHA = 0x8004
501 	};
502 	enum class NV2A_COMPARISON_OP {
503 		NEVER = 0x0200,
504 		LESS = 0x0201,
505 		EQUAL = 0x0202,
506 		LEQUAL = 0x0203,
507 		GREATER = 0x0204,
508 		NOTEQUAL = 0x0205,
509 		GEQUAL = 0x0206,
510 		ALWAYS = 0x0207
511 	};
512 	enum class NV2A_STENCIL_OP {
513 		ZEROOP = 0x0000,
514 		INVERTOP = 0x150a,
515 		KEEP = 0x1e00,
516 		REPLACE = 0x1e01,
517 		INCR = 0x1e02,
518 		DECR = 0x1e03,
519 		INCR_WRAP = 0x8507,
520 		DECR_WRAP = 0x8508
521 	};
522 	enum class NV2A_RT_TYPE {
523 		LINEAR = 1,
524 		SWIZZLED = 2
525 	};
526 	enum class NV2A_RT_DEPTH_FORMAT {
527 		Z16 = 0x0001,
528 		Z24S8 = 0x0002
529 	};
530 	enum class NV2A_COLOR_FORMAT {
531 		X1R5G5B5_Z1R5G5B5 = 1,
532 		X1R5G5B5_X1R5G5B5 = 2,
533 		R5G6B5 = 3,
534 		X8R8G8B8_Z8R8G8B8 = 4,
535 		X8R8G8B8_X8R8G8B8 = 5,
536 		X1A7R8G8B8_Z1A7R8G8B8 = 6,
537 		X1A7R8G8B8_X1A7R8G8B8 = 7,
538 		A8R8G8B8 = 8,
539 		B8 = 9,
540 		G8B8 = 10
541 	};
542 	enum class NV2A_GL_FRONT_FACE {
543 		CW = 0x0900,
544 		CCW = 0x0901
545 	};
546 	enum class NV2A_GL_CULL_FACE {
547 		FRONT = 0x0404,
548 		BACK = 0x0405,
549 		FRONT_AND_BACK = 0x0408
550 	};
551 	enum class COMMAND {
552 		CALL = 7,
553 		JUMP = 6,
554 		NON_INCREASING = 5,
555 		OLD_JUMP = 4,
556 		LONG_NON_INCREASING = 3,
557 		RETURN = 2,
558 		SLI_CONDITIONAL = 1,
559 		INCREASING = 0,
560 		INVALID = -1
561 	};
562 
563 	struct nv2avertex_t : public nv2a_rasterizer::vertex_t
564 	{
565 		double w;
566 	};
567 
nv2a_renderer(running_machine & machine)568 	nv2a_renderer(running_machine &machine)
569 		: rasterizer(machine)
570 		, mach(machine)
571 	{
572 		memset(channel, 0, sizeof(channel));
573 		memset(pfifo, 0, sizeof(pfifo));
574 		memset(pcrtc, 0, sizeof(pcrtc));
575 		memset(pmc, 0, sizeof(pmc));
576 		memset(pgraph, 0, sizeof(pgraph));
577 		memset(ramin, 0, sizeof(ramin));
578 		computedilated();
579 		objectdata = &(rasterizer.object_data_alloc());
580 		objectdata->data = this;
581 		combiner.used = 0;
582 		primitives_total_count = 0;
583 		primitives_batches_count = 0;
584 		indexesleft_count = 0;
585 		triangles_bfculled = 0;
586 		vertex_pipeline = 4;
587 		color_mask = 0xffffffff;
588 		backface_culling_enabled = false;
589 		backface_culling_winding = NV2A_GL_FRONT_FACE::CCW;
590 		backface_culling_culled = NV2A_GL_CULL_FACE::BACK;
591 		alpha_test_enabled = false;
592 		alpha_reference = 0;
593 		alpha_func = NV2A_COMPARISON_OP::ALWAYS;
594 		depth_test_enabled = false;
595 		depth_function = NV2A_COMPARISON_OP::LESS;
596 		depth_write_enabled = false;
597 		stencil_test_enabled = false;
598 		stencil_func = NV2A_COMPARISON_OP::ALWAYS;
599 		stencil_ref = 0;
600 		stencil_mask = -1;
601 		stencil_op_fail = NV2A_STENCIL_OP::KEEP;
602 		stencil_op_zfail = NV2A_STENCIL_OP::KEEP;
603 		stencil_op_zpass = NV2A_STENCIL_OP::KEEP;
604 		blending_enabled = false;
605 		blend_equation = NV2A_BLEND_EQUATION::FUNC_ADD;
606 		blend_color = 0;
607 		blend_function_destination = NV2A_BLEND_FACTOR::ZERO;
608 		blend_function_source = NV2A_BLEND_FACTOR::ONE;
609 		logical_operation_enabled = false;
610 		logical_operation = NV2A_LOGIC_OP::COPY;
611 		fog_color = 0;
612 		for (int n = 0; n < 4; n++) {
613 			texture[n].enabled = 0;
614 			texture[n].mode = 0;
615 			texture[n].addrmodes = 1;
616 			texture[n].addrmodet = 1;
617 			texture[n].addrmoder = 1;
618 		}
619 		for (int n = 0; n < 8; n++)
620 			clippingwindows[n].set(0, 0, 640, 480);
621 		limits_rendertarget.set(0, 0, 640, 480);
622 		pitch_rendertarget = 0;
623 		pitch_depthbuffer = 0;
624 		size_rendertarget = 0;
625 		size_depthbuffer = 0;
626 		log2height_rendertarget = 0;
627 		log2width_rendertarget = 0;
628 		dilate_rendertarget = 0;
629 		antialiasing_rendertarget = 0;
630 		type_rendertarget = NV2A_RT_TYPE::LINEAR;
631 		depthformat_rendertarget = NV2A_RT_DEPTH_FORMAT::Z24S8;
632 		colorformat_rendertarget = NV2A_COLOR_FORMAT::A8R8G8B8;
633 		bytespixel_rendertarget = 4;
634 		clear_rendertarget.set(0, 0, 639, 479);
635 		primitive_type = NV2A_BEGIN_END::STOP;
636 		antialias_control = 0;
637 		supersample_factor_x = 1.0;
638 		supersample_factor_y = 1.0;
639 		rendertarget = nullptr;
640 		depthbuffer = nullptr;
641 		displayedtarget = nullptr;
642 		old_rendertarget = nullptr;
643 		puller_waiting = 0;
644 		debug_grab_texttype = -1;
645 		debug_grab_textfile = nullptr;
646 		enable_waitvblank = true;
647 		enable_clipping_w = false;
648 		memset(&vertexbuffer, 0, sizeof(vertexbuffer));
649 		memset(&persistvertexattr, 0, sizeof(persistvertexattr));
650 		for (int n = 0; n < 16; n++)
651 			persistvertexattr.attribute[n].fv[3] = 1;
652 	}
machine()653 	running_machine &machine() { return mach; }
654 	uint32_t geforce_r(offs_t offset, uint32_t mem_mask = ~0);
655 	void geforce_w(address_space &space, offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
656 	DECLARE_WRITE_LINE_MEMBER(vblank_callback);
657 	uint32_t screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
658 	bool update_interrupts();
set_irq_callbaclk(std::function<void (int state)> callback)659 	void set_irq_callbaclk(std::function<void(int state)> callback) { irq_callback = callback; }
660 
661 	void render_texture_simple(int32_t scanline, const nv2a_rasterizer::extent_t &extent, const nvidia_object_data &extradata, int threadid);
662 	void render_color(int32_t scanline, const nv2a_rasterizer::extent_t &extent, const nvidia_object_data &extradata, int threadid);
663 	void render_register_combiners(int32_t scanline, const nv2a_rasterizer::extent_t &extent, const nvidia_object_data &objectdata, int threadid);
664 
665 	COMMAND geforce_commandkind(uint32_t word);
666 	uint32_t geforce_object_offset(uint32_t handle);
667 	void geforce_read_dma_object(uint32_t handle, uint32_t &offset, uint32_t &size);
668 	void geforce_assign_object(address_space &space, uint32_t chanel, uint32_t subchannel, uint32_t address);
669 	int execute_method(address_space &space, uint32_t channel, uint32_t subchannel, uint32_t method, uint32_t address, int &countlen);
670 	int execute_method_3d(address_space &space, uint32_t chanel, uint32_t subchannel, uint32_t maddress, uint32_t address, uint32_t data, int &countlen);
671 	int execute_method_m2mf(address_space &space, uint32_t chanel, uint32_t subchannel, uint32_t maddress, uint32_t address, uint32_t data, int &countlen);
672 	int execute_method_surf2d(address_space &space, uint32_t chanel, uint32_t subchannel, uint32_t maddress, uint32_t address, uint32_t data, int &countlen);
673 	int execute_method_blit(address_space &space, uint32_t chanel, uint32_t subchannel, uint32_t maddress, uint32_t address, uint32_t data, int &countlen);
674 	void surface_2d_blit();
675 	uint32_t texture_get_texel(int number, int x, int y);
676 	uint8_t *read_pixel(int x, int y, int32_t c[4]);
677 	void write_pixel(int x, int y, uint32_t color, int z);
678 	void combiner_initialize_registers(int id, float rgba[6][4]);
679 	void combiner_initialize_stage(int id, int stage_number);
680 	void combiner_initialize_final(int id);
681 	void combiner_map_stage_input(int id, int stage_number); // map combiner registers to variables A..D
682 	void combiner_map_stage_output(int id, int stage_number); // map combiner calculation results to combiner registers
683 	void combiner_map_final_input(int id); // map final combiner registers to variables A..F
684 	void combiner_final_output(int id); // generate final combiner output
685 	float combiner_map_input_select(int id, Combiner::InputRegister code, int index); // get component index in register selected as input
686 	float *combiner_map_input_select_array(int id, Combiner::InputRegister code); // get pointer to register selected as input
687 	float *combiner_map_output_select_array(int id, Combiner::InputRegister code); // get pointer to register selected as output
688 	float combiner_map_input_function(Combiner::MapFunction code, float value); // apply input mapping function code to value
689 	void combiner_map_input_function_array(Combiner::MapFunction code, float *data); // apply input mapping function code to data
690 	void combiner_function_AB(int id, float result[4]); // calculate values for possible outputs
691 	void combiner_function_AdotB(int id, float result[4]);
692 	void combiner_function_CD(int id, float result[4]);
693 	void combiner_function_CdotD(int id, float result[4]);
694 	void combiner_function_ABmuxCD(int id, float result[4]);
695 	void combiner_function_ABsumCD(int id, float result[4]);
696 	void combiner_compute_rgb_outputs(int id, int index);
697 	void combiner_compute_alpha_outputs(int id, int index);
698 	void combiner_argb8_float(uint32_t color, float reg[4]); // convert from color to float array
699 	uint32_t combiner_float_argb8(float reg[4]); // convert from float array to color
700 	uint32_t dilate0(uint32_t value, int bits);
701 	uint32_t dilate1(uint32_t value, int bits);
702 	void computedilated(void);
703 	bool toggle_register_combiners_usage();
704 	bool toggle_wait_vblank_support();
705 	bool toggle_clipping_w_support();
706 	void debug_grab_texture(int type, const char *filename);
707 	void debug_grab_vertex_program_slot(int slot, uint32_t *instruction);
708 	void start(address_space *cpu_space);
709 	void set_ram_base(void *base);
710 	void savestate_items();
711 	void compute_supersample_factors(float &horizontal, float &vertical);
712 	void compute_limits_rendertarget(uint32_t chanel, uint32_t subchannel);
713 	void compute_size_rendertarget(uint32_t chanel, uint32_t subchannel);
714 	void extract_packed_float(uint32_t data, float &first, float &second, float &third);
715 	void read_vertex(address_space &space, offs_t address, vertex_nv &vertex, int attrib);
716 	int read_vertices_0x180x(address_space &space, int destination, uint32_t address, int limit);
717 	int read_vertices_0x1810(address_space &space, int destination, int offset, int limit);
718 	int read_vertices_0x1818(address_space &space, int destination, uint32_t address, int limit);
719 	void convert_vertices(vertex_nv *source, nv2avertex_t *destination);
720 	void assemble_primitive(int source, int count);
721 	void process_persistent_vertex();
722 	int clip_triangle_w(nv2avertex_t vi[3], nv2avertex_t *vo);
723 	uint32_t render_triangle_clipping(const rectangle &cliprect, nv2avertex_t &_v1, nv2avertex_t &_v2, nv2avertex_t &_v3);
724 	uint32_t render_triangle_culling(const rectangle &cliprect, nv2avertex_t &_v1, nv2avertex_t &_v2, nv2avertex_t &_v3);
725 	void clear_render_target(int what, uint32_t value);
726 	void clear_depth_buffer(int what, uint32_t value);
727 	inline uint8_t *direct_access_ptr(offs_t address);
728 	TIMER_CALLBACK_MEMBER(puller_timer_work);
729 
730 	nv2a_rasterizer rasterizer;
731 	running_machine &mach;
732 	struct {
733 		uint32_t regs[0x80 / 4];
734 		struct {
735 			uint32_t offset;
736 			uint32_t objclass;
737 			uint32_t method[0x2000 / 4];
738 		} object;
739 	} channel[32][8];
740 	uint32_t pfifo[0x2000 / 4];
741 	uint32_t pcrtc[0x1000 / 4];
742 	uint32_t pmc[0x1000 / 4];
743 	uint32_t pgraph[0x2000 / 4];
744 	uint32_t ramin[0x100000 / 4];
745 	uint32_t dma_offset[13];
746 	uint32_t dma_size[13];
747 	uint8_t *basemempointer;
748 	uint8_t *topmempointer;
749 	std::function<void(int state)> irq_callback;
750 	rectangle clippingwindows[8];
751 	rectangle limits_rendertarget;
752 	uint32_t pitch_rendertarget;
753 	uint32_t pitch_depthbuffer;
754 	uint32_t size_rendertarget;
755 	uint32_t size_depthbuffer;
756 	int log2height_rendertarget;
757 	int log2width_rendertarget;
758 	int dilate_rendertarget;
759 	int antialiasing_rendertarget;
760 	NV2A_RT_TYPE type_rendertarget;
761 	NV2A_RT_DEPTH_FORMAT depthformat_rendertarget;
762 	NV2A_COLOR_FORMAT colorformat_rendertarget;
763 	int bytespixel_rendertarget;
764 	rectangle clear_rendertarget;
765 	uint32_t antialias_control;
766 	float supersample_factor_x;
767 	float supersample_factor_y;
768 	uint32_t *rendertarget;
769 	uint32_t *depthbuffer;
770 	uint32_t *displayedtarget;
771 	uint32_t *old_rendertarget;
772 	struct {
773 		uint32_t address[16];
774 		int type[16];
775 		int stride[16];
776 		int words[16];
777 		int offset[16 + 1];
778 		int enabled; // bitmask
779 	} vertexbuffer;
780 	struct {
781 		int enabled;
782 		int sizes;
783 		int sizet;
784 		int sizer;
785 		int dilate;
786 		NV2A_TEX_FORMAT format;
787 		bool rectangle;
788 		int rectangle_pitch;
789 		void *buffer;
790 		int dma0;
791 		int dma1;
792 		int mode;
793 		int cubic;
794 		int noborder;
795 		int dims;
796 		int mipmap;
797 		int colorkey;
798 		int imagefield;
799 		int aniso;
800 		int mipmapmaxlod;
801 		int mipmapminlod;
802 		int rectheight;
803 		int rectwidth;
804 		int addrmodes;
805 		int addrmodet;
806 		int addrmoder;
807 	} texture[4];
808 	uint32_t triangles_bfculled;
809 	NV2A_BEGIN_END primitive_type;
810 	uint32_t primitives_count;
811 	uint32_t primitives_total_count;
812 	uint32_t primitives_batches_count;
813 	int indexesleft_count;
814 	int indexesleft_first;
815 	uint32_t vertex_indexes[1024]; // vertex indices sent by the software to the 3d accelerator
816 	int vertex_count;
817 	unsigned int vertex_first;
818 	int vertex_accumulated;
819 	vertex_nv vertex_software[1024+2]; // vertex attributes sent by the software to the 3d accelerator
820 	nv2avertex_t vertex_xy[1024+2]; // vertex attributes computed by the 3d accelerator
821 	vertex_nv persistvertexattr; // persistent vertex attributes
822 	nv2a_rasterizer::render_delegate render_spans_callback;
823 	Combiner combiner;
824 	uint32_t color_mask;
825 	bool backface_culling_enabled;
826 	NV2A_GL_FRONT_FACE backface_culling_winding;
827 	NV2A_GL_CULL_FACE backface_culling_culled;
828 	bool alpha_test_enabled;
829 	bool depth_test_enabled;
830 	bool stencil_test_enabled;
831 	bool depth_write_enabled;
832 	bool blending_enabled;
833 	bool logical_operation_enabled;
834 	NV2A_COMPARISON_OP alpha_func;
835 	int alpha_reference;
836 	NV2A_COMPARISON_OP depth_function;
837 	NV2A_COMPARISON_OP stencil_func;
838 	int stencil_ref;
839 	int stencil_mask;
840 	NV2A_STENCIL_OP stencil_op_fail;
841 	NV2A_STENCIL_OP stencil_op_zfail;
842 	NV2A_STENCIL_OP stencil_op_zpass;
843 	NV2A_BLEND_EQUATION blend_equation;
844 	NV2A_BLEND_FACTOR blend_function_source;
845 	NV2A_BLEND_FACTOR blend_function_destination;
846 	uint32_t blend_color;
847 	NV2A_LOGIC_OP logical_operation;
848 	uint32_t fog_color;
849 	struct {
850 		float modelview[4][4];
851 		float modelview_inverse[4][4];
852 		float composite[4][4];
853 		float projection[4][4];
854 		float translate[4];
855 		float scale[4];
856 	} matrix;
857 	struct {
858 		vertex_program_simulator exec;
859 		int instructions;
860 		int upload_instruction_index;
861 		int upload_instruction_component;
862 		int start_instruction;
863 		int upload_parameter_index;
864 		int upload_parameter_component;
865 	} vertexprogram;
866 	int vertex_pipeline;
867 
868 	struct {
869 		int format;
870 		uint32_t pitch_source;
871 		uint32_t pitch_destination;
872 		offs_t source_address;
873 		offs_t destination_address;
874 		int op;
875 		int width;
876 		int heigth;
877 		uint32_t sourcex;
878 		uint32_t sourcey;
879 		uint32_t destinationx;
880 		uint32_t destinationy;
881 	} bitblit;
882 	emu_timer *puller_timer;
883 	int puller_waiting;
884 	address_space *puller_space;
885 	uint32_t dilated0[16][2048];
886 	uint32_t dilated1[16][2048];
887 	int dilatechose[256];
888 	nvidia_object_data *objectdata;
889 	int debug_grab_texttype;
890 	char *debug_grab_textfile;
891 	bool enable_waitvblank;
892 	bool enable_clipping_w;
893 };
894 
895 #endif // MAME_INCLUDES_XBOX_NV2A_H
896