/* 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);
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;
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;
}
}
/* 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;
}
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;
#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);
}
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,
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;
}
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++;
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;
unsigned size;
unsigned tiling_flags;
unsigned kernel_pitch;
+ unsigned domains;
};