struct radeon_bo *bo;
+ /* The CS associated with the last buffer_map. */
+ struct radeon_libdrm_cs *cs;
+
boolean flinked;
uint32_t flink;
FREE(buf);
}
+static unsigned get_pb_usage_from_transfer_flags(enum pipe_transfer_usage usage)
+{
+ unsigned res = 0;
+
+ if (usage & PIPE_TRANSFER_READ)
+ res |= PB_USAGE_CPU_READ;
+
+ if (usage & PIPE_TRANSFER_WRITE)
+ res |= PB_USAGE_CPU_WRITE;
+
+ if (usage & PIPE_TRANSFER_DONTBLOCK)
+ res |= PB_USAGE_DONTBLOCK;
+
+ if (usage & PIPE_TRANSFER_UNSYNCHRONIZED)
+ res |= PB_USAGE_UNSYNCHRONIZED;
+
+ return res;
+}
+
static void *
-radeon_drm_buffer_map(struct pb_buffer *_buf,
+radeon_drm_buffer_map_internal(struct pb_buffer *_buf,
unsigned flags)
{
struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
+ struct radeon_libdrm_cs *cs = buf->cs;
int write = 0;
- if (flags & PIPE_TRANSFER_DONTBLOCK) {
- if ((_buf->base.usage & PIPE_BIND_VERTEX_BUFFER) ||
- (_buf->base.usage & PIPE_BIND_INDEX_BUFFER))
- if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs))
+ if (flags & PB_USAGE_DONTBLOCK) {
+ if (_buf->base.usage & RADEON_PB_USAGE_VERTEX)
+ if (cs && radeon_bo_is_referenced_by_cs(buf->bo, cs->cs))
return NULL;
}
if (buf->bo->ptr != NULL)
return buf->bo->ptr;
- if (flags & PIPE_TRANSFER_DONTBLOCK) {
+ if (flags & PB_USAGE_DONTBLOCK) {
uint32_t domain;
if (radeon_bo_is_busy(buf->bo, &domain))
return NULL;
}
- if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
- buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data);
+ if (cs && radeon_bo_is_referenced_by_cs(buf->bo, cs->cs)) {
+ cs->flush_cs(cs->flush_data);
}
- if (flags & PIPE_TRANSFER_WRITE) {
+ if (flags & PB_USAGE_CPU_WRITE) {
write = 1;
}
}
static void
-radeon_drm_buffer_unmap(struct pb_buffer *_buf)
+radeon_drm_buffer_unmap_internal(struct pb_buffer *_buf)
{
(void)_buf;
}
const struct pb_vtbl radeon_drm_buffer_vtbl = {
radeon_drm_buffer_destroy,
- radeon_drm_buffer_map,
- radeon_drm_buffer_unmap,
+ radeon_drm_buffer_map_internal,
+ radeon_drm_buffer_unmap_internal,
radeon_drm_buffer_validate,
radeon_drm_buffer_fence,
radeon_drm_buffer_get_base_buffer,
};
-
-static uint32_t radeon_domain_from_usage(unsigned usage)
-{
- uint32_t domain = 0;
-
- if (usage & PIPE_BIND_RENDER_TARGET) {
- domain |= RADEON_GEM_DOMAIN_VRAM;
- }
- if (usage & PIPE_BIND_DEPTH_STENCIL) {
- domain |= RADEON_GEM_DOMAIN_VRAM;
- }
- if (usage & PIPE_BIND_SAMPLER_VIEW) {
- domain |= RADEON_GEM_DOMAIN_VRAM;
- }
- /* also need BIND_BLIT_SOURCE/DESTINATION ? */
- if (usage & PIPE_BIND_VERTEX_BUFFER) {
- domain |= RADEON_GEM_DOMAIN_GTT;
- }
- if (usage & PIPE_BIND_INDEX_BUFFER) {
- domain |= RADEON_GEM_DOMAIN_GTT;
- }
-
- return domain;
-}
-
struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
uint32_t handle)
{
pipe_reference_init(&buf->base.base.reference, 1);
buf->base.base.alignment = 0;
- buf->base.base.usage = PIPE_BIND_SAMPLER_VIEW;
- buf->base.base.size = 0;
+ buf->base.base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ;
+ buf->base.base.size = bo->size;
buf->base.vtbl = &radeon_drm_buffer_vtbl;
buf->mgr = mgr;
buf->mgr = mgr;
make_empty_list(buf);
- domain = radeon_domain_from_usage(desc->usage);
+
+ domain =
+ (desc->usage & RADEON_PB_USAGE_DOMAIN_GTT ? RADEON_GEM_DOMAIN_GTT : 0) |
+ (desc->usage & RADEON_PB_USAGE_DOMAIN_VRAM ? RADEON_GEM_DOMAIN_VRAM : 0);
+
buf->bo = radeon_bo_open(rws->bom, 0, size,
desc->alignment, domain, 0);
if (buf->bo == NULL)
static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf)
{
- struct radeon_drm_buffer *buf;
+ struct radeon_drm_buffer *buf = NULL;
+
if (_buf->vtbl == &radeon_drm_buffer_vtbl) {
buf = radeon_drm_buffer(_buf);
} else {
pb_size offset;
pb_get_base_buffer(_buf, &base_buf, &offset);
- buf = radeon_drm_buffer(base_buf);
+ if (base_buf->vtbl == &radeon_drm_buffer_vtbl)
+ buf = radeon_drm_buffer(base_buf);
}
+
return buf;
}
+void *radeon_drm_buffer_map(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf,
+ struct r300_winsys_cs *cs,
+ enum pipe_transfer_usage usage)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+ struct radeon_drm_buffer *rbuf = get_drm_buffer(_buf);
+
+ if (rbuf)
+ rbuf->cs = radeon_libdrm_cs(cs);
+
+ return pb_map(_buf, get_pb_usage_from_transfer_flags(usage));
+}
+
+void radeon_drm_buffer_unmap(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *buf)
+{
+ struct pb_buffer *_buf = radeon_pb_buffer(buf);
+
+ pb_unmap(_buf);
+}
+
boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
struct winsys_handle *whandle)
{
- int retval, fd;
struct drm_gem_flink flink;
struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+
if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
if (!buf->flinked) {
- fd = buf->mgr->rws->fd;
flink.handle = buf->bo->handle;
- retval = ioctl(fd, DRM_IOCTL_GEM_FLINK, &flink);
- if (retval) {
+ if (ioctl(buf->mgr->rws->fd, DRM_IOCTL_GEM_FLINK, &flink)) {
return FALSE;
}
return TRUE;
}
-void radeon_drm_bufmgr_get_tiling(struct pb_buffer *_buf,
+void radeon_drm_bufmgr_get_tiling(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *_buf,
enum r300_buffer_tiling *microtiled,
enum r300_buffer_tiling *macrotiled)
{
- struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
uint32_t flags = 0, pitch;
radeon_bo_get_tiling(buf->bo, &flags, &pitch);
*macrotiled = R300_BUFFER_TILED;
}
-void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf,
+void radeon_drm_bufmgr_set_tiling(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *_buf,
enum r300_buffer_tiling microtiled,
enum r300_buffer_tiling macrotiled,
uint32_t pitch)
{
- struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
- uint32_t flags = 0, old_flags, old_pitch;
+ struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
+ uint32_t flags = 0;
if (microtiled == R300_BUFFER_TILED)
flags |= RADEON_BO_FLAGS_MICRO_TILE;
/* XXX Remove this ifdef when libdrm version 2.4.19 becomes mandatory. */
if (macrotiled == R300_BUFFER_TILED)
flags |= RADEON_BO_FLAGS_MACRO_TILE;
- radeon_bo_get_tiling(buf->bo, &old_flags, &old_pitch);
-
- if (flags != old_flags || pitch != old_pitch) {
- /* Tiling determines how DRM treats the buffer data.
- * We must flush CS when changing it if the buffer is referenced. */
- if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
- buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data);
- }
- }
radeon_bo_set_tiling(buf->bo, flags, pitch);
+}
+
+static uint32_t get_gem_domain(enum r300_buffer_domain domain)
+{
+ uint32_t res = 0;
+ if (domain & R300_DOMAIN_GTT)
+ res |= RADEON_GEM_DOMAIN_GTT;
+ if (domain & R300_DOMAIN_VRAM)
+ res |= RADEON_GEM_DOMAIN_VRAM;
+ return res;
}
-boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf,
- uint32_t rd, uint32_t wd)
+void radeon_drm_bufmgr_add_buffer(struct r300_winsys_cs *rcs,
+ struct r300_winsys_buffer *_buf,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd)
{
- struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
- radeon_cs_space_add_persistent_bo(buf->mgr->rws->cs, buf->bo,
- rd, wd);
- return TRUE;
+ struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+ struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
+ uint32_t gem_rd = get_gem_domain(rd);
+ uint32_t gem_wd = get_gem_domain(wd);
+
+ radeon_cs_space_add_persistent_bo(cs->cs, buf->bo, gem_rd, gem_wd);
}
-void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
- uint32_t rd, uint32_t wd,
- uint32_t flags)
+void radeon_drm_bufmgr_write_reloc(struct r300_winsys_cs *rcs,
+ struct r300_winsys_buffer *_buf,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd)
{
- struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+ struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
int retval;
+ uint32_t gem_rd = get_gem_domain(rd);
+ uint32_t gem_wd = get_gem_domain(wd);
- retval = radeon_cs_write_reloc(buf->mgr->rws->cs,
- buf->bo, rd, wd, flags);
+ cs->cs->cdw = cs->base.cdw;
+ retval = radeon_cs_write_reloc(cs->cs, buf->bo, gem_rd, gem_wd, 0);
+ cs->base.cdw = cs->cs->cdw;
if (retval) {
- debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n",
- buf, rd, wd, flags);
+ fprintf(stderr, "radeon: Relocation of %p (%d, %d, %d) failed!\n",
+ buf, gem_rd, gem_wd, 0);
}
}
-boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf,
+boolean radeon_drm_bufmgr_is_buffer_referenced(struct r300_winsys_cs *rcs,
+ struct r300_winsys_buffer *_buf,
enum r300_reference_domain domain)
{
- struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+ struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
uint32_t tmp;
if (domain & R300_REF_CS) {
- if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
+ if (radeon_bo_is_referenced_by_cs(buf->bo, cs->cs)) {
return TRUE;
}
}
return FALSE;
}
-
void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr)
{
struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
make_empty_list(&mgr->buffer_map_list);
}
+
+void radeon_drm_bufmgr_wait(struct r300_winsys_screen *ws,
+ struct r300_winsys_buffer *_buf)
+{
+ struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
+
+ radeon_bo_wait(buf->bo);
+}