summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2014-12-26 09:37:27 -1000
committerEric Anholt <eric@anholt.net>2015-06-04 14:15:28 -0700
commit37737b6747d4804f88f6b787f2132efe62f5047b (patch)
treeb384c20da491c6475d29bce8abad999ef462dfc2
parent291ad365c0fb29d1f19c0111c480b8b698b793ba (diff)
downloadlinux-37737b6747d4804f88f6b787f2132efe62f5047b.tar.gz
drm/vc4: Store the validated shader state.
This massively reduces the overhead of CL submission in the kernel. Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r--drivers/gpu/drm/vc4/vc4_bo.c3
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h3
-rw-r--r--drivers/gpu/drm/vc4/vc4_validate.c6
-rw-r--r--drivers/gpu/drm/vc4/vc4_validate_shaders.c5
4 files changed, 12 insertions, 5 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c
index 8bfca3b0b3e1..93be736c87bf 100644
--- a/drivers/gpu/drm/vc4/vc4_bo.c
+++ b/drivers/gpu/drm/vc4/vc4_bo.c
@@ -174,6 +174,9 @@ vc4_free_object(struct drm_gem_object *gem_bo)
return;
}
+ kfree(bo->validated_shader);
+ bo->validated_shader = NULL;
+
bo->free_time = jiffies;
list_add(&bo->size_head, cache_list);
list_add(&bo->unref_head, &vc4->bo_cache.time_list);
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index c7da68b854fe..0f71effb1cab 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -99,6 +99,9 @@ struct vc4_bo {
/* List entry for the BO's position in vc4_dev->bo_cache.size_list */
struct list_head size_head;
+
+ /* Cached state from validation of the shader code. */
+ struct vc4_validated_shader_info *validated_shader;
};
static inline struct vc4_bo *
diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c
index 0691a8d769ca..5ecd640f625a 100644
--- a/drivers/gpu/drm/vc4/vc4_validate.c
+++ b/drivers/gpu/drm/vc4/vc4_validate.c
@@ -1003,7 +1003,7 @@ validate_shader_rec(struct drm_device *dev,
struct drm_gem_cma_object *bo[ARRAY_SIZE(gl_relocs) + 8];
uint32_t nr_attributes = 0, nr_fixed_relocs, nr_relocs, packet_size;
int i;
- struct vc4_validated_shader_info *validated_shader = NULL;
+ struct vc4_validated_shader_info *validated_shader;
if (state->packet == VC4_PACKET_NV_SHADER_STATE) {
relocs = nv_relocs;
@@ -1080,7 +1080,6 @@ validate_shader_rec(struct drm_device *dev,
goto fail;
}
- kfree(validated_shader);
validated_shader = vc4_validate_shader(bo[i]);
if (!validated_shader)
goto fail;
@@ -1153,12 +1152,9 @@ validate_shader_rec(struct drm_device *dev,
*(uint32_t *)(pkt_v + o) = vbo->paddr + offset;
}
- kfree(validated_shader);
-
return 0;
fail:
- kfree(validated_shader);
return -EINVAL;
}
diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c
index ad7ebb11f2d8..17c5bdcf5aa7 100644
--- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c
+++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c
@@ -369,6 +369,7 @@ check_instruction_reads(uint64_t inst,
struct vc4_validated_shader_info *
vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
{
+ struct vc4_bo *shader_bo = to_vc4_bo(&shader_obj->base);
bool found_shader_end = false;
int shader_end_ip = 0;
uint32_t ip, max_ip;
@@ -377,6 +378,9 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
struct vc4_shader_validation_state validation_state;
int i;
+ if (shader_bo->validated_shader)
+ return shader_bo->validated_shader;
+
memset(&validation_state, 0, sizeof(validation_state));
for (i = 0; i < 8; i++)
@@ -456,6 +460,7 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj)
(validated_shader->uniforms_size +
4 * validated_shader->num_texture_samples);
+ shader_bo->validated_shader = validated_shader;
return validated_shader;
fail: