This opens the question of what interface the winsys layer should really have for talking about these concepts. For now I'm using the existing gallium resource usage concept, but there is no reason not use terms closer to what the hardware understands - eg. the domains themselves.tags/snb-magic
| @@ -112,7 +112,8 @@ struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon); | |||
| /* r600_bo.c */ | |||
| struct r600_bo; | |||
| struct r600_bo *r600_bo(struct radeon *radeon, | |||
| unsigned size, unsigned alignment, unsigned usage); | |||
| unsigned size, unsigned alignment, | |||
| unsigned binding, unsigned usage); | |||
| struct r600_bo *r600_bo_handle(struct radeon *radeon, | |||
| unsigned handle, unsigned *array_mode); | |||
| void *r600_bo_map(struct radeon *radeon, struct r600_bo *bo, unsigned usage, void *ctx); | |||
| @@ -86,7 +86,7 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, | |||
| rbuffer->r.base.vtbl = &r600_buffer_vtbl; | |||
| rbuffer->r.size = rbuffer->r.base.b.width0; | |||
| rbuffer->r.domain = r600_domain_from_usage(rbuffer->r.base.b.bind); | |||
| bo = r600_bo((struct radeon*)screen->winsys, rbuffer->r.base.b.width0, alignment, rbuffer->r.base.b.bind); | |||
| bo = r600_bo((struct radeon*)screen->winsys, rbuffer->r.base.b.width0, alignment, rbuffer->r.base.b.bind, rbuffer->r.base.b.usage); | |||
| if (bo == NULL) { | |||
| FREE(rbuffer); | |||
| return NULL; | |||
| @@ -156,8 +156,9 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe, | |||
| r600_bo_reference((struct radeon*)pipe->winsys, &rbuffer->r.bo, NULL); | |||
| rbuffer->num_ranges = 0; | |||
| rbuffer->r.bo = r600_bo((struct radeon*)pipe->winsys, | |||
| rbuffer->r.base.b.width0, 0, | |||
| rbuffer->r.base.b.bind); | |||
| rbuffer->r.base.b.width0, 0, | |||
| rbuffer->r.base.b.bind, | |||
| rbuffer->r.base.b.usage); | |||
| break; | |||
| } | |||
| } | |||
| @@ -218,7 +218,7 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s | |||
| /* copy new shader */ | |||
| if (shader->bo == NULL) { | |||
| shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, 0); | |||
| shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, 0, 0); | |||
| if (shader->bo == NULL) { | |||
| return -ENOMEM; | |||
| } | |||
| @@ -294,7 +294,7 @@ r600_texture_create_object(struct pipe_screen *screen, | |||
| resource->size = rtex->size; | |||
| if (!resource->bo) { | |||
| resource->bo = r600_bo(radeon, rtex->size, 4096, 0); | |||
| resource->bo = r600_bo(radeon, rtex->size, 4096, base->bind, base->usage); | |||
| if (!resource->bo) { | |||
| FREE(rtex); | |||
| return NULL; | |||
| @@ -29,23 +29,37 @@ | |||
| #include "radeon_drm.h" | |||
| #include "r600_priv.h" | |||
| #include "r600d.h" | |||
| #include "radeon_drm.h" | |||
| struct r600_bo *r600_bo(struct radeon *radeon, | |||
| unsigned size, unsigned alignment, unsigned usage) | |||
| unsigned size, unsigned alignment, | |||
| unsigned binding, unsigned usage) | |||
| { | |||
| struct r600_bo *ws_bo = calloc(1, sizeof(struct r600_bo)); | |||
| struct pb_desc desc; | |||
| struct pb_manager *man; | |||
| desc.alignment = alignment; | |||
| desc.usage = usage; | |||
| desc.usage = (PB_USAGE_CPU_READ_WRITE | PB_USAGE_GPU_READ_WRITE); | |||
| ws_bo->size = size; | |||
| if (usage & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) | |||
| if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) | |||
| man = radeon->cman; | |||
| else | |||
| man = radeon->kman; | |||
| /* Staging resources particpate in transfers and blits only | |||
| * and are used for uploads and downloads from regular | |||
| * resources. We generate them internally for some transfers. | |||
| */ | |||
| if (usage == PIPE_USAGE_STAGING) | |||
| ws_bo->domains = RADEON_GEM_DOMAIN_CPU | RADEON_GEM_DOMAIN_GTT; | |||
| else | |||
| ws_bo->domains = (RADEON_GEM_DOMAIN_CPU | | |||
| RADEON_GEM_DOMAIN_GTT | | |||
| RADEON_GEM_DOMAIN_VRAM); | |||
| ws_bo->pb = man->create_buffer(man, size, &desc); | |||
| if (ws_bo->pb == NULL) { | |||
| free(ws_bo); | |||
| @@ -69,6 +83,10 @@ struct r600_bo *r600_bo_handle(struct radeon *radeon, | |||
| } | |||
| bo = radeon_bo_pb_get_bo(ws_bo->pb); | |||
| ws_bo->size = bo->size; | |||
| ws_bo->domains = (RADEON_GEM_DOMAIN_CPU | | |||
| RADEON_GEM_DOMAIN_GTT | | |||
| RADEON_GEM_DOMAIN_VRAM); | |||
| pipe_reference_init(&ws_bo->reference, 1); | |||
| radeon_bo_get_tiling_flags(radeon, bo, &ws_bo->tiling_flags, | |||
| @@ -44,7 +44,7 @@ | |||
| int r600_context_init_fence(struct r600_context *ctx) | |||
| { | |||
| ctx->fence = 1; | |||
| ctx->fence_bo = r600_bo(ctx->radeon, 4096, 0, 0); | |||
| ctx->fence_bo = r600_bo(ctx->radeon, 4096, 0, 0, 0); | |||
| if (ctx->fence_bo == NULL) { | |||
| return -ENOMEM; | |||
| } | |||
| @@ -787,8 +787,8 @@ void r600_context_bo_reloc(struct r600_context *ctx, u32 *pm4, struct r600_bo *r | |||
| bo->reloc = &ctx->reloc[ctx->creloc]; | |||
| bo->reloc_id = ctx->creloc * sizeof(struct r600_reloc) / 4; | |||
| ctx->reloc[ctx->creloc].handle = bo->handle; | |||
| ctx->reloc[ctx->creloc].read_domain = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM; | |||
| ctx->reloc[ctx->creloc].write_domain = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM; | |||
| ctx->reloc[ctx->creloc].read_domain = rbo->domains & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM); | |||
| ctx->reloc[ctx->creloc].write_domain = rbo->domains & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM); | |||
| ctx->reloc[ctx->creloc].flags = 0; | |||
| radeon_bo_reference(ctx->radeon, &ctx->bo[ctx->creloc], bo); | |||
| ctx->creloc++; | |||
| @@ -1306,7 +1306,12 @@ struct r600_query *r600_context_query_create(struct r600_context *ctx, unsigned | |||
| query->type = query_type; | |||
| query->buffer_size = 4096; | |||
| query->buffer = r600_bo(ctx->radeon, query->buffer_size, 1, 0); | |||
| /* As of GL4, query buffers are normally read by the CPU after | |||
| * being written by the gpu, hence staging is probably a good | |||
| * usage pattern. | |||
| */ | |||
| query->buffer = r600_bo(ctx->radeon, query->buffer_size, 1, 0, | |||
| PIPE_USAGE_STAGING); | |||
| if (!query->buffer) { | |||
| free(query); | |||
| return NULL; | |||
| @@ -79,6 +79,7 @@ struct r600_bo { | |||
| unsigned size; | |||
| unsigned tiling_flags; | |||
| unsigned kernel_pitch; | |||
| unsigned domains; | |||
| }; | |||