From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Vetter Subject: Re: [PATCH 2/3] drm/i915: add render state initialization Date: Tue, 22 Apr 2014 22:26:26 +0200 Message-ID: <20140422202626.GL10722@phenom.ffwll.local> References: <1398187184-14919-1-git-send-email-mika.kuoppala@intel.com> <1398187184-14919-3-git-send-email-mika.kuoppala@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Return-path: Received: from mail-ee0-f42.google.com (mail-ee0-f42.google.com [74.125.83.42]) by gabe.freedesktop.org (Postfix) with ESMTP id 3B0E56E94E for ; Tue, 22 Apr 2014 13:26:31 -0700 (PDT) Received: by mail-ee0-f42.google.com with SMTP id d17so98285eek.1 for ; Tue, 22 Apr 2014 13:26:30 -0700 (PDT) Content-Disposition: inline In-Reply-To: <1398187184-14919-3-git-send-email-mika.kuoppala@intel.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: Mika Kuoppala Cc: intel-gfx@lists.freedesktop.org, miku@iki.fi, ben@bwidawsk.net List-Id: intel-gfx@lists.freedesktop.org On Tue, Apr 22, 2014 at 08:19:43PM +0300, Mika Kuoppala wrote: > HW guys say that it is not a cool idea to let device > go into rc6 without proper 3d pipeline state. > = > For each new uninitialized context, generate a > valid null render state to be run on context > creation. > = > This patch introduces a skeleton with emty states. > = > Signed-off-by: Mika Kuoppala > --- > drivers/gpu/drm/i915/Makefile | 1 + > drivers/gpu/drm/i915/i915_drv.h | 2 + > drivers/gpu/drm/i915/i915_gem_context.c | 7 + > drivers/gpu/drm/i915/i915_gem_render_state.c | 222 +++++++++++++++++++= ++++++ > drivers/gpu/drm/i915/intel_renderstate_gen6.h | 11 ++ > drivers/gpu/drm/i915/intel_renderstate_gen7.h | 11 ++ > drivers/gpu/drm/i915/intel_renderstate_gen8.h | 11 ++ Imo static const arrays in headers look ugly ... I prefer we just add normal C files with forward declarations in i915_gem_render_state.c. In the i915/Makefile you could add a new section for all these golden renderstate files. I know this is a bikeshed, but ;-) -Daniel > 7 files changed, 265 insertions(+) > create mode 100644 drivers/gpu/drm/i915/i915_gem_render_state.c > create mode 100644 drivers/gpu/drm/i915/intel_renderstate_gen6.h > create mode 100644 drivers/gpu/drm/i915/intel_renderstate_gen7.h > create mode 100644 drivers/gpu/drm/i915/intel_renderstate_gen8.h > = > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > index b1445b7..b5d4029 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -18,6 +18,7 @@ i915-$(CONFIG_DEBUG_FS) +=3D i915_debugfs.o > # GEM code > i915-y +=3D i915_cmd_parser.o \ > i915_gem_context.o \ > + i915_gem_render_state.o \ > i915_gem_debug.o \ > i915_gem_dmabuf.o \ > i915_gem_evict.o \ > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_= drv.h > index 43b022c..f6ae2ee 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -2330,6 +2330,8 @@ int i915_gem_context_create_ioctl(struct drm_device= *dev, void *data, > int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data, > struct drm_file *file); > = > +/* i915_gem_render_state.c */ > +int i915_gem_init_render_state(struct intel_ring_buffer *ring); > /* i915_gem_evict.c */ > int __must_check i915_gem_evict_something(struct drm_device *dev, > struct i915_address_space *vm, > diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i9= 15/i915_gem_context.c > index 30b355a..d648d4d 100644 > --- a/drivers/gpu/drm/i915/i915_gem_context.c > +++ b/drivers/gpu/drm/i915/i915_gem_context.c > @@ -746,6 +746,13 @@ static int do_switch(struct intel_ring_buffer *ring, > /* obj is kept alive until the next request by its active ref */ > i915_gem_object_ggtt_unpin(from->obj); > i915_gem_context_unreference(from); > + } else { > + if (ring->id =3D=3D RCS && to->is_initialized =3D=3D false) { > + > + ret =3D i915_gem_init_render_state(ring); > + if (ret) > + DRM_ERROR("init render state: %d\n", ret); > + } > } > = > to->is_initialized =3D true; > diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/d= rm/i915/i915_gem_render_state.c > new file mode 100644 > index 0000000..409f99b > --- /dev/null > +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c > @@ -0,0 +1,222 @@ > +/* > + * Copyright =A9 2014 Intel Corporation > + * > + * Permission is hereby granted, free of charge, to any person obtaining= a > + * copy of this software and associated documentation files (the "Softwa= re"), > + * to deal in the Software without restriction, including without limita= tion > + * the rights to use, copy, modify, merge, publish, distribute, sublicen= se, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice (including the = next > + * paragraph) shall be included in all copies or substantial portions of= the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRE= SS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILI= TY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SH= ALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR = OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISI= NG > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER D= EALINGS > + * IN THE SOFTWARE. > + * > + * Authors: > + * Mika Kuoppala > + * > + */ > + > +#include "i915_drv.h" > + > +#include "intel_renderstate_gen6.h" > +#include "intel_renderstate_gen7.h" > +#include "intel_renderstate_gen8.h" > + > +#define BATCH_MAX_SIZE 4096 > + > +struct i915_render_state { > + struct drm_i915_gem_object *obj; > + unsigned long ggtt_offset; > + void *batch; > + u32 size; > + u32 len; > +}; > + > +static struct i915_render_state * > +render_state_alloc(struct drm_device *dev, unsigned int size) > +{ > + struct i915_render_state *so; > + int ret; > + > + so =3D kzalloc(sizeof(*so), GFP_KERNEL); > + if (!so) > + return ERR_PTR(-ENOMEM); > + > + so->size =3D ALIGN(size, 4096); > + > + so->obj =3D i915_gem_alloc_object(dev, so->size); > + if (so->obj =3D=3D NULL) { > + ret =3D -ENOMEM; > + goto free; > + } > + > + ret =3D i915_gem_obj_ggtt_pin(so->obj, 4096, 0); > + if (ret) > + goto free_gem; > + > + so->batch =3D i915_gem_vmap_obj(so->obj); > + if (!so->batch) { > + ret =3D -ENOMEM; > + goto unpin; > + } > + > + so->ggtt_offset =3D i915_gem_obj_ggtt_offset(so->obj); > + > + return so; > +unpin: > + i915_gem_object_ggtt_unpin(so->obj); > +free_gem: > + drm_gem_object_unreference(&so->obj->base); > +free: > + kfree(so); > + return ERR_PTR(ret); > +} > + > +static void render_state_free(struct i915_render_state *so) > +{ > + vunmap(so->batch); > + i915_gem_object_ggtt_unpin(so->obj); > + drm_gem_object_unreference(&so->obj->base); > + kfree(so); > +} > + > +struct render_state_ro_data { > + const u32 *batch; > + unsigned int batch_items; > + const u32 *reloc; > + unsigned int reloc_items; > + bool reloc_64bit; > +}; > + > +static int render_state_copy(struct i915_render_state *so, > + const struct render_state_ro_data *source) > +{ > + const u64 goffset =3D i915_gem_obj_ggtt_offset(so->obj); > + const unsigned int num_relocs =3D source->reloc_items; > + int reloc_index =3D 0; > + u32 *d =3D (uint32_t *)so->batch; > + unsigned int i =3D 0; > + > + if (source->batch_items * sizeof(*source->batch) > so->size) > + return -EINVAL; > + > + while (i < source->batch_items) { > + u32 s =3D source->batch[i]; > + > + if (reloc_index < num_relocs && > + i * 4 =3D=3D source->reloc[reloc_index]) { > + > + s +=3D goffset & 0xffffffff; > + > + /* We keep batch offsets max 32bit */ > + if (source->reloc_64bit) { > + if (i + 1 >=3D source->batch_items || > + source->batch[i + 1] !=3D 0) > + return -EINVAL; > + > + d[i] =3D s; > + i++; > + s =3D (goffset & 0xffffffff00000000ull) >> 32; > + } > + > + reloc_index++; > + } > + > + d[i] =3D s; > + i++; > + } > + > + if (num_relocs !=3D reloc_index) { > + DRM_ERROR("not all relocs resolved, %d out of %d\n", > + reloc_index, num_relocs); > + return -EINVAL; > + } > + > + so->len =3D source->batch_items * sizeof(*source->batch); > + > + return 0; > +} > + > +static int render_state_get(struct i915_render_state *so, int gen) > +{ > + struct render_state_ro_data ro_data; > + > +#define RS_SETUP(_d, _g, _r) { \ > + if (!sizeof(gen ## _g ## _null_state_batch)) \ > + return -EINVAL; \ > + if (sizeof(gen ## _g ## _null_state_batch) & 0x3) \ > + return -EINVAL; \ > + if (sizeof(gen ## _g ## _null_state_relocs) & 0x3) \ > + return -EINVAL; \ > + _d.batch =3D gen ## _g ## _null_state_batch; \ > + _d.batch_items =3D sizeof(gen ##_g ## _null_state_batch) / 4; \ > + _d.reloc =3D gen ## _g ## _null_state_relocs; \ > + _d.reloc_items =3D sizeof(gen ## _g ## _null_state_relocs) / 4; \ > + _d.reloc_64bit =3D _r; \ > + } > + > + switch (gen) { > + case 6: > + RS_SETUP(ro_data, 6, false); > + break; > + case 7: > + RS_SETUP(ro_data, 7, false); > + break; > + case 8: > + RS_SETUP(ro_data, 8, true); > + break; > + default: > + return -ENOENT; > + } > +#undef RS_SETUP > + > + return render_state_copy(so, &ro_data); > +} > + > +int i915_gem_init_render_state(struct intel_ring_buffer *ring) > +{ > + const int gen =3D INTEL_INFO(ring->dev)->gen; > + struct i915_render_state *so; > + u32 seqno; > + int ret; > + > + if (gen < 6) > + return 0; > + > + so =3D render_state_alloc(ring->dev, BATCH_MAX_SIZE); > + if (IS_ERR(so)) > + return PTR_ERR(so); > + > + ret =3D render_state_get(so, gen); > + if (ret) > + goto out; > + > + ret =3D ring->dispatch_execbuffer(ring, > + i915_gem_obj_ggtt_offset(so->obj), > + so->len, > + I915_DISPATCH_SECURE); > + if (ret) > + goto out; > + > + ret =3D intel_ring_flush_all_caches(ring); > + if (ret) > + goto out; > + > + ret =3D i915_add_request(ring, &seqno); > + if (ret) > + goto out; > + > + ret =3D i915_wait_seqno(ring, seqno); > +out: > + render_state_free(so); > + return ret; > +} > diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen6.h b/drivers/gpu/= drm/i915/intel_renderstate_gen6.h > new file mode 100644 > index 0000000..4809f2f > --- /dev/null > +++ b/drivers/gpu/drm/i915/intel_renderstate_gen6.h > @@ -0,0 +1,11 @@ > +#ifndef __INTEL_RENDERSTATE_GEN6 > +#define __INTEL_RENDERSTATE_GEN6 > + > +static const uint32_t gen6_null_state_relocs[] =3D { > +}; > + > +static const uint32_t gen6_null_state_batch[] =3D { > + MI_BATCH_BUFFER_END, > +}; > + > +#endif /* __INTEL_RENDERSTATE_GEN6 */ > diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen7.h b/drivers/gpu/= drm/i915/intel_renderstate_gen7.h > new file mode 100644 > index 0000000..9b1420b > --- /dev/null > +++ b/drivers/gpu/drm/i915/intel_renderstate_gen7.h > @@ -0,0 +1,11 @@ > +#ifndef __INTEL_RENDERSTATE_GEN7 > +#define __INTEL_RENDERSTATE_GEN7 > + > +static const uint32_t gen7_null_state_relocs[] =3D { > +}; > + > +static const uint32_t gen7_null_state_batch[] =3D { > + MI_BATCH_BUFFER_END, > +}; > + > +#endif /* __INTEL_RENDERSTATE_GEN7 */ > diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen8.h b/drivers/gpu/= drm/i915/intel_renderstate_gen8.h > new file mode 100644 > index 0000000..d349dda > --- /dev/null > +++ b/drivers/gpu/drm/i915/intel_renderstate_gen8.h > @@ -0,0 +1,11 @@ > +#ifndef __INTEL_RENDERSTATE_GEN8 > +#define __INTEL_RENDERSTATE_GEN8 > + > +static const uint32_t gen8_null_state_relocs[] =3D { > +}; > + > +static const uint32_t gen8_null_state_batch[] =3D { > + MI_BATCH_BUFFER_END, > +}; > + > +#endif /* __INTEL_RENDERSTATE_GEN8 */ > -- = > 1.7.9.5 > = > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- = Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch