summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2013-05-09 15:14:11 +0800
committerChia-I Wu <[email protected]>2013-05-09 16:05:48 +0800
commita8e46140718b85fd33be97c693050f8722db1def (patch)
treeaf2c16f4d51d58ac1370e26c73bc656a5f598e0a /src/gallium
parent183ea823fd3a8a043ceb0e5d774eee459155a6f6 (diff)
ilo: add support for PIPE_FORMAT_ETC1_RGB8
It is decompressed to and stored as PIPE_FORMAT_R8G8B8X8_UNORM on-the-fly.
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/ilo/ilo_format.h5
-rw-r--r--src/gallium/drivers/ilo/ilo_resource.c61
2 files changed, 61 insertions, 5 deletions
diff --git a/src/gallium/drivers/ilo/ilo_format.h b/src/gallium/drivers/ilo/ilo_format.h
index 556b21887c3..c01edd9b73c 100644
--- a/src/gallium/drivers/ilo/ilo_format.h
+++ b/src/gallium/drivers/ilo/ilo_format.h
@@ -70,6 +70,9 @@ ilo_translate_format(enum pipe_format format, unsigned bind)
* values. But we assume in many places that the depth values are
* returned as I values (util_make_fragment_tex_shader_writedepth() is
* one such example). We have to live with that at least for now.
+ *
+ * For ETC1 format, the texture data will be decompressed before being
+ * written to the bo. See transfer_unmap_sys_convert().
*/
switch (format) {
case PIPE_FORMAT_Z16_UNORM:
@@ -81,6 +84,8 @@ ilo_translate_format(enum pipe_format format, unsigned bind)
return BRW_SURFACEFORMAT_I24X8_UNORM;
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
return BRW_SURFACEFORMAT_I32X32_FLOAT;
+ case PIPE_FORMAT_ETC1_RGB8:
+ return BRW_SURFACEFORMAT_R8G8B8X8_UNORM;
default:
return ilo_translate_color_format(format);
}
diff --git a/src/gallium/drivers/ilo/ilo_resource.c b/src/gallium/drivers/ilo/ilo_resource.c
index 082d9170fd0..c401d9f5f2b 100644
--- a/src/gallium/drivers/ilo/ilo_resource.c
+++ b/src/gallium/drivers/ilo/ilo_resource.c
@@ -27,6 +27,7 @@
#include "util/u_surface.h"
#include "util/u_transfer.h"
+#include "util/u_format_etc.h"
#include "ilo_cp.h"
#include "ilo_context.h"
@@ -266,6 +267,35 @@ ilo_transfer_inline_write(struct pipe_context *pipe,
}
static void
+transfer_unmap_sys_convert(enum pipe_format dst_fmt,
+ const struct pipe_transfer *dst_xfer,
+ void *dst,
+ enum pipe_format src_fmt,
+ const struct pipe_transfer *src_xfer,
+ const void *src)
+{
+ int i;
+
+ switch (src_fmt) {
+ case PIPE_FORMAT_ETC1_RGB8:
+ assert(dst_fmt == PIPE_FORMAT_R8G8B8X8_UNORM);
+
+ for (i = 0; i < dst_xfer->box.depth; i++) {
+ util_format_etc1_rgb8_unpack_rgba_8unorm(dst,
+ dst_xfer->stride, src, src_xfer->stride,
+ dst_xfer->box.width, dst_xfer->box.height);
+
+ dst += dst_xfer->layer_stride;
+ src += src_xfer->layer_stride;
+ }
+ break;
+ default:
+ assert(!"unable to convert the staging data");
+ break;
+ }
+}
+
+static void
transfer_unmap_sys(struct ilo_context *ilo,
struct ilo_resource *res,
struct ilo_transfer *xfer)
@@ -286,10 +316,16 @@ transfer_unmap_sys(struct ilo_context *ilo,
return;
}
- util_copy_box(dst, res->bo_format,
- dst_xfer->stride, dst_xfer->layer_stride, 0, 0, 0,
- dst_xfer->box.width, dst_xfer->box.height, dst_xfer->box.depth,
- src, xfer->base.stride, xfer->base.layer_stride, 0, 0, 0);
+ if (likely(res->bo_format != res->base.format)) {
+ transfer_unmap_sys_convert(res->bo_format, dst_xfer, dst,
+ res->base.format, &xfer->base, src);
+ }
+ else {
+ util_copy_box(dst, res->bo_format,
+ dst_xfer->stride, dst_xfer->layer_stride, 0, 0, 0,
+ dst_xfer->box.width, dst_xfer->box.height, dst_xfer->box.depth,
+ src, xfer->base.stride, xfer->base.layer_stride, 0, 0, 0);
+ }
ilo->base.transfer_unmap(&ilo->base, dst_xfer);
FREE(xfer->staging_sys);
@@ -406,6 +442,14 @@ transfer_map_choose_method(struct ilo_context *ilo,
{
bool will_be_busy, will_stall;
+ /* need to convert on-the-fly */
+ if (res->bo_format != res->base.format &&
+ !(xfer->base.usage & PIPE_TRANSFER_MAP_DIRECTLY)) {
+ xfer->method = ILO_TRANSFER_MAP_STAGING_SYS;
+
+ return true;
+ }
+
xfer->method = ILO_TRANSFER_MAP_DIRECT;
/* unsynchronized map does not stall */
@@ -1220,7 +1264,14 @@ init_texture(struct ilo_resource *res)
{
struct layout_tex_info info;
- res->bo_format = res->base.format;
+ switch (res->base.format) {
+ case PIPE_FORMAT_ETC1_RGB8:
+ res->bo_format = PIPE_FORMAT_R8G8B8X8_UNORM;
+ break;
+ default:
+ res->bo_format = res->base.format;
+ break;
+ }
/* determine tiling first as it may affect the layout */
res->tiling = get_tex_tiling(res);