diff options
Diffstat (limited to 'src/gallium/winsys')
5 files changed, 86 insertions, 15 deletions
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c index 25e1cdcdb6d..5214b6d8bcb 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c @@ -51,6 +51,23 @@ static const char *radeon_get_name(struct pipe_winsys *ws) return "Radeon/GEM+KMS"; } +uint32_t radeon_domain_from_usage(unsigned usage) +{ + uint32_t domain = 0; + + if (usage & PIPE_BUFFER_USAGE_PIXEL) { + domain |= RADEON_GEM_DOMAIN_VRAM; + } + if (usage & PIPE_BUFFER_USAGE_VERTEX) { + domain |= RADEON_GEM_DOMAIN_GTT; + } + if (usage & PIPE_BUFFER_USAGE_INDEX) { + domain |= RADEON_GEM_DOMAIN_GTT; + } + + return domain; +} + static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws, unsigned alignment, unsigned usage, @@ -71,25 +88,17 @@ static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws, radeon_buffer->base.usage = usage; radeon_buffer->base.size = size; - if (usage == PIPE_BUFFER_USAGE_CONSTANT && is_r3xx(radeon_ws->pci_id)) { + if ((usage == PIPE_BUFFER_USAGE_CONSTANT && is_r3xx(radeon_ws->pci_id)) || + (usage == PIPE_BUFFER_USAGE_VERTEX && size < 512)) { /* Don't bother allocating a BO, as it'll never get to the card. */ + /* Also, create small vertex buffers in RAM. */ desc.alignment = alignment; desc.usage = usage; radeon_buffer->pb = pb_malloc_buffer_create(size, &desc); return &radeon_buffer->base; } - domain = 0; - - if (usage & PIPE_BUFFER_USAGE_PIXEL) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BUFFER_USAGE_VERTEX) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - if (usage & PIPE_BUFFER_USAGE_INDEX) { - domain |= RADEON_GEM_DOMAIN_GTT; - } + domain = radeon_domain_from_usage(usage); radeon_buffer->bo = radeon_bo_open(radeon_ws->priv->bom, 0, size, alignment, domain, 0); @@ -222,6 +231,54 @@ static void radeon_buffer_set_tiling(struct radeon_winsys *ws, radeon_bo_set_tiling(radeon_buffer->bo, flags, pitch); } +static boolean radeon_buffer_is_local(struct radeon_winsys *ws, + struct pipe_buffer *buffer) +{ + struct radeon_pipe_buffer *radeon_buffer = + (struct radeon_pipe_buffer*)buffer; + + return radeon_buffer->pb != NULL; +} + +static void radeon_buffer_make_managed(struct radeon_winsys *ws, + struct pipe_buffer *buffer) +{ + struct radeon_pipe_buffer* radeon_buffer = + (struct radeon_pipe_buffer*)buffer; + uint32_t domain; + void *map; + + if (radeon_buffer->pb) { + domain = radeon_domain_from_usage(buffer->usage); + + /* Create a managed buffer. */ + radeon_buffer->bo = radeon_bo_open(ws->priv->bom, 0, + buffer->size, buffer->alignment, + domain, 0); + if (radeon_buffer->bo == NULL) { + /* XXX What now? */ + fprintf(stderr, "radeon: cannot create a buffer in function %s\n", + __FUNCTION__); + assert(0); + abort(); + } + + /* Move data. */ + radeon_bo_map(radeon_buffer->bo, 1); + map = pb_map(radeon_buffer->pb, PIPE_BUFFER_USAGE_CPU_READ); + + memcpy(radeon_buffer->bo->ptr, map, buffer->size); + + pb_unmap(radeon_buffer->pb); + radeon_bo_unmap(radeon_buffer->bo); + + /* Release the locally-created buffer. */ + pipe_reference_init(&radeon_buffer->pb->base.reference, 0); + pb_destroy(radeon_buffer->pb); + radeon_buffer->pb = 0; + } +} + static void radeon_fence_reference(struct pipe_winsys *ws, struct pipe_fence_handle **ptr, struct pipe_fence_handle *pfence) @@ -325,6 +382,8 @@ struct radeon_winsys* radeon_pipe_winsys(int fd) radeon_ws->base.get_name = radeon_get_name; radeon_ws->buffer_set_tiling = radeon_buffer_set_tiling; + radeon_ws->buffer_is_local = radeon_buffer_is_local; + radeon_ws->buffer_make_managed = radeon_buffer_make_managed; return radeon_ws; } diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h index de71cb2f42d..c46abff793e 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h @@ -77,6 +77,8 @@ struct radeon_winsys_priv { void *flush_data; }; +uint32_t radeon_domain_from_usage(unsigned usage); + struct radeon_winsys* radeon_pipe_winsys(int fb); #if 0 struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context, diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h index ddd7983824a..077388ee028 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h @@ -81,7 +81,7 @@ void radeon_destroy_drm_api(struct drm_api* api); /* Guess at whether this chipset should use r300g. * * I believe that this check is valid, but I haven't been exhaustive. */ -static boolean is_r3xx(int pciid) +static INLINE boolean is_r3xx(int pciid) { return (pciid > 0x3150) && (pciid < 0x796f); } diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c index 0253bc2527e..d759beaba13 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c @@ -81,9 +81,13 @@ static void radeon_write_cs_reloc(struct radeon_winsys* winsys, uint32_t flags) { int retval = 0; + struct radeon_pipe_buffer* radeon_buffer = + (struct radeon_pipe_buffer*)pbuffer; - retval = radeon_cs_write_reloc(winsys->priv->cs, - ((struct radeon_pipe_buffer*)pbuffer)->bo, rd, wd, flags); + assert(!radeon_buffer->pb); + + retval = radeon_cs_write_reloc(winsys->priv->cs, radeon_buffer->bo, + rd, wd, flags); if (retval) { debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n", diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h index 864082b99b3..462fba844ef 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_winsys.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys.h @@ -106,6 +106,12 @@ struct radeon_winsys { uint32_t pitch, boolean microtiled, boolean macrotiled); + + boolean (*buffer_is_local)(struct radeon_winsys* winsys, + struct pipe_buffer* buffer); + + void (*buffer_make_managed)(struct radeon_winsys* winsys, + struct pipe_buffer* buffer); }; #endif |