From a8e46140718b85fd33be97c693050f8722db1def Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 9 May 2013 15:14:11 +0800 Subject: ilo: add support for PIPE_FORMAT_ETC1_RGB8 It is decompressed to and stored as PIPE_FORMAT_R8G8B8X8_UNORM on-the-fly. --- src/gallium/drivers/ilo/ilo_format.h | 5 +++ src/gallium/drivers/ilo/ilo_resource.c | 61 +++++++++++++++++++++++++++++++--- 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" @@ -265,6 +266,35 @@ ilo_transfer_inline_write(struct pipe_context *pipe, res->bo->pwrite(res->bo, offset, size, data); } +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, @@ -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); -- cgit v1.2.3