From 77e635f9f4bc42100122263fbe2126a69583b403 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Tue, 29 Jul 2014 17:26:44 +0200 Subject: etna: use plain etna_resource to wrap framebuffer This moves framebuffer handling almost completely into MESA and doesn't rely on libetna anymore. Signed-off-by: Lucas Stach --- src/gallium/drivers/etna/etna_screen.c | 24 ++--- src/gallium/drivers/etna/etna_screen.h | 13 --- src/gallium/winsys/etna/fbdev/etna_fbdev_winsys.c | 117 +++++++++++++++++----- 3 files changed, 105 insertions(+), 49 deletions(-) diff --git a/src/gallium/drivers/etna/etna_screen.c b/src/gallium/drivers/etna/etna_screen.c index a3c8ed375c..591596a37e 100644 --- a/src/gallium/drivers/etna/etna_screen.c +++ b/src/gallium/drivers/etna/etna_screen.c @@ -432,16 +432,13 @@ static void etna_screen_flush_frontbuffer( struct pipe_screen *screen, void *winsys_drawable_handle, struct pipe_box *subbox) { - struct etna_rs_target *drawable = (struct etna_rs_target *)winsys_drawable_handle; + struct etna_resource *drawable = winsys_drawable_handle; struct etna_resource *rt_resource = etna_resource(resource); struct etna_pipe_context *ectx = rt_resource->last_ctx; assert(level <= resource->last_level && layer < resource->array_size); assert(ectx); struct etna_ctx *ctx = ectx->ctx; - /* release previous fence, make reference to fence if we need one */ - screen->fence_reference(screen, &drawable->fence, NULL); - etna_set_state(ctx, VIVS_GL_FLUSH_CACHE, VIVS_GL_FLUSH_CACHE_COLOR); etna_stall(ctx, SYNC_RECIPIENT_RA, SYNC_RECIPIENT_PE); @@ -475,25 +472,26 @@ static void etna_screen_flush_frontbuffer( struct pipe_screen *screen, .source_addr[0] = etna_get_level_pipe_addr(rt_resource, level, 0), .source_addr[1] = etna_get_level_pipe_addr(rt_resource, level, 1), .source_stride = rt_resource->levels[level].stride, - .dest_format = drawable->rs_format, - .dest_tiling = ETNA_LAYOUT_LINEAR, + .dest_format = translate_rt_format(drawable->base.format, false), + .dest_tiling = drawable->layout, .dest_addr[0] = etna_bo_gpu_address(drawable->bo), - .dest_stride = drawable->stride, + .dest_stride = drawable->levels[0].stride, .downsample_x = msaa_xscale > 1, .downsample_y = msaa_yscale > 1, - .swap_rb = drawable->swap_rb, + .swap_rb = translate_rb_src_dst_swap(rt_resource->base.format, + drawable->base.format), .dither = {0xffffffff, 0xffffffff}, // XXX dither when going from 24 to 16 bit? .clear_mode = VIVS_RS_CLEAR_CONTROL_MODE_DISABLED, - .width = drawable->width * msaa_xscale, - .height = drawable->height * msaa_yscale + .width = drawable->levels[0].width * msaa_xscale, + .height = drawable->levels[0].height * msaa_yscale }); etna_submit_rs_state(ctx, ©_to_screen); DBG_F(ETNA_DBG_FRAME_MSGS, "Queued RS command to flush screen from %08x to %08x stride=%08x width=%i height=%i, ctx %p", etna_bo_gpu_address(rt_resource->bo) + rt_resource->levels[level].offset, - etna_bo_gpu_address(drawable->bo), drawable->stride, - drawable->width, drawable->height, ctx); - ectx->base.flush(&ectx->base, &drawable->fence, 0); + etna_bo_gpu_address(drawable->bo), drawable->levels[0].stride, + drawable->levels[0].width, drawable->levels[0].height, ctx); + ectx->base.flush(&ectx->base, NULL, 0); } struct pipe_screen * diff --git a/src/gallium/drivers/etna/etna_screen.h b/src/gallium/drivers/etna/etna_screen.h index 80ccd2cf0a..81c5281b82 100644 --- a/src/gallium/drivers/etna/etna_screen.h +++ b/src/gallium/drivers/etna/etna_screen.h @@ -41,19 +41,6 @@ struct etna_screen { struct etna_pipe_specs specs; }; -/* Resolve target. - * Used by etna_screen_flush_frontbuffer - */ -struct etna_rs_target -{ - unsigned rs_format; - bool swap_rb; - unsigned width, height; - struct etna_bo *bo; - size_t stride; - struct pipe_fence_handle *fence; -}; - static INLINE struct etna_screen * etna_screen(struct pipe_screen *pscreen) { diff --git a/src/gallium/winsys/etna/fbdev/etna_fbdev_winsys.c b/src/gallium/winsys/etna/fbdev/etna_fbdev_winsys.c index ea92712ae2..da22458d90 100644 --- a/src/gallium/winsys/etna/fbdev/etna_fbdev_winsys.c +++ b/src/gallium/winsys/etna/fbdev/etna_fbdev_winsys.c @@ -9,6 +9,7 @@ #include "etna_fbdev_public.h" #include "etna/etna_screen.h" +#include "etna/etna_pipe.h" #include #include @@ -24,14 +25,81 @@ struct etna_fbdev_screen /* anything? */ }; -static inline struct etna_fbdev_screen *etna_fbdev_screen(struct native_fbdev_screen *fbdev_screen) +static void etna_fbdev_screen_destroy(struct native_fbdev_screen *fbdev_screen) { - return (struct etna_fbdev_screen*)fbdev_screen; + FREE(fbdev_screen); } -static void etna_fbdev_screen_destroy(struct native_fbdev_screen *fbdev_screen) +struct etna_fb_format_desc { - FREE(fbdev_screen); + unsigned bits_per_pixel; + unsigned red_offset; + unsigned red_length; + unsigned green_offset; + unsigned green_length; + unsigned blue_offset; + unsigned blue_length; + unsigned alpha_offset; + unsigned alpha_length; + enum pipe_format format; +}; + +static const struct etna_fb_format_desc etna_fb_formats[] = { +/* bpp ro rl go gl bo bl ao al gs format */ + {32, 16, 8, 8, 8, 0 , 8, 0, 0, PIPE_FORMAT_B8G8R8X8_UNORM}, + {32, 0 , 8, 8, 8, 16, 8, 0, 0, PIPE_FORMAT_R8G8B8X8_UNORM}, + {32, 16, 8, 8, 8, 0 , 8, 24, 8, PIPE_FORMAT_B8G8R8A8_UNORM}, + {32, 0 , 8, 8, 8, 16, 8, 24, 8, PIPE_FORMAT_R8G8B8A8_UNORM}, + {16, 8 , 4, 4, 4, 0, 4, 12, 4, PIPE_FORMAT_B4G4R4A4_UNORM}, + {16, 10, 5, 5, 5, 0, 5, 0, 0, PIPE_FORMAT_B5G5R5X1_UNORM}, + {16, 10, 5, 5, 5, 0, 5, 15, 1, PIPE_FORMAT_B5G5R5A1_UNORM}, + {16, 11, 5, 5, 6, 0, 5, 0, 0, PIPE_FORMAT_B5G6R5_UNORM }, +}; + +#define NUM_FB_FORMATS (sizeof(etna_fb_formats) / sizeof(etna_fb_formats[0])) + +/* Get resolve format and swap red/blue format based on report on red/green/blue + * bit positions from kernel. + */ +static enum pipe_format etna_fbdev_get_format(const struct fb_var_screeninfo *fb_var) +{ + int fmt_idx = 0; + + if (fb_var->grayscale) + return PIPE_FORMAT_COUNT; + + /* linear scan of table to find matching format */ + for (fmt_idx = 0; fmt_idxred_offset == fb_var->red.offset && + desc->red_length == fb_var->red.length && + desc->green_offset == fb_var->green.offset && + desc->green_length == fb_var->green.length && + desc->blue_offset == fb_var->blue.offset && + desc->blue_length == fb_var->blue.length && + (desc->alpha_offset == fb_var->transp.offset || desc->alpha_length == 0) && + desc->alpha_length == fb_var->transp.length) + { + break; + } + } + /* no matching format found */ + if (fmt_idx == NUM_FB_FORMATS) + { + printf("Unsupported framebuffer format: red_offset=%i red_length=%i green_offset=%i green_length=%i blue_offset=%i blue_length=%i trans_offset=%i transp_length=%i grayscale=%i\n", + (int)fb_var->red.offset, (int)fb_var->red.length, + (int)fb_var->green.offset, (int)fb_var->green.length, + (int)fb_var->blue.offset, (int)fb_var->blue.length, + (int)fb_var->transp.offset, (int)fb_var->transp.length, + (int)fb_var->grayscale); + return PIPE_FORMAT_COUNT; + } + + printf("Framebuffer format: %s\n",util_format_short_name( + etna_fb_formats[fmt_idx].format)); + + return etna_fb_formats[fmt_idx].format; } static void *etna_fbdev_create_drawable(struct native_fbdev_screen *fbdev_screen, @@ -39,7 +107,7 @@ static void *etna_fbdev_create_drawable(struct native_fbdev_screen *fbdev_screen unsigned xoffset, unsigned yoffset, unsigned width, unsigned height) { - struct etna_rs_target *drawable = CALLOC_STRUCT(etna_rs_target); + struct etna_resource *drawable = CALLOC_STRUCT(etna_resource); struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; struct etna_screen *screen = etna_screen(fbdev_screen->screen); @@ -63,33 +131,36 @@ static void *etna_fbdev_create_drawable(struct native_fbdev_screen *fbdev_screen height = vinfo.yres_virtual - yoffset; } - drawable->width = width; - drawable->height = height; + drawable->base.format = etna_fbdev_get_format(&vinfo); + if (drawable->base.format == PIPE_FORMAT_COUNT) { + FREE(drawable); + return NULL; + } + drawable->bo = etna_bo_from_fbdev(screen->dev, fd, finfo.line_length * yoffset + vinfo.bits_per_pixel / 8 * xoffset, finfo.line_length * height); - drawable->stride = finfo.line_length; + drawable->layout = ETNA_LAYOUT_LINEAR; + + drawable->levels[0].width = width; + drawable->levels[0].height = height; + drawable->levels[0].padded_width = width; + drawable->levels[0].padded_height = height; + drawable->levels[0].stride = finfo.line_length; + + drawable->base.screen = fbdev_screen->screen; + pipe_reference_init(&drawable->base.reference, 1); - if(width == 0 || height == 0 || - !etna_fb_get_format(&vinfo, &drawable->rs_format, &drawable->swap_rb)) - { - FREE(drawable); - return NULL; - } return drawable; } static void etna_fbdev_destroy_drawable(struct native_fbdev_screen *fbdev_screen, void *hdrawable) { - struct etna_rs_target *drawable = (struct etna_rs_target*)hdrawable; - fbdev_screen->screen->fence_reference(fbdev_screen->screen, &drawable->fence, NULL); - FREE(drawable); -} + struct etna_resource *drawable = hdrawable; + struct etna_screen *screen = etna_screen(fbdev_screen->screen); -static struct pipe_fence_handle *etna_fbdev_get_drawable_fence(struct native_fbdev_screen *fbdev_screen, void *hdrawable) -{ - struct etna_rs_target *drawable = (struct etna_rs_target*)hdrawable; - return (struct pipe_fence_handle*)drawable->fence; + etna_bo_del(screen->dev, drawable->bo, NULL); + FREE(drawable); } static bool etna_fbdev_probe(const struct native_fbdev_driver *driver) @@ -115,7 +186,7 @@ static struct native_fbdev_screen *etna_fbdev_create_screen( fscreen->base.destroy = etna_fbdev_screen_destroy; fscreen->base.create_drawable = etna_fbdev_create_drawable; fscreen->base.destroy_drawable = etna_fbdev_destroy_drawable; - fscreen->base.get_drawable_fence = etna_fbdev_get_drawable_fence; + return &fscreen->base; } -- cgit v1.2.3