summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2011-12-24 08:15:40 +0100
committerMarek Olšák <maraeo@gmail.com>2011-12-24 21:28:43 +0100
commit93f4e3cb6c1ca303ee1f5c2a2491a8eff33f2633 (patch)
treec6515ad448336db16756adba362412b025ce8cde
parente6e9becd5016df649d3c19a3e81e85bd63b895b7 (diff)
winsys/radeon: move managing GEM domains back to drivers
This partially reverts commit 363ff844753c46ac9c13866627e096b091ea81f8. It caused severe performance drops in Nexuiz. Reported by Phoronix. Tested by me on r300g and by IRC people on r600g.
-rw-r--r--src/gallium/drivers/r300/r300_context.h3
-rw-r--r--src/gallium/drivers/r300/r300_emit.c20
-rw-r--r--src/gallium/drivers/r300/r300_flush.c4
-rw-r--r--src/gallium/drivers/r300/r300_query.c2
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.c10
-rw-r--r--src/gallium/drivers/r300/r300_texture.c10
-rw-r--r--src/gallium/drivers/r600/r600.h3
-rw-r--r--src/gallium/drivers/r600/r600_buffer.c30
-rw-r--r--src/gallium/drivers/r600/r600_hw_context_priv.h2
-rw-r--r--src/gallium/drivers/r600/r600_texture.c2
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_bo.c35
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_bo.h2
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_cs.c43
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_winsys.h16
14 files changed, 106 insertions, 76 deletions
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index e1c12d9c516..5c0f53e9aad 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -302,6 +302,8 @@ struct r300_surface {
302 struct pb_buffer *buf; 302 struct pb_buffer *buf;
303 struct radeon_winsys_cs_handle *cs_buf; 303 struct radeon_winsys_cs_handle *cs_buf;
304 304
305 enum radeon_bo_domain domain;
306
305 uint32_t offset; /* COLOROFFSET or DEPTHOFFSET. */ 307 uint32_t offset; /* COLOROFFSET or DEPTHOFFSET. */
306 uint32_t pitch; /* COLORPITCH or DEPTHPITCH. */ 308 uint32_t pitch; /* COLORPITCH or DEPTHPITCH. */
307 uint32_t pitch_zmask; /* ZMASK_PITCH */ 309 uint32_t pitch_zmask; /* ZMASK_PITCH */
@@ -385,6 +387,7 @@ struct r300_resource
385 /* Winsys buffer backing this resource. */ 387 /* Winsys buffer backing this resource. */
386 struct pb_buffer *buf; 388 struct pb_buffer *buf;
387 struct radeon_winsys_cs_handle *cs_buf; 389 struct radeon_winsys_cs_handle *cs_buf;
390 enum radeon_bo_domain domain;
388 391
389 /* Constant buffers are in user memory. */ 392 /* Constant buffers are in user memory. */
390 uint8_t *constant_buffer; 393 uint8_t *constant_buffer;
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index d93a5786ff8..3897e990b1c 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -1190,14 +1190,16 @@ validate:
1190 tex = r300_resource(fb->cbufs[i]->texture); 1190 tex = r300_resource(fb->cbufs[i]->texture);
1191 assert(tex && tex->buf && "cbuf is marked, but NULL!"); 1191 assert(tex && tex->buf && "cbuf is marked, but NULL!");
1192 r300->rws->cs_add_reloc(r300->cs, tex->cs_buf, 1192 r300->rws->cs_add_reloc(r300->cs, tex->cs_buf,
1193 RADEON_USAGE_READWRITE); 1193 RADEON_USAGE_READWRITE,
1194 r300_surface(fb->cbufs[i])->domain);
1194 } 1195 }
1195 /* ...depth buffer... */ 1196 /* ...depth buffer... */
1196 if (fb->zsbuf) { 1197 if (fb->zsbuf) {
1197 tex = r300_resource(fb->zsbuf->texture); 1198 tex = r300_resource(fb->zsbuf->texture);
1198 assert(tex && tex->buf && "zsbuf is marked, but NULL!"); 1199 assert(tex && tex->buf && "zsbuf is marked, but NULL!");
1199 r300->rws->cs_add_reloc(r300->cs, tex->cs_buf, 1200 r300->rws->cs_add_reloc(r300->cs, tex->cs_buf,
1200 RADEON_USAGE_READWRITE); 1201 RADEON_USAGE_READWRITE,
1202 r300_surface(fb->zsbuf)->domain);
1201 } 1203 }
1202 } 1204 }
1203 if (r300->textures_state.dirty) { 1205 if (r300->textures_state.dirty) {
@@ -1208,17 +1210,19 @@ validate:
1208 } 1210 }
1209 1211
1210 tex = r300_resource(texstate->sampler_views[i]->base.texture); 1212 tex = r300_resource(texstate->sampler_views[i]->base.texture);
1211 r300->rws->cs_add_reloc(r300->cs, tex->cs_buf, RADEON_USAGE_READ); 1213 r300->rws->cs_add_reloc(r300->cs, tex->cs_buf, RADEON_USAGE_READ,
1214 tex->domain);
1212 } 1215 }
1213 } 1216 }
1214 /* ...occlusion query buffer... */ 1217 /* ...occlusion query buffer... */
1215 if (r300->query_current) 1218 if (r300->query_current)
1216 r300->rws->cs_add_reloc(r300->cs, r300->query_current->cs_buf, 1219 r300->rws->cs_add_reloc(r300->cs, r300->query_current->cs_buf,
1217 RADEON_USAGE_WRITE); 1220 RADEON_USAGE_WRITE, RADEON_DOMAIN_GTT);
1218 /* ...vertex buffer for SWTCL path... */ 1221 /* ...vertex buffer for SWTCL path... */
1219 if (r300->vbo) 1222 if (r300->vbo)
1220 r300->rws->cs_add_reloc(r300->cs, r300_resource(r300->vbo)->cs_buf, 1223 r300->rws->cs_add_reloc(r300->cs, r300_resource(r300->vbo)->cs_buf,
1221 RADEON_USAGE_READ); 1224 RADEON_USAGE_READ,
1225 r300_resource(r300->vbo)->domain);
1222 /* ...vertex buffers for HWTCL path... */ 1226 /* ...vertex buffers for HWTCL path... */
1223 if (do_validate_vertex_buffers && r300->vertex_arrays_dirty) { 1227 if (do_validate_vertex_buffers && r300->vertex_arrays_dirty) {
1224 struct pipe_vertex_buffer *vbuf = r300->vbuf_mgr->real_vertex_buffer; 1228 struct pipe_vertex_buffer *vbuf = r300->vbuf_mgr->real_vertex_buffer;
@@ -1231,13 +1235,15 @@ validate:
1231 continue; 1235 continue;
1232 1236
1233 r300->rws->cs_add_reloc(r300->cs, r300_resource(buf)->cs_buf, 1237 r300->rws->cs_add_reloc(r300->cs, r300_resource(buf)->cs_buf,
1234 RADEON_USAGE_READ); 1238 RADEON_USAGE_READ,
1239 r300_resource(buf)->domain);
1235 } 1240 }
1236 } 1241 }
1237 /* ...and index buffer for HWTCL path. */ 1242 /* ...and index buffer for HWTCL path. */
1238 if (index_buffer) 1243 if (index_buffer)
1239 r300->rws->cs_add_reloc(r300->cs, r300_resource(index_buffer)->cs_buf, 1244 r300->rws->cs_add_reloc(r300->cs, r300_resource(index_buffer)->cs_buf,
1240 RADEON_USAGE_READ); 1245 RADEON_USAGE_READ,
1246 r300_resource(index_buffer)->domain);
1241 1247
1242 /* Now do the validation (flush is called inside cs_validate on failure). */ 1248 /* Now do the validation (flush is called inside cs_validate on failure). */
1243 if (!r300->rws->cs_validate(r300->cs)) { 1249 if (!r300->rws->cs_validate(r300->cs)) {
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index 9459a95cd73..f8546443692 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -80,11 +80,11 @@ void r300_flush(struct pipe_context *pipe,
80 /* Create a fence, which is a dummy BO. */ 80 /* Create a fence, which is a dummy BO. */
81 *rfence = r300->rws->buffer_create(r300->rws, 1, 1, 81 *rfence = r300->rws->buffer_create(r300->rws, 1, 1,
82 PIPE_BIND_CUSTOM, 82 PIPE_BIND_CUSTOM,
83 PIPE_USAGE_IMMUTABLE); 83 RADEON_DOMAIN_GTT);
84 /* Add the fence as a dummy relocation. */ 84 /* Add the fence as a dummy relocation. */
85 r300->rws->cs_add_reloc(r300->cs, 85 r300->rws->cs_add_reloc(r300->cs,
86 r300->rws->buffer_get_cs_handle(*rfence), 86 r300->rws->buffer_get_cs_handle(*rfence),
87 RADEON_USAGE_READWRITE); 87 RADEON_USAGE_READWRITE, RADEON_DOMAIN_GTT);
88 } 88 }
89 89
90 if (r300->dirty_hw) { 90 if (r300->dirty_hw) {
diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c
index 8f7de79538d..bcf6d0eb475 100644
--- a/src/gallium/drivers/r300/r300_query.c
+++ b/src/gallium/drivers/r300/r300_query.c
@@ -58,7 +58,7 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe,
58 q->num_pipes = r300screen->info.r300_num_gb_pipes; 58 q->num_pipes = r300screen->info.r300_num_gb_pipes;
59 59
60 q->buf = r300->rws->buffer_create(r300->rws, 4096, 4096, 60 q->buf = r300->rws->buffer_create(r300->rws, 4096, 4096,
61 PIPE_BIND_CUSTOM, PIPE_USAGE_STAGING); 61 PIPE_BIND_CUSTOM, RADEON_DOMAIN_GTT);
62 if (!q->buf) { 62 if (!q->buf) {
63 FREE(q); 63 FREE(q);
64 return NULL; 64 return NULL;
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index a5ec8ef9656..a8392d2dc52 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -187,6 +187,7 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
187 pipe_reference_init(&rbuf->b.b.b.reference, 1); 187 pipe_reference_init(&rbuf->b.b.b.reference, 1);
188 rbuf->b.b.b.screen = screen; 188 rbuf->b.b.b.screen = screen;
189 rbuf->b.user_ptr = NULL; 189 rbuf->b.user_ptr = NULL;
190 rbuf->domain = RADEON_DOMAIN_GTT;
190 rbuf->buf = NULL; 191 rbuf->buf = NULL;
191 rbuf->constant_buffer = NULL; 192 rbuf->constant_buffer = NULL;
192 193
@@ -196,16 +197,10 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
196 return &rbuf->b.b.b; 197 return &rbuf->b.b.b;
197 } 198 }
198 199
199#ifdef PIPE_ARCH_BIG_ENDIAN
200 /* Force buffer placement to GTT on big endian machines, because
201 * the vertex fetcher can't swap bytes from VRAM. */
202 rbuf->b.b.b.usage = PIPE_USAGE_STAGING;
203#endif
204
205 rbuf->buf = 200 rbuf->buf =
206 r300screen->rws->buffer_create(r300screen->rws, 201 r300screen->rws->buffer_create(r300screen->rws,
207 rbuf->b.b.b.width0, alignment, 202 rbuf->b.b.b.width0, alignment,
208 rbuf->b.b.b.bind, rbuf->b.b.b.usage); 203 rbuf->b.b.b.bind, rbuf->domain);
209 if (!rbuf->buf) { 204 if (!rbuf->buf) {
210 util_slab_free(&r300screen->pool_buffers, rbuf); 205 util_slab_free(&r300screen->pool_buffers, rbuf);
211 return NULL; 206 return NULL;
@@ -239,6 +234,7 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
239 rbuf->b.b.b.flags = 0; 234 rbuf->b.b.b.flags = 0;
240 rbuf->b.b.vtbl = &r300_buffer_vtbl; 235 rbuf->b.b.vtbl = &r300_buffer_vtbl;
241 rbuf->b.user_ptr = ptr; 236 rbuf->b.user_ptr = ptr;
237 rbuf->domain = RADEON_DOMAIN_GTT;
242 rbuf->buf = NULL; 238 rbuf->buf = NULL;
243 rbuf->constant_buffer = NULL; 239 rbuf->constant_buffer = NULL;
244 return &rbuf->b.b.b; 240 return &rbuf->b.b.b;
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 2738f582f69..6fc60fb60d6 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -901,6 +901,9 @@ r300_texture_create_object(struct r300_screen *rscreen,
901 tex->tex.microtile = microtile; 901 tex->tex.microtile = microtile;
902 tex->tex.macrotile[0] = macrotile; 902 tex->tex.macrotile[0] = macrotile;
903 tex->tex.stride_in_bytes_override = stride_in_bytes_override; 903 tex->tex.stride_in_bytes_override = stride_in_bytes_override;
904 tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ?
905 RADEON_DOMAIN_GTT :
906 RADEON_DOMAIN_VRAM | RADEON_DOMAIN_GTT;
904 tex->buf = buffer; 907 tex->buf = buffer;
905 908
906 r300_resource_set_properties(&rscreen->screen, &tex->b.b.b, base); 909 r300_resource_set_properties(&rscreen->screen, &tex->b.b.b, base);
@@ -908,7 +911,7 @@ r300_texture_create_object(struct r300_screen *rscreen,
908 /* Create the backing buffer if needed. */ 911 /* Create the backing buffer if needed. */
909 if (!tex->buf) { 912 if (!tex->buf) {
910 tex->buf = rws->buffer_create(rws, tex->tex.size_in_bytes, 2048, 913 tex->buf = rws->buffer_create(rws, tex->tex.size_in_bytes, 2048,
911 base->bind, base->usage); 914 base->bind, tex->domain);
912 915
913 if (!tex->buf) { 916 if (!tex->buf) {
914 FREE(tex); 917 FREE(tex);
@@ -1019,6 +1022,11 @@ struct pipe_surface* r300_create_surface(struct pipe_context * ctx,
1019 surface->buf = tex->buf; 1022 surface->buf = tex->buf;
1020 surface->cs_buf = tex->cs_buf; 1023 surface->cs_buf = tex->cs_buf;
1021 1024
1025 /* Prefer VRAM if there are multiple domains to choose from. */
1026 surface->domain = tex->domain;
1027 if (surface->domain & RADEON_DOMAIN_VRAM)
1028 surface->domain &= ~RADEON_DOMAIN_GTT;
1029
1022 surface->offset = r300_texture_get_offset(tex, level, 1030 surface->offset = r300_texture_get_offset(tex, level,
1023 surf_tmpl->u.tex.first_layer); 1031 surf_tmpl->u.tex.first_layer);
1024 r300_texture_setup_fb_state(surface); 1032 r300_texture_setup_fb_state(surface);
diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h
index fbd12fbe1b7..4bfb5a980f1 100644
--- a/src/gallium/drivers/r600/r600.h
+++ b/src/gallium/drivers/r600/r600.h
@@ -88,6 +88,9 @@ struct r600_resource {
88 /* Winsys objects. */ 88 /* Winsys objects. */
89 struct pb_buffer *buf; 89 struct pb_buffer *buf;
90 struct radeon_winsys_cs_handle *cs_buf; 90 struct radeon_winsys_cs_handle *cs_buf;
91
92 /* Resource state. */
93 unsigned domains;
91}; 94};
92 95
93/* R600/R700 STATES */ 96/* R600/R700 STATES */
diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c
index f4388867a92..a0386fe4b26 100644
--- a/src/gallium/drivers/r600/r600_buffer.c
+++ b/src/gallium/drivers/r600/r600_buffer.c
@@ -151,12 +151,40 @@ bool r600_init_resource(struct r600_screen *rscreen,
151 unsigned size, unsigned alignment, 151 unsigned size, unsigned alignment,
152 unsigned bind, unsigned usage) 152 unsigned bind, unsigned usage)
153{ 153{
154 res->buf = rscreen->ws->buffer_create(rscreen->ws, size, alignment, bind, usage); 154 uint32_t initial_domain, domains;
155
156 /* Staging resources particpate in transfers and blits only
157 * and are used for uploads and downloads from regular
158 * resources. We generate them internally for some transfers.
159 */
160 if (usage == PIPE_USAGE_STAGING) {
161 domains = RADEON_DOMAIN_GTT;
162 initial_domain = RADEON_DOMAIN_GTT;
163 } else {
164 domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM;
165
166 switch(usage) {
167 case PIPE_USAGE_DYNAMIC:
168 case PIPE_USAGE_STREAM:
169 case PIPE_USAGE_STAGING:
170 initial_domain = RADEON_DOMAIN_GTT;
171 break;
172 case PIPE_USAGE_DEFAULT:
173 case PIPE_USAGE_STATIC:
174 case PIPE_USAGE_IMMUTABLE:
175 default:
176 initial_domain = RADEON_DOMAIN_VRAM;
177 break;
178 }
179 }
180
181 res->buf = rscreen->ws->buffer_create(rscreen->ws, size, alignment, bind, initial_domain);
155 if (!res->buf) { 182 if (!res->buf) {
156 return false; 183 return false;
157 } 184 }
158 185
159 res->cs_buf = rscreen->ws->buffer_get_cs_handle(res->buf); 186 res->cs_buf = rscreen->ws->buffer_get_cs_handle(res->buf);
187 res->domains = domains;
160 return true; 188 return true;
161} 189}
162 190
diff --git a/src/gallium/drivers/r600/r600_hw_context_priv.h b/src/gallium/drivers/r600/r600_hw_context_priv.h
index 206de7e819f..2ad56242059 100644
--- a/src/gallium/drivers/r600/r600_hw_context_priv.h
+++ b/src/gallium/drivers/r600/r600_hw_context_priv.h
@@ -90,7 +90,7 @@ static INLINE unsigned r600_context_bo_reloc(struct r600_context *ctx, struct r6
90 90
91 assert(usage); 91 assert(usage);
92 92
93 reloc_index = ctx->ws->cs_add_reloc(ctx->cs, rbo->cs_buf, usage); 93 reloc_index = ctx->ws->cs_add_reloc(ctx->cs, rbo->cs_buf, usage, rbo->domains);
94 if (reloc_index >= ctx->creloc) 94 if (reloc_index >= ctx->creloc)
95 ctx->creloc = reloc_index+1; 95 ctx->creloc = reloc_index+1;
96 96
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 2d041b04e49..8fe54c8a539 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -469,11 +469,13 @@ r600_texture_create_object(struct pipe_screen *screen,
469 } else if (buf) { 469 } else if (buf) {
470 resource->buf = buf; 470 resource->buf = buf;
471 resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf); 471 resource->cs_buf = rscreen->ws->buffer_get_cs_handle(buf);
472 resource->domains = RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM;
472 } 473 }
473 474
474 if (rtex->stencil) { 475 if (rtex->stencil) {
475 pb_reference(&rtex->stencil->resource.buf, rtex->resource.buf); 476 pb_reference(&rtex->stencil->resource.buf, rtex->resource.buf);
476 rtex->stencil->resource.cs_buf = rtex->resource.cs_buf; 477 rtex->stencil->resource.cs_buf = rtex->resource.cs_buf;
478 rtex->stencil->resource.domains = rtex->resource.domains;
477 } 479 }
478 return rtex; 480 return rtex;
479} 481}
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
index ccf9c4f5dc6..d4746ffc535 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c
@@ -346,11 +346,9 @@ static struct pb_buffer *radeon_bomgr_create_bo(struct pb_manager *_mgr,
346 346
347 memset(&args, 0, sizeof(args)); 347 memset(&args, 0, sizeof(args));
348 348
349 assert(rdesc->initial_domains && rdesc->reloc_domains); 349 assert(rdesc->initial_domains);
350 assert((rdesc->initial_domains & 350 assert((rdesc->initial_domains &
351 ~(RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == 0); 351 ~(RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == 0);
352 assert((rdesc->reloc_domains &
353 ~(RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM)) == 0);
354 352
355 args.size = size; 353 args.size = size;
356 args.alignment = desc->alignment; 354 args.alignment = desc->alignment;
@@ -377,7 +375,6 @@ static struct pb_buffer *radeon_bomgr_create_bo(struct pb_manager *_mgr,
377 bo->mgr = mgr; 375 bo->mgr = mgr;
378 bo->rws = mgr->rws; 376 bo->rws = mgr->rws;
379 bo->handle = args.handle; 377 bo->handle = args.handle;
380 bo->reloc_domains = rdesc->reloc_domains;
381 pipe_mutex_init(bo->map_mutex); 378 pipe_mutex_init(bo->map_mutex);
382 379
383 return &bo->base; 380 return &bo->base;
@@ -526,7 +523,8 @@ static struct pb_buffer *
526radeon_winsys_bo_create(struct radeon_winsys *rws, 523radeon_winsys_bo_create(struct radeon_winsys *rws,
527 unsigned size, 524 unsigned size,
528 unsigned alignment, 525 unsigned alignment,
529 unsigned bind, unsigned usage) 526 unsigned bind,
527 enum radeon_bo_domain domain)
530{ 528{
531 struct radeon_drm_winsys *ws = radeon_drm_winsys(rws); 529 struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
532 struct radeon_bo_desc desc; 530 struct radeon_bo_desc desc;
@@ -536,31 +534,9 @@ radeon_winsys_bo_create(struct radeon_winsys *rws,
536 memset(&desc, 0, sizeof(desc)); 534 memset(&desc, 0, sizeof(desc));
537 desc.base.alignment = alignment; 535 desc.base.alignment = alignment;
538 536
539 /* Determine the memory domains. */
540 switch (usage) {
541 case PIPE_USAGE_STAGING:
542 case PIPE_USAGE_STREAM:
543 case PIPE_USAGE_DYNAMIC:
544 desc.initial_domains = RADEON_GEM_DOMAIN_GTT;
545 desc.reloc_domains = RADEON_GEM_DOMAIN_GTT;
546 break;
547 case PIPE_USAGE_IMMUTABLE:
548 case PIPE_USAGE_STATIC:
549 desc.initial_domains = RADEON_GEM_DOMAIN_VRAM;
550 desc.reloc_domains = RADEON_GEM_DOMAIN_VRAM;
551 break;
552 default:
553 if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER |
554 PIPE_BIND_CONSTANT_BUFFER)) {
555 desc.initial_domains = RADEON_GEM_DOMAIN_GTT;
556 } else {
557 desc.initial_domains = RADEON_GEM_DOMAIN_VRAM;
558 }
559 desc.reloc_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
560 }
561
562 /* Additional criteria for the cache manager. */ 537 /* Additional criteria for the cache manager. */
563 desc.base.usage = desc.initial_domains; 538 desc.base.usage = domain;
539 desc.initial_domains = domain;
564 540
565 /* Assign a buffer manager. */ 541 /* Assign a buffer manager. */
566 if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER | 542 if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER |
@@ -618,7 +594,6 @@ static struct pb_buffer *radeon_winsys_bo_from_handle(struct radeon_winsys *rws,
618 } 594 }
619 bo->handle = open_arg.handle; 595 bo->handle = open_arg.handle;
620 bo->name = whandle->handle; 596 bo->name = whandle->handle;
621 bo->reloc_domains = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM;
622 597
623 /* Initialize it. */ 598 /* Initialize it. */
624 pipe_reference_init(&bo->base.reference, 1); 599 pipe_reference_init(&bo->base.reference, 1);
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.h b/src/gallium/winsys/radeon/drm/radeon_drm_bo.h
index ba71cfb3440..35d25e87eb3 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.h
@@ -42,7 +42,6 @@ struct radeon_bo_desc {
42 struct pb_desc base; 42 struct pb_desc base;
43 43
44 unsigned initial_domains; 44 unsigned initial_domains;
45 unsigned reloc_domains;
46}; 45};
47 46
48struct radeon_bo { 47struct radeon_bo {
@@ -58,7 +57,6 @@ struct radeon_bo {
58 void *ptr; 57 void *ptr;
59 pipe_mutex map_mutex; 58 pipe_mutex map_mutex;
60 59
61 uint32_t reloc_domains;
62 uint32_t handle; 60 uint32_t handle;
63 uint32_t name; 61 uint32_t name;
64 62
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
index 2239059cc53..e6109afd7ea 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
@@ -181,13 +181,14 @@ static struct radeon_winsys_cs *radeon_drm_cs_create(struct radeon_winsys *rws)
181#define OUT_CS(cs, value) (cs)->buf[(cs)->cdw++] = (value) 181#define OUT_CS(cs, value) (cs)->buf[(cs)->cdw++] = (value)
182 182
183static INLINE void update_reloc_domains(struct drm_radeon_cs_reloc *reloc, 183static INLINE void update_reloc_domains(struct drm_radeon_cs_reloc *reloc,
184 enum radeon_bo_usage usage, 184 enum radeon_bo_domain rd,
185 unsigned domains) 185 enum radeon_bo_domain wd,
186 enum radeon_bo_domain *added_domains)
186{ 187{
187 if (usage & RADEON_USAGE_READ) 188 *added_domains = (rd | wd) & ~(reloc->read_domains | reloc->write_domain);
188 reloc->read_domains |= domains; 189
189 if (usage & RADEON_USAGE_WRITE) 190 reloc->read_domains |= rd;
190 reloc->write_domain |= domains; 191 reloc->write_domain |= wd;
191} 192}
192 193
193int radeon_get_reloc(struct radeon_cs_context *csc, struct radeon_bo *bo) 194int radeon_get_reloc(struct radeon_cs_context *csc, struct radeon_bo *bo)
@@ -209,7 +210,7 @@ int radeon_get_reloc(struct radeon_cs_context *csc, struct radeon_bo *bo)
209 if (reloc->handle == bo->handle) { 210 if (reloc->handle == bo->handle) {
210 /* Put this reloc in the hash list. 211 /* Put this reloc in the hash list.
211 * This will prevent additional hash collisions if there are 212 * This will prevent additional hash collisions if there are
212 * several subsequent get_reloc calls of the same buffer. 213 * several consecutive get_reloc calls for the same buffer.
213 * 214 *
214 * Example: Assuming buffers A,B,C collide in the hash list, 215 * Example: Assuming buffers A,B,C collide in the hash list,
215 * the following sequence of relocs: 216 * the following sequence of relocs:
@@ -230,16 +231,19 @@ int radeon_get_reloc(struct radeon_cs_context *csc, struct radeon_bo *bo)
230static unsigned radeon_add_reloc(struct radeon_cs_context *csc, 231static unsigned radeon_add_reloc(struct radeon_cs_context *csc,
231 struct radeon_bo *bo, 232 struct radeon_bo *bo,
232 enum radeon_bo_usage usage, 233 enum radeon_bo_usage usage,
233 unsigned *added_domains) 234 enum radeon_bo_domain domains,
235 enum radeon_bo_domain *added_domains)
234{ 236{
235 struct drm_radeon_cs_reloc *reloc; 237 struct drm_radeon_cs_reloc *reloc;
236 unsigned i; 238 unsigned i;
237 unsigned hash = bo->handle & (sizeof(csc->is_handle_added)-1); 239 unsigned hash = bo->handle & (sizeof(csc->is_handle_added)-1);
240 enum radeon_bo_domain rd = usage & RADEON_USAGE_READ ? domains : 0;
241 enum radeon_bo_domain wd = usage & RADEON_USAGE_WRITE ? domains : 0;
238 242
239 if (csc->is_handle_added[hash]) { 243 if (csc->is_handle_added[hash]) {
240 reloc = csc->relocs_hashlist[hash]; 244 reloc = csc->relocs_hashlist[hash];
241 if (reloc->handle == bo->handle) { 245 if (reloc->handle == bo->handle) {
242 update_reloc_domains(reloc, usage, bo->reloc_domains); 246 update_reloc_domains(reloc, rd, wd, added_domains);
243 return csc->reloc_indices_hashlist[hash]; 247 return csc->reloc_indices_hashlist[hash];
244 } 248 }
245 249
@@ -248,7 +252,7 @@ static unsigned radeon_add_reloc(struct radeon_cs_context *csc,
248 --i; 252 --i;
249 reloc = &csc->relocs[i]; 253 reloc = &csc->relocs[i];
250 if (reloc->handle == bo->handle) { 254 if (reloc->handle == bo->handle) {
251 update_reloc_domains(reloc, usage, bo->reloc_domains); 255 update_reloc_domains(reloc, rd, wd, added_domains);
252 256
253 csc->relocs_hashlist[hash] = reloc; 257 csc->relocs_hashlist[hash] = reloc;
254 csc->reloc_indices_hashlist[hash] = i; 258 csc->reloc_indices_hashlist[hash] = i;
@@ -278,10 +282,8 @@ static unsigned radeon_add_reloc(struct radeon_cs_context *csc,
278 p_atomic_inc(&bo->num_cs_references); 282 p_atomic_inc(&bo->num_cs_references);
279 reloc = &csc->relocs[csc->crelocs]; 283 reloc = &csc->relocs[csc->crelocs];
280 reloc->handle = bo->handle; 284 reloc->handle = bo->handle;
281 if (usage & RADEON_USAGE_READ) 285 reloc->read_domains = rd;
282 reloc->read_domains = bo->reloc_domains; 286 reloc->write_domain = wd;
283 if (usage & RADEON_USAGE_WRITE)
284 reloc->write_domain = bo->reloc_domains;
285 reloc->flags = 0; 287 reloc->flags = 0;
286 288
287 csc->is_handle_added[hash] = TRUE; 289 csc->is_handle_added[hash] = TRUE;
@@ -290,23 +292,24 @@ static unsigned radeon_add_reloc(struct radeon_cs_context *csc,
290 292
291 csc->chunks[1].length_dw += RELOC_DWORDS; 293 csc->chunks[1].length_dw += RELOC_DWORDS;
292 294
293 *added_domains = bo->reloc_domains; 295 *added_domains = rd | wd;
294 return csc->crelocs++; 296 return csc->crelocs++;
295} 297}
296 298
297static unsigned radeon_drm_cs_add_reloc(struct radeon_winsys_cs *rcs, 299static unsigned radeon_drm_cs_add_reloc(struct radeon_winsys_cs *rcs,
298 struct radeon_winsys_cs_handle *buf, 300 struct radeon_winsys_cs_handle *buf,
299 enum radeon_bo_usage usage) 301 enum radeon_bo_usage usage,
302 enum radeon_bo_domain domains)
300{ 303{
301 struct radeon_drm_cs *cs = radeon_drm_cs(rcs); 304 struct radeon_drm_cs *cs = radeon_drm_cs(rcs);
302 struct radeon_bo *bo = (struct radeon_bo*)buf; 305 struct radeon_bo *bo = (struct radeon_bo*)buf;
303 unsigned added_domains = 0; 306 enum radeon_bo_domain added_domains;
304 307
305 unsigned index = radeon_add_reloc(cs->csc, bo, usage, &added_domains); 308 unsigned index = radeon_add_reloc(cs->csc, bo, usage, domains, &added_domains);
306 309
307 if (added_domains & RADEON_GEM_DOMAIN_GTT) 310 if (added_domains & RADEON_DOMAIN_GTT)
308 cs->csc->used_gart += bo->base.size; 311 cs->csc->used_gart += bo->base.size;
309 if (added_domains & RADEON_GEM_DOMAIN_VRAM) 312 if (added_domains & RADEON_DOMAIN_VRAM)
310 cs->csc->used_vram += bo->base.size; 313 cs->csc->used_vram += bo->base.size;
311 314
312 return index; 315 return index;
diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h
index ea335d87113..59c1aad3308 100644
--- a/src/gallium/winsys/radeon/drm/radeon_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
@@ -58,6 +58,11 @@ enum radeon_bo_layout {
58 RADEON_LAYOUT_UNKNOWN 58 RADEON_LAYOUT_UNKNOWN
59}; 59};
60 60
61enum radeon_bo_domain { /* bitfield */
62 RADEON_DOMAIN_GTT = 2,
63 RADEON_DOMAIN_VRAM = 4
64};
65
61enum radeon_bo_usage { /* bitfield */ 66enum radeon_bo_usage { /* bitfield */
62 RADEON_USAGE_READ = 2, 67 RADEON_USAGE_READ = 2,
63 RADEON_USAGE_WRITE = 4, 68 RADEON_USAGE_WRITE = 4,
@@ -137,13 +142,14 @@ struct radeon_winsys {
137 * \param size The size to allocate. 142 * \param size The size to allocate.
138 * \param alignment An alignment of the buffer in memory. 143 * \param alignment An alignment of the buffer in memory.
139 * \param bind A bitmask of the PIPE_BIND_* flags. 144 * \param bind A bitmask of the PIPE_BIND_* flags.
140 * \param usage A bitmask of the PIPE_USAGE_* flags. 145 * \param domain A bitmask of the RADEON_DOMAIN_* flags.
141 * \return The created buffer object. 146 * \return The created buffer object.
142 */ 147 */
143 struct pb_buffer *(*buffer_create)(struct radeon_winsys *ws, 148 struct pb_buffer *(*buffer_create)(struct radeon_winsys *ws,
144 unsigned size, 149 unsigned size,
145 unsigned alignment, 150 unsigned alignment,
146 unsigned bind, unsigned usage); 151 unsigned bind,
152 enum radeon_bo_domain domain);
147 153
148 struct radeon_winsys_cs_handle *(*buffer_get_cs_handle)( 154 struct radeon_winsys_cs_handle *(*buffer_get_cs_handle)(
149 struct pb_buffer *buf); 155 struct pb_buffer *buf);
@@ -271,12 +277,14 @@ struct radeon_winsys {
271 * 277 *
272 * \param cs A command stream to add buffer for validation against. 278 * \param cs A command stream to add buffer for validation against.
273 * \param buf A winsys buffer to validate. 279 * \param buf A winsys buffer to validate.
274 * \param usage Whether the buffer is used for read and/or write. 280 * \param usage Whether the buffer is used for read and/or write.
281 * \param domain Bitmask of the RADEON_DOMAIN_* flags.
275 * \return Relocation index. 282 * \return Relocation index.
276 */ 283 */
277 unsigned (*cs_add_reloc)(struct radeon_winsys_cs *cs, 284 unsigned (*cs_add_reloc)(struct radeon_winsys_cs *cs,
278 struct radeon_winsys_cs_handle *buf, 285 struct radeon_winsys_cs_handle *buf,
279 enum radeon_bo_usage usage); 286 enum radeon_bo_usage usage,
287 enum radeon_bo_domain domain);
280 288
281 /** 289 /**
282 * Return TRUE if there is enough memory in VRAM and GTT for the relocs 290 * Return TRUE if there is enough memory in VRAM and GTT for the relocs