aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-06-10 06:23:33 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-06-16 13:53:09 -0400
commit1ce826d436f33c8fc0cf8b51d213b496ea73e0a6 (patch)
tree9abd31ba2f1739f60e40ddbca8a0850195b75591 /drivers/gpu/drm/i915
parent6254b2042c794a8c2e14dc49b575a0708c823f88 (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.c161
-rw-r--r--drivers/gpu/drm/i915/intel_renderstate.h2
-rw-r--r--drivers/gpu/drm/i915/intel_renderstate_gen6.c1
-rw-r--r--drivers/gpu/drm/i915/intel_renderstate_gen7.c1
-rw-r--r--drivers/gpu/drm/i915/intel_renderstate_gen8.c1
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
31struct i915_render_state { 31struct 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
39static 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;
72unpin:
73 i915_gem_object_ggtt_unpin(so->obj);
74free_gem:
75 drm_gem_object_unreference(&so->obj->base);
76free:
77 kfree(so);
78 return ERR_PTR(ret);
79}
80
81static 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
89static const struct intel_renderstate_rodata * 38static const struct intel_renderstate_rodata *
90render_state_get_rodata(struct drm_device *dev, const int gen) 39render_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
104static int render_state_setup(const int gen, 53static 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
76free_gem:
77 drm_gem_object_unreference(&so->obj->base);
78 return ret;
79}
80
81static 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
130static 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
162int i915_gem_render_state_init(struct intel_engine_cs *ring) 136int 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 */
195out: 166out:
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
29struct intel_renderstate_rodata { 29struct 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
11static const u32 gen6_null_state_batch[] = { 12static 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
10static const u32 gen7_null_state_batch[] = { 11static 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
10static const u32 gen8_null_state_batch[] = { 11static const u32 gen8_null_state_batch[] = {