drm/radeon/kms: fix and unify tiled buffer alignment checking for r6xx/7xx

Tiled buffers have the same alignment requirements regardless of
whether the surface is for db, cb, or textures. Previously, the
calculations where inconsistent for each buffer type.

- Unify the alignment calculations in a common function
- Standardize the alignment units (pixels for pitch/height/depth,
bytes for base)
- properly check the buffer base alignments

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by

Alex Deucher and committed by
Dave Airlie
16790569 0143832c

+199 -116
+193 -116
drivers/gpu/drm/radeon/r600_cs.c
··· 50 u32 nsamples; 51 u32 cb_color_base_last[8]; 52 struct radeon_bo *cb_color_bo[8]; 53 u32 cb_color_bo_offset[8]; 54 struct radeon_bo *cb_color_frag_bo[8]; 55 struct radeon_bo *cb_color_tile_bo[8]; ··· 68 u32 db_depth_size; 69 u32 db_offset; 70 struct radeon_bo *db_bo; 71 }; 72 73 static inline int r600_bpe_from_format(u32 *bpe, u32 format) ··· 142 return 0; 143 } 144 145 static void r600_cs_track_init(struct r600_cs_track *track) 146 { 147 int i; ··· 217 track->cb_color_info[i] = 0; 218 track->cb_color_bo[i] = NULL; 219 track->cb_color_bo_offset[i] = 0xFFFFFFFF; 220 } 221 track->cb_target_mask = 0xFFFFFFFF; 222 track->cb_shader_mask = 0xFFFFFFFF; 223 track->db_bo = NULL; 224 /* assume the biggest format and that htile is enabled */ 225 track->db_depth_info = 7 | (1 << 25); 226 track->db_depth_view = 0xFFFFC000; ··· 234 static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) 235 { 236 struct r600_cs_track *track = p->track; 237 - u32 bpe = 0, pitch, slice_tile_max, size, tmp, height, pitch_align; 238 volatile u32 *ib = p->ib->ptr; 239 unsigned array_mode; 240 ··· 252 i, track->cb_color_info[i]); 253 return -EINVAL; 254 } 255 - /* pitch is the number of 8x8 tiles per row */ 256 - pitch = G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1; 257 slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1; 258 slice_tile_max *= 64; 259 - height = slice_tile_max / (pitch * 8); 260 if (height > 8192) 261 height = 8192; 262 array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]); 263 switch (array_mode) { 264 case V_0280A0_ARRAY_LINEAR_GENERAL: 265 - /* technically height & 0x7 */ 266 break; 267 case V_0280A0_ARRAY_LINEAR_ALIGNED: 268 - pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8; 269 - if (!IS_ALIGNED(pitch, pitch_align)) { 270 - dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", 271 - __func__, __LINE__, pitch); 272 - return -EINVAL; 273 - } 274 - if (!IS_ALIGNED(height, 8)) { 275 - dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", 276 - __func__, __LINE__, height); 277 - return -EINVAL; 278 - } 279 break; 280 case V_0280A0_ARRAY_1D_TILED_THIN1: 281 - pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe * track->nsamples))) / 8; 282 - if (!IS_ALIGNED(pitch, pitch_align)) { 283 - dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", 284 - __func__, __LINE__, pitch); 285 - return -EINVAL; 286 - } 287 /* avoid breaking userspace */ 288 if (height > 7) 289 height &= ~0x7; 290 - if (!IS_ALIGNED(height, 8)) { 291 - dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", 292 - __func__, __LINE__, height); 293 - return -EINVAL; 294 - } 295 break; 296 case V_0280A0_ARRAY_2D_TILED_THIN1: 297 - pitch_align = max((u32)track->nbanks, 298 - (u32)(((track->group_size / 8) / (bpe * track->nsamples)) * track->nbanks)) / 8; 299 - if (!IS_ALIGNED(pitch, pitch_align)) { 300 - dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", 301 - __func__, __LINE__, pitch); 302 - return -EINVAL; 303 - } 304 - if (!IS_ALIGNED((height / 8), track->npipes)) { 305 - dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", 306 - __func__, __LINE__, height); 307 - return -EINVAL; 308 - } 309 break; 310 default: 311 dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, ··· 293 track->cb_color_info[i]); 294 return -EINVAL; 295 } 296 /* check offset */ 297 - tmp = height * pitch * 8 * bpe; 298 if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { 299 if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { 300 /* the initial DDX does bad things with the CB size occasionally */ ··· 325 return -EINVAL; 326 } 327 } 328 - if (!IS_ALIGNED(track->cb_color_bo_offset[i], track->group_size)) { 329 - dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->cb_color_bo_offset[i]); 330 - return -EINVAL; 331 - } 332 /* limit max tile */ 333 - tmp = (height * pitch * 8) >> 6; 334 if (tmp < slice_tile_max) 335 slice_tile_max = tmp; 336 - tmp = S_028060_PITCH_TILE_MAX(pitch - 1) | 337 S_028060_SLICE_TILE_MAX(slice_tile_max - 1); 338 ib[track->cb_color_size_idx[i]] = tmp; 339 return 0; ··· 371 /* Check depth buffer */ 372 if (G_028800_STENCIL_ENABLE(track->db_depth_control) || 373 G_028800_Z_ENABLE(track->db_depth_control)) { 374 - u32 nviews, bpe, ntiles, pitch, pitch_align, height, size, slice_tile_max; 375 if (track->db_bo == NULL) { 376 dev_warn(p->dev, "z/stencil with no depth buffer\n"); 377 return -EINVAL; ··· 419 ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF); 420 } else { 421 size = radeon_bo_size(track->db_bo); 422 - pitch = G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1; 423 slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; 424 slice_tile_max *= 64; 425 - height = slice_tile_max / (pitch * 8); 426 if (height > 8192) 427 height = 8192; 428 - switch (G_028010_ARRAY_MODE(track->db_depth_info)) { 429 case V_028010_ARRAY_1D_TILED_THIN1: 430 - pitch_align = (max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8); 431 - if (!IS_ALIGNED(pitch, pitch_align)) { 432 - dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", 433 - __func__, __LINE__, pitch); 434 - return -EINVAL; 435 - } 436 /* don't break userspace */ 437 height &= ~0x7; 438 - if (!IS_ALIGNED(height, 8)) { 439 - dev_warn(p->dev, "%s:%d db height (%d) invalid\n", 440 - __func__, __LINE__, height); 441 - return -EINVAL; 442 - } 443 break; 444 case V_028010_ARRAY_2D_TILED_THIN1: 445 - pitch_align = max((u32)track->nbanks, 446 - (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8; 447 - if (!IS_ALIGNED(pitch, pitch_align)) { 448 - dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", 449 - __func__, __LINE__, pitch); 450 - return -EINVAL; 451 - } 452 - if (!IS_ALIGNED((height / 8), track->npipes)) { 453 - dev_warn(p->dev, "%s:%d db height (%d) invalid\n", 454 - __func__, __LINE__, height); 455 - return -EINVAL; 456 - } 457 break; 458 default: 459 dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, ··· 454 track->db_depth_info); 455 return -EINVAL; 456 } 457 - if (!IS_ALIGNED(track->db_offset, track->group_size)) { 458 - dev_warn(p->dev, "%s offset[%d] %d not aligned\n", __func__, i, track->db_offset); 459 return -EINVAL; 460 } 461 ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; 462 nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; 463 tmp = ntiles * bpe * 64 * nviews; 464 if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { 465 - dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %d have %ld)\n", 466 track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, 467 radeon_bo_size(track->db_bo)); 468 return -EINVAL; ··· 1025 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 1026 track->cb_color_base_last[tmp] = ib[idx]; 1027 track->cb_color_bo[tmp] = reloc->robj; 1028 break; 1029 case DB_DEPTH_BASE: 1030 r = r600_cs_packet_next_reloc(p, &reloc); ··· 1037 track->db_offset = radeon_get_ib_value(p, idx) << 8; 1038 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 1039 track->db_bo = reloc->robj; 1040 break; 1041 case DB_HTILE_DATA_BASE: 1042 case SQ_PGM_START_FS: ··· 1159 static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, 1160 struct radeon_bo *texture, 1161 struct radeon_bo *mipmap, 1162 u32 tiling_flags) 1163 { 1164 struct r600_cs_track *track = p->track; 1165 u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0; 1166 - u32 word0, word1, l0_size, mipmap_size, pitch, pitch_align; 1167 1168 /* on legacy kernel we don't perform advanced check */ 1169 if (p->rdev == NULL) 1170 return 0; 1171 1172 word0 = radeon_get_ib_value(p, idx + 0); 1173 if (tiling_flags & RADEON_TILING_MACRO) ··· 1210 return -EINVAL; 1211 } 1212 1213 - pitch = G_038000_PITCH(word0) + 1; 1214 - switch (G_038000_TILE_MODE(word0)) { 1215 - case V_038000_ARRAY_LINEAR_GENERAL: 1216 - pitch_align = 1; 1217 - /* XXX check height align */ 1218 - break; 1219 - case V_038000_ARRAY_LINEAR_ALIGNED: 1220 - pitch_align = max((u32)64, (u32)(track->group_size / bpe)) / 8; 1221 - if (!IS_ALIGNED(pitch, pitch_align)) { 1222 - dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", 1223 - __func__, __LINE__, pitch); 1224 - return -EINVAL; 1225 - } 1226 - /* XXX check height align */ 1227 - break; 1228 - case V_038000_ARRAY_1D_TILED_THIN1: 1229 - pitch_align = max((u32)8, (u32)(track->group_size / (8 * bpe))) / 8; 1230 - if (!IS_ALIGNED(pitch, pitch_align)) { 1231 - dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", 1232 - __func__, __LINE__, pitch); 1233 - return -EINVAL; 1234 - } 1235 - /* XXX check height align */ 1236 - break; 1237 - case V_038000_ARRAY_2D_TILED_THIN1: 1238 - pitch_align = max((u32)track->nbanks, 1239 - (u32)(((track->group_size / 8) / bpe) * track->nbanks)) / 8; 1240 - if (!IS_ALIGNED(pitch, pitch_align)) { 1241 - dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", 1242 - __func__, __LINE__, pitch); 1243 - return -EINVAL; 1244 - } 1245 - /* XXX check height align */ 1246 - break; 1247 - default: 1248 - dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, 1249 - G_038000_TILE_MODE(word0), word0); 1250 return -EINVAL; 1251 } 1252 - /* XXX check offset align */ 1253 1254 word0 = radeon_get_ib_value(p, idx + 4); 1255 word1 = radeon_get_ib_value(p, idx + 5); ··· 1476 mip_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 1477 mipmap = reloc->robj; 1478 r = r600_check_texture_resource(p, idx+(i*7)+1, 1479 - texture, mipmap, reloc->lobj.tiling_flags); 1480 if (r) 1481 return r; 1482 ib[idx+1+(i*7)+2] += base_offset;
··· 50 u32 nsamples; 51 u32 cb_color_base_last[8]; 52 struct radeon_bo *cb_color_bo[8]; 53 + u64 cb_color_bo_mc[8]; 54 u32 cb_color_bo_offset[8]; 55 struct radeon_bo *cb_color_frag_bo[8]; 56 struct radeon_bo *cb_color_tile_bo[8]; ··· 67 u32 db_depth_size; 68 u32 db_offset; 69 struct radeon_bo *db_bo; 70 + u64 db_bo_mc; 71 }; 72 73 static inline int r600_bpe_from_format(u32 *bpe, u32 format) ··· 140 return 0; 141 } 142 143 + struct array_mode_checker { 144 + int array_mode; 145 + u32 group_size; 146 + u32 nbanks; 147 + u32 npipes; 148 + u32 nsamples; 149 + u32 bpe; 150 + }; 151 + 152 + /* returns alignment in pixels for pitch/height/depth and bytes for base */ 153 + static inline int r600_get_array_mode_alignment(struct array_mode_checker *values, 154 + u32 *pitch_align, 155 + u32 *height_align, 156 + u32 *depth_align, 157 + u64 *base_align) 158 + { 159 + u32 tile_width = 8; 160 + u32 tile_height = 8; 161 + u32 macro_tile_width = values->nbanks; 162 + u32 macro_tile_height = values->npipes; 163 + u32 tile_bytes = tile_width * tile_height * values->bpe * values->nsamples; 164 + u32 macro_tile_bytes = macro_tile_width * macro_tile_height * tile_bytes; 165 + 166 + switch (values->array_mode) { 167 + case ARRAY_LINEAR_GENERAL: 168 + /* technically tile_width/_height for pitch/height */ 169 + *pitch_align = 1; /* tile_width */ 170 + *height_align = 1; /* tile_height */ 171 + *depth_align = 1; 172 + *base_align = 1; 173 + break; 174 + case ARRAY_LINEAR_ALIGNED: 175 + *pitch_align = max((u32)64, (u32)(values->group_size / values->bpe)); 176 + *height_align = tile_height; 177 + *depth_align = 1; 178 + *base_align = values->group_size; 179 + break; 180 + case ARRAY_1D_TILED_THIN1: 181 + *pitch_align = max((u32)tile_width, 182 + (u32)(values->group_size / 183 + (tile_height * values->bpe * values->nsamples))); 184 + *height_align = tile_height; 185 + *depth_align = 1; 186 + *base_align = values->group_size; 187 + break; 188 + case ARRAY_2D_TILED_THIN1: 189 + *pitch_align = max((u32)macro_tile_width, 190 + (u32)(((values->group_size / tile_height) / 191 + (values->bpe * values->nsamples)) * 192 + values->nbanks)) * tile_width; 193 + *height_align = macro_tile_height * tile_height; 194 + *depth_align = 1; 195 + *base_align = max(macro_tile_bytes, 196 + (*pitch_align) * values->bpe * (*height_align) * values->nsamples); 197 + break; 198 + default: 199 + return -EINVAL; 200 + } 201 + 202 + return 0; 203 + } 204 + 205 static void r600_cs_track_init(struct r600_cs_track *track) 206 { 207 int i; ··· 153 track->cb_color_info[i] = 0; 154 track->cb_color_bo[i] = NULL; 155 track->cb_color_bo_offset[i] = 0xFFFFFFFF; 156 + track->cb_color_bo_mc[i] = 0xFFFFFFFF; 157 } 158 track->cb_target_mask = 0xFFFFFFFF; 159 track->cb_shader_mask = 0xFFFFFFFF; 160 track->db_bo = NULL; 161 + track->db_bo_mc = 0xFFFFFFFF; 162 /* assume the biggest format and that htile is enabled */ 163 track->db_depth_info = 7 | (1 << 25); 164 track->db_depth_view = 0xFFFFC000; ··· 168 static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) 169 { 170 struct r600_cs_track *track = p->track; 171 + u32 bpe = 0, slice_tile_max, size, tmp; 172 + u32 height, height_align, pitch, pitch_align, depth_align; 173 + u64 base_offset, base_align; 174 + struct array_mode_checker array_check; 175 volatile u32 *ib = p->ib->ptr; 176 unsigned array_mode; 177 ··· 183 i, track->cb_color_info[i]); 184 return -EINVAL; 185 } 186 + /* pitch in pixels */ 187 + pitch = (G_028060_PITCH_TILE_MAX(track->cb_color_size[i]) + 1) * 8; 188 slice_tile_max = G_028060_SLICE_TILE_MAX(track->cb_color_size[i]) + 1; 189 slice_tile_max *= 64; 190 + height = slice_tile_max / pitch; 191 if (height > 8192) 192 height = 8192; 193 array_mode = G_0280A0_ARRAY_MODE(track->cb_color_info[i]); 194 + 195 + base_offset = track->cb_color_bo_mc[i] + track->cb_color_bo_offset[i]; 196 + array_check.array_mode = array_mode; 197 + array_check.group_size = track->group_size; 198 + array_check.nbanks = track->nbanks; 199 + array_check.npipes = track->npipes; 200 + array_check.nsamples = track->nsamples; 201 + array_check.bpe = bpe; 202 + if (r600_get_array_mode_alignment(&array_check, 203 + &pitch_align, &height_align, &depth_align, &base_align)) { 204 + dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, 205 + G_0280A0_ARRAY_MODE(track->cb_color_info[i]), i, 206 + track->cb_color_info[i]); 207 + return -EINVAL; 208 + } 209 switch (array_mode) { 210 case V_0280A0_ARRAY_LINEAR_GENERAL: 211 break; 212 case V_0280A0_ARRAY_LINEAR_ALIGNED: 213 break; 214 case V_0280A0_ARRAY_1D_TILED_THIN1: 215 /* avoid breaking userspace */ 216 if (height > 7) 217 height &= ~0x7; 218 break; 219 case V_0280A0_ARRAY_2D_TILED_THIN1: 220 break; 221 default: 222 dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, ··· 244 track->cb_color_info[i]); 245 return -EINVAL; 246 } 247 + 248 + if (!IS_ALIGNED(pitch, pitch_align)) { 249 + dev_warn(p->dev, "%s:%d cb pitch (%d) invalid\n", 250 + __func__, __LINE__, pitch); 251 + return -EINVAL; 252 + } 253 + if (!IS_ALIGNED(height, height_align)) { 254 + dev_warn(p->dev, "%s:%d cb height (%d) invalid\n", 255 + __func__, __LINE__, height); 256 + return -EINVAL; 257 + } 258 + if (!IS_ALIGNED(base_offset, base_align)) { 259 + dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset); 260 + return -EINVAL; 261 + } 262 + 263 /* check offset */ 264 + tmp = height * pitch * bpe; 265 if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { 266 if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { 267 /* the initial DDX does bad things with the CB size occasionally */ ··· 260 return -EINVAL; 261 } 262 } 263 /* limit max tile */ 264 + tmp = (height * pitch) >> 6; 265 if (tmp < slice_tile_max) 266 slice_tile_max = tmp; 267 + tmp = S_028060_PITCH_TILE_MAX((pitch / 8) - 1) | 268 S_028060_SLICE_TILE_MAX(slice_tile_max - 1); 269 ib[track->cb_color_size_idx[i]] = tmp; 270 return 0; ··· 310 /* Check depth buffer */ 311 if (G_028800_STENCIL_ENABLE(track->db_depth_control) || 312 G_028800_Z_ENABLE(track->db_depth_control)) { 313 + u32 nviews, bpe, ntiles, size, slice_tile_max; 314 + u32 height, height_align, pitch, pitch_align, depth_align; 315 + u64 base_offset, base_align; 316 + struct array_mode_checker array_check; 317 + int array_mode; 318 + 319 if (track->db_bo == NULL) { 320 dev_warn(p->dev, "z/stencil with no depth buffer\n"); 321 return -EINVAL; ··· 353 ib[track->db_depth_size_idx] = S_028000_SLICE_TILE_MAX(tmp - 1) | (track->db_depth_size & 0x3FF); 354 } else { 355 size = radeon_bo_size(track->db_bo); 356 + /* pitch in pixels */ 357 + pitch = (G_028000_PITCH_TILE_MAX(track->db_depth_size) + 1) * 8; 358 slice_tile_max = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; 359 slice_tile_max *= 64; 360 + height = slice_tile_max / pitch; 361 if (height > 8192) 362 height = 8192; 363 + base_offset = track->db_bo_mc + track->db_offset; 364 + array_mode = G_028010_ARRAY_MODE(track->db_depth_info); 365 + array_check.array_mode = array_mode; 366 + array_check.group_size = track->group_size; 367 + array_check.nbanks = track->nbanks; 368 + array_check.npipes = track->npipes; 369 + array_check.nsamples = track->nsamples; 370 + array_check.bpe = bpe; 371 + if (r600_get_array_mode_alignment(&array_check, 372 + &pitch_align, &height_align, &depth_align, &base_align)) { 373 + dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, 374 + G_028010_ARRAY_MODE(track->db_depth_info), 375 + track->db_depth_info); 376 + return -EINVAL; 377 + } 378 + switch (array_mode) { 379 case V_028010_ARRAY_1D_TILED_THIN1: 380 /* don't break userspace */ 381 height &= ~0x7; 382 break; 383 case V_028010_ARRAY_2D_TILED_THIN1: 384 break; 385 default: 386 dev_warn(p->dev, "%s invalid tiling %d (0x%08X)\n", __func__, ··· 395 track->db_depth_info); 396 return -EINVAL; 397 } 398 + 399 + if (!IS_ALIGNED(pitch, pitch_align)) { 400 + dev_warn(p->dev, "%s:%d db pitch (%d) invalid\n", 401 + __func__, __LINE__, pitch); 402 return -EINVAL; 403 } 404 + if (!IS_ALIGNED(height, height_align)) { 405 + dev_warn(p->dev, "%s:%d db height (%d) invalid\n", 406 + __func__, __LINE__, height); 407 + return -EINVAL; 408 + } 409 + if (!IS_ALIGNED(base_offset, base_align)) { 410 + dev_warn(p->dev, "%s offset[%d] 0x%llx not aligned\n", __func__, i, base_offset); 411 + return -EINVAL; 412 + } 413 + 414 ntiles = G_028000_SLICE_TILE_MAX(track->db_depth_size) + 1; 415 nviews = G_028004_SLICE_MAX(track->db_depth_view) + 1; 416 tmp = ntiles * bpe * 64 * nviews; 417 if ((tmp + track->db_offset) > radeon_bo_size(track->db_bo)) { 418 + dev_warn(p->dev, "z/stencil buffer too small (0x%08X %d %d %d -> %u have %lu)\n", 419 track->db_depth_size, ntiles, nviews, bpe, tmp + track->db_offset, 420 radeon_bo_size(track->db_bo)); 421 return -EINVAL; ··· 954 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 955 track->cb_color_base_last[tmp] = ib[idx]; 956 track->cb_color_bo[tmp] = reloc->robj; 957 + track->cb_color_bo_mc[tmp] = reloc->lobj.gpu_offset; 958 break; 959 case DB_DEPTH_BASE: 960 r = r600_cs_packet_next_reloc(p, &reloc); ··· 965 track->db_offset = radeon_get_ib_value(p, idx) << 8; 966 ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 967 track->db_bo = reloc->robj; 968 + track->db_bo_mc = reloc->lobj.gpu_offset; 969 break; 970 case DB_HTILE_DATA_BASE: 971 case SQ_PGM_START_FS: ··· 1086 static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, 1087 struct radeon_bo *texture, 1088 struct radeon_bo *mipmap, 1089 + u64 base_offset, 1090 + u64 mip_offset, 1091 u32 tiling_flags) 1092 { 1093 struct r600_cs_track *track = p->track; 1094 u32 nfaces, nlevels, blevel, w0, h0, d0, bpe = 0; 1095 + u32 word0, word1, l0_size, mipmap_size; 1096 + u32 height_align, pitch, pitch_align, depth_align; 1097 + u64 base_align; 1098 + struct array_mode_checker array_check; 1099 1100 /* on legacy kernel we don't perform advanced check */ 1101 if (p->rdev == NULL) 1102 return 0; 1103 + 1104 + /* convert to bytes */ 1105 + base_offset <<= 8; 1106 + mip_offset <<= 8; 1107 1108 word0 = radeon_get_ib_value(p, idx + 0); 1109 if (tiling_flags & RADEON_TILING_MACRO) ··· 1128 return -EINVAL; 1129 } 1130 1131 + /* pitch in texels */ 1132 + pitch = (G_038000_PITCH(word0) + 1) * 8; 1133 + array_check.array_mode = G_038000_TILE_MODE(word0); 1134 + array_check.group_size = track->group_size; 1135 + array_check.nbanks = track->nbanks; 1136 + array_check.npipes = track->npipes; 1137 + array_check.nsamples = 1; 1138 + array_check.bpe = bpe; 1139 + if (r600_get_array_mode_alignment(&array_check, 1140 + &pitch_align, &height_align, &depth_align, &base_align)) { 1141 + dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", 1142 + __func__, __LINE__, G_038000_TILE_MODE(word0)); 1143 return -EINVAL; 1144 } 1145 + 1146 + /* XXX check height as well... */ 1147 + 1148 + if (!IS_ALIGNED(pitch, pitch_align)) { 1149 + dev_warn(p->dev, "%s:%d tex pitch (%d) invalid\n", 1150 + __func__, __LINE__, pitch); 1151 + return -EINVAL; 1152 + } 1153 + if (!IS_ALIGNED(base_offset, base_align)) { 1154 + dev_warn(p->dev, "%s:%d tex base offset (0x%llx) invalid\n", 1155 + __func__, __LINE__, base_offset); 1156 + return -EINVAL; 1157 + } 1158 + if (!IS_ALIGNED(mip_offset, base_align)) { 1159 + dev_warn(p->dev, "%s:%d tex mip offset (0x%llx) invalid\n", 1160 + __func__, __LINE__, mip_offset); 1161 + return -EINVAL; 1162 + } 1163 1164 word0 = radeon_get_ib_value(p, idx + 4); 1165 word1 = radeon_get_ib_value(p, idx + 5); ··· 1402 mip_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); 1403 mipmap = reloc->robj; 1404 r = r600_check_texture_resource(p, idx+(i*7)+1, 1405 + texture, mipmap, 1406 + base_offset + radeon_get_ib_value(p, idx+1+(i*7)+2), 1407 + mip_offset + radeon_get_ib_value(p, idx+1+(i*7)+3), 1408 + reloc->lobj.tiling_flags); 1409 if (r) 1410 return r; 1411 ib[idx+1+(i*7)+2] += base_offset;
+6
drivers/gpu/drm/radeon/r600d.h
··· 51 #define PTE_READABLE (1 << 5) 52 #define PTE_WRITEABLE (1 << 6) 53 54 /* Registers */ 55 #define ARB_POP 0x2418 56 #define ENABLE_TC128 (1 << 30)
··· 51 #define PTE_READABLE (1 << 5) 52 #define PTE_WRITEABLE (1 << 6) 53 54 + /* tiling bits */ 55 + #define ARRAY_LINEAR_GENERAL 0x00000000 56 + #define ARRAY_LINEAR_ALIGNED 0x00000001 57 + #define ARRAY_1D_TILED_THIN1 0x00000002 58 + #define ARRAY_2D_TILED_THIN1 0x00000004 59 + 60 /* Registers */ 61 #define ARB_POP 0x2418 62 #define ENABLE_TC128 (1 << 30)