diff options
Diffstat (limited to 'drivers/char/drm/r300_cmdbuf.c')
-rw-r--r-- | drivers/char/drm/r300_cmdbuf.c | 117 |
1 files changed, 95 insertions, 22 deletions
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c index f535812e4057..702df45320f7 100644 --- a/drivers/char/drm/r300_cmdbuf.c +++ b/drivers/char/drm/r300_cmdbuf.c | |||
@@ -189,18 +189,12 @@ void r300_init_reg_flags(struct drm_device *dev) | |||
189 | ADD_RANGE(R300_RE_CULL_CNTL, 1); | 189 | ADD_RANGE(R300_RE_CULL_CNTL, 1); |
190 | ADD_RANGE(0x42C0, 2); | 190 | ADD_RANGE(0x42C0, 2); |
191 | ADD_RANGE(R300_RS_CNTL_0, 2); | 191 | ADD_RANGE(R300_RS_CNTL_0, 2); |
192 | ADD_RANGE(R300_RS_INTERP_0, 8); | 192 | |
193 | ADD_RANGE(R300_RS_ROUTE_0, 8); | 193 | ADD_RANGE(R300_SC_HYPERZ, 2); |
194 | ADD_RANGE(0x43A4, 2); | ||
195 | ADD_RANGE(0x43E8, 1); | 194 | ADD_RANGE(0x43E8, 1); |
196 | ADD_RANGE(R300_PFS_CNTL_0, 3); | 195 | |
197 | ADD_RANGE(R300_PFS_NODE_0, 4); | ||
198 | ADD_RANGE(R300_PFS_TEXI_0, 64); | ||
199 | ADD_RANGE(0x46A4, 5); | 196 | ADD_RANGE(0x46A4, 5); |
200 | ADD_RANGE(R300_PFS_INSTR0_0, 64); | 197 | |
201 | ADD_RANGE(R300_PFS_INSTR1_0, 64); | ||
202 | ADD_RANGE(R300_PFS_INSTR2_0, 64); | ||
203 | ADD_RANGE(R300_PFS_INSTR3_0, 64); | ||
204 | ADD_RANGE(R300_RE_FOG_STATE, 1); | 198 | ADD_RANGE(R300_RE_FOG_STATE, 1); |
205 | ADD_RANGE(R300_FOG_COLOR_R, 3); | 199 | ADD_RANGE(R300_FOG_COLOR_R, 3); |
206 | ADD_RANGE(R300_PP_ALPHA_TEST, 2); | 200 | ADD_RANGE(R300_PP_ALPHA_TEST, 2); |
@@ -215,14 +209,12 @@ void r300_init_reg_flags(struct drm_device *dev) | |||
215 | ADD_RANGE(0x4E50, 9); | 209 | ADD_RANGE(0x4E50, 9); |
216 | ADD_RANGE(0x4E88, 1); | 210 | ADD_RANGE(0x4E88, 1); |
217 | ADD_RANGE(0x4EA0, 2); | 211 | ADD_RANGE(0x4EA0, 2); |
218 | ADD_RANGE(R300_RB3D_ZSTENCIL_CNTL_0, 3); | 212 | ADD_RANGE(R300_ZB_CNTL, 3); |
219 | ADD_RANGE(R300_RB3D_ZSTENCIL_FORMAT, 4); | 213 | ADD_RANGE(R300_ZB_FORMAT, 4); |
220 | ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */ | 214 | ADD_RANGE_MARK(R300_ZB_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */ |
221 | ADD_RANGE(R300_RB3D_DEPTHPITCH, 1); | 215 | ADD_RANGE(R300_ZB_DEPTHPITCH, 1); |
222 | ADD_RANGE(0x4F28, 1); | 216 | ADD_RANGE(R300_ZB_DEPTHCLEARVALUE, 1); |
223 | ADD_RANGE(0x4F30, 2); | 217 | ADD_RANGE(R300_ZB_ZMASK_OFFSET, 13); |
224 | ADD_RANGE(0x4F44, 1); | ||
225 | ADD_RANGE(0x4F54, 1); | ||
226 | 218 | ||
227 | ADD_RANGE(R300_TX_FILTER_0, 16); | 219 | ADD_RANGE(R300_TX_FILTER_0, 16); |
228 | ADD_RANGE(R300_TX_FILTER1_0, 16); | 220 | ADD_RANGE(R300_TX_FILTER1_0, 16); |
@@ -235,13 +227,32 @@ void r300_init_reg_flags(struct drm_device *dev) | |||
235 | ADD_RANGE(R300_TX_BORDER_COLOR_0, 16); | 227 | ADD_RANGE(R300_TX_BORDER_COLOR_0, 16); |
236 | 228 | ||
237 | /* Sporadic registers used as primitives are emitted */ | 229 | /* Sporadic registers used as primitives are emitted */ |
238 | ADD_RANGE(R300_RB3D_ZCACHE_CTLSTAT, 1); | 230 | ADD_RANGE(R300_ZB_ZCACHE_CTLSTAT, 1); |
239 | ADD_RANGE(R300_RB3D_DSTCACHE_CTLSTAT, 1); | 231 | ADD_RANGE(R300_RB3D_DSTCACHE_CTLSTAT, 1); |
240 | ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8); | 232 | ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8); |
241 | ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8); | 233 | ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8); |
242 | 234 | ||
243 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { | 235 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { |
244 | ADD_RANGE(0x4074, 16); | 236 | ADD_RANGE(R500_VAP_INDEX_OFFSET, 1); |
237 | ADD_RANGE(R500_US_CONFIG, 2); | ||
238 | ADD_RANGE(R500_US_CODE_ADDR, 3); | ||
239 | ADD_RANGE(R500_US_FC_CTRL, 1); | ||
240 | ADD_RANGE(R500_RS_IP_0, 16); | ||
241 | ADD_RANGE(R500_RS_INST_0, 16); | ||
242 | ADD_RANGE(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2); | ||
243 | ADD_RANGE(R500_RB3D_CONSTANT_COLOR_AR, 2); | ||
244 | ADD_RANGE(R500_ZB_FIFO_SIZE, 2); | ||
245 | } else { | ||
246 | ADD_RANGE(R300_PFS_CNTL_0, 3); | ||
247 | ADD_RANGE(R300_PFS_NODE_0, 4); | ||
248 | ADD_RANGE(R300_PFS_TEXI_0, 64); | ||
249 | ADD_RANGE(R300_PFS_INSTR0_0, 64); | ||
250 | ADD_RANGE(R300_PFS_INSTR1_0, 64); | ||
251 | ADD_RANGE(R300_PFS_INSTR2_0, 64); | ||
252 | ADD_RANGE(R300_PFS_INSTR3_0, 64); | ||
253 | ADD_RANGE(R300_RS_INTERP_0, 8); | ||
254 | ADD_RANGE(R300_RS_ROUTE_0, 8); | ||
255 | |||
245 | } | 256 | } |
246 | } | 257 | } |
247 | 258 | ||
@@ -707,8 +718,9 @@ static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv) | |||
707 | BEGIN_RING(6); | 718 | BEGIN_RING(6); |
708 | OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); | 719 | OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0)); |
709 | OUT_RING(R300_RB3D_DSTCACHE_UNKNOWN_0A); | 720 | OUT_RING(R300_RB3D_DSTCACHE_UNKNOWN_0A); |
710 | OUT_RING(CP_PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0)); | 721 | OUT_RING(CP_PACKET0(R300_ZB_ZCACHE_CTLSTAT, 0)); |
711 | OUT_RING(R300_RB3D_ZCACHE_UNKNOWN_03); | 722 | OUT_RING(R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE| |
723 | R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); | ||
712 | OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0)); | 724 | OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0)); |
713 | OUT_RING(0x0); | 725 | OUT_RING(0x0); |
714 | ADVANCE_RING(); | 726 | ADVANCE_RING(); |
@@ -829,6 +841,54 @@ static int r300_scratch(drm_radeon_private_t *dev_priv, | |||
829 | } | 841 | } |
830 | 842 | ||
831 | /** | 843 | /** |
844 | * Uploads user-supplied vertex program instructions or parameters onto | ||
845 | * the graphics card. | ||
846 | * Called by r300_do_cp_cmdbuf. | ||
847 | */ | ||
848 | static inline int r300_emit_r500fp(drm_radeon_private_t *dev_priv, | ||
849 | drm_radeon_kcmd_buffer_t *cmdbuf, | ||
850 | drm_r300_cmd_header_t header) | ||
851 | { | ||
852 | int sz; | ||
853 | int addr; | ||
854 | int type; | ||
855 | int clamp; | ||
856 | int stride; | ||
857 | RING_LOCALS; | ||
858 | |||
859 | sz = header.r500fp.count; | ||
860 | /* address is 9 bits 0 - 8, bit 1 of flags is part of address */ | ||
861 | addr = ((header.r500fp.adrhi_flags & 1) << 8) | header.r500fp.adrlo; | ||
862 | |||
863 | type = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_TYPE); | ||
864 | clamp = !!(header.r500fp.adrhi_flags & R500FP_CONSTANT_CLAMP); | ||
865 | |||
866 | addr |= (type << 16); | ||
867 | addr |= (clamp << 17); | ||
868 | |||
869 | stride = type ? 4 : 6; | ||
870 | |||
871 | DRM_DEBUG("r500fp %d %d type: %d\n", sz, addr, type); | ||
872 | if (!sz) | ||
873 | return 0; | ||
874 | if (sz * stride * 4 > cmdbuf->bufsz) | ||
875 | return -EINVAL; | ||
876 | |||
877 | BEGIN_RING(3 + sz * stride); | ||
878 | OUT_RING_REG(R500_GA_US_VECTOR_INDEX, addr); | ||
879 | OUT_RING(CP_PACKET0_TABLE(R500_GA_US_VECTOR_DATA, sz * stride - 1)); | ||
880 | OUT_RING_TABLE((int *)cmdbuf->buf, sz * stride); | ||
881 | |||
882 | ADVANCE_RING(); | ||
883 | |||
884 | cmdbuf->buf += sz * stride * 4; | ||
885 | cmdbuf->bufsz -= sz * stride * 4; | ||
886 | |||
887 | return 0; | ||
888 | } | ||
889 | |||
890 | |||
891 | /** | ||
832 | * Parses and validates a user-supplied command buffer and emits appropriate | 892 | * Parses and validates a user-supplied command buffer and emits appropriate |
833 | * commands on the DMA ring buffer. | 893 | * commands on the DMA ring buffer. |
834 | * Called by the ioctl handler function radeon_cp_cmdbuf. | 894 | * Called by the ioctl handler function radeon_cp_cmdbuf. |
@@ -963,6 +1023,19 @@ int r300_do_cp_cmdbuf(struct drm_device *dev, | |||
963 | } | 1023 | } |
964 | break; | 1024 | break; |
965 | 1025 | ||
1026 | case R300_CMD_R500FP: | ||
1027 | if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV515) { | ||
1028 | DRM_ERROR("Calling r500 command on r300 card\n"); | ||
1029 | ret = -EINVAL; | ||
1030 | goto cleanup; | ||
1031 | } | ||
1032 | DRM_DEBUG("R300_CMD_R500FP\n"); | ||
1033 | ret = r300_emit_r500fp(dev_priv, cmdbuf, header); | ||
1034 | if (ret) { | ||
1035 | DRM_ERROR("r300_emit_r500fp failed\n"); | ||
1036 | goto cleanup; | ||
1037 | } | ||
1038 | break; | ||
966 | default: | 1039 | default: |
967 | DRM_ERROR("bad cmd_type %i at %p\n", | 1040 | DRM_ERROR("bad cmd_type %i at %p\n", |
968 | header.header.cmd_type, | 1041 | header.header.cmd_type, |