From 49d3c6a8e63ead43fafb7d52e2c770a1320eb2ee Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 23 Feb 2015 06:48:34 +0000 Subject: [PATCH] vc4: Update to current kernel sources. New BO create and mmap ioctls are added. The submit ABI gains a flags argument, and the pointers are fixed at 64-bit. Shaders are now fixed at the start of their BOs. --- src/gallium/drivers/vc4/kernel/vc4_drv.h | 12 +++-- src/gallium/drivers/vc4/kernel/vc4_gem.c | 16 ++++-- src/gallium/drivers/vc4/kernel/vc4_validate.c | 28 +++++++---- .../drivers/vc4/kernel/vc4_validate_shaders.c | 16 ++---- src/gallium/drivers/vc4/vc4_context.c | 10 ++-- src/gallium/drivers/vc4/vc4_drm.h | 50 ++++++++++++++++--- src/gallium/drivers/vc4/vc4_simulator.c | 6 +-- .../drivers/vc4/vc4_simulator_validate.h | 4 +- 8 files changed, 93 insertions(+), 49 deletions(-) diff --git a/src/gallium/drivers/vc4/kernel/vc4_drv.h b/src/gallium/drivers/vc4/kernel/vc4_drv.h index 81ffa03a6fa..12a3ceff725 100644 --- a/src/gallium/drivers/vc4/kernel/vc4_drv.h +++ b/src/gallium/drivers/vc4/kernel/vc4_drv.h @@ -39,7 +39,10 @@ struct vc4_bo_exec_state { enum vc4_bo_mode mode; }; -struct exec_info { +struct vc4_exec_info { + /* Sequence number for this bin/render job. */ + uint64_t seqno; + /* Kernel-space copy of the ioctl arguments */ struct drm_vc4_submit_cl *args; @@ -159,13 +162,12 @@ vc4_validate_cl(struct drm_device *dev, void *unvalidated, uint32_t len, bool is_bin, - struct exec_info *exec); + struct vc4_exec_info *exec); int -vc4_validate_shader_recs(struct drm_device *dev, struct exec_info *exec); +vc4_validate_shader_recs(struct drm_device *dev, struct vc4_exec_info *exec); struct vc4_validated_shader_info * -vc4_validate_shader(struct drm_gem_cma_object *shader_obj, - uint32_t start_offset); +vc4_validate_shader(struct drm_gem_cma_object *shader_obj); #endif /* VC4_DRV_H */ diff --git a/src/gallium/drivers/vc4/kernel/vc4_gem.c b/src/gallium/drivers/vc4/kernel/vc4_gem.c index 1ea17aa4e8c..c9a75733d6d 100644 --- a/src/gallium/drivers/vc4/kernel/vc4_gem.c +++ b/src/gallium/drivers/vc4/kernel/vc4_gem.c @@ -26,7 +26,7 @@ #include "vc4_drv.h" int -vc4_cl_validate(struct drm_device *dev, struct exec_info *exec) +vc4_cl_validate(struct drm_device *dev, struct vc4_exec_info *exec) { struct drm_vc4_submit_cl *args = exec->args; void *temp = NULL; @@ -72,26 +72,32 @@ vc4_cl_validate(struct drm_device *dev, struct exec_info *exec) exec->shader_state = temp + exec_size; exec->shader_state_size = args->shader_rec_count; - ret = copy_from_user(bin, args->bin_cl, args->bin_cl_size); + ret = copy_from_user(bin, + (void __user *)(uintptr_t)args->bin_cl, + args->bin_cl_size); if (ret) { DRM_ERROR("Failed to copy in bin cl\n"); goto fail; } - ret = copy_from_user(render, args->render_cl, args->render_cl_size); + ret = copy_from_user(render, + (void __user *)(uintptr_t)args->render_cl, + args->render_cl_size); if (ret) { DRM_ERROR("Failed to copy in render cl\n"); goto fail; } - ret = copy_from_user(exec->shader_rec_u, args->shader_rec, + ret = copy_from_user(exec->shader_rec_u, + (void __user *)(uintptr_t)args->shader_rec, args->shader_rec_size); if (ret) { DRM_ERROR("Failed to copy in shader recs\n"); goto fail; } - ret = copy_from_user(exec->uniforms_u, args->uniforms, + ret = copy_from_user(exec->uniforms_u, + (void __user *)(uintptr_t)args->uniforms, args->uniforms_size); if (ret) { DRM_ERROR("Failed to copy in uniforms cl\n"); diff --git a/src/gallium/drivers/vc4/kernel/vc4_validate.c b/src/gallium/drivers/vc4/kernel/vc4_validate.c index ba6e46f2041..0691a8d769c 100644 --- a/src/gallium/drivers/vc4/kernel/vc4_validate.c +++ b/src/gallium/drivers/vc4/kernel/vc4_validate.c @@ -43,7 +43,7 @@ #include "vc4_packet.h" #define VALIDATE_ARGS \ - struct exec_info *exec, \ + struct vc4_exec_info *exec, \ void *validated, \ void *untrusted @@ -95,7 +95,7 @@ size_is_lt(uint32_t width, uint32_t height, int cpp) } static bool -vc4_use_bo(struct exec_info *exec, +vc4_use_bo(struct vc4_exec_info *exec, uint32_t hindex, enum vc4_bo_mode mode, struct drm_gem_cma_object **obj) @@ -123,7 +123,7 @@ vc4_use_bo(struct exec_info *exec, } static bool -vc4_use_handle(struct exec_info *exec, +vc4_use_handle(struct vc4_exec_info *exec, uint32_t gem_handles_packet_index, enum vc4_bo_mode mode, struct drm_gem_cma_object **obj) @@ -148,7 +148,7 @@ gl_shader_rec_size(uint32_t pointer_bits) } static bool -check_tex_size(struct exec_info *exec, struct drm_gem_cma_object *fbo, +check_tex_size(struct vc4_exec_info *exec, struct drm_gem_cma_object *fbo, uint32_t offset, uint8_t tiling_format, uint32_t width, uint32_t height, uint8_t cpp) { @@ -657,7 +657,8 @@ static const struct cmd_info { bool render; uint16_t len; const char *name; - int (*func)(struct exec_info *exec, void *validated, void *untrusted); + int (*func)(struct vc4_exec_info *exec, void *validated, + void *untrusted); } cmd_info[] = { [VC4_PACKET_HALT] = { 1, 1, 1, "halt", NULL }, [VC4_PACKET_NOP] = { 1, 1, 1, "nop", NULL }, @@ -720,7 +721,7 @@ vc4_validate_cl(struct drm_device *dev, void *unvalidated, uint32_t len, bool is_bin, - struct exec_info *exec) + struct vc4_exec_info *exec) { uint32_t dst_offset = 0; uint32_t src_offset = 0; @@ -815,7 +816,7 @@ vc4_validate_cl(struct drm_device *dev, } static bool -reloc_tex(struct exec_info *exec, +reloc_tex(struct vc4_exec_info *exec, void *uniform_data_u, struct vc4_texture_sample_info *sample, uint32_t texture_handle_index) @@ -976,7 +977,7 @@ reloc_tex(struct exec_info *exec, static int validate_shader_rec(struct drm_device *dev, - struct exec_info *exec, + struct vc4_exec_info *exec, struct vc4_shader_state *state) { uint32_t *src_handles; @@ -1073,9 +1074,14 @@ validate_shader_rec(struct drm_device *dev, switch (relocs[i].type) { case RELOC_CODE: + if (src_offset != 0) { + DRM_ERROR("Shaders must be at offset 0 of " + "the BO.\n"); + goto fail; + } + kfree(validated_shader); - validated_shader = vc4_validate_shader(bo[i], - src_offset); + validated_shader = vc4_validate_shader(bo[i]); if (!validated_shader) goto fail; @@ -1158,7 +1164,7 @@ fail: int vc4_validate_shader_recs(struct drm_device *dev, - struct exec_info *exec) + struct vc4_exec_info *exec) { uint32_t i; int ret = 0; diff --git a/src/gallium/drivers/vc4/kernel/vc4_validate_shaders.c b/src/gallium/drivers/vc4/kernel/vc4_validate_shaders.c index 48bc683da5c..e5a75c5f8c2 100644 --- a/src/gallium/drivers/vc4/kernel/vc4_validate_shaders.c +++ b/src/gallium/drivers/vc4/kernel/vc4_validate_shaders.c @@ -368,8 +368,7 @@ check_instruction_reads(uint64_t inst, } struct vc4_validated_shader_info * -vc4_validate_shader(struct drm_gem_cma_object *shader_obj, - uint32_t start_offset) +vc4_validate_shader(struct drm_gem_cma_object *shader_obj) { bool found_shader_end = false; int shader_end_ip = 0; @@ -386,14 +385,8 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj, for (i = 0; i < ARRAY_SIZE(validation_state.live_clamp_offsets); i++) validation_state.live_clamp_offsets[i] = ~0; - if (start_offset + sizeof(uint64_t) > shader_obj->base.size) { - DRM_ERROR("shader starting at %d outside of BO sized %d\n", - start_offset, - shader_obj->base.size); - return NULL; - } - shader = shader_obj->vaddr + start_offset; - max_ip = (shader_obj->base.size - start_offset) / sizeof(uint64_t); + shader = shader_obj->vaddr; + max_ip = shader_obj->base.size / sizeof(uint64_t); validated_shader = kcalloc(sizeof(*validated_shader), 1, GFP_KERNEL); if (!validated_shader) @@ -450,9 +443,8 @@ vc4_validate_shader(struct drm_gem_cma_object *shader_obj, } if (ip == max_ip) { - DRM_ERROR("shader starting at %d failed to terminate before " + DRM_ERROR("shader failed to terminate before " "shader BO end at %d\n", - start_offset, shader_obj->base.size); goto fail; } diff --git a/src/gallium/drivers/vc4/vc4_context.c b/src/gallium/drivers/vc4/vc4_context.c index 17520163d18..ed10f7ac7d3 100644 --- a/src/gallium/drivers/vc4/vc4_context.c +++ b/src/gallium/drivers/vc4/vc4_context.c @@ -363,17 +363,17 @@ vc4_flush(struct pipe_context *pctx) struct drm_vc4_submit_cl submit; memset(&submit, 0, sizeof(submit)); - submit.bo_handles = vc4->bo_handles.base; + submit.bo_handles = (uintptr_t)vc4->bo_handles.base; submit.bo_handle_count = (vc4->bo_handles.next - vc4->bo_handles.base) / 4; - submit.bin_cl = vc4->bcl.base; + submit.bin_cl = (uintptr_t)vc4->bcl.base; submit.bin_cl_size = vc4->bcl.next - vc4->bcl.base; - submit.render_cl = vc4->rcl.base; + submit.render_cl = (uintptr_t)vc4->rcl.base; submit.render_cl_size = vc4->rcl.next - vc4->rcl.base; - submit.shader_rec = vc4->shader_rec.base; + submit.shader_rec = (uintptr_t)vc4->shader_rec.base; submit.shader_rec_size = vc4->shader_rec.next - vc4->shader_rec.base; submit.shader_rec_count = vc4->shader_rec_count; - submit.uniforms = vc4->uniforms.base; + submit.uniforms = (uintptr_t)vc4->uniforms.base; submit.uniforms_size = vc4->uniforms.next - vc4->uniforms.base; if (!(vc4_debug & VC4_DEBUG_NORAST)) { diff --git a/src/gallium/drivers/vc4/vc4_drm.h b/src/gallium/drivers/vc4/vc4_drm.h index 34f5a88fa01..062fd3b687e 100644 --- a/src/gallium/drivers/vc4/vc4_drm.h +++ b/src/gallium/drivers/vc4/vc4_drm.h @@ -1,5 +1,5 @@ /* - * Copyright © 2014 Broadcom + * Copyright © 2014-2015 Broadcom * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -29,10 +29,14 @@ #define DRM_VC4_SUBMIT_CL 0x00 #define DRM_VC4_WAIT_SEQNO 0x01 #define DRM_VC4_WAIT_BO 0x02 +#define DRM_VC4_CREATE_BO 0x03 +#define DRM_VC4_MMAP_BO 0x04 #define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl) #define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno) #define DRM_IOCTL_VC4_WAIT_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_WAIT_BO, struct drm_vc4_wait_bo) +#define DRM_IOCTL_VC4_CREATE_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_CREATE_BO, struct drm_vc4_create_bo) +#define DRM_IOCTL_VC4_MMAP_BO DRM_IOWR( DRM_COMMAND_BASE + DRM_VC4_MMAP_BO, struct drm_vc4_mmap_bo) /** @@ -56,7 +60,7 @@ struct drm_vc4_submit_cl { * then writes out the state updates and draw calls necessary per tile * to the tile allocation BO. */ - void __user *bin_cl; + uint64_t bin_cl; /* Pointer to the render command list. * @@ -66,7 +70,7 @@ struct drm_vc4_submit_cl { * stored rendering for that tile, then store the tile's state back to * memory. */ - void __user *render_cl; + uint64_t render_cl; /* Pointer to the shader records. * @@ -77,7 +81,7 @@ struct drm_vc4_submit_cl { * and an attribute count), so those BO indices into bo_handles are * just stored as uint32_ts before each shader record passed in. */ - void __user *shader_rec; + uint64_t shader_rec; /* Pointer to uniform data and texture handles for the textures * referenced by the shader. @@ -93,8 +97,8 @@ struct drm_vc4_submit_cl { * because the kernel has to determine the sizes anyway during shader * code validation. */ - void __user *uniforms; - void __user *bo_handles; + uint64_t uniforms; + uint64_t bo_handles; /* Size in bytes of the binner command list. */ uint32_t bin_cl_size; @@ -115,6 +119,7 @@ struct drm_vc4_submit_cl { /* Number of BO handles passed in (size is that times 4). */ uint32_t bo_handle_count; + uint32_t flags; uint32_t pad; /* Returned value of the seqno of this render job (for the @@ -149,4 +154,37 @@ struct drm_vc4_wait_bo { uint64_t timeout_ns; }; +/** + * struct drm_vc4_create_bo - ioctl argument for creating VC4 BOs. + * + * There are currently no values for the flags argument, but it may be + * used in a future extension. + */ +struct drm_vc4_create_bo { + uint32_t size; + uint32_t flags; + /** Returned GEM handle for the BO. */ + uint32_t handle; + uint32_t pad; +}; + +/** + * struct drm_vc4_mmap_bo - ioctl argument for mapping VC4 BOs. + * + * This doesn't actually perform an mmap. Instead, it returns the + * offset you need to use in an mmap on the DRM device node. This + * means that tools like valgrind end up knowing about the mapped + * memory. + * + * There are currently no values for the flags argument, but it may be + * used in a future extension. + */ +struct drm_vc4_mmap_bo { + /** Handle for the object being mapped. */ + uint32_t handle; + uint32_t flags; + /** offset into the drm node to use for subsequent mmap call. */ + uint64_t offset; +}; + #endif /* _UAPI_VC4_DRM_H_ */ diff --git a/src/gallium/drivers/vc4/vc4_simulator.c b/src/gallium/drivers/vc4/vc4_simulator.c index ee4ad96123b..cd8cc5bb56c 100644 --- a/src/gallium/drivers/vc4/vc4_simulator.c +++ b/src/gallium/drivers/vc4/vc4_simulator.c @@ -65,7 +65,7 @@ drm_gem_cma_create(struct drm_device *dev, size_t size) } static int -vc4_simulator_pin_bos(struct drm_device *dev, struct exec_info *exec) +vc4_simulator_pin_bos(struct drm_device *dev, struct vc4_exec_info *exec) { struct drm_vc4_submit_cl *args = exec->args; struct vc4_context *vc4 = dev->vc4; @@ -90,7 +90,7 @@ vc4_simulator_pin_bos(struct drm_device *dev, struct exec_info *exec) } static int -vc4_simulator_unpin_bos(struct exec_info *exec) +vc4_simulator_unpin_bos(struct vc4_exec_info *exec) { for (int i = 0; i < exec->bo_count; i++) { struct drm_gem_cma_object *obj = exec->bo[i].bo; @@ -115,7 +115,7 @@ vc4_simulator_flush(struct vc4_context *vc4, struct drm_vc4_submit_cl *args) uint32_t winsys_stride = ctex ? ctex->bo->simulator_winsys_stride : 0; uint32_t sim_stride = ctex ? ctex->slices[0].stride : 0; uint32_t row_len = MIN2(sim_stride, winsys_stride); - struct exec_info exec; + struct vc4_exec_info exec; struct drm_device local_dev = { .vc4 = vc4, .simulator_mem_next = OVERFLOW_SIZE, diff --git a/src/gallium/drivers/vc4/vc4_simulator_validate.h b/src/gallium/drivers/vc4/vc4_simulator_validate.h index d6c2aec51c1..1f0c6b67c0f 100644 --- a/src/gallium/drivers/vc4/vc4_simulator_validate.h +++ b/src/gallium/drivers/vc4/vc4_simulator_validate.h @@ -34,7 +34,7 @@ #include "vc4_context.h" #include "vc4_qpu_defines.h" -struct exec_info; +struct vc4_exec_info; #define DRM_INFO(...) fprintf(stderr, __VA_ARGS__) #define DRM_ERROR(...) fprintf(stderr, __VA_ARGS__) @@ -78,6 +78,6 @@ struct drm_gem_cma_object * drm_gem_cma_create(struct drm_device *dev, size_t size); int -vc4_cl_validate(struct drm_device *dev, struct exec_info *exec); +vc4_cl_validate(struct drm_device *dev, struct vc4_exec_info *exec); #endif /* VC4_SIMULATOR_VALIDATE_H */ -- 2.30.2