All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mika Kuoppala <mika.kuoppala@linux.intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: ben@bwidawsk.net, miku@iki.fi
Subject: [PATCH 2/3] drm/i915: add render state initialization
Date: Tue, 22 Apr 2014 20:19:43 +0300	[thread overview]
Message-ID: <1398187184-14919-3-git-send-email-mika.kuoppala@intel.com> (raw)
In-Reply-To: <1398187184-14919-1-git-send-email-mika.kuoppala@intel.com>

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 <mika.kuoppala@intel.com>
---
 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 ++
 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) += i915_debugfs.o
 # GEM code
 i915-y += 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/i915/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 == RCS && to->is_initialized == false) {
+
+			ret = i915_gem_init_render_state(ring);
+			if (ret)
+				DRM_ERROR("init render state: %d\n", ret);
+		}
 	}
 
 	to->is_initialized = true;
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/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 © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * 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, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Mika Kuoppala <mika.kuoppala@intel.com>
+ *
+ */
+
+#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 = kzalloc(sizeof(*so), GFP_KERNEL);
+	if (!so)
+		return ERR_PTR(-ENOMEM);
+
+	so->size = ALIGN(size, 4096);
+
+	so->obj = i915_gem_alloc_object(dev, so->size);
+	if (so->obj == NULL) {
+		ret = -ENOMEM;
+		goto free;
+	}
+
+	ret = i915_gem_obj_ggtt_pin(so->obj, 4096, 0);
+	if (ret)
+		goto free_gem;
+
+	so->batch = i915_gem_vmap_obj(so->obj);
+	if (!so->batch) {
+		ret = -ENOMEM;
+		goto unpin;
+	}
+
+	so->ggtt_offset = 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 = i915_gem_obj_ggtt_offset(so->obj);
+	const unsigned int num_relocs = source->reloc_items;
+	int reloc_index = 0;
+	u32 *d = (uint32_t *)so->batch;
+	unsigned int i = 0;
+
+	if (source->batch_items * sizeof(*source->batch) > so->size)
+		return -EINVAL;
+
+	while (i < source->batch_items) {
+		u32 s = source->batch[i];
+
+		if (reloc_index < num_relocs &&
+		    i * 4  == source->reloc[reloc_index]) {
+
+			s += goffset & 0xffffffff;
+
+			/* We keep batch offsets max 32bit */
+			if (source->reloc_64bit) {
+				if (i + 1 >= source->batch_items ||
+				    source->batch[i + 1] != 0)
+					return -EINVAL;
+
+				d[i] = s;
+				i++;
+				s = (goffset & 0xffffffff00000000ull) >> 32;
+			}
+
+			reloc_index++;
+		}
+
+		d[i] = s;
+		i++;
+	}
+
+	if (num_relocs != reloc_index) {
+		DRM_ERROR("not all relocs resolved, %d out of %d\n",
+			  reloc_index, num_relocs);
+		return -EINVAL;
+	}
+
+	so->len = 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 = gen ## _g ## _null_state_batch;		\
+		_d.batch_items = sizeof(gen ##_g ## _null_state_batch) / 4; \
+		_d.reloc = gen ## _g ## _null_state_relocs;		\
+		_d.reloc_items = sizeof(gen ## _g ## _null_state_relocs) / 4; \
+		_d.reloc_64bit = _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 = INTEL_INFO(ring->dev)->gen;
+	struct i915_render_state *so;
+	u32 seqno;
+	int ret;
+
+	if (gen < 6)
+		return 0;
+
+	so = render_state_alloc(ring->dev, BATCH_MAX_SIZE);
+	if (IS_ERR(so))
+		return PTR_ERR(so);
+
+	ret = render_state_get(so, gen);
+	if (ret)
+		goto out;
+
+	ret = ring->dispatch_execbuffer(ring,
+					i915_gem_obj_ggtt_offset(so->obj),
+					so->len,
+					I915_DISPATCH_SECURE);
+	if (ret)
+		goto out;
+
+	ret = intel_ring_flush_all_caches(ring);
+	if (ret)
+		goto out;
+
+	ret = i915_add_request(ring, &seqno);
+	if (ret)
+		goto out;
+
+	ret = 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[] = {
+};
+
+static const uint32_t gen6_null_state_batch[] = {
+	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[] = {
+};
+
+static const uint32_t gen7_null_state_batch[] = {
+	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[] = {
+};
+
+static const uint32_t gen8_null_state_batch[] = {
+	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

  parent reply	other threads:[~2014-04-22 17:20 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-22 17:19 [RFC 0/3] render state initialization (bdw rc6) Mika Kuoppala
2014-04-22 17:19 ` [PATCH 1/3] drm/i915: export vmap_batch from command parser Mika Kuoppala
2014-04-22 17:19 ` Mika Kuoppala [this message]
2014-04-22 20:26   ` [PATCH 2/3] drm/i915: add render state initialization Daniel Vetter
2014-05-06  1:20   ` Ben Widawsky
2014-05-06 13:33     ` Mika Kuoppala
2014-04-22 17:19 ` [PATCH 3/3] drm/i915: add null render states for gen6, gen7 and gen8 Mika Kuoppala
2014-05-02 20:43   ` Damien Lespiau
2014-05-02 22:09     ` Damien Lespiau
2014-04-22 20:51 ` [RFC 0/3] render state initialization (bdw rc6) Chris Wilson
2014-04-23 18:04   ` Ben Widawsky
2014-04-24 18:51 ` Kristen Carlson Accardi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1398187184-14919-3-git-send-email-mika.kuoppala@intel.com \
    --to=mika.kuoppala@linux.intel.com \
    --cc=ben@bwidawsk.net \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=miku@iki.fi \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.