/* * Copyright (C) 2005 Vladimir Dergachev. * * 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 THE COPYRIGHT OWNER(S) 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: * Vladimir Dergachev * Nicolai Haehnle * Aapo Tahkola * Ben Skeggs * Jerome Glisse */ /* This files defines functions for accessing R300 hardware. */ #ifndef __R300_EMIT_H__ #define __R300_EMIT_H__ #include "main/glheader.h" #include "r300_context.h" #include "r300_cmdbuf.h" #include "radeon_reg.h" /* TODO: move these defines (and the ones from DRM) into r300_reg.h and sync up * with DRM */ #define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2)) #define CP_PACKET3( pkt, n ) \ (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) static INLINE uint32_t cmdpacket0(int reg, int count) { drm_r300_cmd_header_t cmd; cmd.packet0.cmd_type = R300_CMD_PACKET0; cmd.packet0.count = count; cmd.packet0.reghi = ((unsigned int)reg & 0xFF00) >> 8; cmd.packet0.reglo = ((unsigned int)reg & 0x00FF); return cmd.u; } static INLINE uint32_t cmdvpu(int addr, int count) { drm_r300_cmd_header_t cmd; cmd.vpu.cmd_type = R300_CMD_VPU; cmd.vpu.count = count; cmd.vpu.adrhi = ((unsigned int)addr & 0xFF00) >> 8; cmd.vpu.adrlo = ((unsigned int)addr & 0x00FF); return cmd.u; } static INLINE uint32_t cmdr500fp(int addr, int count, int type, int clamp) { drm_r300_cmd_header_t cmd; cmd.r500fp.cmd_type = R300_CMD_R500FP; cmd.r500fp.count = count; cmd.r500fp.adrhi_flags = ((unsigned int)addr & 0x100) >> 8; cmd.r500fp.adrhi_flags |= type ? R500FP_CONSTANT_TYPE : 0; cmd.r500fp.adrhi_flags |= clamp ? R500FP_CONSTANT_CLAMP : 0; cmd.r500fp.adrlo = ((unsigned int)addr & 0x00FF); return cmd.u; } static INLINE uint32_t cmdpacket3(int packet) { drm_r300_cmd_header_t cmd; cmd.packet3.cmd_type = R300_CMD_PACKET3; cmd.packet3.packet = packet; return cmd.u; } static INLINE uint32_t cmdcpdelay(unsigned short count) { drm_r300_cmd_header_t cmd; cmd.delay.cmd_type = R300_CMD_CP_DELAY; cmd.delay.count = count; return cmd.u; } static INLINE uint32_t cmdwait(unsigned char flags) { drm_r300_cmd_header_t cmd; cmd.wait.cmd_type = R300_CMD_WAIT; cmd.wait.flags = flags; return cmd.u; } static INLINE uint32_t cmdpacify(void) { drm_r300_cmd_header_t cmd; cmd.header.cmd_type = R300_CMD_END3D; return cmd.u; } /** * Prepare to write a register value to register at address reg. * If num_extra > 0 then the following extra values are written * to registers with address +4, +8 and so on.. */ #define reg_start(reg, num_extra) \ do { \ int _n; \ _n=(num_extra); \ cmd = (drm_radeon_cmd_header_t*) \ r300AllocCmdBuf(rmesa, \ (_n+2), \ __FUNCTION__); \ cmd_reserved=_n+2; \ cmd_written=1; \ cmd[0].i=cmdpacket0((reg), _n+1); \ } while (0); /** * Emit GLuint freestyle */ #define e32(dword) \ do { \ if(cmd_written 0x3fff) { \ fprintf(stderr,"Too big packet3 %08x: cannot " \ "store %d dwords\n", \ _p, _n); \ _mesa_exit(-1); \ } \ cmd[0].i = cmdpacket3(R300_CMD_PACKET3_RAW); \ cmd[1].i = _p | ((_n & 0x3fff)<<16); \ } /** * Must be sent to switch to 2d commands */ void static INLINE end_3d(r300ContextPtr rmesa) { drm_radeon_cmd_header_t *cmd = NULL; cmd = (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__); cmd[0].header.cmd_type = R300_CMD_END3D; } void static INLINE cp_delay(r300ContextPtr rmesa, unsigned short count) { drm_radeon_cmd_header_t *cmd = NULL; cmd = (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__); cmd[0].i = cmdcpdelay(count); } void static INLINE cp_wait(r300ContextPtr rmesa, unsigned char flags) { drm_radeon_cmd_header_t *cmd = NULL; cmd = (drm_radeon_cmd_header_t *) r300AllocCmdBuf(rmesa, 1, __FUNCTION__); cmd[0].i = cmdwait(flags); } extern int r300EmitArrays(GLcontext * ctx); #ifdef USER_BUFFERS void r300UseArrays(GLcontext * ctx); #endif extern void r300ReleaseArrays(GLcontext * ctx); extern int r300PrimitiveType(r300ContextPtr rmesa, int prim); extern int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim); extern void r300EmitCacheFlush(r300ContextPtr rmesa); extern GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr, int *inputs, GLint * tab, GLuint nr); extern GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr); extern GLuint r300VAPInputCntl0(GLcontext * ctx, GLuint InputsRead); extern GLuint r300VAPInputCntl1(GLcontext * ctx, GLuint InputsRead); extern GLuint r300VAPOutputCntl0(GLcontext * ctx, GLuint OutputsWritten); extern GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint OutputsWritten); #endif