diff options
Diffstat (limited to 'src/mesa/drivers/dri/r300')
20 files changed, 4439 insertions, 1359 deletions
diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile index 44248964fd..5b2bd0bc2b 100644 --- a/src/mesa/drivers/dri/r300/Makefile +++ b/src/mesa/drivers/dri/r300/Makefile @@ -39,6 +39,7 @@ DRIVER_SOURCES = \ r300_texstate.c \ r300_vertprog.c \ r300_fragprog.c \ + r500_fragprog.c \ r300_shader.c \ r300_emit.c \ r300_swtcl.c \ diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 3497738eac..8d4d604ba9 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -164,7 +164,7 @@ static inline void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty) r300->cmdbuf.count_used++; /* Emit cache flush */ - *dest = cmdpacket0(R300_TX_CNTL, 1); + *dest = cmdpacket0(R300_TX_INVALTAGS, 1); dest++; r300->cmdbuf.count_used++; @@ -242,6 +242,7 @@ void r300EmitState(r300ContextPtr r300) #define packet0_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->packet0.count) #define vpu_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count) +#define r500fp_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->r500fp.count) static int check_always(r300ContextPtr r300, struct r300_state_atom *atom) { @@ -262,6 +263,20 @@ static int check_vpu(r300ContextPtr r300, struct r300_state_atom *atom) return cnt ? (cnt * 4) + 1 : 0; } +static int check_r500fp(r300ContextPtr r300, struct r300_state_atom *atom) +{ + int cnt; + cnt = r500fp_count(atom->cmd); + return cnt ? (cnt * 6) + 1 : 0; +} + +static int check_r500fp_const(r300ContextPtr r300, struct r300_state_atom *atom) +{ + int cnt; + cnt = r500fp_count(atom->cmd); + return cnt ? (cnt * 4) + 1 : 0; +} + #define ALLOC_STATE( ATOM, CHK, SZ, IDX ) \ do { \ r300->hw.ATOM.cmd_size = (SZ); \ @@ -281,10 +296,15 @@ void r300InitCmdBuf(r300ContextPtr r300) { int size, mtu; int has_tcl = 1; + int is_r500 = 0; + int i; if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) has_tcl = 0; + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) + is_r500 = 1; + r300->hw.max_state_size = 2 + 2; /* reserve extra space for WAIT_IDLE and tex cache flush */ mtu = r300->radeon.glCtx->Const.MaxTextureUnits; @@ -299,8 +319,15 @@ void r300InitCmdBuf(r300ContextPtr r300) /* Initialize state atoms */ ALLOC_STATE(vpt, always, R300_VPT_CMDSIZE, 0); r300->hw.vpt.cmd[R300_VPT_CMD_0] = cmdpacket0(R300_SE_VPORT_XSCALE, 6); - ALLOC_STATE(vap_cntl, always, 2, 0); - r300->hw.vap_cntl.cmd[0] = cmdpacket0(R300_VAP_CNTL, 1); + ALLOC_STATE(vap_cntl, always, R300_VAP_CNTL_SIZE, 0); + r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH] = cmdpacket0(R300_VAP_PVS_STATE_FLUSH_REG, 1); + r300->hw.vap_cntl.cmd[R300_VAP_CNTL_FLUSH_1] = 0; + r300->hw.vap_cntl.cmd[R300_VAP_CNTL_CMD] = cmdpacket0(R300_VAP_CNTL, 1); + if (is_r500) { + ALLOC_STATE(vap_index_offset, always, 2, 0); + r300->hw.vap_index_offset.cmd[0] = cmdpacket0(R500_VAP_INDEX_OFFSET, 1); + r300->hw.vap_index_offset.cmd[1] = 0; + } ALLOC_STATE(vte, always, 3, 0); r300->hw.vte.cmd[0] = cmdpacket0(R300_SE_VTE_CNTL, 2); ALLOC_STATE(vap_vf_max_vtx_indx, always, 3, 0); @@ -309,12 +336,12 @@ void r300InitCmdBuf(r300ContextPtr r300) r300->hw.vap_cntl_status.cmd[0] = cmdpacket0(R300_VAP_CNTL_STATUS, 1); ALLOC_STATE(vir[0], variable, R300_VIR_CMDSIZE, 0); r300->hw.vir[0].cmd[R300_VIR_CMD_0] = - cmdpacket0(R300_VAP_INPUT_ROUTE_0_0, 1); + cmdpacket0(R300_VAP_PROG_STREAM_CNTL_0, 1); ALLOC_STATE(vir[1], variable, R300_VIR_CMDSIZE, 1); r300->hw.vir[1].cmd[R300_VIR_CMD_0] = - cmdpacket0(R300_VAP_INPUT_ROUTE_1_0, 1); + cmdpacket0(R300_VAP_PROG_STREAM_CNTL_EXT_0, 1); ALLOC_STATE(vic, always, R300_VIC_CMDSIZE, 0); - r300->hw.vic.cmd[R300_VIC_CMD_0] = cmdpacket0(R300_VAP_INPUT_CNTL_0, 2); + r300->hw.vic.cmd[R300_VIC_CMD_0] = cmdpacket0(R300_VAP_VTX_STATE_CNTL, 2); ALLOC_STATE(vap_psc_sgn_norm_cntl, always, 2, 0); r300->hw.vap_psc_sgn_norm_cntl.cmd[0] = cmdpacket0(R300_VAP_PSC_SGN_NORM_CNTL, SGN_NORM_ZERO_CLAMP_MINUS_ONE); @@ -322,7 +349,7 @@ void r300InitCmdBuf(r300ContextPtr r300) ALLOC_STATE(vap_clip_cntl, always, 2, 0); r300->hw.vap_clip_cntl.cmd[0] = cmdpacket0(R300_VAP_CLIP_CNTL, 1); ALLOC_STATE(vap_clip, always, 5, 0); - r300->hw.vap_clip.cmd[0] = cmdpacket0(R300_VAP_CLIP_X_0, 4); + r300->hw.vap_clip.cmd[0] = cmdpacket0(R300_VAP_GB_VERT_CLIP_ADJ, 4); ALLOC_STATE(vap_pvs_vtx_timeout_reg, always, 2, 0); r300->hw.vap_pvs_vtx_timeout_reg.cmd[0] = cmdpacket0(VAP_PVS_VTX_TIMEOUT_REG, 1); } @@ -334,7 +361,7 @@ void r300InitCmdBuf(r300ContextPtr r300) if (has_tcl) { ALLOC_STATE(pvs, always, R300_PVS_CMDSIZE, 0); r300->hw.pvs.cmd[R300_PVS_CMD_0] = - cmdpacket0(R300_VAP_PVS_CNTL_1, 3); + cmdpacket0(R300_VAP_PVS_CODE_CNTL_0, 3); } ALLOC_STATE(gb_enable, always, 2, 0); @@ -344,69 +371,99 @@ void r300InitCmdBuf(r300ContextPtr r300) ALLOC_STATE(txe, always, R300_TXE_CMDSIZE, 0); r300->hw.txe.cmd[R300_TXE_CMD_0] = cmdpacket0(R300_TX_ENABLE, 1); ALLOC_STATE(ga_point_s0, always, 5, 0); - r300->hw.ga_point_s0.cmd[0] = cmdpacket0(GA_POINT_S0, 4); + r300->hw.ga_point_s0.cmd[0] = cmdpacket0(R300_GA_POINT_S0, 4); ALLOC_STATE(ga_triangle_stipple, always, 2, 0); - r300->hw.ga_triangle_stipple.cmd[0] = cmdpacket0(GA_TRIANGLE_STIPPLE, 1); + r300->hw.ga_triangle_stipple.cmd[0] = cmdpacket0(R300_GA_TRIANGLE_STIPPLE, 1); ALLOC_STATE(ps, always, R300_PS_CMDSIZE, 0); r300->hw.ps.cmd[0] = cmdpacket0(R300_GA_POINT_SIZE, 1); ALLOC_STATE(ga_point_minmax, always, 4, 0); r300->hw.ga_point_minmax.cmd[0] = cmdpacket0(R300_GA_POINT_MINMAX, 3); ALLOC_STATE(lcntl, always, 2, 0); - r300->hw.lcntl.cmd[0] = cmdpacket0(GA_LINE_CNTL, 1); + r300->hw.lcntl.cmd[0] = cmdpacket0(R300_GA_LINE_CNTL, 1); ALLOC_STATE(ga_line_stipple, always, 4, 0); r300->hw.ga_line_stipple.cmd[0] = cmdpacket0(R300_GA_LINE_STIPPLE_VALUE, 3); ALLOC_STATE(shade, always, 5, 0); - r300->hw.shade.cmd[0] = cmdpacket0(GA_ENHANCE, 4); + r300->hw.shade.cmd[0] = cmdpacket0(R300_GA_ENHANCE, 4); ALLOC_STATE(polygon_mode, always, 4, 0); - r300->hw.polygon_mode.cmd[0] = cmdpacket0(GA_POLY_MODE, 3); + r300->hw.polygon_mode.cmd[0] = cmdpacket0(R300_GA_POLY_MODE, 3); ALLOC_STATE(fogp, always, 3, 0); - r300->hw.fogp.cmd[0] = cmdpacket0(R300_RE_FOG_SCALE, 2); + r300->hw.fogp.cmd[0] = cmdpacket0(R300_GA_FOG_SCALE, 2); ALLOC_STATE(zbias_cntl, always, 2, 0); - r300->hw.zbias_cntl.cmd[0] = cmdpacket0(R300_RE_ZBIAS_CNTL, 1); + r300->hw.zbias_cntl.cmd[0] = cmdpacket0(R300_SU_TEX_WRAP, 1); ALLOC_STATE(zbs, always, R300_ZBS_CMDSIZE, 0); r300->hw.zbs.cmd[R300_ZBS_CMD_0] = - cmdpacket0(R300_RE_ZBIAS_T_FACTOR, 4); + cmdpacket0(R300_SU_POLY_OFFSET_FRONT_SCALE, 4); ALLOC_STATE(occlusion_cntl, always, 2, 0); - r300->hw.occlusion_cntl.cmd[0] = cmdpacket0(R300_RE_OCCLUSION_CNTL, 1); + r300->hw.occlusion_cntl.cmd[0] = cmdpacket0(R300_SU_POLY_OFFSET_ENABLE, 1); ALLOC_STATE(cul, always, R300_CUL_CMDSIZE, 0); - r300->hw.cul.cmd[R300_CUL_CMD_0] = cmdpacket0(R300_RE_CULL_CNTL, 1); + r300->hw.cul.cmd[R300_CUL_CMD_0] = cmdpacket0(R300_SU_CULL_MODE, 1); ALLOC_STATE(su_depth_scale, always, 3, 0); r300->hw.su_depth_scale.cmd[0] = cmdpacket0(R300_SU_DEPTH_SCALE, 2); ALLOC_STATE(rc, always, R300_RC_CMDSIZE, 0); r300->hw.rc.cmd[R300_RC_CMD_0] = cmdpacket0(R300_RS_COUNT, 2); - ALLOC_STATE(ri, always, R300_RI_CMDSIZE, 0); - r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(R300_RS_IP_0, 8); - ALLOC_STATE(rr, variable, R300_RR_CMDSIZE, 0); - r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, 1); + if (is_r500) { + ALLOC_STATE(ri, always, R500_RI_CMDSIZE, 0); + r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(R500_RS_IP_0, 16); + for (i = 0; i < 8; i++) { + r300->hw.ri.cmd[R300_RI_CMD_0 + i +1] = + (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) | + (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) | + (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) | + (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT); + } + ALLOC_STATE(rr, variable, R300_RR_CMDSIZE, 0); + r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R500_RS_INST_0, 1); + } else { + ALLOC_STATE(ri, always, R300_RI_CMDSIZE, 0); + r300->hw.ri.cmd[R300_RI_CMD_0] = cmdpacket0(R300_RS_IP_0, 8); + ALLOC_STATE(rr, variable, R300_RR_CMDSIZE, 0); + r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, 1); + } ALLOC_STATE(sc_hyperz, always, 3, 0); r300->hw.sc_hyperz.cmd[0] = cmdpacket0(R300_SC_HYPERZ, 2); ALLOC_STATE(sc_screendoor, always, 2, 0); r300->hw.sc_screendoor.cmd[0] = cmdpacket0(R300_SC_SCREENDOOR, 1); - ALLOC_STATE(fp, always, R300_FP_CMDSIZE, 0); - r300->hw.fp.cmd[R300_FP_CMD_0] = cmdpacket0(R300_PFS_CNTL_0, 3); - r300->hw.fp.cmd[R300_FP_CMD_1] = cmdpacket0(R300_PFS_NODE_0, 4); - ALLOC_STATE(fpt, variable, R300_FPT_CMDSIZE, 0); - r300->hw.fpt.cmd[R300_FPT_CMD_0] = cmdpacket0(R300_PFS_TEXI_0, 0); ALLOC_STATE(us_out_fmt, always, 6, 0); - r300->hw.us_out_fmt.cmd[0] = cmdpacket0(R500_US_OUT_FMT, 5); - ALLOC_STATE(fpi[0], variable, R300_FPI_CMDSIZE, 0); - r300->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR0_0, 1); - ALLOC_STATE(fpi[1], variable, R300_FPI_CMDSIZE, 1); - r300->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR1_0, 1); - ALLOC_STATE(fpi[2], variable, R300_FPI_CMDSIZE, 2); - r300->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR2_0, 1); - ALLOC_STATE(fpi[3], variable, R300_FPI_CMDSIZE, 3); - r300->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR3_0, 1); + r300->hw.us_out_fmt.cmd[0] = cmdpacket0(R300_US_OUT_FMT, 5); + + if (is_r500) { + ALLOC_STATE(fp, always, R500_FP_CMDSIZE, 0); + r300->hw.fp.cmd[R500_FP_CMD_0] = cmdpacket0(R500_US_CONFIG, 2); + r300->hw.fp.cmd[R500_FP_CNTL] = R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO; + r300->hw.fp.cmd[R500_FP_CMD_1] = cmdpacket0(R500_US_CODE_ADDR, 3); + r300->hw.fp.cmd[R500_FP_CMD_2] = cmdpacket0(R500_US_FC_CTRL, 1); + r300->hw.fp.cmd[R500_FP_FC_CNTL] = 0; /* FIXME when we add flow control */ + + ALLOC_STATE(r500fp, r500fp, R500_FPI_CMDSIZE, 0); + r300->hw.r500fp.cmd[R300_FPI_CMD_0] = cmdr500fp(0, 0, 0, 0); + ALLOC_STATE(r500fp_const, r500fp_const, R500_FPP_CMDSIZE, 0); + r300->hw.r500fp_const.cmd[R300_FPI_CMD_0] = cmdr500fp(0, 0, 1, 0); + } else { + ALLOC_STATE(fp, always, R300_FP_CMDSIZE, 0); + r300->hw.fp.cmd[R300_FP_CMD_0] = cmdpacket0(R300_US_CONFIG, 3); + r300->hw.fp.cmd[R300_FP_CMD_1] = cmdpacket0(R300_US_CODE_ADDR_0, 4); + ALLOC_STATE(fpt, variable, R300_FPT_CMDSIZE, 0); + r300->hw.fpt.cmd[R300_FPT_CMD_0] = cmdpacket0(R300_US_TEX_INST_0, 0); + + ALLOC_STATE(fpi[0], variable, R300_FPI_CMDSIZE, 0); + r300->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_INST_0, 1); + ALLOC_STATE(fpi[1], variable, R300_FPI_CMDSIZE, 1); + r300->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_ADDR_0, 1); + ALLOC_STATE(fpi[2], variable, R300_FPI_CMDSIZE, 2); + r300->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_INST_0, 1); + ALLOC_STATE(fpi[3], variable, R300_FPI_CMDSIZE, 3); + r300->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0, 1); + ALLOC_STATE(fpp, variable, R300_FPP_CMDSIZE, 0); + r300->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(R300_PFS_PARAM_0_X, 0); + } ALLOC_STATE(fogs, always, R300_FOGS_CMDSIZE, 0); - r300->hw.fogs.cmd[R300_FOGS_CMD_0] = cmdpacket0(FG_FOG_BLEND, 1); + r300->hw.fogs.cmd[R300_FOGS_CMD_0] = cmdpacket0(R300_FG_FOG_BLEND, 1); ALLOC_STATE(fogc, always, R300_FOGC_CMDSIZE, 0); - r300->hw.fogc.cmd[R300_FOGC_CMD_0] = cmdpacket0(FG_FOG_COLOR_R, 3); + r300->hw.fogc.cmd[R300_FOGC_CMD_0] = cmdpacket0(R300_FG_FOG_COLOR_R, 3); ALLOC_STATE(at, always, R300_AT_CMDSIZE, 0); - r300->hw.at.cmd[R300_AT_CMD_0] = cmdpacket0(FG_ALPHA_FUNC, 2); + r300->hw.at.cmd[R300_AT_CMD_0] = cmdpacket0(R300_FG_ALPHA_FUNC, 2); ALLOC_STATE(fg_depth_src, always, 2, 0); r300->hw.fg_depth_src.cmd[0] = cmdpacket0(R300_FG_DEPTH_SRC, 1); - ALLOC_STATE(fpp, variable, R300_FPP_CMDSIZE, 0); - r300->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(R300_PFS_PARAM_0_X, 0); ALLOC_STATE(rb3d_cctl, always, 2, 0); r300->hw.rb3d_cctl.cmd[0] = cmdpacket0(R300_RB3D_CCTL, 1); ALLOC_STATE(bld, always, R300_BLD_CMDSIZE, 0); @@ -421,45 +478,61 @@ void r300InitCmdBuf(r300ContextPtr r300) ALLOC_STATE(rb3d_dither_ctl, always, 10, 0); r300->hw.rb3d_dither_ctl.cmd[0] = cmdpacket0(R300_RB3D_DITHER_CTL, 9); ALLOC_STATE(rb3d_aaresolve_ctl, always, 2, 0); - r300->hw.rb3d_aaresolve_ctl.cmd[0] = cmdpacket0(RB3D_AARESOLVE_CTL, 1); + r300->hw.rb3d_aaresolve_ctl.cmd[0] = cmdpacket0(R300_RB3D_AARESOLVE_CTL, 1); ALLOC_STATE(rb3d_discard_src_pixel_lte_threshold, always, 3, 0); - r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[0] = cmdpacket0(RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 2); + r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[0] = cmdpacket0(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 2); ALLOC_STATE(zs, always, R300_ZS_CMDSIZE, 0); r300->hw.zs.cmd[R300_ZS_CMD_0] = - cmdpacket0(R300_RB3D_ZSTENCIL_CNTL_0, 3); + cmdpacket0(R300_ZB_CNTL, 3); ALLOC_STATE(zstencil_format, always, 5, 0); r300->hw.zstencil_format.cmd[0] = - cmdpacket0(ZB_FORMAT, 4); + cmdpacket0(R300_ZB_FORMAT, 4); ALLOC_STATE(zb, always, R300_ZB_CMDSIZE, 0); - r300->hw.zb.cmd[R300_ZB_CMD_0] = cmdpacket0(ZB_DEPTHOFFSET, 2); + r300->hw.zb.cmd[R300_ZB_CMD_0] = cmdpacket0(R300_ZB_DEPTHOFFSET, 2); ALLOC_STATE(zb_depthclearvalue, always, 2, 0); - r300->hw.zb_depthclearvalue.cmd[0] = cmdpacket0(ZB_DEPTHCLEARVALUE, 1); + r300->hw.zb_depthclearvalue.cmd[0] = cmdpacket0(R300_ZB_DEPTHCLEARVALUE, 1); ALLOC_STATE(unk4F30, always, 3, 0); r300->hw.unk4F30.cmd[0] = cmdpacket0(0x4F30, 2); ALLOC_STATE(zb_hiz_offset, always, 2, 0); - r300->hw.zb_hiz_offset.cmd[0] = cmdpacket0(ZB_HIZ_OFFSET, 1); + r300->hw.zb_hiz_offset.cmd[0] = cmdpacket0(R300_ZB_HIZ_OFFSET, 1); ALLOC_STATE(zb_hiz_pitch, always, 2, 0); - r300->hw.zb_hiz_pitch.cmd[0] = cmdpacket0(ZB_HIZ_PITCH, 1); + r300->hw.zb_hiz_pitch.cmd[0] = cmdpacket0(R300_ZB_HIZ_PITCH, 1); /* VPU only on TCL */ if (has_tcl) { int i; ALLOC_STATE(vpi, vpu, R300_VPI_CMDSIZE, 0); r300->hw.vpi.cmd[R300_VPI_CMD_0] = - cmdvpu(R300_PVS_UPLOAD_PROGRAM, 0); + cmdvpu(R300_PVS_CODE_START, 0); - ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0); - r300->hw.vpp.cmd[R300_VPP_CMD_0] = - cmdvpu(R300_PVS_UPLOAD_PARAMETERS, 0); + if (is_r500) { + ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0); + r300->hw.vpp.cmd[R300_VPP_CMD_0] = + cmdvpu(R500_PVS_CONST_START, 0); - ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0); - r300->hw.vps.cmd[R300_VPS_CMD_0] = - cmdvpu(R300_PVS_UPLOAD_POINTSIZE, 1); + ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0); + r300->hw.vps.cmd[R300_VPS_CMD_0] = + cmdvpu(R500_POINT_VPORT_SCALE_OFFSET, 1); - for (i = 0; i < 6; i++) { - ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0); - r300->hw.vpucp[i].cmd[R300_VPUCP_CMD_0] = - cmdvpu(R300_PVS_UPLOAD_CLIP_PLANE0+i, 1); + for (i = 0; i < 6; i++) { + ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0); + r300->hw.vpucp[i].cmd[R300_VPUCP_CMD_0] = + cmdvpu(R500_PVS_UCP_START + i, 1); + } + } else { + ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0); + r300->hw.vpp.cmd[R300_VPP_CMD_0] = + cmdvpu(R300_PVS_CONST_START, 0); + + ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0); + r300->hw.vps.cmd[R300_VPS_CMD_0] = + cmdvpu(R300_POINT_VPORT_SCALE_OFFSET, 1); + + for (i = 0; i < 6; i++) { + ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0); + r300->hw.vpucp[i].cmd[R300_VPUCP_CMD_0] = + cmdvpu(R300_PVS_UCP_START + i, 1); + } } } diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index c56a762289..31cc00a081 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -278,6 +278,11 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, ctx->Const.MaxTextureCoordUnits); ctx->Const.MaxTextureMaxAnisotropy = 16.0; + if (screen->chip_family >= CHIP_FAMILY_RV515) { + ctx->Const.MaxTextureLevels = 13; + ctx->Const.MaxTextureRectSize = 4096; + } + ctx->Const.MinPointSize = 1.0; ctx->Const.MinPointSizeAA = 1.0; ctx->Const.MaxPointSize = R300_POINTSIZE_MAX; diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 780d9aa5d2..a5ec5ee46e 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -74,6 +74,7 @@ typedef struct r300_context *r300ContextPtr; #include "r300_vertprog.h" #include "r300_fragprog.h" +#include "r500_fragprog.h" /** * This function takes a float and packs it into a uint32_t @@ -330,6 +331,8 @@ struct r300_state_atom { #define R300_RI_INTERP_7 8 #define R300_RI_CMDSIZE 9 +#define R500_RI_CMDSIZE 17 + #define R300_RR_CMD_0 0 /* rr is variable size (at least 1) */ #define R300_RR_INST_0 1 #define R300_RR_INST_1 2 @@ -352,6 +355,17 @@ struct r300_state_atom { #define R300_FP_NODE3 8 #define R300_FP_CMDSIZE 9 +#define R500_FP_CMD_0 0 +#define R500_FP_CNTL 1 +#define R500_FP_PIXSIZE 2 +#define R500_FP_CMD_1 3 +#define R500_FP_CODE_ADDR 4 +#define R500_FP_CODE_RANGE 5 +#define R500_FP_CODE_OFFSET 6 +#define R500_FP_CMD_2 7 +#define R500_FP_FC_CNTL 8 +#define R500_FP_CMDSIZE 9 + #define R300_FPT_CMD_0 0 #define R300_FPT_INSTR_0 1 #define R300_FPT_CMDSIZE 65 @@ -359,10 +373,14 @@ struct r300_state_atom { #define R300_FPI_CMD_0 0 #define R300_FPI_INSTR_0 1 #define R300_FPI_CMDSIZE 65 +/* R500 has space for 512 instructions - 6 dwords per instruction */ +#define R500_FPI_CMDSIZE (512*6+1) #define R300_FPP_CMD_0 0 #define R300_FPP_PARAM_0 1 #define R300_FPP_CMDSIZE (32*4+1) +/* R500 has spcae for 256 constants - 4 dwords per constant */ +#define R500_FPP_CMDSIZE (256*4+1) #define R300_FOGS_CMD_0 0 #define R300_FOGS_STATE 1 @@ -410,6 +428,12 @@ struct r300_state_atom { #define R300_ZB_PITCH 2 #define R300_ZB_CMDSIZE 3 +#define R300_VAP_CNTL_FLUSH 0 +#define R300_VAP_CNTL_FLUSH_1 1 +#define R300_VAP_CNTL_CMD 2 +#define R300_VAP_CNTL_INSTR 3 +#define R300_VAP_CNTL_SIZE 4 + #define R300_VPI_CMD_0 0 #define R300_VPI_INSTR_0 1 #define R300_VPI_CMDSIZE 1025 /* 256 16 byte instructions */ @@ -451,6 +475,7 @@ struct r300_hw_state { struct r300_state_atom vpt; /* viewport (1D98) */ struct r300_state_atom vap_cntl; + struct r300_state_atom vap_index_offset; /* 0x208c r5xx only */ struct r300_state_atom vof; /* VAP output format register 0x2090 */ struct r300_state_atom vte; /* (20B0) */ struct r300_state_atom vap_vf_max_vtx_indx; /* Maximum Vertex Indx Clamp (2134) */ @@ -473,7 +498,7 @@ struct r300_hw_state { struct r300_state_atom shade; struct r300_state_atom polygon_mode; struct r300_state_atom fogp; /* fog parameters (4294) */ - struct r300_state_atom unk429C; /* (429C) */ + struct r300_state_atom ga_soft_reset; /* (429C) */ struct r300_state_atom zbias_cntl; struct r300_state_atom zbs; /* zbias (42A4) */ struct r300_state_atom occlusion_cntl; @@ -487,6 +512,8 @@ struct r300_hw_state { struct r300_state_atom fp; /* fragment program cntl + nodes (4600) */ struct r300_state_atom fpt; /* texi - (4620) */ struct r300_state_atom us_out_fmt; /* (46A4) */ + struct r300_state_atom r500fp; /* r500 fp instructions */ + struct r300_state_atom r500fp_const; /* r500 fp constants */ struct r300_state_atom fpi[4]; /* fp instructions (46C0/47C0/48C0/49C0) */ struct r300_state_atom fogs; /* fog state (4BC0) */ struct r300_state_atom fogc; /* fog color (4BC8) */ @@ -767,6 +794,47 @@ struct r300_fragment_program { int max_temp_idx; + GLboolean WritesDepth; + GLuint optimization; +}; + +struct r500_fragment_program { + struct gl_fragment_program mesa_program; + + GLcontext *ctx; + GLboolean translated; + GLboolean error; + struct r300_pfs_compile_state *cs; + + struct { + GLuint inst0; + GLuint inst1; + GLuint inst2; + GLuint inst3; + GLuint inst4; + GLuint inst5; + } inst[512]; + /* TODO: This is magic! */ + + int temp_reg_offset; + + int inst_offset; + int inst_end; + + /* Hardware constants. + * Contains a pointer to the value. The destination of the pointer + * is supposed to be updated when GL state changes. + * Typically, this is either a pointer into + * gl_program_parameter_list::ParameterValues, or a pointer to a + * global constant (e.g. for sin/cos-approximation) + */ + const GLfloat *constant[PFS_NUM_CONST_REGS]; + int const_nr; + + int max_temp_idx; + + GLboolean writes_depth; + GLuint optimization; }; @@ -804,7 +872,7 @@ struct r300_state { */ struct r300_swtcl_info { GLuint RenderIndex; - + /** * Size of a hardware vertex. This is calculated when \c ::vertex_attrs is * installed in the Mesa state vector. diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c index e7371133d3..2ea17ad0a7 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.c +++ b/src/mesa/drivers/dri/r300/r300_emit.c @@ -207,7 +207,10 @@ static void r300EmitVec(GLcontext * ctx, struct r300_dma_region *rvb, } } -static GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr, +#define DW_SIZE(x) ((inputs[tab[(x)]] << R300_DST_VEC_LOC_SHIFT) | \ + (attribptr[tab[(x)]]->size - 1) << R300_DATA_TYPE_0_SHIFT) + +GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr, int *inputs, GLint * tab, GLuint nr) { GLuint i, dw; @@ -216,14 +219,15 @@ static GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr, for (i = 0; i < nr; i += 2) { /* make sure input is valid, would lockup the gpu */ assert(inputs[tab[i]] != -1); - dw = R300_INPUT_ROUTE_FLOAT | (inputs[tab[i]] << 8) | (attribptr[tab[i]]->size - 1); + dw = (R300_SIGNED | DW_SIZE(i)); if (i + 1 == nr) { - dw |= R300_VAP_INPUT_ROUTE_END; + dw |= R300_LAST_VEC << R300_DATA_TYPE_0_SHIFT; } else { assert(inputs[tab[i + 1]] != -1); - dw |= (R300_INPUT_ROUTE_FLOAT | (inputs[tab[i + 1]] << 8) | (attribptr[tab[i + 1]]->size - 1)) << 16; + dw |= (R300_SIGNED | + DW_SIZE(i + 1)) << R300_DATA_TYPE_1_SHIFT; if (i + 2 == nr) { - dw |= (R300_VAP_INPUT_ROUTE_END << 16); + dw |= R300_LAST_VEC << R300_DATA_TYPE_1_SHIFT; } } dst[i >> 1] = dw; @@ -234,10 +238,10 @@ static GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr, static GLuint r300VAPInputRoute1Swizzle(int swizzle[4]) { - return (swizzle[0] << R300_INPUT_ROUTE_X_SHIFT) | - (swizzle[1] << R300_INPUT_ROUTE_Y_SHIFT) | - (swizzle[2] << R300_INPUT_ROUTE_Z_SHIFT) | - (swizzle[3] << R300_INPUT_ROUTE_W_SHIFT); + return (swizzle[0] << R300_SWIZZLE_SELECT_X_SHIFT) | + (swizzle[1] << R300_SWIZZLE_SELECT_Y_SHIFT) | + (swizzle[2] << R300_SWIZZLE_SELECT_Z_SHIFT) | + (swizzle[3] << R300_SWIZZLE_SELECT_W_SHIFT); } GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr) @@ -245,9 +249,13 @@ GLuint r300VAPInputRoute1(uint32_t * dst, int swizzle[][4], GLuint nr) GLuint i, dw; for (i = 0; i < nr; i += 2) { - dw = r300VAPInputRoute1Swizzle(swizzle[i]) | R300_INPUT_ROUTE_ENABLE; + dw = (r300VAPInputRoute1Swizzle(swizzle[i]) | + ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | + R300_WRITE_ENA_Z | R300_WRITE_ENA_W) << R300_WRITE_ENA_SHIFT)) << R300_SWIZZLE0_SHIFT; if (i + 1 < nr) { - dw |= (r300VAPInputRoute1Swizzle(swizzle[i + 1]) | R300_INPUT_ROUTE_ENABLE) << 16; + dw |= (r300VAPInputRoute1Swizzle(swizzle[i + 1]) | + ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | + R300_WRITE_ENA_Z | R300_WRITE_ENA_W) << R300_WRITE_ENA_SHIFT)) << R300_SWIZZLE1_SHIFT; } dst[i >> 1] = dw; } @@ -542,10 +550,10 @@ void r300EmitCacheFlush(r300ContextPtr rmesa) drm_radeon_cmd_header_t *cmd = NULL; reg_start(R300_RB3D_DSTCACHE_CTLSTAT, 0); - e32(RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS | - RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); + e32(R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS | + R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); - reg_start(ZB_ZCACHE_CTLSTAT, 0); - e32(ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | - ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); + reg_start(R300_ZB_ZCACHE_CTLSTAT, 0); + e32(R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | + R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); } diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h index a6d69ec5ff..e6a6df8c4c 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.h +++ b/src/mesa/drivers/dri/r300/r300_emit.h @@ -74,6 +74,20 @@ static inline uint32_t cmdvpu(int addr, int count) 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; @@ -166,6 +180,19 @@ static inline uint32_t cmdpacify(void) cmd[0].i = cmdvpu((dest), _n/4); \ } while (0); +#define r500fp_start_fragment(dest, length) \ + do { \ + int _n; \ + _n = (length); \ + cmd = (drm_radeon_cmd_header_t*) \ + r300AllocCmdBuf(rmesa, \ + (_n+1), \ + __FUNCTION__); \ + cmd_reserved = _n+1; \ + cmd_written =1; \ + cmd[0].i = cmdr500fp((dest), _n/6, 0, 0); \ + } while (0); + #define start_packet3(packet, count) \ { \ int _n; \ @@ -230,6 +257,8 @@ 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); diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index c664fb6562..54b80d20a1 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -172,19 +172,19 @@ static const struct { int s_op; } r300_fpop[] = { /* *INDENT-OFF* */ - {"MAD", 3, R300_FPI0_OUTC_MAD, R300_FPI2_OUTA_MAD}, - {"DP3", 2, R300_FPI0_OUTC_DP3, R300_FPI2_OUTA_DP4}, - {"DP4", 2, R300_FPI0_OUTC_DP4, R300_FPI2_OUTA_DP4}, - {"MIN", 2, R300_FPI0_OUTC_MIN, R300_FPI2_OUTA_MIN}, - {"MAX", 2, R300_FPI0_OUTC_MAX, R300_FPI2_OUTA_MAX}, - {"CMP", 3, R300_FPI0_OUTC_CMP, R300_FPI2_OUTA_CMP}, - {"FRC", 1, R300_FPI0_OUTC_FRC, R300_FPI2_OUTA_FRC}, - {"EX2", 1, R300_FPI0_OUTC_REPL_ALPHA, R300_FPI2_OUTA_EX2}, - {"LG2", 1, R300_FPI0_OUTC_REPL_ALPHA, R300_FPI2_OUTA_LG2}, - {"RCP", 1, R300_FPI0_OUTC_REPL_ALPHA, R300_FPI2_OUTA_RCP}, - {"RSQ", 1, R300_FPI0_OUTC_REPL_ALPHA, R300_FPI2_OUTA_RSQ}, - {"REPL_ALPHA", 1, R300_FPI0_OUTC_REPL_ALPHA, PFS_INVAL}, - {"CMPH", 3, R300_FPI0_OUTC_CMPH, PFS_INVAL}, + {"MAD", 3, R300_ALU_OUTC_MAD, R300_ALU_OUTA_MAD}, + {"DP3", 2, R300_ALU_OUTC_DP3, R300_ALU_OUTA_DP4}, + {"DP4", 2, R300_ALU_OUTC_DP4, R300_ALU_OUTA_DP4}, + {"MIN", 2, R300_ALU_OUTC_MIN, R300_ALU_OUTA_MIN}, + {"MAX", 2, R300_ALU_OUTC_MAX, R300_ALU_OUTA_MAX}, + {"CMP", 3, R300_ALU_OUTC_CMP, R300_ALU_OUTA_CMP}, + {"FRC", 1, R300_ALU_OUTC_FRC, R300_ALU_OUTA_FRC}, + {"EX2", 1, R300_ALU_OUTC_REPL_ALPHA, R300_ALU_OUTA_EX2}, + {"LG2", 1, R300_ALU_OUTC_REPL_ALPHA, R300_ALU_OUTA_LG2}, + {"RCP", 1, R300_ALU_OUTC_REPL_ALPHA, R300_ALU_OUTA_RCP}, + {"RSQ", 1, R300_ALU_OUTC_REPL_ALPHA, R300_ALU_OUTA_RSQ}, + {"REPL_ALPHA", 1, R300_ALU_OUTC_REPL_ALPHA, PFS_INVAL}, + {"CMPH", 3, R300_ALU_OUTC_CMPH, PFS_INVAL}, /* *INDENT-ON* */ }; @@ -209,17 +209,17 @@ static const struct r300_pfs_swizzle { GLuint flags; } v_swiz[] = { /* *INDENT-OFF* */ - {MAKE_SWZ3(X, Y, Z), R300_FPI0_ARGC_SRC0C_XYZ, 4, SLOT_SRC_VECTOR}, - {MAKE_SWZ3(X, X, X), R300_FPI0_ARGC_SRC0C_XXX, 4, SLOT_SRC_VECTOR}, - {MAKE_SWZ3(Y, Y, Y), R300_FPI0_ARGC_SRC0C_YYY, 4, SLOT_SRC_VECTOR}, - {MAKE_SWZ3(Z, Z, Z), R300_FPI0_ARGC_SRC0C_ZZZ, 4, SLOT_SRC_VECTOR}, - {MAKE_SWZ3(W, W, W), R300_FPI0_ARGC_SRC0A, 1, SLOT_SRC_SCALAR}, - {MAKE_SWZ3(Y, Z, X), R300_FPI0_ARGC_SRC0C_YZX, 1, SLOT_SRC_VECTOR}, - {MAKE_SWZ3(Z, X, Y), R300_FPI0_ARGC_SRC0C_ZXY, 1, SLOT_SRC_VECTOR}, - {MAKE_SWZ3(W, Z, Y), R300_FPI0_ARGC_SRC0CA_WZY, 1, SLOT_SRC_BOTH}, - {MAKE_SWZ3(ONE, ONE, ONE), R300_FPI0_ARGC_ONE, 0, 0}, - {MAKE_SWZ3(ZERO, ZERO, ZERO), R300_FPI0_ARGC_ZERO, 0, 0}, - {MAKE_SWZ3(HALF, HALF, HALF), R300_FPI0_ARGC_HALF, 0, 0}, + {MAKE_SWZ3(X, Y, Z), R300_ALU_ARGC_SRC0C_XYZ, 4, SLOT_SRC_VECTOR}, + {MAKE_SWZ3(X, X, X), R300_ALU_ARGC_SRC0C_XXX, 4, SLOT_SRC_VECTOR}, + {MAKE_SWZ3(Y, Y, Y), R300_ALU_ARGC_SRC0C_YYY, 4, SLOT_SRC_VECTOR}, + {MAKE_SWZ3(Z, Z, Z), R300_ALU_ARGC_SRC0C_ZZZ, 4, SLOT_SRC_VECTOR}, + {MAKE_SWZ3(W, W, W), R300_ALU_ARGC_SRC0A, 1, SLOT_SRC_SCALAR}, + {MAKE_SWZ3(Y, Z, X), R300_ALU_ARGC_SRC0C_YZX, 1, SLOT_SRC_VECTOR}, + {MAKE_SWZ3(Z, X, Y), R300_ALU_ARGC_SRC0C_ZXY, 1, SLOT_SRC_VECTOR}, + {MAKE_SWZ3(W, Z, Y), R300_ALU_ARGC_SRC0CA_WZY, 1, SLOT_SRC_BOTH}, + {MAKE_SWZ3(ONE, ONE, ONE), R300_ALU_ARGC_ONE, 0, 0}, + {MAKE_SWZ3(ZERO, ZERO, ZERO), R300_ALU_ARGC_ZERO, 0, 0}, + {MAKE_SWZ3(HALF, HALF, HALF), R300_ALU_ARGC_HALF, 0, 0}, {PFS_INVAL, 0, 0, 0}, /* *INDENT-ON* */ }; @@ -252,13 +252,13 @@ static const struct { GLuint flags; } s_swiz[] = { /* *INDENT-OFF* */ - {R300_FPI2_ARGA_SRC0C_X, 3, SLOT_SRC_VECTOR}, - {R300_FPI2_ARGA_SRC0C_Y, 3, SLOT_SRC_VECTOR}, - {R300_FPI2_ARGA_SRC0C_Z, 3, SLOT_SRC_VECTOR}, - {R300_FPI2_ARGA_SRC0A, 1, SLOT_SRC_SCALAR}, - {R300_FPI2_ARGA_ZERO, 0, 0}, - {R300_FPI2_ARGA_ONE, 0, 0}, - {R300_FPI2_ARGA_HALF, 0, 0} + {R300_ALU_ARGA_SRC0C_X, 3, SLOT_SRC_VECTOR}, + {R300_ALU_ARGA_SRC0C_Y, 3, SLOT_SRC_VECTOR}, + {R300_ALU_ARGA_SRC0C_Z, 3, SLOT_SRC_VECTOR}, + {R300_ALU_ARGA_SRC0A, 1, SLOT_SRC_SCALAR}, + {R300_ALU_ARGA_ZERO, 0, 0}, + {R300_ALU_ARGA_ONE, 0, 0}, + {R300_ALU_ARGA_HALF, 0, 0} /* *INDENT-ON* */ }; @@ -859,11 +859,12 @@ static int t_hw_dst(struct r300_fragment_program *fp, switch (index) { case FRAG_RESULT_COLR: fp->node[fp->cur_node].flags |= - R300_PFS_NODE_OUTPUT_COLOR; + R300_RGBA_OUT; break; case FRAG_RESULT_DEPR: + fp->WritesDepth = GL_TRUE; fp->node[fp->cur_node].flags |= - R300_PFS_NODE_OUTPUT_DEPTH; + R300_W_OUT; break; } return index; @@ -903,49 +904,59 @@ static void emit_tex(struct r300_fragment_program *fp, int hwsrc, hwdest; GLuint tempreg = 0; + /** + * Hardware uses [0..1]x[0..1] range for rectangle textures + * instead of [0..Width]x[0..Height]. + * Add a scaling instruction. + * + * \todo Refactor this once we have proper rewriting/optimization + * support for programs. + */ + if (opcode != R300_TEX_OP_KIL && fpi->TexSrcTarget == TEXTURE_RECT_INDEX) { + gl_state_index tokens[STATE_LENGTH] = { + STATE_INTERNAL, STATE_R300_TEXRECT_FACTOR, 0, 0, + 0 + }; + int factor_index; + GLuint factorreg; + + tokens[2] = unit; + factor_index = + _mesa_add_state_reference(fp->mesa_program.Base. + Parameters, tokens); + factorreg = + emit_const4fv(fp, + fp->mesa_program.Base.Parameters-> + ParameterValues[factor_index]); + tempreg = keep(get_temp_reg(fp)); + + emit_arith(fp, PFS_OP_MAD, tempreg, WRITEMASK_XYZW, + coord, factorreg, pfs_zero, 0); + + coord = tempreg; + } + + /* Texture operations do not support swizzles etc. in hardware, + * so emit an additional arithmetic operation if necessary. + */ + if (REG_GET_VSWZ(coord) != SWIZZLE_XYZ || + REG_GET_SSWZ(coord) != SWIZZLE_W || + coord & (REG_NEGV_MASK | REG_NEGS_MASK | REG_ABS_MASK)) { + assert(tempreg == 0); + tempreg = keep(get_temp_reg(fp)); + emit_arith(fp, PFS_OP_MAD, tempreg, WRITEMASK_XYZW, + coord, pfs_one, pfs_zero, 0); + coord = tempreg; + } + + /* Ensure correct node indirection */ uin = cs->used_in_node; din = cs->dest_in_node; /* Resolve source/dest to hardware registers */ - if (opcode != R300_FPITX_OP_KIL) { - if (fpi->TexSrcTarget == TEXTURE_RECT_INDEX) { - /** - * Hardware uses [0..1]x[0..1] range for rectangle textures - * instead of [0..Width]x[0..Height]. - * Add a scaling instruction. - * - * \todo Refactor this once we have proper rewriting/optimization - * support for programs. - */ - gl_state_index tokens[STATE_LENGTH] = { - STATE_INTERNAL, STATE_R300_TEXRECT_FACTOR, 0, 0, - 0 - }; - int factor_index; - GLuint factorreg; - - tokens[2] = unit; - factor_index = - _mesa_add_state_reference(fp->mesa_program.Base. - Parameters, tokens); - factorreg = - emit_const4fv(fp, - fp->mesa_program.Base.Parameters-> - ParameterValues[factor_index]); - tempreg = keep(get_temp_reg(fp)); - - emit_arith(fp, PFS_OP_MAD, tempreg, WRITEMASK_XYZW, - coord, factorreg, pfs_zero, 0); - - /* Ensure correct node indirection */ - uin = cs->used_in_node; - din = cs->dest_in_node; - - hwsrc = t_hw_src(fp, tempreg, GL_TRUE); - } else { - hwsrc = t_hw_src(fp, coord, GL_TRUE); - } + hwsrc = t_hw_src(fp, coord, GL_TRUE); + if (opcode != R300_TEX_OP_KIL) { dest = t_dst(fp, fpi->DstReg); /* r300 doesn't seem to be able to do TEX->output reg */ @@ -972,7 +983,6 @@ static void emit_tex(struct r300_fragment_program *fp, } else { hwdest = 0; unit = 0; - hwsrc = t_hw_src(fp, coord, GL_TRUE); } /* Indirection if source has been written in this node, or if the @@ -1007,11 +1017,10 @@ static void emit_tex(struct r300_fragment_program *fp, if (fp->cur_node == 0) fp->first_node_has_tex = 1; - fp->tex.inst[fp->tex.length++] = 0 | (hwsrc << R300_FPITX_SRC_SHIFT) - | (hwdest << R300_FPITX_DST_SHIFT) - | (unit << R300_FPITX_IMAGE_SHIFT) - /* not entirely sure about this */ - | (opcode << R300_FPITX_OPCODE_SHIFT); + fp->tex.inst[fp->tex.length++] = 0 | (hwsrc << R300_SRC_ADDR_SHIFT) + | (hwdest << R300_DST_ADDR_SHIFT) + | (unit << R300_TEX_ID_SHIFT) + | (opcode << R300_TEX_INST_SHIFT); cs->dest_in_node |= (1 << hwdest); if (REG_GET_TYPE(coord) != REG_TYPE_CONST) @@ -1228,17 +1237,17 @@ static int find_and_prepare_slot(struct r300_fragment_program *fp, } // Emit the source fetch code - fp->alu.inst[pos].inst1 &= ~R300_FPI1_SRC_MASK; + fp->alu.inst[pos].inst1 &= ~R300_ALU_SRC_MASK; fp->alu.inst[pos].inst1 |= - ((cs->slot[pos].vsrc[0] << R300_FPI1_SRC0C_SHIFT) | - (cs->slot[pos].vsrc[1] << R300_FPI1_SRC1C_SHIFT) | - (cs->slot[pos].vsrc[2] << R300_FPI1_SRC2C_SHIFT)); + ((cs->slot[pos].vsrc[0] << R300_ALU_SRC0C_SHIFT) | + (cs->slot[pos].vsrc[1] << R300_ALU_SRC1C_SHIFT) | + (cs->slot[pos].vsrc[2] << R300_ALU_SRC2C_SHIFT)); - fp->alu.inst[pos].inst3 &= ~R300_FPI3_SRC_MASK; + fp->alu.inst[pos].inst3 &= ~R300_ALU_SRC_MASK; fp->alu.inst[pos].inst3 |= - ((cs->slot[pos].ssrc[0] << R300_FPI3_SRC0A_SHIFT) | - (cs->slot[pos].ssrc[1] << R300_FPI3_SRC1A_SHIFT) | - (cs->slot[pos].ssrc[2] << R300_FPI3_SRC2A_SHIFT)); + ((cs->slot[pos].ssrc[0] << R300_ALU_SRC0A_SHIFT) | + (cs->slot[pos].ssrc[1] << R300_ALU_SRC1A_SHIFT) | + (cs->slot[pos].ssrc[2] << R300_ALU_SRC2A_SHIFT)); // Emit the argument selection code if (emit_vop) { @@ -1257,17 +1266,17 @@ static int find_and_prepare_slot(struct r300_fragment_program *fp, ARG_ABS : 0); } else { - swz[i] = R300_FPI0_ARGC_ZERO; + swz[i] = R300_ALU_ARGC_ZERO; } } fp->alu.inst[pos].inst0 &= - ~(R300_FPI0_ARG0C_MASK | R300_FPI0_ARG1C_MASK | - R300_FPI0_ARG2C_MASK); + ~(R300_ALU_ARG0C_MASK | R300_ALU_ARG1C_MASK | + R300_ALU_ARG2C_MASK); fp->alu.inst[pos].inst0 |= - (swz[0] << R300_FPI0_ARG0C_SHIFT) | (swz[1] << - R300_FPI0_ARG1C_SHIFT) - | (swz[2] << R300_FPI0_ARG2C_SHIFT); + (swz[0] << R300_ALU_ARG0C_SHIFT) | (swz[1] << + R300_ALU_ARG1C_SHIFT) + | (swz[2] << R300_ALU_ARG2C_SHIFT); } if (emit_sop) { @@ -1286,17 +1295,17 @@ static int find_and_prepare_slot(struct r300_fragment_program *fp, ARG_ABS : 0); } else { - swz[i] = R300_FPI2_ARGA_ZERO; + swz[i] = R300_ALU_ARGA_ZERO; } } fp->alu.inst[pos].inst2 &= - ~(R300_FPI2_ARG0A_MASK | R300_FPI2_ARG1A_MASK | - R300_FPI2_ARG2A_MASK); + ~(R300_ALU_ARG0A_MASK | R300_ALU_ARG1A_MASK | + R300_ALU_ARG2A_MASK); fp->alu.inst[pos].inst2 |= - (swz[0] << R300_FPI2_ARG0A_SHIFT) | (swz[1] << - R300_FPI2_ARG1A_SHIFT) - | (swz[2] << R300_FPI2_ARG2A_SHIFT); + (swz[0] << R300_ALU_ARG0A_SHIFT) | (swz[1] << + R300_ALU_ARG1A_SHIFT) + | (swz[2] << R300_ALU_ARG2A_SHIFT); } return pos; @@ -1333,9 +1342,9 @@ static void emit_arith(struct r300_fragment_program *fp, emit_vop = GL_FALSE; emit_sop = GL_FALSE; - if ((mask & WRITEMASK_XYZ) || vop == R300_FPI0_OUTC_DP3) + if ((mask & WRITEMASK_XYZ) || vop == R300_ALU_OUTC_DP3) emit_vop = GL_TRUE; - if ((mask & WRITEMASK_W) || vop == R300_FPI0_OUTC_REPL_ALPHA) + if ((mask & WRITEMASK_W) || vop == R300_ALU_OUTC_REPL_ALPHA) emit_sop = GL_TRUE; pos = @@ -1347,33 +1356,33 @@ static void emit_arith(struct r300_fragment_program *fp, hwdest = t_hw_dst(fp, dest, GL_FALSE, pos); /* Note: Side effects wrt register allocation */ if (flags & PFS_FLAG_SAT) { - vop |= R300_FPI0_OUTC_SAT; - sop |= R300_FPI2_OUTA_SAT; + vop |= R300_ALU_OUTC_CLAMP; + sop |= R300_ALU_OUTA_CLAMP; } - /* Throw the pieces together and get FPI0/1 */ + /* Throw the pieces together and get ALU/1 */ if (emit_vop) { fp->alu.inst[pos].inst0 |= vop; - fp->alu.inst[pos].inst1 |= hwdest << R300_FPI1_DSTC_SHIFT; + fp->alu.inst[pos].inst1 |= hwdest << R300_ALU_DSTC_SHIFT; if (REG_GET_TYPE(dest) == REG_TYPE_OUTPUT) { if (REG_GET_INDEX(dest) == FRAG_RESULT_COLR) { fp->alu.inst[pos].inst1 |= (mask & WRITEMASK_XYZ) << - R300_FPI1_DSTC_OUTPUT_MASK_SHIFT; + R300_ALU_DSTC_OUTPUT_MASK_SHIFT; } else assert(0); } else { fp->alu.inst[pos].inst1 |= (mask & WRITEMASK_XYZ) << - R300_FPI1_DSTC_REG_MASK_SHIFT; + R300_ALU_DSTC_REG_MASK_SHIFT; cs->hwtemps[hwdest].vector_valid = pos + 1; } } - /* And now FPI2/3 */ + /* And now ALU/3 */ if (emit_sop) { fp->alu.inst[pos].inst2 |= sop; @@ -1381,18 +1390,18 @@ static void emit_arith(struct r300_fragment_program *fp, if (REG_GET_TYPE(dest) == REG_TYPE_OUTPUT) { if (REG_GET_INDEX(dest) == FRAG_RESULT_COLR) { fp->alu.inst[pos].inst3 |= - (hwdest << R300_FPI3_DSTA_SHIFT) | - R300_FPI3_DSTA_OUTPUT; + (hwdest << R300_ALU_DSTA_SHIFT) | + R300_ALU_DSTA_OUTPUT; } else if (REG_GET_INDEX(dest) == FRAG_RESULT_DEPR) { fp->alu.inst[pos].inst3 |= - R300_FPI3_DSTA_DEPTH; + R300_ALU_DSTA_DEPTH; } else assert(0); } else { fp->alu.inst[pos].inst3 |= - (hwdest << R300_FPI3_DSTA_SHIFT) | - R300_FPI3_DSTA_REG; + (hwdest << R300_ALU_DSTA_SHIFT) | + R300_ALU_DSTA_REG; cs->hwtemps[hwdest].scalar_valid = pos + 1; } @@ -1708,7 +1717,7 @@ static GLboolean parse_program(struct r300_fragment_program *fp) src[0], undef, undef, flags); break; case OPCODE_KIL: - emit_tex(fp, fpi, R300_FPITX_OP_KIL); + emit_tex(fp, fpi, R300_TEX_OP_KIL); break; case OPCODE_LG2: src[0] = t_scalar_src(fp, fpi->SrcReg[0]); @@ -1943,13 +1952,13 @@ static GLboolean parse_program(struct r300_fragment_program *fp) src[0], pfs_one, negate(src[1]), flags); break; case OPCODE_TEX: - emit_tex(fp, fpi, R300_FPITX_OP_TEX); + emit_tex(fp, fpi, R300_TEX_OP_LD); break; case OPCODE_TXB: - emit_tex(fp, fpi, R300_FPITX_OP_TXB); + emit_tex(fp, fpi, R300_TEX_OP_TXB); break; case OPCODE_TXP: - emit_tex(fp, fpi, R300_FPITX_OP_TXP); + emit_tex(fp, fpi, R300_TEX_OP_TXP); break; case OPCODE_XPD:{ src[0] = t_src(fp, fpi->SrcReg[0]); @@ -2097,6 +2106,7 @@ static void init_program(r300ContextPtr r300, struct r300_fragment_program *fp) fp->translated = GL_FALSE; fp->error = GL_FALSE; fp->cs = cs = &(R300_CONTEXT(fp->ctx)->state.pfs_compile); + fp->WritesDepth = GL_FALSE; fp->tex.length = 0; fp->cur_node = 0; fp->first_node_has_tex = 0; @@ -2217,6 +2227,7 @@ static void update_params(struct r300_fragment_program *fp) void r300TranslateFragmentShader(r300ContextPtr r300, struct r300_fragment_program *fp) { + struct r300_pfs_compile_state *cs = NULL; if (!fp->translated) { @@ -2281,18 +2292,18 @@ static void dump_program(struct r300_fragment_program *fp) const char *instr; switch ((fp->tex. - inst[i] >> R300_FPITX_OPCODE_SHIFT) & + inst[i] >> R300_TEX_INST_SHIFT) & 15) { - case R300_FPITX_OP_TEX: + case R300_TEX_OP_LD: instr = "TEX"; break; - case R300_FPITX_OP_KIL: + case R300_TEX_OP_KIL: instr = "KIL"; break; - case R300_FPITX_OP_TXP: + case R300_TEX_OP_TXP: instr = "TXP"; break; - case R300_FPITX_OP_TXB: + case R300_TEX_OP_TXB: instr = "TXB"; break; default: @@ -2303,15 +2314,13 @@ static void dump_program(struct r300_fragment_program *fp) " %s t%i, %c%i, texture[%i] (%08x)\n", instr, (fp->tex. - inst[i] >> R300_FPITX_DST_SHIFT) & 31, - (fp->tex. - inst[i] & R300_FPITX_SRC_CONST) ? 'c' : + inst[i] >> R300_DST_ADDR_SHIFT) & 31, 't', (fp->tex. - inst[i] >> R300_FPITX_SRC_SHIFT) & 31, + inst[i] >> R300_SRC_ADDR_SHIFT) & 31, (fp->tex. - inst[i] & R300_FPITX_IMAGE_MASK) >> - R300_FPITX_IMAGE_SHIFT, + inst[i] & R300_TEX_ID_MASK) >> + R300_TEX_ID_SHIFT, fp->tex.inst[i]); } } @@ -2337,45 +2346,45 @@ static void dump_program(struct r300_fragment_program *fp) dstc[0] = 0; sprintf(flags, "%s%s%s", (fp->alu.inst[i]. - inst1 & R300_FPI1_DSTC_REG_X) ? "x" : "", + inst1 & R300_ALU_DSTC_REG_X) ? "x" : "", (fp->alu.inst[i]. - inst1 & R300_FPI1_DSTC_REG_Y) ? "y" : "", + inst1 & R300_ALU_DSTC_REG_Y) ? "y" : "", (fp->alu.inst[i]. - inst1 & R300_FPI1_DSTC_REG_Z) ? "z" : ""); + inst1 & R300_ALU_DSTC_REG_Z) ? "z" : ""); if (flags[0] != 0) { sprintf(dstc, "t%i.%s ", (fp->alu.inst[i]. - inst1 >> R300_FPI1_DSTC_SHIFT) & 31, + inst1 >> R300_ALU_DSTC_SHIFT) & 31, flags); } sprintf(flags, "%s%s%s", (fp->alu.inst[i]. - inst1 & R300_FPI1_DSTC_OUTPUT_X) ? "x" : "", + inst1 & R300_ALU_DSTC_OUTPUT_X) ? "x" : "", (fp->alu.inst[i]. - inst1 & R300_FPI1_DSTC_OUTPUT_Y) ? "y" : "", + inst1 & R300_ALU_DSTC_OUTPUT_Y) ? "y" : "", (fp->alu.inst[i]. - inst1 & R300_FPI1_DSTC_OUTPUT_Z) ? "z" : ""); + inst1 & R300_ALU_DSTC_OUTPUT_Z) ? "z" : ""); if (flags[0] != 0) { sprintf(tmp, "o%i.%s", (fp->alu.inst[i]. - inst1 >> R300_FPI1_DSTC_SHIFT) & 31, + inst1 >> R300_ALU_DSTC_SHIFT) & 31, flags); strcat(dstc, tmp); } dsta[0] = 0; - if (fp->alu.inst[i].inst3 & R300_FPI3_DSTA_REG) { + if (fp->alu.inst[i].inst3 & R300_ALU_DSTA_REG) { sprintf(dsta, "t%i.w ", (fp->alu.inst[i]. - inst3 >> R300_FPI3_DSTA_SHIFT) & 31); + inst3 >> R300_ALU_DSTA_SHIFT) & 31); } - if (fp->alu.inst[i].inst3 & R300_FPI3_DSTA_OUTPUT) { + if (fp->alu.inst[i].inst3 & R300_ALU_DSTA_OUTPUT) { sprintf(tmp, "o%i.w ", (fp->alu.inst[i]. - inst3 >> R300_FPI3_DSTA_SHIFT) & 31); + inst3 >> R300_ALU_DSTA_SHIFT) & 31); strcat(dsta, tmp); } - if (fp->alu.inst[i].inst3 & R300_FPI3_DSTA_DEPTH) { + if (fp->alu.inst[i].inst3 & R300_ALU_DSTA_DEPTH) { strcat(dsta, "Z"); } @@ -2395,19 +2404,19 @@ static void dump_program(struct r300_fragment_program *fp) d = regc & 31; if (d < 12) { switch (d % 4) { - case R300_FPI0_ARGC_SRC0C_XYZ: + case R300_ALU_ARGC_SRC0C_XYZ: sprintf(buf, "%s.xyz", srcc[d / 4]); break; - case R300_FPI0_ARGC_SRC0C_XXX: + case R300_ALU_ARGC_SRC0C_XXX: sprintf(buf, "%s.xxx", srcc[d / 4]); break; - case R300_FPI0_ARGC_SRC0C_YYY: + case R300_ALU_ARGC_SRC0C_YYY: sprintf(buf, "%s.yyy", srcc[d / 4]); break; - case R300_FPI0_ARGC_SRC0C_ZZZ: + case R300_ALU_ARGC_SRC0C_ZZZ: sprintf(buf, "%s.zzz", srcc[d / 4]); break; diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.h b/src/mesa/drivers/dri/r300/r300_fragprog.h index 73efe49fc1..573aacf19a 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.h +++ b/src/mesa/drivers/dri/r300/r300_fragprog.h @@ -75,23 +75,23 @@ typedef struct r300_fragment_program_swizzle { #define SRC_STRIDE 6 #define NOP_INST0 ( \ - (R300_FPI0_OUTC_MAD) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG0C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG1C_SHIFT) | \ - (R300_FPI0_ARGC_ZERO << R300_FPI0_ARG2C_SHIFT)) + (R300_ALU_OUTC_MAD) | \ + (R300_ALU_ARGC_ZERO << R300_ALU_ARG0C_SHIFT) | \ + (R300_ALU_ARGC_ZERO << R300_ALU_ARG1C_SHIFT) | \ + (R300_ALU_ARGC_ZERO << R300_ALU_ARG2C_SHIFT)) #define NOP_INST1 ( \ - ((0 | SRC_CONST) << R300_FPI1_SRC0C_SHIFT) | \ - ((0 | SRC_CONST) << R300_FPI1_SRC1C_SHIFT) | \ - ((0 | SRC_CONST) << R300_FPI1_SRC2C_SHIFT)) + ((0 | SRC_CONST) << R300_ALU_SRC0C_SHIFT) | \ + ((0 | SRC_CONST) << R300_ALU_SRC1C_SHIFT) | \ + ((0 | SRC_CONST) << R300_ALU_SRC2C_SHIFT)) #define NOP_INST2 ( \ - (R300_FPI2_OUTA_MAD) | \ - (R300_FPI2_ARGA_ZERO << R300_FPI2_ARG0A_SHIFT) | \ - (R300_FPI2_ARGA_ZERO << R300_FPI2_ARG1A_SHIFT) | \ - (R300_FPI2_ARGA_ZERO << R300_FPI2_ARG2A_SHIFT)) + (R300_ALU_OUTA_MAD) | \ + (R300_ALU_ARGA_ZERO << R300_ALU_ARG0A_SHIFT) | \ + (R300_ALU_ARGA_ZERO << R300_ALU_ARG1A_SHIFT) | \ + (R300_ALU_ARGA_ZERO << R300_ALU_ARG2A_SHIFT)) #define NOP_INST3 ( \ - ((0 | SRC_CONST) << R300_FPI3_SRC0A_SHIFT) | \ - ((0 | SRC_CONST) << R300_FPI3_SRC1A_SHIFT) | \ - ((0 | SRC_CONST) << R300_FPI3_SRC2A_SHIFT)) + ((0 | SRC_CONST) << R300_ALU_SRC0A_SHIFT) | \ + ((0 | SRC_CONST) << R300_ALU_SRC1A_SHIFT) | \ + ((0 | SRC_CONST) << R300_ALU_SRC2A_SHIFT)) #define DRI_CONF_FP_OPTIMIZATION_SPEED 0 #define DRI_CONF_FP_OPTIMIZATION_QUALITY 1 @@ -117,42 +117,42 @@ typedef struct r300_fragment_program_swizzle { #define FP_SELC_MASK_XYZ 7 #define FP_SELC(destidx,regmask,outmask,src0,src1,src2) \ - (((destidx) << R300_FPI1_DSTC_SHIFT) | \ + (((destidx) << R300_ALU_DSTC_SHIFT) | \ (FP_SELC_MASK_##regmask << 23) | \ (FP_SELC_MASK_##outmask << 26) | \ - ((src0) << R300_FPI1_SRC0C_SHIFT) | \ - ((src1) << R300_FPI1_SRC1C_SHIFT) | \ - ((src2) << R300_FPI1_SRC2C_SHIFT)) + ((src0) << R300_ALU_SRC0C_SHIFT) | \ + ((src1) << R300_ALU_SRC1C_SHIFT) | \ + ((src2) << R300_ALU_SRC2C_SHIFT)) #define FP_SELA_MASK_NO 0 #define FP_SELA_MASK_W 1 #define FP_SELA(destidx,regmask,outmask,src0,src1,src2) \ - (((destidx) << R300_FPI3_DSTA_SHIFT) | \ + (((destidx) << R300_ALU_DSTA_SHIFT) | \ (FP_SELA_MASK_##regmask << 23) | \ (FP_SELA_MASK_##outmask << 24) | \ - ((src0) << R300_FPI3_SRC0A_SHIFT) | \ - ((src1) << R300_FPI3_SRC1A_SHIFT) | \ - ((src2) << R300_FPI3_SRC2A_SHIFT)) + ((src0) << R300_ALU_SRC0A_SHIFT) | \ + ((src1) << R300_ALU_SRC1A_SHIFT) | \ + ((src2) << R300_ALU_SRC2A_SHIFT)) /* Produce unshifted argument selectors */ -#define FP_ARGC(source) R300_FPI0_ARGC_##source -#define FP_ARGA(source) R300_FPI2_ARGA_##source +#define FP_ARGC(source) R300_ALU_ARGC_##source +#define FP_ARGA(source) R300_ALU_ARGA_##source #define FP_ABS(arg) ((arg) | (1 << 6)) #define FP_NEG(arg) ((arg) ^ (1 << 5)) /* Produce instruction dword */ #define FP_INSTRC(opcode,arg0,arg1,arg2) \ - (R300_FPI0_OUTC_##opcode | \ - ((arg0) << R300_FPI0_ARG0C_SHIFT) | \ - ((arg1) << R300_FPI0_ARG1C_SHIFT) | \ - ((arg2) << R300_FPI0_ARG2C_SHIFT)) + (R300_ALU_OUTC_##opcode | \ + ((arg0) << R300_ALU_ARG0C_SHIFT) | \ + ((arg1) << R300_ALU_ARG1C_SHIFT) | \ + ((arg2) << R300_ALU_ARG2C_SHIFT)) #define FP_INSTRA(opcode,arg0,arg1,arg2) \ - (R300_FPI2_OUTA_##opcode | \ - ((arg0) << R300_FPI2_ARG0A_SHIFT) | \ - ((arg1) << R300_FPI2_ARG1A_SHIFT) | \ - ((arg2) << R300_FPI2_ARG2A_SHIFT)) + (R300_ALU_OUTA_##opcode | \ + ((arg0) << R300_ALU_ARG0A_SHIFT) | \ + ((arg1) << R300_ALU_ARG1A_SHIFT) | \ + ((arg2) << R300_ALU_ARG2A_SHIFT)) #endif diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c index 1b405889c3..b0225453d3 100644 --- a/src/mesa/drivers/dri/r300/r300_ioctl.c +++ b/src/mesa/drivers/dri/r300/r300_ioctl.c @@ -118,7 +118,7 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) } R300_STATECHANGE(r300, zs); - reg_start(R300_RB3D_ZSTENCIL_CNTL_0, 2); + reg_start(R300_ZB_CNTL, 2); { uint32_t t1, t2; @@ -127,32 +127,32 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags, int buffer) t2 = 0x0; if (flags & CLEARBUFFER_DEPTH) { - t1 |= R300_RB3D_Z_WRITE_ONLY; + t1 |= R300_Z_ENABLE | R300_Z_WRITE_ENABLE; t2 |= - (R300_ZS_ALWAYS << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT); - } else { - t1 |= R300_RB3D_Z_DISABLED_1; // disable + (R300_ZS_ALWAYS << R300_Z_FUNC_SHIFT); + } else { //XXX + t1 |= R300_STENCIL_FRONT_BACK; // disable } if (flags & CLEARBUFFER_STENCIL) { - t1 |= R300_RB3D_STENCIL_ENABLE; + t1 |= R300_STENCIL_ENABLE; t2 |= (R300_ZS_ALWAYS << - R300_RB3D_ZS1_FRONT_FUNC_SHIFT) | + R300_S_FRONT_FUNC_SHIFT) | (R300_ZS_REPLACE << - R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT) | + R300_S_FRONT_SFAIL_OP_SHIFT) | (R300_ZS_REPLACE << - R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT) | + R300_S_FRONT_ZPASS_OP_SHIFT) | (R300_ZS_REPLACE << - R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT) | + R300_S_FRONT_ZFAIL_OP_SHIFT) | (R300_ZS_ALWAYS << - R300_RB3D_ZS1_BACK_FUNC_SHIFT) | + R300_S_BACK_FUNC_SHIFT) | (R300_ZS_REPLACE << - R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) | + R300_S_BACK_SFAIL_OP_SHIFT) | (R300_ZS_REPLACE << - R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT) | + R300_S_BACK_ZPASS_OP_SHIFT) | (R300_ZS_REPLACE << - R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT); + R300_S_BACK_ZFAIL_OP_SHIFT); } e32(t1); @@ -186,10 +186,16 @@ static void r300EmitClearState(GLcontext * ctx) int cmd_written = 0; drm_radeon_cmd_header_t *cmd = NULL; int has_tcl = 1; + int is_r500 = 0; + GLuint vap_cntl; if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) has_tcl = 0; + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) + is_r500 = 1; + + /* FIXME: the values written to R300_VAP_INPUT_ROUTE_0_0 and * R300_VAP_INPUT_ROUTE_0_1 are in fact known, however, the values are * quite complex; see the functions in r300_emit.c. @@ -199,25 +205,38 @@ static void r300EmitClearState(GLcontext * ctx) * these registers, as well as the actual values used for rendering. */ R300_STATECHANGE(r300, vir[0]); - reg_start(R300_VAP_INPUT_ROUTE_0_0, 0); + reg_start(R300_VAP_PROG_STREAM_CNTL_0, 0); if (!has_tcl) - e32(0x22030003); + e32(((((0 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (2 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT))); else - e32(0x21030003); + e32(((((0 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_0_SHIFT) | + ((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) | R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT))); /* disable fog */ R300_STATECHANGE(r300, fogs); - reg_start(FG_FOG_BLEND, 0); + reg_start(R300_FG_FOG_BLEND, 0); e32(0x0); R300_STATECHANGE(r300, vir[1]); - reg_start(R300_VAP_INPUT_ROUTE_1_0, 0); - e32(0xF688F688); + reg_start(R300_VAP_PROG_STREAM_CNTL_EXT_0, 0); + e32(((((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) | + (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) | + (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_SHIFT) | + (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_SHIFT) | + ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W) << R300_WRITE_ENA_SHIFT)) + << R300_SWIZZLE0_SHIFT) | + (((R300_SWIZZLE_SELECT_X << R300_SWIZZLE_SELECT_X_SHIFT) | + (R300_SWIZZLE_SELECT_Y << R300_SWIZZLE_SELECT_Y_SHIFT) | + (R300_SWIZZLE_SELECT_Z << R300_SWIZZLE_SELECT_Z_SHIFT) | + (R300_SWIZZLE_SELECT_W << R300_SWIZZLE_SELECT_W_SHIFT) | + ((R300_WRITE_ENA_X | R300_WRITE_ENA_Y | R300_WRITE_ENA_Z | R300_WRITE_ENA_W) << R300_WRITE_ENA_SHIFT)) + << R300_SWIZZLE1_SHIFT))); /* R300_VAP_INPUT_CNTL_0, R300_VAP_INPUT_CNTL_1 */ R300_STATECHANGE(r300, vic); - reg_start(R300_VAP_INPUT_CNTL_0, 1); - e32(R300_INPUT_CNTL_0_COLOR); + reg_start(R300_VAP_VTX_STATE_CNTL, 1); + e32((R300_SEL_USER_COLOR_0 << R300_COLOR_0_ASSEMBLY_SHIFT)); e32(R300_INPUT_CNTL_POS | R300_INPUT_CNTL_COLOR | R300_INPUT_CNTL_TC0); R300_STATECHANGE(r300, vte); @@ -229,7 +248,7 @@ static void r300EmitClearState(GLcontext * ctx) R300_VPORT_Z_OFFSET_ENA); e32(0x8); - reg_start(R300_VAP_PSC_SGN_NORM_CNTL, SGN_NORM_ZERO); + reg_start(R300_VAP_PSC_SGN_NORM_CNTL, 0); e32(0xaaaaaaaa); R300_STATECHANGE(r300, vof); @@ -252,7 +271,7 @@ static void r300EmitClearState(GLcontext * ctx) efloat(0.0); R300_STATECHANGE(r300, at); - reg_start(FG_ALPHA_FUNC, 0); + reg_start(R300_FG_ALPHA_FUNC, 0); e32(0x0); R300_STATECHANGE(r300, bld); @@ -263,7 +282,7 @@ static void r300EmitClearState(GLcontext * ctx) if (has_tcl) { R300_STATECHANGE(r300, vap_clip_cntl); reg_start(R300_VAP_CLIP_CNTL, 0); - e32(R300_221C_CLEAR); + e32(R300_PS_UCP_MODE_CLIP_AS_TRIFAN | R300_CLIP_DISABLE); } R300_STATECHANGE(r300, ps); @@ -271,59 +290,169 @@ static void r300EmitClearState(GLcontext * ctx) e32(((dPriv->w * 6) << R300_POINTSIZE_X_SHIFT) | ((dPriv->h * 6) << R300_POINTSIZE_Y_SHIFT)); - R300_STATECHANGE(r300, ri); - reg_start(R300_RS_IP_0, 8); - for (i = 0; i < 8; ++i) { - e32(R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3)); + if (!is_r500) { + R300_STATECHANGE(r300, ri); + reg_start(R300_RS_IP_0, 7); + for (i = 0; i < 8; ++i) { + e32(R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3)); + } + + R300_STATECHANGE(r300, rc); + /* The second constant is needed to get glxgears display anything .. */ + reg_start(R300_RS_COUNT, 1); + e32((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN); + e32(0x0); + + R300_STATECHANGE(r300, rr); + reg_start(R300_RS_INST_0, 0); + e32(R300_RS_INST_COL_CN_WRITE); + } else { + + R300_STATECHANGE(r300, ri); + reg_start(R500_RS_IP_0, 7); + for (i = 0; i < 8; ++i) { + e32((R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) | + (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) | + (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) | + (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)); + } + + R300_STATECHANGE(r300, rc); + /* The second constant is needed to get glxgears display anything .. */ + reg_start(R300_RS_COUNT, 1); + e32((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN); + e32(0x0); + + R300_STATECHANGE(r300, rr); + reg_start(R500_RS_INST_0, 0); + e32(R500_RS_INST_COL_CN_WRITE); + } - R300_STATECHANGE(r300, rc); - /* The second constant is needed to get glxgears display anything .. */ - reg_start(R300_RS_COUNT, 1); - e32((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN); - e32(0x0); + if (!is_r500) { + R300_STATECHANGE(r300, fp); + reg_start(R300_US_CONFIG, 2); + e32(0x0); + e32(0x0); + e32(0x0); + reg_start(R300_US_CODE_ADDR_0, 3); + e32(0x0); + e32(0x0); + e32(0x0); + e32(R300_RGBA_OUT); - R300_STATECHANGE(r300, rr); - reg_start(R300_RS_INST_0, 0); - e32(R300_RS_INST_COL_CN_WRITE); + R300_STATECHANGE(r300, fpi[0]); + R300_STATECHANGE(r300, fpi[1]); + R300_STATECHANGE(r300, fpi[2]); + R300_STATECHANGE(r300, fpi[3]); - R300_STATECHANGE(r300, fp); - reg_start(R300_PFS_CNTL_0, 2); - e32(0x0); - e32(0x0); - e32(0x0); - reg_start(R300_PFS_NODE_0, 3); - e32(0x0); - e32(0x0); - e32(0x0); - e32(R300_PFS_NODE_OUTPUT_COLOR); + reg_start(R300_US_ALU_RGB_INST_0, 0); + e32(FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO))); - R300_STATECHANGE(r300, fpi[0]); - R300_STATECHANGE(r300, fpi[1]); - R300_STATECHANGE(r300, fpi[2]); - R300_STATECHANGE(r300, fpi[3]); + reg_start(R300_US_ALU_RGB_ADDR_0, 0); + e32(FP_SELC(0, NO, XYZ, FP_TMP(0), 0, 0)); - reg_start(R300_PFS_INSTR0_0, 0); - e32(FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO))); + reg_start(R300_US_ALU_ALPHA_INST_0, 0); + e32(FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO))); - reg_start(R300_PFS_INSTR1_0, 0); - e32(FP_SELC(0, NO, XYZ, FP_TMP(0), 0, 0)); + reg_start(R300_US_ALU_ALPHA_ADDR_0, 0); + e32(FP_SELA(0, NO, W, FP_TMP(0), 0, 0)); + } else { + R300_STATECHANGE(r300, fp); + reg_start(R500_US_CONFIG, 1); + e32(R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); + e32(0x0); + reg_start(R500_US_CODE_ADDR, 2); + e32(R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(1)); + e32(R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(1)); + e32(R500_US_CODE_OFFSET_ADDR(0)); + + R300_STATECHANGE(r300, r500fp); + r500fp_start_fragment(0, 6); + + e32(R500_INST_TYPE_OUT | + R500_INST_TEX_SEM_WAIT | + R500_INST_LAST | + R500_INST_RGB_OMASK_R | + R500_INST_RGB_OMASK_G | + R500_INST_RGB_OMASK_B | + R500_INST_ALPHA_OMASK | + R500_INST_RGB_CLAMP | + R500_INST_ALPHA_CLAMP); + + e32(R500_RGB_ADDR0(0) | + R500_RGB_ADDR1(0) | + R500_RGB_ADDR1_CONST | + R500_RGB_ADDR2(0) | + R500_RGB_ADDR2_CONST); + + e32(R500_ALPHA_ADDR0(0) | + R500_ALPHA_ADDR1(0) | + R500_ALPHA_ADDR1_CONST | + R500_ALPHA_ADDR2(0) | + R500_ALPHA_ADDR2_CONST); + + e32(R500_ALU_RGB_SEL_A_SRC0 | + R500_ALU_RGB_R_SWIZ_A_R | + R500_ALU_RGB_G_SWIZ_A_G | + R500_ALU_RGB_B_SWIZ_A_B | + R500_ALU_RGB_SEL_B_SRC0 | + R500_ALU_RGB_R_SWIZ_B_R | + R500_ALU_RGB_B_SWIZ_B_G | + R500_ALU_RGB_G_SWIZ_B_B); + + e32(R500_ALPHA_OP_CMP | + R500_ALPHA_SWIZ_A_A | + R500_ALPHA_SWIZ_B_A); + + e32(R500_ALU_RGBA_OP_CMP | + R500_ALU_RGBA_R_SWIZ_0 | + R500_ALU_RGBA_G_SWIZ_0 | + R500_ALU_RGBA_B_SWIZ_0 | + R500_ALU_RGBA_A_SWIZ_0); + } - reg_start(R300_PFS_INSTR2_0, 0); - e32(FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO))); + reg_start(R300_VAP_PVS_STATE_FLUSH_REG, 0); + e32(0x00000000); + if (has_tcl) { + vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) | + (5 << R300_PVS_NUM_CNTLRS_SHIFT) | + (12 << R300_VF_MAX_VTX_NUM_SHIFT)); + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) + vap_cntl |= R500_TCL_STATE_OPTIMIZATION; + } else + vap_cntl = ((10 << R300_PVS_NUM_SLOTS_SHIFT) | + (5 << R300_PVS_NUM_CNTLRS_SHIFT) | + (5 << R300_VF_MAX_VTX_NUM_SHIFT)); + + if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV515) + vap_cntl |= (2 << R300_PVS_NUM_FPUS_SHIFT); + else if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) || + (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV560)) + vap_cntl |= (5 << R300_PVS_NUM_FPUS_SHIFT); + else if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R420) + vap_cntl |= (6 << R300_PVS_NUM_FPUS_SHIFT); + else if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R520) || + (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R580) || + (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV570)) + vap_cntl |= (8 << R300_PVS_NUM_FPUS_SHIFT); + else + vap_cntl |= (4 << R300_PVS_NUM_FPUS_SHIFT); - reg_start(R300_PFS_INSTR3_0, 0); - e32(FP_SELA(0, NO, W, FP_TMP(0), 0, 0)); + R300_STATECHANGE(rmesa, vap_cntl); + reg_start(R300_VAP_CNTL, 0); + e32(vap_cntl); if (has_tcl) { R300_STATECHANGE(r300, pvs); - reg_start(R300_VAP_PVS_CNTL_1, 2); - - e32((0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) | - (0 << R300_PVS_CNTL_1_POS_END_SHIFT) | - (1 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT)); - e32(0x0); - e32(1 << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT); + reg_start(R300_VAP_PVS_CODE_CNTL_0, 2); + + e32((0 << R300_PVS_FIRST_INST_SHIFT) | + (0 << R300_PVS_XYZW_VALID_INST_SHIFT) | + (1 << R300_PVS_LAST_INST_SHIFT)); + e32((0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) | + (0 << R300_PVS_MAX_CONST_ADDR_SHIFT)); + e32(1 << R300_PVS_LAST_VTX_SRC_INST_SHIFT); R300_STATECHANGE(r300, vpi); vsf_start_fragment(0x0, 8); diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index 2200cec6ab..21e1dc29de 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -67,9 +67,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Vertex Array Processing (VAP) Control - * Stolen from r200 code from Christoph Brill (It's a guess!) */ #define R300_VAP_CNTL 0x2080 +# define R300_PVS_NUM_SLOTS_SHIFT 0 +# define R300_PVS_NUM_CNTLRS_SHIFT 4 +# define R300_PVS_NUM_FPUS_SHIFT 8 +# define R300_VF_MAX_VTX_NUM_SHIFT 18 +# define R300_GL_CLIP_SPACE_DEF (0 << 22) +# define R300_DX_CLIP_SPACE_DEF (1 << 22) +# define R500_TCL_STATE_OPTIMIZATION (1 << 23) /* This register is written directly and also starts data section * in many 3d CP_PACKET3's @@ -106,6 +112,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* number of vertices */ # define R300_VAP_VF_CNTL__NUM_VERTICES__SHIFT 16 +#define R500_VAP_INDEX_OFFSET 0x208c + #define R300_VAP_OUTPUT_VTX_FMT_0 0x2090 # define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT (1<<0) # define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT (1<<1) @@ -125,24 +133,23 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_VAP_OUTPUT_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15 # define R300_VAP_OUTPUT_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18 # define R300_VAP_OUTPUT_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21 -# define R300_VAP_OUTPUT_VTX_FMT_1__NOT_PRESENT (1<<0) -# define R300_VAP_OUTPUT_VTX_FMT_1__1_COMPONENT (1<<1) -# define R300_VAP_OUTPUT_VTX_FMT_1__2_COMPONENTS (1<<2) -# define R300_VAP_OUTPUT_VTX_FMT_1__3_COMPONENTS (1<<3) -# define R300_VAP_OUTPUT_VTX_FMT_1__4_COMPONENTS (1<<4) +# define R300_VAP_OUTPUT_VTX_FMT_1__NOT_PRESENT 0 +# define R300_VAP_OUTPUT_VTX_FMT_1__1_COMPONENT 1 +# define R300_VAP_OUTPUT_VTX_FMT_1__2_COMPONENTS 2 +# define R300_VAP_OUTPUT_VTX_FMT_1__3_COMPONENTS 3 +# define R300_VAP_OUTPUT_VTX_FMT_1__4_COMPONENTS 4 #define R300_SE_VTE_CNTL 0x20b0 -# define R300_VPORT_X_SCALE_ENA 0x00000001 -# define R300_VPORT_X_OFFSET_ENA 0x00000002 -# define R300_VPORT_Y_SCALE_ENA 0x00000004 -# define R300_VPORT_Y_OFFSET_ENA 0x00000008 -# define R300_VPORT_Z_SCALE_ENA 0x00000010 -# define R300_VPORT_Z_OFFSET_ENA 0x00000020 -# define R300_VTX_XY_FMT 0x00000100 -# define R300_VTX_Z_FMT 0x00000200 -# define R300_VTX_W0_FMT 0x00000400 -# define R300_VTX_W0_NORMALIZE 0x00000800 -# define R300_VTX_ST_DENORMALIZED 0x00001000 +# define R300_VPORT_X_SCALE_ENA (1 << 0) +# define R300_VPORT_X_OFFSET_ENA (1 << 1) +# define R300_VPORT_Y_SCALE_ENA (1 << 2) +# define R300_VPORT_Y_OFFSET_ENA (1 << 3) +# define R300_VPORT_Z_SCALE_ENA (1 << 4) +# define R300_VPORT_Z_OFFSET_ENA (1 << 5) +# define R300_VTX_XY_FMT (1 << 8) +# define R300_VTX_Z_FMT (1 << 9) +# define R300_VTX_W0_FMT (1 << 10) +# define R300_SERIAL_PROC_ENA (1 << 11) /* BEGIN: Vertex data assembly - lots of uncertainties */ @@ -211,27 +218,31 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Always set COMPONENTS_4 in immediate mode. */ -#define R300_VAP_INPUT_ROUTE_0_0 0x2150 -# define R300_INPUT_ROUTE_COMPONENTS_1 (0 << 0) -# define R300_INPUT_ROUTE_COMPONENTS_2 (1 << 0) -# define R300_INPUT_ROUTE_COMPONENTS_3 (2 << 0) -# define R300_INPUT_ROUTE_COMPONENTS_4 (3 << 0) -# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) /* GUESS */ -# define R300_VAP_INPUT_ROUTE_IDX_SHIFT 8 -# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) /* GUESS */ -# define R300_VAP_INPUT_ROUTE_END (1 << 13) -# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) /* GUESS */ -# define R300_INPUT_ROUTE_FLOAT (1 << 14) /* GUESS */ -# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) /* GUESS */ -# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) /* GUESS */ -#define R300_VAP_INPUT_ROUTE_0_1 0x2154 -#define R300_VAP_INPUT_ROUTE_0_2 0x2158 -#define R300_VAP_INPUT_ROUTE_0_3 0x215C -#define R300_VAP_INPUT_ROUTE_0_4 0x2160 -#define R300_VAP_INPUT_ROUTE_0_5 0x2164 -#define R300_VAP_INPUT_ROUTE_0_6 0x2168 -#define R300_VAP_INPUT_ROUTE_0_7 0x216C - +#define R300_VAP_PROG_STREAM_CNTL_0 0x2150 +# define R300_DATA_TYPE_0_SHIFT 0 +# define R300_DATA_TYPE_FLOAT_1 0 +# define R300_DATA_TYPE_FLOAT_2 1 +# define R300_DATA_TYPE_FLOAT_3 2 +# define R300_DATA_TYPE_FLOAT_4 3 +# define R300_DATA_TYPE_BYTE 4 +# define R300_DATA_TYPE_D3DCOLOR 5 +# define R300_DATA_TYPE_SHORT_2 6 +# define R300_DATA_TYPE_SHORT_4 7 +# define R300_DATA_TYPE_VECTOR_3_TTT 8 +# define R300_DATA_TYPE_VECTOR_3_EET 9 +# define R300_SKIP_DWORDS_SHIFT 4 +# define R300_DST_VEC_LOC_SHIFT 8 +# define R300_LAST_VEC (1 << 13) +# define R300_SIGNED (1 << 14) +# define R300_NORMALIZE (1 << 15) +# define R300_DATA_TYPE_1_SHIFT 16 +#define R300_VAP_PROG_STREAM_CNTL_1 0x2154 +#define R300_VAP_PROG_STREAM_CNTL_2 0x2158 +#define R300_VAP_PROG_STREAM_CNTL_3 0x215C +#define R300_VAP_PROG_STREAM_CNTL_4 0x2160 +#define R300_VAP_PROG_STREAM_CNTL_5 0x2164 +#define R300_VAP_PROG_STREAM_CNTL_6 0x2168 +#define R300_VAP_PROG_STREAM_CNTL_7 0x216C /* gap */ /* Notes: @@ -239,9 +250,26 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * if vertex program uses only position, fglrx will set normal, too * - INPUT_CNTL_0_COLOR and INPUT_CNTL_COLOR bits are always equal. */ -#define R300_VAP_INPUT_CNTL_0 0x2180 -# define R300_INPUT_CNTL_0_COLOR 0x00000001 -#define R300_VAP_INPUT_CNTL_1 0x2184 +#define R300_VAP_VTX_STATE_CNTL 0x2180 +# define R300_COLOR_0_ASSEMBLY_SHIFT 0 +# define R300_SEL_COLOR 0 +# define R300_SEL_USER_COLOR_0 1 +# define R300_SEL_USER_COLOR_1 2 +# define R300_COLOR_1_ASSEMBLY_SHIFT 2 +# define R300_COLOR_2_ASSEMBLY_SHIFT 4 +# define R300_COLOR_3_ASSEMBLY_SHIFT 6 +# define R300_COLOR_4_ASSEMBLY_SHIFT 8 +# define R300_COLOR_5_ASSEMBLY_SHIFT 10 +# define R300_COLOR_6_ASSEMBLY_SHIFT 12 +# define R300_COLOR_7_ASSEMBLY_SHIFT 14 +# define R300_UPDATE_USER_COLOR_0_ENA (1 << 16) + +/* + * Each bit in this field applies to the corresponding vector in the VSM + * memory (i.e. Bit 0 applies to VECTOR_0 (POSITION), etc.). If the bit + * is set, then the corresponding 4-Dword Vector is output into the Vertex Stream. + */ +#define R300_VAP_VSM_VTX_ASSM 0x2184 # define R300_INPUT_CNTL_POS 0x00000001 # define R300_INPUT_CNTL_NORMAL 0x00000002 # define R300_INPUT_CNTL_COLOR 0x00000004 @@ -269,26 +297,40 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * mode, the swizzling pattern is e.g. used to set zw components in texture * coordinates with only tweo components. */ -#define R300_VAP_INPUT_ROUTE_1_0 0x21E0 +#define R300_VAP_PROG_STREAM_CNTL_EXT_0 0x21e0 +# define R300_SWIZZLE0_SHIFT 0 +# define R300_SWIZZLE_SELECT_X_SHIFT 0 +# define R300_SWIZZLE_SELECT_Y_SHIFT 3 +# define R300_SWIZZLE_SELECT_Z_SHIFT 6 +# define R300_SWIZZLE_SELECT_W_SHIFT 9 + +# define R300_SWIZZLE_SELECT_X 0 +# define R300_SWIZZLE_SELECT_Y 1 +# define R300_SWIZZLE_SELECT_Z 2 +# define R300_SWIZZLE_SELECT_W 3 +# define R300_SWIZZLE_SELECT_FP_ZERO 4 +# define R300_SWIZZLE_SELECT_FP_ONE 5 +/* alternate forms for r300_emit.c */ # define R300_INPUT_ROUTE_SELECT_X 0 # define R300_INPUT_ROUTE_SELECT_Y 1 # define R300_INPUT_ROUTE_SELECT_Z 2 # define R300_INPUT_ROUTE_SELECT_W 3 # define R300_INPUT_ROUTE_SELECT_ZERO 4 # define R300_INPUT_ROUTE_SELECT_ONE 5 -# define R300_INPUT_ROUTE_SELECT_MASK 7 -# define R300_INPUT_ROUTE_X_SHIFT 0 -# define R300_INPUT_ROUTE_Y_SHIFT 3 -# define R300_INPUT_ROUTE_Z_SHIFT 6 -# define R300_INPUT_ROUTE_W_SHIFT 9 -# define R300_INPUT_ROUTE_ENABLE (15 << 12) -#define R300_VAP_INPUT_ROUTE_1_1 0x21E4 -#define R300_VAP_INPUT_ROUTE_1_2 0x21E8 -#define R300_VAP_INPUT_ROUTE_1_3 0x21EC -#define R300_VAP_INPUT_ROUTE_1_4 0x21F0 -#define R300_VAP_INPUT_ROUTE_1_5 0x21F4 -#define R300_VAP_INPUT_ROUTE_1_6 0x21F8 -#define R300_VAP_INPUT_ROUTE_1_7 0x21FC + +# define R300_WRITE_ENA_SHIFT 12 +# define R300_WRITE_ENA_X 1 +# define R300_WRITE_ENA_Y 2 +# define R300_WRITE_ENA_Z 4 +# define R300_WRITE_ENA_W 8 +# define R300_SWIZZLE1_SHIFT 16 +#define R300_VAP_PROG_STREAM_CNTL_EXT_1 0x21e4 +#define R300_VAP_PROG_STREAM_CNTL_EXT_2 0x21e8 +#define R300_VAP_PROG_STREAM_CNTL_EXT_3 0x21ec +#define R300_VAP_PROG_STREAM_CNTL_EXT_4 0x21f0 +#define R300_VAP_PROG_STREAM_CNTL_EXT_5 0x21f4 +#define R300_VAP_PROG_STREAM_CNTL_EXT_6 0x21f8 +#define R300_VAP_PROG_STREAM_CNTL_EXT_7 0x21fc /* END: Vertex data assembly */ @@ -320,25 +362,20 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Multiple vertex programs and parameter sets can be loaded at once, * which could explain the size discrepancy. */ -#define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200 -# define R300_PVS_UPLOAD_PROGRAM 0x00000000 -/* gap */ -# define R300_PVS_UPLOAD_PARAMETERS 0x00000200 -/* gap */ -# define R300_PVS_UPLOAD_CLIP_PLANE0 0x00000400 -# define R300_PVS_UPLOAD_CLIP_PLANE1 0x00000401 -# define R300_PVS_UPLOAD_CLIP_PLANE2 0x00000402 -# define R300_PVS_UPLOAD_CLIP_PLANE3 0x00000403 -# define R300_PVS_UPLOAD_CLIP_PLANE4 0x00000404 -# define R300_PVS_UPLOAD_CLIP_PLANE5 0x00000405 -# define R300_PVS_UPLOAD_POINTSIZE 0x00000406 - -# define R500_PVS_UPLOAD_CLIP_PLANE0 0x00000600 -# define R500_PVS_UPLOAD_CLIP_PLANE1 0x00000601 -# define R500_PVS_UPLOAD_CLIP_PLANE2 0x00000602 -# define R500_PVS_UPLOAD_CLIP_PLANE3 0x00000603 -# define R500_PVS_UPLOAD_CLIP_PLANE4 0x00000604 -# define R500_PVS_UPLOAD_CLIP_PLANE5 0x00000605 +#define R300_VAP_PVS_VECTOR_INDX_REG 0x2200 +# define R300_PVS_CODE_START 0 +# define R300_MAX_PVS_CODE_LINES 256 +# define R500_MAX_PVS_CODE_LINES 1024 +# define R300_PVS_CONST_START 512 +# define R500_PVS_CONST_START 1024 +# define R300_MAX_PVS_CONST_VECS 256 +# define R500_MAX_PVS_CONST_VECS 1024 +# define R300_PVS_UCP_START 1024 +# define R500_PVS_UCP_START 1536 +# define R300_POINT_VPORT_SCALE_OFFSET 1030 +# define R500_POINT_VPORT_SCALE_OFFSET 1542 +# define R300_POINT_GEN_TEX_OFFSET 1031 +# define R500_POINT_GEN_TEX_OFFSET 1543 /* * These are obsolete defines form r300_context.h, but they might give some @@ -373,9 +410,21 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * See bug #9871. http://bugs.freedesktop.org/attachment.cgi?id=10672&action=view */ #define R300_VAP_CLIP_CNTL 0x221C -# define R300_221C_NORMAL 0x00000000 -# define R300_221C_CLEAR 0x0001C000 -#define R300_VAP_UCP_ENABLE_0 (1 << 0) +# define R300_VAP_UCP_ENABLE_0 (1 << 0) +# define R300_VAP_UCP_ENABLE_1 (1 << 1) +# define R300_VAP_UCP_ENABLE_2 (1 << 2) +# define R300_VAP_UCP_ENABLE_3 (1 << 3) +# define R300_VAP_UCP_ENABLE_4 (1 << 4) +# define R300_VAP_UCP_ENABLE_5 (1 << 5) +# define R300_PS_UCP_MODE_DIST_COP (0 << 14) +# define R300_PS_UCP_MODE_RADIUS_COP (1 << 14) +# define R300_PS_UCP_MODE_RADIUS_COP_CLIP (2 << 14) +# define R300_PS_UCP_MODE_CLIP_AS_TRIFAN (3 << 14) +# define R300_CLIP_DISABLE (1 << 16) +# define R300_UCP_CULL_ONLY_ENABLE (1 << 17) +# define R300_BOUNDARY_EDGE_FLAG_ENABLE (1 << 18) +# define R500_COLOR2_IS_TEXTURE (1 << 20) +# define R500_COLOR3_IS_TEXTURE (1 << 21) /* These seem to be per-pixel and per-vertex X and Y clipping planes. The first * plane is per-pixel and the second plane is per-vertex. @@ -384,10 +433,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * * These registers are called X_QUAD0_1_FL to X_QUAD0_4_FL by glxtest. */ -#define R300_VAP_CLIP_X_0 0x2220 -#define R300_VAP_CLIP_X_1 0x2224 -#define R300_VAP_CLIP_Y_0 0x2228 -#define R300_VAP_CLIP_Y_1 0x222c +#define R300_VAP_GB_VERT_CLIP_ADJ 0x2220 +#define R300_VAP_GB_VERT_DISC_ADJ 0x2224 +#define R300_VAP_GB_HORZ_CLIP_ADJ 0x2228 +#define R300_VAP_GB_HORZ_DISC_ADJ 0x222c /* gap */ @@ -396,7 +445,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Therefore, I suspect writing zero to 0x2284 synchronizes the engine and * avoids bugs caused by still running shaders reading bad data from memory. */ -#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */ +#define R300_VAP_PVS_STATE_FLUSH_REG 0x2284 /* This register is used to define the number of core clocks to wait for a * vertex to be received by the VAP input controller (while the primitive @@ -426,17 +475,17 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * is sometimes accepted other instruction that have no relationship with * position calculations. */ -#define R300_VAP_PVS_CNTL_1 0x22D0 -# define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0 -# define R300_PVS_CNTL_1_POS_END_SHIFT 10 -# define R300_PVS_CNTL_1_PROGRAM_END_SHIFT 20 +#define R300_VAP_PVS_CODE_CNTL_0 0x22D0 +# define R300_PVS_FIRST_INST_SHIFT 0 +# define R300_PVS_XYZW_VALID_INST_SHIFT 10 +# define R300_PVS_LAST_INST_SHIFT 20 /* Addresses are relative the the vertex program parameters area. */ -#define R300_VAP_PVS_CNTL_2 0x22D4 -# define R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT 0 -# define R300_PVS_CNTL_2_PARAM_COUNT_SHIFT 16 -#define R300_VAP_PVS_CNTL_3 0x22D8 -# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT 10 -# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT 0 +#define R300_VAP_PVS_CONST_CNTL 0x22D4 +# define R300_PVS_CONST_BASE_OFFSET_SHIFT 0 +# define R300_PVS_MAX_CONST_ADDR_SHIFT 16 +#define R300_VAP_PVS_CODE_CNTL_1 0x22D8 +# define R300_PVS_LAST_VTX_SRC_INST_SHIFT 0 +#define R300_VAP_PVS_FLOW_CNTL_OPC 0x22DC /* The entire range from 0x2300 to 0x2AC inclusive seems to be used for * immediate vertices @@ -657,7 +706,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* This table specifies the source location and format for up to 16 texture * addresses (i[0]:i[15]) and four colors (c[0]:c[3]) */ -#define R500_RS_IP_0 0x4074
+#define R500_RS_IP_0 0x4074 #define R500_RS_IP_1 0x4078 #define R500_RS_IP_2 0x407C #define R500_RS_IP_3 0x4080 @@ -673,31 +722,24 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define R500_RS_IP_13 0x40A8 #define R500_RS_IP_14 0x40AC #define R500_RS_IP_15 0x40B0 -#define R500_RS_IP_TEX_PTR_S_SHIFT 0
-#define R500_RS_IP_TEX_PTR_T_SHIFT 6
-#define R500_RS_IP_TEX_PTR_R_SHIFT 12
-#define R500_RS_IP_TEX_PTR_Q_SHIFT 18
-#define R500_RS_IP_COL_PTR_SHIFT 24
-#define R500_RS_IP_COL_FMT_SHIFT 27
-#define R500_RS_IP_COL_FMT_RGBA (0 << 27) -#define R500_RS_IP_COL_FMT_RGB0 (1 << 27) -#define R500_RS_IP_COL_FMT_RGB1 (2 << 27) -/* gap */ -#define R500_RS_IP_COL_FMT_000A (4 << 27) -#define R500_RS_IP_COL_FMT_0000 (5 << 27) -#define R500_RS_IP_COL_FMT_0001 (6 << 27) -/* gap */ -#define R500_RS_IP_COL_FMT_111A (8 << 27) -#define R500_RS_IP_COL_FMT_1110 (9 << 27) -#define R500_RS_IP_COL_FMT_1111 (10 << 27) +#define R500_RS_IP_PTR_K0 62 +#define R500_RS_IP_PTR_K1 63 +#define R500_RS_IP_TEX_PTR_S_SHIFT 0 +#define R500_RS_IP_TEX_PTR_T_SHIFT 6 +#define R500_RS_IP_TEX_PTR_R_SHIFT 12 +#define R500_RS_IP_TEX_PTR_Q_SHIFT 18 +#define R500_RS_IP_COL_PTR_SHIFT 24 +#define R500_RS_IP_COL_FMT_SHIFT 27 +# define R500_RS_COL_PTR(x) (x << 24) +# define R500_RS_COL_FMT(x) (x << 27) /* gap */ #define R500_RS_IP_OFFSET_DIS (0 << 31) -#define R500_RS_IP_OFFSET_EN (1 << 31)
+#define R500_RS_IP_OFFSET_EN (1 << 31) /* gap */ /* Zero to flush caches. */ -#define R300_TX_CNTL 0x4100 +#define R300_TX_INVALTAGS 0x4100 #define R300_TX_FLUSH 0x0 /* The upper enable bits are guessed, based on fglrx reported limits. */ @@ -728,25 +770,25 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R500_TX_DIRECTION_VERITCAL (1<<27) /* S Texture Coordinate of Vertex 0 for Point texture stuffing (LLC) */ -#define GA_POINT_S0 0x4200 +#define R300_GA_POINT_S0 0x4200 /* T Texture Coordinate of Vertex 0 for Point texture stuffing (LLC) */ -#define GA_POINT_T0 0x4204 +#define R300_GA_POINT_T0 0x4204 /* S Texture Coordinate of Vertex 2 for Point texture stuffing (URC) */ -#define GA_POINT_S1 0x4208 +#define R300_GA_POINT_S1 0x4208 /* T Texture Coordinate of Vertex 2 for Point texture stuffing (URC) */ -#define GA_POINT_T1 0x420c +#define R300_GA_POINT_T1 0x420c /* Specifies amount to shift integer position of vertex (screen space) before * converting to float for triangle stipple. */ -#define GA_TRIANGLE_STIPPLE 0x4214 -# define GA_TRIANGLE_STIPPLE_X_SHIFT_SHIFT 0 -# define GA_TRIANGLE_STIPPLE_X_SHIFT_MASK 0x0000000f -# define GA_TRIANGLE_STIPPLE_Y_SHIFT_SHIFT 16 -# define GA_TRIANGLE_STIPPLE_Y_SHIFT_MASK 0x000f0000 +#define R300_GA_TRIANGLE_STIPPLE 0x4214 +# define R300_GA_TRIANGLE_STIPPLE_X_SHIFT_SHIFT 0 +# define R300_GA_TRIANGLE_STIPPLE_X_SHIFT_MASK 0x0000000f +# define R300_GA_TRIANGLE_STIPPLE_Y_SHIFT_SHIFT 16 +# define R300_GA_TRIANGLE_STIPPLE_Y_SHIFT_MASK 0x000f0000 /* The pointsize is given in multiples of 6. The pointsize can be enormous: * Clear() renders a single point that fills the entire framebuffer. @@ -761,16 +803,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_POINTSIZE_MAX (R300_POINTSIZE_Y_MASK / 6) /* Blue fill color */ -#define GA_FILL_R 0x4220 +#define R500_GA_FILL_R 0x4220 /* Blue fill color */ -#define GA_FILL_G 0x4224 +#define R500_GA_FILL_G 0x4224 /* Blue fill color */ -#define GA_FILL_B 0x4228 +#define R500_GA_FILL_B 0x4228 /* Alpha fill color */ -#define GA_FILL_A 0x422c +#define R500_GA_FILL_A 0x422c /* Specifies maximum and minimum point & sprite sizes for per vertex size @@ -791,159 +833,159 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * VE: vertical or horizontal * HO & VE: no classification */ -#define GA_LINE_CNTL 0x4234 -# define GA_LINE_CNTL_WIDTH_SHIFT 0 -# define GA_LINE_CNTL_WIDTH_MASK 0x0000ffff -# define GA_LINE_CNTL_END_TYPE_HOR (0 << 16) -# define GA_LINE_CNTL_END_TYPE_VER (1 << 16) -# define GA_LINE_CNTL_END_TYPE_SQR (2 << 16) /* horizontal or vertical depending upon slope */ -# define GA_LINE_CNTL_END_TYPE_COMP (3 << 16) /* Computed (perpendicular to slope) */ -# define GA_LINE_CNTL_SORT_NO (0 << 18) -# define GA_LINE_CNTL_SORT_MINX_MINY (1 << 18) +#define R300_GA_LINE_CNTL 0x4234 +# define R300_GA_LINE_CNTL_WIDTH_SHIFT 0 +# define R300_GA_LINE_CNTL_WIDTH_MASK 0x0000ffff +# define R300_GA_LINE_CNTL_END_TYPE_HOR (0 << 16) +# define R300_GA_LINE_CNTL_END_TYPE_VER (1 << 16) +# define R300_GA_LINE_CNTL_END_TYPE_SQR (2 << 16) /* horizontal or vertical depending upon slope */ +# define R300_GA_LINE_CNTL_END_TYPE_COMP (3 << 16) /* Computed (perpendicular to slope) */ +# define R500_GA_LINE_CNTL_SORT_NO (0 << 18) +# define R500_GA_LINE_CNTL_SORT_MINX_MINY (1 << 18) /** TODO: looks wrong */ -# define R300_LINESIZE_MAX (GA_LINE_CNTL_WIDTH_MASK / 6) +# define R300_LINESIZE_MAX (R300_GA_LINE_CNTL_WIDTH_MASK / 6) /** TODO: looks wrong */ # define R300_LINE_CNT_HO (1 << 16) /** TODO: looks wrong */ # define R300_LINE_CNT_VE (1 << 17) /* Line Stipple configuration information. */ -#define GA_LINE_STIPPLE_CONFIG 0x4238 -# define GA_LINE_STIPPLE_CONFIG_LINE_RESET_NO (0 << 0) -# define GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE (1 << 0) -# define GA_LINE_STIPPLE_CONFIG_LINE_RESET_PACKET (2 << 0) -# define GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_SHIFT 2 -# define GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK 0xfffffffc +#define R300_GA_LINE_STIPPLE_CONFIG 0x4238 +# define R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_NO (0 << 0) +# define R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE (1 << 0) +# define R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_PACKET (2 << 0) +# define R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_SHIFT 2 +# define R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK 0xfffffffc /* Used to load US instructions and constants */ #define R500_GA_US_VECTOR_INDEX 0x4250 -# define GA_US_VECTOR_INDEX_SHIFT 0 -# define GA_US_VECTOR_INDEX_MASK 0x000000ff -# define GA_US_VECTOR_INDEX_TYPE_INSTR (0 << 16) -# define GA_US_VECTOR_INDEX_TYPE_CONST (1 << 16) -# define GA_US_VECTOR_INDEX_CLAMP_NO (0 << 17) -# define GA_US_VECTOR_INDEX_CLAMP_CONST (1 << 17) +# define R500_GA_US_VECTOR_INDEX_SHIFT 0 +# define R500_GA_US_VECTOR_INDEX_MASK 0x000000ff +# define R500_GA_US_VECTOR_INDEX_TYPE_INSTR (0 << 16) +# define R500_GA_US_VECTOR_INDEX_TYPE_CONST (1 << 16) +# define R500_GA_US_VECTOR_INDEX_CLAMP_NO (0 << 17) +# define R500_GA_US_VECTOR_INDEX_CLAMP_CONST (1 << 17) /* Data register for loading US instructions and constants */ #define R500_GA_US_VECTOR_DATA 0x4254 /* Specifies color properties and mappings of textures. */ -#define GA_COLOR_CONTROL_PS3 0x4258 -# define TEX0_SHADING_PS3_SOLID (0 << 0) -# define TEX0_SHADING_PS3_FLAT (1 << 0) -# define TEX0_SHADING_PS3_GOURAUD (2 << 0) -# define TEX1_SHADING_PS3_SOLID (0 << 2) -# define TEX1_SHADING_PS3_FLAT (1 << 2) -# define TEX1_SHADING_PS3_GOURAUD (2 << 2) -# define TEX2_SHADING_PS3_SOLID (0 << 4) -# define TEX2_SHADING_PS3_FLAT (1 << 4) -# define TEX2_SHADING_PS3_GOURAUD (2 << 4) -# define TEX3_SHADING_PS3_SOLID (0 << 6) -# define TEX3_SHADING_PS3_FLAT (1 << 6) -# define TEX3_SHADING_PS3_GOURAUD (2 << 6) -# define TEX4_SHADING_PS3_SOLID (0 << 8) -# define TEX4_SHADING_PS3_FLAT (1 << 8) -# define TEX4_SHADING_PS3_GOURAUD (2 << 8) -# define TEX5_SHADING_PS3_SOLID (0 << 10) -# define TEX5_SHADING_PS3_FLAT (1 << 10) -# define TEX5_SHADING_PS3_GOURAUD (2 << 10) -# define TEX6_SHADING_PS3_SOLID (0 << 12) -# define TEX6_SHADING_PS3_FLAT (1 << 12) -# define TEX6_SHADING_PS3_GOURAUD (2 << 12) -# define TEX7_SHADING_PS3_SOLID (0 << 14) -# define TEX7_SHADING_PS3_FLAT (1 << 14) -# define TEX7_SHADING_PS3_GOURAUD (2 << 14) -# define TEX8_SHADING_PS3_SOLID (0 << 16) -# define TEX8_SHADING_PS3_FLAT (1 << 16) -# define TEX8_SHADING_PS3_GOURAUD (2 << 16) -# define TEX9_SHADING_PS3_SOLID (0 << 18) -# define TEX9_SHADING_PS3_FLAT (1 << 18) -# define TEX9_SHADING_PS3_GOURAUD (2 << 18) -# define TEX10_SHADING_PS3_SOLID (0 << 20) -# define TEX10_SHADING_PS3_FLAT (1 << 20) -# define TEX10_SHADING_PS3_GOURAUD (2 << 20) -# define COLOR0_TEX_OVERRIDE_NO (0 << 22) -# define COLOR0_TEX_OVERRIDE_TEX_0 (1 << 22) -# define COLOR0_TEX_OVERRIDE_TEX_1 (2 << 22) -# define COLOR0_TEX_OVERRIDE_TEX_2 (3 << 22) -# define COLOR0_TEX_OVERRIDE_TEX_3 (4 << 22) -# define COLOR0_TEX_OVERRIDE_TEX_4 (5 << 22) -# define COLOR0_TEX_OVERRIDE_TEX_5 (6 << 22) -# define COLOR0_TEX_OVERRIDE_TEX_6 (7 << 22) -# define COLOR0_TEX_OVERRIDE_TEX_7 (8 << 22) -# define COLOR0_TEX_OVERRIDE_TEX_8_C2 (9 << 22) -# define COLOR0_TEX_OVERRIDE_TEX_9_C3 (10 << 22) -# define COLOR1_TEX_OVERRIDE_NO (0 << 26) -# define COLOR1_TEX_OVERRIDE_TEX_0 (1 << 26) -# define COLOR1_TEX_OVERRIDE_TEX_1 (2 << 26) -# define COLOR1_TEX_OVERRIDE_TEX_2 (3 << 26) -# define COLOR1_TEX_OVERRIDE_TEX_3 (4 << 26) -# define COLOR1_TEX_OVERRIDE_TEX_4 (5 << 26) -# define COLOR1_TEX_OVERRIDE_TEX_5 (6 << 26) -# define COLOR1_TEX_OVERRIDE_TEX_6 (7 << 26) -# define COLOR1_TEX_OVERRIDE_TEX_7 (8 << 26) -# define COLOR1_TEX_OVERRIDE_TEX_8_C2 (9 << 26) -# define COLOR1_TEX_OVERRIDE_TEX_9_C3 (10 << 26) +#define R500_GA_COLOR_CONTROL_PS3 0x4258 +# define R500_TEX0_SHADING_PS3_SOLID (0 << 0) +# define R500_TEX0_SHADING_PS3_FLAT (1 << 0) +# define R500_TEX0_SHADING_PS3_GOURAUD (2 << 0) +# define R500_TEX1_SHADING_PS3_SOLID (0 << 2) +# define R500_TEX1_SHADING_PS3_FLAT (1 << 2) +# define R500_TEX1_SHADING_PS3_GOURAUD (2 << 2) +# define R500_TEX2_SHADING_PS3_SOLID (0 << 4) +# define R500_TEX2_SHADING_PS3_FLAT (1 << 4) +# define R500_TEX2_SHADING_PS3_GOURAUD (2 << 4) +# define R500_TEX3_SHADING_PS3_SOLID (0 << 6) +# define R500_TEX3_SHADING_PS3_FLAT (1 << 6) +# define R500_TEX3_SHADING_PS3_GOURAUD (2 << 6) +# define R500_TEX4_SHADING_PS3_SOLID (0 << 8) +# define R500_TEX4_SHADING_PS3_FLAT (1 << 8) +# define R500_TEX4_SHADING_PS3_GOURAUD (2 << 8) +# define R500_TEX5_SHADING_PS3_SOLID (0 << 10) +# define R500_TEX5_SHADING_PS3_FLAT (1 << 10) +# define R500_TEX5_SHADING_PS3_GOURAUD (2 << 10) +# define R500_TEX6_SHADING_PS3_SOLID (0 << 12) +# define R500_TEX6_SHADING_PS3_FLAT (1 << 12) +# define R500_TEX6_SHADING_PS3_GOURAUD (2 << 12) +# define R500_TEX7_SHADING_PS3_SOLID (0 << 14) +# define R500_TEX7_SHADING_PS3_FLAT (1 << 14) +# define R500_TEX7_SHADING_PS3_GOURAUD (2 << 14) +# define R500_TEX8_SHADING_PS3_SOLID (0 << 16) +# define R500_TEX8_SHADING_PS3_FLAT (1 << 16) +# define R500_TEX8_SHADING_PS3_GOURAUD (2 << 16) +# define R500_TEX9_SHADING_PS3_SOLID (0 << 18) +# define R500_TEX9_SHADING_PS3_FLAT (1 << 18) +# define R500_TEX9_SHADING_PS3_GOURAUD (2 << 18) +# define R500_TEX10_SHADING_PS3_SOLID (0 << 20) +# define R500_TEX10_SHADING_PS3_FLAT (1 << 20) +# define R500_TEX10_SHADING_PS3_GOURAUD (2 << 20) +# define R500_COLOR0_TEX_OVERRIDE_NO (0 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_0 (1 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_1 (2 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_2 (3 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_3 (4 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_4 (5 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_5 (6 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_6 (7 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_7 (8 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_8_C2 (9 << 22) +# define R500_COLOR0_TEX_OVERRIDE_TEX_9_C3 (10 << 22) +# define R500_COLOR1_TEX_OVERRIDE_NO (0 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_0 (1 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_1 (2 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_2 (3 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_3 (4 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_4 (5 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_5 (6 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_6 (7 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_7 (8 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_8_C2 (9 << 26) +# define R500_COLOR1_TEX_OVERRIDE_TEX_9_C3 (10 << 26) /* Returns idle status of various G3D block, captured when GA_IDLE written or * when hard or soft reset asserted. */ -#define GA_IDLE 0x425c -# define GA_IDLE_PIPE3_Z_IDLE (0 << 0) -# define GA_IDLE_PIPE2_Z_IDLE (0 << 1) -# define GA_IDLE_PIPE3_CD_IDLE (0 << 2) -# define GA_IDLE_PIPE2_CD_IDLE (0 << 3) -# define GA_IDLE_PIPE3_FG_IDLE (0 << 4) -# define GA_IDLE_PIPE2_FG_IDLE (0 << 5) -# define GA_IDLE_PIPE3_US_IDLE (0 << 6) -# define GA_IDLE_PIPE2_US_IDLE (0 << 7) -# define GA_IDLE_PIPE3_SC_IDLE (0 << 8) -# define GA_IDLE_PIPE2_SC_IDLE (0 << 9) -# define GA_IDLE_PIPE3_RS_IDLE (0 << 10) -# define GA_IDLE_PIPE2_RS_IDLE (0 << 11) -# define GA_IDLE_PIPE1_Z_IDLE (0 << 12) -# define GA_IDLE_PIPE0_Z_IDLE (0 << 13) -# define GA_IDLE_PIPE1_CD_IDLE (0 << 14) -# define GA_IDLE_PIPE0_CD_IDLE (0 << 15) -# define GA_IDLE_PIPE1_FG_IDLE (0 << 16) -# define GA_IDLE_PIPE0_FG_IDLE (0 << 17) -# define GA_IDLE_PIPE1_US_IDLE (0 << 18) -# define GA_IDLE_PIPE0_US_IDLE (0 << 19) -# define GA_IDLE_PIPE1_SC_IDLE (0 << 20) -# define GA_IDLE_PIPE0_SC_IDLE (0 << 21) -# define GA_IDLE_PIPE1_RS_IDLE (0 << 22) -# define GA_IDLE_PIPE0_RS_IDLE (0 << 23) -# define GA_IDLE_SU_IDLE (0 << 24) -# define GA_IDLE_GA_IDLE (0 << 25) -# define GA_IDLE_GA_UNIT2_IDLE (0 << 26) +#define R500_GA_IDLE 0x425c +# define R500_GA_IDLE_PIPE3_Z_IDLE (0 << 0) +# define R500_GA_IDLE_PIPE2_Z_IDLE (0 << 1) +# define R500_GA_IDLE_PIPE3_CD_IDLE (0 << 2) +# define R500_GA_IDLE_PIPE2_CD_IDLE (0 << 3) +# define R500_GA_IDLE_PIPE3_FG_IDLE (0 << 4) +# define R500_GA_IDLE_PIPE2_FG_IDLE (0 << 5) +# define R500_GA_IDLE_PIPE3_US_IDLE (0 << 6) +# define R500_GA_IDLE_PIPE2_US_IDLE (0 << 7) +# define R500_GA_IDLE_PIPE3_SC_IDLE (0 << 8) +# define R500_GA_IDLE_PIPE2_SC_IDLE (0 << 9) +# define R500_GA_IDLE_PIPE3_RS_IDLE (0 << 10) +# define R500_GA_IDLE_PIPE2_RS_IDLE (0 << 11) +# define R500_GA_IDLE_PIPE1_Z_IDLE (0 << 12) +# define R500_GA_IDLE_PIPE0_Z_IDLE (0 << 13) +# define R500_GA_IDLE_PIPE1_CD_IDLE (0 << 14) +# define R500_GA_IDLE_PIPE0_CD_IDLE (0 << 15) +# define R500_GA_IDLE_PIPE1_FG_IDLE (0 << 16) +# define R500_GA_IDLE_PIPE0_FG_IDLE (0 << 17) +# define R500_GA_IDLE_PIPE1_US_IDLE (0 << 18) +# define R500_GA_IDLE_PIPE0_US_IDLE (0 << 19) +# define R500_GA_IDLE_PIPE1_SC_IDLE (0 << 20) +# define R500_GA_IDLE_PIPE0_SC_IDLE (0 << 21) +# define R500_GA_IDLE_PIPE1_RS_IDLE (0 << 22) +# define R500_GA_IDLE_PIPE0_RS_IDLE (0 << 23) +# define R500_GA_IDLE_SU_IDLE (0 << 24) +# define R500_GA_IDLE_GA_IDLE (0 << 25) +# define R500_GA_IDLE_GA_UNIT2_IDLE (0 << 26) /* Current value of stipple accumulator. */ #define R300_GA_LINE_STIPPLE_VALUE 0x4260 /* S Texture Coordinate Value for Vertex 0 of Line (stuff textures -- i.e. AA) */ -#define GA_LINE_S0 0x4264 +#define R300_GA_LINE_S0 0x4264 /* S Texture Coordinate Value for Vertex 1 of Lines (V2 of parallelogram -- stuff textures -- i.e. AA) */ -#define GA_LINE_S1 0x4268 +#define R300_GA_LINE_S1 0x4268 /* GA Input fifo high water marks */ -#define GA_FIFO_CNTL 0x4270 -# define GA_FIFO_CNTL_VERTEX_FIFO_MASK 0x00000007 -# define GA_FIFO_CNTL_VERTEX_FIFO_SHIFT 0 -# define GA_FIFO_CNTL_VERTEX_INDEX_MASK 0x00000038 -# define GA_FIFO_CNTL_VERTEX_INDEX_SHIFT 3 -# define GA_FIFO_CNTL_VERTEX_REG_MASK 0x00003fc0 -# define GA_FIFO_CNTL_VERTEX_REG_SHIFT 6 - -/* Something shade related */ -#define GA_ENHANCE 0x4274 -# define GA_ENHANCE_DEADLOCK_CNTL_NO_EFFECT (0 << 0) -# define GA_ENHANCE_DEADLOCK_CNTL_PREVENT_TCL (1 << 0) /* Prevents TCL interface from deadlocking on GA side. */ -# define GA_ENHANCE_FASTSYNC_CNTL_NO_EFFECT (0 << 1) -# define GA_ENHANCE_FASTSYNC_CNTL_ENABLE (1 << 1) /* Enables high-performance register/primitive switching. */ -# define GA_ENHANCE_REG_READWRITE_NO_EFFECT (0 << 2) /* R520+ only */ -# define GA_ENHANCE_REG_READWRITE_ENABLE (1 << 2) /* R520+ only, Enables GA support of simultaneous register reads and writes. */ -# define GA_ENHANCE_REG_NOSTALL_NO_EFFECT (0 << 3) -# define GA_ENHANCE_REG_NOSTALL_ENABLE (1 << 3) /* Enables GA support of no-stall reads for register read back. */ +#define R500_GA_FIFO_CNTL 0x4270 +# define R500_GA_FIFO_CNTL_VERTEX_FIFO_MASK 0x00000007 +# define R500_GA_FIFO_CNTL_VERTEX_FIFO_SHIFT 0 +# define R500_GA_FIFO_CNTL_VERTEX_INDEX_MASK 0x00000038 +# define R500_GA_FIFO_CNTL_VERTEX_INDEX_SHIFT 3 +# define R500_GA_FIFO_CNTL_VERTEX_REG_MASK 0x00003fc0 +# define R500_GA_FIFO_CNTL_VERTEX_REG_SHIFT 6 + +/* GA enhance/tweaks */ +#define R300_GA_ENHANCE 0x4274 +# define R300_GA_ENHANCE_DEADLOCK_CNTL_NO_EFFECT (0 << 0) +# define R300_GA_ENHANCE_DEADLOCK_CNTL_PREVENT_TCL (1 << 0) /* Prevents TCL interface from deadlocking on GA side. */ +# define R300_GA_ENHANCE_FASTSYNC_CNTL_NO_EFFECT (0 << 1) +# define R300_GA_ENHANCE_FASTSYNC_CNTL_ENABLE (1 << 1) /* Enables high-performance register/primitive switching. */ +# define R500_GA_ENHANCE_REG_READWRITE_NO_EFFECT (0 << 2) /* R520+ only */ +# define R500_GA_ENHANCE_REG_READWRITE_ENABLE (1 << 2) /* R520+ only, Enables GA support of simultaneous register reads and writes. */ +# define R500_GA_ENHANCE_REG_NOSTALL_NO_EFFECT (0 << 3) +# define R500_GA_ENHANCE_REG_NOSTALL_ENABLE (1 << 3) /* Enables GA support of no-stall reads for register read back. */ #define R300_GA_COLOR_CONTROL 0x4278 # define R300_GA_COLOR_CONTROL_RGB0_SHADING_SOLID (0 << 0) @@ -1006,46 +1048,48 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* Polygon Mode * Dangerous */ -#define GA_POLY_MODE 0x4288 -# define GA_POLY_MODE_DISABLE (0 << 0) -# define GA_POLY_MODE_DUAL (1 << 0) /* send 2 sets of 3 polys with specified poly type */ +#define R300_GA_POLY_MODE 0x4288 +# define R300_GA_POLY_MODE_DISABLE (0 << 0) +# define R300_GA_POLY_MODE_DUAL (1 << 0) /* send 2 sets of 3 polys with specified poly type */ /* reserved */ -# define GA_POLY_MODE_FRONT_PTYPE_POINT (0 << 4) -# define GA_POLY_MODE_FRONT_PTYPE_LINE (1 << 4) -# define GA_POLY_MODE_FRONT_PTYPE_TRI (2 << 4) +# define R300_GA_POLY_MODE_FRONT_PTYPE_POINT (0 << 4) +# define R300_GA_POLY_MODE_FRONT_PTYPE_LINE (1 << 4) +# define R300_GA_POLY_MODE_FRONT_PTYPE_TRI (2 << 4) /* reserved */ -# define GA_POLY_MODE_BACK_PTYPE_POINT (0 << 7) -# define GA_POLY_MODE_BACK_PTYPE_LINE (1 << 7) -# define GA_POLY_MODE_BACK_PTYPE_TRI (2 << 7) +# define R300_GA_POLY_MODE_BACK_PTYPE_POINT (0 << 7) +# define R300_GA_POLY_MODE_BACK_PTYPE_LINE (1 << 7) +# define R300_GA_POLY_MODE_BACK_PTYPE_TRI (2 << 7) /* reserved */ /* Specifies the rouding mode for geometry & color SPFP to FP conversions. */ -#define GA_ROUND_MODE 0x428c -# define GA_ROUND_MODE_GEOMETRY_ROUND_TRUNC (0 << 0) -# define GA_ROUND_MODE_GEOMETRY_ROUND_NEAREST (1 << 0) -# define GA_ROUND_MODE_COLOR_ROUND_TRUNC (0 << 2) -# define GA_ROUND_MODE_COLOR_ROUND_NEAREST (1 << 2) -# define GA_ROUND_MODE_RGB_CLAMP_RGB (0 << 4) -# define GA_ROUND_MODE_RGB_CLAMP_FP20 (1 << 4) -# define GA_ROUND_MODE_ALPHA_CLAMP_RGB (0 << 5) -# define GA_ROUND_MODE_ALPHA_CLAMP_FP20 (1 << 5) -# define GA_ROUND_MODE_GEOMETRY_MASK_SHIFT 6 -# define GA_ROUND_MODE_GEOMETRY_MASK_MASK 0x000003c0 +#define R300_GA_ROUND_MODE 0x428c +# define R300_GA_ROUND_MODE_GEOMETRY_ROUND_TRUNC (0 << 0) +# define R300_GA_ROUND_MODE_GEOMETRY_ROUND_NEAREST (1 << 0) +# define R300_GA_ROUND_MODE_COLOR_ROUND_TRUNC (0 << 2) +# define R300_GA_ROUND_MODE_COLOR_ROUND_NEAREST (1 << 2) +# define R300_GA_ROUND_MODE_RGB_CLAMP_RGB (0 << 4) +# define R300_GA_ROUND_MODE_RGB_CLAMP_FP20 (1 << 4) +# define R300_GA_ROUND_MODE_ALPHA_CLAMP_RGB (0 << 5) +# define R300_GA_ROUND_MODE_ALPHA_CLAMP_FP20 (1 << 5) +# define R500_GA_ROUND_MODE_GEOMETRY_MASK_SHIFT 6 +# define R500_GA_ROUND_MODE_GEOMETRY_MASK_MASK 0x000003c0 /* Specifies x & y offsets for vertex data after conversion to FP. * Offsets are in S15 format (subpixels -- 1/12 or 1/16, even in 8b * subprecision). */ -#define GA_OFFSET 0x4290 -# define GA_OFFSET_X_OFFSET_SHIFT 0 -# define GA_OFFSET_X_OFFSET_MASK 0x0000ffff -# define GA_OFFSET_Y_OFFSET_SHIFT 16 -# define GA_OFFSET_Y_OFFSET_MASK 0xffff0000 +#define R300_GA_OFFSET 0x4290 +# define R300_GA_OFFSET_X_OFFSET_SHIFT 0 +# define R300_GA_OFFSET_X_OFFSET_MASK 0x0000ffff +# define R300_GA_OFFSET_Y_OFFSET_SHIFT 16 +# define R300_GA_OFFSET_Y_OFFSET_MASK 0xffff0000 /* Specifies the scale to apply to fog. */ -#define R300_RE_FOG_SCALE 0x4294 +#define R300_GA_FOG_SCALE 0x4294 /* Specifies the offset to apply to fog. */ -#define R300_RE_FOG_START 0x4298 +#define R300_GA_FOG_OFFSET 0x4298 +/* Specifies number of cycles to assert reset, and also causes RB3D soft reset to assert. */ +#define R300_GA_SOFT_RESET 0x429c /* 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. @@ -1053,11 +1097,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Some of the tests indicate that fgl has a fallback implementation of zbias * via pixel shaders. */ -#define R300_RE_ZBIAS_CNTL 0x42A0 /* GUESS */ -#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 +#define R300_SU_TEX_WRAP 0x42A0 +#define R300_SU_POLY_OFFSET_FRONT_SCALE 0x42A4 +#define R300_SU_POLY_OFFSET_FRONT_OFFSET 0x42A8 +#define R300_SU_POLY_OFFSET_BACK_SCALE 0x42AC +#define R300_SU_POLY_OFFSET_BACK_OFFSET 0x42B0 /* This register needs to be set to (1<<1) for RV350 to correctly * perform depth test (see --vb-triangles in r300_demo) @@ -1068,10 +1112,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * 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_SU_POLY_OFFSET_ENABLE 0x42B4 +# define R300_FRONT_ENABLE (1 << 0) +# define R300_BACK_ENABLE (1 << 1) +# define R300_PARA_ENABLE (1 << 2) -#define R300_RE_CULL_CNTL 0x42B8 +#define R300_SU_CULL_MODE 0x42B8 # define R300_CULL_FRONT (1 << 0) # define R300_CULL_BACK (1 << 1) # define R300_FRONT_FACE_CCW (0 << 2) @@ -1126,32 +1172,32 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define R300_RS_IP_3 0x431C # define R300_RS_INTERP_SRC_SHIFT 2 /* TODO: check for removal */ # define R300_RS_INTERP_SRC_MASK (7 << 2) /* TODO: check for removal */ -# define R300_RS_TEX_PTR(x) (x << 0)
-# define R300_RS_COL_PTR(x) (x << 6)
-# define R300_RS_COL_FMT(x) (x << 9)
-# define R300_RS_COL_FMT_RGBA 0
-# define R300_RS_COL_FMT_RGB0 2
-# define R300_RS_COL_FMT_RGB1 3
-# define R300_RS_COL_FMT_000A 4
-# define R300_RS_COL_FMT_0000 5
-# define R300_RS_COL_FMT_0001 6
-# define R300_RS_COL_FMT_111A 8
-# define R300_RS_COL_FMT_1110 9
-# define R300_RS_COL_FMT_1111 10
-# define R300_RS_SEL_S(x) (x << 13)
-# define R300_RS_SEL_T(x) (x << 16)
-# define R300_RS_SEL_R(x) (x << 19)
-# define R300_RS_SEL_Q(x) (x << 22)
-# define R300_RS_SEL_C0 0
-# define R300_RS_SEL_C1 1
-# define R300_RS_SEL_C2 2
-# define R300_RS_SEL_C3 3
-# define R300_RS_SEL_K0 4
-# define R300_RS_SEL_K1 5
+# define R300_RS_TEX_PTR(x) (x << 0) +# define R300_RS_COL_PTR(x) (x << 6) +# define R300_RS_COL_FMT(x) (x << 9) +# define R300_RS_COL_FMT_RGBA 0 +# define R300_RS_COL_FMT_RGB0 1 +# define R300_RS_COL_FMT_RGB1 2 +# define R300_RS_COL_FMT_000A 4 +# define R300_RS_COL_FMT_0000 5 +# define R300_RS_COL_FMT_0001 6 +# define R300_RS_COL_FMT_111A 8 +# define R300_RS_COL_FMT_1110 9 +# define R300_RS_COL_FMT_1111 10 +# define R300_RS_SEL_S(x) (x << 13) +# define R300_RS_SEL_T(x) (x << 16) +# define R300_RS_SEL_R(x) (x << 19) +# define R300_RS_SEL_Q(x) (x << 22) +# define R300_RS_SEL_C0 0 +# define R300_RS_SEL_C1 1 +# define R300_RS_SEL_C2 2 +# define R300_RS_SEL_C3 3 +# define R300_RS_SEL_K0 4 +# define R300_RS_SEL_K1 5 /* */ -#define R500_RS_INST_0 0x4320
+#define R500_RS_INST_0 0x4320 #define R500_RS_INST_1 0x4324 #define R500_RS_INST_2 0x4328 #define R500_RS_INST_3 0x432c @@ -1167,17 +1213,17 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define R500_RS_INST_13 0x4354 #define R500_RS_INST_14 0x4358 #define R500_RS_INST_15 0x435c -#define R500_RS_INST_TEX_ID_SHIFT 0
-#define R500_RS_INST_TEX_CN_WRITE (1 << 4)
-#define R500_RS_INST_TEX_ADDR_SHIFT 5
-#define R500_RS_INST_COL_ID_SHIFT 12
-#define R500_RS_INST_COL_CN_NO_WRITE (0 << 16)
-#define R500_RS_INST_COL_CN_WRITE (1 << 16)
-#define R500_RS_INST_COL_CN_WRITE_FBUFFER (2 << 16)
-#define R500_RS_INST_COL_CN_WRITE_BACKFACE (3 << 16)
-#define R500_RS_INST_COL_ADDR_SHIFT 18
-#define R500_RS_INST_TEX_ADJ (1 << 25)
-#define R500_RS_INST_W_CN (1 << 26)
+#define R500_RS_INST_TEX_ID_SHIFT 0 +#define R500_RS_INST_TEX_CN_WRITE (1 << 4) +#define R500_RS_INST_TEX_ADDR_SHIFT 5 +#define R500_RS_INST_COL_ID_SHIFT 12 +#define R500_RS_INST_COL_CN_NO_WRITE (0 << 16) +#define R500_RS_INST_COL_CN_WRITE (1 << 16) +#define R500_RS_INST_COL_CN_WRITE_FBUFFER (2 << 16) +#define R500_RS_INST_COL_CN_WRITE_BACKFACE (3 << 16) +#define R500_RS_INST_COL_ADDR_SHIFT 18 +#define R500_RS_INST_TEX_ADJ (1 << 25) +#define R500_RS_INST_W_CN (1 << 26) /* These DWORDs control how vertex data is routed into fragment program * registers, after interpolators. @@ -1220,6 +1266,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_SC_HYPERZ_HZ_Z0MAX_NO (0 << 6) # define R300_SC_HYPERZ_HZ_Z0MAX (1 << 6) +#define R300_SC_EDGERULE 0x43a8 /* BEGIN: Scissors and cliprects */ @@ -1237,21 +1284,21 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * 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_SC_CLIPRECT_TL_0 0x43B0 +#define R300_SC_CLIPRECT_BR_0 0x43B4 +#define R300_SC_CLIPRECT_TL_1 0x43B8 +#define R300_SC_CLIPRECT_BR_1 0x43BC +#define R300_SC_CLIPRECT_TL_2 0x43C0 +#define R300_SC_CLIPRECT_BR_2 0x43C4 +#define R300_SC_CLIPRECT_TL_3 0x43C8 +#define R300_SC_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_SC_CLIP_RULE 0x43D0 # define R300_CLIP_OUT (1 << 0) # define R300_CLIP_0 (1 << 1) # define R300_CLIP_1 (1 << 2) @@ -1271,8 +1318,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* gap */ -#define R300_RE_SCISSORS_TL 0x43E0 -#define R300_RE_SCISSORS_BR 0x43E4 +#define R300_SC_SCISSORS_TL 0x43E0 +#define R300_SC_SCISSORS_BR 0x43E4 # define R300_SCISSORS_OFFSET 1440 # define R300_SCISSORS_X_SHIFT 0 # define R300_SCISSORS_X_MASK (0x1FFF << 0) @@ -1556,23 +1603,23 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * 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_US_CONFIG 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 +#define R300_US_PIXSIZE 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_US_CODE_OFFSET 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 << 6) -# define R300_PFS_CNTL_TEX_OFFSET_SHIFT 12 -# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) /* GUESS */ +# define R300_PFS_CNTL_TEX_OFFSET_SHIFT 13 +# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 13) # define R300_PFS_CNTL_TEX_END_SHIFT 18 -# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* GUESS */ +# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* gap */ @@ -1583,70 +1630,65 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * * Offsets are relative to the master offset from PFS_CNTL_2. */ -#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_OUTPUT_COLOR (1 << 22) -# define R300_PFS_NODE_OUTPUT_DEPTH (1 << 23) +#define R300_US_CODE_ADDR_0 0x4610 +#define R300_US_CODE_ADDR_1 0x4614 +#define R300_US_CODE_ADDR_2 0x4618 +#define R300_US_CODE_ADDR_3 0x461C +# define R300_ALU_START_SHIFT 0 +# define R300_ALU_START_MASK (63 << 0) +# define R300_ALU_SIZE_SHIFT 6 +# define R300_ALU_SIZE_MASK (63 << 6) +# define R300_TEX_START_SHIFT 12 +# define R300_TEX_START_MASK (31 << 12) +# define R300_TEX_SIZE_SHIFT 17 +# define R300_TEX_SIZE_MASK (31 << 17) +# define R300_RGBA_OUT (1 << 22) +# define R300_W_OUT (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) - /* GUESS */ -# define R300_FPITX_SRC_CONST (1 << 5) -# define R300_FPITX_DST_SHIFT 6 -# define R300_FPITX_DST_MASK (31 << 6) -# define R300_FPITX_IMAGE_SHIFT 11 - /* GUESS based on layout and native limits */ -# define R300_FPITX_IMAGE_MASK (15 << 11) -/* 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 -# define R300_FPITX_OPCODE_MASK (7 << 15) +#define R300_US_TEX_INST_0 0x4620 +# define R300_SRC_ADDR_SHIFT 0 +# define R300_SRC_ADDR_MASK (31 << 0) +# define R300_DST_ADDR_SHIFT 6 +# define R300_DST_ADDR_MASK (31 << 6) +# define R300_TEX_ID_SHIFT 11 +# define R300_TEX_ID_MASK (15 << 11) +# define R300_TEX_INST_SHIFT 15 +# define R300_TEX_OP_NOP 0 +# define R300_TEX_OP_LD 1 +# define R300_TEX_OP_KIL 2 +# define R300_TEX_OP_TXP 3 +# define R300_TEX_OP_TXB 4 +# define R300_TEX_INST_MASK (7 << 15) /* Output format from the unfied shader */ -#define R500_US_OUT_FMT 0x46A4 -# define R500_US_OUT_FMT_C4_8 (0 << 0) -# define R500_US_OUT_FMT_C4_10 (1 << 0) -# define R500_US_OUT_FMT_C4_10_GAMMA (2 << 0) -# define R500_US_OUT_FMT_C_16 (3 << 0) -# define R500_US_OUT_FMT_C2_16 (4 << 0) -# define R500_US_OUT_FMT_C4_16 (5 << 0) -# define R500_US_OUT_FMT_C_16_MPEG (6 << 0) -# define R500_US_OUT_FMT_C2_16_MPEG (7 << 0) -# define R500_US_OUT_FMT_C2_4 (8 << 0) -# define R500_US_OUT_FMT_C_3_3_2 (9 << 0) -# define R500_US_OUT_FMT_C_6_5_6 (10 << 0) -# define R500_US_OUT_FMT_C_11_11_10 (11 << 0) -# define R500_US_OUT_FMT_C_10_11_11 (12 << 0) -# define R500_US_OUT_FMT_C_2_10_10_10 (13 << 0) +#define R300_US_OUT_FMT 0x46A4 +# define R300_US_OUT_FMT_C4_8 (0 << 0) +# define R300_US_OUT_FMT_C4_10 (1 << 0) +# define R300_US_OUT_FMT_C4_10_GAMMA (2 << 0) +# define R300_US_OUT_FMT_C_16 (3 << 0) +# define R300_US_OUT_FMT_C2_16 (4 << 0) +# define R300_US_OUT_FMT_C4_16 (5 << 0) +# define R300_US_OUT_FMT_C_16_MPEG (6 << 0) +# define R300_US_OUT_FMT_C2_16_MPEG (7 << 0) +# define R300_US_OUT_FMT_C2_4 (8 << 0) +# define R300_US_OUT_FMT_C_3_3_2 (9 << 0) +# define R300_US_OUT_FMT_C_6_5_6 (10 << 0) +# define R300_US_OUT_FMT_C_11_11_10 (11 << 0) +# define R300_US_OUT_FMT_C_10_11_11 (12 << 0) +# define R300_US_OUT_FMT_C_2_10_10_10 (13 << 0) /* reserved */ -# define R500_US_OUT_FMT_UNUSED (15 << 0) -# define R500_US_OUT_FMT_C_16_FP (16 << 0) -# define R500_US_OUT_FMT_C2_16_FP (17 << 0) -# define R500_US_OUT_FMT_C4_16_FP (18 << 0) -# define R500_US_OUT_FMT_C_32_FP (19 << 0) -# define R500_US_OUT_FMT_C2_32_FP (20 << 0) -# define R500_US_OUT_FMT_C4_32_FP (20 << 0) +# define R300_US_OUT_FMT_UNUSED (15 << 0) +# define R300_US_OUT_FMT_C_16_FP (16 << 0) +# define R300_US_OUT_FMT_C2_16_FP (17 << 0) +# define R300_US_OUT_FMT_C4_16_FP (18 << 0) +# define R300_US_OUT_FMT_C_32_FP (19 << 0) +# define R300_US_OUT_FMT_C2_32_FP (20 << 0) +# define R300_US_OUT_FMT_C4_32_FP (20 << 0) /* ALU * The ALU instructions register blocks are enumerated according to the order @@ -1712,204 +1754,247 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * - 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_SRC_MASK 0x0003ffff -# 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_SRC_MASK 0x0003ffff -# 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 - /* GUESS */ -# define R300_FPI0_ARGC_HALF 22 -# 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_CMPH (7 << 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 - /* GUESS */ -# define R300_FPI2_ARGA_HALF 18 -# define R300_FPI2_ARG0A_SHIFT 0 -# define R300_FPI2_ARG0A_MASK (31 << 0) -# define R300_FPI2_ARG0A_NEG (1 << 5) - /* GUESS */ -# define R300_FPI2_ARG0A_ABS (1 << 6) -# define R300_FPI2_ARG1A_SHIFT 7 -# define R300_FPI2_ARG1A_MASK (31 << 7) -# define R300_FPI2_ARG1A_NEG (1 << 12) - /* GUESS */ -# define R300_FPI2_ARG1A_ABS (1 << 13) -# define R300_FPI2_ARG2A_SHIFT 14 -# define R300_FPI2_ARG2A_MASK (31 << 14) -# define R300_FPI2_ARG2A_NEG (1 << 19) - /* GUESS */ -# define R300_FPI2_ARG2A_ABS (1 << 20) -# 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) +#define R300_US_ALU_RGB_ADDR_0 0x46C0 +# define R300_ALU_SRC0C_SHIFT 0 +# define R300_ALU_SRC0C_MASK (31 << 0) +# define R300_ALU_SRC0C_CONST (1 << 5) +# define R300_ALU_SRC1C_SHIFT 6 +# define R300_ALU_SRC1C_MASK (31 << 6) +# define R300_ALU_SRC1C_CONST (1 << 11) +# define R300_ALU_SRC2C_SHIFT 12 +# define R300_ALU_SRC2C_MASK (31 << 12) +# define R300_ALU_SRC2C_CONST (1 << 17) +# define R300_ALU_SRC_MASK 0x0003ffff +# define R300_ALU_DSTC_SHIFT 18 +# define R300_ALU_DSTC_MASK (31 << 18) +# define R300_ALU_DSTC_REG_MASK_SHIFT 23 +# define R300_ALU_DSTC_REG_X (1 << 23) +# define R300_ALU_DSTC_REG_Y (1 << 24) +# define R300_ALU_DSTC_REG_Z (1 << 25) +# define R300_ALU_DSTC_OUTPUT_MASK_SHIFT 26 +# define R300_ALU_DSTC_OUTPUT_X (1 << 26) +# define R300_ALU_DSTC_OUTPUT_Y (1 << 27) +# define R300_ALU_DSTC_OUTPUT_Z (1 << 28) + +#define R300_US_ALU_ALPHA_ADDR_0 0x47C0 +# define R300_ALU_SRC0A_SHIFT 0 +# define R300_ALU_SRC0A_MASK (31 << 0) +# define R300_ALU_SRC0A_CONST (1 << 5) +# define R300_ALU_SRC1A_SHIFT 6 +# define R300_ALU_SRC1A_MASK (31 << 6) +# define R300_ALU_SRC1A_CONST (1 << 11) +# define R300_ALU_SRC2A_SHIFT 12 +# define R300_ALU_SRC2A_MASK (31 << 12) +# define R300_ALU_SRC2A_CONST (1 << 17) +# define R300_ALU_SRC_MASK 0x0003ffff +# define R300_ALU_DSTA_SHIFT 18 +# define R300_ALU_DSTA_MASK (31 << 18) +# define R300_ALU_DSTA_REG (1 << 23) +# define R300_ALU_DSTA_OUTPUT (1 << 24) +# define R300_ALU_DSTA_DEPTH (1 << 27) + +#define R300_US_ALU_RGB_INST_0 0x48C0 +# define R300_ALU_ARGC_SRC0C_XYZ 0 +# define R300_ALU_ARGC_SRC0C_XXX 1 +# define R300_ALU_ARGC_SRC0C_YYY 2 +# define R300_ALU_ARGC_SRC0C_ZZZ 3 +# define R300_ALU_ARGC_SRC1C_XYZ 4 +# define R300_ALU_ARGC_SRC1C_XXX 5 +# define R300_ALU_ARGC_SRC1C_YYY 6 +# define R300_ALU_ARGC_SRC1C_ZZZ 7 +# define R300_ALU_ARGC_SRC2C_XYZ 8 +# define R300_ALU_ARGC_SRC2C_XXX 9 +# define R300_ALU_ARGC_SRC2C_YYY 10 +# define R300_ALU_ARGC_SRC2C_ZZZ 11 +# define R300_ALU_ARGC_SRC0A 12 +# define R300_ALU_ARGC_SRC1A 13 +# define R300_ALU_ARGC_SRC2A 14 +# define R300_ALU_ARGC_SRCP_XYZ 15 +# define R300_ALU_ARGC_SRCP_XXX 16 +# define R300_ALU_ARGC_SRCP_YYY 17 +# define R300_ALU_ARGC_SRCP_ZZZ 18 +# define R300_ALU_ARGC_SRCP_WWW 19 +# define R300_ALU_ARGC_ZERO 20 +# define R300_ALU_ARGC_ONE 21 +# define R300_ALU_ARGC_HALF 22 +# define R300_ALU_ARGC_SRC0C_YZX 23 +# define R300_ALU_ARGC_SRC1C_YZX 24 +# define R300_ALU_ARGC_SRC2C_YZX 25 +# define R300_ALU_ARGC_SRC0C_ZXY 26 +# define R300_ALU_ARGC_SRC1C_ZXY 27 +# define R300_ALU_ARGC_SRC2C_ZXY 28 +# define R300_ALU_ARGC_SRC0CA_WZY 29 +# define R300_ALU_ARGC_SRC1CA_WZY 30 +# define R300_ALU_ARGC_SRC2CA_WZY 31 + +# define R300_ALU_ARG0C_SHIFT 0 +# define R300_ALU_ARG0C_MASK (31 << 0) +# define R300_ALU_ARG0C_NOP (0 << 5) +# define R300_ALU_ARG0C_NEG (1 << 5) +# define R300_ALU_ARG0C_ABS (2 << 5) +# define R300_ALU_ARG0C_NAB (3 << 5) +# define R300_ALU_ARG1C_SHIFT 7 +# define R300_ALU_ARG1C_MASK (31 << 7) +# define R300_ALU_ARG1C_NOP (0 << 12) +# define R300_ALU_ARG1C_NEG (1 << 12) +# define R300_ALU_ARG1C_ABS (2 << 12) +# define R300_ALU_ARG1C_NAB (3 << 12) +# define R300_ALU_ARG2C_SHIFT 14 +# define R300_ALU_ARG2C_MASK (31 << 14) +# define R300_ALU_ARG2C_NOP (0 << 19) +# define R300_ALU_ARG2C_NEG (1 << 19) +# define R300_ALU_ARG2C_ABS (2 << 19) +# define R300_ALU_ARG2C_NAB (3 << 19) +# define R300_ALU_SRCP_1_MINUS_2_SRC0 (0 << 21) +# define R300_ALU_SRCP_SRC1_MINUS_SRC0 (1 << 21) +# define R300_ALU_SRCP_SRC1_PLUS_SRC0 (2 << 21) +# define R300_ALU_SRCP_1_MINUS_SRC0 (3 << 21) + +# define R300_ALU_OUTC_MAD (0 << 23) +# define R300_ALU_OUTC_DP3 (1 << 23) +# define R300_ALU_OUTC_DP4 (2 << 23) +# define R300_ALU_OUTC_D2A (3 << 23) +# define R300_ALU_OUTC_MIN (4 << 23) +# define R300_ALU_OUTC_MAX (5 << 23) +# define R300_ALU_OUTC_CMPH (7 << 23) +# define R300_ALU_OUTC_CMP (8 << 23) +# define R300_ALU_OUTC_FRC (9 << 23) +# define R300_ALU_OUTC_REPL_ALPHA (10 << 23) + +# define R300_ALU_OUTC_MOD_NOP (0 << 27) +# define R300_ALU_OUTC_MOD_MUL2 (1 << 27) +# define R300_ALU_OUTC_MOD_MUL4 (2 << 27) +# define R300_ALU_OUTC_MOD_MUL8 (3 << 27) +# define R300_ALU_OUTC_MOD_DIV2 (4 << 27) +# define R300_ALU_OUTC_MOD_DIV4 (5 << 27) +# define R300_ALU_OUTC_MOD_DIV8 (6 << 27) + +# define R300_ALU_OUTC_CLAMP (1 << 30) +# define R300_ALU_INSERT_NOP (1 << 31) + +#define R300_US_ALU_ALPHA_INST_0 0x49C0 +# define R300_ALU_ARGA_SRC0C_X 0 +# define R300_ALU_ARGA_SRC0C_Y 1 +# define R300_ALU_ARGA_SRC0C_Z 2 +# define R300_ALU_ARGA_SRC1C_X 3 +# define R300_ALU_ARGA_SRC1C_Y 4 +# define R300_ALU_ARGA_SRC1C_Z 5 +# define R300_ALU_ARGA_SRC2C_X 6 +# define R300_ALU_ARGA_SRC2C_Y 7 +# define R300_ALU_ARGA_SRC2C_Z 8 +# define R300_ALU_ARGA_SRC0A 9 +# define R300_ALU_ARGA_SRC1A 10 +# define R300_ALU_ARGA_SRC2A 11 +# define R300_ALU_ARGA_SRCP_X 12 +# define R300_ALU_ARGA_SRCP_Y 13 +# define R300_ALU_ARGA_SRCP_Z 14 +# define R300_ALU_ARGA_SRCP_W 15 + +# define R300_ALU_ARGA_ZERO 16 +# define R300_ALU_ARGA_ONE 17 +# define R300_ALU_ARGA_HALF 18 +# define R300_ALU_ARG0A_SHIFT 0 +# define R300_ALU_ARG0A_MASK (31 << 0) +# define R300_ALU_ARG0A_NOP (0 << 5) +# define R300_ALU_ARG0A_NEG (1 << 5) +# define R300_ALU_ARG0A_ABS (2 << 5) +# define R300_ALU_ARG0A_NAB (3 << 5) +# define R300_ALU_ARG1A_SHIFT 7 +# define R300_ALU_ARG1A_MASK (31 << 7) +# define R300_ALU_ARG1A_NOP (0 << 12) +# define R300_ALU_ARG1A_NEG (1 << 12) +# define R300_ALU_ARG1A_ABS (2 << 12) +# define R300_ALU_ARG1A_NAB (3 << 12) +# define R300_ALU_ARG2A_SHIFT 14 +# define R300_ALU_ARG2A_MASK (31 << 14) +# define R300_ALU_ARG2A_NOP (0 << 19) +# define R300_ALU_ARG2A_NEG (1 << 19) +# define R300_ALU_ARG2A_ABS (2 << 19) +# define R300_ALU_ARG2A_NAB (3 << 19) +# define R300_ALU_SRCP_1_MINUS_2_SRC0 (0 << 21) +# define R300_ALU_SRCP_SRC1_MINUS_SRC0 (1 << 21) +# define R300_ALU_SRCP_SRC1_PLUS_SRC0 (2 << 21) +# define R300_ALU_SRCP_1_MINUS_SRC0 (3 << 21) + +# define R300_ALU_OUTA_MAD (0 << 23) +# define R300_ALU_OUTA_DP4 (1 << 23) +# define R300_ALU_OUTA_MIN (2 << 23) +# define R300_ALU_OUTA_MAX (3 << 23) +# define R300_ALU_OUTA_CND (5 << 23) +# define R300_ALU_OUTA_CMP (6 << 23) +# define R300_ALU_OUTA_FRC (7 << 23) +# define R300_ALU_OUTA_EX2 (8 << 23) +# define R300_ALU_OUTA_LG2 (9 << 23) +# define R300_ALU_OUTA_RCP (10 << 23) +# define R300_ALU_OUTA_RSQ (11 << 23) + +# define R300_ALU_OUTA_MOD_NOP (0 << 27) +# define R300_ALU_OUTA_MOD_MUL2 (1 << 27) +# define R300_ALU_OUTA_MOD_MUL4 (2 << 27) +# define R300_ALU_OUTA_MOD_MUL8 (3 << 27) +# define R300_ALU_OUTA_MOD_DIV2 (4 << 27) +# define R300_ALU_OUTA_MOD_DIV4 (5 << 27) +# define R300_ALU_OUTA_MOD_DIV8 (6 << 27) + +# define R300_ALU_OUTA_CLAMP (1 << 30) /* END: Fragment program instruction set */ /* Fog: Fog Blending Enable */ -#define FG_FOG_BLEND 0x4bc0 -# define FG_FOG_BLEND_DISABLE (0 << 0) -# define FG_FOG_BLEND_ENABLE (1 << 0) -# define FG_FOG_BLEND_FN_LINEAR (0 << 1) -# define FG_FOG_BLEND_FN_EXP (1 << 1) -# define FG_FOG_BLEND_FN_EXP2 (2 << 1) -# define FG_FOG_BLEND_FN_CONSTANT (3 << 1) -# define FG_FOG_BLEND_FN_MASK 0x00000006 +#define R300_FG_FOG_BLEND 0x4bc0 +# define R300_FG_FOG_BLEND_DISABLE (0 << 0) +# define R300_FG_FOG_BLEND_ENABLE (1 << 0) +# define R300_FG_FOG_BLEND_FN_LINEAR (0 << 1) +# define R300_FG_FOG_BLEND_FN_EXP (1 << 1) +# define R300_FG_FOG_BLEND_FN_EXP2 (2 << 1) +# define R300_FG_FOG_BLEND_FN_CONSTANT (3 << 1) +# define R300_FG_FOG_BLEND_FN_MASK (3 << 1) /* Fog: Red Component of Fog Color */ -#define FG_FOG_COLOR_R 0x4bc8 +#define R300_FG_FOG_COLOR_R 0x4bc8 /* Fog: Green Component of Fog Color */ -#define FG_FOG_COLOR_G 0x4bcc +#define R300_FG_FOG_COLOR_G 0x4bcc /* Fog: Blue Component of Fog Color */ -#define FG_FOG_COLOR_B 0x4bd0 -# define FG_FOG_COLOR_MASK 0x000001ff +#define R300_FG_FOG_COLOR_B 0x4bd0 +# define R300_FG_FOG_COLOR_MASK 0x000003ff /* Fog: Constant Factor for Fog Blending */ -#define FG_FOG_FACTOR 0x4bc4 -# define FG_FOG_FACTOR_MASK 0x000001ff +#define R300_FG_FOG_FACTOR 0x4bc4 +# define FG_FOG_FACTOR_MASK 0x000003ff /* Fog: Alpha function */ -#define FG_ALPHA_FUNC 0x4bd4 -# define R300_REF_ALPHA_MASK 0x000000ff -# define FG_ALPHA_FUNC_NEVER (0 << 8) -# define FG_ALPHA_FUNC_LESS (1 << 8) -# define FG_ALPHA_FUNC_EQUAL (2 << 8) -# define FG_ALPHA_FUNC_LE (3 << 8) -# define FG_ALPHA_FUNC_GREATER (4 << 8) -# define FG_ALPHA_FUNC_NOTEQUAL (5 << 8) -# define FG_ALPHA_FUNC_GE (6 << 8) -# define FG_ALPHA_FUNC_ALWAYS (7 << 8) -# define R300_ALPHA_TEST_OP_MASK (7 << 8) -# define FG_ALPHA_FUNC_DISABLE (0 << 11) -# define FG_ALPHA_FUNC_ENABLE (1 << 11) -# define FG_ALPHA_FUNC_10BIT (0 << 12) -# define FG_ALPHA_FUNC_8BIT (1 << 12) -/* gap in AMD spec */ -# define FG_ALPHA_FUNC_MASK_DISABLE (0 << 16) -# define FG_ALPHA_FUNC_MASK_ENABLE (1 << 16) -# define FG_ALPHA_FUNC_CFG_2_OF_4 (0 << 17) -# define FG_ALPHA_FUNC_CFG_3_OF_6 (1 << 17) -/* gap in AMD spec */ -# define FG_ALPHA_FUNC_DITH_DISABLE (0 << 20) -# define FG_ALPHA_FUNC_DITH_ENABLE (1 << 20) -/* gap in AMD spec */ -# define FG_ALPHA_FUNC_OFFSET_DISABLE (0 << 24) /* Not supported in R520. Default R300 and RV350 behaviour. */ -# define FG_ALPHA_FUNC_OFFSET_ENABLE (1 << 24) /* Not supported in R520 */ -# define FG_ALPHA_FUNC_DISC_ZERO_MASK_DISABLE (0 << 25) -# define FG_ALPHA_FUNC_DISC_ZERO_MASK_ENABLE (1 << 25) -/* gap in AMD spec */ -# define FG_ALPHA_FUNC_FP16_DISABLE (0 << 28) -# define FG_ALPHA_FUNC_FP16_ENABLE (1 << 28) -/* gap in AMD spec */ +#define R300_FG_ALPHA_FUNC 0x4bd4 +# define R300_FG_ALPHA_FUNC_VAL_MASK 0x000000ff +# define R300_FG_ALPHA_FUNC_NEVER (0 << 8) +# define R300_FG_ALPHA_FUNC_LESS (1 << 8) +# define R300_FG_ALPHA_FUNC_EQUAL (2 << 8) +# define R300_FG_ALPHA_FUNC_LE (3 << 8) +# define R300_FG_ALPHA_FUNC_GREATER (4 << 8) +# define R300_FG_ALPHA_FUNC_NOTEQUAL (5 << 8) +# define R300_FG_ALPHA_FUNC_GE (6 << 8) +# define R300_FG_ALPHA_FUNC_ALWAYS (7 << 8) +# define R300_ALPHA_TEST_OP_MASK (7 << 8) +# define R300_FG_ALPHA_FUNC_DISABLE (0 << 11) +# define R300_FG_ALPHA_FUNC_ENABLE (1 << 11) + +# define R500_FG_ALPHA_FUNC_10BIT (0 << 12) +# define R500_FG_ALPHA_FUNC_8BIT (1 << 12) + +# define R300_FG_ALPHA_FUNC_MASK_DISABLE (0 << 16) +# define R300_FG_ALPHA_FUNC_MASK_ENABLE (1 << 16) +# define R300_FG_ALPHA_FUNC_CFG_2_OF_4 (0 << 17) +# define R300_FG_ALPHA_FUNC_CFG_3_OF_6 (1 << 17) + +# define R300_FG_ALPHA_FUNC_DITH_DISABLE (0 << 20) +# define R300_FG_ALPHA_FUNC_DITH_ENABLE (1 << 20) + +# define R500_FG_ALPHA_FUNC_OFFSET_DISABLE (0 << 24) +# define R500_FG_ALPHA_FUNC_OFFSET_ENABLE (1 << 24) /* Not supported in R520 */ +# define R500_FG_ALPHA_FUNC_DISC_ZERO_MASK_DISABLE (0 << 25) +# define R500_FG_ALPHA_FUNC_DISC_ZERO_MASK_ENABLE (1 << 25) + +# define R500_FG_ALPHA_FUNC_FP16_DISABLE (0 << 28) +# define R500_FG_ALPHA_FUNC_FP16_ENABLE (1 << 28) + /* Fog: Where does the depth come from? */ #define R300_FG_DEPTH_SRC 0x4bd8 @@ -1917,8 +2002,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_FG_DEPTH_SRC_SHADER (1 << 0) /* Fog: Alpha Compare Value */ -#define FG_ALPHA_VALUE 0x4be0 -# define FG_ALPHA_VALUE_MASK 0x0000ffff +#define R500_FG_ALPHA_VALUE 0x4be0 +# define R500_FG_ALPHA_VALUE_MASK 0x0000ffff /* gap */ @@ -1927,7 +2012,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #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 */ +/* last consts */ #define R300_PFS_PARAM_31_X 0x4DF0 #define R300_PFS_PARAM_31_Y 0x4DF4 #define R300_PFS_PARAM_31_Z 0x4DF8 @@ -1935,14 +2020,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* Unpipelined. */ #define R300_RB3D_CCTL 0x4e00 -/* gap in AMD docs */ # define R300_RB3D_CCTL_NUM_MULTIWRITES_1_BUFFER (0 << 5) # define R300_RB3D_CCTL_NUM_MULTIWRITES_2_BUFFERS (1 << 5) # define R300_RB3D_CCTL_NUM_MULTIWRITES_3_BUFFERS (2 << 5) # define R300_RB3D_CCTL_NUM_MULTIWRITES_4_BUFFERS (3 << 5) # define R300_RB3D_CCTL_CLRCMP_FLIPE_DISABLE (0 << 7) # define R300_RB3D_CCTL_CLRCMP_FLIPE_ENABLE (1 << 7) -/* gap in AMD docs */ # define R300_RB3D_CCTL_AA_COMPRESSION_DISABLE (0 << 9) # define R300_RB3D_CCTL_AA_COMPRESSION_ENABLE (1 << 9) # define R300_RB3D_CCTL_CMASK_DISABLE (0 << 10) @@ -1967,9 +2050,17 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #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) +# define R300_ALPHA_BLEND_ENABLE (1 << 0) +# define R300_SEPARATE_ALPHA_ENABLE (1 << 1) +# define R300_READ_ENABLE (1 << 2) +# define R300_DISCARD_SRC_PIXELS_DIS (0 << 3) +# define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_0 (1 << 3) +# define R300_DISCARD_SRC_PIXELS_SRC_COLOR_0 (2 << 3) +# define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_COLOR_0 (3 << 3) +# define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_1 (4 << 3) +# define R300_DISCARD_SRC_PIXELS_SRC_COLOR_1 (5 << 3) +# define R300_DISCARD_SRC_PIXELS_SRC_ALPHA_COLOR_1 (6 << 3) + /* the following are shared between CBLEND and ABLEND */ # define R300_FCN_MASK (3 << 12) # define R300_COMB_FCN_ADD_CLAMP (0 << 12) @@ -2044,7 +2135,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* Color Buffer Address Offset of multibuffer 0. Unpipelined. */ #define R300_RB3D_COLOROFFSET0 0x4E28 -# define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */ +# define R300_COLOROFFSET_MASK 0xFFFFFFE0 /* Color Buffer Address Offset of multibuffer 1. Unpipelined. */ #define R300_RB3D_COLOROFFSET1 0x4E2C /* Color Buffer Address Offset of multibuffer 2. Unpipelined. */ @@ -2061,7 +2152,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Bit 18: Extremely weird tile like, but some pixels duplicated? */ #define R300_RB3D_COLORPITCH0 0x4E38 -# define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS, should be 13:1 */ +# define R300_COLORPITCH_MASK 0x00003FFE # define R300_COLOR_TILE_DISABLE (0 << 16) # define R300_COLOR_TILE_ENABLE (1 << 16) # define R300_COLOR_MICROTILE_DISABLE (0 << 17) @@ -2071,12 +2162,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_COLOR_ENDIAN_WORD_SWAP (1 << 19) # define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 19) # define R300_COLOR_ENDIAN_HALF_DWORD_SWAP (3 << 19) -# define R300_COLOR_FORMAT_ARGB10101010 (0 << 21) -# define R300_COLOR_FORMAT_UV1010 (1 << 21) -# define R300_COLOR_FORMAT_CI8 (2 << 21) /* 2D only */ +# define R500_COLOR_FORMAT_ARGB10101010 (0 << 21) +# define R500_COLOR_FORMAT_UV1010 (1 << 21) +# define R500_COLOR_FORMAT_CI8 (2 << 21) /* 2D only */ # define R300_COLOR_FORMAT_ARGB1555 (3 << 21) # define R300_COLOR_FORMAT_RGB565 (4 << 21) -# define R300_COLOR_FORMAT_ARGB2101010 (5 << 21) +# define R500_COLOR_FORMAT_ARGB2101010 (5 << 21) # define R300_COLOR_FORMAT_ARGB8888 (6 << 21) # define R300_COLOR_FORMAT_ARGB32323232 (7 << 21) /* reserved */ @@ -2085,7 +2176,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_COLOR_FORMAT_VYUY (11 << 21) # define R300_COLOR_FORMAT_YVYU (12 << 21) # define R300_COLOR_FORMAT_UV88 (13 << 21) -# define R300_COLOR_FORMAT_I10 (14 << 21) +# define R500_COLOR_FORMAT_I10 (14 << 21) # define R300_COLOR_FORMAT_ARGB4444 (15 << 21) #define R300_RB3D_COLORPITCH1 0x4E3C #define R300_RB3D_COLORPITCH2 0x4E40 @@ -2104,16 +2195,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Set to 0A before 3D operations, set to 02 afterwards. */ #define R300_RB3D_DSTCACHE_CTLSTAT 0x4e4c -# define RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_NO_EFFECT (0 << 0) -# define RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_NO_EFFECT_1 (1 << 0) -# define RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D (2 << 0) -# define RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D_1 (3 << 0) -# define RB3D_DSTCACHE_CTLSTAT_DC_FREE_NO_EFFECT (0 << 2) -# define RB3D_DSTCACHE_CTLSTAT_DC_FREE_NO_EFFECT_1 (1 << 2) -# define RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS (2 << 2) -# define RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS_1 (3 << 2) -# define RB3D_DSTCACHE_CTLSTAT_DC_FINISH_NO_SIGNAL (0 << 4) -# define RB3D_DSTCACHE_CTLSTAT_DC_FINISH_SIGNAL (1 << 4) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_NO_EFFECT (0 << 0) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_NO_EFFECT_1 (1 << 0) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D (2 << 0) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D_1 (3 << 0) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_NO_EFFECT (0 << 2) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_NO_EFFECT_1 (1 << 2) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS (2 << 2) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS_1 (3 << 2) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FINISH_NO_SIGNAL (0 << 4) +# define R300_RB3D_DSTCACHE_CTLSTAT_DC_FINISH_SIGNAL (1 << 4) #define R300_RB3D_DITHER_CTL 0x4E50 # define R300_RB3D_DITHER_CTL_DITHER_MODE_TRUNCATE (0 << 0) @@ -2128,87 +2219,81 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* Resolve buffer destination address. The cache must be empty before changing * this register if the cb is in resolve mode. Unpipelined */ -#define RB3D_AARESOLVE_OFFSET 0x4e80 -# define RB3D_AARESOLVE_OFFSET_SHIFT 5 -# define RB3D_AARESOLVE_OFFSET_MASK 0xffffffe0 /* At least according to the calculations of Christoph Brill */ +#define R300_RB3D_AARESOLVE_OFFSET 0x4e80 +# define R300_RB3D_AARESOLVE_OFFSET_SHIFT 5 +# define R300_RB3D_AARESOLVE_OFFSET_MASK 0xffffffe0 /* At least according to the calculations of Christoph Brill */ /* Resolve Buffer Pitch and Tiling Control. The cache must be empty before * changing this register if the cb is in resolve mode. Unpipelined */ -#define RB3D_AARESOLVE_PITCH 0x4e84 -# define RB3D_AARESOLVE_PITCH_SHIFT 1 -# define RB3D_AARESOLVE_PITCH_MASK 0x00003ffe /* At least according to the calculations of Christoph Brill */ +#define R300_RB3D_AARESOLVE_PITCH 0x4e84 +# define R300_RB3D_AARESOLVE_PITCH_SHIFT 1 +# define R300_RB3D_AARESOLVE_PITCH_MASK 0x00003ffe /* At least according to the calculations of Christoph Brill */ /* Resolve Buffer Control. Unpipelined */ -#define RB3D_AARESOLVE_CTL 0x4e88 -# define RB3D_AARESOLVE_CTL_AARESOLVE_MODE_NORMAL (0 << 0) -# define RB3D_AARESOLVE_CTL_AARESOLVE_MODE_RESOLVE (1 << 0) -# define RB3D_AARESOLVE_CTL_AARESOLVE_GAMMA_10 (0 << 1) -# define RB3D_AARESOLVE_CTL_AARESOLVE_GAMMA_22 (1 << 1) -# define RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_SAMPLE0 (0 << 2) -# define RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_AVERAGE (1 << 2) +#define R300_RB3D_AARESOLVE_CTL 0x4e88 +# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_MODE_NORMAL (0 << 0) +# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_MODE_RESOLVE (1 << 0) +# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_GAMMA_10 (0 << 1) +# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_GAMMA_22 (1 << 1) +# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_SAMPLE0 (0 << 2) +# define R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_AVERAGE (1 << 2) /* Discard src pixels less than or equal to threshold. */ -#define RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4ea0 +#define R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4ea0 /* Discard src pixels greater than or equal to threshold. */ -#define RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4ea4 -# define RB3D_DISCARD_SRC_PIXEL_THRESHOLD_BLUE_SHIFT 0 -# define RB3D_DISCARD_SRC_PIXEL_THRESHOLD_BLUE_MASK 0x000000ff -# define RB3D_DISCARD_SRC_PIXEL_THRESHOLD_GREEN_SHIFT 8 -# define RB3D_DISCARD_SRC_PIXEL_THRESHOLD_GREEN_MASK 0x0000ff00 -# define RB3D_DISCARD_SRC_PIXEL_THRESHOLD_RED_SHIFT 16 -# define RB3D_DISCARD_SRC_PIXEL_THRESHOLD_RED_MASK 0x00ff0000 -# define RB3D_DISCARD_SRC_PIXEL_THRESHOLD_ALPHA_SHIFT 24 -# define RB3D_DISCARD_SRC_PIXEL_THRESHOLD_ALPHA_MASK 0xff000000 +#define R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4ea4 +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_BLUE_SHIFT 0 +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_BLUE_MASK 0x000000ff +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_GREEN_SHIFT 8 +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_GREEN_MASK 0x0000ff00 +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_RED_SHIFT 16 +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_RED_MASK 0x00ff0000 +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_ALPHA_SHIFT 24 +# define R500_RB3D_DISCARD_SRC_PIXEL_THRESHOLD_ALPHA_MASK 0xff000000 /* 3D ROP Control. Stalls the 2d/3d datapath until it is idle. */ -#define RB3D_ROPCNTL 0x4e18 +#define R300_RB3D_ROPCNTL 0x4e18 /* TODO: fill in content here */ /* Color Compare Flip. Stalls the 2d/3d datapath until it is idle. */ -#define RB3D_CLRCMP_FLIPE 0x4e1c +#define R300_RB3D_CLRCMP_FLIPE 0x4e1c /* Sets the fifo sizes */ -#define RB3D_FIFO_SIZE 0x4ef4 -# define RB3D_FIFO_SIZE_OP_FIFO_SIZE_FULL (0 << 0) -# define RB3D_FIFO_SIZE_OP_FIFO_SIZE_HALF (1 << 0) -# define RB3D_FIFO_SIZE_OP_FIFO_SIZE_QUATER (2 << 0) -# define RB3D_FIFO_SIZE_OP_FIFO_SIZE_EIGTHS (3 << 0) -/* gap in AMD spec */ +#define R500_RB3D_FIFO_SIZE 0x4ef4 +# define R500_RB3D_FIFO_SIZE_OP_FIFO_SIZE_FULL (0 << 0) +# define R500_RB3D_FIFO_SIZE_OP_FIFO_SIZE_HALF (1 << 0) +# define R500_RB3D_FIFO_SIZE_OP_FIFO_SIZE_QUATER (2 << 0) +# define R500_RB3D_FIFO_SIZE_OP_FIFO_SIZE_EIGTHS (3 << 0) /* Constant color used by the blender. Pipelined through the blender. */ -#define RB3D_CONSTANT_COLOR_AR 0x4ef8 -# define RB3D_CONSTANT_COLOR_AR_RED_MASK 0x0000ffff -# define RB3D_CONSTANT_COLOR_AR_RED_SHIFT 0 -# define RB3D_CONSTANT_COLOR_AR_ALPHA_MASK 0xffff0000 -# define RB3D_CONSTANT_COLOR_AR_ALPHA_SHIFT 16 +#define R500_RB3D_CONSTANT_COLOR_AR 0x4ef8 +# define R500_RB3D_CONSTANT_COLOR_AR_RED_MASK 0x0000ffff +# define R500_RB3D_CONSTANT_COLOR_AR_RED_SHIFT 0 +# define R500_RB3D_CONSTANT_COLOR_AR_ALPHA_MASK 0xffff0000 +# define R500_RB3D_CONSTANT_COLOR_AR_ALPHA_SHIFT 16 /* Constant color used by the blender. Pipelined through the blender. */ -#define RB3D_CONSTANT_COLOR_GB 0x4efc -# define RB3D_CONSTANT_COLOR_AR_BLUE_MASK 0x0000ffff -# define RB3D_CONSTANT_COLOR_AR_BLUE_SHIFT 0 -# define RB3D_CONSTANT_COLOR_AR_GREEN_MASK 0xffff0000 -# define RB3D_CONSTANT_COLOR_AR_GREEN_SHIFT 16 +#define R500_RB3D_CONSTANT_COLOR_GB 0x4efc +# define R500_RB3D_CONSTANT_COLOR_AR_BLUE_MASK 0x0000ffff +# define R500_RB3D_CONSTANT_COLOR_AR_BLUE_SHIFT 0 +# define R500_RB3D_CONSTANT_COLOR_AR_GREEN_MASK 0xffff0000 +# define R500_RB3D_CONSTANT_COLOR_AR_GREEN_SHIFT 16 /* 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 -# define R300_RB3D_Z_DISABLED_2 0x00000014 -# 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 +#define R300_ZB_CNTL 0x4F00 +# define R300_STENCIL_ENABLE (1 << 0) +# define R300_Z_ENABLE (1 << 1) +# define R300_Z_WRITE_ENABLE (1 << 2) +# define R300_Z_SIGNED_COMPARE (1 << 3) +# define R300_STENCIL_FRONT_BACK (1 << 4) + +#define R300_ZB_ZSTENCILCNTL 0x4f04 /* functions */ # define R300_ZS_NEVER 0 # define R300_ZS_LESS 1 @@ -2228,51 +2313,49 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_ZS_INVERT 5 # define R300_ZS_INCR_WRAP 6 # define R300_ZS_DECR_WRAP 7 +# define R300_Z_FUNC_SHIFT 0 /* 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 ZB_STENCILREFMASK 0x4f08 -# define ZB_STENCILREFMASK_STENCILREF_SHIFT 0 -# define ZB_STENCILREFMASK_STENCIL_MASK 0xff -# define ZB_STENCILREFMASK_STENCILREF_MASK 0x000000ff -# define ZB_STENCILREFMASK_STENCILMASK_SHIFT 8 -# define ZB_STENCILREFMASK_STENCILMASK_MASK 0x0000ff00 -# define ZB_STENCILREFMASK_STENCILWRITEMASK_SHIFT 16 -# define ZB_STENCILREFMASK_STENCILWRITEMASK_MASK 0xffff0000 +# define R300_S_FRONT_FUNC_SHIFT 3 +# define R300_S_FRONT_SFAIL_OP_SHIFT 6 +# define R300_S_FRONT_ZPASS_OP_SHIFT 9 +# define R300_S_FRONT_ZFAIL_OP_SHIFT 12 +# define R300_S_BACK_FUNC_SHIFT 15 +# define R300_S_BACK_SFAIL_OP_SHIFT 18 +# define R300_S_BACK_ZPASS_OP_SHIFT 21 +# define R300_S_BACK_ZFAIL_OP_SHIFT 24 + +#define R300_ZB_STENCILREFMASK 0x4f08 +# define R300_STENCILREF_SHIFT 0 +# define R300_STENCILREF_MASK 0x000000ff +# define R300_STENCILMASK_SHIFT 8 +# define R300_STENCILMASK_MASK 0x0000ff00 +# define R300_STENCILWRITEMASK_SHIFT 16 +# define R300_STENCILWRITEMASK_MASK 0x00ff0000 /* gap */ -#define ZB_FORMAT 0x4f10 -# define ZB_FORMAR_DEPTHFORMAT_16BIT_INT_Z (0 << 0) -# define ZB_FORMAR_DEPTHFORMAT_16BIT_13E3 (1 << 0) -# define ZB_FORMAR_DEPTHFORMAT_24BIT_INT_Z (2 << 0) +#define R300_ZB_FORMAT 0x4f10 +# define R300_DEPTHFORMAT_16BIT_INT_Z (0 << 0) +# define R300_DEPTHFORMAT_16BIT_13E3 (1 << 0) +# define R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL (2 << 0) /* reserved up to (15 << 0) */ -# define ZB_FORMAR_INVERT_13E3_LEADING_ONES (0 << 4) -# define ZB_FORMAR_INVERT_13E3_LEADING_ZEROS (1 << 4) -# define ZB_FORMAR_PEQ8_UNUSED (1 << 5) +# define R300_INVERT_13E3_LEADING_ONES (0 << 4) +# define R300_INVERT_13E3_LEADING_ZEROS (1 << 4) -#define R300_RB3D_EARLY_Z 0x4F14 -# define R300_EARLY_Z_DISABLE (0 << 0) -# define R300_EARLY_Z_ENABLE (1 << 0) +#define R300_ZB_ZTOP 0x4F14 +# define R300_ZTOP_DISABLE (0 << 0) +# define R300_ZTOP_ENABLE (1 << 0) /* gap */ -#define ZB_ZCACHE_CTLSTAT 0x4f18 -# define ZB_ZCACHE_CTLSTAT_ZC_FLUSH_NO_EFFECT (0 << 0) -# define ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE (1 << 0) -# define ZB_ZCACHE_CTLSTAT_ZC_FREE_NO_EFFECT (0 << 1) -# define ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE (1 << 1) -# define ZB_ZCACHE_CTLSTAT_ZC_BUSY_IDLE (0 << 31) -# define ZB_ZCACHE_CTLSTAT_ZC_BUSY_BUSY (1 << 31) +#define R300_ZB_ZCACHE_CTLSTAT 0x4f18 +# define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_NO_EFFECT (0 << 0) +# define R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE (1 << 0) +# define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_NO_EFFECT (0 << 1) +# define R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE (1 << 1) +# define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_IDLE (0 << 31) +# define R300_ZB_ZCACHE_CTLSTAT_ZC_BUSY_BUSY (1 << 31) #define R300_ZB_BW_CNTL 0x4f1c # define R300_HIZ_DISABLE (0 << 0) @@ -2289,31 +2372,32 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_ZB_CB_CLEAR_CACHE_LINEAR (1 << 5) # define R300_FORCE_COMPRESSED_STENCIL_VALUE_DISABLE (0 << 6) # define R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE (1 << 6) -# define R300_ZEQUAL_OPTIMIZE_ENABLE (0 << 7) -# define R300_ZEQUAL_OPTIMIZE_DISABLE (1 << 7) -# define R300_SEQUAL_OPTIMIZE_ENABLE (0 << 8) -# define R300_SEQUAL_OPTIMIZE_DISABLE (1 << 8) -/* gap in AMD docs */ -# define R300_BMASK_ENABLE (0 << 10) -# define R300_BMASK_DISABLE (1 << 10) -# define R300_HIZ_EQUAL_REJECT_DISABLE (0 << 11) -# define R300_HIZ_EQUAL_REJECT_ENABLE (1 << 11) -# define R300_HIZ_FP_EXP_BITS_DISABLE (0 << 12) -# define R300_HIZ_FP_EXP_BITS_1 (1 << 12) -# define R300_HIZ_FP_EXP_BITS_2 (2 << 12) -# define R300_HIZ_FP_EXP_BITS_3 (3 << 12) -# define R300_HIZ_FP_EXP_BITS_4 (4 << 12) -# define R300_HIZ_FP_EXP_BITS_5 (5 << 12) -# define R300_HIZ_FP_INVERT_LEADING_ONES (0 << 15) -# define R300_HIZ_FP_INVERT_LEADING_ZEROS (1 << 15) -# define R300_TILE_OVERWRITE_RECOMPRESSION_ENABLE (0 << 16) -# define R300_TILE_OVERWRITE_RECOMPRESSION_DISABLE (1 << 16) -# define R300_CONTIGUOUS_6XAA_SAMPLES_ENABLE (0 << 17) -# define R300_CONTIGUOUS_6XAA_SAMPLES_DISABLE (1 << 17) -# define R300_PEQ_PACKING_DISABLE (0 << 18) -# define R300_PEQ_PACKING_ENABLE (1 << 18) -# define R300_COVERED_PTR_MASKING_DISABLE (0 << 18) -# define R300_COVERED_PTR_MASKING_ENABLE (1 << 18) + +# define R500_ZEQUAL_OPTIMIZE_ENABLE (0 << 7) +# define R500_ZEQUAL_OPTIMIZE_DISABLE (1 << 7) +# define R500_SEQUAL_OPTIMIZE_ENABLE (0 << 8) +# define R500_SEQUAL_OPTIMIZE_DISABLE (1 << 8) + +# define R500_BMASK_ENABLE (0 << 10) +# define R500_BMASK_DISABLE (1 << 10) +# define R500_HIZ_EQUAL_REJECT_DISABLE (0 << 11) +# define R500_HIZ_EQUAL_REJECT_ENABLE (1 << 11) +# define R500_HIZ_FP_EXP_BITS_DISABLE (0 << 12) +# define R500_HIZ_FP_EXP_BITS_1 (1 << 12) +# define R500_HIZ_FP_EXP_BITS_2 (2 << 12) +# define R500_HIZ_FP_EXP_BITS_3 (3 << 12) +# define R500_HIZ_FP_EXP_BITS_4 (4 << 12) +# define R500_HIZ_FP_EXP_BITS_5 (5 << 12) +# define R500_HIZ_FP_INVERT_LEADING_ONES (0 << 15) +# define R500_HIZ_FP_INVERT_LEADING_ZEROS (1 << 15) +# define R500_TILE_OVERWRITE_RECOMPRESSION_ENABLE (0 << 16) +# define R500_TILE_OVERWRITE_RECOMPRESSION_DISABLE (1 << 16) +# define R500_CONTIGUOUS_6XAA_SAMPLES_ENABLE (0 << 17) +# define R500_CONTIGUOUS_6XAA_SAMPLES_DISABLE (1 << 17) +# define R500_PEQ_PACKING_DISABLE (0 << 18) +# define R500_PEQ_PACKING_ENABLE (1 << 18) +# define R500_COVERED_PTR_MASKING_DISABLE (0 << 18) +# define R500_COVERED_PTR_MASKING_ENABLE (1 << 18) /* gap */ @@ -2321,67 +2405,68 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* Z Buffer Address Offset. * Bits 31 to 5 are used for aligned Z buffer address offset for macro tiles. */ -#define ZB_DEPTHOFFSET 0x4f20 +#define R300_ZB_DEPTHOFFSET 0x4f20 /* Z Buffer Pitch and Endian Control */ -#define ZB_DEPTHPITCH 0x4f24 -# define R300_DEPTHPITCH_MASK 0x00001FF8 /* TODO: should be (13:2) */ -# define ZB_DEPTHPITCH_DEPTHMACROTILE_DISABLE (0 << 16) -# define ZB_DEPTHPITCH_DEPTHMACROTILE_ENABLE (1 << 16) -# define ZB_DEPTHPITCH_DEPTHMICROTILE_LINEAR (0 << 17) -# define ZB_DEPTHPITCH_DEPTHMICROTILE_TILED (1 << 17) -# define ZB_DEPTHPITCH_DEPTHMICROTILE_TILED_SQUARE (2 << 17) -# define ZB_DEPTHPITCH_DEPTHENDIAN_NO_SWAP (0 << 18) -# define ZB_DEPTHPITCH_DEPTHENDIAN_WORD_SWAP (1 << 18) -# define ZB_DEPTHPITCH_DEPTHENDIAN_DWORD_SWAP (2 << 18) -# define ZB_DEPTHPITCH_DEPTHENDIAN_HALF_DWORD_SWAP (3 << 18) +#define R300_ZB_DEPTHPITCH 0x4f24 +# define R300_DEPTHPITCH_MASK 0x00003FFC +# define R300_DEPTHMACROTILE_DISABLE (0 << 16) +# define R300_DEPTHMACROTILE_ENABLE (1 << 16) +# define R300_DEPTHMICROTILE_LINEAR (0 << 17) +# define R300_DEPTHMICROTILE_TILED (1 << 17) +# define R300_DEPTHMICROTILE_TILED_SQUARE (2 << 17) +# define R300_DEPTHENDIAN_NO_SWAP (0 << 18) +# define R300_DEPTHENDIAN_WORD_SWAP (1 << 18) +# define R300_DEPTHENDIAN_DWORD_SWAP (2 << 18) +# define R300_DEPTHENDIAN_HALF_DWORD_SWAP (3 << 18) /* Z Buffer Clear Value */ -#define ZB_DEPTHCLEARVALUE 0x4f28 +#define R300_ZB_DEPTHCLEARVALUE 0x4f28 /* Hierarchical Z Memory Offset */ -#define ZB_HIZ_OFFSET 0x4f44 +#define R300_ZB_HIZ_OFFSET 0x4f44 -/* Hierarchical Z Read Index */ -#define ZB_HIZ_RDINDEX 0x4f48 +/* Hierarchical Z Write Index */ +#define R300_ZB_HIZ_WRINDEX 0x4f48 /* Hierarchical Z Data */ -#define ZB_HIZ_DWORD 0x4f4c +#define R300_ZB_HIZ_DWORD 0x4f4c -/* Hierarchical Z Write Index */ -#define ZB_HIZ_WRINDEX 0x4f50 +/* Hierarchical Z Read Index */ +#define R300_ZB_HIZ_RDINDEX 0x4f50 /* Hierarchical Z Pitch */ -#define ZB_HIZ_PITCH 0x4f54 +#define R300_ZB_HIZ_PITCH 0x4f54 /* Z Buffer Z Pass Counter Data */ -#define ZB_ZPASS_DATA 0x4f58 +#define R300_ZB_ZPASS_DATA 0x4f58 /* Z Buffer Z Pass Counter Address */ -#define ZB_ZPASS_ADDR 0x4f5c +#define R300_ZB_ZPASS_ADDR 0x4f5c /* Depth buffer X and Y coordinate offset */ -#define ZB_DEPTHXY_OFFSET 0x4f60 -# define ZB_DEPTHX_OFFSET_SHIFT 1 -# define ZB_DEPTHX_OFFSET_MASK 0x000007FE -# define ZB_DEPTHY_OFFSET_SHIFT 17 -# define ZB_DEPTHY_OFFSET_MASK 0x07FE0000 +#define R300_ZB_DEPTHXY_OFFSET 0x4f60 +# define R300_DEPTHX_OFFSET_SHIFT 1 +# define R300_DEPTHX_OFFSET_MASK 0x000007FE +# define R300_DEPTHY_OFFSET_SHIFT 17 +# define R300_DEPTHY_OFFSET_MASK 0x07FE0000 /* Sets the fifo sizes */ -#define ZB_FIFO_SIZE 0x4fd0 -# define ZB_FIFO_SIZE_OP_FIFO_SIZE_FULL (0 << 0) -# define ZB_FIFO_SIZE_OP_FIFO_SIZE_HALF (1 << 0) -# define ZB_FIFO_SIZE_OP_FIFO_SIZE_QUATER (2 << 0) -# define ZB_FIFO_SIZE_OP_FIFO_SIZE_EIGTHS (4 << 0) +#define R500_ZB_FIFO_SIZE 0x4fd0 +# define R500_OP_FIFO_SIZE_FULL (0 << 0) +# define R500_OP_FIFO_SIZE_HALF (1 << 0) +# define R500_OP_FIFO_SIZE_QUATER (2 << 0) +# define R500_OP_FIFO_SIZE_EIGTHS (4 << 0) /* Stencil Reference Value and Mask for backfacing quads */ -#define ZB_STENCILREFMASK_BF 0x4fd4 -# define ZB_STENCILREFMASK_BF_STENCILREF_SHIFT 0 -# define ZB_STENCILREFMASK_BF_STENCILREF_MASK 0x000000ff -# define ZB_STENCILREFMASK_BF_STENCILMASK_SHIFT 8 -# define ZB_STENCILREFMASK_BF_STENCILMASK_MASK 0x0000ff00 -# define ZB_STENCILREFMASK_BF_STENCILWRITEMASK_SHIFT 16 -# define ZB_STENCILREFMASK_BF_STENCILWRITEMASK_MASK 0xffff0000 +/* R300_ZB_STENCILREFMASK handles front face */ +#define R500_ZB_STENCILREFMASK_BF 0x4fd4 +# define R500_STENCILREF_SHIFT 0 +# define R500_STENCILREF_MASK 0x000000ff +# define R500_STENCILMASK_SHIFT 8 +# define R500_STENCILMASK_MASK 0x0000ff00 +# define R500_STENCILWRITEMASK_SHIFT 16 +# define R500_STENCILWRITEMASK_MASK 0x00ff0000 /** * \defgroup R3XX_R5XX_PROGRAMMABLE_VERTEX_SHADER_DESCRIPTION R3XX-R5XX PROGRAMMABLE VERTEX SHADER DESCRIPTION @@ -2598,6 +2683,479 @@ enum { #define R300_PRIM_NUM_VERTICES_SHIFT 16 #define R300_PRIM_NUM_VERTICES_MASK 0xffff + + +/* + * The R500 unified shader (US) registers come in banks of 512 each, one + * for each instruction slot in the shader. You can't touch them directly. + * R500_US_VECTOR_INDEX() sets the base instruction to modify; successive + * writes to R500_GA_US_VECTOR_DATA autoincrement the index after the + * instruction is fully specified. + */ +#define R500_US_ALU_ALPHA_INST_0 0xa800 +# define R500_ALPHA_OP_MAD 0 +# define R500_ALPHA_OP_DP 1 +# define R500_ALPHA_OP_MIN 2 +# define R500_ALPHA_OP_MAX 3 +/* #define R500_ALPHA_OP_RESERVED 4 */ +# define R500_ALPHA_OP_CND 5 +# define R500_ALPHA_OP_CMP 6 +# define R500_ALPHA_OP_FRC 7 +# define R500_ALPHA_OP_EX2 8 +# define R500_ALPHA_OP_LN2 9 +# define R500_ALPHA_OP_RCP 10 +# define R500_ALPHA_OP_RSQ 11 +# define R500_ALPHA_OP_SIN 12 +# define R500_ALPHA_OP_COS 13 +# define R500_ALPHA_OP_MDH 14 +# define R500_ALPHA_OP_MDV 15 +# define R500_ALPHA_ADDRD(x) (x << 4) +# define R500_ALPHA_ADDRD_REL (1 << 11) +# define R500_ALPHA_SEL_A_SRC0 (0 << 12) +# define R500_ALPHA_SEL_A_SRC1 (1 << 12) +# define R500_ALPHA_SEL_A_SRC2 (2 << 12) +# define R500_ALPHA_SEL_A_SRCP (3 << 12) +# define R500_ALPHA_SWIZ_A_R (0 << 14) +# define R500_ALPHA_SWIZ_A_G (1 << 14) +# define R500_ALPHA_SWIZ_A_B (2 << 14) +# define R500_ALPHA_SWIZ_A_A (3 << 14) +# define R500_ALPHA_SWIZ_A_0 (4 << 14) +# define R500_ALPHA_SWIZ_A_HALF (5 << 14) +# define R500_ALPHA_SWIZ_A_1 (6 << 14) +/* #define R500_ALPHA_SWIZ_A_UNUSED (7 << 14) */ +# define R500_ALPHA_MOD_A_NOP (0 << 17) +# define R500_ALPHA_MOD_A_NEG (1 << 17) +# define R500_ALPHA_MOD_A_ABS (2 << 17) +# define R500_ALPHA_MOD_A_NAB (3 << 17) +# define R500_ALPHA_SEL_B_SRC0 (0 << 19) +# define R500_ALPHA_SEL_B_SRC1 (1 << 19) +# define R500_ALPHA_SEL_B_SRC2 (2 << 19) +# define R500_ALPHA_SEL_B_SRCP (3 << 19) +# define R500_ALPHA_SWIZ_B_R (0 << 21) +# define R500_ALPHA_SWIZ_B_G (1 << 21) +# define R500_ALPHA_SWIZ_B_B (2 << 21) +# define R500_ALPHA_SWIZ_B_A (3 << 21) +# define R500_ALPHA_SWIZ_B_0 (4 << 21) +# define R500_ALPHA_SWIZ_B_HALF (5 << 21) +# define R500_ALPHA_SWIZ_B_1 (6 << 21) +/* #define R500_ALPHA_SWIZ_B_UNUSED (7 << 21) */ +# define R500_ALPHA_MOD_B_NOP (0 << 24) +# define R500_ALPHA_MOD_B_NEG (1 << 24) +# define R500_ALPHA_MOD_B_ABS (2 << 24) +# define R500_ALPHA_MOD_B_NAB (3 << 24) +# define R500_ALPHA_OMOD_IDENTITY (0 << 26) +# define R500_ALPHA_OMOD_MUL_2 (1 << 26) +# define R500_ALPHA_OMOD_MUL_4 (2 << 26) +# define R500_ALPHA_OMOD_MUL_8 (3 << 26) +# define R500_ALPHA_OMOD_DIV_2 (4 << 26) +# define R500_ALPHA_OMOD_DIV_4 (5 << 26) +# define R500_ALPHA_OMOD_DIV_8 (6 << 26) +# define R500_ALPHA_OMOD_DISABLE (7 << 26) +# define R500_ALPHA_TARGET(x) (x << 29) +# define R500_ALPHA_W_OMASK (1 << 31) +#define R500_US_ALU_ALPHA_ADDR_0 0x9800 +# define R500_ALPHA_ADDR0(x) (x << 0) +# define R500_ALPHA_ADDR0_CONST (1 << 8) +# define R500_ALPHA_ADDR0_REL (1 << 9) +# define R500_ALPHA_ADDR1(x) (x << 10) +# define R500_ALPHA_ADDR1_CONST (1 << 18) +# define R500_ALPHA_ADDR1_REL (1 << 19) +# define R500_ALPHA_ADDR2(x) (x << 20) +# define R500_ALPHA_ADDR2_CONST (1 << 28) +# define R500_ALPHA_ADDR2_REL (1 << 29) +# define R500_ALPHA_SRCP_OP_1_MINUS_2A0 (0 << 30) +# define R500_ALPHA_SRCP_OP_A1_MINUS_A0 (1 << 30) +# define R500_ALPHA_SRCP_OP_A1_PLUS_A0 (2 << 30) +# define R500_ALPHA_SRCP_OP_1_MINUS_A0 (3 << 30) +#define R500_US_ALU_RGBA_INST_0 0xb000 +# define R500_ALU_RGBA_OP_MAD (0 << 0) +# define R500_ALU_RGBA_OP_DP3 (1 << 0) +# define R500_ALU_RGBA_OP_DP4 (2 << 0) +# define R500_ALU_RGBA_OP_D2A (3 << 0) +# define R500_ALU_RGBA_OP_MIN (4 << 0) +# define R500_ALU_RGBA_OP_MAX (5 << 0) +/* #define R500_ALU_RGBA_OP_RESERVED (6 << 0) */ +# define R500_ALU_RGBA_OP_CND (7 << 0) +# define R500_ALU_RGBA_OP_CMP (8 << 0) +# define R500_ALU_RGBA_OP_FRC (9 << 0) +# define R500_ALU_RGBA_OP_SOP (10 << 0) +# define R500_ALU_RGBA_OP_MDH (11 << 0) +# define R500_ALU_RGBA_OP_MDV (12 << 0) +# define R500_ALU_RGBA_ADDRD(x) (x << 4) +# define R500_ALU_RGBA_ADDRD_REL (1 << 11) +# define R500_ALU_RGBA_SEL_C_SRC0 (0 << 12) +# define R500_ALU_RGBA_SEL_C_SRC1 (1 << 12) +# define R500_ALU_RGBA_SEL_C_SRC2 (2 << 12) +# define R500_ALU_RGBA_SEL_C_SRCP (3 << 12) +# define R500_ALU_RGBA_R_SWIZ_R (0 << 14) +# define R500_ALU_RGBA_R_SWIZ_G (1 << 14) +# define R500_ALU_RGBA_R_SWIZ_B (2 << 14) +# define R500_ALU_RGBA_R_SWIZ_A (3 << 14) +# define R500_ALU_RGBA_R_SWIZ_0 (4 << 14) +# define R500_ALU_RGBA_R_SWIZ_HALF (5 << 14) +# define R500_ALU_RGBA_R_SWIZ_1 (6 << 14) +/* #define R500_ALU_RGBA_R_SWIZ_UNUSED (7 << 14) */ +# define R500_ALU_RGBA_G_SWIZ_R (0 << 17) +# define R500_ALU_RGBA_G_SWIZ_G (1 << 17) +# define R500_ALU_RGBA_G_SWIZ_B (2 << 17) +# define R500_ALU_RGBA_G_SWIZ_A (3 << 17) +# define R500_ALU_RGBA_G_SWIZ_0 (4 << 17) +# define R500_ALU_RGBA_G_SWIZ_HALF (5 << 17) +# define R500_ALU_RGBA_G_SWIZ_1 (6 << 17) +/* #define R500_ALU_RGBA_G_SWIZ_UNUSED (7 << 17) */ +# define R500_ALU_RGBA_B_SWIZ_R (0 << 20) +# define R500_ALU_RGBA_B_SWIZ_G (1 << 20) +# define R500_ALU_RGBA_B_SWIZ_B (2 << 20) +# define R500_ALU_RGBA_B_SWIZ_A (3 << 20) +# define R500_ALU_RGBA_B_SWIZ_0 (4 << 20) +# define R500_ALU_RGBA_B_SWIZ_HALF (5 << 20) +# define R500_ALU_RGBA_B_SWIZ_1 (6 << 20) +/* #define R500_ALU_RGBA_B_SWIZ_UNUSED (7 << 20) */ +# define R500_ALU_RGBA_MOD_C_NOP (0 << 23) +# define R500_ALU_RGBA_MOD_C_NEG (1 << 23) +# define R500_ALU_RGBA_MOD_C_ABS (2 << 23) +# define R500_ALU_RGBA_MOD_C_NAB (3 << 23) +# define R500_ALU_RGBA_ALPHA_SEL_C_SRC0 (0 << 25) +# define R500_ALU_RGBA_ALPHA_SEL_C_SRC1 (1 << 25) +# define R500_ALU_RGBA_ALPHA_SEL_C_SRC2 (2 << 25) +# define R500_ALU_RGBA_ALPHA_SEL_C_SRCP (3 << 25) +# define R500_ALU_RGBA_A_SWIZ_R (0 << 27) +# define R500_ALU_RGBA_A_SWIZ_G (1 << 27) +# define R500_ALU_RGBA_A_SWIZ_B (2 << 27) +# define R500_ALU_RGBA_A_SWIZ_A (3 << 27) +# define R500_ALU_RGBA_A_SWIZ_0 (4 << 27) +# define R500_ALU_RGBA_A_SWIZ_HALF (5 << 27) +# define R500_ALU_RGBA_A_SWIZ_1 (6 << 27) +/* #define R500_ALU_RGBA_A_SWIZ_UNUSED (7 << 27) */ +# define R500_ALU_RGBA_ALPHA_MOD_C_NOP (0 << 30) +# define R500_ALU_RGBA_ALPHA_MOD_C_NEG (1 << 30) +# define R500_ALU_RGBA_ALPHA_MOD_C_ABS (2 << 30) +# define R500_ALU_RGBA_ALPHA_MOD_C_NAB (3 << 30) +#define R500_US_ALU_RGB_INST_0 0xa000 +# define R500_ALU_RGB_SEL_A_SRC0 (0 << 0) +# define R500_ALU_RGB_SEL_A_SRC1 (1 << 0) +# define R500_ALU_RGB_SEL_A_SRC2 (2 << 0) +# define R500_ALU_RGB_SEL_A_SRCP (3 << 0) +# define R500_ALU_RGB_R_SWIZ_A_R (0 << 2) +# define R500_ALU_RGB_R_SWIZ_A_G (1 << 2) +# define R500_ALU_RGB_R_SWIZ_A_B (2 << 2) +# define R500_ALU_RGB_R_SWIZ_A_A (3 << 2) +# define R500_ALU_RGB_R_SWIZ_A_0 (4 << 2) +# define R500_ALU_RGB_R_SWIZ_A_HALF (5 << 2) +# define R500_ALU_RGB_R_SWIZ_A_1 (6 << 2) +/* #define R500_ALU_RGB_R_SWIZ_A_UNUSED (7 << 2) */ +# define R500_ALU_RGB_G_SWIZ_A_R (0 << 5) +# define R500_ALU_RGB_G_SWIZ_A_G (1 << 5) +# define R500_ALU_RGB_G_SWIZ_A_B (2 << 5) +# define R500_ALU_RGB_G_SWIZ_A_A (3 << 5) +# define R500_ALU_RGB_G_SWIZ_A_0 (4 << 5) +# define R500_ALU_RGB_G_SWIZ_A_HALF (5 << 5) +# define R500_ALU_RGB_G_SWIZ_A_1 (6 << 5) +/* #define R500_ALU_RGB_G_SWIZ_A_UNUSED (7 << 5) */ +# define R500_ALU_RGB_B_SWIZ_A_R (0 << 8) +# define R500_ALU_RGB_B_SWIZ_A_G (1 << 8) +# define R500_ALU_RGB_B_SWIZ_A_B (2 << 8) +# define R500_ALU_RGB_B_SWIZ_A_A (3 << 8) +# define R500_ALU_RGB_B_SWIZ_A_0 (4 << 8) +# define R500_ALU_RGB_B_SWIZ_A_HALF (5 << 8) +# define R500_ALU_RGB_B_SWIZ_A_1 (6 << 8) +/* #define R500_ALU_RGB_B_SWIZ_A_UNUSED (7 << 8) */ +# define R500_ALU_RGB_MOD_A_NOP (0 << 11) +# define R500_ALU_RGB_MOD_A_NEG (1 << 11) +# define R500_ALU_RGB_MOD_A_ABS (2 << 11) +# define R500_ALU_RGB_MOD_A_NAB (3 << 11) +# define R500_ALU_RGB_SEL_B_SRC0 (0 << 13) +# define R500_ALU_RGB_SEL_B_SRC1 (1 << 13) +# define R500_ALU_RGB_SEL_B_SRC2 (2 << 13) +# define R500_ALU_RGB_SEL_B_SRCP (3 << 13) +# define R500_ALU_RGB_R_SWIZ_B_R (0 << 15) +# define R500_ALU_RGB_R_SWIZ_B_G (1 << 15) +# define R500_ALU_RGB_R_SWIZ_B_B (2 << 15) +# define R500_ALU_RGB_R_SWIZ_B_A (3 << 15) +# define R500_ALU_RGB_R_SWIZ_B_0 (4 << 15) +# define R500_ALU_RGB_R_SWIZ_B_HALF (5 << 15) +# define R500_ALU_RGB_R_SWIZ_B_1 (6 << 15) +/* #define R500_ALU_RGB_R_SWIZ_B_UNUSED (7 << 15) */ +# define R500_ALU_RGB_G_SWIZ_B_R (0 << 18) +# define R500_ALU_RGB_G_SWIZ_B_G (1 << 18) +# define R500_ALU_RGB_G_SWIZ_B_B (2 << 18) +# define R500_ALU_RGB_G_SWIZ_B_A (3 << 18) +# define R500_ALU_RGB_G_SWIZ_B_0 (4 << 18) +# define R500_ALU_RGB_G_SWIZ_B_HALF (5 << 18) +# define R500_ALU_RGB_G_SWIZ_B_1 (6 << 18) +/* #define R500_ALU_RGB_G_SWIZ_B_UNUSED (7 << 18) */ +# define R500_ALU_RGB_B_SWIZ_B_R (0 << 21) +# define R500_ALU_RGB_B_SWIZ_B_G (1 << 21) +# define R500_ALU_RGB_B_SWIZ_B_B (2 << 21) +# define R500_ALU_RGB_B_SWIZ_B_A (3 << 21) +# define R500_ALU_RGB_B_SWIZ_B_0 (4 << 21) +# define R500_ALU_RGB_B_SWIZ_B_HALF (5 << 21) +# define R500_ALU_RGB_B_SWIZ_B_1 (6 << 21) +/* #define R500_ALU_RGB_B_SWIZ_B_UNUSED (7 << 21) */ +# define R500_ALU_RGB_MOD_B_NOP (0 << 24) +# define R500_ALU_RGB_MOD_B_NEG (1 << 24) +# define R500_ALU_RGB_MOD_B_ABS (2 << 24) +# define R500_ALU_RGB_MOD_B_NAB (3 << 24) +# define R500_ALU_RGB_OMOD_IDENTITY (0 << 26) +# define R500_ALU_RGB_OMOD_MUL_2 (1 << 26) +# define R500_ALU_RGB_OMOD_MUL_4 (2 << 26) +# define R500_ALU_RGB_OMOD_MUL_8 (3 << 26) +# define R500_ALU_RGB_OMOD_DIV_2 (4 << 26) +# define R500_ALU_RGB_OMOD_DIV_4 (5 << 26) +# define R500_ALU_RGB_OMOD_DIV_8 (6 << 26) +# define R500_ALU_RGB_OMOD_DISABLE (7 << 26) +# define R500_ALU_RGB_TARGET(x) (x << 29) +# define R500_ALU_RGB_WMASK (1 << 31) +#define R500_US_ALU_RGB_ADDR_0 0x9000 +# define R500_RGB_ADDR0(x) (x << 0) +# define R500_RGB_ADDR0_CONST (1 << 8) +# define R500_RGB_ADDR0_REL (1 << 9) +# define R500_RGB_ADDR1(x) (x << 10) +# define R500_RGB_ADDR1_CONST (1 << 18) +# define R500_RGB_ADDR1_REL (1 << 19) +# define R500_RGB_ADDR2(x) (x << 20) +# define R500_RGB_ADDR2_CONST (1 << 28) +# define R500_RGB_ADDR2_REL (1 << 29) +# define R500_RGB_SRCP_OP_1_MINUS_2RGB0 (0 << 30) +# define R500_RGB_SRCP_OP_RGB1_MINUS_RGB0 (1 << 30) +# define R500_RGB_SRCP_OP_RGB1_PLUS_RGB0 (2 << 30) +# define R500_RGB_SRCP_OP_1_MINUS_RGB0 (3 << 30) +#define R500_US_CMN_INST_0 0xb800 +# define R500_INST_TYPE_ALU (0 << 0) +# define R500_INST_TYPE_OUT (1 << 0) +# define R500_INST_TYPE_FC (2 << 0) +# define R500_INST_TYPE_TEX (3 << 0) +# define R500_INST_TEX_SEM_WAIT (1 << 2) +# define R500_INST_RGB_PRED_SEL_NONE (0 << 3) +# define R500_INST_RGB_PRED_SEL_RGBA (1 << 3) +# define R500_INST_RGB_PRED_SEL_RRRR (2 << 3) +# define R500_INST_RGB_PRED_SEL_GGGG (3 << 3) +# define R500_INST_RGB_PRED_SEL_BBBB (4 << 3) +# define R500_INST_RGB_PRED_SEL_AAAA (5 << 3) +# define R500_INST_RGB_PRED_INV (1 << 6) +# define R500_INST_WRITE_INACTIVE (1 << 7) +# define R500_INST_LAST (1 << 8) +# define R500_INST_NOP (1 << 9) +# define R500_INST_ALU_WAIT (1 << 10) +# define R500_INST_RGB_WMASK_R (1 << 11) +# define R500_INST_RGB_WMASK_G (1 << 12) +# define R500_INST_RGB_WMASK_B (1 << 13) +# define R500_INST_ALPHA_WMASK (1 << 14) +# define R500_INST_RGB_OMASK_R (1 << 15) +# define R500_INST_RGB_OMASK_G (1 << 16) +# define R500_INST_RGB_OMASK_B (1 << 17) +# define R500_INST_ALPHA_OMASK (1 << 18) +# define R500_INST_RGB_CLAMP (1 << 19) +# define R500_INST_ALPHA_CLAMP (1 << 20) +# define R500_INST_ALU_RESULT_SEL (1 << 21) +# define R500_INST_ALPHA_PRED_INV (1 << 22) +# define R500_INST_ALU_RESULT_OP_EQ (0 << 23) +# define R500_INST_ALU_RESULT_OP_LT (1 << 23) +# define R500_INST_ALU_RESULT_OP_GE (2 << 23) +# define R500_INST_ALU_RESULT_OP_NE (3 << 23) +# define R500_INST_ALPHA_PRED_SEL_NONE (0 << 25) +# define R500_INST_ALPHA_PRED_SEL_RGBA (1 << 25) +# define R500_INST_ALPHA_PRED_SEL_RRRR (2 << 25) +# define R500_INST_ALPHA_PRED_SEL_GGGG (3 << 25) +# define R500_INST_ALPHA_PRED_SEL_BBBB (4 << 25) +# define R500_INST_ALPHA_PRED_SEL_AAAA (5 << 25) +/* XXX next four are kind of guessed */ +# define R500_INST_STAT_WE_R (1 << 28) +# define R500_INST_STAT_WE_G (1 << 29) +# define R500_INST_STAT_WE_B (1 << 30) +# define R500_INST_STAT_WE_A (1 << 31) + +/* note that these are 8 bit lengths, despite the offsets, at least for R500 */ +#define R500_US_CODE_ADDR 0x4630 +# define R500_US_CODE_START_ADDR(x) (x << 0) +# define R500_US_CODE_END_ADDR(x) (x << 16) +#define R500_US_CODE_OFFSET 0x4638 +# define R500_US_CODE_OFFSET_ADDR(x) (x << 0) +#define R500_US_CODE_RANGE 0x4634 +# define R500_US_CODE_RANGE_ADDR(x) (x << 0) +# define R500_US_CODE_RANGE_SIZE(x) (x << 16) +#define R500_US_CONFIG 0x4600 +# define R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO (1 << 1) +#define R500_US_FC_ADDR_0 0xa000 +# define R500_FC_BOOL_ADDR(x) (x << 0) +# define R500_FC_INT_ADDR(x) (x << 8) +# define R500_FC_JUMP_ADDR(x) (x << 16) +# define R500_FC_JUMP_GLOBAL (1 << 31) +#define R500_US_FC_BOOL_CONST 0x4620 +# define R500_FC_KBOOL(x) (x) +#define R500_US_FC_CTRL 0x4624 +# define R500_FC_TEST_EN (1 << 30) +# define R500_FC_FULL_FC_EN (1 << 31) +#define R500_US_FC_INST_0 0x9800 +# define R500_FC_OP_JUMP (0 << 0) +# define R500_FC_OP_LOOP (1 << 0) +# define R500_FC_OP_ENDLOOP (2 << 0) +# define R500_FC_OP_REP (3 << 0) +# define R500_FC_OP_ENDREP (4 << 0) +# define R500_FC_OP_BREAKLOOP (5 << 0) +# define R500_FC_OP_BREAKREP (6 << 0) +# define R500_FC_OP_CONTINUE (7 << 0) +# define R500_FC_B_ELSE (1 << 4) +# define R500_FC_JUMP_ANY (1 << 5) +# define R500_FC_A_OP_NONE (0 << 6) +# define R500_FC_A_OP_POP (1 << 6) +# define R500_FC_A_OP_PUSH (2 << 6) +# define R500_FC_JUMP_FUNC(x) (x << 8) +# define R500_FC_B_POP_CNT(x) (x << 16) +# define R500_FC_B_OP0_NONE (0 << 24) +# define R500_FC_B_OP0_DECR (1 << 24) +# define R500_FC_B_OP0_INCR (2 << 24) +# define R500_FC_B_OP1_DECR (0 << 26) +# define R500_FC_B_OP1_NONE (1 << 26) +# define R500_FC_B_OP1_INCR (2 << 26) +# define R500_FC_IGNORE_UNCOVERED (1 << 28) +#define R500_US_FC_INT_CONST_0 0x4c00 +# define R500_FC_INT_CONST_KR(x) (x << 0) +# define R500_FC_INT_CONST_KG(x) (x << 8) +# define R500_FC_INT_CONST_KB(x) (x << 16) +/* _0 through _15 */ +#define R500_US_FORMAT0_0 0x4640 +# define R500_FORMAT_TXWIDTH(x) (x << 0) +# define R500_FORMAT_TXHEIGHT(x) (x << 11) +# define R500_FORMAT_TXDEPTH(x) (x << 22) +/* _0 through _3 */ +#define R500_US_OUT_FMT_0 0x46a4 +# define R500_OUT_FMT_C4_8 (0 << 0) +# define R500_OUT_FMT_C4_10 (1 << 0) +# define R500_OUT_FMT_C4_10_GAMMA (2 << 0) +# define R500_OUT_FMT_C_16 (3 << 0) +# define R500_OUT_FMT_C2_16 (4 << 0) +# define R500_OUT_FMT_C4_16 (5 << 0) +# define R500_OUT_FMT_C_16_MPEG (6 << 0) +# define R500_OUT_FMT_C2_16_MPEG (7 << 0) +# define R500_OUT_FMT_C2_4 (8 << 0) +# define R500_OUT_FMT_C_3_3_2 (9 << 0) +# define R500_OUT_FMT_C_6_5_6 (10 << 0) +# define R500_OUT_FMT_C_11_11_10 (11 << 0) +# define R500_OUT_FMT_C_10_11_11 (12 << 0) +# define R500_OUT_FMT_C_2_10_10_10 (13 << 0) +/* #define R500_OUT_FMT_RESERVED (14 << 0) */ +# define R500_OUT_FMT_UNUSED (15 << 0) +# define R500_OUT_FMT_C_16_FP (16 << 0) +# define R500_OUT_FMT_C2_16_FP (17 << 0) +# define R500_OUT_FMT_C4_16_FP (18 << 0) +# define R500_OUT_FMT_C_32_FP (19 << 0) +# define R500_OUT_FMT_C2_32_FP (20 << 0) +# define R500_OUT_FMT_C4_32_FP (21 << 0) +# define R500_C0_SEL_A (0 << 8) +# define R500_C0_SEL_R (1 << 8) +# define R500_C0_SEL_G (2 << 8) +# define R500_C0_SEL_B (3 << 8) +# define R500_C1_SEL_A (0 << 10) +# define R500_C1_SEL_R (1 << 10) +# define R500_C1_SEL_G (2 << 10) +# define R500_C1_SEL_B (3 << 10) +# define R500_C2_SEL_A (0 << 12) +# define R500_C2_SEL_R (1 << 12) +# define R500_C2_SEL_G (2 << 12) +# define R500_C2_SEL_B (3 << 12) +# define R500_C3_SEL_A (0 << 14) +# define R500_C3_SEL_R (1 << 14) +# define R500_C3_SEL_G (2 << 14) +# define R500_C3_SEL_B (3 << 14) +# define R500_OUT_SIGN(x) (x << 16) +# define R500_ROUND_ADJ (1 << 20) +#define R500_US_PIXSIZE 0x4604 +# define R500_PIX_SIZE(x) (x) +#define R500_US_TEX_ADDR_0 0x9800 +# define R500_TEX_SRC_ADDR(x) (x << 0) +# define R500_TEX_SRC_ADDR_REL (1 << 7) +# define R500_TEX_SRC_S_SWIZ_R (0 << 8) +# define R500_TEX_SRC_S_SWIZ_G (1 << 8) +# define R500_TEX_SRC_S_SWIZ_B (2 << 8) +# define R500_TEX_SRC_S_SWIZ_A (3 << 8) +# define R500_TEX_SRC_T_SWIZ_R (0 << 10) +# define R500_TEX_SRC_T_SWIZ_G (1 << 10) +# define R500_TEX_SRC_T_SWIZ_B (2 << 10) +# define R500_TEX_SRC_T_SWIZ_A (3 << 10) +# define R500_TEX_SRC_R_SWIZ_R (0 << 12) +# define R500_TEX_SRC_R_SWIZ_G (1 << 12) +# define R500_TEX_SRC_R_SWIZ_B (2 << 12) +# define R500_TEX_SRC_R_SWIZ_A (3 << 12) +# define R500_TEX_SRC_Q_SWIZ_R (0 << 14) +# define R500_TEX_SRC_Q_SWIZ_G (1 << 14) +# define R500_TEX_SRC_Q_SWIZ_B (2 << 14) +# define R500_TEX_SRC_Q_SWIZ_A (3 << 14) +# define R500_TEX_DST_ADDR(x) (x << 16) +# define R500_TEX_DST_ADDR_REL (1 << 23) +# define R500_TEX_DST_R_SWIZ_R (0 << 24) +# define R500_TEX_DST_R_SWIZ_G (1 << 24) +# define R500_TEX_DST_R_SWIZ_B (2 << 24) +# define R500_TEX_DST_R_SWIZ_A (3 << 24) +# define R500_TEX_DST_G_SWIZ_R (0 << 26) +# define R500_TEX_DST_G_SWIZ_G (1 << 26) +# define R500_TEX_DST_G_SWIZ_B (2 << 26) +# define R500_TEX_DST_G_SWIZ_A (3 << 26) +# define R500_TEX_DST_B_SWIZ_R (0 << 28) +# define R500_TEX_DST_B_SWIZ_G (1 << 28) +# define R500_TEX_DST_B_SWIZ_B (2 << 28) +# define R500_TEX_DST_B_SWIZ_A (3 << 28) +# define R500_TEX_DST_A_SWIZ_R (0 << 30) +# define R500_TEX_DST_A_SWIZ_G (1 << 30) +# define R500_TEX_DST_A_SWIZ_B (2 << 30) +# define R500_TEX_DST_A_SWIZ_A (3 << 30) +#define R500_US_TEX_ADDR_DXDY_0 0xa000 +# define R500_DX_ADDR(x) (x << 0) +# define R500_DX_ADDR_REL (1 << 7) +# define R500_DX_S_SWIZ_R (0 << 8) +# define R500_DX_S_SWIZ_G (1 << 8) +# define R500_DX_S_SWIZ_B (2 << 8) +# define R500_DX_S_SWIZ_A (3 << 8) +# define R500_DX_T_SWIZ_R (0 << 10) +# define R500_DX_T_SWIZ_G (1 << 10) +# define R500_DX_T_SWIZ_B (2 << 10) +# define R500_DX_T_SWIZ_A (3 << 10) +# define R500_DX_R_SWIZ_R (0 << 12) +# define R500_DX_R_SWIZ_G (1 << 12) +# define R500_DX_R_SWIZ_B (2 << 12) +# define R500_DX_R_SWIZ_A (3 << 12) +# define R500_DX_Q_SWIZ_R (0 << 14) +# define R500_DX_Q_SWIZ_G (1 << 14) +# define R500_DX_Q_SWIZ_B (2 << 14) +# define R500_DX_Q_SWIZ_A (3 << 14) +# define R500_DY_ADDR(x) (x << 16) +# define R500_DY_ADDR_REL (1 << 17) +# define R500_DY_S_SWIZ_R (0 << 24) +# define R500_DY_S_SWIZ_G (1 << 24) +# define R500_DY_S_SWIZ_B (2 << 24) +# define R500_DY_S_SWIZ_A (3 << 24) +# define R500_DY_T_SWIZ_R (0 << 26) +# define R500_DY_T_SWIZ_G (1 << 26) +# define R500_DY_T_SWIZ_B (2 << 26) +# define R500_DY_T_SWIZ_A (3 << 26) +# define R500_DY_R_SWIZ_R (0 << 28) +# define R500_DY_R_SWIZ_G (1 << 28) +# define R500_DY_R_SWIZ_B (2 << 28) +# define R500_DY_R_SWIZ_A (3 << 28) +# define R500_DY_Q_SWIZ_R (0 << 30) +# define R500_DY_Q_SWIZ_G (1 << 30) +# define R500_DY_Q_SWIZ_B (2 << 30) +# define R500_DY_Q_SWIZ_A (3 << 30) +#define R500_US_TEX_INST_0 0x9000 +# define R500_TEX_ID(x) (x << 16) +# define R500_TEX_INST_NOP (0 << 22) +# define R500_TEX_INST_LD (1 << 22) +# define R500_TEX_INST_TEXKILL (2 << 22) +# define R500_TEX_INST_PROJ (3 << 22) +# define R500_TEX_INST_LODBIAS (4 << 22) +# define R500_TEX_INST_LOD (5 << 22) +# define R500_TEX_INST_DXDY (6 << 22) +# define R500_TEX_SEM_ACQUIRE (1 << 25) +# define R500_TEX_IGNORE_UNCOVERED (1 << 26) +# define R500_TEX_UNSCALED (1 << 27) +#define R300_US_W_FMT 0x46b4 +# define R300_W_FMT_W0 (0 << 0) +# define R300_W_FMT_W24 (1 << 0) +# define R300_W_FMT_W24FP (2 << 0) +# define R300_W_SRC_US (0 << 2) +# define R300_W_SRC_RAS (1 << 2) + + /* Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR. * Two parameter dwords: * 0. VAP_VTX_FMT: The first parameter is not written to hardware diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index eee1e803a0..fc07105c56 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -334,13 +334,26 @@ static GLboolean r300RunRender(GLcontext * ctx, static int r300Fallback(GLcontext * ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); - struct r300_fragment_program *fp = (struct r300_fragment_program *) + /* Do we need to use new-style shaders? + * Also is there a better way to do this? */ + if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { + struct r500_fragment_program *fp = (struct r500_fragment_program *) (char *)ctx->FragmentProgram._Current; - - if (fp) { - if (!fp->translated) - r300TranslateFragmentShader(r300, fp); - FALLBACK_IF(!fp->translated); + if (fp) { + if (!fp->translated) { + r500TranslateFragmentShader(r300, fp); + FALLBACK_IF(!fp->translated); + } + } + } else { + struct r300_fragment_program *fp = (struct r300_fragment_program *) + (char *)ctx->FragmentProgram._Current; + if (fp) { + if (!fp->translated) { + r300TranslateFragmentShader(r300, fp); + FALLBACK_IF(!fp->translated); + } + } } FALLBACK_IF(ctx->RenderMode != GL_RENDER); diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c index 77abf86a8e..5c8fd8a5e5 100644 --- a/src/mesa/drivers/dri/r300/r300_shader.c +++ b/src/mesa/drivers/dri/r300/r300_shader.c @@ -9,8 +9,10 @@ static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target, GLuint id) { + r300ContextPtr rmesa = R300_CONTEXT(ctx); struct r300_vertex_program_cont *vp; - struct r300_fragment_program *fp; + struct r300_fragment_program *r300_fp; + struct r500_fragment_program *r500_fp; switch (target) { case GL_VERTEX_STATE_PROGRAM_NV: @@ -19,14 +21,28 @@ static struct gl_program *r300NewProgram(GLcontext * ctx, GLenum target, return _mesa_init_vertex_program(ctx, &vp->mesa_program, target, id); case GL_FRAGMENT_PROGRAM_ARB: - fp = CALLOC_STRUCT(r300_fragment_program); - fp->ctx = ctx; - return _mesa_init_fragment_program(ctx, &fp->mesa_program, - target, id); + if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { + r500_fp = CALLOC_STRUCT(r500_fragment_program); + r500_fp->ctx = ctx; + return _mesa_init_fragment_program(ctx, &r500_fp->mesa_program, + target, id); + } else { + r300_fp = CALLOC_STRUCT(r300_fragment_program); + r300_fp->ctx = ctx; + return _mesa_init_fragment_program(ctx, &r300_fp->mesa_program, + target, id); + } + case GL_FRAGMENT_PROGRAM_NV: - fp = CALLOC_STRUCT(r300_fragment_program); - return _mesa_init_fragment_program(ctx, &fp->mesa_program, - target, id); + if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { + r500_fp = CALLOC_STRUCT(r500_fragment_program); + return _mesa_init_fragment_program(ctx, &r500_fp->mesa_program, + target, id); + } else { + r300_fp = CALLOC_STRUCT(r300_fragment_program); + return _mesa_init_fragment_program(ctx, &r300_fp->mesa_program, + target, id); + } default: _mesa_problem(ctx, "Bad target in r300NewProgram"); } @@ -42,15 +58,20 @@ static void r300DeleteProgram(GLcontext * ctx, struct gl_program *prog) static void r300ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) { + r300ContextPtr rmesa = R300_CONTEXT(ctx); struct r300_vertex_program_cont *vp = (void *)prog; - struct r300_fragment_program *fp = (struct r300_fragment_program *)prog; + struct r300_fragment_program *r300_fp = (struct r300_fragment_program *)prog; + struct r500_fragment_program *r500_fp = (struct r500_fragment_program *)prog; switch (target) { case GL_VERTEX_PROGRAM_ARB: vp->progs = NULL; break; case GL_FRAGMENT_PROGRAM_ARB: - fp->translated = GL_FALSE; + if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) + r500_fp->translated = GL_FALSE; + else + r300_fp->translated = GL_FALSE; break; } diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index e11b5afc30..550f710854 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -60,7 +60,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_state.h" #include "r300_reg.h" #include "r300_emit.h" -#include "r300_fragprog.h" #include "r300_tex.h" #include "drirenderbuffer.h" @@ -189,7 +188,7 @@ static void r300SetBlendCntl(r300ContextPtr r300, int func, int eqn, */ #if 0 if (new_ablend == new_cblend) { - new_cblend |= R300_BLEND_NO_SEPARATE; + new_cblend |= R300_DISCARD_SRC_PIXELS_SRC_ALPHA_0; } #endif new_cblend |= cbits; @@ -295,7 +294,9 @@ static void r300SetBlendState(GLcontext * ctx) r300SetBlendCntl(r300, func, eqn, - R300_BLEND_UNKNOWN | R300_BLEND_ENABLE, funcA, eqnA); + (R300_SEPARATE_ALPHA_ENABLE | + R300_READ_ENABLE | + R300_ALPHA_BLEND_ENABLE), funcA, eqnA); } static void r300BlendEquationSeparate(GLcontext * ctx, @@ -401,42 +402,40 @@ static void r300SetPolygonOffsetState(GLcontext * ctx, GLboolean state) } } -static void r300SetEarlyZState(GLcontext * ctx) +static GLboolean current_fragment_program_writes_depth(GLcontext* ctx) { - /* updates register R300_RB3D_EARLY_Z (0x4F14) - if depth test is not enabled it should be R300_EARLY_Z_DISABLE - if depth is enabled and alpha not it should be R300_EARLY_Z_ENABLE - if depth and alpha is enabled it should be R300_EARLY_Z_DISABLE - */ r300ContextPtr r300 = R300_CONTEXT(ctx); - R300_STATECHANGE(r300, zstencil_format); - switch (ctx->Visual.depthBits) { - case 16: - r300->hw.zstencil_format.cmd[1] = ZB_FORMAR_DEPTHFORMAT_16BIT_INT_Z; - break; - case 24: - r300->hw.zstencil_format.cmd[1] = ZB_FORMAR_DEPTHFORMAT_24BIT_INT_Z; - break; - default: - fprintf(stderr, "Error: Unsupported depth %d... exiting\n", ctx->Visual.depthBits); - _mesa_exit(-1); + if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) { + struct r300_fragment_program *fp = (struct r300_fragment_program *) + (char *)ctx->FragmentProgram._Current; + return (fp && fp->WritesDepth); + } else { + struct r500_fragment_program* fp = + (struct r500_fragment_program*)(char*) + ctx->FragmentProgram._Current; + return (fp && fp->writes_depth); } +} + +static void r300SetEarlyZState(GLcontext * ctx) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + GLuint topZ = R300_ZTOP_ENABLE; if (ctx->Color.AlphaEnabled && ctx->Color.AlphaFunc != GL_ALWAYS) - /* disable early Z */ - r300->hw.zstencil_format.cmd[2] = R300_EARLY_Z_DISABLE; - else { - if (ctx->Depth.Test && ctx->Depth.Func != GL_NEVER) - /* enable early Z */ - r300->hw.zstencil_format.cmd[2] = R300_EARLY_Z_ENABLE; - else - /* disable early Z */ - r300->hw.zstencil_format.cmd[2] = R300_EARLY_Z_DISABLE; + topZ = R300_ZTOP_DISABLE; + if (current_fragment_program_writes_depth(ctx)) + topZ = R300_ZTOP_DISABLE; + + if (topZ != r300->hw.zstencil_format.cmd[2]) { + /* Note: This completely reemits the stencil format. + * I have not tested whether this is strictly necessary, + * or if emitting a write to ZB_ZTOP is enough. + */ + R300_STATECHANGE(r300, zstencil_format); + r300->hw.zstencil_format.cmd[2] = topZ; } - - r300->hw.zstencil_format.cmd[3] = 0x00000003; - r300->hw.zstencil_format.cmd[4] = 0x00000000; } static void r300SetAlphaState(GLcontext * ctx) @@ -450,25 +449,25 @@ static void r300SetAlphaState(GLcontext * ctx) switch (ctx->Color.AlphaFunc) { case GL_NEVER: - pp_misc |= FG_ALPHA_FUNC_NEVER; + pp_misc |= R300_FG_ALPHA_FUNC_NEVER; break; case GL_LESS: - pp_misc |= FG_ALPHA_FUNC_LESS; + pp_misc |= R300_FG_ALPHA_FUNC_LESS; break; case GL_EQUAL: - pp_misc |= FG_ALPHA_FUNC_EQUAL; + pp_misc |= R300_FG_ALPHA_FUNC_EQUAL; break; case GL_LEQUAL: - pp_misc |= FG_ALPHA_FUNC_LE; + pp_misc |= R300_FG_ALPHA_FUNC_LE; break; case GL_GREATER: - pp_misc |= FG_ALPHA_FUNC_GREATER; + pp_misc |= R300_FG_ALPHA_FUNC_GREATER; break; case GL_NOTEQUAL: - pp_misc |= FG_ALPHA_FUNC_NOTEQUAL; + pp_misc |= R300_FG_ALPHA_FUNC_NOTEQUAL; break; case GL_GEQUAL: - pp_misc |= FG_ALPHA_FUNC_GE; + pp_misc |= R300_FG_ALPHA_FUNC_GE; break; case GL_ALWAYS: /*pp_misc |= FG_ALPHA_FUNC_ALWAYS; */ @@ -477,8 +476,9 @@ static void r300SetAlphaState(GLcontext * ctx) } if (really_enabled) { - pp_misc |= FG_ALPHA_FUNC_ENABLE; - pp_misc |= (refByte & R300_REF_ALPHA_MASK); + pp_misc |= R300_FG_ALPHA_FUNC_ENABLE; + pp_misc |= R500_FG_ALPHA_FUNC_8BIT; + pp_misc |= (refByte & R300_FG_ALPHA_FUNC_VAL_MASK); } else { pp_misc = 0x0; } @@ -525,24 +525,24 @@ static void r300SetDepthState(GLcontext * ctx) r300ContextPtr r300 = R300_CONTEXT(ctx); R300_STATECHANGE(r300, zs); - r300->hw.zs.cmd[R300_ZS_CNTL_0] &= R300_RB3D_STENCIL_ENABLE; + r300->hw.zs.cmd[R300_ZS_CNTL_0] &= R300_STENCIL_ENABLE; // XXX r300->hw.zs.cmd[R300_ZS_CNTL_1] &= - ~(R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT); + ~(R300_ZS_MASK << R300_Z_FUNC_SHIFT); if (ctx->Depth.Test && ctx->Depth.Func != GL_NEVER) { if (ctx->Depth.Mask) r300->hw.zs.cmd[R300_ZS_CNTL_0] |= - R300_RB3D_Z_TEST_AND_WRITE; + R300_Z_ENABLE | R300_Z_WRITE_ENABLE | R300_STENCIL_FRONT_BACK; // XXX else - r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_Z_TEST; + r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_Z_ENABLE | R300_STENCIL_FRONT_BACK; // XXX r300->hw.zs.cmd[R300_ZS_CNTL_1] |= translate_func(ctx->Depth. - Func) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT; + Func) << R300_Z_FUNC_SHIFT; } else { - r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_RB3D_Z_DISABLED_1; + r300->hw.zs.cmd[R300_ZS_CNTL_0] |= R300_STENCIL_FRONT_BACK; // XXX r300->hw.zs.cmd[R300_ZS_CNTL_1] |= - translate_func(GL_NEVER) << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT; + translate_func(GL_NEVER) << R300_Z_FUNC_SHIFT; } r300SetEarlyZState(ctx); @@ -556,10 +556,10 @@ static void r300SetStencilState(GLcontext * ctx, GLboolean state) R300_STATECHANGE(r300, zs); if (state) { r300->hw.zs.cmd[R300_ZS_CNTL_0] |= - R300_RB3D_STENCIL_ENABLE; + R300_STENCIL_ENABLE; } else { r300->hw.zs.cmd[R300_ZS_CNTL_0] &= - ~R300_RB3D_STENCIL_ENABLE; + ~R300_STENCIL_ENABLE; } } else { #if R200_MERGED @@ -571,7 +571,7 @@ static void r300SetStencilState(GLcontext * ctx, GLboolean state) static void r300UpdatePolygonMode(GLcontext * ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); - uint32_t hw_mode = GA_POLY_MODE_DISABLE; + uint32_t hw_mode = R300_GA_POLY_MODE_DISABLE; /* Only do something if a polygon mode is wanted, default is GL_FILL */ if (ctx->Polygon.FrontMode != GL_FILL || @@ -590,29 +590,29 @@ static void r300UpdatePolygonMode(GLcontext * ctx) } /* Enable polygon mode */ - hw_mode |= GA_POLY_MODE_DUAL; + hw_mode |= R300_GA_POLY_MODE_DUAL; switch (f) { case GL_LINE: - hw_mode |= GA_POLY_MODE_FRONT_PTYPE_LINE; + hw_mode |= R300_GA_POLY_MODE_FRONT_PTYPE_LINE; break; case GL_POINT: - hw_mode |= GA_POLY_MODE_FRONT_PTYPE_POINT; + hw_mode |= R300_GA_POLY_MODE_FRONT_PTYPE_POINT; break; case GL_FILL: - hw_mode |= GA_POLY_MODE_FRONT_PTYPE_TRI; + hw_mode |= R300_GA_POLY_MODE_FRONT_PTYPE_TRI; break; } switch (b) { case GL_LINE: - hw_mode |= GA_POLY_MODE_BACK_PTYPE_LINE; + hw_mode |= R300_GA_POLY_MODE_BACK_PTYPE_LINE; break; case GL_POINT: - hw_mode |= GA_POLY_MODE_BACK_PTYPE_POINT; + hw_mode |= R300_GA_POLY_MODE_BACK_PTYPE_POINT; break; case GL_FILL: - hw_mode |= GA_POLY_MODE_BACK_PTYPE_TRI; + hw_mode |= R300_GA_POLY_MODE_BACK_PTYPE_TRI; break; } } @@ -716,8 +716,8 @@ static void r300Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) R300_STATECHANGE(r300, fogs); r300->hw.fogs.cmd[R300_FOGS_STATE] = (r300->hw.fogs. - cmd[R300_FOGS_STATE] & ~FG_FOG_BLEND_FN_MASK) | - FG_FOG_BLEND_FN_LINEAR; + cmd[R300_FOGS_STATE] & ~R300_FG_FOG_BLEND_FN_MASK) | + R300_FG_FOG_BLEND_FN_LINEAR; if (ctx->Fog.Start == ctx->Fog.End) { fogScale.f = -1.0; @@ -734,8 +734,8 @@ static void r300Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) R300_STATECHANGE(r300, fogs); r300->hw.fogs.cmd[R300_FOGS_STATE] = (r300->hw.fogs. - cmd[R300_FOGS_STATE] & ~FG_FOG_BLEND_FN_MASK) | - FG_FOG_BLEND_FN_EXP; + cmd[R300_FOGS_STATE] & ~R300_FG_FOG_BLEND_FN_MASK) | + R300_FG_FOG_BLEND_FN_EXP; fogScale.f = 0.0933 * ctx->Fog.Density; fogStart.f = 0.0; break; @@ -743,8 +743,8 @@ static void r300Fogfv(GLcontext * ctx, GLenum pname, const GLfloat * param) R300_STATECHANGE(r300, fogs); r300->hw.fogs.cmd[R300_FOGS_STATE] = (r300->hw.fogs. - cmd[R300_FOGS_STATE] & ~FG_FOG_BLEND_FN_MASK) | - FG_FOG_BLEND_FN_EXP2; + cmd[R300_FOGS_STATE] & ~R300_FG_FOG_BLEND_FN_MASK) | + R300_FG_FOG_BLEND_FN_EXP2; fogScale.f = 0.3 * ctx->Fog.Density; fogStart.f = 0.0; default: @@ -808,7 +808,7 @@ static void r300SetFogState(GLcontext * ctx, GLboolean state) R300_STATECHANGE(r300, fogs); if (state) { - r300->hw.fogs.cmd[R300_FOGS_STATE] |= FG_FOG_BLEND_ENABLE; + r300->hw.fogs.cmd[R300_FOGS_STATE] |= R300_FG_FOG_BLEND_ENABLE; r300Fogfv(ctx, GL_FOG_MODE, NULL); r300Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density); @@ -816,7 +816,7 @@ static void r300SetFogState(GLcontext * ctx, GLboolean state) r300Fogfv(ctx, GL_FOG_END, &ctx->Fog.End); r300Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color); } else { - r300->hw.fogs.cmd[R300_FOGS_STATE] &= ~FG_FOG_BLEND_ENABLE; + r300->hw.fogs.cmd[R300_FOGS_STATE] &= ~R300_FG_FOG_BLEND_ENABLE; } } @@ -914,36 +914,36 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face, r300ContextPtr rmesa = R300_CONTEXT(ctx); GLuint refmask = (((ctx->Stencil. - Ref[0] & 0xff) << ZB_STENCILREFMASK_STENCILREF_SHIFT) | ((ctx-> - Stencil. - ValueMask - [0] & - 0xff) - << - ZB_STENCILREFMASK_STENCILMASK_SHIFT)); + Ref[0] & 0xff) << R300_STENCILREF_SHIFT) | ((ctx-> + Stencil. + ValueMask + [0] & + 0xff) + << + R300_STENCILMASK_SHIFT)); GLuint flag; R300_STATECHANGE(rmesa, zs); rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~((R300_ZS_MASK << - R300_RB3D_ZS1_FRONT_FUNC_SHIFT) + R300_S_FRONT_FUNC_SHIFT) | (R300_ZS_MASK << - R300_RB3D_ZS1_BACK_FUNC_SHIFT)); + R300_S_BACK_FUNC_SHIFT)); rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= - ~((ZB_STENCILREFMASK_STENCIL_MASK << ZB_STENCILREFMASK_STENCILREF_SHIFT) | - (ZB_STENCILREFMASK_STENCIL_MASK << ZB_STENCILREFMASK_STENCILMASK_SHIFT)); + ~((R300_STENCILREF_MASK << R300_STENCILREF_SHIFT) | + (R300_STENCILREF_MASK << R300_STENCILMASK_SHIFT)); flag = translate_func(ctx->Stencil.Function[0]); rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= - (flag << R300_RB3D_ZS1_FRONT_FUNC_SHIFT); + (flag << R300_S_FRONT_FUNC_SHIFT); if (ctx->Stencil._TestTwoSide) flag = translate_func(ctx->Stencil.Function[1]); rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= - (flag << R300_RB3D_ZS1_BACK_FUNC_SHIFT); + (flag << R300_S_BACK_FUNC_SHIFT); rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask; } @@ -953,12 +953,12 @@ static void r300StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) R300_STATECHANGE(rmesa, zs); rmesa->hw.zs.cmd[R300_ZS_CNTL_2] &= - ~(ZB_STENCILREFMASK_STENCIL_MASK << - ZB_STENCILREFMASK_STENCILWRITEMASK_SHIFT); + ~(R300_STENCILREF_MASK << + R300_STENCILWRITEMASK_SHIFT); rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= (ctx->Stencil. - WriteMask[0] & ZB_STENCILREFMASK_STENCIL_MASK) << - ZB_STENCILREFMASK_STENCILWRITEMASK_SHIFT; + WriteMask[0] & R300_STENCILREF_MASK) << + R300_STENCILWRITEMASK_SHIFT; } static void r300StencilOpSeparate(GLcontext * ctx, GLenum face, @@ -969,34 +969,34 @@ static void r300StencilOpSeparate(GLcontext * ctx, GLenum face, R300_STATECHANGE(rmesa, zs); /* It is easier to mask what's left.. */ rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= - (R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT) | - (R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT) | - (R300_ZS_MASK << R300_RB3D_ZS1_BACK_FUNC_SHIFT); + (R300_ZS_MASK << R300_Z_FUNC_SHIFT) | + (R300_ZS_MASK << R300_S_FRONT_FUNC_SHIFT) | + (R300_ZS_MASK << R300_S_BACK_FUNC_SHIFT); rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (translate_stencil_op(ctx->Stencil.FailFunc[0]) << - R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT) + R300_S_FRONT_SFAIL_OP_SHIFT) | (translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << - R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT) + R300_S_FRONT_ZFAIL_OP_SHIFT) | (translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << - R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT); + R300_S_FRONT_ZPASS_OP_SHIFT); if (ctx->Stencil._TestTwoSide) { rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (translate_stencil_op(ctx->Stencil.FailFunc[1]) << - R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) + R300_S_BACK_SFAIL_OP_SHIFT) | (translate_stencil_op(ctx->Stencil.ZFailFunc[1]) << - R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT) + R300_S_BACK_ZFAIL_OP_SHIFT) | (translate_stencil_op(ctx->Stencil.ZPassFunc[1]) << - R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT); + R300_S_BACK_ZPASS_OP_SHIFT); } else { rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |= (translate_stencil_op(ctx->Stencil.FailFunc[0]) << - R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT) + R300_S_BACK_SFAIL_OP_SHIFT) | (translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << - R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT) + R300_S_BACK_ZFAIL_OP_SHIFT) | (translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << - R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT); + R300_S_BACK_ZPASS_OP_SHIFT); } } @@ -1005,10 +1005,10 @@ static void r300ClearStencil(GLcontext * ctx, GLint s) r300ContextPtr rmesa = R300_CONTEXT(ctx); rmesa->state.stencil.clear = - ((GLuint) (ctx->Stencil.Clear & ZB_STENCILREFMASK_STENCIL_MASK) | - (ZB_STENCILREFMASK_STENCIL_MASK << ZB_STENCILREFMASK_STENCILMASK_SHIFT) | - ((ctx->Stencil.WriteMask[0] & ZB_STENCILREFMASK_STENCIL_MASK) << - ZB_STENCILREFMASK_STENCILMASK_SHIFT)); + ((GLuint) (ctx->Stencil.Clear & R300_STENCILREF_MASK) | + (R300_STENCILREF_MASK << R300_STENCILMASK_SHIFT) | + ((ctx->Stencil.WriteMask[0] & R300_STENCILREF_MASK) << + R300_STENCILMASK_SHIFT)); } /* ============================================================= @@ -1322,6 +1322,82 @@ static unsigned long gen_fixed_filter(unsigned long f) return f; } +static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + int i; + struct r300_fragment_program *fp = (struct r300_fragment_program *) + (char *)ctx->FragmentProgram._Current; + + R300_STATECHANGE(r300, fpt); + + for (i = 0; i < fp->tex.length; i++) { + int unit; + int opcode; + unsigned long val; + + unit = fp->tex.inst[i] >> R300_TEX_ID_SHIFT; + unit &= 15; + + val = fp->tex.inst[i]; + val &= ~R300_TEX_ID_MASK; + + opcode = + (val & R300_TEX_INST_MASK) >> R300_TEX_INST_SHIFT; + if (opcode == R300_TEX_OP_KIL) { + r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val; + } else { + if (tmu_mappings[unit] >= 0) { + val |= + tmu_mappings[unit] << + R300_TEX_ID_SHIFT; + r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val; + } else { + // We get here when the corresponding texture image is incomplete + // (e.g. incomplete mipmaps etc.) + r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val; + } + } + } + + r300->hw.fpt.cmd[R300_FPT_CMD_0] = + cmdpacket0(R300_US_TEX_INST_0, fp->tex.length); +} + +static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) +{ + int i; + struct r500_fragment_program *fp = (struct r500_fragment_program *) + (char *)ctx->FragmentProgram._Current; + + /* find all the texture instructions and relocate the texture units */ + for (i = 0; i < fp->inst_end + 1; i++) { + if ((fp->inst[i].inst0 & 0x3) == R500_INST_TYPE_TEX) { + uint32_t val; + int unit, opcode, new_unit; + + val = fp->inst[i].inst1; + + unit = (val >> 16) & 0xf; + + val &= ~(0xf << 16); + + opcode = val & (0x7 << 22); + if (opcode == R500_TEX_INST_TEXKILL) { + new_unit = 0; + } else { + if (tmu_mappings[unit] >= 0) { + new_unit = tmu_mappings[unit]; + } else { + new_unit = 0; + } + } + val |= R500_TEX_ID(new_unit); + fp->inst[i].inst1 = val; + } + } +} + static void r300SetupTextures(GLcontext * ctx) { int i, mtu; @@ -1436,39 +1512,18 @@ static void r300SetupTextures(GLcontext * ctx) if (!fp) /* should only happenen once, just after context is created */ return; - R300_STATECHANGE(r300, fpt); - - for (i = 0; i < fp->tex.length; i++) { - int unit; - int opcode; - unsigned long val; - - unit = fp->tex.inst[i] >> R300_FPITX_IMAGE_SHIFT; - unit &= 15; - - val = fp->tex.inst[i]; - val &= ~R300_FPITX_IMAGE_MASK; - - opcode = - (val & R300_FPITX_OPCODE_MASK) >> R300_FPITX_OPCODE_SHIFT; - if (opcode == R300_FPITX_OP_KIL) { - r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val; - } else { - if (tmu_mappings[unit] >= 0) { - val |= - tmu_mappings[unit] << - R300_FPITX_IMAGE_SHIFT; - r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val; - } else { - // We get here when the corresponding texture image is incomplete - // (e.g. incomplete mipmaps etc.) - r300->hw.fpt.cmd[R300_FPT_INSTR_0 + i] = val; - } + if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) { + if (fp->mesa_program.UsesKill && last_hw_tmu < 0) { + // The KILL operation requires the first texture unit + // to be enabled. + r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1; + r300->hw.tex.filter.cmd[R300_TEX_VALUE_0] = 0; + r300->hw.tex.filter.cmd[R300_TEX_CMD_0] = + cmdpacket0(R300_TX_FILTER0_0, 1); } - } - - r300->hw.fpt.cmd[R300_FPT_CMD_0] = - cmdpacket0(R300_PFS_TEXI_0, fp->tex.length); + r300SetupFragmentShaderTextures(ctx, tmu_mappings); + } else + r500SetupFragmentShaderTextures(ctx, tmu_mappings); if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "TX_ENABLE: %08x last_hw_tmu=%d\n", @@ -1488,21 +1543,17 @@ static void r300SetupRSUnit(GLcontext * ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); /* I'm still unsure if these are needed */ - GLuint interp_magic[8] = { - 0x00, - R300_RS_COL_PTR(1), - R300_RS_COL_PTR(2), - R300_RS_COL_PTR(3), - 0x00, - 0x00, - 0x00, - 0x00 - }; + GLuint interp_col[8]; + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; union r300_outputs_written OutputsWritten; GLuint InputsRead; int fp_reg, high_rr; - int in_texcoords, col_interp_nr; - int i; + int col_interp_nr; + int rs_tex_count = 0, rs_col_count = 0; + int i, count; + + memset(interp_col, 0, sizeof(interp_col)); if (hw_tcl_on) OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten; @@ -1520,7 +1571,7 @@ static void r300SetupRSUnit(GLcontext * ctx) R300_STATECHANGE(r300, rc); R300_STATECHANGE(r300, rr); - fp_reg = in_texcoords = col_interp_nr = high_rr = 0; + fp_reg = col_interp_nr = high_rr = 0; r300->hw.rr.cmd[R300_RR_INST_1] = 0; @@ -1538,12 +1589,50 @@ static void r300SetupRSUnit(GLcontext * ctx) InputsRead &= ~FRAG_BIT_WPOS; } + if (InputsRead & FRAG_BIT_COL0) { + count = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size; + interp_col[0] |= R300_RS_COL_PTR(rs_col_count); + if (count == 3) + interp_col[0] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB1); + rs_col_count += count; + } + else + interp_col[0] = R300_RS_COL_FMT(R300_RS_COL_FMT_0001); + + if (InputsRead & FRAG_BIT_COL1) { + count = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->size; + if (count == 3) + interp_col[1] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGB0); + interp_col[1] |= R300_RS_COL_PTR(1); + rs_col_count += count; + } + + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = 0 | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3) | (in_texcoords << R300_RS_INTERP_SRC_SHIFT) - | interp_magic[i]; + int swiz; + + /* with TCL we always seem to route 4 components */ + if (hw_tcl_on) + count = 4; + else + count = VB->AttribPtr[_TNL_ATTRIB_TEX(i)]->size; + + r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = interp_col[i] | rs_tex_count; + switch(count) { + case 4: swiz = R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(3); break; + case 3: swiz = R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(2) | R300_RS_SEL_Q(R300_RS_SEL_K1); break; + default: + case 1: + case 2: swiz = R300_RS_SEL_S(0) | R300_RS_SEL_T(1) | R300_RS_SEL_R(R300_RS_SEL_K0) | R300_RS_SEL_Q(R300_RS_SEL_K1); break; + }; + + r300->hw.ri.cmd[R300_RI_INTERP_0 + i] |= swiz; r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] = 0; if (InputsRead & (FRAG_BIT_TEX0 << i)) { + + rs_tex_count += count; + //assert(r300->state.texture.tc_count != 0); r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] |= R300_RS_INST_TEX_CN_WRITE | i /* source INTERP */ | (fp_reg << R300_RS_INST_TEX_ADDR_SHIFT); @@ -1557,10 +1646,6 @@ static void r300SetupRSUnit(GLcontext * ctx) WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i); } } - /* Need to count all coords enabled at vof */ - if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_TEX0 + i, _TNL_ATTRIB_TEX(i))) { - in_texcoords++; - } } if (InputsRead & FRAG_BIT_COL0) { @@ -1586,23 +1671,186 @@ static void r300SetupRSUnit(GLcontext * ctx) } /* Need at least one. This might still lock as the values are undefined... */ - if (in_texcoords == 0 && col_interp_nr == 0) { + if (rs_tex_count == 0 && col_interp_nr == 0) { r300->hw.rr.cmd[R300_RR_INST_0] |= R300_RS_INST_COL_ID(0) | R300_RS_INST_COL_CN_WRITE | (fp_reg++ << R300_RS_INST_COL_ADDR_SHIFT); col_interp_nr++; } - r300->hw.rc.cmd[1] = 0 | ((in_texcoords << 2) << R300_IT_COUNT_SHIFT) + r300->hw.rc.cmd[1] = 0 | (rs_tex_count << R300_IT_COUNT_SHIFT) | (col_interp_nr << R300_IC_COUNT_SHIFT) | R300_HIRES_EN; assert(high_rr >= 0); r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R300_RS_INST_0, high_rr + 1); + r300->hw.rc.cmd[2] = high_rr; + + if (InputsRead) + WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead); +} + +static void r500SetupRSUnit(GLcontext * ctx) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + /* I'm still unsure if these are needed */ + GLuint interp_col[8]; + union r300_outputs_written OutputsWritten; + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint InputsRead; + int fp_reg, high_rr; + int rs_col_count = 0; + int in_texcoords, col_interp_nr; + int i, count; + + memset(interp_col, 0, sizeof(interp_col)); + if (hw_tcl_on) + OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten; + else + RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->state.render_inputs_bitset); + + if (ctx->FragmentProgram._Current) + InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; + else { + fprintf(stderr, "No ctx->FragmentProgram._Current!!\n"); + return; /* This should only ever happen once.. */ + } + + R300_STATECHANGE(r300, ri); + R300_STATECHANGE(r300, rc); + R300_STATECHANGE(r300, rr); + + fp_reg = col_interp_nr = high_rr = in_texcoords = 0; + + r300->hw.rr.cmd[R300_RR_INST_1] = 0; + + if (InputsRead & FRAG_BIT_WPOS) { + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) + if (!(InputsRead & (FRAG_BIT_TEX0 << i))) + break; + + if (i == ctx->Const.MaxTextureUnits) { + fprintf(stderr, "\tno free texcoord found...\n"); + _mesa_exit(-1); + } + + InputsRead |= (FRAG_BIT_TEX0 << i); + InputsRead &= ~FRAG_BIT_WPOS; + } + + if (InputsRead & FRAG_BIT_COL0) { + count = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size; + interp_col[0] |= R500_RS_COL_PTR(rs_col_count); + if (count == 3) + interp_col[0] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB1); + rs_col_count += count; + } + else + interp_col[0] = R500_RS_COL_FMT(R300_RS_COL_FMT_0001); + + if (InputsRead & FRAG_BIT_COL1) { + count = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->size; + interp_col[1] |= R500_RS_COL_PTR(1); + if (count == 3) + interp_col[1] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGB0); + rs_col_count += count; + } + + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { + GLuint swiz = 0; + + /* with TCL we always seem to route 4 components */ + if (InputsRead & (FRAG_BIT_TEX0 << i)) { + + if (hw_tcl_on) + count = 4; + else + count = VB->AttribPtr[_TNL_ATTRIB_TEX(i)]->size; + + /* always have on texcoord */ + swiz |= in_texcoords++ << R500_RS_IP_TEX_PTR_S_SHIFT; + if (count >= 2) + swiz |= in_texcoords++ << R500_RS_IP_TEX_PTR_T_SHIFT; + else + swiz |= R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT; + + if (count >= 3) + swiz |= in_texcoords++ << R500_RS_IP_TEX_PTR_R_SHIFT; + else + swiz |= R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT; + + if (count == 4) + swiz |= in_texcoords++ << R500_RS_IP_TEX_PTR_Q_SHIFT; + else + swiz |= R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT; + + } else + swiz = (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) | + (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) | + (R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) | + (R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT); + + r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = interp_col[i] | swiz; + + r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] = 0; + if (InputsRead & (FRAG_BIT_TEX0 << i)) { + //assert(r300->state.texture.tc_count != 0); + r300->hw.rr.cmd[R300_RR_INST_0 + fp_reg] |= R500_RS_INST_TEX_CN_WRITE | i /* source INTERP */ + | (fp_reg << R500_RS_INST_TEX_ADDR_SHIFT); + high_rr = fp_reg; + + /* Passing invalid data here can lock the GPU. */ + if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_TEX0 + i, _TNL_ATTRIB_TEX(i))) { + InputsRead &= ~(FRAG_BIT_TEX0 << i); + fp_reg++; + } else { + WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i); + } + } + } + + if (InputsRead & FRAG_BIT_COL0) { + if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL0, _TNL_ATTRIB_COLOR0)) { + r300->hw.rr.cmd[R300_RR_INST_0] |= R500_RS_INST_COL_CN_WRITE | (fp_reg++ << R500_RS_INST_COL_ADDR_SHIFT); + InputsRead &= ~FRAG_BIT_COL0; + col_interp_nr++; + } else { + WARN_ONCE("fragprog wants col0, vp doesn't provide it\n"); + } + } + + if (InputsRead & FRAG_BIT_COL1) { + if (R300_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1)) { + r300->hw.rr.cmd[R300_RR_INST_1] |= (1 << 12) | R500_RS_INST_COL_CN_WRITE | (fp_reg++ << R500_RS_INST_COL_ADDR_SHIFT); + InputsRead &= ~FRAG_BIT_COL1; + if (high_rr < 1) + high_rr = 1; + col_interp_nr++; + } else { + WARN_ONCE("fragprog wants col1, vp doesn't provide it\n"); + } + } + + /* Need at least one. This might still lock as the values are undefined... */ + if (in_texcoords == 0 && col_interp_nr == 0) { + r300->hw.rr.cmd[R300_RR_INST_0] |= 0 | R500_RS_INST_COL_CN_WRITE | (fp_reg++ << R500_RS_INST_COL_ADDR_SHIFT); + col_interp_nr++; + } + + r300->hw.rc.cmd[1] = 0 | (in_texcoords << R300_IT_COUNT_SHIFT) + | (col_interp_nr << R300_IC_COUNT_SHIFT) + | R300_HIRES_EN; + + assert(high_rr >= 0); + r300->hw.rr.cmd[R300_RR_CMD_0] = cmdpacket0(R500_RS_INST_0, high_rr + 1); r300->hw.rc.cmd[2] = 0xC0 | high_rr; if (InputsRead) WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead); } + + + #define bump_vpu_count(ptr, new_count) do{\ drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\ int _nc=(new_count)/4; \ @@ -1648,10 +1896,67 @@ static inline void r300SetupVertexProgramFragment(r300ContextPtr r300, int dest, } } +#define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c)) + + +static void r300VapCntl(r300ContextPtr rmesa, GLuint input_count, + GLuint output_count, GLuint temp_count) +{ + int vtx_mem_size; + int pvs_num_slots; + int pvs_num_cntrls; + + /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS. + * See r500 docs 6.5.2 - done in emit */ + + /* avoid division by zero */ + if (input_count == 0) input_count = 1; + if (output_count == 0) output_count = 1; + if (temp_count == 0) temp_count = 1; + + if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) + vtx_mem_size = 128; + else + vtx_mem_size = 72; + + pvs_num_slots = MIN3(10, vtx_mem_size/input_count, vtx_mem_size/output_count); + pvs_num_cntrls = MIN2(6, vtx_mem_size/temp_count); + + R300_STATECHANGE(rmesa, vap_cntl); + if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { + rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] = + (pvs_num_slots << R300_PVS_NUM_SLOTS_SHIFT) | + (pvs_num_cntrls << R300_PVS_NUM_CNTLRS_SHIFT) | + (12 << R300_VF_MAX_VTX_NUM_SHIFT); + if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) + rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= R500_TCL_STATE_OPTIMIZATION; + } else + /* not sure about non-tcl */ + rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] = ((10 << R300_PVS_NUM_SLOTS_SHIFT) | + (5 << R300_PVS_NUM_CNTLRS_SHIFT) | + (5 << R300_VF_MAX_VTX_NUM_SHIFT)); + + if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV515) + rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (2 << R300_PVS_NUM_FPUS_SHIFT); + else if ((rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) || + (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV560)) + rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (5 << R300_PVS_NUM_FPUS_SHIFT); + else if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R420) + rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (6 << R300_PVS_NUM_FPUS_SHIFT); + else if ((rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R520) || + (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R580) || + (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV570)) + rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (8 << R300_PVS_NUM_FPUS_SHIFT); + else + rmesa->hw.vap_cntl.cmd[R300_VAP_CNTL_INSTR] |= (4 << R300_PVS_NUM_FPUS_SHIFT); + +} + static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa) { struct r300_vertex_shader_state *prog = &(rmesa->state.vertex_shader); GLuint o_reg = 0; + GLuint i_reg = 0; int i; int inst_count = 0; int param_count = 0; @@ -1664,26 +1969,37 @@ static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa) prog->program.body.i[program_end + 2] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE); prog->program.body.i[program_end + 3] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE); program_end += 4; + i_reg++; } } prog->program.length = program_end; - r300SetupVertexProgramFragment(rmesa, R300_PVS_UPLOAD_PROGRAM, + r300SetupVertexProgramFragment(rmesa, R300_PVS_CODE_START, &(prog->program)); inst_count = (prog->program.length / 4) - 1; + r300VapCntl(rmesa, i_reg, o_reg, 0); + R300_STATECHANGE(rmesa, pvs); rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = - (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) | - (inst_count << R300_PVS_CNTL_1_POS_END_SHIFT) | - (inst_count << R300_PVS_CNTL_1_PROGRAM_END_SHIFT); + (0 << R300_PVS_FIRST_INST_SHIFT) | + (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) | + (inst_count << R300_PVS_LAST_INST_SHIFT); rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] = - (0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT) | - (param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT); + (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) | + (param_count << R300_PVS_MAX_CONST_ADDR_SHIFT); rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] = - (inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) | - (inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT); + (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT); +} + +static int bit_count (int x) +{ + x = ((x & 0xaaaaaaaaU) >> 1) + (x & 0x55555555U); + x = ((x & 0xccccccccU) >> 2) + (x & 0x33333333U); + x = (x >> 16) + (x & 0xffff); + x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f); + return (x >> 8) + (x & 0x00ff); } static void r300SetupRealVertexProgram(r300ContextPtr rmesa) @@ -1704,20 +2020,22 @@ static void r300SetupRealVertexProgram(r300ContextPtr rmesa) bump_vpu_count(rmesa->hw.vpp.cmd, param_count); param_count /= 4; - r300SetupVertexProgramFragment(rmesa, R300_PVS_UPLOAD_PROGRAM, &(prog->program)); + r300SetupVertexProgramFragment(rmesa, R300_PVS_CODE_START, &(prog->program)); inst_count = (prog->program.length / 4) - 1; + r300VapCntl(rmesa, bit_count(prog->key.InputsRead), + bit_count(prog->key.OutputsWritten), prog->num_temporaries); + R300_STATECHANGE(rmesa, pvs); rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = - (0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) | - (inst_count << R300_PVS_CNTL_1_POS_END_SHIFT) | - (inst_count << R300_PVS_CNTL_1_PROGRAM_END_SHIFT); + (0 << R300_PVS_FIRST_INST_SHIFT) | + (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) | + (inst_count << R300_PVS_LAST_INST_SHIFT); rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] = - (0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT) | - (param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT); + (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) | + (param_count << R300_PVS_MAX_CONST_ADDR_SHIFT); rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] = - (inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) | - (inst_count << R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT); + (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT); } static void r300SetupVertexProgram(r300ContextPtr rmesa) @@ -1740,13 +2058,6 @@ static void r300SetupVertexProgram(r300ContextPtr rmesa) r300SetupDefaultVertexProgram(rmesa); } - - /* FIXME: This is done for vertex shader fragments, but also needs to be - * done for vap_pvs, so I leave it as a reminder. */ -#if 0 - reg_start(R300_VAP_PVS_WAITIDLE, 0); - e32(0x00000000); -#endif } /** @@ -1848,11 +2159,6 @@ static void r300ResetHwState(r300ContextPtr r300) r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef); r300Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled); - if (!has_tcl) - r300->hw.vap_cntl.cmd[1] = 0x0014045a; - else - r300->hw.vap_cntl.cmd[1] = 0x0030045A; //0x0030065a /* Dangerous */ - r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA | R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA @@ -1878,7 +2184,7 @@ static void r300ResetHwState(r300ContextPtr r300) /* XXX: Other families? */ if (has_tcl) { - r300->hw.vap_clip_cntl.cmd[1] = R300_221C_NORMAL; + r300->hw.vap_clip_cntl.cmd[1] = R300_PS_UCP_MODE_DIST_COP; r300->hw.vap_clip.cmd[1] = r300PackFloat32(1.0); /* X */ r300->hw.vap_clip.cmd[2] = r300PackFloat32(1.0); /* X */ @@ -1902,23 +2208,25 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_0] = 0x66666666; r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_1] = 0x06666666; - /* XXX: Other families? */ r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = - R300_GB_TILE_ENABLE | R300_GB_TILE_SIZE_16; - switch (r300->radeon.radeonScreen->chip_family) { - case CHIP_FAMILY_R300: - case CHIP_FAMILY_R350: - case CHIP_FAMILY_RV410: + R300_GB_TILE_ENABLE | R300_GB_TILE_SIZE_16 /*| R300_GB_SUBPIXEL_1_16*/; + switch (r300->radeon.radeonScreen->num_gb_pipes) { + case 1: + default: + r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |= + R300_GB_TILE_PIPE_COUNT_RV300; + break; + case 2: r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |= R300_GB_TILE_PIPE_COUNT_R300; break; - case CHIP_FAMILY_R420: + case 3: r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |= - R300_GB_TILE_PIPE_COUNT_R420; + R300_GB_TILE_PIPE_COUNT_R420_3P; break; - default: + case 4: r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |= - R300_GB_TILE_DISABLE; /* TODO: This disables tiling totally. I guess it happened accidentially. */ + R300_GB_TILE_PIPE_COUNT_R420; break; } @@ -1967,11 +2275,15 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.sc_screendoor.cmd[1] = 0x00FFFFFF; - r300->hw.us_out_fmt.cmd[1] = 0x00001B01; - r300->hw.us_out_fmt.cmd[2] = 0x00001B0F; - r300->hw.us_out_fmt.cmd[3] = 0x00001B0F; - r300->hw.us_out_fmt.cmd[4] = 0x00001B0F; - r300->hw.us_out_fmt.cmd[5] = 0x00000001; + r300->hw.us_out_fmt.cmd[1] = R500_OUT_FMT_C4_8 | + R500_C0_SEL_B | R500_C1_SEL_G | R500_C2_SEL_R | R500_C3_SEL_A; + r300->hw.us_out_fmt.cmd[2] = R500_OUT_FMT_UNUSED | + R500_C0_SEL_B | R500_C1_SEL_G | R500_C2_SEL_R | R500_C3_SEL_A; + r300->hw.us_out_fmt.cmd[3] = R500_OUT_FMT_UNUSED | + R500_C0_SEL_B | R500_C1_SEL_G | R500_C2_SEL_R | R500_C3_SEL_A; + r300->hw.us_out_fmt.cmd[4] = R500_OUT_FMT_UNUSED | + R500_C0_SEL_B | R500_C1_SEL_G | R500_C2_SEL_R | R500_C3_SEL_A; + r300->hw.us_out_fmt.cmd[5] = R300_W_FMT_W24; r300Enable(ctx, GL_FOG, ctx->Fog.Enabled); r300Fogfv(ctx, GL_FOG_MODE, NULL); @@ -2023,15 +2335,32 @@ static void r300ResetHwState(r300ContextPtr r300) if (r300->radeon.sarea->tiling_enabled) { /* XXX: Turn off when clearing buffers ? */ - r300->hw.zb.cmd[R300_ZB_PITCH] |= ZB_DEPTHPITCH_DEPTHMACROTILE_ENABLE; + r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTHMACROTILE_ENABLE; if (ctx->Visual.depthBits == 24) r300->hw.zb.cmd[R300_ZB_PITCH] |= - ZB_DEPTHPITCH_DEPTHMICROTILE_TILED; + R300_DEPTHMICROTILE_TILED; } r300->hw.zb_depthclearvalue.cmd[1] = 0; + switch (ctx->Visual.depthBits) { + case 16: + r300->hw.zstencil_format.cmd[1] = R300_DEPTHFORMAT_16BIT_INT_Z; + break; + case 24: + r300->hw.zstencil_format.cmd[1] = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL; + break; + default: + fprintf(stderr, "Error: Unsupported depth %d... exiting\n", ctx->Visual.depthBits); + _mesa_exit(-1); + } + + r300->hw.zstencil_format.cmd[2] = R300_ZTOP_DISABLE; + r300->hw.zstencil_format.cmd[3] = 0x00000003; + r300->hw.zstencil_format.cmd[4] = 0x00000000; + r300SetEarlyZState(ctx); + r300->hw.unk4F30.cmd[1] = 0; r300->hw.unk4F30.cmd[2] = 0; @@ -2039,6 +2368,7 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.zb_hiz_pitch.cmd[1] = 0; + r300VapCntl(r300, 0, 0, 0); if (has_tcl) { r300->hw.vps.cmd[R300_VPS_ZERO_0] = 0; r300->hw.vps.cmd[R300_VPS_ZERO_1] = 0; @@ -2084,10 +2414,11 @@ void r300UpdateShaders(r300ContextPtr rmesa) hw_tcl_on = future_hw_tcl_on = 0; r300ResetHwState(rmesa); + r300UpdateStateParameters(ctx, _NEW_PROGRAM); return; } - r300UpdateStateParameters(ctx, _NEW_PROGRAM); } + r300UpdateStateParameters(ctx, _NEW_PROGRAM); } static void r300SetupPixelShader(r300ContextPtr rmesa) @@ -2107,26 +2438,28 @@ static void r300SetupPixelShader(r300ContextPtr rmesa) return; } + r300SetupTextures(ctx); + R300_STATECHANGE(rmesa, fpi[0]); - rmesa->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR0_0, fp->alu_end + 1); + rmesa->hw.fpi[0].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_INST_0, fp->alu_end + 1); for (i = 0; i <= fp->alu_end; i++) { rmesa->hw.fpi[0].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst0; } R300_STATECHANGE(rmesa, fpi[1]); - rmesa->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR1_0, fp->alu_end + 1); + rmesa->hw.fpi[1].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_RGB_ADDR_0, fp->alu_end + 1); for (i = 0; i <= fp->alu_end; i++) { rmesa->hw.fpi[1].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst1; } R300_STATECHANGE(rmesa, fpi[2]); - rmesa->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR2_0, fp->alu_end + 1); + rmesa->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_INST_0, fp->alu_end + 1); for (i = 0; i <= fp->alu_end; i++) { rmesa->hw.fpi[2].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst2; } R300_STATECHANGE(rmesa, fpi[3]); - rmesa->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_PFS_INSTR3_0, fp->alu_end + 1); + rmesa->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(R300_US_ALU_ALPHA_ADDR_0, fp->alu_end + 1); for (i = 0; i <= fp->alu_end; i++) { rmesa->hw.fpi[3].cmd[R300_FPI_INSTR_0 + i] = fp->alu.inst[i].inst3; } @@ -2143,10 +2476,10 @@ static void r300SetupPixelShader(r300ContextPtr rmesa) for (i = 0, k = (4 - (fp->cur_node + 1)); i < 4; i++, k++) { if (i < (fp->cur_node + 1)) { rmesa->hw.fp.cmd[R300_FP_NODE0 + k] = - (fp->node[i].alu_offset << R300_PFS_NODE_ALU_OFFSET_SHIFT) | - (fp->node[i].alu_end << R300_PFS_NODE_ALU_END_SHIFT) | - (fp->node[i].tex_offset << R300_PFS_NODE_TEX_OFFSET_SHIFT) | - (fp->node[i].tex_end << R300_PFS_NODE_TEX_END_SHIFT) | + (fp->node[i].alu_offset << R300_ALU_START_SHIFT) | + (fp->node[i].alu_end << R300_ALU_SIZE_SHIFT) | + (fp->node[i].tex_offset << R300_TEX_START_SHIFT) | + (fp->node[i].tex_end << R300_TEX_SIZE_SHIFT) | fp->node[i].flags; } else { rmesa->hw.fp.cmd[R300_FP_NODE0 + (3 - i)] = 0; @@ -2163,19 +2496,107 @@ static void r300SetupPixelShader(r300ContextPtr rmesa) } } +#define bump_r500fp_count(ptr, new_count) do{\ + drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\ + int _nc=(new_count)/6; \ + assert(_nc < 256); \ + if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\ +} while(0) + +#define bump_r500fp_const_count(ptr, new_count) do{\ + drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\ + int _nc=(new_count)/4; \ + assert(_nc < 256); \ + if(_nc>_p->r500fp.count)_p->r500fp.count=_nc;\ +} while(0) + +static void r500SetupPixelShader(r300ContextPtr rmesa) +{ + GLcontext *ctx = rmesa->radeon.glCtx; + struct r500_fragment_program *fp = (struct r500_fragment_program *) + (char *)ctx->FragmentProgram._Current; + int i; + + if (!fp) /* should only happenen once, just after context is created */ + return; + + ((drm_r300_cmd_header_t *) rmesa->hw.r500fp.cmd)->r500fp.count = 0; + ((drm_r300_cmd_header_t *) rmesa->hw.r500fp_const.cmd)->r500fp.count = 0; + + r500TranslateFragmentShader(rmesa, fp); + if (!fp->translated) { + fprintf(stderr, "%s: No valid fragment shader, exiting\n", + __FUNCTION__); + return; + } + + r300SetupTextures(ctx); + + R300_STATECHANGE(rmesa, fp); + rmesa->hw.fp.cmd[R500_FP_PIXSIZE] = fp->max_temp_idx; + + rmesa->hw.fp.cmd[R500_FP_CODE_ADDR] = + R500_US_CODE_START_ADDR(fp->inst_offset) | + R500_US_CODE_END_ADDR(fp->inst_end); + rmesa->hw.fp.cmd[R500_FP_CODE_RANGE] = + R500_US_CODE_RANGE_ADDR(fp->inst_offset) | + R500_US_CODE_RANGE_SIZE(fp->inst_end); + rmesa->hw.fp.cmd[R500_FP_CODE_OFFSET] = + R500_US_CODE_OFFSET_ADDR(0); /* FIXME when we add flow control */ + + R300_STATECHANGE(rmesa, r500fp); + /* Emit our shader... */ + for (i = 0; i < fp->inst_end+1; i++) { + rmesa->hw.r500fp.cmd[i*6+1] = fp->inst[i].inst0; + rmesa->hw.r500fp.cmd[i*6+2] = fp->inst[i].inst1; + rmesa->hw.r500fp.cmd[i*6+3] = fp->inst[i].inst2; + rmesa->hw.r500fp.cmd[i*6+4] = fp->inst[i].inst3; + rmesa->hw.r500fp.cmd[i*6+5] = fp->inst[i].inst4; + rmesa->hw.r500fp.cmd[i*6+6] = fp->inst[i].inst5; + } + + bump_r500fp_count(rmesa->hw.r500fp.cmd, (fp->inst_end + 1) * 6); + + R300_STATECHANGE(rmesa, r500fp_const); + for (i = 0; i < fp->const_nr; i++) { + rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat32(fp->constant[i][0]); + rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat32(fp->constant[i][1]); + rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat32(fp->constant[i][2]); + rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 3] = r300PackFloat32(fp->constant[i][3]); + } + bump_r500fp_const_count(rmesa->hw.r500fp_const.cmd, fp->const_nr * 4); + +} + void r300UpdateShaderStates(r300ContextPtr rmesa) { GLcontext *ctx; ctx = rmesa->radeon.glCtx; r300UpdateTextureState(ctx); + r300SetEarlyZState(ctx); - r300SetupPixelShader(rmesa); - r300SetupTextures(ctx); + GLuint fgdepthsrc = R300_FG_DEPTH_SRC_SCAN; + if (current_fragment_program_writes_depth(ctx)) + fgdepthsrc = R300_FG_DEPTH_SRC_SHADER; + if (fgdepthsrc != rmesa->hw.fg_depth_src.cmd[1]) { + R300_STATECHANGE(rmesa, fg_depth_src); + rmesa->hw.fg_depth_src.cmd[1] = fgdepthsrc; + } + + if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) + r500SetupPixelShader(rmesa); + else + r300SetupPixelShader(rmesa); + + if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) + r500SetupRSUnit(ctx); + else + r300SetupRSUnit(ctx); if ((rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) r300SetupVertexProgram(rmesa); - r300SetupRSUnit(ctx); + } /** @@ -2215,12 +2636,12 @@ void r300InitState(r300ContextPtr r300) switch (ctx->Visual.depthBits) { case 16: r300->state.depth.scale = 1.0 / (GLfloat) 0xffff; - depth_fmt = ZB_FORMAR_DEPTHFORMAT_16BIT_INT_Z; + depth_fmt = R300_DEPTHFORMAT_16BIT_INT_Z; r300->state.stencil.clear = 0x00000000; break; case 24: r300->state.depth.scale = 1.0 / (GLfloat) 0xffffff; - depth_fmt = ZB_FORMAR_DEPTHFORMAT_24BIT_INT_Z; + depth_fmt = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL; r300->state.stencil.clear = 0x00ff0000; break; default: @@ -2249,11 +2670,11 @@ void r300UpdateClipPlanes( GLcontext *ctx ) { r300ContextPtr rmesa = R300_CONTEXT(ctx); GLuint p; - + for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p]; - + R300_STATECHANGE( rmesa, vpucp[p] ); rmesa->hw.vpucp[p].cmd[R300_VPUCP_X] = ip[0]; rmesa->hw.vpucp[p].cmd[R300_VPUCP_Y] = ip[1]; diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c index a732bdb559..8aebd9be3e 100644 --- a/src/mesa/drivers/dri/r300/r300_swtcl.c +++ b/src/mesa/drivers/dri/r300/r300_swtcl.c @@ -78,31 +78,6 @@ do { \ rmesa->swtcl.vertex_attr_count++; \ } while (0) -/* this differs from the VIR0 in emit.c - TODO merge them using another option */ -static GLuint r300VAPInputRoute0(uint32_t * dst, GLvector4f ** attribptr, - int *inputs, GLint * tab, GLuint nr) -{ - GLuint i, dw; - - /* type, inputs, stop bit, size */ - for (i = 0; i + 1 < nr; i += 2) { - dw = (inputs[tab[i]] << 8) | 0x3; - dw |= ((inputs[tab[i + 1]] << 8) | 0x3) << 16; - if (i + 2 == nr) { - dw |= (R300_VAP_INPUT_ROUTE_END << 16); - } - dst[i >> 1] = dw; - } - - if (nr & 1) { - dw = (inputs[tab[nr - 1]] << 8) | 0x3; - dw |= R300_VAP_INPUT_ROUTE_END; - dst[nr >> 1] = dw; - } - - return (nr + 1) >> 1; -} - static void r300SetVertexFormat( GLcontext *ctx ) { r300ContextPtr rmesa = R300_CONTEXT( ctx ); @@ -118,19 +93,24 @@ static void r300SetVertexFormat( GLcontext *ctx ) GLint tab[VERT_ATTRIB_MAX]; int swizzle[VERT_ATTRIB_MAX][4]; GLuint i, nr; + GLuint sz, vap_fmt_1 = 0; DECLARE_RENDERINPUTS(render_inputs_bitset); RENDERINPUTS_COPY(render_inputs_bitset, tnl->render_inputs_bitset); RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset ); RENDERINPUTS_COPY(rmesa->state.render_inputs_bitset, render_inputs_bitset); + vte = rmesa->hw.vte.cmd[1]; + vte &= ~(R300_VTX_XY_FMT | R300_VTX_Z_FMT | R300_VTX_W0_FMT); /* Important: */ if ( VB->NdcPtr != NULL ) { VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; + vte |= R300_VTX_XY_FMT | R300_VTX_Z_FMT; } else { VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr; + vte |= R300_VTX_W0_FMT; } assert( VB->AttribPtr[VERT_ATTRIB_POS] != NULL ); @@ -140,14 +120,15 @@ static void r300SetVertexFormat( GLcontext *ctx ) * build up a hardware vertex. */ if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POS)) { - vap_vte_cntl |= R300_VTX_W0_FMT; + sz = VB->AttribPtr[VERT_ATTRIB_POS]->size; InputsRead |= 1 << VERT_ATTRIB_POS; OutputsWritten |= 1 << VERT_RESULT_HPOS; - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F ); - } else + EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_1F + sz - 1 ); + offset = sz; + } else { + offset = 4; EMIT_PAD(4 * sizeof(float)); - - offset = 4; + } if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) { EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F ); @@ -156,18 +137,19 @@ static void r300SetVertexFormat( GLcontext *ctx ) } if (RENDERINPUTS_TEST(index_bitset, _TNL_ATTRIB_COLOR0)) { + sz = VB->AttribPtr[VERT_ATTRIB_COLOR0]->size; rmesa->swtcl.coloroffset = offset; InputsRead |= 1 << VERT_ATTRIB_COLOR0; OutputsWritten |= 1 << VERT_RESULT_COL0; - EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4F ); + EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_1F + sz - 1 ); + offset += sz; } - offset += 4; - rmesa->swtcl.specoffset = 0; if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) { + sz = VB->AttribPtr[VERT_ATTRIB_COLOR1]->size; rmesa->swtcl.specoffset = offset; - EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4F ); + EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_1F + sz - 1 ); InputsRead |= 1 << VERT_ATTRIB_COLOR1; OutputsWritten |= 1 << VERT_RESULT_COL1; } @@ -177,9 +159,11 @@ static void r300SetVertexFormat( GLcontext *ctx ) for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) { + sz = VB->TexCoordPtr[i]->size; InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i); OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i); - EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_4F ); + EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_1F + sz - 1 ); + vap_fmt_1 |= sz << (3 * i); } } } @@ -238,7 +222,7 @@ static void r300SetVertexFormat( GLcontext *ctx ) R300_STATECHANGE(rmesa, vof); rmesa->hw.vof.cmd[R300_VOF_CNTL_0] = r300VAPOutputCntl0(ctx, OutputsWritten); - rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = r300VAPOutputCntl1(ctx, OutputsWritten); + rmesa->hw.vof.cmd[R300_VOF_CNTL_1] = vap_fmt_1; rmesa->swtcl.vertex_size = _tnl_install_attrs( ctx, @@ -250,7 +234,7 @@ static void r300SetVertexFormat( GLcontext *ctx ) RENDERINPUTS_COPY( rmesa->tnl_index_bitset, index_bitset ); - vte = rmesa->hw.vte.cmd[1]; + R300_STATECHANGE(rmesa, vte); rmesa->hw.vte.cmd[1] = vte; rmesa->hw.vte.cmd[2] = rmesa->swtcl.vertex_size; @@ -591,6 +575,7 @@ static void r300RenderStart(GLcontext *ctx) r300ChooseRenderState(ctx); r300SetVertexFormat(ctx); + r300UpdateShaders(rmesa); r300UpdateShaderStates(rmesa); r300EmitCacheFlush(rmesa); diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 43d1406da3..78fa75228e 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -398,16 +398,18 @@ static void r300SetTexImages(r300ContextPtr rmesa, R300_TX_HEIGHTMASK_SHIFT)) | ((numLevels - 1) << R300_TX_MAX_MIP_LEVEL_SHIFT); + t->pitch = 0; + /* Only need to round to nearest 32 for textures, but the blitter * requires 64-byte aligned pitches, and we may/may not need the * blitter. NPOT only! */ if (baseImage->IsCompressed) { - t->pitch = + t->pitch |= (tObj->Image[0][t->base.firstLevel]->Width + 63) & ~(63); } else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) { unsigned int align = blitWidth - 1; - t->pitch = ((tObj->Image[0][t->base.firstLevel]->Width * + t->pitch |= ((tObj->Image[0][t->base.firstLevel]->Width * texelBytes) + 63) & ~(63); t->size |= R300_TX_SIZE_TXPITCH_EN; if (!t->image_override) @@ -415,11 +417,18 @@ static void r300SetTexImages(r300ContextPtr rmesa, (((tObj->Image[0][t->base.firstLevel]->Width) + align) & ~align) - 1; } else { - t->pitch = + t->pitch |= ((tObj->Image[0][t->base.firstLevel]->Width * texelBytes) + 63) & ~(63); } + if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) { + if (tObj->Image[0][t->base.firstLevel]->Width > 2048) + t->pitch_reg |= R500_TXWIDTH_BIT11; + if (tObj->Image[0][t->base.firstLevel]->Height > 2048) + t->pitch_reg |= R500_TXHEIGHT_BIT11; + } + t->dirty_state = TEX_ALL; /* FYI: r300UploadTexImages( rmesa, t ) used to be called here */ @@ -573,6 +582,7 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, struct gl_texture_object *tObj = _mesa_lookup_texture(rmesa->radeon.glCtx, texname); r300TexObjPtr t; + uint32_t pitch_val; if (!tObj) return; @@ -585,28 +595,30 @@ void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, return; t->offset = offset; - t->pitch_reg = pitch; + t->pitch_reg &= (1 << 13) -1; + pitch_val = pitch; switch (depth) { case 32: t->format = R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); t->filter |= tx_table[2].filter; - t->pitch_reg /= 4; + pitch_val /= 4; break; case 24: default: t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8); t->filter |= tx_table[4].filter; - t->pitch_reg /= 4; + pitch_val /= 4; break; case 16: t->format = R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5); t->filter |= tx_table[5].filter; - t->pitch_reg /= 2; + pitch_val /= 2; break; } + pitch_val--; - t->pitch_reg--; + t->pitch_reg |= pitch_val; } static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit) diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index e91d96852d..861f0427cf 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -1426,6 +1426,8 @@ void r300SelectVertexShader(r300ContextPtr r300) GLint wpos_idx; vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current; + wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead; + wanted_key.OutputsWritten = vpc->mesa_program.Base.OutputsWritten; InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; wpos_idx = -1; @@ -1439,11 +1441,9 @@ void r300SelectVertexShader(r300ContextPtr r300) _mesa_exit(-1); } - InputsRead |= (FRAG_BIT_TEX0 << i); + wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i); wpos_idx = i; } - wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead; - wanted_key.OutputsWritten = vpc->mesa_program.Base.OutputsWritten; add_outputs(&wanted_key, VERT_RESULT_HPOS); diff --git a/src/mesa/drivers/dri/r300/r500_fragprog.c b/src/mesa/drivers/dri/r300/r500_fragprog.c new file mode 100644 index 0000000000..b967aa2d73 --- /dev/null +++ b/src/mesa/drivers/dri/r300/r500_fragprog.c @@ -0,0 +1,1667 @@ +/* + * Copyright (C) 2005 Ben Skeggs. + * + * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> + * Adaptation and modification for ATI/AMD Radeon R500 GPU chipsets. + * + * 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. + * + */ + +/** + * \file + * + * \author Ben Skeggs <darktama@iinet.net.au> + * + * \author Jerome Glisse <j.glisse@gmail.com> + * + * \author Corbin Simpson <MostAwesomeDude@gmail.com> + * + * \todo Depth write, WPOS/FOGC inputs + * + * \todo FogOption + * + * \todo Verify results of opcodes for accuracy, I've only checked them in + * specific cases. + */ + +#include "glheader.h" +#include "macros.h" +#include "enums.h" +#include "shader/prog_instruction.h" +#include "shader/prog_parameter.h" +#include "shader/prog_print.h" + +#include "r300_context.h" +#include "r500_fragprog.h" +#include "r300_reg.h" +#include "r300_state.h" + +/* + * Useful macros and values + */ +#define ERROR(fmt, args...) do { \ + fprintf(stderr, "%s::%s(): " fmt "\n", \ + __FILE__, __FUNCTION__, ##args); \ + fp->error = GL_TRUE; \ + } while(0) + +#define COMPILE_STATE struct r300_pfs_compile_state *cs = fp->cs + +#define R500_US_NUM_TEMP_REGS 128 +#define R500_US_NUM_CONST_REGS 256 + +/* "Register" flags */ +#define REG_CONSTANT (1 << 8) +#define REG_SRC_REL (1 << 9) +#define REG_DEST_REL (1 << 7) + +/* Swizzle tools */ +#define R500_SWIZZLE_ZERO 4 +#define R500_SWIZZLE_HALF 5 +#define R500_SWIZZLE_ONE 6 +#define R500_SWIZ_RGB_ZERO ((4 << 0) | (4 << 3) | (4 << 6)) +#define R500_SWIZ_RGB_ONE ((6 << 0) | (6 << 3) | (6 << 6)) +#define R500_SWIZ_RGB_RGB ((0 << 0) | (1 << 3) | (2 << 6)) +#define R500_SWIZ_MOD_NEG 1 +#define R500_SWIZ_MOD_ABS 2 +#define R500_SWIZ_MOD_NEG_ABS 3 +/* Swizzles for inst2 */ +#define MAKE_SWIZ_TEX_STRQ(x) (x << 8) +#define MAKE_SWIZ_TEX_RGBA(x) (x << 24) +/* Swizzles for inst3 */ +#define MAKE_SWIZ_RGB_A(x) (x << 2) +#define MAKE_SWIZ_RGB_B(x) (x << 15) +/* Swizzles for inst4 */ +#define MAKE_SWIZ_ALPHA_A(x) (x << 14) +#define MAKE_SWIZ_ALPHA_B(x) (x << 21) +/* Swizzle for inst5 */ +#define MAKE_SWIZ_RGBA_C(x) (x << 14) +#define MAKE_SWIZ_ALPHA_C(x) (x << 27) + +/* Writemasks */ +#define R500_WRITEMASK_G 0x2 +#define R500_WRITEMASK_B 0x4 +#define R500_WRITEMASK_RGB 0x7 +#define R500_WRITEMASK_A 0x8 +#define R500_WRITEMASK_AR 0x9 +#define R500_WRITEMASK_AG 0xA +#define R500_WRITEMASK_ARG 0xB +#define R500_WRITEMASK_AB 0xC +#define R500_WRITEMASK_ARGB 0xF + +/* 1/(2pi), needed for quick modulus in trig insts + * Thanks to glisse for pointing out how to do it! */ +static const GLfloat RCP_2PI[] = {0.15915494309189535, + 0.15915494309189535, + 0.15915494309189535, + 0.15915494309189535}; + +static const GLfloat LIT[] = {127.999999, + 127.999999, + 127.999999, + -127.999999}; + +static void dump_program(struct r500_fragment_program *fp); + +static inline GLuint make_rgb_swizzle(struct prog_src_register src) { + GLuint swiz = 0x0; + GLuint temp; + /* This could be optimized, but it should be plenty fast already. */ + int i; + for (i = 0; i < 3; i++) { + temp = GET_SWZ(src.Swizzle, i); + /* Fix SWIZZLE_ONE */ + if (temp == 5) temp++; + swiz |= temp << i*3; + } + if (src.NegateBase) + swiz |= (R500_SWIZ_MOD_NEG << 9); + return swiz; +} + +static inline GLuint make_rgba_swizzle(GLuint src) { + GLuint swiz = 0x0; + GLuint temp; + int i; + for (i = 0; i < 4; i++) { + temp = GET_SWZ(src, i); + /* Fix SWIZZLE_ONE */ + if (temp == 5) temp++; + swiz |= temp << i*3; + } + return swiz; +} + +static inline GLuint make_alpha_swizzle(struct prog_src_register src) { + GLuint swiz = GET_SWZ(src.Swizzle, 3); + + if (swiz == 5) swiz++; + + if (src.NegateBase) + swiz |= (R500_SWIZ_MOD_NEG << 3); + + return swiz; +} + +static inline GLuint make_sop_swizzle(struct prog_src_register src) { + GLuint swiz = GET_SWZ(src.Swizzle, 0); + + if (swiz == 5) swiz++; + return swiz; +} + +static inline GLuint make_strq_swizzle(struct prog_src_register src) { + GLuint swiz = 0x0, temp = 0x0; + int i; + for (i = 0; i < 4; i++) { + temp = GET_SWZ(src.Swizzle, i) & 0x3; + swiz |= temp << i*2; + } + return swiz; +} + +static int get_temp(struct r500_fragment_program *fp, int slot) { + + COMPILE_STATE; + + int r = fp->temp_reg_offset + cs->temp_in_use + slot; + + if (r > R500_US_NUM_TEMP_REGS) { + ERROR("Too many temporary registers requested, can't compile!\n"); + } + + return r; +} + +/* Borrowed verbatim from r300_fragprog since it hasn't changed. */ +static GLuint emit_const4fv(struct r500_fragment_program *fp, + const GLfloat * cp) +{ + GLuint reg = 0x0; + int index; + + for (index = 0; index < fp->const_nr; ++index) { + if (fp->constant[index] == cp) + break; + } + + if (index >= fp->const_nr) { + if (index >= R500_US_NUM_CONST_REGS) { + ERROR("Out of hw constants!\n"); + return reg; + } + + fp->const_nr++; + fp->constant[index] = cp; + } + + reg = index | REG_CONSTANT; + return reg; +} + +static GLuint make_src(struct r500_fragment_program *fp, struct prog_src_register src) { + COMPILE_STATE; + GLuint reg; + switch (src.File) { + case PROGRAM_TEMPORARY: + reg = src.Index + fp->temp_reg_offset; + break; + case PROGRAM_INPUT: + reg = cs->inputs[src.Index].reg; + break; + case PROGRAM_LOCAL_PARAM: + reg = emit_const4fv(fp, + fp->mesa_program.Base.LocalParams[src. + Index]); + break; + case PROGRAM_ENV_PARAM: + reg = emit_const4fv(fp, + fp->ctx->FragmentProgram.Parameters[src. + Index]); + break; + case PROGRAM_STATE_VAR: + case PROGRAM_NAMED_PARAM: + case PROGRAM_CONSTANT: + reg = emit_const4fv(fp, fp->mesa_program.Base.Parameters-> + ParameterValues[src.Index]); + break; + default: + ERROR("Can't handle src.File %x\n", src.File); + reg = 0x0; + break; + } + return reg; +} + +static GLuint make_dest(struct r500_fragment_program *fp, struct prog_dst_register dest) { + GLuint reg; + switch (dest.File) { + case PROGRAM_TEMPORARY: + reg = dest.Index + fp->temp_reg_offset; + break; + case PROGRAM_OUTPUT: + /* Eventually we may need to handle multiple + * rendering targets... */ + reg = dest.Index; + break; + default: + ERROR("Can't handle dest.File %x\n", dest.File); + reg = 0x0; + break; + } + return reg; +} + +static void emit_tex(struct r500_fragment_program *fp, + struct prog_instruction *fpi, int dest, int counter) +{ + int hwsrc, hwdest; + GLuint mask; + + mask = fpi->DstReg.WriteMask << 11; + hwsrc = make_src(fp, fpi->SrcReg[0]); + + if (fpi->DstReg.File == PROGRAM_OUTPUT) { + hwdest = get_temp(fp, 0); + } else { + hwdest = dest; + } + + fp->inst[counter].inst0 = R500_INST_TYPE_TEX | mask + | R500_INST_TEX_SEM_WAIT; + + fp->inst[counter].inst1 = R500_TEX_ID(fpi->TexSrcUnit) + | R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED; + + if (fpi->TexSrcTarget == TEXTURE_RECT_INDEX) + fp->inst[counter].inst1 |= R500_TEX_UNSCALED; + + switch (fpi->Opcode) { + case OPCODE_KIL: + fp->inst[counter].inst1 |= R500_TEX_INST_TEXKILL; + break; + case OPCODE_TEX: + fp->inst[counter].inst1 |= R500_TEX_INST_LD; + break; + case OPCODE_TXB: + fp->inst[counter].inst1 |= R500_TEX_INST_LODBIAS; + break; + case OPCODE_TXP: + fp->inst[counter].inst1 |= R500_TEX_INST_PROJ; + break; + default: + ERROR("emit_tex can't handle opcode %x\n", fpi->Opcode); + } + + fp->inst[counter].inst2 = R500_TEX_SRC_ADDR(hwsrc) + | MAKE_SWIZ_TEX_STRQ(make_strq_swizzle(fpi->SrcReg[0])) + /* | R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G + | R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A */ + | R500_TEX_DST_ADDR(hwdest) + | R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G + | R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A; + + fp->inst[counter].inst3 = 0x0; + fp->inst[counter].inst4 = 0x0; + fp->inst[counter].inst5 = 0x0; + + if (fpi->DstReg.File == PROGRAM_OUTPUT) { + counter++; + fp->inst[counter].inst0 = R500_INST_TYPE_OUT + | R500_INST_TEX_SEM_WAIT | (mask << 4); + fp->inst[counter].inst1 = R500_RGB_ADDR0(get_temp(fp, 0)); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(get_temp(fp, 0)); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_RGB) + | R500_ALU_RGB_SEL_B_SRC0 + | MAKE_SWIZ_RGB_B(R500_SWIZ_RGB_RGB) + | R500_ALU_RGB_OMOD_DISABLE; + fp->inst[counter].inst4 = R500_ALPHA_OP_CMP + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(R500_ALPHA_SWIZ_A_A) + | R500_ALPHA_SEL_B_SRC0 | MAKE_SWIZ_ALPHA_B(R500_ALPHA_SWIZ_A_A) + | R500_ALPHA_OMOD_DISABLE; + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_CMP + | R500_ALU_RGBA_ADDRD(dest) + | MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_ZERO) + | MAKE_SWIZ_ALPHA_C(R500_SWIZZLE_ZERO); + } +} + +static void emit_alu(struct r500_fragment_program *fp, int counter, struct prog_instruction *fpi) { + /* Ideally, we shouldn't have to explicitly clear memory here! */ + fp->inst[counter].inst0 = 0x0; + fp->inst[counter].inst1 = 0x0; + fp->inst[counter].inst2 = 0x0; + fp->inst[counter].inst3 = 0x0; + fp->inst[counter].inst4 = 0x0; + fp->inst[counter].inst5 = 0x0; + + if (fpi->DstReg.File == PROGRAM_OUTPUT) { + fp->inst[counter].inst0 = R500_INST_TYPE_OUT; + + if (fpi->DstReg.Index == FRAG_RESULT_COLR) + fp->inst[counter].inst0 |= (fpi->DstReg.WriteMask << 15); + + if (fpi->DstReg.Index == FRAG_RESULT_DEPR) { + fp->inst[counter].inst4 |= R500_ALPHA_W_OMASK; + /* Notify the state emission! */ + fp->writes_depth = GL_TRUE; + } + } else { + fp->inst[counter].inst0 = R500_INST_TYPE_ALU + /* pixel_mask */ + | (fpi->DstReg.WriteMask << 11); + } + + fp->inst[counter].inst0 |= R500_INST_TEX_SEM_WAIT; +} + +static void emit_mov(struct r500_fragment_program *fp, int counter, struct prog_instruction *fpi, GLuint src_reg, GLuint swizzle, GLuint dest) { + /* The r3xx shader uses MAD to implement MOV. We are using CMP, since + * it is technically more accurate and recommended by ATI/AMD. */ + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src_reg); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src_reg); + /* (De)mangle the swizzle from Mesa to R500. */ + swizzle = make_rgba_swizzle(swizzle); + /* 0x1FF is 9 bits, size of an RGB swizzle. */ + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A((swizzle & 0x1ff)) + | R500_ALU_RGB_SEL_B_SRC0 + | MAKE_SWIZ_RGB_B((swizzle & 0x1ff)) + | R500_ALU_RGB_OMOD_DISABLE; + fp->inst[counter].inst4 |= R500_ALPHA_OP_CMP + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(GET_SWZ(swizzle, 3)) + | R500_ALPHA_SEL_B_SRC0 | MAKE_SWIZ_ALPHA_B(GET_SWZ(swizzle, 3)) + | R500_ALPHA_OMOD_DISABLE; + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_CMP + | R500_ALU_RGBA_ADDRD(dest) + | MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_ZERO) + | MAKE_SWIZ_ALPHA_C(R500_SWIZZLE_ZERO); +} + +static void emit_mad(struct r500_fragment_program *fp, int counter, struct prog_instruction *fpi, int one, int two, int three) { + /* Note: This code was all Corbin's. Corbin is a rather hackish coder. + * If you can make it pretty or fast, please do so! */ + emit_alu(fp, counter, fpi); + /* Common MAD stuff */ + fp->inst[counter].inst4 |= R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(make_dest(fp, fpi->DstReg)); + fp->inst[counter].inst5 |= R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(make_dest(fp, fpi->DstReg)); + switch (one) { + case 0: + case 1: + case 2: + fp->inst[counter].inst1 |= R500_RGB_ADDR0(make_src(fp, fpi->SrcReg[one])); + fp->inst[counter].inst2 |= R500_ALPHA_ADDR0(make_src(fp, fpi->SrcReg[one])); + fp->inst[counter].inst3 |= R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(make_rgb_swizzle(fpi->SrcReg[one])); + fp->inst[counter].inst4 |= R500_ALPHA_SEL_A_SRC0 + | MAKE_SWIZ_ALPHA_A(make_alpha_swizzle(fpi->SrcReg[one])); + break; + case R500_SWIZZLE_ZERO: + fp->inst[counter].inst3 |= MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_ZERO); + fp->inst[counter].inst4 |= MAKE_SWIZ_ALPHA_A(R500_SWIZZLE_ZERO); + break; + case R500_SWIZZLE_ONE: + fp->inst[counter].inst3 |= MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_ONE); + fp->inst[counter].inst4 |= MAKE_SWIZ_ALPHA_A(R500_SWIZZLE_ONE); + break; + default: + ERROR("Bad src index in emit_mad: %d\n", one); + break; + } + switch (two) { + case 0: + case 1: + case 2: + fp->inst[counter].inst1 |= R500_RGB_ADDR1(make_src(fp, fpi->SrcReg[two])); + fp->inst[counter].inst2 |= R500_ALPHA_ADDR1(make_src(fp, fpi->SrcReg[two])); + fp->inst[counter].inst3 |= R500_ALU_RGB_SEL_B_SRC1 + | MAKE_SWIZ_RGB_B(make_rgb_swizzle(fpi->SrcReg[two])); + fp->inst[counter].inst4 |= R500_ALPHA_SEL_B_SRC1 + | MAKE_SWIZ_ALPHA_B(make_alpha_swizzle(fpi->SrcReg[two])); + break; + case R500_SWIZZLE_ZERO: + fp->inst[counter].inst3 |= MAKE_SWIZ_RGB_B(R500_SWIZ_RGB_ZERO); + fp->inst[counter].inst4 |= MAKE_SWIZ_ALPHA_B(R500_SWIZZLE_ZERO); + break; + case R500_SWIZZLE_ONE: + fp->inst[counter].inst3 |= MAKE_SWIZ_RGB_B(R500_SWIZ_RGB_ONE); + fp->inst[counter].inst4 |= MAKE_SWIZ_ALPHA_B(R500_SWIZZLE_ONE); + break; + default: + ERROR("Bad src index in emit_mad: %d\n", two); + break; + } + switch (three) { + case 0: + case 1: + case 2: + fp->inst[counter].inst1 |= R500_RGB_ADDR2(make_src(fp, fpi->SrcReg[three])); + fp->inst[counter].inst2 |= R500_ALPHA_ADDR2(make_src(fp, fpi->SrcReg[three])); + fp->inst[counter].inst5 |= R500_ALU_RGBA_SEL_C_SRC2 + | MAKE_SWIZ_RGBA_C(make_rgb_swizzle(fpi->SrcReg[three])) + | R500_ALU_RGBA_ALPHA_SEL_C_SRC2 + | MAKE_SWIZ_ALPHA_C(make_alpha_swizzle(fpi->SrcReg[three])); + break; + case R500_SWIZZLE_ZERO: + fp->inst[counter].inst5 |= MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_ZERO) + | MAKE_SWIZ_ALPHA_C(R500_SWIZZLE_ZERO); + break; + case R500_SWIZZLE_ONE: + fp->inst[counter].inst5 |= MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_ONE) + | MAKE_SWIZ_ALPHA_C(R500_SWIZZLE_ONE); + break; + default: + ERROR("Bad src index in emit_mad: %d\n", three); + break; + } +} + +static void emit_sop(struct r500_fragment_program *fp, int counter, struct prog_instruction *fpi, int opcode, GLuint src, GLuint swiz, GLuint dest) { + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src); + fp->inst[counter].inst4 |= R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(swiz); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_SOP + | R500_ALU_RGBA_ADDRD(dest); + switch (opcode) { + case OPCODE_COS: + fp->inst[counter].inst4 |= R500_ALPHA_OP_COS; + break; + case OPCODE_EX2: + fp->inst[counter].inst4 |= R500_ALPHA_OP_EX2; + break; + case OPCODE_LG2: + fp->inst[counter].inst4 |= R500_ALPHA_OP_LN2; + break; + case OPCODE_RCP: + fp->inst[counter].inst4 |= R500_ALPHA_OP_RCP; + break; + case OPCODE_RSQ: + fp->inst[counter].inst4 |= R500_ALPHA_OP_RSQ; + break; + case OPCODE_SIN: + fp->inst[counter].inst4 |= R500_ALPHA_OP_SIN; + break; + default: + ERROR("Bad opcode in emit_sop: %d\n", opcode); + break; + } +} + +static GLboolean parse_program(struct r500_fragment_program *fp) +{ + struct gl_fragment_program *mp = &fp->mesa_program; + const struct prog_instruction *inst = mp->Base.Instructions; + struct prog_instruction *fpi; + GLuint src[3], dest = 0; + int temp_swiz, counter = 0; + + if (!inst || inst[0].Opcode == OPCODE_END) { + ERROR("The program is empty!\n"); + return GL_FALSE; + } + + for (fpi = mp->Base.Instructions; fpi->Opcode != OPCODE_END; fpi++) { + + if (fpi->Opcode != OPCODE_KIL) { + dest = make_dest(fp, fpi->DstReg); + } + + switch (fpi->Opcode) { + case OPCODE_ABS: + emit_mov(fp, counter, fpi, make_src(fp, fpi->SrcReg[0]), fpi->SrcReg[0].Swizzle, dest); + fp->inst[counter].inst3 |= R500_ALU_RGB_MOD_A_ABS + | R500_ALU_RGB_MOD_B_ABS; + fp->inst[counter].inst4 |= R500_ALPHA_MOD_A_ABS + | R500_ALPHA_MOD_B_ABS; + break; + case OPCODE_ADD: + /* Variation on MAD: 1*src0+src1 */ + emit_mad(fp, counter, fpi, R500_SWIZZLE_ONE, 0, 1); + break; + case OPCODE_CMP: + /* This inst's selects need to be swapped as follows: + * 0 -> C ; 1 -> B ; 2 -> A */ + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = make_src(fp, fpi->SrcReg[1]); + src[2] = make_src(fp, fpi->SrcReg[2]); + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[2]) + | R500_RGB_ADDR1(src[1]) | R500_RGB_ADDR2(src[0]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[2]) + | R500_ALPHA_ADDR1(src[1]) | R500_ALPHA_ADDR2(src[0]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(make_rgb_swizzle(fpi->SrcReg[2])) + | R500_ALU_RGB_SEL_B_SRC1 | MAKE_SWIZ_RGB_B(make_rgb_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst4 |= R500_ALPHA_OP_CMP + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(make_alpha_swizzle(fpi->SrcReg[2])) + | R500_ALPHA_SEL_B_SRC1 | MAKE_SWIZ_ALPHA_B(make_alpha_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_CMP + | R500_ALU_RGBA_ADDRD(dest) + | R500_ALU_RGBA_SEL_C_SRC2 + | MAKE_SWIZ_RGBA_C(make_rgb_swizzle(fpi->SrcReg[0])) + | R500_ALU_RGBA_ALPHA_SEL_C_SRC2 + | MAKE_SWIZ_ALPHA_C(make_alpha_swizzle(fpi->SrcReg[0])); + break; + case OPCODE_COS: + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = emit_const4fv(fp, RCP_2PI); + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | R500_INST_TEX_SEM_WAIT + | (R500_WRITEMASK_ARGB << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) + | R500_RGB_ADDR1(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) + | R500_ALPHA_ADDR1(src[1]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_RGB) + | R500_ALU_RGB_SEL_B_SRC1 | MAKE_SWIZ_RGB_B(R500_SWIZ_RGB_RGB); + fp->inst[counter].inst4 = R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(get_temp(fp, 0)) + | R500_ALPHA_SEL_A_SRC0 | R500_ALPHA_SWIZ_A_A + | R500_ALPHA_SEL_B_SRC1 | R500_ALPHA_SWIZ_B_A; + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(get_temp(fp, 0)) + | MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_ZERO) + | MAKE_SWIZ_ALPHA_C(R500_SWIZZLE_ZERO); + counter++; + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | (R500_WRITEMASK_ARGB << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR0(get_temp(fp, 0)); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(get_temp(fp, 0)); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_RGB); + fp->inst[counter].inst4 = R500_ALPHA_OP_FRC + | R500_ALPHA_ADDRD(get_temp(fp, 1)) + | R500_ALPHA_SEL_A_SRC0 | R500_ALPHA_SWIZ_A_A; + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_FRC + | R500_ALU_RGBA_ADDRD(get_temp(fp, 1)); + counter++; + emit_sop(fp, counter, fpi, OPCODE_COS, get_temp(fp, 1), make_sop_swizzle(fpi->SrcReg[0]), dest); + break; + case OPCODE_DP3: + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = make_src(fp, fpi->SrcReg[1]); + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) + | R500_RGB_ADDR1(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) + | R500_ALPHA_ADDR1(src[1]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(make_rgb_swizzle(fpi->SrcReg[0])) + | R500_ALU_RGB_SEL_B_SRC1 | MAKE_SWIZ_RGB_B(make_rgb_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst4 |= R500_ALPHA_OP_DP + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(make_alpha_swizzle(fpi->SrcReg[0])) + | R500_ALPHA_SEL_B_SRC1 | MAKE_SWIZ_ALPHA_B(make_alpha_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_DP3 + | R500_ALU_RGBA_ADDRD(dest); + break; + case OPCODE_DP4: + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = make_src(fp, fpi->SrcReg[1]); + /* Based on DP3 */ + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) + | R500_RGB_ADDR1(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) + | R500_ALPHA_ADDR1(src[1]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(make_rgb_swizzle(fpi->SrcReg[0])) + | R500_ALU_RGB_SEL_B_SRC1 | MAKE_SWIZ_RGB_B(make_rgb_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst4 |= R500_ALPHA_OP_DP + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(make_alpha_swizzle(fpi->SrcReg[0])) + | R500_ALPHA_SEL_B_SRC1 | MAKE_SWIZ_ALPHA_B(make_alpha_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_DP4 + | R500_ALU_RGBA_ADDRD(dest); + break; + case OPCODE_DPH: + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = make_src(fp, fpi->SrcReg[1]); + /* Based on DP3 */ + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) + | R500_RGB_ADDR1(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) + | R500_ALPHA_ADDR1(src[1]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(make_rgb_swizzle(fpi->SrcReg[0])) + | R500_ALU_RGB_SEL_B_SRC1 | MAKE_SWIZ_RGB_B(make_rgb_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst4 |= R500_ALPHA_OP_DP + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(R500_SWIZZLE_ONE) + | R500_ALPHA_SEL_B_SRC1 | MAKE_SWIZ_ALPHA_B(make_alpha_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_DP4 + | R500_ALU_RGBA_ADDRD(dest); + break; + case OPCODE_DST: + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = make_src(fp, fpi->SrcReg[1]); + /* [1, src0.y*src1.y, src0.z, src1.w] + * So basically MUL with lotsa swizzling. */ + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) + | R500_RGB_ADDR1(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) + | R500_ALPHA_ADDR1(src[1]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | R500_ALU_RGB_SEL_B_SRC1; + /* Select [1, y, z, 1] */ + temp_swiz = (make_rgb_swizzle(fpi->SrcReg[0]) & ~0x7) | R500_SWIZZLE_ONE; + fp->inst[counter].inst3 |= MAKE_SWIZ_RGB_A(temp_swiz); + /* Select [1, y, 1, w] */ + temp_swiz = (make_rgb_swizzle(fpi->SrcReg[0]) & ~0x1c7) | R500_SWIZZLE_ONE | (R500_SWIZZLE_ONE << 6); + fp->inst[counter].inst3 |= MAKE_SWIZ_RGB_B(temp_swiz); + fp->inst[counter].inst4 |= R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(R500_SWIZZLE_ONE) + | R500_ALPHA_SEL_B_SRC1 | MAKE_SWIZ_ALPHA_B(make_alpha_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(dest) + | MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_ZERO) + | MAKE_SWIZ_ALPHA_C(R500_SWIZZLE_ZERO); + break; + case OPCODE_EX2: + src[0] = make_src(fp, fpi->SrcReg[0]); + emit_sop(fp, counter, fpi, OPCODE_EX2, src[0], make_sop_swizzle(fpi->SrcReg[0]), dest); + break; + case OPCODE_FLR: + src[0] = make_src(fp, fpi->SrcReg[0]); + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | (R500_WRITEMASK_ARGB << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(make_rgb_swizzle(fpi->SrcReg[0])); + fp->inst[counter].inst4 |= R500_ALPHA_OP_FRC + | R500_ALPHA_ADDRD(get_temp(fp, 0)) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(make_alpha_swizzle(fpi->SrcReg[0])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_FRC + | R500_ALU_RGBA_ADDRD(get_temp(fp, 0)); + counter++; + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) + | R500_RGB_ADDR1(get_temp(fp, 0)); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) + | R500_ALPHA_ADDR1(get_temp(fp, 0)); + fp->inst[counter].inst3 = MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_ONE) + | R500_ALU_RGB_SEL_B_SRC0 | MAKE_SWIZ_RGB_B(make_rgb_swizzle(fpi->SrcReg[0])); + fp->inst[counter].inst4 = R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SWIZ_A_A + | R500_ALPHA_SEL_B_SRC0 | MAKE_SWIZ_ALPHA_B(make_alpha_swizzle(fpi->SrcReg[0])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(dest) + | R500_ALU_RGBA_SEL_C_SRC1 + | MAKE_SWIZ_RGBA_C(make_rgb_swizzle(fpi->SrcReg[0])) + | R500_ALU_RGBA_ALPHA_SEL_C_SRC1 + | MAKE_SWIZ_ALPHA_C(make_alpha_swizzle(fpi->SrcReg[0])) + | R500_ALU_RGBA_MOD_C_NEG; + break; + case OPCODE_FRC: + src[0] = make_src(fp, fpi->SrcReg[0]); + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(make_rgb_swizzle(fpi->SrcReg[0])); + fp->inst[counter].inst4 |= R500_ALPHA_OP_FRC + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(make_alpha_swizzle(fpi->SrcReg[0])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_FRC + | R500_ALU_RGBA_ADDRD(dest); + break; + case OPCODE_LG2: + src[0] = make_src(fp, fpi->SrcReg[0]); + emit_sop(fp, counter, fpi, OPCODE_LG2, src[0], make_sop_swizzle(fpi->SrcReg[0]), dest); + break; + case OPCODE_LIT: + /* To be honest, I have no idea how I came up with the following. + * All I know is that it's based on the r3xx stuff, and was + * concieved with the help of NyQuil. Mmm, MyQuil. */ + + /* First instruction */ + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = emit_const4fv(fp, LIT); + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | R500_INST_TEX_SEM_WAIT + | (R500_WRITEMASK_ARG << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) | R500_RGB_ADDR1(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) | R500_ALPHA_ADDR1(src[1]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(make_rgb_swizzle(fpi->SrcReg[0])) + | MAKE_SWIZ_RGB_B(R500_SWIZ_RGB_ZERO); + fp->inst[counter].inst4 = R500_ALPHA_OP_MAX + | R500_ALPHA_ADDRD(get_temp(fp, 0)) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(make_alpha_swizzle(fpi->SrcReg[0])) + | R500_ALPHA_SEL_B_SRC1 | R500_ALPHA_SWIZ_B_A; + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAX + | R500_ALU_RGBA_ADDRD(get_temp(fp, 0)); + counter++; + /* Second instruction */ + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | (R500_WRITEMASK_AB << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR0(get_temp(fp, 0)) | R500_RGB_ADDR1(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(get_temp(fp, 0)); + /* Select [w, w, w, y] */ + temp_swiz = 3 | (3 << 3) | (3 << 6); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(temp_swiz) + | R500_ALU_RGB_SEL_B_SRC1 + | MAKE_SWIZ_RGB_B(R500_SWIZ_RGB_RGB); + fp->inst[counter].inst4 = R500_ALPHA_OP_LN2 + | R500_ALPHA_ADDRD(get_temp(fp, 0)) + | R500_ALPHA_SEL_A_SRC0 | R500_ALPHA_SWIZ_A_G; + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MIN + | R500_ALU_RGBA_ADDRD(get_temp(fp, 0)); + counter++; + /* Third instruction */ + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | (R500_WRITEMASK_AG << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR0(get_temp(fp, 0)); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(get_temp(fp, 0)); + /* Select [x, x, x, z] */ + temp_swiz = 0; + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(temp_swiz) + | R500_ALU_RGB_SEL_B_SRC0 + | MAKE_SWIZ_RGB_B(R500_SWIZ_RGB_ONE); + fp->inst[counter].inst4 = R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(get_temp(fp, 1)) + | R500_ALPHA_SEL_A_SRC0 | R500_ALPHA_SWIZ_A_A + | R500_ALPHA_SEL_B_SRC0 | R500_ALPHA_SWIZ_B_B; + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(get_temp(fp, 1)) + | MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_ZERO) + | R500_ALU_RGBA_A_SWIZ_0; + counter++; + /* Fourth instruction */ + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | (R500_WRITEMASK_AR << 11); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(get_temp(fp, 0)); + fp->inst[counter].inst3 = MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_ONE) + | MAKE_SWIZ_RGB_B(R500_SWIZ_RGB_ONE); + fp->inst[counter].inst4 = R500_ALPHA_OP_EX2 + | R500_ALPHA_ADDRD(get_temp(fp, 0)) + | R500_ALPHA_SEL_A_SRC0 | R500_ALPHA_SWIZ_A_A; + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(get_temp(fp, 0)) + | MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_ZERO) + | MAKE_SWIZ_ALPHA_C(R500_SWIZZLE_ZERO); + counter++; + /* Fifth instruction */ + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | (R500_WRITEMASK_AB << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR0(get_temp(fp, 0)); + /* Select [w, w, w] */ + temp_swiz = 3 | (3 << 3) | (3 << 6); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_ZERO) + | R500_ALU_RGB_SEL_B_SRC0 + | MAKE_SWIZ_RGB_B(temp_swiz); + fp->inst[counter].inst4 |= R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(get_temp(fp, 0)) + | R500_ALPHA_SWIZ_A_1 + | R500_ALPHA_SWIZ_B_1; + /* Select [-y, -y, -y] */ + temp_swiz = 1 | (1 << 3) | (1 << 6); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_CMP + | R500_ALU_RGBA_ADDRD(get_temp(fp, 0)) + | MAKE_SWIZ_RGBA_C(temp_swiz) + | R500_ALU_RGBA_MOD_C_NEG + | MAKE_SWIZ_ALPHA_C(R500_SWIZZLE_ZERO); + counter++; + /* Final instruction */ + emit_mov(fp, counter, fpi, get_temp(fp, 0), SWIZZLE_NOOP, dest); + break; + case OPCODE_LRP: + /* src0 * src1 + INV(src0) * src2 + * 1) MUL src0, src1, temp + * 2) PRE 1-src0; MAD srcp, src2, temp */ + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = make_src(fp, fpi->SrcReg[1]); + src[2] = make_src(fp, fpi->SrcReg[2]); + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | R500_INST_TEX_SEM_WAIT + | R500_INST_NOP | (R500_WRITEMASK_ARGB << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) + | R500_RGB_ADDR1(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) + | R500_ALPHA_ADDR1(src[1]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(make_rgb_swizzle(fpi->SrcReg[0])) + | R500_ALU_RGB_SEL_B_SRC1 | MAKE_SWIZ_RGB_B(make_rgb_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst4 = R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(get_temp(fp, 0)) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(make_alpha_swizzle(fpi->SrcReg[0])) + | R500_ALPHA_SEL_B_SRC1 | MAKE_SWIZ_ALPHA_B(make_alpha_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(get_temp(fp, 0)) + | MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_ZERO) + | MAKE_SWIZ_ALPHA_C(R500_SWIZZLE_ZERO); + counter++; + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) + | R500_RGB_ADDR1(src[2]) + | R500_RGB_ADDR2(get_temp(fp, 0)) + | R500_RGB_SRCP_OP_1_MINUS_RGB0; + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) + | R500_ALPHA_ADDR1(src[2]) + | R500_ALPHA_ADDR2(get_temp(fp, 0)) + | R500_ALPHA_SRCP_OP_1_MINUS_A0; + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRCP + | MAKE_SWIZ_RGB_A(make_rgb_swizzle(fpi->SrcReg[0])) + | R500_ALU_RGB_SEL_B_SRC1 | MAKE_SWIZ_RGB_B(R500_SWIZ_RGB_RGB); + fp->inst[counter].inst4 |= R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SEL_A_SRCP | MAKE_SWIZ_ALPHA_A(make_alpha_swizzle(fpi->SrcReg[0])) + | R500_ALPHA_SEL_B_SRC1 | R500_ALPHA_SWIZ_B_A; + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(dest) + | R500_ALU_RGBA_SEL_C_SRC2 | MAKE_SWIZ_RGBA_C(make_rgb_swizzle(fpi->SrcReg[2])) + | R500_ALU_RGBA_ALPHA_SEL_C_SRC2 + | MAKE_SWIZ_ALPHA_C(make_alpha_swizzle(fpi->SrcReg[2])); + break; + case OPCODE_MAD: + emit_mad(fp, counter, fpi, 0, 1, 2); + break; + case OPCODE_MAX: + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = make_src(fp, fpi->SrcReg[1]); + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) | R500_RGB_ADDR1(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) | R500_ALPHA_ADDR1(src[1]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(make_rgb_swizzle(fpi->SrcReg[0])) + | R500_ALU_RGB_SEL_B_SRC1 + | MAKE_SWIZ_RGB_B(make_rgb_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst4 |= R500_ALPHA_OP_MAX + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(make_alpha_swizzle(fpi->SrcReg[0])) + | R500_ALPHA_SEL_B_SRC1 | MAKE_SWIZ_ALPHA_B(make_alpha_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAX + | R500_ALU_RGBA_ADDRD(dest); + break; + case OPCODE_MIN: + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = make_src(fp, fpi->SrcReg[1]); + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) | R500_RGB_ADDR1(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) | R500_ALPHA_ADDR1(src[1]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(make_rgb_swizzle(fpi->SrcReg[0])) + | R500_ALU_RGB_SEL_B_SRC1 + | MAKE_SWIZ_RGB_B(make_rgb_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst4 |= R500_ALPHA_OP_MIN + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(make_alpha_swizzle(fpi->SrcReg[0])) + | R500_ALPHA_SEL_B_SRC1 | MAKE_SWIZ_ALPHA_B(make_alpha_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MIN + | R500_ALU_RGBA_ADDRD(dest); + break; + case OPCODE_MOV: + emit_mov(fp, counter, fpi, make_src(fp, fpi->SrcReg[0]), fpi->SrcReg[0].Swizzle, dest); + break; + case OPCODE_MUL: + /* Variation on MAD: src0*src1+0 */ + emit_mad(fp, counter, fpi, 0, 1, R500_SWIZZLE_ZERO); + break; + case OPCODE_POW: + /* POW(a,b) = EX2(LN2(a)*b) */ + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = make_src(fp, fpi->SrcReg[1]); + emit_sop(fp, counter, fpi, OPCODE_LG2, src[0], make_sop_swizzle(fpi->SrcReg[0]), get_temp(fp, 0)); + fp->inst[counter].inst0 |= (R500_WRITEMASK_ARGB << 11); + counter++; + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | (R500_WRITEMASK_ARGB << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR0(get_temp(fp, 0)) + | R500_RGB_ADDR1(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(get_temp(fp, 0)) + | R500_ALPHA_ADDR1(src[1]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(make_rgb_swizzle(fpi->SrcReg[0])) + | R500_ALU_RGB_SEL_B_SRC1 | MAKE_SWIZ_RGB_B(make_rgb_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst4 = R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(get_temp(fp, 1)) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(make_alpha_swizzle(fpi->SrcReg[0])) + | R500_ALPHA_SEL_B_SRC1 | MAKE_SWIZ_ALPHA_B(make_alpha_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(get_temp(fp, 1)) + | MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_ZERO) + | MAKE_SWIZ_ALPHA_C(R500_SWIZZLE_ZERO); + counter++; + emit_sop(fp, counter, fpi, OPCODE_EX2, get_temp(fp, 1), make_sop_swizzle(fpi->SrcReg[0]), dest); + break; + case OPCODE_RCP: + src[0] = make_src(fp, fpi->SrcReg[0]); + emit_sop(fp, counter, fpi, OPCODE_RCP, src[0], make_sop_swizzle(fpi->SrcReg[0]), dest); + break; + case OPCODE_RSQ: + src[0] = make_src(fp, fpi->SrcReg[0]); + emit_sop(fp, counter, fpi, OPCODE_RSQ, src[0], make_sop_swizzle(fpi->SrcReg[0]), dest); + break; + case OPCODE_SCS: + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = emit_const4fv(fp, RCP_2PI); + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | R500_INST_TEX_SEM_WAIT + | (R500_WRITEMASK_ARGB << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) + | R500_RGB_ADDR1(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) + | R500_ALPHA_ADDR1(src[1]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_RGB) + | R500_ALU_RGB_SEL_B_SRC1 | MAKE_SWIZ_RGB_B(R500_SWIZ_RGB_RGB); + fp->inst[counter].inst4 = R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(get_temp(fp, 0)) + | R500_ALPHA_SEL_A_SRC0 | R500_ALPHA_SWIZ_A_A + | R500_ALPHA_SEL_B_SRC1 | R500_ALPHA_SWIZ_B_A; + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(get_temp(fp, 0)) + | MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_ZERO) + | MAKE_SWIZ_ALPHA_C(R500_SWIZZLE_ZERO); + counter++; + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | (R500_WRITEMASK_ARGB << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR0(get_temp(fp, 0)); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(get_temp(fp, 0)); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_RGB); + fp->inst[counter].inst4 = R500_ALPHA_OP_FRC + | R500_ALPHA_ADDRD(get_temp(fp, 1)) + | R500_ALPHA_SEL_A_SRC0 | R500_ALPHA_SWIZ_A_A; + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_FRC + | R500_ALU_RGBA_ADDRD(get_temp(fp, 1)); + counter++; + /* Do a cosine, then a sine, masking out the channels we want to protect. */ + /* Cosine only goes in R (x) channel. */ + fpi->DstReg.WriteMask = 0x1; + emit_sop(fp, counter, fpi, OPCODE_COS, get_temp(fp, 1), make_sop_swizzle(fpi->SrcReg[0]), dest); + counter++; + /* Sine only goes in G (y) channel. */ + fpi->DstReg.WriteMask = 0x2; + emit_sop(fp, counter, fpi, OPCODE_SIN, get_temp(fp, 1), make_sop_swizzle(fpi->SrcReg[0]), dest); + break; + case OPCODE_SGE: + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = make_src(fp, fpi->SrcReg[1]); + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | R500_INST_TEX_SEM_WAIT + | (R500_WRITEMASK_ARGB << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR1(src[0]) + | R500_RGB_ADDR2(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR1(src[0]) + | R500_ALPHA_ADDR2(src[1]); + fp->inst[counter].inst3 = /* 1 */ + MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_ONE) + | R500_ALU_RGB_SEL_B_SRC1 | MAKE_SWIZ_RGB_B(make_rgb_swizzle(fpi->SrcReg[0])); + fp->inst[counter].inst4 = R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(get_temp(fp, 0)) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(R500_SWIZZLE_ONE) + | R500_ALPHA_SEL_B_SRC1 | MAKE_SWIZ_ALPHA_B(make_alpha_swizzle(fpi->SrcReg[0])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(get_temp(fp, 0)) + | R500_ALU_RGBA_SEL_C_SRC2 + | MAKE_SWIZ_RGBA_C(make_rgb_swizzle(fpi->SrcReg[1])) + | R500_ALU_RGBA_MOD_C_NEG + | R500_ALU_RGBA_ALPHA_SEL_C_SRC2 + | MAKE_SWIZ_ALPHA_C(make_alpha_swizzle(fpi->SrcReg[1])) + | R500_ALU_RGBA_ALPHA_MOD_C_NEG; + counter++; + /* This inst's selects need to be swapped as follows: + * 0 -> C ; 1 -> B ; 2 -> A */ + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(get_temp(fp, 0)); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(get_temp(fp, 0)); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_ONE) + | R500_ALU_RGB_SEL_B_SRC0 + | MAKE_SWIZ_RGB_B(R500_SWIZ_RGB_ZERO); + fp->inst[counter].inst4 |= R500_ALPHA_OP_CMP + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(R500_SWIZZLE_ONE) + | R500_ALPHA_SEL_B_SRC0 | MAKE_SWIZ_ALPHA_B(R500_SWIZZLE_ZERO); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_CMP + | R500_ALU_RGBA_ADDRD(dest) + | R500_ALU_RGBA_SEL_C_SRC0 + | MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_RGB) + | R500_ALU_RGBA_ALPHA_SEL_C_SRC0 + | R500_ALU_RGBA_A_SWIZ_A; + break; + case OPCODE_SIN: + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = emit_const4fv(fp, RCP_2PI); + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | R500_INST_TEX_SEM_WAIT + | (R500_WRITEMASK_ARGB << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) + | R500_RGB_ADDR1(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) + | R500_ALPHA_ADDR1(src[1]); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_RGB) + | R500_ALU_RGB_SEL_B_SRC1 | MAKE_SWIZ_RGB_B(R500_SWIZ_RGB_RGB); + fp->inst[counter].inst4 = R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(get_temp(fp, 0)) + | R500_ALPHA_SEL_A_SRC0 | R500_ALPHA_SWIZ_A_A + | R500_ALPHA_SEL_B_SRC1 | R500_ALPHA_SWIZ_B_A; + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(get_temp(fp, 0)) + | MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_ZERO) + | MAKE_SWIZ_ALPHA_C(R500_SWIZZLE_ZERO); + counter++; + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | (R500_WRITEMASK_ARGB << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR0(get_temp(fp, 0)); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(get_temp(fp, 0)); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_RGB); + fp->inst[counter].inst4 = R500_ALPHA_OP_FRC + | R500_ALPHA_ADDRD(get_temp(fp, 1)) + | R500_ALPHA_SEL_A_SRC0 | R500_ALPHA_SWIZ_A_A; + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_FRC + | R500_ALU_RGBA_ADDRD(get_temp(fp, 1)); + counter++; + emit_sop(fp, counter, fpi, OPCODE_SIN, get_temp(fp, 1), make_sop_swizzle(fpi->SrcReg[0]), dest); + break; + case OPCODE_SLT: + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = make_src(fp, fpi->SrcReg[1]); + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | R500_INST_TEX_SEM_WAIT + | (R500_WRITEMASK_ARGB << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR1(src[0]) + | R500_RGB_ADDR2(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR1(src[0]) + | R500_ALPHA_ADDR2(src[1]); + fp->inst[counter].inst3 = /* 1 */ + MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_ONE) + | R500_ALU_RGB_SEL_B_SRC1 | MAKE_SWIZ_RGB_B(make_rgb_swizzle(fpi->SrcReg[0])); + fp->inst[counter].inst4 = R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(get_temp(fp, 0)) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(R500_SWIZZLE_ONE) + | R500_ALPHA_SEL_B_SRC1 | MAKE_SWIZ_ALPHA_B(make_alpha_swizzle(fpi->SrcReg[0])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(get_temp(fp, 0)) + | R500_ALU_RGBA_SEL_C_SRC2 + | MAKE_SWIZ_RGBA_C(make_rgb_swizzle(fpi->SrcReg[1])) + | R500_ALU_RGBA_MOD_C_NEG + | R500_ALU_RGBA_ALPHA_SEL_C_SRC2 + | MAKE_SWIZ_ALPHA_C(make_alpha_swizzle(fpi->SrcReg[1])) + | R500_ALU_RGBA_ALPHA_MOD_C_NEG; + counter++; + /* This inst's selects need to be swapped as follows: + * 0 -> C ; 1 -> B ; 2 -> A */ + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(get_temp(fp, 0)); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(get_temp(fp, 0)); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(R500_SWIZ_RGB_ZERO) + | R500_ALU_RGB_SEL_B_SRC0 + | MAKE_SWIZ_RGB_B(R500_SWIZ_RGB_ONE); + fp->inst[counter].inst4 |= R500_ALPHA_OP_CMP + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(R500_SWIZZLE_ZERO) + | R500_ALPHA_SEL_B_SRC0 | MAKE_SWIZ_ALPHA_B(R500_SWIZZLE_ONE); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_CMP + | R500_ALU_RGBA_ADDRD(dest) + | R500_ALU_RGBA_SEL_C_SRC0 + | MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_RGB) + | R500_ALU_RGBA_ALPHA_SEL_C_SRC0 + | R500_ALU_RGBA_A_SWIZ_A; + break; + case OPCODE_SUB: + /* Variation on MAD: 1*src0-src1 */ + fpi->SrcReg[1].NegateBase = 0xF; /* NEG_XYZW */ + emit_mad(fp, counter, fpi, R500_SWIZZLE_ONE, 0, 1); + break; + case OPCODE_SWZ: + /* TODO: The rarer negation masks! */ + emit_mov(fp, counter, fpi, make_src(fp, fpi->SrcReg[0]), fpi->SrcReg[0].Swizzle, dest); + break; + case OPCODE_XPD: + /* src0 * src1 - src1 * src0 + * 1) MUL temp.xyz, src0.yzx, src1.zxy + * 2) MAD src0.zxy, src1.yzx, -temp.xyz */ + src[0] = make_src(fp, fpi->SrcReg[0]); + src[1] = make_src(fp, fpi->SrcReg[1]); + fp->inst[counter].inst0 = R500_INST_TYPE_ALU | R500_INST_TEX_SEM_WAIT + | (R500_WRITEMASK_RGB << 11); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) + | R500_RGB_ADDR1(src[1]); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) + | R500_ALPHA_ADDR1(src[1]); + /* Select [y, z, x] */ + temp_swiz = make_rgb_swizzle(fpi->SrcReg[0]); + temp_swiz = (GET_SWZ(temp_swiz, 1) << 0) | (GET_SWZ(temp_swiz, 2) << 3) | (GET_SWZ(temp_swiz, 0) << 6); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(temp_swiz); + /* Select [z, x, y] */ + temp_swiz = make_rgb_swizzle(fpi->SrcReg[1]); + temp_swiz = (GET_SWZ(temp_swiz, 2) << 0) | (GET_SWZ(temp_swiz, 0) << 3) | (GET_SWZ(temp_swiz, 1) << 6); + fp->inst[counter].inst3 |= R500_ALU_RGB_SEL_B_SRC1 + | MAKE_SWIZ_RGB_B(temp_swiz); + fp->inst[counter].inst4 = R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(get_temp(fp, 0)) + | R500_ALPHA_SEL_A_SRC0 | MAKE_SWIZ_ALPHA_A(make_alpha_swizzle(fpi->SrcReg[0])) + | R500_ALPHA_SEL_B_SRC1 | MAKE_SWIZ_ALPHA_B(make_alpha_swizzle(fpi->SrcReg[1])); + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(get_temp(fp, 0)) + | MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_ZERO) + | MAKE_SWIZ_ALPHA_C(R500_SWIZZLE_ZERO); + counter++; + emit_alu(fp, counter, fpi); + fp->inst[counter].inst1 = R500_RGB_ADDR0(src[0]) + | R500_RGB_ADDR1(src[1]) + | R500_RGB_ADDR2(get_temp(fp, 0)); + fp->inst[counter].inst2 = R500_ALPHA_ADDR0(src[0]) + | R500_ALPHA_ADDR1(src[1]) + | R500_ALPHA_ADDR2(get_temp(fp, 0)); + /* Select [z, x, y] */ + temp_swiz = make_rgb_swizzle(fpi->SrcReg[0]); + temp_swiz = (GET_SWZ(temp_swiz, 2) << 0) | (GET_SWZ(temp_swiz, 0) << 3) | (GET_SWZ(temp_swiz, 1) << 6); + fp->inst[counter].inst3 = R500_ALU_RGB_SEL_A_SRC0 + | MAKE_SWIZ_RGB_A(temp_swiz); + /* Select [y, z, x] */ + temp_swiz = make_rgb_swizzle(fpi->SrcReg[1]); + temp_swiz = (GET_SWZ(temp_swiz, 1) << 0) | (GET_SWZ(temp_swiz, 2) << 3) | (GET_SWZ(temp_swiz, 0) << 6); + fp->inst[counter].inst3 |= R500_ALU_RGB_SEL_B_SRC1 + | MAKE_SWIZ_RGB_B(temp_swiz); + fp->inst[counter].inst4 |= R500_ALPHA_OP_MAD + | R500_ALPHA_ADDRD(dest) + | R500_ALPHA_SWIZ_A_1 + | R500_ALPHA_SWIZ_B_1; + fp->inst[counter].inst5 = R500_ALU_RGBA_OP_MAD + | R500_ALU_RGBA_ADDRD(dest) + | R500_ALU_RGBA_SEL_C_SRC2 + | MAKE_SWIZ_RGBA_C(R500_SWIZ_RGB_RGB) + | R500_ALU_RGBA_MOD_C_NEG + | R500_ALU_RGBA_A_SWIZ_0; + break; + case OPCODE_KIL: + case OPCODE_TEX: + case OPCODE_TXB: + case OPCODE_TXP: + emit_tex(fp, fpi, dest, counter); + if (fpi->DstReg.File == PROGRAM_OUTPUT) + counter++; + break; + default: + ERROR("unknown fpi->Opcode %s\n", _mesa_opcode_string(fpi->Opcode)); + break; + } + + /* Finishing touches */ + if (fpi->SaturateMode == SATURATE_ZERO_ONE) { + fp->inst[counter].inst0 |= R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP; + } + + counter++; + + if (fp->error) + return GL_FALSE; + + } + + /* Finish him! (If it's an ALU/OUT instruction...) */ + if ((fp->inst[counter-1].inst0 & 0x3) == 1) { + fp->inst[counter-1].inst0 |= R500_INST_LAST; + } else { + /* We still need to put an output inst, right? */ + WARN_ONCE("Final FP instruction is not an OUT.\n"); + } + + fp->cs->nrslots = counter; + + fp->max_temp_idx++; + + return GL_TRUE; +} + +static void init_program(r300ContextPtr r300, struct r500_fragment_program *fp) +{ + struct r300_pfs_compile_state *cs = NULL; + struct gl_fragment_program *mp = &fp->mesa_program; + struct prog_instruction *fpi; + GLuint InputsRead = mp->Base.InputsRead; + GLuint temps_used = 0; + int i, j; + + /* New compile, reset tracking data */ + fp->optimization = + driQueryOptioni(&r300->radeon.optionCache, "fp_optimization"); + fp->translated = GL_FALSE; + fp->error = GL_FALSE; + fp->cs = cs = &(R300_CONTEXT(fp->ctx)->state.pfs_compile); + fp->const_nr = 0; + /* Size of pixel stack, plus 1. */ + fp->max_temp_idx = 1; + /* Temp register offset. */ + fp->temp_reg_offset = 0; + /* Whether or not we perform any depth writing. */ + fp->writes_depth = GL_FALSE; + + _mesa_memset(cs, 0, sizeof(*fp->cs)); + for (i = 0; i < PFS_MAX_ALU_INST; i++) { + for (j = 0; j < 3; j++) { + cs->slot[i].vsrc[j] = SRC_CONST; + cs->slot[i].ssrc[j] = SRC_CONST; + } + } + + /* Work out what temps the Mesa inputs correspond to, this must match + * what setup_rs_unit does, which shouldn't be a problem as rs_unit + * configures itself based on the fragprog's InputsRead + * + * NOTE: this depends on get_hw_temp() allocating registers in order, + * starting from register 0, so we're just going to do that instead. + */ + + /* Texcoords come first */ + for (i = 0; i < fp->ctx->Const.MaxTextureUnits; i++) { + if (InputsRead & (FRAG_BIT_TEX0 << i)) { + cs->inputs[FRAG_ATTRIB_TEX0 + i].refcount = 0; + cs->inputs[FRAG_ATTRIB_TEX0 + i].reg = + fp->temp_reg_offset; + fp->temp_reg_offset++; + } + } + InputsRead &= ~FRAG_BITS_TEX_ANY; + + /* fragment position treated as a texcoord */ + if (InputsRead & FRAG_BIT_WPOS) { + cs->inputs[FRAG_ATTRIB_WPOS].refcount = 0; + cs->inputs[FRAG_ATTRIB_WPOS].reg = + fp->temp_reg_offset; + fp->temp_reg_offset++; + } + InputsRead &= ~FRAG_BIT_WPOS; + + /* Then primary colour */ + if (InputsRead & FRAG_BIT_COL0) { + cs->inputs[FRAG_ATTRIB_COL0].refcount = 0; + cs->inputs[FRAG_ATTRIB_COL0].reg = + fp->temp_reg_offset; + fp->temp_reg_offset++; + } + InputsRead &= ~FRAG_BIT_COL0; + + /* Secondary color */ + if (InputsRead & FRAG_BIT_COL1) { + cs->inputs[FRAG_ATTRIB_COL1].refcount = 0; + cs->inputs[FRAG_ATTRIB_COL1].reg = + fp->temp_reg_offset; + fp->temp_reg_offset++; + } + InputsRead &= ~FRAG_BIT_COL1; + + /* Anything else */ + if (InputsRead) { + WARN_ONCE("Don't know how to handle inputs 0x%x\n", InputsRead); + /* force read from hwreg 0 for now */ + for (i = 0; i < 32; i++) + if (InputsRead & (1 << i)) + cs->inputs[i].reg = 0; + } + + if (!mp->Base.Instructions) { + ERROR("No instructions found in program, going to go die now.\n"); + return; + } + + for (fpi = mp->Base.Instructions; fpi->Opcode != OPCODE_END; fpi++) { + for (i = 0; i < 3; i++) { + if (fpi->SrcReg[i].File == PROGRAM_TEMPORARY) { + if (fpi->SrcReg[i].Index >= temps_used) + temps_used = fpi->SrcReg[i].Index + 1; + } + } + } + + cs->temp_in_use = temps_used + 1; + + fp->max_temp_idx = fp->temp_reg_offset + cs->temp_in_use; + + if (RADEON_DEBUG & DEBUG_PIXEL) + fprintf(stderr, "FP temp indices: fp->max_temp_idx: %d cs->temp_in_use: %d\n", fp->max_temp_idx, cs->temp_in_use); +} + +static void update_params(struct r500_fragment_program *fp) +{ + struct gl_fragment_program *mp = &fp->mesa_program; + + /* Ask Mesa nicely to fill in ParameterValues for us */ + if (mp->Base.Parameters) + _mesa_load_state_parameters(fp->ctx, mp->Base.Parameters); +} + +static void dumb_shader(struct r500_fragment_program *fp) +{ + fp->inst[0].inst0 = R500_INST_TYPE_TEX + | R500_INST_TEX_SEM_WAIT + | R500_INST_RGB_WMASK_R + | R500_INST_RGB_WMASK_G + | R500_INST_RGB_WMASK_B + | R500_INST_ALPHA_WMASK + | R500_INST_RGB_CLAMP + | R500_INST_ALPHA_CLAMP; + fp->inst[0].inst1 = R500_TEX_ID(0) + | R500_TEX_INST_LD + | R500_TEX_SEM_ACQUIRE + | R500_TEX_IGNORE_UNCOVERED; + fp->inst[0].inst2 = R500_TEX_SRC_ADDR(0) + | R500_TEX_SRC_S_SWIZ_R + | R500_TEX_SRC_T_SWIZ_G + | R500_TEX_DST_ADDR(0) + | R500_TEX_DST_R_SWIZ_R + | R500_TEX_DST_G_SWIZ_G + | R500_TEX_DST_B_SWIZ_B + | R500_TEX_DST_A_SWIZ_A; + fp->inst[0].inst3 = R500_DX_ADDR(0) + | R500_DX_S_SWIZ_R + | R500_DX_T_SWIZ_R + | R500_DX_R_SWIZ_R + | R500_DX_Q_SWIZ_R + | R500_DY_ADDR(0) + | R500_DY_S_SWIZ_R + | R500_DY_T_SWIZ_R + | R500_DY_R_SWIZ_R + | R500_DY_Q_SWIZ_R; + fp->inst[0].inst4 = 0x0; + fp->inst[0].inst5 = 0x0; + + fp->inst[1].inst0 = R500_INST_TYPE_OUT | + R500_INST_TEX_SEM_WAIT | + R500_INST_LAST | + R500_INST_RGB_OMASK_R | + R500_INST_RGB_OMASK_G | + R500_INST_RGB_OMASK_B | + R500_INST_ALPHA_OMASK; + fp->inst[1].inst1 = R500_RGB_ADDR0(0) | + R500_RGB_ADDR1(0) | + R500_RGB_ADDR1_CONST | + R500_RGB_ADDR2(0) | + R500_RGB_ADDR2_CONST | + R500_RGB_SRCP_OP_1_MINUS_2RGB0; + fp->inst[1].inst2 = R500_ALPHA_ADDR0(0) | + R500_ALPHA_ADDR1(0) | + R500_ALPHA_ADDR1_CONST | + R500_ALPHA_ADDR2(0) | + R500_ALPHA_ADDR2_CONST | + R500_ALPHA_SRCP_OP_1_MINUS_2A0; + fp->inst[1].inst3 = R500_ALU_RGB_SEL_A_SRC0 | + R500_ALU_RGB_R_SWIZ_A_R | + R500_ALU_RGB_G_SWIZ_A_G | + R500_ALU_RGB_B_SWIZ_A_B | + R500_ALU_RGB_SEL_B_SRC0 | + R500_ALU_RGB_R_SWIZ_B_1 | + R500_ALU_RGB_B_SWIZ_B_1 | + R500_ALU_RGB_G_SWIZ_B_1; + fp->inst[1].inst4 = R500_ALPHA_OP_MAD | + R500_ALPHA_SWIZ_A_A | + R500_ALPHA_SWIZ_B_1; + fp->inst[1].inst5 = R500_ALU_RGBA_OP_MAD | + R500_ALU_RGBA_R_SWIZ_0 | + R500_ALU_RGBA_G_SWIZ_0 | + R500_ALU_RGBA_B_SWIZ_0 | + R500_ALU_RGBA_A_SWIZ_0; + + fp->cs->nrslots = 2; + fp->translated = GL_TRUE; +} + +void r500TranslateFragmentShader(r300ContextPtr r300, + struct r500_fragment_program *fp) +{ + + struct r300_pfs_compile_state *cs = NULL; + + if (!fp->translated) { + + init_program(r300, fp); + cs = fp->cs; + + if (parse_program(fp) == GL_FALSE) { + ERROR("Huh. Couldn't parse program. There should be additional errors explaining why.\nUsing dumb shader...\n"); + dumb_shader(fp); + fp->inst_offset = 0; + fp->inst_end = cs->nrslots - 1; + return; + } + fp->inst_offset = 0; + fp->inst_end = cs->nrslots - 1; + + fp->translated = GL_TRUE; + if (RADEON_DEBUG & DEBUG_PIXEL) { + fprintf(stderr, "Mesa program:\n"); + fprintf(stderr, "-------------\n"); + _mesa_print_program(&fp->mesa_program.Base); + fflush(stdout); + dump_program(fp); + } + + + r300UpdateStateParameters(fp->ctx, _NEW_PROGRAM); + } + + update_params(fp); + +} + +static char *toswiz(int swiz_val) { + switch(swiz_val) { + case 0: return "R"; + case 1: return "G"; + case 2: return "B"; + case 3: return "A"; + case 4: return "0"; + case 5: return "1/2"; + case 6: return "1"; + case 7: return "U"; + } + return NULL; +} + +static char *toop(int op_val) +{ + char *str = NULL; + switch (op_val) { + case 0: str = "MAD"; break; + case 1: str = "DP3"; break; + case 2: str = "DP4"; break; + case 3: str = "D2A"; break; + case 4: str = "MIN"; break; + case 5: str = "MAX"; break; + case 6: str = "Reserved"; break; + case 7: str = "CND"; break; + case 8: str = "CMP"; break; + case 9: str = "FRC"; break; + case 10: str = "SOP"; break; + case 11: str = "MDH"; break; + case 12: str = "MDV"; break; + } + return str; +} + +static char *to_alpha_op(int op_val) +{ + char *str = NULL; + switch (op_val) { + case 0: str = "MAD"; break; + case 1: str = "DP"; break; + case 2: str = "MIN"; break; + case 3: str = "MAX"; break; + case 4: str = "Reserved"; break; + case 5: str = "CND"; break; + case 6: str = "CMP"; break; + case 7: str = "FRC"; break; + case 8: str = "EX2"; break; + case 9: str = "LN2"; break; + case 10: str = "RCP"; break; + case 11: str = "RSQ"; break; + case 12: str = "SIN"; break; + case 13: str = "COS"; break; + case 14: str = "MDH"; break; + case 15: str = "MDV"; break; + } + return str; +} + +static char *to_mask(int val) +{ + char *str = NULL; + switch(val) { + case 0: str = "NONE"; break; + case 1: str = "R"; break; + case 2: str = "G"; break; + case 3: str = "RG"; break; + case 4: str = "B"; break; + case 5: str = "RB"; break; + case 6: str = "GB"; break; + case 7: str = "RGB"; break; + case 8: str = "A"; break; + case 9: str = "AR"; break; + case 10: str = "AG"; break; + case 11: str = "ARG"; break; + case 12: str = "AB"; break; + case 13: str = "ARB"; break; + case 14: str = "AGB"; break; + case 15: str = "ARGB"; break; + } + return str; +} + +static char *to_texop(int val) +{ + switch(val) { + case 0: return "NOP"; + case 1: return "LD"; + case 2: return "TEXKILL"; + case 3: return "PROJ"; + case 4: return "LODBIAS"; + case 5: return "LOD"; + case 6: return "DXDY"; + } + return NULL; +} + +static void dump_program(struct r500_fragment_program *fp) +{ + + fprintf(stderr, "R500 Fragment Program:\n--------\n"); + + int n; + uint32_t inst; + uint32_t inst0; + char *str = NULL; + + if (fp->const_nr) { + fprintf(stderr, "--------\nConstants:\n"); + for (n = 0; n < fp->const_nr; n++) { + fprintf(stderr, "Constant %d: %f %f\n\t %f %f\n", n, + fp->constant[n][0], fp->constant[n][1], fp->constant[n][2], + fp->constant[n][3]); + } + fprintf(stderr, "--------\n"); + } + + for (n = 0; n < fp->inst_end+1; n++) { + inst0 = inst = fp->inst[n].inst0; + fprintf(stderr,"%d\t0:CMN_INST 0x%08x:", n, inst); + switch(inst & 0x3) { + case R500_INST_TYPE_ALU: str = "ALU"; break; + case R500_INST_TYPE_OUT: str = "OUT"; break; + case R500_INST_TYPE_FC: str = "FC"; break; + case R500_INST_TYPE_TEX: str = "TEX"; break; + }; + fprintf(stderr,"%s %s %s %s %s ", str, + inst & R500_INST_TEX_SEM_WAIT ? "TEX_WAIT" : "", + inst & R500_INST_LAST ? "LAST" : "", + inst & R500_INST_NOP ? "NOP" : "", + inst & R500_INST_ALU_WAIT ? "ALU WAIT" : ""); + fprintf(stderr,"wmask: %s omask: %s\n", to_mask((inst >> 11) & 0xf), + to_mask((inst >> 15) & 0xf)); + + switch(inst0 & 0x3) { + case 0: + case 1: + fprintf(stderr,"\t1:RGB_ADDR 0x%08x:", fp->inst[n].inst1); + inst = fp->inst[n].inst1; + + fprintf(stderr,"Addr0: %d%c, Addr1: %d%c, Addr2: %d%c, srcp:%d\n", + inst & 0xff, (inst & (1<<8)) ? 'c' : 't', + (inst >> 10) & 0xff, (inst & (1<<18)) ? 'c' : 't', + (inst >> 20) & 0xff, (inst & (1<<28)) ? 'c' : 't', + (inst >> 30)); + + fprintf(stderr,"\t2:ALPHA_ADDR 0x%08x:", fp->inst[n].inst2); + inst = fp->inst[n].inst2; + fprintf(stderr,"Addr0: %d%c, Addr1: %d%c, Addr2: %d%c, srcp:%d\n", + inst & 0xff, (inst & (1<<8)) ? 'c' : 't', + (inst >> 10) & 0xff, (inst & (1<<18)) ? 'c' : 't', + (inst >> 20) & 0xff, (inst & (1<<28)) ? 'c' : 't', + (inst >> 30)); + fprintf(stderr,"\t3 RGB_INST: 0x%08x:", fp->inst[n].inst3); + inst = fp->inst[n].inst3; + fprintf(stderr,"rgb_A_src:%d %s/%s/%s %d rgb_B_src:%d %s/%s/%s %d\n", + (inst) & 0x3, toswiz((inst >> 2) & 0x7), toswiz((inst >> 5) & 0x7), toswiz((inst >> 8) & 0x7), + (inst >> 11) & 0x3, + (inst >> 13) & 0x3, toswiz((inst >> 15) & 0x7), toswiz((inst >> 18) & 0x7), toswiz((inst >> 21) & 0x7), + (inst >> 24) & 0x3); + + + fprintf(stderr,"\t4 ALPHA_INST:0x%08x:", fp->inst[n].inst4); + inst = fp->inst[n].inst4; + fprintf(stderr,"%s dest:%d%s alp_A_src:%d %s %d alp_B_src:%d %s %d w:%d\n", to_alpha_op(inst & 0xf), + (inst >> 4) & 0x7f, inst & (1<<11) ? "(rel)":"", + (inst >> 12) & 0x3, toswiz((inst >> 14) & 0x7), (inst >> 17) & 0x3, + (inst >> 19) & 0x3, toswiz((inst >> 21) & 0x7), (inst >> 24) & 0x3, + (inst >> 31) & 0x1); + + fprintf(stderr,"\t5 RGBA_INST: 0x%08x:", fp->inst[n].inst5); + inst = fp->inst[n].inst5; + fprintf(stderr,"%s dest:%d%s rgb_C_src:%d %s/%s/%s %d alp_C_src:%d %s %d\n", toop(inst & 0xf), + (inst >> 4) & 0x7f, inst & (1<<11) ? "(rel)":"", + (inst >> 12) & 0x3, toswiz((inst >> 14) & 0x7), toswiz((inst >> 17) & 0x7), toswiz((inst >> 20) & 0x7), + (inst >> 23) & 0x3, + (inst >> 25) & 0x3, toswiz((inst >> 27) & 0x7), (inst >> 30) & 0x3); + break; + case 2: + break; + case 3: + inst = fp->inst[n].inst1; + fprintf(stderr,"\t1:TEX_INST: 0x%08x: id: %d op:%s, %s, %s %s\n", inst, (inst >> 16) & 0xf, + to_texop((inst >> 22) & 0x7), (inst & (1<<25)) ? "ACQ" : "", + (inst & (1<<26)) ? "IGNUNC" : "", (inst & (1<<27)) ? "UNSCALED" : "SCALED"); + inst = fp->inst[n].inst2; + fprintf(stderr,"\t2:TEX_ADDR: 0x%08x: src: %d%s %s/%s/%s/%s dst: %d%s %s/%s/%s/%s\n", inst, + inst & 127, inst & (1<<7) ? "(rel)" : "", + toswiz((inst >> 8) & 0x3), toswiz((inst >> 10) & 0x3), + toswiz((inst >> 12) & 0x3), toswiz((inst >> 14) & 0x3), + (inst >> 16) & 127, inst & (1<<23) ? "(rel)" : "", + toswiz((inst >> 24) & 0x3), toswiz((inst >> 26) & 0x3), + toswiz((inst >> 28) & 0x3), toswiz((inst >> 30) & 0x3)); + + fprintf(stderr,"\t3:TEX_DXDY: 0x%08x\n", fp->inst[n].inst3); + break; + } + fprintf(stderr,"\n"); + } + +} diff --git a/src/mesa/drivers/dri/r300/r500_fragprog.h b/src/mesa/drivers/dri/r300/r500_fragprog.h new file mode 100644 index 0000000000..5dd2def1c4 --- /dev/null +++ b/src/mesa/drivers/dri/r300/r500_fragprog.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2005 Ben Skeggs. + * + * 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: + * Ben Skeggs <darktama@iinet.net.au> + * Jerome Glisse <j.glisse@gmail.com> + */ +#ifndef __R500_FRAGPROG_H_ +#define __R500_FRAGPROG_H_ + +#include "glheader.h" +#include "macros.h" +#include "enums.h" +#include "shader/program.h" +#include "shader/prog_instruction.h" + +#include "r300_context.h" + +/* supported hw opcodes */ +#define PFS_OP_MAD 0 +#define PFS_OP_DP3 1 +#define PFS_OP_DP4 2 +#define PFS_OP_MIN 3 +#define PFS_OP_MAX 4 +#define PFS_OP_CMP 5 +#define PFS_OP_FRC 6 +#define PFS_OP_EX2 7 +#define PFS_OP_LG2 8 +#define PFS_OP_RCP 9 +#define PFS_OP_RSQ 10 +#define PFS_OP_REPL_ALPHA 11 +#define PFS_OP_CMPH 12 +#define MAX_PFS_OP 12 + +#define PFS_FLAG_SAT (1 << 0) +#define PFS_FLAG_ABS (1 << 1) + +#define ARG_NEG (1 << 5) +#define ARG_ABS (1 << 6) +#define ARG_MASK (127 << 0) +#define ARG_STRIDE 7 +#define SRC_CONST (1 << 5) +#define SRC_MASK (63 << 0) +#define SRC_STRIDE 6 + +#define DRI_CONF_FP_OPTIMIZATION_SPEED 0 +#define DRI_CONF_FP_OPTIMIZATION_QUALITY 1 + +struct r500_fragment_program; + +extern void r500TranslateFragmentShader(r300ContextPtr r300, + struct r500_fragment_program *fp); + +#endif diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c index 9c0a5868b5..3fc724a553 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.c +++ b/src/mesa/drivers/dri/r300/radeon_context.c @@ -135,6 +135,7 @@ GLboolean radeonInitContext(radeonContextPtr radeon, /* Fill in additional standard functions. */ radeonInitDriverFuncs(functions); + radeon->radeonScreen = screen; /* Allocate and initialize the Mesa context */ if (sharedContextPrivate) shareCtx = ((radeonContextPtr)sharedContextPrivate)->glCtx; @@ -158,7 +159,6 @@ GLboolean radeonInitContext(radeonContextPtr radeon, radeon->dri.fd = sPriv->fd; radeon->dri.drmMinor = sPriv->drm_version.minor; - radeon->radeonScreen = screen; radeon->sarea = (drm_radeon_sarea_t *) ((GLubyte *) sPriv->pSAREA + screen->sarea_priv_offset); diff --git a/src/mesa/drivers/dri/r300/radeon_ioctl.c b/src/mesa/drivers/dri/r300/radeon_ioctl.c index 31a000d5e6..0c1a19507b 100644 --- a/src/mesa/drivers/dri/r300/radeon_ioctl.c +++ b/src/mesa/drivers/dri/r300/radeon_ioctl.c @@ -215,16 +215,18 @@ void radeonCopyBuffer(__DRIdrawablePrivate * dPriv, if (rect->y2 < b->y2) b->y2 = rect->y2; - if (b->x1 < b->x2 && b->y1 < b->y2) - b++; + if (b->x1 >= b->x2 || b->y1 >= b->y2) + continue; } - else - b++; + b++; n++; } radeon->sarea->nbox = n; + if (!n) + continue; + ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_SWAP); if (ret) { |