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