aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark2013-12-21 11:11:40 -0600
committerRob Clark2014-01-07 10:33:54 -0600
commit9fa22a845bb40f602eaf073ac84b4af8384eaf3b (patch)
tree3fc948539c15e569f6d022a78b40ee12727c807b /freedreno/msm/msm_ringbuffer.c
parentb6caecfa904de0b4e35b93ed1212ae0089078b6d (diff)
downloadexternal-libdrm-9fa22a845bb40f602eaf073ac84b4af8384eaf3b.tar.gz
external-libdrm-9fa22a845bb40f602eaf073ac84b4af8384eaf3b.tar.xz
external-libdrm-9fa22a845bb40f602eaf073ac84b4af8384eaf3b.zip
freedreno: allow IB to different ringbuffer
Allow IB to different ringbuffer in addition to just different part of same ringbuffer. In particular, we need to add bo's to the parent (ie. one passed to flush) bo table, since the bo table applies to all the cmd buffers in submit ioctl. Signed-off-by: Rob Clark <robclark@freedesktop.org>
Diffstat (limited to 'freedreno/msm/msm_ringbuffer.c')
-rw-r--r--freedreno/msm/msm_ringbuffer.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c
index fc5193ae..f3e951f9 100644
--- a/freedreno/msm/msm_ringbuffer.c
+++ b/freedreno/msm/msm_ringbuffer.c
@@ -44,6 +44,8 @@ struct msm_ringbuffer {
44 /* cmd's table: */ 44 /* cmd's table: */
45 struct drm_msm_gem_submit_cmd *cmds; 45 struct drm_msm_gem_submit_cmd *cmds;
46 uint32_t nr_cmds, max_cmds; 46 uint32_t nr_cmds, max_cmds;
47 struct fd_ringbuffer **rings;
48 uint32_t nr_rings, max_rings;
47 49
48 /* reloc's table: */ 50 /* reloc's table: */
49 struct drm_msm_gem_submit_reloc *relocs; 51 struct drm_msm_gem_submit_reloc *relocs;
@@ -100,13 +102,21 @@ static uint32_t bo2idx(struct fd_ringbuffer *ring, struct fd_bo *bo, uint32_t fl
100 return idx; 102 return idx;
101} 103}
102 104
105static int check_cmd_bo(struct fd_ringbuffer *ring,
106 struct drm_msm_gem_submit_cmd *cmd, struct fd_bo *bo)
107{
108 struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
109 return msm_ring->bos[cmd->submit_idx].handle == bo->handle;
110}
111
103static uint32_t offset_bytes(void *end, void *start) 112static uint32_t offset_bytes(void *end, void *start)
104{ 113{
105 return ((char *)end) - ((char *)start); 114 return ((char *)end) - ((char *)start);
106} 115}
107 116
108static struct drm_msm_gem_submit_cmd * get_cmd(struct fd_ringbuffer *ring, 117static struct drm_msm_gem_submit_cmd * get_cmd(struct fd_ringbuffer *ring,
109 struct fd_bo *ring_bo, uint32_t submit_offset, uint32_t size, uint32_t type) 118 struct fd_ringbuffer *target_ring, struct fd_bo *target_bo,
119 uint32_t submit_offset, uint32_t size, uint32_t type)
110{ 120{
111 struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); 121 struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
112 struct drm_msm_gem_submit_cmd *cmd = NULL; 122 struct drm_msm_gem_submit_cmd *cmd = NULL;
@@ -117,7 +127,8 @@ static struct drm_msm_gem_submit_cmd * get_cmd(struct fd_ringbuffer *ring,
117 cmd = &msm_ring->cmds[i]; 127 cmd = &msm_ring->cmds[i];
118 if ((cmd->submit_offset == submit_offset) && 128 if ((cmd->submit_offset == submit_offset) &&
119 (cmd->size == size) && 129 (cmd->size == size) &&
120 (cmd->type == type)) 130 (cmd->type == type) &&
131 check_cmd_bo(ring, cmd, target_bo))
121 break; 132 break;
122 cmd = NULL; 133 cmd = NULL;
123 } 134 }
@@ -125,9 +136,11 @@ static struct drm_msm_gem_submit_cmd * get_cmd(struct fd_ringbuffer *ring,
125 /* create cmd buf if not: */ 136 /* create cmd buf if not: */
126 if (!cmd) { 137 if (!cmd) {
127 uint32_t idx = APPEND(msm_ring, cmds); 138 uint32_t idx = APPEND(msm_ring, cmds);
139 APPEND(msm_ring, rings);
140 msm_ring->rings[idx] = target_ring;
128 cmd = &msm_ring->cmds[idx]; 141 cmd = &msm_ring->cmds[idx];
129 cmd->type = type; 142 cmd->type = type;
130 cmd->submit_idx = bo2idx(ring, ring_bo, FD_RELOC_READ); 143 cmd->submit_idx = bo2idx(ring, target_bo, FD_RELOC_READ);
131 cmd->submit_offset = submit_offset; 144 cmd->submit_offset = submit_offset;
132 cmd->size = size; 145 cmd->size = size;
133 } 146 }
@@ -170,7 +183,7 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
170 submit_offset = offset_bytes(last_start, ring->start); 183 submit_offset = offset_bytes(last_start, ring->start);
171 size = offset_bytes(ring->cur, last_start); 184 size = offset_bytes(ring->cur, last_start);
172 185
173 get_cmd(ring, ring_bo, submit_offset, size, MSM_SUBMIT_CMD_BUF); 186 get_cmd(ring, ring, ring_bo, submit_offset, size, MSM_SUBMIT_CMD_BUF);
174 187
175 /* needs to be after get_cmd() as that could create bos/cmds table: */ 188 /* needs to be after get_cmd() as that could create bos/cmds table: */
176 req.bos = VOID2U64(msm_ring->bos), 189 req.bos = VOID2U64(msm_ring->bos),
@@ -181,9 +194,10 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
181 /* for each of the cmd's fix up their reloc's: */ 194 /* for each of the cmd's fix up their reloc's: */
182 for (i = 0; i < msm_ring->nr_cmds; i++) { 195 for (i = 0; i < msm_ring->nr_cmds; i++) {
183 struct drm_msm_gem_submit_cmd *cmd = &msm_ring->cmds[i]; 196 struct drm_msm_gem_submit_cmd *cmd = &msm_ring->cmds[i];
184 uint32_t a = find_next_reloc_idx(msm_ring, 0, cmd->submit_offset); 197 struct msm_ringbuffer *target_ring = to_msm_ringbuffer(msm_ring->rings[i]);
185 uint32_t b = find_next_reloc_idx(msm_ring, a, cmd->submit_offset + cmd->size); 198 uint32_t a = find_next_reloc_idx(target_ring, 0, cmd->submit_offset);
186 cmd->relocs = VOID2U64(&msm_ring->relocs[a]); 199 uint32_t b = find_next_reloc_idx(target_ring, a, cmd->submit_offset + cmd->size);
200 cmd->relocs = VOID2U64(&target_ring->relocs[a]);
187 cmd->nr_relocs = (b > a) ? b - a : 0; 201 cmd->nr_relocs = (b > a) ? b - a : 0;
188 } 202 }
189 203
@@ -201,8 +215,13 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
201 fd_bo_del(&msm_bo->base); 215 fd_bo_del(&msm_bo->base);
202 } 216 }
203 217
218 /* for each of the cmd buffers, clear their reloc's: */
219 for (i = 0; i < msm_ring->nr_cmds; i++) {
220 struct msm_ringbuffer *target_ring = to_msm_ringbuffer(msm_ring->rings[i]);
221 target_ring->nr_relocs = 0;
222 }
223
204 msm_ring->nr_cmds = 0; 224 msm_ring->nr_cmds = 0;
205 msm_ring->nr_relocs = 0;
206 msm_ring->nr_bos = 0; 225 msm_ring->nr_bos = 0;
207 226
208 return ret; 227 return ret;
@@ -212,6 +231,7 @@ static void msm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring,
212 const struct fd_reloc *r) 231 const struct fd_reloc *r)
213{ 232{
214 struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring); 233 struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
234 struct fd_ringbuffer *parent = ring->parent ? ring->parent : ring;
215 struct msm_bo *msm_bo = to_msm_bo(r->bo); 235 struct msm_bo *msm_bo = to_msm_bo(r->bo);
216 struct drm_msm_gem_submit_reloc *reloc; 236 struct drm_msm_gem_submit_reloc *reloc;
217 uint32_t idx = APPEND(msm_ring, relocs); 237 uint32_t idx = APPEND(msm_ring, relocs);
@@ -219,7 +239,7 @@ static void msm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring,
219 239
220 reloc = &msm_ring->relocs[idx]; 240 reloc = &msm_ring->relocs[idx];
221 241
222 reloc->reloc_idx = bo2idx(ring, r->bo, r->flags); 242 reloc->reloc_idx = bo2idx(parent, r->bo, r->flags);
223 reloc->reloc_offset = r->offset; 243 reloc->reloc_offset = r->offset;
224 reloc->or = r->or; 244 reloc->or = r->or;
225 reloc->shift = r->shift; 245 reloc->shift = r->shift;
@@ -236,21 +256,19 @@ static void msm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring,
236static void msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring, 256static void msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
237 struct fd_ringmarker *target, struct fd_ringmarker *end) 257 struct fd_ringmarker *target, struct fd_ringmarker *end)
238{ 258{
239 struct fd_bo *ring_bo = to_msm_ringbuffer(target->ring)->ring_bo; 259 struct fd_bo *target_bo = to_msm_ringbuffer(target->ring)->ring_bo;
240 struct drm_msm_gem_submit_cmd *cmd; 260 struct drm_msm_gem_submit_cmd *cmd;
241 uint32_t submit_offset, size; 261 uint32_t submit_offset, size;
242 262
243 submit_offset = offset_bytes(target->cur, target->ring->start); 263 submit_offset = offset_bytes(target->cur, target->ring->start);
244 size = offset_bytes(end->cur, target->cur); 264 size = offset_bytes(end->cur, target->cur);
245 265
246 assert(target->ring == ring); // TODO 266 cmd = get_cmd(ring, target->ring, target_bo, submit_offset, size,
247
248 cmd = get_cmd(ring, ring_bo, submit_offset, size,
249 MSM_SUBMIT_CMD_IB_TARGET_BUF); 267 MSM_SUBMIT_CMD_IB_TARGET_BUF);
250 assert(cmd); 268 assert(cmd);
251 269
252 msm_ringbuffer_emit_reloc(ring, &(struct fd_reloc){ 270 msm_ringbuffer_emit_reloc(ring, &(struct fd_reloc){
253 .bo = ring_bo, 271 .bo = target_bo,
254 .flags = FD_RELOC_READ, 272 .flags = FD_RELOC_READ,
255 .offset = submit_offset, 273 .offset = submit_offset,
256 }); 274 });