summaryrefslogtreecommitdiff
path: root/shared-core/radeon_ms.h
blob: ec26420781b4780986081f17f457e37a04d6f504 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
/*
 * Copyright 2007 Jérôme Glisse
 * Copyright 2007 Dave Airlie
 * Copyright 2007 Alex Deucher
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
/*
 * Authors:
 *    Jérôme Glisse <glisse@freedesktop.org>
 */
#ifndef __RADEON_MS_H__
#define __RADEON_MS_H__

#include "radeon_ms_drv.h"
#include "radeon_ms_reg.h"
#include "radeon_ms_drm.h"
#include "radeon_ms_rom.h"
#include "radeon_ms_properties.h"
#include "amd.h"
#include "amd_legacy.h"

#define DRIVER_AUTHOR      "Jerome Glisse, Dave Airlie,  Gareth Hughes, "\
			   "Keith Whitwell, others."
#define DRIVER_NAME        "radeon_ms"
#define DRIVER_DESC        "radeon kernel modesetting"
#define DRIVER_DATE        "20071108"
#define DRIVER_MAJOR        1
#define DRIVER_MINOR        0
#define DRIVER_PATCHLEVEL   0

enum radeon_bus_type {
	RADEON_PCI = 0x10000,
	RADEON_AGP = 0x20000,
	RADEON_PCIE = 0x30000,
};

enum radeon_family {
	CHIP_R100,
	CHIP_RV100,
	CHIP_RS100,
	CHIP_RV200,
	CHIP_RS200,
	CHIP_R200,
	CHIP_RV250,
	CHIP_RS300,
	CHIP_RV280,
	CHIP_R300,
	CHIP_R350,
	CHIP_R360,
	CHIP_RV350,
	CHIP_RV370,
	CHIP_RV380,
	CHIP_RS400,
	CHIP_RV410,
	CHIP_R420,
	CHIP_R430,
	CHIP_R480,
	CHIP_LAST,
};

enum radeon_monitor_type {
	MT_UNKNOWN = -1,
	MT_NONE    = 0,
	MT_CRT     = 1,
	MT_LCD     = 2,
	MT_DFP     = 3,
	MT_CTV     = 4,
	MT_STV     = 5
};

enum radeon_connector_type {
	CONNECTOR_NONE,
	CONNECTOR_PROPRIETARY,
	CONNECTOR_VGA,
	CONNECTOR_DVI_I,
	CONNECTOR_DVI_D,
	CONNECTOR_CTV,
	CONNECTOR_STV,
	CONNECTOR_UNSUPPORTED
};

enum radeon_output_type {
	OUTPUT_NONE,
	OUTPUT_DAC1,
	OUTPUT_DAC2,
	OUTPUT_TMDS,
	OUTPUT_LVDS
};

struct radeon_state;

struct radeon_ms_crtc {
	int             crtc;
	uint16_t	lut_r[256];
	uint16_t	lut_g[256];
	uint16_t	lut_b[256];
};

struct radeon_ms_i2c {
	struct drm_device           *drm_dev;
	uint32_t    	            reg;
	struct i2c_adapter          adapter;
	struct i2c_algo_bit_data    algo;
};

struct radeon_ms_connector {
	struct radeon_ms_i2c    *i2c;
	struct edid             *edid;
	struct drm_output       *output;
	int                     type;
	int                     monitor_type;
	int                     crtc;
	uint32_t    	        i2c_reg;
	char                    outputs[RADEON_MAX_OUTPUTS];
	char                    name[32];
};

struct radeon_ms_output {
	int                         type;
	struct drm_device           *dev;
	struct radeon_ms_connector  *connector;
	int (*initialize)(struct radeon_ms_output *output);
	enum drm_output_status (*detect)(struct radeon_ms_output *output);
	void (*dpms)(struct radeon_ms_output *output, int mode);
	int (*get_modes)(struct radeon_ms_output *output);
	bool (*mode_fixup)(struct radeon_ms_output *output,
			struct drm_display_mode *mode,
			struct drm_display_mode *adjusted_mode);
	int (*mode_set)(struct radeon_ms_output *output,
			struct drm_display_mode *mode,
			struct drm_display_mode *adjusted_mode);
	void (*restore)(struct radeon_ms_output *output,
			struct radeon_state *state);
	void (*save)(struct radeon_ms_output *output,
			struct radeon_state *state);
};

struct radeon_state {
	/* memory */
	uint32_t        config_aper_0_base;
	uint32_t        config_aper_1_base;
	uint32_t        config_aper_size;
	uint32_t        mc_fb_location;
	uint32_t        display_base_addr;
	/* irq */
	uint32_t	gen_int_cntl;
	/* pci */
	uint32_t        aic_ctrl;
	uint32_t        aic_pt_base;
	uint32_t        aic_pt_base_lo;
	uint32_t        aic_pt_base_hi;
	uint32_t        aic_lo_addr;
	uint32_t        aic_hi_addr;
	/* agp */
	uint32_t        agp_cntl;
	uint32_t        agp_command;
	uint32_t        agp_base;
	uint32_t        agp_base_2;
	uint32_t        bus_cntl;
	uint32_t        mc_agp_location;
	/* cp */
	uint32_t        cp_rb_cntl;
	uint32_t        cp_rb_base;
	uint32_t        cp_rb_rptr_addr;
	uint32_t        cp_rb_wptr;
	uint32_t        cp_rb_wptr_delay;
	uint32_t        scratch_umsk;
	uint32_t        scratch_addr;
	/* pcie */
	uint32_t        pcie_tx_gart_cntl;
	uint32_t        pcie_tx_gart_discard_rd_addr_lo;
	uint32_t        pcie_tx_gart_discard_rd_addr_hi;
	uint32_t        pcie_tx_gart_base;
	uint32_t        pcie_tx_gart_start_lo;
	uint32_t        pcie_tx_gart_start_hi;
	uint32_t        pcie_tx_gart_end_lo;
	uint32_t        pcie_tx_gart_end_hi;
	/* surface */
	uint32_t        surface_cntl;
	uint32_t        surface0_info;
	uint32_t        surface0_lower_bound;
	uint32_t        surface0_upper_bound;
	uint32_t        surface1_info;
	uint32_t        surface1_lower_bound;
	uint32_t        surface1_upper_bound;
	uint32_t        surface2_info;
	uint32_t        surface2_lower_bound;
	uint32_t        surface2_upper_bound;
	uint32_t        surface3_info;
	uint32_t        surface3_lower_bound;
	uint32_t        surface3_upper_bound;
	uint32_t        surface4_info;
	uint32_t        surface4_lower_bound;
	uint32_t        surface4_upper_bound;
	uint32_t        surface5_info;
	uint32_t        surface5_lower_bound;
	uint32_t        surface5_upper_bound;
	uint32_t        surface6_info;
	uint32_t        surface6_lower_bound;
	uint32_t        surface6_upper_bound;
	uint32_t        surface7_info;
	uint32_t        surface7_lower_bound;
	uint32_t        surface7_upper_bound;
	/* crtc */
	uint32_t        crtc_gen_cntl;
	uint32_t        crtc_ext_cntl;
	uint32_t        crtc_h_total_disp;
	uint32_t        crtc_h_sync_strt_wid;
	uint32_t        crtc_v_total_disp;
	uint32_t        crtc_v_sync_strt_wid;
	uint32_t        crtc_offset;
	uint32_t        crtc_offset_cntl;
	uint32_t        crtc_pitch;
	uint32_t        crtc_more_cntl;
	uint32_t        crtc_tile_x0_y0;
	uint32_t        fp_h_sync_strt_wid;
	uint32_t        fp_v_sync_strt_wid;
	uint32_t        fp_crtc_h_total_disp;
	uint32_t        fp_crtc_v_total_disp;
	/* pll */
	uint32_t        clock_cntl_index;
	uint32_t        ppll_cntl;
	uint32_t        ppll_ref_div;
	uint32_t        ppll_div_0;
	uint32_t        ppll_div_1;
	uint32_t        ppll_div_2;
	uint32_t        ppll_div_3;
	uint32_t        vclk_ecp_cntl;
	uint32_t        htotal_cntl;
	/* dac */
	uint32_t        dac_cntl;
	uint32_t        dac_cntl2;
	uint32_t        dac_ext_cntl;
	uint32_t        disp_misc_cntl;
	uint32_t        dac_macro_cntl;
	uint32_t        disp_pwr_man;
	uint32_t        disp_merge_cntl;
	uint32_t        disp_output_cntl;
	uint32_t        disp2_merge_cntl;
	uint32_t        dac_embedded_sync_cntl;
	uint32_t        dac_broad_pulse;
	uint32_t        dac_skew_clks;
	uint32_t        dac_incr;
	uint32_t        dac_neg_sync_level;
	uint32_t        dac_pos_sync_level;
	uint32_t        dac_blank_level;
	uint32_t        dac_sync_equalization;
	uint32_t        tv_dac_cntl;
	uint32_t        tv_master_cntl;
};

struct drm_radeon_private {
	/* driver family specific functions */
	int (*bus_finish)(struct drm_device *dev);
	int (*bus_init)(struct drm_device *dev);
	void (*bus_restore)(struct drm_device *dev, struct radeon_state *state);
	void (*bus_save)(struct drm_device *dev, struct radeon_state *state);
	struct drm_ttm_backend *(*create_ttm)(struct drm_device *dev);
	void (*irq_emit)(struct drm_device *dev);
	void (*flush_cache)(struct drm_device *dev);
	/* bus informations */
	void                        *bus;
	uint32_t                    bus_type;
	/* cp */
	uint32_t                    ring_buffer_size;
	uint32_t                    ring_rptr;
	uint32_t                    ring_wptr;
	uint32_t                    ring_mask;
	int                         ring_free;
	uint32_t                    ring_tail_mask;
	uint32_t                    write_back_area_size;
	struct drm_buffer_object    *ring_buffer_object;
	struct drm_bo_kmap_obj      ring_buffer_map;
	uint32_t                    *ring_buffer;
	uint32_t                    *write_back_area;
	const uint32_t              *microcode;
	/* framebuffer */
	struct amd_fb               *fb;
	/* card family */
	uint32_t                    usec_timeout;
	uint32_t                    family;
	struct radeon_ms_output     *outputs[RADEON_MAX_OUTPUTS];
	struct radeon_ms_connector  *connectors[RADEON_MAX_CONNECTORS];
	/* drm map (MMIO, FB) */
	struct drm_map              mmio;
	struct drm_map              vram;
	/* gpu address space */
	uint32_t                    gpu_vram_size;
	uint32_t                    gpu_vram_start;
	uint32_t                    gpu_vram_end;
	uint32_t                    gpu_gart_size;
	uint32_t                    gpu_gart_start;
	uint32_t                    gpu_gart_end;
	/* state of the card when module was loaded */
	struct radeon_state         load_state;
	/* state the driver wants */
	struct radeon_state         driver_state;
	/* last emitted fence */
	uint32_t                    fence_id_last;
	uint32_t                    fence_reg;
	/* when doing gpu stop we save here current state */
	uint32_t                    crtc_ext_cntl;
	uint32_t                    crtc_gen_cntl;
	uint32_t                    crtc2_gen_cntl;
	uint32_t                    ov0_scale_cntl;
	/* bool & type on the hw */
	uint8_t                     crtc1_dpms;
	uint8_t                     crtc2_dpms;
	uint8_t                     restore_state;
	uint8_t                     cp_ready;
	uint8_t                     bus_ready;
	uint8_t                     write_back;
	/* command buffer informations */
	struct amd_cbuffer_checker  cbuffer_checker;
	/* abstract asic specific structures */
	struct radeon_ms_rom        rom;
	struct radeon_ms_properties properties;
	void                        *fence;
};


/* radeon_ms_bo.c */
int radeon_ms_bo_get_gpu_addr(struct drm_device *dev,
			      struct drm_bo_mem_reg *mem,
			      uint32_t *gpu_addr);
int radeon_ms_bo_move(struct drm_buffer_object * bo, int evict,
		      int no_wait, struct drm_bo_mem_reg * new_mem);
struct drm_ttm_backend *radeon_ms_create_ttm_backend(struct drm_device * dev);
uint64_t radeon_ms_evict_flags(struct drm_buffer_object *bo);
int radeon_ms_init_mem_type(struct drm_device * dev, uint32_t type,
			    struct drm_mem_type_manager * man);
int radeon_ms_invalidate_caches(struct drm_device * dev, uint64_t flags);
void radeon_ms_ttm_flush(struct drm_ttm *ttm);

/* radeon_ms_bus.c */
int radeon_ms_agp_finish(struct drm_device *dev);
int radeon_ms_agp_init(struct drm_device *dev);
void radeon_ms_agp_restore(struct drm_device *dev, struct radeon_state *state);
void radeon_ms_agp_save(struct drm_device *dev, struct radeon_state *state);
struct drm_ttm_backend *radeon_ms_pcie_create_ttm(struct drm_device *dev);
int radeon_ms_pcie_finish(struct drm_device *dev);
int radeon_ms_pcie_init(struct drm_device *dev);
void radeon_ms_pcie_restore(struct drm_device *dev, struct radeon_state *state);
void radeon_ms_pcie_save(struct drm_device *dev, struct radeon_state *state);

/* radeon_ms_combios.c */
int radeon_ms_combios_get_properties(struct drm_device *dev);
int radeon_ms_connectors_from_combios(struct drm_device *dev);
int radeon_ms_outputs_from_combios(struct drm_device *dev);

/* radeon_ms_compat.c */
long radeon_ms_compat_ioctl(struct file *filp, unsigned int cmd,
			    unsigned long arg);

/* radeon_ms_cp.c */
int radeon_ms_cp_finish(struct drm_device *dev);
int radeon_ms_cp_init(struct drm_device *dev);
void radeon_ms_cp_restore(struct drm_device *dev, struct radeon_state *state);
void radeon_ms_cp_save(struct drm_device *dev, struct radeon_state *state);
void radeon_ms_cp_stop(struct drm_device *dev);
int radeon_ms_cp_wait(struct drm_device *dev, int n);
int radeon_ms_ring_emit(struct drm_device *dev, uint32_t *cmd, uint32_t count);
int radeon_ms_resetcp(struct drm_device *dev, void *data,
		      struct drm_file *file_priv);

/* radeon_ms_crtc.c */
int radeon_ms_crtc_create(struct drm_device *dev, int crtc);
void radeon_ms_crtc1_restore(struct drm_device *dev,
			     struct radeon_state *state);
void radeon_ms_crtc1_save(struct drm_device *dev, struct radeon_state *state);

/* radeon_ms_dac.c */
int radeon_ms_dac1_initialize(struct radeon_ms_output *output);
enum drm_output_status radeon_ms_dac1_detect(struct radeon_ms_output *output);
void radeon_ms_dac1_dpms(struct radeon_ms_output *output, int mode);
int radeon_ms_dac1_get_modes(struct radeon_ms_output *output);
bool radeon_ms_dac1_mode_fixup(struct radeon_ms_output *output,
		struct drm_display_mode *mode,
		struct drm_display_mode *adjusted_mode);
int radeon_ms_dac1_mode_set(struct radeon_ms_output *output,
		struct drm_display_mode *mode,
		struct drm_display_mode *adjusted_mode);
void radeon_ms_dac1_restore(struct radeon_ms_output *output,
		struct radeon_state *state);
void radeon_ms_dac1_save(struct radeon_ms_output *output,
		struct radeon_state *state);
int radeon_ms_dac2_initialize(struct radeon_ms_output *output);
enum drm_output_status radeon_ms_dac2_detect(struct radeon_ms_output *output);
void radeon_ms_dac2_dpms(struct radeon_ms_output *output, int mode);
int radeon_ms_dac2_get_modes(struct radeon_ms_output *output);
bool radeon_ms_dac2_mode_fixup(struct radeon_ms_output *output,
		struct drm_display_mode *mode,
		struct drm_display_mode *adjusted_mode);
int radeon_ms_dac2_mode_set(struct radeon_ms_output *output,
		struct drm_display_mode *mode,
		struct drm_display_mode *adjusted_mode);
void radeon_ms_dac2_restore(struct radeon_ms_output *output,
		struct radeon_state *state);
void radeon_ms_dac2_save(struct radeon_ms_output *output,
		struct radeon_state *state);

/* radeon_ms_drm.c */
int radeon_ms_driver_dma_ioctl(struct drm_device *dev, void *data,
			       struct drm_file *file_priv);
void radeon_ms_driver_lastclose(struct drm_device * dev);
int radeon_ms_driver_load(struct drm_device *dev, unsigned long flags);
int radeon_ms_driver_open(struct drm_device * dev, struct drm_file *file_priv);
int radeon_ms_driver_unload(struct drm_device *dev);

/* radeon_ms_exec.c */
int radeon_ms_execbuffer(struct drm_device *dev, void *data,
			 struct drm_file *file_priv);

/* radeon_ms_family.c */
int radeon_ms_family_init(struct drm_device *dev);

/* radeon_ms_fence.c */
void r3xx_fence_handler(struct drm_device * dev);
int r3xx_fence_types(struct drm_buffer_object *bo,
		     uint32_t * class, uint32_t * type);

/* radeon_ms_fb.c */
int radeonfb_probe(struct drm_device *dev, struct drm_crtc *crtc);
int radeonfb_remove(struct drm_device *dev, struct drm_crtc *crtc);

/* radeon_ms_gpu.c */
int radeon_ms_gpu_initialize(struct drm_device *dev);
void radeon_ms_gpu_dpms(struct drm_device *dev);
void radeon_ms_gpu_flush(struct drm_device *dev);
void radeon_ms_gpu_restore(struct drm_device *dev, struct radeon_state *state);
void radeon_ms_gpu_save(struct drm_device *dev, struct radeon_state *state);
int radeon_ms_wait_for_idle(struct drm_device *dev);

/* radeon_ms_i2c.c */
void radeon_ms_i2c_destroy(struct radeon_ms_i2c *i2c);
struct radeon_ms_i2c *radeon_ms_i2c_create(struct drm_device *dev,
					   const uint32_t reg,
					   const char *name);

/* radeon_ms_irq.c */
void radeon_ms_irq_emit(struct drm_device *dev);
irqreturn_t radeon_ms_irq_handler(DRM_IRQ_ARGS);
void radeon_ms_irq_preinstall(struct drm_device * dev);
int radeon_ms_irq_postinstall(struct drm_device * dev);
int radeon_ms_irq_init(struct drm_device *dev);
void radeon_ms_irq_restore(struct drm_device *dev, struct radeon_state *state);
void radeon_ms_irq_save(struct drm_device *dev, struct radeon_state *state);
void radeon_ms_irq_uninstall(struct drm_device * dev);

