Commit 1ce826d4 authored by Chris Wilson's avatar Chris Wilson Committed by Daniel Vetter

drm/i915: Simplify processing of the golden render context state

Rewrite i915_gem_render_state.c for the purposes of clarity and
compactness, in the process we can eliminate some dodgy math that did
not handle 64bit addresses correctly.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Damien Lespiau <damien.lespiau@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Reviewed-by: default avatarMika Kuoppala <mika.kuoppala@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 6254b204
...@@ -28,64 +28,13 @@ ...@@ -28,64 +28,13 @@
#include "i915_drv.h" #include "i915_drv.h"
#include "intel_renderstate.h" #include "intel_renderstate.h"
struct i915_render_state { struct render_state {
const struct intel_renderstate_rodata *rodata;
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
unsigned long ggtt_offset; u64 ggtt_offset;
void *batch; int gen;
u32 size;
u32 len;
}; };
static struct i915_render_state *render_state_alloc(struct drm_device *dev)
{
struct i915_render_state *so;
struct page *page;
int ret;
so = kzalloc(sizeof(*so), GFP_KERNEL);
if (!so)
return ERR_PTR(-ENOMEM);
so->obj = i915_gem_alloc_object(dev, 4096);
if (so->obj == NULL) {
ret = -ENOMEM;
goto free;
}
so->size = 4096;
ret = i915_gem_obj_ggtt_pin(so->obj, 4096, 0);
if (ret)
goto free_gem;
BUG_ON(so->obj->pages->nents != 1);
page = sg_page(so->obj->pages->sgl);
so->batch = kmap(page);
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)
{
kunmap(so->batch);
i915_gem_object_ggtt_unpin(so->obj);
drm_gem_object_unreference(&so->obj->base);
kfree(so);
}
static const struct intel_renderstate_rodata * static const struct intel_renderstate_rodata *
render_state_get_rodata(struct drm_device *dev, const int gen) render_state_get_rodata(struct drm_device *dev, const int gen)
{ {
...@@ -101,98 +50,120 @@ render_state_get_rodata(struct drm_device *dev, const int gen) ...@@ -101,98 +50,120 @@ render_state_get_rodata(struct drm_device *dev, const int gen)
return NULL; return NULL;
} }
static int render_state_setup(const int gen, static int render_state_init(struct render_state *so, struct drm_device *dev)
const struct intel_renderstate_rodata *rodata,
struct i915_render_state *so)
{ {
const u64 goffset = i915_gem_obj_ggtt_offset(so->obj);
u32 reloc_index = 0;
u32 * const d = so->batch;
unsigned int i = 0;
int ret; int ret;
if (!rodata || rodata->batch_items * 4 > so->size) so->gen = INTEL_INFO(dev)->gen;
so->rodata = render_state_get_rodata(dev, so->gen);
if (so->rodata == NULL)
return 0;
if (so->rodata->batch_items * 4 > 4096)
return -EINVAL; return -EINVAL;
so->obj = i915_gem_alloc_object(dev, 4096);
if (so->obj == NULL)
return -ENOMEM;
ret = i915_gem_obj_ggtt_pin(so->obj, 4096, 0);
if (ret)
goto free_gem;
so->ggtt_offset = i915_gem_obj_ggtt_offset(so->obj);
return 0;
free_gem:
drm_gem_object_unreference(&so->obj->base);
return ret;
}
static int render_state_setup(struct render_state *so)
{
const struct intel_renderstate_rodata *rodata = so->rodata;
unsigned int i = 0, reloc_index = 0;
struct page *page;
u32 *d;
int ret;
ret = i915_gem_object_set_to_cpu_domain(so->obj, true); ret = i915_gem_object_set_to_cpu_domain(so->obj, true);
if (ret) if (ret)
return ret; return ret;
page = sg_page(so->obj->pages->sgl);
d = kmap(page);
while (i < rodata->batch_items) { while (i < rodata->batch_items) {
u32 s = rodata->batch[i]; u32 s = rodata->batch[i];
if (reloc_index < rodata->reloc_items && if (i * 4 == rodata->reloc[reloc_index]) {
i * 4 == rodata->reloc[reloc_index]) { u64 r = s + so->ggtt_offset;
s = lower_32_bits(r);
s += goffset & 0xffffffff; if (so->gen >= 8) {
/* We keep batch offsets max 32bit */
if (gen >= 8) {
if (i + 1 >= rodata->batch_items || if (i + 1 >= rodata->batch_items ||
rodata->batch[i + 1] != 0) rodata->batch[i + 1] != 0)
return -EINVAL; return -EINVAL;
d[i] = s; d[i++] = s;
i++; s = upper_32_bits(r);
s = (goffset & 0xffffffff00000000ull) >> 32;
} }
reloc_index++; reloc_index++;
} }
d[i] = s; d[i++] = s;
i++;
} }
kunmap(page);
ret = i915_gem_object_set_to_gtt_domain(so->obj, false); ret = i915_gem_object_set_to_gtt_domain(so->obj, false);
if (ret) if (ret)
return ret; return ret;
if (rodata->reloc_items != reloc_index) { if (rodata->reloc[reloc_index] != -1) {
DRM_ERROR("not all relocs resolved, %d out of %d\n", DRM_ERROR("only %d relocs resolved\n", reloc_index);
reloc_index, rodata->reloc_items);
return -EINVAL; return -EINVAL;
} }
so->len = rodata->batch_items * 4;
return 0; return 0;
} }
static void render_state_fini(struct render_state *so)
{
i915_gem_object_ggtt_unpin(so->obj);
drm_gem_object_unreference(&so->obj->base);
}
int i915_gem_render_state_init(struct intel_engine_cs *ring) int i915_gem_render_state_init(struct intel_engine_cs *ring)
{ {
const int gen = INTEL_INFO(ring->dev)->gen; struct render_state so;
struct i915_render_state *so;
const struct intel_renderstate_rodata *rodata;
int ret; int ret;
if (WARN_ON(ring->id != RCS)) if (WARN_ON(ring->id != RCS))
return -ENOENT; return -ENOENT;
rodata = render_state_get_rodata(ring->dev, gen); ret = render_state_init(&so, ring->dev);
if (rodata == NULL) if (ret)
return 0; return ret;
so = render_state_alloc(ring->dev); if (so.rodata == NULL)
if (IS_ERR(so)) return 0;
return PTR_ERR(so);
ret = render_state_setup(gen, rodata, so); ret = render_state_setup(&so);
if (ret) if (ret)
goto out; goto out;
ret = ring->dispatch_execbuffer(ring, ret = ring->dispatch_execbuffer(ring,
i915_gem_obj_ggtt_offset(so->obj), so.ggtt_offset,
so->len, so.rodata->batch_items * 4,
I915_DISPATCH_SECURE); I915_DISPATCH_SECURE);
if (ret) if (ret)
goto out; goto out;
i915_vma_move_to_active(i915_gem_obj_to_ggtt(so->obj), ring); i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring);
ret = __i915_add_request(ring, NULL, so->obj, NULL); ret = __i915_add_request(ring, NULL, so.obj, NULL);
/* __i915_add_request moves object to inactive if it fails */ /* __i915_add_request moves object to inactive if it fails */
out: out:
render_state_free(so); render_state_fini(&so);
return ret; return ret;
} }
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
struct intel_renderstate_rodata { struct intel_renderstate_rodata {
const u32 *reloc; const u32 *reloc;
const u32 reloc_items;
const u32 *batch; const u32 *batch;
const u32 batch_items; const u32 batch_items;
}; };
...@@ -40,7 +39,6 @@ extern const struct intel_renderstate_rodata gen8_null_state; ...@@ -40,7 +39,6 @@ extern const struct intel_renderstate_rodata gen8_null_state;
#define RO_RENDERSTATE(_g) \ #define RO_RENDERSTATE(_g) \
const struct intel_renderstate_rodata gen ## _g ## _null_state = { \ const struct intel_renderstate_rodata gen ## _g ## _null_state = { \
.reloc = gen ## _g ## _null_state_relocs, \ .reloc = gen ## _g ## _null_state_relocs, \
.reloc_items = sizeof(gen ## _g ## _null_state_relocs)/4, \
.batch = gen ## _g ## _null_state_batch, \ .batch = gen ## _g ## _null_state_batch, \
.batch_items = sizeof(gen ## _g ## _null_state_batch)/4, \ .batch_items = sizeof(gen ## _g ## _null_state_batch)/4, \
} }
......
...@@ -6,6 +6,7 @@ static const u32 gen6_null_state_relocs[] = { ...@@ -6,6 +6,7 @@ static const u32 gen6_null_state_relocs[] = {
0x0000002c, 0x0000002c,
0x000001e0, 0x000001e0,
0x000001e4, 0x000001e4,
-1,
}; };
static const u32 gen6_null_state_batch[] = { static const u32 gen6_null_state_batch[] = {
......
...@@ -5,6 +5,7 @@ static const u32 gen7_null_state_relocs[] = { ...@@ -5,6 +5,7 @@ static const u32 gen7_null_state_relocs[] = {
0x00000010, 0x00000010,
0x00000018, 0x00000018,
0x000001ec, 0x000001ec,
-1,
}; };
static const u32 gen7_null_state_batch[] = { static const u32 gen7_null_state_batch[] = {
......
...@@ -5,6 +5,7 @@ static const u32 gen8_null_state_relocs[] = { ...@@ -5,6 +5,7 @@ static const u32 gen8_null_state_relocs[] = {
0x00000050, 0x00000050,
0x00000060, 0x00000060,
0x000003ec, 0x000003ec,
-1,
}; };
static const u32 gen8_null_state_batch[] = { static const u32 gen8_null_state_batch[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment