diff options
author | Eric Anholt <eric@anholt.net> | 2016-07-02 12:57:07 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2016-07-14 11:09:27 -0400 |
commit | d0566c2a2f2baacefe1eb75be8a001fdd6fe84a3 (patch) | |
tree | 3fe0d7c9ceffb8bf2abd36171286a8b0e0f50995 /drivers/gpu/drm/vc4/vc4_validate_shaders.c | |
parent | af713795c59fea36161a7debf97dbc10bf652cf7 (diff) |
drm/vc4: Move validation's current/max ip into the validation struct.
Reduces the argument count for some of the functions, and will be used
more with the upcoming looping support.
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/vc4/vc4_validate_shaders.c')
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_validate_shaders.c | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c index f67124b4c534..771d904653f2 100644 --- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c +++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c | |||
@@ -40,6 +40,14 @@ | |||
40 | #include "vc4_qpu_defines.h" | 40 | #include "vc4_qpu_defines.h" |
41 | 41 | ||
42 | struct vc4_shader_validation_state { | 42 | struct vc4_shader_validation_state { |
43 | /* Current IP being validated. */ | ||
44 | uint32_t ip; | ||
45 | |||
46 | /* IP at the end of the BO, do not read shader[max_ip] */ | ||
47 | uint32_t max_ip; | ||
48 | |||
49 | uint64_t *shader; | ||
50 | |||
43 | struct vc4_texture_sample_info tmu_setup[2]; | 51 | struct vc4_texture_sample_info tmu_setup[2]; |
44 | int tmu_write_count[2]; | 52 | int tmu_write_count[2]; |
45 | 53 | ||
@@ -129,11 +137,11 @@ record_texture_sample(struct vc4_validated_shader_info *validated_shader, | |||
129 | } | 137 | } |
130 | 138 | ||
131 | static bool | 139 | static bool |
132 | check_tmu_write(uint64_t inst, | 140 | check_tmu_write(struct vc4_validated_shader_info *validated_shader, |
133 | struct vc4_validated_shader_info *validated_shader, | ||
134 | struct vc4_shader_validation_state *validation_state, | 141 | struct vc4_shader_validation_state *validation_state, |
135 | bool is_mul) | 142 | bool is_mul) |
136 | { | 143 | { |
144 | uint64_t inst = validation_state->shader[validation_state->ip]; | ||
137 | uint32_t waddr = (is_mul ? | 145 | uint32_t waddr = (is_mul ? |
138 | QPU_GET_FIELD(inst, QPU_WADDR_MUL) : | 146 | QPU_GET_FIELD(inst, QPU_WADDR_MUL) : |
139 | QPU_GET_FIELD(inst, QPU_WADDR_ADD)); | 147 | QPU_GET_FIELD(inst, QPU_WADDR_ADD)); |
@@ -228,11 +236,11 @@ check_tmu_write(uint64_t inst, | |||
228 | } | 236 | } |
229 | 237 | ||
230 | static bool | 238 | static bool |
231 | check_reg_write(uint64_t inst, | 239 | check_reg_write(struct vc4_validated_shader_info *validated_shader, |
232 | struct vc4_validated_shader_info *validated_shader, | ||
233 | struct vc4_shader_validation_state *validation_state, | 240 | struct vc4_shader_validation_state *validation_state, |
234 | bool is_mul) | 241 | bool is_mul) |
235 | { | 242 | { |
243 | uint64_t inst = validation_state->shader[validation_state->ip]; | ||
236 | uint32_t waddr = (is_mul ? | 244 | uint32_t waddr = (is_mul ? |
237 | QPU_GET_FIELD(inst, QPU_WADDR_MUL) : | 245 | QPU_GET_FIELD(inst, QPU_WADDR_MUL) : |
238 | QPU_GET_FIELD(inst, QPU_WADDR_ADD)); | 246 | QPU_GET_FIELD(inst, QPU_WADDR_ADD)); |
@@ -261,7 +269,7 @@ check_reg_write(uint64_t inst, | |||
261 | case QPU_W_TMU1_T: | 269 | case QPU_W_TMU1_T: |
262 | case QPU_W_TMU1_R: | 270 | case QPU_W_TMU1_R: |
263 | case QPU_W_TMU1_B: | 271 | case QPU_W_TMU1_B: |
264 | return check_tmu_write(inst, validated_shader, validation_state, | 272 | return check_tmu_write(validated_shader, validation_state, |
265 | is_mul); | 273 | is_mul); |
266 | 274 | ||
267 | case QPU_W_HOST_INT: | 275 | case QPU_W_HOST_INT: |
@@ -294,10 +302,10 @@ check_reg_write(uint64_t inst, | |||
294 | } | 302 | } |
295 | 303 | ||
296 | static void | 304 | static void |
297 | track_live_clamps(uint64_t inst, | 305 | track_live_clamps(struct vc4_validated_shader_info *validated_shader, |
298 | struct vc4_validated_shader_info *validated_shader, | ||
299 | struct vc4_shader_validation_state *validation_state) | 306 | struct vc4_shader_validation_state *validation_state) |
300 | { | 307 | { |
308 | uint64_t inst = validation_state->shader[validation_state->ip]; | ||
301 | uint32_t op_add = QPU_GET_FIELD(inst, QPU_OP_ADD); | 309 | uint32_t op_add = QPU_GET_FIELD(inst, QPU_OP_ADD); |
302 | uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD); | 310 | uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD); |
303 | uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL); | 311 | uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL); |
@@ -369,10 +377,10 @@ track_live_clamps(uint64_t inst, | |||
369 | } | 377 | } |
370 | 378 | ||
371 | static bool | 379 | static bool |
372 | check_instruction_writes(uint64_t inst, | 380 | check_instruction_writes(struct vc4_validated_shader_info *validated_shader, |
373 | struct vc4_validated_shader_info *validated_shader, | ||
374 | struct vc4_shader_validation_state *validation_state) | 381 | struct vc4_shader_validation_state *validation_state) |
375 | { | 382 | { |
383 | uint64_t inst = validation_state->shader[validation_state->ip]; | ||
376 | uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD); | 384 | uint32_t waddr_add = QPU_GET_FIELD(inst, QPU_WADDR_ADD); |
377 | uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL); | 385 | uint32_t waddr_mul = QPU_GET_FIELD(inst, QPU_WADDR_MUL); |
378 | bool ok; | 386 | bool ok; |
@@ -382,12 +390,10 @@ check_instruction_writes(uint64_t inst, | |||
382 | return false; | 390 | return false; |
383 | } | 391 | } |
384 | 392 | ||
385 | ok = (check_reg_write(inst, validated_shader, validation_state, | 393 | ok = (check_reg_write(validated_shader, validation_state, false) && |
386 | false) && | 394 | check_reg_write(validated_shader, validation_state, true)); |
387 | check_reg_write(inst, validated_shader, validation_state, | ||
388 | true)); | ||
389 | 395 | ||
390 | track_live_clamps(inst, validated_shader, validation_state); | 396 | track_live_clamps(validated_shader, validation_state); |
391 | 397 | ||
392 | return ok; | 398 | return ok; |
393 | } | 399 | } |
@@ -417,30 +423,30 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) | |||
417 | { | 423 | { |
418 | bool found_shader_end = false; | 424 | bool found_shader_end = false; |
419 | int shader_end_ip = 0; | 425 | int shader_end_ip = 0; |
420 | uint32_t ip, max_ip; | 426 | uint32_t ip; |
421 | uint64_t *shader; | ||
422 | struct vc4_validated_shader_info *validated_shader; | 427 | struct vc4_validated_shader_info *validated_shader; |
423 | struct vc4_shader_validation_state validation_state; | 428 | struct vc4_shader_validation_state validation_state; |
424 | int i; | 429 | int i; |
425 | 430 | ||
426 | memset(&validation_state, 0, sizeof(validation_state)); | 431 | memset(&validation_state, 0, sizeof(validation_state)); |
432 | validation_state.shader = shader_obj->vaddr; | ||
433 | validation_state.max_ip = shader_obj->base.size / sizeof(uint64_t); | ||
427 | 434 | ||
428 | for (i = 0; i < 8; i++) | 435 | for (i = 0; i < 8; i++) |
429 | validation_state.tmu_setup[i / 4].p_offset[i % 4] = ~0; | 436 | validation_state.tmu_setup[i / 4].p_offset[i % 4] = ~0; |
430 | for (i = 0; i < ARRAY_SIZE(validation_state.live_min_clamp_offsets); i++) | 437 | for (i = 0; i < ARRAY_SIZE(validation_state.live_min_clamp_offsets); i++) |
431 | validation_state.live_min_clamp_offsets[i] = ~0; | 438 | validation_state.live_min_clamp_offsets[i] = ~0; |
432 | 439 | ||
433 | shader = shader_obj->vaddr; | ||
434 | max_ip = shader_obj->base.size / sizeof(uint64_t); | ||
435 | |||
436 | validated_shader = kcalloc(1, sizeof(*validated_shader), GFP_KERNEL); | 440 | validated_shader = kcalloc(1, sizeof(*validated_shader), GFP_KERNEL); |
437 | if (!validated_shader) | 441 | if (!validated_shader) |
438 | return NULL; | 442 | return NULL; |
439 | 443 | ||
440 | for (ip = 0; ip < max_ip; ip++) { | 444 | for (ip = 0; ip < validation_state.max_ip; ip++) { |
441 | uint64_t inst = shader[ip]; | 445 | uint64_t inst = validation_state.shader[ip]; |
442 | uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG); | 446 | uint32_t sig = QPU_GET_FIELD(inst, QPU_SIG); |
443 | 447 | ||
448 | validation_state.ip = ip; | ||
449 | |||
444 | switch (sig) { | 450 | switch (sig) { |
445 | case QPU_SIG_NONE: | 451 | case QPU_SIG_NONE: |
446 | case QPU_SIG_WAIT_FOR_SCOREBOARD: | 452 | case QPU_SIG_WAIT_FOR_SCOREBOARD: |
@@ -450,7 +456,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) | |||
450 | case QPU_SIG_LOAD_TMU1: | 456 | case QPU_SIG_LOAD_TMU1: |
451 | case QPU_SIG_PROG_END: | 457 | case QPU_SIG_PROG_END: |
452 | case QPU_SIG_SMALL_IMM: | 458 | case QPU_SIG_SMALL_IMM: |
453 | if (!check_instruction_writes(inst, validated_shader, | 459 | if (!check_instruction_writes(validated_shader, |
454 | &validation_state)) { | 460 | &validation_state)) { |
455 | DRM_ERROR("Bad write at ip %d\n", ip); | 461 | DRM_ERROR("Bad write at ip %d\n", ip); |
456 | goto fail; | 462 | goto fail; |
@@ -467,7 +473,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) | |||
467 | break; | 473 | break; |
468 | 474 | ||
469 | case QPU_SIG_LOAD_IMM: | 475 | case QPU_SIG_LOAD_IMM: |
470 | if (!check_instruction_writes(inst, validated_shader, | 476 | if (!check_instruction_writes(validated_shader, |
471 | &validation_state)) { | 477 | &validation_state)) { |
472 | DRM_ERROR("Bad LOAD_IMM write at ip %d\n", ip); | 478 | DRM_ERROR("Bad LOAD_IMM write at ip %d\n", ip); |
473 | goto fail; | 479 | goto fail; |
@@ -487,7 +493,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj) | |||
487 | break; | 493 | break; |
488 | } | 494 | } |
489 | 495 | ||
490 | if (ip == max_ip) { | 496 | if (ip == validation_state.max_ip) { |
491 | DRM_ERROR("shader failed to terminate before " | 497 | DRM_ERROR("shader failed to terminate before " |
492 | "shader BO end at %zd\n", | 498 | "shader BO end at %zd\n", |
493 | shader_obj->base.size); | 499 | shader_obj->base.size); |