/* radeon_ms_output.c */
void radeon_ms_connectors_destroy(struct drm_device *dev);
int radeon_ms_connectors_from_properties(struct drm_device *dev);
int radeon_ms_connectors_from_rom(struct drm_device *dev);
void radeon_ms_outputs_destroy(struct drm_device *dev);
int radeon_ms_outputs_from_properties(struct drm_device *dev);
int radeon_ms_outputs_from_rom(struct drm_device *dev);
void radeon_ms_outputs_restore(struct drm_device *dev,
		struct radeon_state *state);
void radeon_ms_outputs_save(struct drm_device *dev, struct radeon_state *state);

/* radeon_ms_properties.c */
int radeon_ms_properties_init(struct drm_device *dev);

/* radeon_ms_rom.c */
int radeon_ms_rom_get_properties(struct drm_device *dev);
int radeon_ms_rom_init(struct drm_device *dev);

/* radeon_ms_state.c */
void radeon_ms_state_save(struct drm_device *dev, struct radeon_state *state);
void radeon_ms_state_restore(struct drm_device *dev,
			     struct radeon_state *state);

/* helper macro & functions ***************************************************/
#define REG_S(rn, bn, v)    (((v) << rn##__##bn##__SHIFT) & rn##__##bn##__MASK)
#define REG_G(rn, bn, v)    (((v) & rn##__##bn##__MASK) >> rn##__##bn##__SHIFT)
#define MMIO_R(rid)         mmio_read(dev_priv, rid)
#define MMIO_W(rid, v)      mmio_write(dev_priv, rid, v)
#define PCIE_R(rid)         pcie_read(dev_priv, rid)
#define PCIE_W(rid, v)      pcie_write(dev_priv, rid, v)
#define PPLL_R(rid)         pll_read(dev_priv, rid)
#define PPLL_W(rid, v)      pll_write(dev_priv, rid, v)

static __inline__ uint32_t mmio_read(struct drm_radeon_private *dev_priv,
				     uint32_t offset)
{
	return DRM_READ32(&dev_priv->mmio, offset);
}


static __inline__ void mmio_write(struct drm_radeon_private *dev_priv,
				  uint32_t offset, uint32_t v)
{
	DRM_WRITE32(&dev_priv->mmio, offset, v);
}

static __inline__ uint32_t pcie_read(struct drm_radeon_private *dev_priv,
				     uint32_t offset)
{
	MMIO_W(PCIE_INDEX, REG_S(PCIE_INDEX, PCIE_INDEX, offset));
	return MMIO_R(PCIE_DATA);
}

static __inline__ void pcie_write(struct drm_radeon_private *dev_priv,
				  uint32_t offset, uint32_t v)
{
	MMIO_W(PCIE_INDEX, REG_S(PCIE_INDEX, PCIE_INDEX, offset));
	MMIO_W(PCIE_DATA, v);
}

static __inline__ void pll_index_errata(struct drm_radeon_private *dev_priv)
{
	uint32_t tmp, save;

	/* This workaround is necessary on rv200 and RS200 or PLL
	 * reads may return garbage (among others...)
	 */
	if (dev_priv->properties.pll_dummy_reads) {
		tmp = MMIO_R(CLOCK_CNTL_DATA);
		tmp = MMIO_R(CRTC_GEN_CNTL);
	}
	/* This function is required to workaround a hardware bug in some (all?)
	 * revisions of the R300.  This workaround should be called after every
	 * CLOCK_CNTL_INDEX register access.  If not, register reads afterward
	 * may not be correct.
	 */
	if (dev_priv->properties.pll_r300_errata) {
		tmp = save = MMIO_R(CLOCK_CNTL_INDEX);
		tmp = tmp & ~CLOCK_CNTL_INDEX__PLL_ADDR__MASK;
		tmp = tmp & ~CLOCK_CNTL_INDEX__PLL_WR_EN;
		MMIO_W(CLOCK_CNTL_INDEX, tmp);
		tmp = MMIO_R(CLOCK_CNTL_DATA);
		MMIO_W(CLOCK_CNTL_INDEX, save);
	}
}

static __inline__ void pll_data_errata(struct drm_radeon_private *dev_priv)
{
	/* This workarounds is necessary on RV100, RS100 and RS200 chips
	 * or the chip could hang on a subsequent access
	 */
	if (dev_priv->properties.pll_delay) {
		/* we can't deal with posted writes here ... */
		udelay(5000);
	}
}

static __inline__ uint32_t pll_read(struct drm_radeon_private *dev_priv,
				    uint32_t offset)
{
	uint32_t clock_cntl_index = dev_priv->driver_state.clock_cntl_index;
	uint32_t data;

	clock_cntl_index &= ~CLOCK_CNTL_INDEX__PLL_ADDR__MASK;
	clock_cntl_index |= REG_S(CLOCK_CNTL_INDEX, PLL_ADDR, offset);
	MMIO_W(CLOCK_CNTL_INDEX, clock_cntl_index);
	pll_index_errata(dev_priv);
	data = MMIO_R(CLOCK_CNTL_DATA);
	pll_data_errata(dev_priv);
	return data;
}

static __inline__ void pll_write(struct drm_radeon_private *dev_priv,
				 uint32_t offset, uint32_t value)
{
	uint32_t clock_cntl_index = dev_priv->driver_state.clock_cntl_index;

	clock_cntl_index &= ~CLOCK_CNTL_INDEX__PLL_ADDR__MASK;
	clock_cntl_index |= REG_S(CLOCK_CNTL_INDEX, PLL_ADDR, offset);
	clock_cntl_index |= CLOCK_CNTL_INDEX__PLL_WR_EN;
	MMIO_W(CLOCK_CNTL_INDEX, clock_cntl_index);
	pll_index_errata(dev_priv);
	MMIO_W(CLOCK_CNTL_DATA, value);
	pll_data_errata(dev_priv);
}

#endif
line width is given in multiples of 6. In default mode lines are classified as vertical lines. HO: horizontal VE: vertical or horizontal HO & VE: no classification */ #define R300_RE_LINE_CNT 0x4234 # define R300_LINESIZE_SHIFT 0 # define R300_LINESIZE_MASK (0xFFFF << 0) /* GUESS */ # define R300_LINESIZE_MAX (R300_LINESIZE_MASK / 6) # define R300_LINE_CNT_HO (1 << 16) # define R300_LINE_CNT_VE (1 << 17) /* Some sort of scale or clamp value for texcoordless textures. */ #define R300_RE_UNK4238 0x4238 #define R300_RE_SHADE_MODEL 0x4278 # define R300_RE_SHADE_MODEL_SMOOTH 0x3aaaa # define R300_RE_SHADE_MODEL_FLAT 0x39595 /* Dangerous */ #define R300_RE_POLYGON_MODE 0x4288 # define R300_PM_ENABLED (1 << 0) # define R300_PM_FRONT_POINT (0 << 0) # define R300_PM_BACK_POINT (0 << 0) # define R300_PM_FRONT_LINE (1 << 4) # define R300_PM_FRONT_FILL (1 << 5) # define R300_PM_BACK_LINE (1 << 7) # define R300_PM_BACK_FILL (1 << 8) /* Not sure why there are duplicate of factor and constant values. My best guess so far is that there are seperate zbiases for test and write. Ordering might be wrong. Some of the tests indicate that fgl has a fallback implementation of zbias via pixel shaders. */ #define R300_RE_ZBIAS_T_FACTOR 0x42A4 #define R300_RE_ZBIAS_T_CONSTANT 0x42A8 #define R300_RE_ZBIAS_W_FACTOR 0x42AC #define R300_RE_ZBIAS_W_CONSTANT 0x42B0 /* This register needs to be set to (1<<1) for RV350 to correctly perform depth test (see --vb-triangles in r300_demo) Don't know about other chips. - Vladimir This is set to 3 when GL_POLYGON_OFFSET_FILL is on. My guess is that there are two bits for each zbias primitive (FILL, LINE, POINT). One to enable depth test and one for depth write. Yet this doesnt explain why depth writes work ... */ #define R300_RE_OCCLUSION_CNTL 0x42B4 # define R300_OCCLUSION_ON (1<<1) #define R300_RE_CULL_CNTL 0x42B8 # define R300_CULL_FRONT (1 << 0) # define R300_CULL_BACK (1 << 1) # define R300_FRONT_FACE_CCW (0 << 2) # define R300_FRONT_FACE_CW (1 << 2) /* BEGIN: Rasterization / Interpolators - many guesses // 0_UNKNOWN_18 has always been set except for clear operations. // TC_CNT is the number of incoming texture coordinate sets (i.e. it depends // on the vertex program, *not* the fragment program) */ #define R300_RS_CNTL_0 0x4300 # define R300_RS_CNTL_TC_CNT_SHIFT 2 # define R300_RS_CNTL_TC_CNT_MASK (7 << 2) # define R300_RS_CNTL_CI_CNT_SHIFT 7 /* number of color interpolators used */ # define R300_RS_CNTL_0_UNKNOWN_18 (1 << 18) /* Guess: RS_CNTL_1 holds the index of the highest used RS_ROUTE_n register. */ #define R300_RS_CNTL_1 0x4304 /* gap */ /* Only used for texture coordinates. // Use the source field to route texture coordinate input from the vertex program // to the desired interpolator. Note that the source field is relative to the // outputs the vertex program *actually* writes. If a vertex program only writes // texcoord[1], this will be source index 0. // Set INTERP_USED on all interpolators that produce data used by the // fragment program. INTERP_USED looks like a swizzling mask, but // I haven't seen it used that way. // // Note: The _UNKNOWN constants are always set in their respective register. // I don't know if this is necessary. */ #define R300_RS_INTERP_0 0x4310 #define R300_RS_INTERP_1 0x4314 # define R300_RS_INTERP_1_UNKNOWN 0x40 #define R300_RS_INTERP_2 0x4318 # define R300_RS_INTERP_2_UNKNOWN 0x80 #define R300_RS_INTERP_3 0x431C # define R300_RS_INTERP_3_UNKNOWN 0xC0 #define R300_RS_INTERP_4 0x4320 #define R300_RS_INTERP_5 0x4324 #define R300_RS_INTERP_6 0x4328 #define R300_RS_INTERP_7 0x432C # define R300_RS_INTERP_SRC_SHIFT 2 # define R300_RS_INTERP_SRC_MASK (7 << 2) # define R300_RS_INTERP_USED 0x00D10000 /* These DWORDs control how vertex data is routed into fragment program // registers, after interpolators. */ #define R300_RS_ROUTE_0 0x4330 #define R300_RS_ROUTE_1 0x4334 #define R300_RS_ROUTE_2 0x4338 #define R300_RS_ROUTE_3 0x433C /* GUESS */ #define R300_RS_ROUTE_4 0x4340 /* GUESS */ #define R300_RS_ROUTE_5 0x4344 /* GUESS */ #define R300_RS_ROUTE_6 0x4348 /* GUESS */ #define R300_RS_ROUTE_7 0x434C /* GUESS */ # define R300_RS_ROUTE_SOURCE_INTERP_0 0 # define R300_RS_ROUTE_SOURCE_INTERP_1 1 # define R300_RS_ROUTE_SOURCE_INTERP_2 2 # define R300_RS_ROUTE_SOURCE_INTERP_3 3 # define R300_RS_ROUTE_SOURCE_INTERP_4 4 # define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */ # define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */ # define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */ # define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */ # define R300_RS_ROUTE_DEST_SHIFT 6 # define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */ /* Special handling for color: When the fragment program uses color, // the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the // color register index. */ # define R300_RS_ROUTE_0_COLOR (1 << 14) # define R300_RS_ROUTE_0_COLOR_DEST_SHIFT 17 # define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */ /* As above, but for secondary color */ # define R300_RS_ROUTE_1_COLOR1 (1 << 14) # define R300_RS_ROUTE_1_COLOR1_DEST_SHIFT 17 # define R300_RS_ROUTE_1_COLOR1_DEST_MASK (31 << 17) # define R300_RS_ROUTE_1_UNKNOWN11 (1 << 11) /* END */ /* BEGIN: Scissors and cliprects // There are four clipping rectangles. Their corner coordinates are inclusive. // Every pixel is assigned a number from 0 and 15 by setting bits 0-3 depending // on whether the pixel is inside cliprects 0-3, respectively. For example, // if a pixel is inside cliprects 0 and 1, but outside 2 and 3, it is assigned // the number 3 (binary 0011). // Iff the bit corresponding to the pixel's number in RE_CLIPRECT_CNTL is set, // the pixel is rasterized. // // In addition to this, there is a scissors rectangle. Only pixels inside the // scissors rectangle are drawn. (coordinates are inclusive) // // For some reason, the top-left corner of the framebuffer is at (1440, 1440) // for the purpose of clipping and scissors. */ #define R300_RE_CLIPRECT_TL_0 0x43B0 #define R300_RE_CLIPRECT_BR_0 0x43B4 #define R300_RE_CLIPRECT_TL_1 0x43B8 #define R300_RE_CLIPRECT_BR_1 0x43BC #define R300_RE_CLIPRECT_TL_2 0x43C0 #define R300_RE_CLIPRECT_BR_2 0x43C4 #define R300_RE_CLIPRECT_TL_3 0x43C8 #define R300_RE_CLIPRECT_BR_3 0x43CC # define R300_CLIPRECT_OFFSET 1440 # define R300_CLIPRECT_MASK 0x1FFF # define R300_CLIPRECT_X_SHIFT 0 # define R300_CLIPRECT_X_MASK (0x1FFF << 0) # define R300_CLIPRECT_Y_SHIFT 13 # define R300_CLIPRECT_Y_MASK (0x1FFF << 13) #define R300_RE_CLIPRECT_CNTL 0x43D0 # define R300_CLIP_OUT (1 << 0) # define R300_CLIP_0 (1 << 1) # define R300_CLIP_1 (1 << 2) # define R300_CLIP_10 (1 << 3) # define R300_CLIP_2 (1 << 4) # define R300_CLIP_20 (1 << 5) # define R300_CLIP_21 (1 << 6) # define R300_CLIP_210 (1 << 7) # define R300_CLIP_3 (1 << 8) # define R300_CLIP_30 (1 << 9) # define R300_CLIP_31 (1 << 10) # define R300_CLIP_310 (1 << 11) # define R300_CLIP_32 (1 << 12) # define R300_CLIP_320 (1 << 13) # define R300_CLIP_321 (1 << 14) # define R300_CLIP_3210 (1 << 15) /* gap */ #define R300_RE_SCISSORS_TL 0x43E0 #define R300_RE_SCISSORS_BR 0x43E4 # define R300_SCISSORS_OFFSET 1440 # define R300_SCISSORS_X_SHIFT 0 # define R300_SCISSORS_X_MASK (0x1FFF << 0) # define R300_SCISSORS_Y_SHIFT 13 # define R300_SCISSORS_Y_MASK (0x1FFF << 13) /* END */ /* BEGIN: Texture specification // The texture specification dwords are grouped by meaning and not by texture unit. // This means that e.g. the offset for texture image unit N is found in register // TX_OFFSET_0 + (4*N) */ #define R300_TX_FILTER_0 0x4400 # define R300_TX_REPEAT 0 # define R300_TX_MIRRORED 1 # define R300_TX_CLAMP 4 # define R300_TX_CLAMP_TO_EDGE 2 # define R300_TX_CLAMP_TO_BORDER 6 # define R300_TX_WRAP_S_SHIFT 0 # define R300_TX_WRAP_S_MASK (7 << 0) # define R300_TX_WRAP_T_SHIFT 3 # define R300_TX_WRAP_T_MASK (7 << 3) # define R300_TX_WRAP_Q_SHIFT 6 # define R300_TX_WRAP_Q_MASK (7 << 6) # define R300_TX_MAG_FILTER_NEAREST (1 << 9) # define R300_TX_MAG_FILTER_LINEAR (2 << 9) # define R300_TX_MAG_FILTER_MASK (3 << 9) # define R300_TX_MIN_FILTER_NEAREST (1 << 11) # define R300_TX_MIN_FILTER_LINEAR (2 << 11) # define R300_TX_MIN_FILTER_NEAREST_MIP_NEAREST (5 << 11) # define R300_TX_MIN_FILTER_NEAREST_MIP_LINEAR (9 << 11) # define R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 11) # define R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR (10 << 11) /* NOTE: NEAREST doesnt seem to exist. Im not seting MAG_FILTER_MASK and (3 << 11) on for all anisotropy modes because that would void selected mag filter */ # define R300_TX_MIN_FILTER_ANISO_NEAREST ((0 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/) # define R300_TX_MIN_FILTER_ANISO_LINEAR ((0 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/) # define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST ((1 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/) # define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR ((2 << 13) /*|R300_TX_MAG_FILTER_MASK|(3<<11)*/) # define R300_TX_MIN_FILTER_MASK ( (15 << 11) | (3 << 13) ) # define R300_TX_MAX_ANISO_1_TO_1 (0 << 21) # define R300_TX_MAX_ANISO_2_TO_1 (2 << 21) # define R300_TX_MAX_ANISO_4_TO_1 (4 << 21) # define R300_TX_MAX_ANISO_8_TO_1 (6 << 21) # define R300_TX_MAX_ANISO_16_TO_1 (8 << 21) # define R300_TX_MAX_ANISO_MASK (14 << 21) #define R300_TX_FILTER1_0 0x4440 # define R300_CHROMA_KEY_MODE_DISABLE 0 # define R300_CHROMA_KEY_FORCE 1 # define R300_CHROMA_KEY_BLEND 2 # define R300_MC_ROUND_NORMAL (0<<2) # define R300_MC_ROUND_MPEG4 (1<<2) # define R300_LOD_BIAS_MASK 0x1fff # define R300_EDGE_ANISO_EDGE_DIAG (0<<13) # define R300_EDGE_ANISO_EDGE_ONLY (1<<13) # define R300_MC_COORD_TRUNCATE_DISABLE (0<<14) # define R300_MC_COORD_TRUNCATE_MPEG (1<<14) # define R300_TX_TRI_PERF_0_8 (0<<15) # define R300_TX_TRI_PERF_1_8 (1<<15) # define R300_TX_TRI_PERF_1_4 (2<<15) # define R300_TX_TRI_PERF_3_8 (3<<15) # define R300_ANISO_THRESHOLD_MASK (7<<17) #define R300_TX_SIZE_0 0x4480 # define R300_TX_WIDTHMASK_SHIFT 0 # define R300_TX_WIDTHMASK_MASK (2047 << 0) # define R300_TX_HEIGHTMASK_SHIFT 11 # define R300_TX_HEIGHTMASK_MASK (2047 << 11) # define R300_TX_UNK23 (1 << 23) # define R300_TX_SIZE_SHIFT 26 /* largest of width, height */ # define R300_TX_SIZE_MASK (15 << 26) # define R300_TX_SIZE_PROJECTED (1<<30) # define R300_TX_SIZE_TXPITCH_EN (1<<31) #define R300_TX_FORMAT_0 0x44C0 /* The interpretation of the format word by Wladimir van der Laan */ /* The X, Y, Z and W refer to the layout of the components. They are given meanings as R, G, B and Alpha by the swizzle specification */ # define R300_TX_FORMAT_X8 0x0 # define R300_TX_FORMAT_X16 0x1 # define R300_TX_FORMAT_Y4X4 0x2 # define R300_TX_FORMAT_Y8X8 0x3 # define R300_TX_FORMAT_Y16X16 0x4 # define R300_TX_FORMAT_Z3Y3X2 0x5 # define R300_TX_FORMAT_Z5Y6X5 0x6 # define R300_TX_FORMAT_Z6Y5X5 0x7 # define R300_TX_FORMAT_Z11Y11X10 0x8 # define R300_TX_FORMAT_Z10Y11X11 0x9 # define R300_TX_FORMAT_W4Z4Y4X4 0xA # define R300_TX_FORMAT_W1Z5Y5X5 0xB # define R300_TX_FORMAT_W8Z8Y8X8 0xC # define R300_TX_FORMAT_W2Z10Y10X10 0xD # define R300_TX_FORMAT_W16Z16Y16X16 0xE # define R300_TX_FORMAT_DXT1 0xF # define R300_TX_FORMAT_DXT3 0x10 # define R300_TX_FORMAT_DXT5 0x11 # define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */ # define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */ # define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */ # define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */ /* 0x16 - some 16 bit green format.. ?? */ # define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */ # define R300_TX_FORMAT_CUBIC_MAP (1 << 26) /* gap */ /* Floating point formats */ /* Note - hardware supports both 16 and 32 bit floating point */ # define R300_TX_FORMAT_FL_I16 0x18 # define R300_TX_FORMAT_FL_I16A16 0x19 # define R300_TX_FORMAT_FL_R16G16B16A16 0x1A # define R300_TX_FORMAT_FL_I32 0x1B # define R300_TX_FORMAT_FL_I32A32 0x1C # define R300_TX_FORMAT_FL_R32G32B32A32 0x1D /* alpha modes, convenience mostly */ /* if you have alpha, pick constant appropriate to the number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */ # define R300_TX_FORMAT_ALPHA_1CH 0x000 # define R300_TX_FORMAT_ALPHA_2CH 0x200 # define R300_TX_FORMAT_ALPHA_4CH 0x600 # define R300_TX_FORMAT_ALPHA_NONE 0xA00 /* Swizzling */ /* constants */ # define R300_TX_FORMAT_X 0 # define R300_TX_FORMAT_Y 1 # define R300_TX_FORMAT_Z 2 # define R300_TX_FORMAT_W 3 # define R300_TX_FORMAT_ZERO 4 # define R300_TX_FORMAT_ONE 5 # define R300_TX_FORMAT_CUT_Z 6 /* 2.0*Z, everything above 1.0 is set to 0.0 */ # define R300_TX_FORMAT_CUT_W 7 /* 2.0*W, everything above 1.0 is set to 0.0 */ # define R300_TX_FORMAT_B_SHIFT 18 # define R300_TX_FORMAT_G_SHIFT 15 # define R300_TX_FORMAT_R_SHIFT 12 # define R300_TX_FORMAT_A_SHIFT 9 /* Convenience macro to take care of layout and swizzling */ # define R300_EASY_TX_FORMAT(B, G, R, A, FMT) (\ ((R300_TX_FORMAT_##B)<<R300_TX_FORMAT_B_SHIFT) \ | ((R300_TX_FORMAT_##G)<<R300_TX_FORMAT_G_SHIFT) \ | ((R300_TX_FORMAT_##R)<<R300_TX_FORMAT_R_SHIFT) \ | ((R300_TX_FORMAT_##A)<<R300_TX_FORMAT_A_SHIFT) \ | (R300_TX_FORMAT_##FMT) \ ) /* These can be ORed with result of R300_EASY_TX_FORMAT() */ /* We don't really know what they do. Take values from a constant color ? */ # define R300_TX_FORMAT_CONST_X (1<<5) # define R300_TX_FORMAT_CONST_Y (2<<5) # define R300_TX_FORMAT_CONST_Z (4<<5) # define R300_TX_FORMAT_CONST_W (8<<5) # define R300_TX_FORMAT_YUV_MODE 0x00800000 #define R300_TX_PITCH_0 0x4500 /* obvious missing in gap */ #define R300_TX_OFFSET_0 0x4540 /* BEGIN: Guess from R200 */ # define R300_TXO_ENDIAN_NO_SWAP (0 << 0) # define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0) # define R300_TXO_ENDIAN_WORD_SWAP (2 << 0) # define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0) # define R300_TXO_MACRO_TILE (1 << 2) # define R300_TXO_MICRO_TILE (1 << 3) # define R300_TXO_OFFSET_MASK 0xffffffe0 # define R300_TXO_OFFSET_SHIFT 5 /* END */ #define R300_TX_CHROMA_KEY_0 0x4580 /* 32 bit chroma key */ #define R300_TX_BORDER_COLOR_0 0x45C0 //ff00ff00 == { 0, 1.0, 0, 1.0 } /* END */ /* BEGIN: Fragment program instruction set // Fragment programs are written directly into register space. // There are separate instruction streams for texture instructions and ALU // instructions. // In order to synchronize these streams, the program is divided into up // to 4 nodes. Each node begins with a number of TEX operations, followed // by a number of ALU operations. // The first node can have zero TEX ops, all subsequent nodes must have at least // one TEX ops. // All nodes must have at least one ALU op. // // The index of the last node is stored in PFS_CNTL_0: A value of 0 means // 1 node, a value of 3 means 4 nodes. // The total amount of instructions is defined in PFS_CNTL_2. The offsets are // offsets into the respective instruction streams, while *_END points to the // last instruction relative to this offset. */ #define R300_PFS_CNTL_0 0x4600 # define R300_PFS_CNTL_LAST_NODES_SHIFT 0 # define R300_PFS_CNTL_LAST_NODES_MASK (3 << 0) # define R300_PFS_CNTL_FIRST_NODE_HAS_TEX (1 << 3) #define R300_PFS_CNTL_1 0x4604 /* There is an unshifted value here which has so far always been equal to the // index of the highest used temporary register. */ #define R300_PFS_CNTL_2 0x4608 # define R300_PFS_CNTL_ALU_OFFSET_SHIFT 0 # define R300_PFS_CNTL_ALU_OFFSET_MASK (63 << 0) # define R300_PFS_CNTL_ALU_END_SHIFT 6 # define R300_PFS_CNTL_ALU_END_MASK (63 << 0) # define R300_PFS_CNTL_TEX_OFFSET_SHIFT 12 # define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) /* GUESS */ # define R300_PFS_CNTL_TEX_END_SHIFT 18 # define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* GUESS */ /* gap */ /* Nodes are stored backwards. The last active node is always stored in // PFS_NODE_3. // Example: In a 2-node program, NODE_0 and NODE_1 are set to 0. The // first node is stored in NODE_2, the second node is stored in NODE_3. // // Offsets are relative to the master offset from PFS_CNTL_2. // LAST_NODE is set for the last node, and only for the last node. */ #define R300_PFS_NODE_0 0x4610 #define R300_PFS_NODE_1 0x4614 #define R300_PFS_NODE_2 0x4618 #define R300_PFS_NODE_3 0x461C # define R300_PFS_NODE_ALU_OFFSET_SHIFT 0 # define R300_PFS_NODE_ALU_OFFSET_MASK (63 << 0) # define R300_PFS_NODE_ALU_END_SHIFT 6 # define R300_PFS_NODE_ALU_END_MASK (63 << 6) # define R300_PFS_NODE_TEX_OFFSET_SHIFT 12 # define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12) # define R300_PFS_NODE_TEX_END_SHIFT 17 # define R300_PFS_NODE_TEX_END_MASK (31 << 17) /*# define R300_PFS_NODE_LAST_NODE (1 << 22) */ # define R300_PFS_NODE_OUTPUT_COLOR (1 << 22) # define R300_PFS_NODE_OUTPUT_DEPTH (1 << 23) /* TEX // As far as I can tell, texture instructions cannot write into output // registers directly. A subsequent ALU instruction is always necessary, // even if it's just MAD o0, r0, 1, 0 */ #define R300_PFS_TEXI_0 0x4620 # define R300_FPITX_SRC_SHIFT 0 # define R300_FPITX_SRC_MASK (31 << 0) # define R300_FPITX_SRC_CONST (1 << 5) /* GUESS */ # define R300_FPITX_DST_SHIFT 6 # define R300_FPITX_DST_MASK (31 << 6) # define R300_FPITX_IMAGE_SHIFT 11 # define R300_FPITX_IMAGE_MASK (15 << 11) /* GUESS based on layout and native limits */ /* Unsure if these are opcodes, or some kind of bitfield, but this is how * they were set when I checked */ # define R300_FPITX_OPCODE_SHIFT 15 # define R300_FPITX_OP_TEX 1 # define R300_FPITX_OP_KIL 2 # define R300_FPITX_OP_TXP 3 # define R300_FPITX_OP_TXB 4 /* ALU // The ALU instructions register blocks are enumerated according to the order // in which fglrx. I assume there is space for 64 instructions, since // each block has space for a maximum of 64 DWORDs, and this matches reported // native limits. // // The basic functional block seems to be one MAD for each color and alpha, // and an adder that adds all components after the MUL. // - ADD, MUL, MAD etc.: use MAD with appropriate neutral operands // - DP4: Use OUTC_DP4, OUTA_DP4 // - DP3: Use OUTC_DP3, OUTA_DP4, appropriate alpha operands // - DPH: Use OUTC_DP4, OUTA_DP4, appropriate alpha operands // - CMP: If ARG2 < 0, return ARG1, else return ARG0 // - FLR: use FRC+MAD // - XPD: use MAD+MAD // - SGE, SLT: use MAD+CMP // - RSQ: use ABS modifier for argument // - Use OUTC_REPL_ALPHA to write results of an alpha-only operation (e.g. RCP) // into color register // - apparently, there's no quick DST operation // - fglrx set FPI2_UNKNOWN_31 on a "MAD fragment.color, tmp0, tmp1, tmp2" // - fglrx set FPI2_UNKNOWN_31 on a "MAX r2, r1, c0" // - fglrx once set FPI0_UNKNOWN_31 on a "FRC r1, r1" // // Operand selection // First stage selects three sources from the available registers and // constant parameters. This is defined in INSTR1 (color) and INSTR3 (alpha). // fglrx sorts the three source fields: Registers before constants, // lower indices before higher indices; I do not know whether this is necessary. // fglrx fills unused sources with "read constant 0" // According to specs, you cannot select more than two different constants. // // Second stage selects the operands from the sources. This is defined in // INSTR0 (color) and INSTR2 (alpha). You can also select the special constants // zero and one. // Swizzling and negation happens in this stage, as well. // // Important: Color and alpha seem to be mostly separate, i.e. their sources // selection appears to be fully independent (the register storage is probably // physically split into a color and an alpha section). // However (because of the apparent physical split), there is some interaction // WRT swizzling. If, for example, you want to load an R component into an // Alpha operand, this R component is taken from a *color* source, not from // an alpha source. The corresponding register doesn't even have to appear in // the alpha sources list. (I hope this alll makes sense to you) // // Destination selection // The destination register index is in FPI1 (color) and FPI3 (alpha) together // with enable bits. // There are separate enable bits for writing into temporary registers // (DSTC_REG_* /DSTA_REG) and and program output registers (DSTC_OUTPUT_* /DSTA_OUTPUT). // You can write to both at once, or not write at all (the same index // must be used for both). // // Note: There is a special form for LRP // - Argument order is the same as in ARB_fragment_program. // - Operation is MAD // - ARG1 is set to ARGC_SRC1C_LRP/ARGC_SRC1A_LRP // - Set FPI0/FPI2_SPECIAL_LRP // Arbitrary LRP (including support for swizzling) requires vanilla MAD+MAD */ #define R300_PFS_INSTR1_0 0x46C0 # define R300_FPI1_SRC0C_SHIFT 0 # define R300_FPI1_SRC0C_MASK (31 << 0) # define R300_FPI1_SRC0C_CONST (1 << 5) # define R300_FPI1_SRC1C_SHIFT 6 # define R300_FPI1_SRC1C_MASK (31 << 6) # define R300_FPI1_SRC1C_CONST (1 << 11) # define R300_FPI1_SRC2C_SHIFT 12 # define R300_FPI1_SRC2C_MASK (31 << 12) # define R300_FPI1_SRC2C_CONST (1 << 17) # define R300_FPI1_DSTC_SHIFT 18 # define R300_FPI1_DSTC_MASK (31 << 18) # define R300_FPI1_DSTC_REG_MASK_SHIFT 23 # define R300_FPI1_DSTC_REG_X (1 << 23) # define R300_FPI1_DSTC_REG_Y (1 << 24) # define R300_FPI1_DSTC_REG_Z (1 << 25) # define R300_FPI1_DSTC_OUTPUT_MASK_SHIFT 26 # define R300_FPI1_DSTC_OUTPUT_X (1 << 26) # define R300_FPI1_DSTC_OUTPUT_Y (1 << 27) # define R300_FPI1_DSTC_OUTPUT_Z (1 << 28) #define R300_PFS_INSTR3_0 0x47C0 # define R300_FPI3_SRC0A_SHIFT 0 # define R300_FPI3_SRC0A_MASK (31 << 0) # define R300_FPI3_SRC0A_CONST (1 << 5) # define R300_FPI3_SRC1A_SHIFT 6 # define R300_FPI3_SRC1A_MASK (31 << 6) # define R300_FPI3_SRC1A_CONST (1 << 11) # define R300_FPI3_SRC2A_SHIFT 12 # define R300_FPI3_SRC2A_MASK (31 << 12) # define R300_FPI3_SRC2A_CONST (1 << 17) # define R300_FPI3_DSTA_SHIFT 18 # define R300_FPI3_DSTA_MASK (31 << 18) # define R300_FPI3_DSTA_REG (1 << 23) # define R300_FPI3_DSTA_OUTPUT (1 << 24) # define R300_FPI3_DSTA_DEPTH (1 << 27) #define R300_PFS_INSTR0_0 0x48C0 # define R300_FPI0_ARGC_SRC0C_XYZ 0 # define R300_FPI0_ARGC_SRC0C_XXX 1 # define R300_FPI0_ARGC_SRC0C_YYY 2 # define R300_FPI0_ARGC_SRC0C_ZZZ 3 # define R300_FPI0_ARGC_SRC1C_XYZ 4 # define R300_FPI0_ARGC_SRC1C_XXX 5 # define R300_FPI0_ARGC_SRC1C_YYY 6 # define R300_FPI0_ARGC_SRC1C_ZZZ 7 # define R300_FPI0_ARGC_SRC2C_XYZ 8 # define R300_FPI0_ARGC_SRC2C_XXX 9 # define R300_FPI0_ARGC_SRC2C_YYY 10 # define R300_FPI0_ARGC_SRC2C_ZZZ 11 # define R300_FPI0_ARGC_SRC0A 12 # define R300_FPI0_ARGC_SRC1A 13 # define R300_FPI0_ARGC_SRC2A 14 # define R300_FPI0_ARGC_SRC1C_LRP 15 # define R300_FPI0_ARGC_ZERO 20 # define R300_FPI0_ARGC_ONE 21 # define R300_FPI0_ARGC_HALF 22 /* GUESS */ # define R300_FPI0_ARGC_SRC0C_YZX 23 # define R300_FPI0_ARGC_SRC1C_YZX 24 # define R300_FPI0_ARGC_SRC2C_YZX 25 # define R300_FPI0_ARGC_SRC0C_ZXY 26 # define R300_FPI0_ARGC_SRC1C_ZXY 27 # define R300_FPI0_ARGC_SRC2C_ZXY 28 # define R300_FPI0_ARGC_SRC0CA_WZY 29 # define R300_FPI0_ARGC_SRC1CA_WZY 30 # define R300_FPI0_ARGC_SRC2CA_WZY 31 # define R300_FPI0_ARG0C_SHIFT 0 # define R300_FPI0_ARG0C_MASK (31 << 0) # define R300_FPI0_ARG0C_NEG (1 << 5) # define R300_FPI0_ARG0C_ABS (1 << 6) # define R300_FPI0_ARG1C_SHIFT 7 # define R300_FPI0_ARG1C_MASK (31 << 7) # define R300_FPI0_ARG1C_NEG (1 << 12) # define R300_FPI0_ARG1C_ABS (1 << 13) # define R300_FPI0_ARG2C_SHIFT 14 # define R300_FPI0_ARG2C_MASK (31 << 14) # define R300_FPI0_ARG2C_NEG (1 << 19) # define R300_FPI0_ARG2C_ABS (1 << 20) # define R300_FPI0_SPECIAL_LRP (1 << 21) # define R300_FPI0_OUTC_MAD (0 << 23) # define R300_FPI0_OUTC_DP3 (1 << 23) # define R300_FPI0_OUTC_DP4 (2 << 23) # define R300_FPI0_OUTC_MIN (4 << 23) # define R300_FPI0_OUTC_MAX (5 << 23) # define R300_FPI0_OUTC_CMP (8 << 23) # define R300_FPI0_OUTC_FRC (9 << 23) # define R300_FPI0_OUTC_REPL_ALPHA (10 << 23) # define R300_FPI0_OUTC_SAT (1 << 30) # define R300_FPI0_INSERT_NOP (1 << 31) #define R300_PFS_INSTR2_0 0x49C0 # define R300_FPI2_ARGA_SRC0C_X 0 # define R300_FPI2_ARGA_SRC0C_Y 1 # define R300_FPI2_ARGA_SRC0C_Z 2 # define R300_FPI2_ARGA_SRC1C_X 3 # define R300_FPI2_ARGA_SRC1C_Y 4 # define R300_FPI2_ARGA_SRC1C_Z 5 # define R300_FPI2_ARGA_SRC2C_X 6 # define R300_FPI2_ARGA_SRC2C_Y 7 # define R300_FPI2_ARGA_SRC2C_Z 8 # define R300_FPI2_ARGA_SRC0A 9 # define R300_FPI2_ARGA_SRC1A 10 # define R300_FPI2_ARGA_SRC2A 11 # define R300_FPI2_ARGA_SRC1A_LRP 15 # define R300_FPI2_ARGA_ZERO 16 # define R300_FPI2_ARGA_ONE 17 # define R300_FPI2_ARGA_HALF 18 /* GUESS */ # define R300_FPI2_ARG0A_SHIFT 0 # define R300_FPI2_ARG0A_MASK (31 << 0) # define R300_FPI2_ARG0A_NEG (1 << 5) # define R300_FPI2_ARG0A_ABS (1 << 6) /* GUESS */ # define R300_FPI2_ARG1A_SHIFT 7 # define R300_FPI2_ARG1A_MASK (31 << 7) # define R300_FPI2_ARG1A_NEG (1 << 12) # define R300_FPI2_ARG1A_ABS (1 << 13) /* GUESS */ # define R300_FPI2_ARG2A_SHIFT 14 # define R300_FPI2_ARG2A_MASK (31 << 14) # define R300_FPI2_ARG2A_NEG (1 << 19) # define R300_FPI2_ARG2A_ABS (1 << 20) /* GUESS */ # define R300_FPI2_SPECIAL_LRP (1 << 21) # define R300_FPI2_OUTA_MAD (0 << 23) # define R300_FPI2_OUTA_DP4 (1 << 23) # define R300_FPI2_OUTA_MIN (2 << 23) # define R300_FPI2_OUTA_MAX (3 << 23) # define R300_FPI2_OUTA_CMP (6 << 23) # define R300_FPI2_OUTA_FRC (7 << 23) # define R300_FPI2_OUTA_EX2 (8 << 23) # define R300_FPI2_OUTA_LG2 (9 << 23) # define R300_FPI2_OUTA_RCP (10 << 23) # define R300_FPI2_OUTA_RSQ (11 << 23) # define R300_FPI2_OUTA_SAT (1 << 30) # define R300_FPI2_UNKNOWN_31 (1 << 31) /* END */ /* gap */ #define R300_PP_ALPHA_TEST 0x4BD4 # define R300_REF_ALPHA_MASK 0x000000ff # define R300_ALPHA_TEST_FAIL (0 << 8) # define R300_ALPHA_TEST_LESS (1 << 8) # define R300_ALPHA_TEST_LEQUAL (3 << 8) # define R300_ALPHA_TEST_EQUAL (2 << 8) # define R300_ALPHA_TEST_GEQUAL (6 << 8) # define R300_ALPHA_TEST_GREATER (4 << 8) # define R300_ALPHA_TEST_NEQUAL (5 << 8) # define R300_ALPHA_TEST_PASS (7 << 8) # define R300_ALPHA_TEST_OP_MASK (7 << 8) # define R300_ALPHA_TEST_ENABLE (1 << 11) /* gap */ /* Fragment program parameters in 7.16 floating point */ #define R300_PFS_PARAM_0_X 0x4C00 #define R300_PFS_PARAM_0_Y 0x4C04 #define R300_PFS_PARAM_0_Z 0x4C08 #define R300_PFS_PARAM_0_W 0x4C0C /* GUESS: PARAM_31 is last, based on native limits reported by fglrx */ #define R300_PFS_PARAM_31_X 0x4DF0 #define R300_PFS_PARAM_31_Y 0x4DF4 #define R300_PFS_PARAM_31_Z 0x4DF8 #define R300_PFS_PARAM_31_W 0x4DFC /* Notes: // - AFAIK fglrx always sets BLEND_UNKNOWN when blending is used in the application // - AFAIK fglrx always sets BLEND_NO_SEPARATE when CBLEND and ABLEND are set to the same // function (both registers are always set up completely in any case) // - Most blend flags are simply copied from R200 and not tested yet */ #define R300_RB3D_CBLEND 0x4E04 #define R300_RB3D_ABLEND 0x4E08 /* the following only appear in CBLEND */ # define R300_BLEND_ENABLE (1 << 0) # define R300_BLEND_UNKNOWN (3 << 1) # define R300_BLEND_NO_SEPARATE (1 << 3) /* the following are shared between CBLEND and ABLEND */ # define R300_FCN_MASK (3 << 12) # define R300_COMB_FCN_ADD_CLAMP (0 << 12) # define R300_COMB_FCN_ADD_NOCLAMP (1 << 12) # define R300_COMB_FCN_SUB_CLAMP (2 << 12) # define R300_COMB_FCN_SUB_NOCLAMP (3 << 12) # define R300_SRC_BLEND_GL_ZERO (32 << 16) # define R300_SRC_BLEND_GL_ONE (33 << 16) # define R300_SRC_BLEND_GL_SRC_COLOR (34 << 16) # define R300_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16) # define R300_SRC_BLEND_GL_DST_COLOR (36 << 16) # define R300_SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16) # define R300_SRC_BLEND_GL_SRC_ALPHA (38 << 16) # define R300_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16) # define R300_SRC_BLEND_GL_DST_ALPHA (40 << 16) # define R300_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16) # define R300_SRC_BLEND_GL_SRC_ALPHA_SATURATE (42 << 16) # define R300_SRC_BLEND_MASK (63 << 16) # define R300_DST_BLEND_GL_ZERO (32 << 24) # define R300_DST_BLEND_GL_ONE (33 << 24) # define R300_DST_BLEND_GL_SRC_COLOR (34 << 24) # define R300_DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24) # define R300_DST_BLEND_GL_DST_COLOR (36 << 24) # define R300_DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24) # define R300_DST_BLEND_GL_SRC_ALPHA (38 << 24) # define R300_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24) # define R300_DST_BLEND_GL_DST_ALPHA (40 << 24) # define R300_DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24) # define R300_DST_BLEND_MASK (63 << 24) #define R300_RB3D_COLORMASK 0x4E0C # define R300_COLORMASK0_B (1<<0) # define R300_COLORMASK0_G (1<<1) # define R300_COLORMASK0_R (1<<2) # define R300_COLORMASK0_A (1<<3) /* gap */ #define R300_RB3D_COLOROFFSET0 0x4E28 # define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */ #define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */ #define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */ #define R300_RB3D_COLOROFFSET3 0x4E34 /* GUESS */ /* gap */ /* Bit 16: Larger tiles // Bit 17: 4x2 tiles // Bit 18: Extremely weird tile like, but some pixels duplicated? */ #define R300_RB3D_COLORPITCH0 0x4E38 # define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */ # define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */ # define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */ # define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */ # define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */ # define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */ # define R300_COLOR_FORMAT_RGB565 (2 << 22) # define R300_COLOR_FORMAT_ARGB8888 (3 << 22) #define R300_RB3D_COLORPITCH1 0x4E3C /* GUESS */ #define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */ #define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */ /* gap */ /* Guess by Vladimir. // Set to 0A before 3D operations, set to 02 afterwards. */ #define R300_RB3D_DSTCACHE_CTLSTAT 0x4E4C # define R300_RB3D_DSTCACHE_02 0x00000002 # define R300_RB3D_DSTCACHE_0A 0x0000000A /* gap */ /* There seems to be no "write only" setting, so use Z-test = ALWAYS for this. */ /* Bit (1<<8) is the "test" bit. so plain write is 6 - vd */ #define R300_RB3D_ZSTENCIL_CNTL_0 0x4F00 # define R300_RB3D_Z_DISABLED_1 0x00000010 /* GUESS */ # define R300_RB3D_Z_DISABLED_2 0x00000014 /* GUESS */ # define R300_RB3D_Z_TEST 0x00000012 # define R300_RB3D_Z_TEST_AND_WRITE 0x00000016 # define R300_RB3D_Z_WRITE_ONLY 0x00000006 # define R300_RB3D_Z_TEST 0x00000012 # define R300_RB3D_Z_TEST_AND_WRITE 0x00000016 # define R300_RB3D_Z_WRITE_ONLY 0x00000006 # define R300_RB3D_STENCIL_ENABLE 0x00000001 #define R300_RB3D_ZSTENCIL_CNTL_1 0x4F04 /* functions */ # define R300_ZS_NEVER 0 # define R300_ZS_LESS 1 # define R300_ZS_LEQUAL 2 # define R300_ZS_EQUAL 3 # define R300_ZS_GEQUAL 4 # define R300_ZS_GREATER 5 # define R300_ZS_NOTEQUAL 6 # define R300_ZS_ALWAYS 7 # define R300_ZS_MASK 7 /* operations */ # define R300_ZS_KEEP 0 # define R300_ZS_ZERO 1 # define R300_ZS_REPLACE 2 # define R300_ZS_INCR 3 # define R300_ZS_DECR 4 # define R300_ZS_INVERT 5 # define R300_ZS_INCR_WRAP 6 # define R300_ZS_DECR_WRAP 7 /* front and back refer to operations done for front and back faces, i.e. separate stencil function support */ # define R300_RB3D_ZS1_DEPTH_FUNC_SHIFT 0 # define R300_RB3D_ZS1_FRONT_FUNC_SHIFT 3 # define R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT 6 # define R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT 9 # define R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT 12 # define R300_RB3D_ZS1_BACK_FUNC_SHIFT 15 # define R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT 18 # define R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT 21 # define R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT 24 #define R300_RB3D_ZSTENCIL_CNTL_2 0x4F08 # define R300_RB3D_ZS2_STENCIL_REF_SHIFT 0 # define R300_RB3D_ZS2_STENCIL_MASK 0xFF # define R300_RB3D_ZS2_STENCIL_MASK_SHIFT 8 # define R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT 16 /* gap */ #define R300_RB3D_ZSTENCIL_FORMAT 0x4F10 # define R300_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) # define R300_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) /* gap */ #define R300_RB3D_DEPTHOFFSET 0x4F20 #define R300_RB3D_DEPTHPITCH 0x4F24 # define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */ # define R300_DEPTH_TILE_ENABLE (1 << 16) /* GUESS */ # define R300_DEPTH_MICROTILE_ENABLE (1 << 17) /* GUESS */ # define R300_DEPTH_ENDIAN_NO_SWAP (0 << 18) /* GUESS */ # define R300_DEPTH_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */ # define R300_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */ /* BEGIN: Vertex program instruction set // Every instruction is four dwords long: // DWORD 0: output and opcode // DWORD 1: first argument // DWORD 2: second argument // DWORD 3: third argument // // Notes: // - ABS r, a is implemented as MAX r, a, -a // - MOV is implemented as ADD to zero // - XPD is implemented as MUL + MAD // - FLR is implemented as FRC + ADD // - apparently, fglrx tries to schedule instructions so that there is at least // one instruction between the write to a temporary and the first read // from said temporary; however, violations of this scheduling are allowed // - register indices seem to be unrelated with OpenGL aliasing to conventional state // - only one attribute and one parameter can be loaded at a time; however, the // same attribute/parameter can be used for more than one argument // - the second software argument for POW is the third hardware argument (no idea why) // - MAD with only temporaries as input seems to use VPI_OUT_SELECT_MAD_2 // // There is some magic surrounding LIT: // The single argument is replicated across all three inputs, but swizzled: // First argument: xyzy // Second argument: xyzx // Third argument: xyzw // Whenever the result is used later in the fragment program, fglrx forces x and w // to be 1.0 in the input selection; I don't know whether this is strictly necessary */ #define R300_VPI_OUT_OP_DOT (1 << 0) #define R300_VPI_OUT_OP_MUL (2 << 0) #define R300_VPI_OUT_OP_ADD (3 << 0) #define R300_VPI_OUT_OP_MAD (4 << 0) #define R300_VPI_OUT_OP_DST (5 << 0) #define R300_VPI_OUT_OP_FRC (6 << 0) #define R300_VPI_OUT_OP_MAX (7 << 0) #define R300_VPI_OUT_OP_MIN (8 << 0) #define R300_VPI_OUT_OP_SGE (9 << 0) #define R300_VPI_OUT_OP_SLT (10 << 0) #define R300_VPI_OUT_OP_UNK12 (12 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */ #define R300_VPI_OUT_OP_EXP (65 << 0) #define R300_VPI_OUT_OP_LOG (66 << 0) #define R300_VPI_OUT_OP_UNK67 (67 << 0) /* Used in fog computations, scalar(scalar) */ #define R300_VPI_OUT_OP_LIT (68 << 0) #define R300_VPI_OUT_OP_POW (69 << 0) #define R300_VPI_OUT_OP_RCP (70 << 0) #define R300_VPI_OUT_OP_RSQ (72 << 0) #define R300_VPI_OUT_OP_UNK73 (73 << 0) /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */ #define R300_VPI_OUT_OP_EX2 (75 << 0) #define R300_VPI_OUT_OP_LG2 (76 << 0) #define R300_VPI_OUT_OP_MAD_2 (128 << 0) #define R300_VPI_OUT_OP_UNK129 (129 << 0) /* all temps, vector(scalar, vector, vector) */ #define R300_VPI_OUT_REG_CLASS_TEMPORARY (0 << 8) #define R300_VPI_OUT_REG_CLASS_RESULT (2 << 8) #define R300_VPI_OUT_REG_CLASS_MASK (31 << 8) #define R300_VPI_OUT_REG_INDEX_SHIFT 13 #define R300_VPI_OUT_REG_INDEX_MASK (31 << 13) /* GUESS based on fglrx native limits */ #define R300_VPI_OUT_WRITE_X (1 << 20) #define R300_VPI_OUT_WRITE_Y (1 << 21) #define R300_VPI_OUT_WRITE_Z (1 << 22) #define R300_VPI_OUT_WRITE_W (1 << 23) #define R300_VPI_IN_REG_CLASS_TEMPORARY (0 << 0) #define R300_VPI_IN_REG_CLASS_ATTRIBUTE (1 << 0) #define R300_VPI_IN_REG_CLASS_PARAMETER (2 << 0) #define R300_VPI_IN_REG_CLASS_NONE (9 << 0) #define R300_VPI_IN_REG_CLASS_MASK (31 << 0) /* GUESS */ #define R300_VPI_IN_REG_INDEX_SHIFT 5 #define R300_VPI_IN_REG_INDEX_MASK (255 << 5) /* GUESS based on fglrx native limits */ /* The R300 can select components from the input register arbitrarily. // Use the following constants, shifted by the component shift you // want to select */ #define R300_VPI_IN_SELECT_X 0 #define R300_VPI_IN_SELECT_Y 1 #define R300_VPI_IN_SELECT_Z 2 #define R300_VPI_IN_SELECT_W 3 #define R300_VPI_IN_SELECT_ZERO 4 #define R300_VPI_IN_SELECT_ONE 5 #define R300_VPI_IN_SELECT_MASK 7 #define R300_VPI_IN_X_SHIFT 13 #define R300_VPI_IN_Y_SHIFT 16 #define R300_VPI_IN_Z_SHIFT 19 #define R300_VPI_IN_W_SHIFT 22 #define R300_VPI_IN_NEG_X (1 << 25) #define R300_VPI_IN_NEG_Y (1 << 26) #define R300_VPI_IN_NEG_Z (1 << 27) #define R300_VPI_IN_NEG_W (1 << 28) /* END */ //BEGIN: Packet 3 commands // A primitive emission dword. #define R300_PRIM_TYPE_NONE (0 << 0) #define R300_PRIM_TYPE_POINT (1 << 0) #define R300_PRIM_TYPE_LINE (2 << 0) #define R300_PRIM_TYPE_LINE_STRIP (3 << 0) #define R300_PRIM_TYPE_TRI_LIST (4 << 0) #define R300_PRIM_TYPE_TRI_FAN (5 << 0) #define R300_PRIM_TYPE_TRI_STRIP (6 << 0) #define R300_PRIM_TYPE_TRI_TYPE2 (7 << 0) #define R300_PRIM_TYPE_RECT_LIST (8 << 0) #define R300_PRIM_TYPE_3VRT_POINT_LIST (9 << 0) #define R300_PRIM_TYPE_3VRT_LINE_LIST (10 << 0) #define R300_PRIM_TYPE_POINT_SPRITES (11 << 0) // GUESS (based on r200) #define R300_PRIM_TYPE_LINE_LOOP (12 << 0) #define R300_PRIM_TYPE_QUADS (13 << 0) #define R300_PRIM_TYPE_QUAD_STRIP (14 << 0) #define R300_PRIM_TYPE_POLYGON (15 << 0) #define R300_PRIM_TYPE_MASK 0xF #define R300_PRIM_WALK_IND (1 << 4) #define R300_PRIM_WALK_LIST (2 << 4) #define R300_PRIM_WALK_RING (3 << 4) #define R300_PRIM_WALK_MASK (3 << 4) #define R300_PRIM_COLOR_ORDER_BGRA (0 << 6) // GUESS (based on r200) #define R300_PRIM_COLOR_ORDER_RGBA (1 << 6) // GUESS #define R300_PRIM_NUM_VERTICES_SHIFT 16 // Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR. // Two parameter dwords: // 0. The first parameter appears to be always 0 // 1. The second parameter is a standard primitive emission dword. #define R300_PACKET3_3D_DRAW_VBUF 0x00002800 // Specify the full set of vertex arrays as (address, stride). // The first parameter is the number of vertex arrays specified. // The rest of the command is a variable length list of blocks, where // each block is three dwords long and specifies two arrays. // The first dword of a block is split into two words, the lower significant // word refers to the first array, the more significant word to the second // array in the block. // The low byte of each word contains the size of an array entry in dwords, // the high byte contains the stride of the array. // The second dword of a block contains the pointer to the first array, // the third dword of a block contains the pointer to the second array. // Note that if the total number of arrays is odd, the third dword of // the last block is omitted. #define R300_PACKET3_3D_LOAD_VBPNTR 0x00002F00 #define R300_PACKET3_INDX_BUFFER 0x00003300 # define R300_EB_UNK1_SHIFT 24 # define R300_EB_UNK1 (0x80<<24) # define R300_EB_UNK2 0x0810 #define R300_PACKET3_3D_DRAW_INDX_2 0x00003600 //END #endif /* _R300_REG_H */