summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2013-06-16 15:13:19 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2013-06-16 15:13:19 +0200
commit8462e12ba214380bb9930be50c2a3bdb9ab918c5 (patch)
tree68681eaabab8a3904ee481b48a7b88506fb35b4d
parent98d06829c0861fab789321f27afb0e03daabade4 (diff)
driver: framebuffer handling
Most of etna_fb is not currently used in the mesa driver, even though it has functionality not in mesa, such as determining an exact match RS format and red/blue swap from linux framebuffer attributes. Expose this function.
-rw-r--r--native/driver/etna_fb.c15
-rw-r--r--native/driver/etna_fb.h3
-rw-r--r--native/driver/etna_pipe.c2
-rw-r--r--native/driver/etna_rs.h12
-rw-r--r--native/driver/etna_screen.c26
-rw-r--r--native/driver/etna_screen.h2
-rw-r--r--native/driver/etna_translate.h2
7 files changed, 34 insertions, 28 deletions
diff --git a/native/driver/etna_fb.c b/native/driver/etna_fb.c
index 2ef30d1..13b78ac 100644
--- a/native/driver/etna_fb.c
+++ b/native/driver/etna_fb.c
@@ -88,7 +88,7 @@ static const struct etna_fb_format_desc etna_fb_formats[] = {
/* Get resolve format and swap red/blue format based on report on red/green/blue
* bit positions from kernel.
*/
-static int fb_get_format(const struct fb_var_screeninfo *fb_var)
+bool etna_fb_get_format(const struct fb_var_screeninfo *fb_var, unsigned *rs_format, bool *swap_rb)
{
int fmt_idx=0;
/* linear scan of table to find matching format */
@@ -114,13 +114,15 @@ static int fb_get_format(const struct fb_var_screeninfo *fb_var)
(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);
- fmt_idx = -1;
+ return false;
} else {
printf("Framebuffer format: %i, flip_rb=%i\n",
etna_fb_formats[fmt_idx].rs_format,
etna_fb_formats[fmt_idx].swap_rb);
+ *rs_format = etna_fb_formats[fmt_idx].rs_format;
+ *swap_rb = etna_fb_formats[fmt_idx].swap_rb;
+ return true;
}
- return fmt_idx;
}
/* Open framebuffer and get information */
@@ -193,12 +195,9 @@ int fb_open(int num, struct fb_info *out)
}
/* determine resolve format */
- int fmt_idx = fb_get_format(&out->fb_var);
- if(fmt_idx != -1)
+ if(!etna_fb_get_format(&out->fb_var, (unsigned*)&out->rs_format, &out->swap_rb))
{
- out->rs_format = etna_fb_formats[fmt_idx].rs_format;
- out->swap_rb = etna_fb_formats[fmt_idx].swap_rb;
- } else {
+ /* no match */
out->rs_format = -1;
out->swap_rb = false;
}
diff --git a/native/driver/etna_fb.h b/native/driver/etna_fb.h
index d67e1ed..63966b3 100644
--- a/native/driver/etna_fb.h
+++ b/native/driver/etna_fb.h
@@ -70,5 +70,8 @@ int etna_fb_bind_resource(struct fb_info *fb, struct pipe_resource *rt_resource)
/* Copy framebuffer from bound render target resource */
int etna_fb_copy_buffer(struct fb_info *fb, struct etna_ctx *ctx, int buffer);
+/* Determine the framebuffer format from Linux framebuffer info structure */
+bool etna_fb_get_format(const struct fb_var_screeninfo *fb_var, unsigned *rs_format, bool *swap_rb);
+
#endif
diff --git a/native/driver/etna_pipe.c b/native/driver/etna_pipe.c
index 57e007e..6ea368a 100644
--- a/native/driver/etna_pipe.c
+++ b/native/driver/etna_pipe.c
@@ -1091,7 +1091,6 @@ static void etna_pipe_set_vertex_buffers( struct pipe_context *pipe,
{
struct etna_pipe_context_priv *priv = ETNA_PIPE(pipe);
struct compiled_set_vertex_buffer *cs = &priv->vertex_buffer;
- printf("pipe_set_vertex_buffers %i %i\n", start_slot, num_buffers);
assert(start_slot == 0 && num_buffers == 1); /* XXX TODO */
assert(vb[0].buffer); /* XXX user_buffer */
priv->vertex_buffer_s = vb[0];
@@ -1155,7 +1154,6 @@ static void etna_pipe_clear(struct pipe_context *pipe,
unsigned stencil)
{
struct etna_pipe_context_priv *priv = ETNA_PIPE(pipe);
- printf("Pipe clear\n");
/* Need to update clear command in non-TS (fast clear) case *if*
* clear value is different from previous time.
*/
diff --git a/native/driver/etna_rs.h b/native/driver/etna_rs.h
index d76ddd4..19b30c3 100644
--- a/native/driver/etna_rs.h
+++ b/native/driver/etna_rs.h
@@ -67,6 +67,18 @@ struct compiled_rs_state
uint32_t RS_PIPE_OFFSET[2]; /* TODO is there hardware with more then 2 pipes? */
};
+/* Resolve target.
+ * Used by etna_screen_flush_frontbuffer
+ */
+struct etna_rs_target
+{
+ unsigned rs_format;
+ bool swap_rb;
+ unsigned width, height;
+ size_t addr; /* GPU address */
+ size_t stride;
+};
+
/* Flush RS? warm up RS on aux render target */
void etna_warm_up_rs(struct etna_ctx *cmdbuf, viv_addr_t aux_rt_physical, viv_addr_t aux_rt_ts_physical);
diff --git a/native/driver/etna_screen.c b/native/driver/etna_screen.c
index 92eb67d..09e1e5e 100644
--- a/native/driver/etna_screen.c
+++ b/native/driver/etna_screen.c
@@ -25,6 +25,7 @@
#include "etna_shader.h"
#include "etna_translate.h"
#include "etna_debug.h"
+#include "etna_rs.h"
#include <etnaviv/viv.h>
#include <etnaviv/etna.h>
@@ -375,24 +376,15 @@ static struct pipe_resource * etna_screen_resource_from_handle(struct pipe_scree
return NULL;
}
-
-/** Temporary hack, belongs in a winsys,
- * and should likely contain a context, flags such as swap_rb,
- * and precompiled RS command like etna_fb.
+/* XXX this should use a blit or resource copy, when implemented, instead
+ * of programming the RS directly.
*/
-struct fbdev_etna_drawable {
- enum pipe_format format;
- unsigned x, y;
- unsigned width, height;
- size_t smem_start, smem_len, line_length;
-};
-
static void etna_screen_flush_frontbuffer( struct pipe_screen *screen,
struct pipe_resource *resource,
unsigned level, unsigned layer,
void *winsys_drawable_handle )
{
- struct fbdev_etna_drawable *drawable = (struct fbdev_etna_drawable *)winsys_drawable_handle;
+ struct etna_rs_target *drawable = (struct etna_rs_target *)winsys_drawable_handle;
struct etna_resource *rt_resource = etna_resource(resource);
struct etna_pipe_context_priv *priv = ETNA_PIPE(_hack_ctx);
assert(priv);
@@ -405,11 +397,11 @@ static void etna_screen_flush_frontbuffer( struct pipe_screen *screen,
.source_tiling = rt_resource->layout,
.source_addr = rt_resource->levels[0].address,
.source_stride = rt_resource->levels[0].stride,
- .dest_format = RS_FORMAT_X8R8G8B8, // XXX
+ .dest_format = drawable->rs_format,
.dest_tiling = ETNA_LAYOUT_LINEAR,
- .dest_addr = drawable->smem_start,
- .dest_stride = drawable->line_length,
- .swap_rb = 0, // XXX
+ .dest_addr = drawable->addr,
+ .dest_stride = drawable->stride,
+ .swap_rb = drawable->swap_rb,
.dither = {0xffffffff, 0xffffffff}, // XXX dither when going from 24 to 16 bit?
.clear_mode = VIVS_RS_CLEAR_CONTROL_MODE_DISABLED,
.width = drawable->width,
@@ -420,7 +412,7 @@ static void etna_screen_flush_frontbuffer( struct pipe_screen *screen,
/* Flush RS */
etna_set_state(ctx, VIVS_RS_FLUSH_CACHE, VIVS_RS_FLUSH_CACHE_FLUSH);
printf("Queued RS command to flush screen from %08x to %08x stride=%08x width=%i height=%i, ctx %p\n", rt_resource->levels[0].address,
- drawable->smem_start, drawable->line_length,
+ drawable->addr, drawable->stride,
drawable->width, drawable->height, ctx);
etna_flush(ctx);
//DBG("unimplemented etna_screen_flush_frontbuffer");
diff --git a/native/driver/etna_screen.h b/native/driver/etna_screen.h
index a025f58..a032892 100644
--- a/native/driver/etna_screen.h
+++ b/native/driver/etna_screen.h
@@ -28,6 +28,8 @@
struct viv_conn;
+/* Gallium screen structure for etna driver.
+ */
struct etna_screen {
struct pipe_screen base;
struct viv_conn *dev;
diff --git a/native/driver/etna_translate.h b/native/driver/etna_translate.h
index c9b1047..91b6c82 100644
--- a/native/driver/etna_translate.h
+++ b/native/driver/etna_translate.h
@@ -218,7 +218,7 @@ static inline uint32_t translate_texture_format(enum pipe_format fmt, bool silen
}
}
-/* render target format */
+/* render target format (non-rb swapped RS-supported formats) */
static inline uint32_t translate_rt_format(enum pipe_format fmt, bool silent)
{
switch(fmt)