Hi Lucas. 2015-04-07 11:47 GMT+02:00 Lucas Stach <l.stach@xxxxxxxxxxxxxx>: > Am Dienstag, den 07.04.2015, 11:40 +0200 schrieb Christian Gmeiner: >> 2015-04-07 11:20 GMT+02:00 Lucas Stach <l.stach@xxxxxxxxxxxxxx>: >> > Am Dienstag, den 07.04.2015, 11:04 +0200 schrieb Christian Gmeiner: >> >> Hi Lucas >> >> >> >> 2015-04-07 9:35 GMT+02:00 Lucas Stach <l.stach@xxxxxxxxxxxxxx>: >> >> > Am Sonntag, den 05.04.2015, 21:26 +0200 schrieb Christian Gmeiner: >> >> >> 2015-04-02 17:29 GMT+02:00 Lucas Stach <l.stach@xxxxxxxxxxxxxx>: >> >> >> > From: Christian Gmeiner <christian.gmeiner@xxxxxxxxx> >> >> >> > >> >> >> > This is a consolidation by Russell King of Christian's drm work. >> >> >> > >> >> >> > Signed-off-by: Christian Gmeiner <christian.gmeiner@xxxxxxxxx> >> >> >> > Signed-off-by: Russell King <rmk+kernel@xxxxxxxxxxxxxxxx> >> >> > >> >> >> > --- >> >> > [...] >> >> > >> >> >> > +#endif /* STATE_HI_XML */ >> >> >> > diff --git a/include/uapi/drm/etnaviv_drm.h b/include/uapi/drm/etnaviv_drm.h >> >> >> > new file mode 100644 >> >> >> > index 000000000000..f7b5ac6f3842 >> >> >> > --- /dev/null >> >> >> > +++ b/include/uapi/drm/etnaviv_drm.h >> >> >> > @@ -0,0 +1,225 @@ >> >> >> > +/* >> >> >> > + * Copyright (C) 2013 Red Hat >> >> >> > + * Author: Rob Clark <robdclark@xxxxxxxxx> >> >> >> > + * >> >> >> > + * This program is free software; you can redistribute it and/or modify it >> >> >> > + * under the terms of the GNU General Public License version 2 as published by >> >> >> > + * the Free Software Foundation. >> >> >> > + * >> >> >> > + * This program is distributed in the hope that it will be useful, but WITHOUT >> >> >> > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or >> >> >> > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for >> >> >> > + * more details. >> >> >> > + * >> >> >> > + * You should have received a copy of the GNU General Public License along with >> >> >> > + * this program. If not, see <http://www.gnu.org/licenses/>. >> >> >> > + */ >> >> >> > + >> >> >> > +#ifndef __ETNAVIV_DRM_H__ >> >> >> > +#define __ETNAVIV_DRM_H__ >> >> >> > + >> >> >> > +#include <stddef.h> >> >> >> > +#include <drm/drm.h> >> >> >> > + >> >> >> > +/* Please note that modifications to all structs defined here are >> >> >> > + * subject to backwards-compatibility constraints: >> >> >> > + * 1) Do not use pointers, use uint64_t instead for 32 bit / 64 bit >> >> >> > + * user/kernel compatibility >> >> >> > + * 2) Keep fields aligned to their size >> >> >> > + * 3) Because of how drm_ioctl() works, we can add new fields at >> >> >> > + * the end of an ioctl if some care is taken: drm_ioctl() will >> >> >> > + * zero out the new fields at the tail of the ioctl, so a zero >> >> >> > + * value should have a backwards compatible meaning. And for >> >> >> > + * output params, userspace won't see the newly added output >> >> >> > + * fields.. so that has to be somehow ok. >> >> >> > + */ >> >> >> > + >> >> >> > +#define ETNA_PIPE_3D 0x00 >> >> >> > +#define ETNA_PIPE_2D 0x01 >> >> >> > +#define ETNA_PIPE_VG 0x02 >> >> >> > + >> >> >> > +#define ETNA_MAX_PIPES 3 >> >> >> > + >> >> >> > +/* timeouts are specified in clock-monotonic absolute times (to simplify >> >> >> > + * restarting interrupted ioctls). The following struct is logically the >> >> >> > + * same as 'struct timespec' but 32/64b ABI safe. >> >> >> > + */ >> >> >> > +struct drm_etnaviv_timespec { >> >> >> > + int64_t tv_sec; /* seconds */ >> >> >> > + int64_t tv_nsec; /* nanoseconds */ >> >> >> > +}; >> >> >> > + >> >> >> > +#define ETNAVIV_PARAM_GPU_MODEL 0x01 >> >> >> > +#define ETNAVIV_PARAM_GPU_REVISION 0x02 >> >> >> > +#define ETNAVIV_PARAM_GPU_FEATURES_0 0x03 >> >> >> > +#define ETNAVIV_PARAM_GPU_FEATURES_1 0x04 >> >> >> > +#define ETNAVIV_PARAM_GPU_FEATURES_2 0x05 >> >> >> > +#define ETNAVIV_PARAM_GPU_FEATURES_3 0x06 >> >> >> > +#define ETNAVIV_PARAM_GPU_FEATURES_4 0x07 >> >> >> > + >> >> >> > +#define ETNAVIV_PARAM_GPU_STREAM_COUNT 0x10 >> >> >> > +#define ETNAVIV_PARAM_GPU_REGISTER_MAX 0x11 >> >> >> > +#define ETNAVIV_PARAM_GPU_THREAD_COUNT 0x12 >> >> >> > +#define ETNAVIV_PARAM_GPU_VERTEX_CACHE_SIZE 0x13 >> >> >> > +#define ETNAVIV_PARAM_GPU_SHADER_CORE_COUNT 0x14 >> >> >> > +#define ETNAVIV_PARAM_GPU_PIXEL_PIPES 0x15 >> >> >> > +#define ETNAVIV_PARAM_GPU_VERTEX_OUTPUT_BUFFER_SIZE 0x16 >> >> >> > +#define ETNAVIV_PARAM_GPU_BUFFER_SIZE 0x17 >> >> >> > +#define ETNAVIV_PARAM_GPU_INSTRUCTION_COUNT 0x18 >> >> >> > +#define ETNAVIV_PARAM_GPU_NUM_CONSTANTS 0x19 >> >> >> > + >> >> >> > +//#define MSM_PARAM_GMEM_SIZE 0x02 >> >> >> > + >> >> >> > +struct drm_etnaviv_param { >> >> >> > + uint32_t pipe; /* in, ETNA_PIPE_x */ >> >> >> > + uint32_t param; /* in, ETNAVIV_PARAM_x */ >> >> >> > + uint64_t value; /* out (get_param) or in (set_param) */ >> >> >> > +}; >> >> >> > + >> >> >> > +/* >> >> >> > + * GEM buffers: >> >> >> > + */ >> >> >> > + >> >> >> > +#define ETNA_BO_CMDSTREAM 0x00000001 >> >> >> > +#define ETNA_BO_CACHE_MASK 0x000f0000 >> >> >> > +/* cache modes */ >> >> >> > +#define ETNA_BO_CACHED 0x00010000 >> >> >> > +#define ETNA_BO_WC 0x00020000 >> >> >> > +#define ETNA_BO_UNCACHED 0x00040000 >> >> >> > + >> >> >> > +struct drm_etnaviv_gem_new { >> >> >> > + uint64_t size; /* in */ >> >> >> > + uint32_t flags; /* in, mask of ETNA_BO_x */ >> >> >> > + uint32_t handle; /* out */ >> >> >> > +}; >> >> >> > + >> >> >> > +struct drm_etnaviv_gem_info { >> >> >> > + uint32_t handle; /* in */ >> >> >> > + uint32_t pad; >> >> >> > + uint64_t offset; /* out, offset to pass to mmap() */ >> >> >> > +}; >> >> >> > + >> >> >> > +#define ETNA_PREP_READ 0x01 >> >> >> > +#define ETNA_PREP_WRITE 0x02 >> >> >> > +#define ETNA_PREP_NOSYNC 0x04 >> >> >> > + >> >> >> > +struct drm_etnaviv_gem_cpu_prep { >> >> >> > + uint32_t handle; /* in */ >> >> >> > + uint32_t op; /* in, mask of ETNA_PREP_x */ >> >> >> > + struct drm_etnaviv_timespec timeout; /* in */ >> >> >> > +}; >> >> >> > + >> >> >> > +struct drm_etnaviv_gem_cpu_fini { >> >> >> > + uint32_t handle; /* in */ >> >> >> > +}; >> >> >> > + >> >> >> > +/* >> >> >> > + * Cmdstream Submission: >> >> >> > + */ >> >> >> > + >> >> >> > +/* The value written into the cmdstream is logically: >> >> >> > + * >> >> >> > + * ((relocbuf->gpuaddr + reloc_offset) << shift) | or >> >> >> > + * >> >> >> > + * When we have GPU's w/ >32bit ptrs, it should be possible to deal >> >> >> > + * with this by emit'ing two reloc entries with appropriate shift >> >> >> > + * values. Or a new ETNA_SUBMIT_CMD_x type would also be an option. >> >> >> > + * >> >> >> > + * NOTE that reloc's must be sorted by order of increasing submit_offset, >> >> >> > + * otherwise EINVAL. >> >> >> > + */ >> >> >> > +struct drm_etnaviv_gem_submit_reloc { >> >> >> > + uint32_t submit_offset; /* in, offset from submit_bo */ >> >> >> > + uint32_t or; /* in, value OR'd with result */ >> >> >> > + int32_t shift; /* in, amount of left shift (can be negative) */ >> >> >> > + uint32_t reloc_idx; /* in, index of reloc_bo buffer */ >> >> >> > + uint64_t reloc_offset; /* in, offset from start of reloc_bo */ >> >> >> > +}; >> >> >> > + >> >> >> > +/* submit-types: >> >> >> > + * BUF - this cmd buffer is executed normally. >> >> >> > + * IB_TARGET_BUF - this cmd buffer is an IB target. Reloc's are >> >> >> > + * processed normally, but the kernel does not setup an IB to >> >> >> > + * this buffer in the first-level ringbuffer >> >> >> > + * CTX_RESTORE_BUF - only executed if there has been a GPU context >> >> >> > + * switch since the last SUBMIT ioctl >> >> >> > + */ >> >> >> > +#define ETNA_SUBMIT_CMD_BUF 0x0001 >> >> >> > +#define ETNA_SUBMIT_CMD_IB_TARGET_BUF 0x0002 >> >> >> > +#define ETNA_SUBMIT_CMD_CTX_RESTORE_BUF 0x0003 is a >> >> >> > +struct drm_etnaviv_gem_submit_cmd { >> >> >> > + uint32_t type; /* in, one of ETNA_SUBMIT_CMD_x */ >> >> >> >> >> >> Do we need different types? I did not use this in my kernel tree. >> >> >> >> >> > >> >> > Please also not the commit cleaning this API, which changes this a bit. >> >> > >> >> >> >> Ah yes.. I see it. >> >> >> >> > But yes we need different types. At least the context restore buffer >> >> > type is needed to properly implement GPU power management and context >> >> > switching. >> >> > >> >> >> >> What role does GPU power management plays here? For the context switching >> >> it could make sense. But for the 2d core the context is so small that >> >> it does not >> >> hurt to send it with every command stream. For the 3d core it is much >> >> bigger, but >> >> this could be done completely in the kernel. Or I am wrong here? >> >> >> > If you power down the GPU you loose the context. You are right that we >> > could save/restore the context from kernel space, but that is really >> > taking a toll on CPU time. It is much better to have userspace provide a >> > context buffer to get the GPU in the expected state, as you then only >> > need to splice this into the execution stream to restore the context >> > instead of pushing it with the CPU. Reading back the context on every >> > switch will kill any performance. >> >> And for this you need a own command type? The context is nothing special. Only >> load state commands in the command buffer. You can have an internal >> representation >> of the context in the user space (as libetnaviv does it right now )and >> work with it. >> Then if you want to submit some render calls etc you can look if the >> state is dirty and submit >> the whole or the changes values. So I am not sure if there is a need >> for a context >> buffer type as it is nothing special. > > How would the userspace know if another process / a GPU hang / a power > management event has dirtied the state of the GPU? It is only the kernel > who knows if the state of the GPU has changed since the last submit of > this process. > Okay got it. > In the common case when nothing has disturbed the context we don't want > to insert the context buffer, as we really want minimal state updates in > that case. We need a way to tell the kernel which command buffer is the > context buffer, so the kernel only splices this buffer into the stream > if the context is dirty. So the context buffer holds the full GPU context and the kernel does the partial update of the current hardware context. This makes the user space a lot simpler as we can send the whole context and do not need take care of partial updates. I like the idea. greets -- Christian Gmeiner, MSc https://soundcloud.com/christian-gmeiner _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel