radeon_cmdbuf.h revision 69edb8a156cb83e6658dfbe50f56ce4394a79e14
1#ifndef COMMON_CMDBUF_H
2#define COMMON_CMDBUF_H
3
4#include "radeon_bocs_wrapper.h"
5
6void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller);
7int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller);
8int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller);
9void rcommonInitCmdBuf(radeonContextPtr rmesa);
10void rcommonDestroyCmdBuf(radeonContextPtr rmesa);
11
12void rcommonBeginBatch(radeonContextPtr rmesa,
13		       int n,
14		       int dostate,
15		       const char *file,
16		       const char *function,
17		       int line);
18
19#define RADEON_CP_PACKET3_NOP                       0xC0001000
20#define RADEON_CP_PACKET3_NEXT_CHAR                 0xC0001900
21#define RADEON_CP_PACKET3_PLY_NEXTSCAN              0xC0001D00
22#define RADEON_CP_PACKET3_SET_SCISSORS              0xC0001E00
23#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM     0xC0002300
24#define RADEON_CP_PACKET3_LOAD_MICROCODE            0xC0002400
25#define RADEON_CP_PACKET3_WAIT_FOR_IDLE             0xC0002600
26#define RADEON_CP_PACKET3_3D_DRAW_VBUF              0xC0002800
27#define RADEON_CP_PACKET3_3D_DRAW_IMMD              0xC0002900
28#define RADEON_CP_PACKET3_3D_DRAW_INDX              0xC0002A00
29#define RADEON_CP_PACKET3_LOAD_PALETTE              0xC0002C00
30#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR            0xC0002F00
31#define RADEON_CP_PACKET3_CNTL_PAINT                0xC0009100
32#define RADEON_CP_PACKET3_CNTL_BITBLT               0xC0009200
33#define RADEON_CP_PACKET3_CNTL_SMALLTEXT            0xC0009300
34#define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT         0xC0009400
35#define RADEON_CP_PACKET3_CNTL_POLYLINE             0xC0009500
36#define RADEON_CP_PACKET3_CNTL_POLYSCANLINES        0xC0009800
37#define RADEON_CP_PACKET3_CNTL_PAINT_MULTI          0xC0009A00
38#define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI         0xC0009B00
39#define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT         0xC0009C00
40
41/* r6xx/r7xx packet 3 type offsets */
42#define R600_SET_CONFIG_REG_OFFSET                  0x00008000
43#define R600_SET_CONFIG_REG_END                     0x0000ac00
44#define R600_SET_CONTEXT_REG_OFFSET                 0x00028000
45#define R600_SET_CONTEXT_REG_END                    0x00029000
46#define R600_SET_ALU_CONST_OFFSET                   0x00030000
47#define R600_SET_ALU_CONST_END                      0x00032000
48#define R600_SET_RESOURCE_OFFSET                    0x00038000
49#define R600_SET_RESOURCE_END                       0x0003c000
50#define R600_SET_SAMPLER_OFFSET                     0x0003c000
51#define R600_SET_SAMPLER_END                        0x0003cff0
52#define R600_SET_CTL_CONST_OFFSET                   0x0003cff0
53#define R600_SET_CTL_CONST_END                      0x0003e200
54#define R600_SET_LOOP_CONST_OFFSET                  0x0003e200
55#define R600_SET_LOOP_CONST_END                     0x0003e380
56#define R600_SET_BOOL_CONST_OFFSET                  0x0003e380
57#define R600_SET_BOOL_CONST_END                     0x00040000
58
59/* r6xx/r7xx packet 3 types */
60#define R600_IT_INDIRECT_BUFFER_END               0x00001700
61#define R600_IT_SET_PREDICATION                   0x00002000
62#define R600_IT_REG_RMW                           0x00002100
63#define R600_IT_COND_EXEC                         0x00002200
64#define R600_IT_PRED_EXEC                         0x00002300
65#define R600_IT_START_3D_CMDBUF                   0x00002400
66#define R600_IT_DRAW_INDEX_2                      0x00002700
67#define R600_IT_CONTEXT_CONTROL                   0x00002800
68#define R600_IT_DRAW_INDEX_IMMD_BE                0x00002900
69#define R600_IT_INDEX_TYPE                        0x00002A00
70#define R600_IT_DRAW_INDEX                        0x00002B00
71#define R600_IT_DRAW_INDEX_AUTO                   0x00002D00
72#define R600_IT_DRAW_INDEX_IMMD                   0x00002E00
73#define R600_IT_NUM_INSTANCES                     0x00002F00
74#define R600_IT_STRMOUT_BUFFER_UPDATE             0x00003400
75#define R600_IT_INDIRECT_BUFFER_MP                0x00003800
76#define R600_IT_MEM_SEMAPHORE                     0x00003900
77#define R600_IT_MPEG_INDEX                        0x00003A00
78#define R600_IT_WAIT_REG_MEM                      0x00003C00
79#define R600_IT_MEM_WRITE                         0x00003D00
80#define R600_IT_INDIRECT_BUFFER                   0x00003200
81#define R600_IT_CP_INTERRUPT                      0x00004000
82#define R600_IT_SURFACE_SYNC                      0x00004300
83#define R600_IT_ME_INITIALIZE                     0x00004400
84#define R600_IT_COND_WRITE                        0x00004500
85#define R600_IT_EVENT_WRITE                       0x00004600
86#define R600_IT_EVENT_WRITE_EOP                   0x00004700
87#define R600_IT_ONE_REG_WRITE                     0x00005700
88#define R600_IT_SET_CONFIG_REG                    0x00006800
89#define R600_IT_SET_CONTEXT_REG                   0x00006900
90#define R600_IT_SET_ALU_CONST                     0x00006A00
91#define R600_IT_SET_BOOL_CONST                    0x00006B00
92#define R600_IT_SET_LOOP_CONST                    0x00006C00
93#define R600_IT_SET_RESOURCE                      0x00006D00
94#define R600_IT_SET_SAMPLER                       0x00006E00
95#define R600_IT_SET_CTL_CONST                     0x00006F00
96#define R600_IT_SURFACE_BASE_UPDATE               0x00007300
97
98
99#define CP_PACKET2  (2 << 30)
100#define CP_PACKET0(reg, n)	(RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2))
101#define CP_PACKET0_ONE(reg, n)	(RADEON_CP_PACKET0 | RADEON_CP_PACKET0_ONE_REG_WR | ((n)<<16) | ((reg)>>2))
102#define CP_PACKET3(pkt, n)	(RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
103
104/**
105 * Every function writing to the command buffer needs to declare this
106 * to get the necessary local variables.
107 */
108#define BATCH_LOCALS(rmesa) \
109	const radeonContextPtr b_l_rmesa = rmesa
110
111/**
112 * Prepare writing n dwords to the command buffer,
113 * including producing any necessary state emits on buffer wraparound.
114 */
115#define BEGIN_BATCH(n) rcommonBeginBatch(b_l_rmesa, n, 1, __FILE__, __FUNCTION__, __LINE__)
116
117/**
118 * Same as BEGIN_BATCH, but do not cause automatic state emits.
119 */
120#define BEGIN_BATCH_NO_AUTOSTATE(n) rcommonBeginBatch(b_l_rmesa, n, 0, __FILE__, __FUNCTION__, __LINE__)
121
122/**
123 * Write one dword to the command buffer.
124 */
125#define OUT_BATCH(data) \
126	do { \
127        radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, data);\
128	} while(0)
129
130/**
131 * Write a relocated dword to the command buffer.
132 */
133#define OUT_BATCH_RELOC(data, bo, offset, rd, wd, flags) 	\
134	do { 							\
135        if (0 && offset) {					\
136            fprintf(stderr, "(%s:%s:%d) offset : %d\n",		\
137            __FILE__, __FUNCTION__, __LINE__, offset);		\
138        }							\
139        radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, offset);	\
140        radeon_cs_write_reloc(b_l_rmesa->cmdbuf.cs, 		\
141                              bo, rd, wd, flags);		\
142	if (!b_l_rmesa->radeonScreen->kernel_mm) 		\
143		b_l_rmesa->cmdbuf.cs->section_cdw += 2;		\
144	} while(0)
145
146
147/**
148 * Write n dwords from ptr to the command buffer.
149 */
150#define OUT_BATCH_TABLE(ptr,n) \
151	do { \
152		int _i; \
153        for (_i=0; _i < n; _i++) {\
154            radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, ptr[_i]);\
155        }\
156	} while(0)
157
158/**
159 * Finish writing dwords to the command buffer.
160 * The number of (direct or indirect) OUT_BATCH calls between the previous
161 * BEGIN_BATCH and END_BATCH must match the number specified at BEGIN_BATCH time.
162 */
163#define END_BATCH() \
164	do { \
165        radeon_cs_end(b_l_rmesa->cmdbuf.cs, __FILE__, __FUNCTION__, __LINE__);\
166	} while(0)
167
168/**
169 * After the last END_BATCH() of rendering, this indicates that flushing
170 * the command buffer now is okay.
171 */
172#define COMMIT_BATCH() \
173	do { \
174	} while(0)
175
176
177/** Single register write to command buffer; requires 2 dwords. */
178#define OUT_BATCH_REGVAL(reg, val) \
179	OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), 1)); \
180	OUT_BATCH((val))
181
182/** Continuous register range write to command buffer; requires 1 dword,
183 * expects count dwords afterwards for register contents. */
184#define OUT_BATCH_REGSEQ(reg, count) \
185	OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), (count)))
186
187/** Write a 32 bit float to the ring; requires 1 dword. */
188#define OUT_BATCH_FLOAT32(f) \
189	OUT_BATCH(radeonPackFloat32((f)))
190
191/* R600/R700 */
192#define R600_OUT_BATCH_REGS(reg, num)					\
193do {								\
194	if ((reg) >= R600_SET_CONFIG_REG_OFFSET && (reg) < R600_SET_CONFIG_REG_END) { \
195		OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, (num)));	\
196		OUT_BATCH(((reg) - R600_SET_CONFIG_REG_OFFSET) >> 2);	\
197	} else if ((reg) >= R600_SET_CONTEXT_REG_OFFSET && (reg) < R600_SET_CONTEXT_REG_END) { \
198		OUT_BATCH(CP_PACKET3(R600_IT_SET_CONTEXT_REG, (num)));	\
199		OUT_BATCH(((reg) - R600_SET_CONTEXT_REG_OFFSET) >> 2);	\
200	} else if ((reg) >= R600_SET_ALU_CONST_OFFSET && (reg) < R600_SET_ALU_CONST_END) { \
201		OUT_BATCH(CP_PACKET3(R600_IT_SET_ALU_CONST, (num)));	\
202		OUT_BATCH(((reg) - R600_SET_ALU_CONST_OFFSET) >> 2);	\
203	} else if ((reg) >= R600_SET_RESOURCE_OFFSET && (reg) < R600_SET_RESOURCE_END) { \
204		OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, (num)));	\
205		OUT_BATCH(((reg) - R600_SET_RESOURCE_OFFSET) >> 2);	\
206	} else if ((reg) >= R600_SET_SAMPLER_OFFSET && (reg) < R600_SET_SAMPLER_END) { \
207		OUT_BATCH(CP_PACKET3(R600_IT_SET_SAMPLER, (num)));	\
208		OUT_BATCH(((reg) - R600_SET_SAMPLER_OFFSET) >> 2);	\
209	} else if ((reg) >= R600_SET_CTL_CONST_OFFSET && (reg) < R600_SET_CTL_CONST_END) { \
210		OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, (num)));	\
211		OUT_BATCH(((reg) - R600_SET_CTL_CONST_OFFSET) >> 2);	\
212	} else if ((reg) >= R600_SET_LOOP_CONST_OFFSET && (reg) < R600_SET_LOOP_CONST_END) { \
213		OUT_BATCH(CP_PACKET3(R600_IT_SET_LOOP_CONST, (num)));	\
214		OUT_BATCH(((reg) - R600_SET_LOOP_CONST_OFFSET) >> 2);	\
215	} else if ((reg) >= R600_SET_BOOL_CONST_OFFSET && (reg) < R600_SET_BOOL_CONST_END) { \
216		OUT_BATCH(CP_PACKET3(R600_IT_SET_BOOL_CONST, (num)));	\
217		OUT_BATCH(((reg) - R600_SET_BOOL_CONST_OFFSET) >> 2);	\
218	} else {							\
219		OUT_BATCH(cmdpacket0(b_l_rmesa->radeonScreen, (reg), (num))); \
220	}								\
221} while (0)
222
223/** Single register write to command buffer; requires 3 dwords for most things. */
224#define R600_OUT_BATCH_REGVAL(reg, val)		\
225	R600_OUT_BATCH_REGS((reg), 1);		\
226	OUT_BATCH((val))
227
228/** Continuous register range write to command buffer; requires 1 dword,
229 * expects count dwords afterwards for register contents. */
230#define R600_OUT_BATCH_REGSEQ(reg, count)	\
231	R600_OUT_BATCH_REGS((reg), (count))
232
233/* Fire the buffered vertices no matter what.
234 */
235static INLINE void radeon_firevertices(radeonContextPtr radeon)
236{
237   if (radeon->cmdbuf.cs->cdw || radeon->dma.flush )
238      radeonFlush(radeon->glCtx);
239}
240
241#endif
242