diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2014-06-10 06:23:33 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-06-16 13:53:09 -0400 |
commit | 1ce826d436f33c8fc0cf8b51d213b496ea73e0a6 (patch) | |
tree | 9abd31ba2f1739f60e40ddbca8a0850195b75591 /drivers/gpu/drm/i915 | |
parent | 6254b2042c794a8c2e14dc49b575a0708c823f88 (diff) |
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: Chris 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: Mika Kuoppala <mika.kuoppala@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_render_state.c | 161 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_renderstate.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_renderstate_gen6.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_renderstate_gen7.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_renderstate_gen8.c | 1 |
5 files changed, 69 insertions, 97 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index 3521f998a178..e60be3f552a6 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c | |||
@@ -28,64 +28,13 @@ | |||
28 | #include "i915_drv.h" | 28 | #include "i915_drv.h" |
29 | #include "intel_renderstate.h" | 29 | #include "intel_renderstate.h" |
30 | 30 | ||
31 | struct i915_render_state { | 31 | struct render_state { |
32 | const struct intel_renderstate_rodata *rodata; | ||
32 | struct drm_i915_gem_object *obj; | 33 | struct drm_i915_gem_object *obj; |
33 | unsigned long ggtt_offset; | 34 | u64 ggtt_offset; |
34 | void *batch; | 35 | int gen; |
35 | u32 size; | ||
36 | u32 len; | ||
37 | }; | 36 | }; |
38 | 37 | ||
39 | static struct i915_render_state *render_state_alloc(struct drm_device *dev) | ||
40 | { | ||
41 | struct i915_render_state *so; | ||
42 | struct page *page; | ||
43 | int ret; | ||
44 | |||
45 | so = kzalloc(sizeof(*so), GFP_KERNEL); | ||
46 | if (!so) | ||
47 | return ERR_PTR(-ENOMEM); | ||
48 | |||
49 | so->obj = i915_gem_alloc_object(dev, 4096); | ||
50 | if (so->obj == NULL) { | ||
51 | ret = -ENOMEM; | ||
52 | goto free; | ||
53 | } | ||
54 | so->size = 4096; | ||
55 | |||
56 | ret = i915_gem_obj_ggtt_pin(so->obj, 4096, 0); | ||
57 | if (ret) | ||
58 | goto free_gem; | ||
59 | |||
60 | BUG_ON(so->obj->pages->nents != 1); | ||
61 | page = sg_page(so->obj->pages->sgl); | ||
62 | |||
63 | so->batch = kmap(page); | ||
64 | if (!so->batch) { | ||
65 | ret = -ENOMEM; | ||
66 | goto unpin; | ||
67 | } | ||
68 | |||
69 | so->ggtt_offset = i915_gem_obj_ggtt_offset(so->obj); | ||
70 | |||
71 | return so; | ||
72 | unpin: | ||
73 | i915_gem_object_ggtt_unpin(so->obj); | ||
74 | free_gem: | ||
75 | drm_gem_object_unreference(&so->obj->base); | ||
76 | free: | ||
77 | kfree(so); | ||
78 | return ERR_PTR(ret); | ||
79 | } | ||
80 | |||
81 | static void render_state_free(struct i915_render_state *so) | ||
82 | { | ||
83 | kunmap(so->batch); | ||
84 | i915_gem_object_ggtt_unpin(so->obj); | ||
85 | drm_gem_object_unreference(&so->obj->base); | ||
86 | kfree(so); | ||
87 | } | ||
88 | |||
89 | static const struct intel_renderstate_rodata * | 38 | static const struct intel_renderstate_rodata * |
90 | render_state_get_rodata(struct drm_device *dev, const int gen) | 39 | render_state_get_rodata(struct drm_device *dev, const int gen) |
91 | { | 40 | { |
@@ -101,98 +50,120 @@ render_state_get_rodata(struct drm_device *dev, const int gen) | |||
101 | return NULL; | 50 | return NULL; |
102 | } | 51 | } |
103 | 52 | ||
104 | static int render_state_setup(const int gen, | 53 | static int render_state_init(struct render_state *so, struct drm_device *dev) |
105 | const struct intel_renderstate_rodata *rodata, | ||
106 | struct i915_render_state *so) | ||
107 | { | 54 | { |
108 | const u64 goffset = i915_gem_obj_ggtt_offset(so->obj); | ||
109 | u32 reloc_index = 0; | ||
110 | u32 * const d = so->batch; | ||
111 | unsigned int i = 0; | ||
112 | int ret; | 55 | int ret; |
113 | 56 | ||
114 | if (!rodata || rodata->batch_items * 4 > so->size) | 57 | so->gen = INTEL_INFO(dev)->gen; |
58 | so->rodata = render_state_get_rodata(dev, so->gen); | ||
59 | if (so->rodata == NULL) | ||
60 | return 0; | ||
61 | |||
62 | if (so->rodata->batch_items * 4 > 4096) | ||
115 | return -EINVAL; | 63 | return -EINVAL; |
116 | 64 | ||
65 | so->obj = i915_gem_alloc_object(dev, 4096); | ||
66 | if (so->obj == NULL) | ||
67 | return -ENOMEM; | ||
68 | |||
69 | ret = i915_gem_obj_ggtt_pin(so->obj, 4096, 0); | ||
70 | if (ret) | ||
71 | goto free_gem; | ||
72 | |||
73 | so->ggtt_offset = i915_gem_obj_ggtt_offset(so->obj); | ||
74 | return 0; | ||
75 | |||
76 | free_gem: | ||
77 | drm_gem_object_unreference(&so->obj->base); | ||
78 | return ret; | ||
79 | } | ||
80 | |||
81 | static int render_state_setup(struct render_state *so) | ||
82 | { | ||
83 | const struct intel_renderstate_rodata *rodata = so->rodata; | ||
84 | unsigned int i = 0, reloc_index = 0; | ||
85 | struct page *page; | ||
86 | u32 *d; | ||
87 | int ret; | ||
88 | |||
117 | ret = i915_gem_object_set_to_cpu_domain(so->obj, true); | 89 | ret = i915_gem_object_set_to_cpu_domain(so->obj, true); |
118 | if (ret) | 90 | if (ret) |
119 | return ret; | 91 | return ret; |
120 | 92 | ||
93 | page = sg_page(so->obj->pages->sgl); | ||
94 | d = kmap(page); | ||
95 | |||
121 | while (i < rodata->batch_items) { | 96 | while (i < rodata->batch_items) { |
122 | u32 s = rodata->batch[i]; | 97 | u32 s = rodata->batch[i]; |
123 | 98 | ||
124 | if (reloc_index < rodata->reloc_items && | 99 | if (i * 4 == rodata->reloc[reloc_index]) { |
125 | i * 4 == rodata->reloc[reloc_index]) { | 100 | u64 r = s + so->ggtt_offset; |
126 | 101 | s = lower_32_bits(r); | |
127 | s += goffset & 0xffffffff; | 102 | if (so->gen >= 8) { |
128 | |||
129 | /* We keep batch offsets max 32bit */ | ||
130 | if (gen >= 8) { | ||
131 | if (i + 1 >= rodata->batch_items || | 103 | if (i + 1 >= rodata->batch_items || |
132 | rodata->batch[i + 1] != 0) | 104 | rodata->batch[i + 1] != 0) |
133 | return -EINVAL; | 105 | return -EINVAL; |
134 | 106 | ||
135 | d[i] = s; | 107 | d[i++] = s; |
136 | i++; | 108 | s = upper_32_bits(r); |
137 | s = (goffset & 0xffffffff00000000ull) >> 32; | ||
138 | } | 109 | } |
139 | 110 | ||
140 | reloc_index++; | 111 | reloc_index++; |
141 | } | 112 | } |
142 | 113 | ||
143 | d[i] = s; | 114 | d[i++] = s; |
144 | i++; | ||
145 | } | 115 | } |
116 | kunmap(page); | ||
146 | 117 | ||
147 | ret = i915_gem_object_set_to_gtt_domain(so->obj, false); | 118 | ret = i915_gem_object_set_to_gtt_domain(so->obj, false); |
148 | if (ret) | 119 | if (ret) |
149 | return ret; | 120 | return ret; |
150 | 121 | ||
151 | if (rodata->reloc_items != reloc_index) { | 122 | if (rodata->reloc[reloc_index] != -1) { |
152 | DRM_ERROR("not all relocs resolved, %d out of %d\n", | 123 | DRM_ERROR("only %d relocs resolved\n", reloc_index); |
153 | reloc_index, rodata->reloc_items); | ||
154 | return -EINVAL; | 124 | return -EINVAL; |
155 | } | 125 | } |
156 | 126 | ||
157 | so->len = rodata->batch_items * 4; | ||
158 | |||
159 | return 0; | 127 | return 0; |
160 | } | 128 | } |
161 | 129 | ||
130 | static void render_state_fini(struct render_state *so) | ||
131 | { | ||
132 | i915_gem_object_ggtt_unpin(so->obj); | ||
133 | drm_gem_object_unreference(&so->obj->base); | ||
134 | } | ||
135 | |||
162 | int i915_gem_render_state_init(struct intel_engine_cs *ring) | 136 | int i915_gem_render_state_init(struct intel_engine_cs *ring) |
163 | { | 137 | { |
164 | const int gen = INTEL_INFO(ring->dev)->gen; | 138 | struct render_state so; |
165 | struct i915_render_state *so; | ||
166 | const struct intel_renderstate_rodata *rodata; | ||
167 | int ret; | 139 | int ret; |
168 | 140 | ||
169 | if (WARN_ON(ring->id != RCS)) | 141 | if (WARN_ON(ring->id != RCS)) |
170 | return -ENOENT; | 142 | return -ENOENT; |
171 | 143 | ||
172 | rodata = render_state_get_rodata(ring->dev, gen); | 144 | ret = render_state_init(&so, ring->dev); |
173 | if (rodata == NULL) | 145 | if (ret) |
174 | return 0; | 146 | return ret; |
175 | 147 | ||
176 | so = render_state_alloc(ring->dev); | 148 | if (so.rodata == NULL) |
177 | if (IS_ERR(so)) | 149 | return 0; |
178 | return PTR_ERR(so); | ||
179 | 150 | ||
180 | ret = render_state_setup(gen, rodata, so); | 151 | ret = render_state_setup(&so); |
181 | if (ret) | 152 | if (ret) |
182 | goto out; | 153 | goto out; |
183 | 154 | ||
184 | ret = ring->dispatch_execbuffer(ring, | 155 | ret = ring->dispatch_execbuffer(ring, |
185 | i915_gem_obj_ggtt_offset(so->obj), | 156 | so.ggtt_offset, |
186 | so->len, | 157 | so.rodata->batch_items * 4, |
187 | I915_DISPATCH_SECURE); | 158 | I915_DISPATCH_SECURE); |
188 | if (ret) | 159 | if (ret) |
189 | goto out; | 160 | goto out; |
190 | 161 | ||
191 | i915_vma_move_to_active(i915_gem_obj_to_ggtt(so->obj), ring); | 162 | i915_vma_move_to_active(i915_gem_obj_to_ggtt(so.obj), ring); |
192 | 163 | ||
193 | ret = __i915_add_request(ring, NULL, so->obj, NULL); | 164 | ret = __i915_add_request(ring, NULL, so.obj, NULL); |
194 | /* __i915_add_request moves object to inactive if it fails */ | 165 | /* __i915_add_request moves object to inactive if it fails */ |
195 | out: | 166 | out: |
196 | render_state_free(so); | 167 | render_state_fini(&so); |
197 | return ret; | 168 | return ret; |
198 | } | 169 | } |
diff --git a/drivers/gpu/drm/i915/intel_renderstate.h b/drivers/gpu/drm/i915/intel_renderstate.h index a5e783a9928a..fd4f66231d30 100644 --- a/drivers/gpu/drm/i915/intel_renderstate.h +++ b/drivers/gpu/drm/i915/intel_renderstate.h | |||
@@ -28,7 +28,6 @@ | |||
28 | 28 | ||
29 | struct intel_renderstate_rodata { | 29 | struct intel_renderstate_rodata { |
30 | const u32 *reloc; | 30 | const u32 *reloc; |
31 | const u32 reloc_items; | ||
32 | const u32 *batch; | 31 | const u32 *batch; |
33 | const u32 batch_items; | 32 | const u32 batch_items; |
34 | }; | 33 | }; |
@@ -40,7 +39,6 @@ extern const struct intel_renderstate_rodata gen8_null_state; | |||
40 | #define RO_RENDERSTATE(_g) \ | 39 | #define RO_RENDERSTATE(_g) \ |
41 | const struct intel_renderstate_rodata gen ## _g ## _null_state = { \ | 40 | const struct intel_renderstate_rodata gen ## _g ## _null_state = { \ |
42 | .reloc = gen ## _g ## _null_state_relocs, \ | 41 | .reloc = gen ## _g ## _null_state_relocs, \ |
43 | .reloc_items = sizeof(gen ## _g ## _null_state_relocs)/4, \ | ||
44 | .batch = gen ## _g ## _null_state_batch, \ | 42 | .batch = gen ## _g ## _null_state_batch, \ |
45 | .batch_items = sizeof(gen ## _g ## _null_state_batch)/4, \ | 43 | .batch_items = sizeof(gen ## _g ## _null_state_batch)/4, \ |
46 | } | 44 | } |
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen6.c b/drivers/gpu/drm/i915/intel_renderstate_gen6.c index 740538ad0977..56c1429d8a60 100644 --- a/drivers/gpu/drm/i915/intel_renderstate_gen6.c +++ b/drivers/gpu/drm/i915/intel_renderstate_gen6.c | |||
@@ -6,6 +6,7 @@ static const u32 gen6_null_state_relocs[] = { | |||
6 | 0x0000002c, | 6 | 0x0000002c, |
7 | 0x000001e0, | 7 | 0x000001e0, |
8 | 0x000001e4, | 8 | 0x000001e4, |
9 | -1, | ||
9 | }; | 10 | }; |
10 | 11 | ||
11 | static const u32 gen6_null_state_batch[] = { | 12 | static const u32 gen6_null_state_batch[] = { |
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen7.c b/drivers/gpu/drm/i915/intel_renderstate_gen7.c index 6fa7ff2a1298..419e35a7b0ff 100644 --- a/drivers/gpu/drm/i915/intel_renderstate_gen7.c +++ b/drivers/gpu/drm/i915/intel_renderstate_gen7.c | |||
@@ -5,6 +5,7 @@ static const u32 gen7_null_state_relocs[] = { | |||
5 | 0x00000010, | 5 | 0x00000010, |
6 | 0x00000018, | 6 | 0x00000018, |
7 | 0x000001ec, | 7 | 0x000001ec, |
8 | -1, | ||
8 | }; | 9 | }; |
9 | 10 | ||
10 | static const u32 gen7_null_state_batch[] = { | 11 | static const u32 gen7_null_state_batch[] = { |
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen8.c b/drivers/gpu/drm/i915/intel_renderstate_gen8.c index 5c875615d42a..75ef1b5de45c 100644 --- a/drivers/gpu/drm/i915/intel_renderstate_gen8.c +++ b/drivers/gpu/drm/i915/intel_renderstate_gen8.c | |||
@@ -5,6 +5,7 @@ static const u32 gen8_null_state_relocs[] = { | |||
5 | 0x00000050, | 5 | 0x00000050, |
6 | 0x00000060, | 6 | 0x00000060, |
7 | 0x000003ec, | 7 | 0x000003ec, |
8 | -1, | ||
8 | }; | 9 | }; |
9 | 10 | ||
10 | static const u32 gen8_null_state_batch[] = { | 11 | static const u32 gen8_null_state_batch[] = { |