diff options
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.c | 1 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.h | 22 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state_common.c | 451 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_texture.c | 454 |
4 files changed, 461 insertions, 467 deletions
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 67767d4b449..dfe78b93a71 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -388,7 +388,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void r600_init_blit_functions(rctx); r600_init_query_functions(rctx); r600_init_context_resource_functions(rctx); - r600_init_surface_functions(rctx); if (rscreen->b.info.has_uvd) { rctx->b.b.create_video_codec = r600_uvd_create_decoder; diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index b00b838db98..36132f26ea8 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -719,18 +719,6 @@ void r600_update_db_shader_control(struct r600_context * rctx); /* r600_texture.c */ void r600_init_screen_texture_functions(struct pipe_screen *screen); -void r600_init_surface_functions(struct r600_context *r600); -uint32_t r600_translate_texformat(struct pipe_screen *screen, enum pipe_format format, - const unsigned char *swizzle_view, - uint32_t *word4_p, uint32_t *yuv_format_p); -struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe, - struct pipe_resource *texture, - const struct pipe_surface *templ, - unsigned width, unsigned height); - -unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format, - const unsigned char *swizzle_view, - boolean vtx); /* r600_hw_context.c */ void r600_get_backend_mask(struct r600_context *ctx); @@ -810,6 +798,16 @@ unsigned r600_tex_filter(unsigned filter); unsigned r600_tex_mipfilter(unsigned filter); unsigned r600_tex_compare(unsigned compare); bool sampler_state_needs_border_color(const struct pipe_sampler_state *state); +struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe, + struct pipe_resource *texture, + const struct pipe_surface *templ, + unsigned width, unsigned height); +unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format, + const unsigned char *swizzle_view, + boolean vtx); +uint32_t r600_translate_texformat(struct pipe_screen *screen, enum pipe_format format, + const unsigned char *swizzle_view, + uint32_t *word4_p, uint32_t *yuv_format_p); /* r600_uvd.c */ struct pipe_video_codec *r600_uvd_create_decoder(struct pipe_context *context, diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 2297377e089..7371bd611c4 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -29,6 +29,7 @@ #include "r600d.h" #include "util/u_draw_quad.h" +#include "util/u_format_s3tc.h" #include "util/u_index_modify.h" #include "util/u_memory.h" #include "util/u_upload_mgr.h" @@ -1628,6 +1629,454 @@ void r600_emit_shader(struct r600_context *rctx, struct r600_atom *a) radeon_emit(cs, r600_context_bo_reloc(&rctx->b, &rctx->b.rings.gfx, shader->bo, RADEON_USAGE_READ)); } +struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe, + struct pipe_resource *texture, + const struct pipe_surface *templ, + unsigned width, unsigned height) +{ + struct r600_surface *surface = CALLOC_STRUCT(r600_surface); + + assert(templ->u.tex.first_layer <= util_max_layer(texture, templ->u.tex.level)); + assert(templ->u.tex.last_layer <= util_max_layer(texture, templ->u.tex.level)); + assert(templ->u.tex.first_layer == templ->u.tex.last_layer); + if (surface == NULL) + return NULL; + pipe_reference_init(&surface->base.reference, 1); + pipe_resource_reference(&surface->base.texture, texture); + surface->base.context = pipe; + surface->base.format = templ->format; + surface->base.width = width; + surface->base.height = height; + surface->base.u = templ->u; + return &surface->base; +} + +static struct pipe_surface *r600_create_surface(struct pipe_context *pipe, + struct pipe_resource *tex, + const struct pipe_surface *templ) +{ + unsigned level = templ->u.tex.level; + + return r600_create_surface_custom(pipe, tex, templ, + u_minify(tex->width0, level), + u_minify(tex->height0, level)); +} + +static void r600_surface_destroy(struct pipe_context *pipe, + struct pipe_surface *surface) +{ + struct r600_surface *surf = (struct r600_surface*)surface; + pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_fmask, NULL); + pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_cmask, NULL); + pipe_resource_reference(&surface->texture, NULL); + FREE(surface); +} + +unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format, + const unsigned char *swizzle_view, + boolean vtx) +{ + unsigned i; + unsigned char swizzle[4]; + unsigned result = 0; + const uint32_t tex_swizzle_shift[4] = { + 16, 19, 22, 25, + }; + const uint32_t vtx_swizzle_shift[4] = { + 3, 6, 9, 12, + }; + const uint32_t swizzle_bit[4] = { + 0, 1, 2, 3, + }; + const uint32_t *swizzle_shift = tex_swizzle_shift; + + if (vtx) + swizzle_shift = vtx_swizzle_shift; + + if (swizzle_view) { + util_format_compose_swizzles(swizzle_format, swizzle_view, swizzle); + } else { + memcpy(swizzle, swizzle_format, 4); + } + + /* Get swizzle. */ + for (i = 0; i < 4; i++) { + switch (swizzle[i]) { + case UTIL_FORMAT_SWIZZLE_Y: + result |= swizzle_bit[1] << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_Z: + result |= swizzle_bit[2] << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_W: + result |= swizzle_bit[3] << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_0: + result |= V_038010_SQ_SEL_0 << swizzle_shift[i]; + break; + case UTIL_FORMAT_SWIZZLE_1: + result |= V_038010_SQ_SEL_1 << swizzle_shift[i]; + break; + default: /* UTIL_FORMAT_SWIZZLE_X */ + result |= swizzle_bit[0] << swizzle_shift[i]; + } + } + return result; +} + +/* texture format translate */ +uint32_t r600_translate_texformat(struct pipe_screen *screen, + enum pipe_format format, + const unsigned char *swizzle_view, + uint32_t *word4_p, uint32_t *yuv_format_p) +{ + struct r600_screen *rscreen = (struct r600_screen *)screen; + uint32_t result = 0, word4 = 0, yuv_format = 0; + const struct util_format_description *desc; + boolean uniform = TRUE; + bool enable_s3tc = rscreen->b.info.drm_minor >= 9; + bool is_srgb_valid = FALSE; + const unsigned char swizzle_xxxx[4] = {0, 0, 0, 0}; + const unsigned char swizzle_yyyy[4] = {1, 1, 1, 1}; + + int i; + const uint32_t sign_bit[4] = { + S_038010_FORMAT_COMP_X(V_038010_SQ_FORMAT_COMP_SIGNED), + S_038010_FORMAT_COMP_Y(V_038010_SQ_FORMAT_COMP_SIGNED), + S_038010_FORMAT_COMP_Z(V_038010_SQ_FORMAT_COMP_SIGNED), + S_038010_FORMAT_COMP_W(V_038010_SQ_FORMAT_COMP_SIGNED) + }; + desc = util_format_description(format); + + /* Depth and stencil swizzling is handled separately. */ + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) { + word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view, FALSE); + } + + /* Colorspace (return non-RGB formats directly). */ + switch (desc->colorspace) { + /* Depth stencil formats */ + case UTIL_FORMAT_COLORSPACE_ZS: + switch (format) { + /* Depth sampler formats. */ + case PIPE_FORMAT_Z16_UNORM: + word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); + result = FMT_16; + goto out_word4; + case PIPE_FORMAT_Z24X8_UNORM: + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); + result = FMT_8_24; + goto out_word4; + case PIPE_FORMAT_X8Z24_UNORM: + case PIPE_FORMAT_S8_UINT_Z24_UNORM: + if (rscreen->b.chip_class < EVERGREEN) + goto out_unknown; + word4 |= r600_get_swizzle_combined(swizzle_yyyy, swizzle_view, FALSE); + result = FMT_24_8; + goto out_word4; + case PIPE_FORMAT_Z32_FLOAT: + word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); + result = FMT_32_FLOAT; + goto out_word4; + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); + result = FMT_X24_8_32_FLOAT; + goto out_word4; + /* Stencil sampler formats. */ + case PIPE_FORMAT_S8_UINT: + word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); + word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); + result = FMT_8; + goto out_word4; + case PIPE_FORMAT_X24S8_UINT: + word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); + word4 |= r600_get_swizzle_combined(swizzle_yyyy, swizzle_view, FALSE); + result = FMT_8_24; + goto out_word4; + case PIPE_FORMAT_S8X24_UINT: + if (rscreen->b.chip_class < EVERGREEN) + goto out_unknown; + word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); + word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); + result = FMT_24_8; + goto out_word4; + case PIPE_FORMAT_X32_S8X24_UINT: + word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); + word4 |= r600_get_swizzle_combined(swizzle_yyyy, swizzle_view, FALSE); + result = FMT_X24_8_32_FLOAT; + goto out_word4; + default: + goto out_unknown; + } + + case UTIL_FORMAT_COLORSPACE_YUV: + yuv_format |= (1 << 30); + switch (format) { + case PIPE_FORMAT_UYVY: + case PIPE_FORMAT_YUYV: + default: + break; + } + goto out_unknown; /* XXX */ + + case UTIL_FORMAT_COLORSPACE_SRGB: + word4 |= S_038010_FORCE_DEGAMMA(1); + break; + + default: + break; + } + + if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) { + if (!enable_s3tc) + goto out_unknown; + + switch (format) { + case PIPE_FORMAT_RGTC1_SNORM: + case PIPE_FORMAT_LATC1_SNORM: + word4 |= sign_bit[0]; + case PIPE_FORMAT_RGTC1_UNORM: + case PIPE_FORMAT_LATC1_UNORM: + result = FMT_BC4; + goto out_word4; + case PIPE_FORMAT_RGTC2_SNORM: + case PIPE_FORMAT_LATC2_SNORM: + word4 |= sign_bit[0] | sign_bit[1]; + case PIPE_FORMAT_RGTC2_UNORM: + case PIPE_FORMAT_LATC2_UNORM: + result = FMT_BC5; + goto out_word4; + default: + goto out_unknown; + } + } + + if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { + + if (!enable_s3tc) + goto out_unknown; + + if (!util_format_s3tc_enabled) { + goto out_unknown; + } + + switch (format) { + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT1_SRGB: + case PIPE_FORMAT_DXT1_SRGBA: + result = FMT_BC1; + is_srgb_valid = TRUE; + goto out_word4; + case PIPE_FORMAT_DXT3_RGBA: + case PIPE_FORMAT_DXT3_SRGBA: + result = FMT_BC2; + is_srgb_valid = TRUE; + goto out_word4; + case PIPE_FORMAT_DXT5_RGBA: + case PIPE_FORMAT_DXT5_SRGBA: + result = FMT_BC3; + is_srgb_valid = TRUE; + goto out_word4; + default: + goto out_unknown; + } + } + + if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) { + switch (format) { + case PIPE_FORMAT_R8G8_B8G8_UNORM: + case PIPE_FORMAT_G8R8_B8R8_UNORM: + result = FMT_GB_GR; + goto out_word4; + case PIPE_FORMAT_G8R8_G8B8_UNORM: + case PIPE_FORMAT_R8G8_R8B8_UNORM: + result = FMT_BG_RG; + goto out_word4; + default: + goto out_unknown; + } + } + + if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) { + result = FMT_5_9_9_9_SHAREDEXP; + goto out_word4; + } else if (format == PIPE_FORMAT_R11G11B10_FLOAT) { + result = FMT_10_11_11_FLOAT; + goto out_word4; + } + + + for (i = 0; i < desc->nr_channels; i++) { + if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { + word4 |= sign_bit[i]; + } + } + + /* R8G8Bx_SNORM - XXX CxV8U8 */ + + /* See whether the components are of the same size. */ + for (i = 1; i < desc->nr_channels; i++) { + uniform = uniform && desc->channel[0].size == desc->channel[i].size; + } + + /* Non-uniform formats. */ + if (!uniform) { + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB && + desc->channel[0].pure_integer) + word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); + switch(desc->nr_channels) { + case 3: + if (desc->channel[0].size == 5 && + desc->channel[1].size == 6 && + desc->channel[2].size == 5) { + result = FMT_5_6_5; + goto out_word4; + } + goto out_unknown; + case 4: + if (desc->channel[0].size == 5 && + desc->channel[1].size == 5 && + desc->channel[2].size == 5 && + desc->channel[3].size == 1) { + result = FMT_1_5_5_5; + goto out_word4; + } + if (desc->channel[0].size == 10 && + desc->channel[1].size == 10 && + desc->channel[2].size == 10 && + desc->channel[3].size == 2) { + result = FMT_2_10_10_10; + goto out_word4; + } + goto out_unknown; + } + goto out_unknown; + } + + /* Find the first non-VOID channel. */ + for (i = 0; i < 4; i++) { + if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { + break; + } + } + + if (i == 4) + goto out_unknown; + + /* uniform formats */ + switch (desc->channel[i].type) { + case UTIL_FORMAT_TYPE_UNSIGNED: + case UTIL_FORMAT_TYPE_SIGNED: +#if 0 + if (!desc->channel[i].normalized && + desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) { + goto out_unknown; + } +#endif + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB && + desc->channel[i].pure_integer) + word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); + + switch (desc->channel[i].size) { + case 4: + switch (desc->nr_channels) { + case 2: + result = FMT_4_4; + goto out_word4; + case 4: + result = FMT_4_4_4_4; + goto out_word4; + } + goto out_unknown; + case 8: + switch (desc->nr_channels) { + case 1: + result = FMT_8; + goto out_word4; + case 2: + result = FMT_8_8; + goto out_word4; + case 4: + result = FMT_8_8_8_8; + is_srgb_valid = TRUE; + goto out_word4; + } + goto out_unknown; + case 16: + switch (desc->nr_channels) { + case 1: + result = FMT_16; + goto out_word4; + case 2: + result = FMT_16_16; + goto out_word4; + case 4: + result = FMT_16_16_16_16; + goto out_word4; + } + goto out_unknown; + case 32: + switch (desc->nr_channels) { + case 1: + result = FMT_32; + goto out_word4; + case 2: + result = FMT_32_32; + goto out_word4; + case 4: + result = FMT_32_32_32_32; + goto out_word4; + } + } + goto out_unknown; + + case UTIL_FORMAT_TYPE_FLOAT: + switch (desc->channel[i].size) { + case 16: + switch (desc->nr_channels) { + case 1: + result = FMT_16_FLOAT; + goto out_word4; + case 2: + result = FMT_16_16_FLOAT; + goto out_word4; + case 4: + result = FMT_16_16_16_16_FLOAT; + goto out_word4; + } + goto out_unknown; + case 32: + switch (desc->nr_channels) { + case 1: + result = FMT_32_FLOAT; + goto out_word4; + case 2: + result = FMT_32_32_FLOAT; + goto out_word4; + case 4: + result = FMT_32_32_32_32_FLOAT; + goto out_word4; + } + } + goto out_unknown; + } + +out_word4: + + if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB && !is_srgb_valid) + return ~0; + if (word4_p) + *word4_p = word4; + if (yuv_format_p) + *yuv_format_p = yuv_format; + return result; +out_unknown: + /* R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); */ + return ~0; +} + /* keep this at the end of this file, please */ void r600_init_common_state_functions(struct r600_context *rctx) { @@ -1662,6 +2111,8 @@ void r600_init_common_state_functions(struct r600_context *rctx) rctx->b.b.sampler_view_destroy = r600_sampler_view_destroy; rctx->b.b.texture_barrier = r600_texture_barrier; rctx->b.b.set_stream_output_targets = r600_set_streamout_targets; + rctx->b.b.create_surface = r600_create_surface; + rctx->b.b.surface_destroy = r600_surface_destroy; rctx->b.b.draw_vbo = r600_draw_vbo; } diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 797506006f0..a86e4c91be8 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -642,49 +642,6 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, 0, NULL, &surface); } -struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe, - struct pipe_resource *texture, - const struct pipe_surface *templ, - unsigned width, unsigned height) -{ - struct r600_surface *surface = CALLOC_STRUCT(r600_surface); - - assert(templ->u.tex.first_layer <= util_max_layer(texture, templ->u.tex.level)); - assert(templ->u.tex.last_layer <= util_max_layer(texture, templ->u.tex.level)); - assert(templ->u.tex.first_layer == templ->u.tex.last_layer); - if (surface == NULL) - return NULL; - pipe_reference_init(&surface->base.reference, 1); - pipe_resource_reference(&surface->base.texture, texture); - surface->base.context = pipe; - surface->base.format = templ->format; - surface->base.width = width; - surface->base.height = height; - surface->base.u = templ->u; - return &surface->base; -} - -static struct pipe_surface *r600_create_surface(struct pipe_context *pipe, - struct pipe_resource *tex, - const struct pipe_surface *templ) -{ - unsigned level = templ->u.tex.level; - - return r600_create_surface_custom(pipe, tex, templ, - u_minify(tex->width0, level), - u_minify(tex->height0, level)); -} - -static void r600_surface_destroy(struct pipe_context *pipe, - struct pipe_surface *surface) -{ - struct r600_surface *surf = (struct r600_surface*)surface; - pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_fmask, NULL); - pipe_resource_reference((struct pipe_resource**)&surf->cb_buffer_cmask, NULL); - pipe_resource_reference(&surface->texture, NULL); - FREE(surface); -} - struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen, const struct pipe_resource *templ, struct winsys_handle *whandle) @@ -989,417 +946,6 @@ static void r600_texture_transfer_unmap(struct pipe_context *ctx, FREE(transfer); } -void r600_init_surface_functions(struct r600_context *r600) -{ - r600->b.b.create_surface = r600_create_surface; - r600->b.b.surface_destroy = r600_surface_destroy; -} - -unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format, - const unsigned char *swizzle_view, - boolean vtx) -{ - unsigned i; - unsigned char swizzle[4]; - unsigned result = 0; - const uint32_t tex_swizzle_shift[4] = { - 16, 19, 22, 25, - }; - const uint32_t vtx_swizzle_shift[4] = { - 3, 6, 9, 12, - }; - const uint32_t swizzle_bit[4] = { - 0, 1, 2, 3, - }; - const uint32_t *swizzle_shift = tex_swizzle_shift; - - if (vtx) - swizzle_shift = vtx_swizzle_shift; - - if (swizzle_view) { - util_format_compose_swizzles(swizzle_format, swizzle_view, swizzle); - } else { - memcpy(swizzle, swizzle_format, 4); - } - - /* Get swizzle. */ - for (i = 0; i < 4; i++) { - switch (swizzle[i]) { - case UTIL_FORMAT_SWIZZLE_Y: - result |= swizzle_bit[1] << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_Z: - result |= swizzle_bit[2] << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_W: - result |= swizzle_bit[3] << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_0: - result |= V_038010_SQ_SEL_0 << swizzle_shift[i]; - break; - case UTIL_FORMAT_SWIZZLE_1: - result |= V_038010_SQ_SEL_1 << swizzle_shift[i]; - break; - default: /* UTIL_FORMAT_SWIZZLE_X */ - result |= swizzle_bit[0] << swizzle_shift[i]; - } - } - return result; -} - -/* texture format translate */ -uint32_t r600_translate_texformat(struct pipe_screen *screen, - enum pipe_format format, - const unsigned char *swizzle_view, - uint32_t *word4_p, uint32_t *yuv_format_p) -{ - struct r600_screen *rscreen = (struct r600_screen *)screen; - uint32_t result = 0, word4 = 0, yuv_format = 0; - const struct util_format_description *desc; - boolean uniform = TRUE; - bool enable_s3tc = rscreen->b.info.drm_minor >= 9; - bool is_srgb_valid = FALSE; - const unsigned char swizzle_xxxx[4] = {0, 0, 0, 0}; - const unsigned char swizzle_yyyy[4] = {1, 1, 1, 1}; - - int i; - const uint32_t sign_bit[4] = { - S_038010_FORMAT_COMP_X(V_038010_SQ_FORMAT_COMP_SIGNED), - S_038010_FORMAT_COMP_Y(V_038010_SQ_FORMAT_COMP_SIGNED), - S_038010_FORMAT_COMP_Z(V_038010_SQ_FORMAT_COMP_SIGNED), - S_038010_FORMAT_COMP_W(V_038010_SQ_FORMAT_COMP_SIGNED) - }; - desc = util_format_description(format); - - /* Depth and stencil swizzling is handled separately. */ - if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) { - word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view, FALSE); - } - - /* Colorspace (return non-RGB formats directly). */ - switch (desc->colorspace) { - /* Depth stencil formats */ - case UTIL_FORMAT_COLORSPACE_ZS: - switch (format) { - /* Depth sampler formats. */ - case PIPE_FORMAT_Z16_UNORM: - word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); - result = FMT_16; - goto out_word4; - case PIPE_FORMAT_Z24X8_UNORM: - case PIPE_FORMAT_Z24_UNORM_S8_UINT: - word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); - result = FMT_8_24; - goto out_word4; - case PIPE_FORMAT_X8Z24_UNORM: - case PIPE_FORMAT_S8_UINT_Z24_UNORM: - if (rscreen->b.chip_class < EVERGREEN) - goto out_unknown; - word4 |= r600_get_swizzle_combined(swizzle_yyyy, swizzle_view, FALSE); - result = FMT_24_8; - goto out_word4; - case PIPE_FORMAT_Z32_FLOAT: - word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); - result = FMT_32_FLOAT; - goto out_word4; - case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: - word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); - result = FMT_X24_8_32_FLOAT; - goto out_word4; - /* Stencil sampler formats. */ - case PIPE_FORMAT_S8_UINT: - word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); - word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); - result = FMT_8; - goto out_word4; - case PIPE_FORMAT_X24S8_UINT: - word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); - word4 |= r600_get_swizzle_combined(swizzle_yyyy, swizzle_view, FALSE); - result = FMT_8_24; - goto out_word4; - case PIPE_FORMAT_S8X24_UINT: - if (rscreen->b.chip_class < EVERGREEN) - goto out_unknown; - word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); - word4 |= r600_get_swizzle_combined(swizzle_xxxx, swizzle_view, FALSE); - result = FMT_24_8; - goto out_word4; - case PIPE_FORMAT_X32_S8X24_UINT: - word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); - word4 |= r600_get_swizzle_combined(swizzle_yyyy, swizzle_view, FALSE); - result = FMT_X24_8_32_FLOAT; - goto out_word4; - default: - goto out_unknown; - } - - case UTIL_FORMAT_COLORSPACE_YUV: - yuv_format |= (1 << 30); - switch (format) { - case PIPE_FORMAT_UYVY: - case PIPE_FORMAT_YUYV: - default: - break; - } - goto out_unknown; /* XXX */ - - case UTIL_FORMAT_COLORSPACE_SRGB: - word4 |= S_038010_FORCE_DEGAMMA(1); - break; - - default: - break; - } - - if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) { - if (!enable_s3tc) - goto out_unknown; - - switch (format) { - case PIPE_FORMAT_RGTC1_SNORM: - case PIPE_FORMAT_LATC1_SNORM: - word4 |= sign_bit[0]; - case PIPE_FORMAT_RGTC1_UNORM: - case PIPE_FORMAT_LATC1_UNORM: - result = FMT_BC4; - goto out_word4; - case PIPE_FORMAT_RGTC2_SNORM: - case PIPE_FORMAT_LATC2_SNORM: - word4 |= sign_bit[0] | sign_bit[1]; - case PIPE_FORMAT_RGTC2_UNORM: - case PIPE_FORMAT_LATC2_UNORM: - result = FMT_BC5; - goto out_word4; - default: - goto out_unknown; - } - } - - if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { - - if (!enable_s3tc) - goto out_unknown; - - if (!util_format_s3tc_enabled) { - goto out_unknown; - } - - switch (format) { - case PIPE_FORMAT_DXT1_RGB: - case PIPE_FORMAT_DXT1_RGBA: - case PIPE_FORMAT_DXT1_SRGB: - case PIPE_FORMAT_DXT1_SRGBA: - result = FMT_BC1; - is_srgb_valid = TRUE; - goto out_word4; - case PIPE_FORMAT_DXT3_RGBA: - case PIPE_FORMAT_DXT3_SRGBA: - result = FMT_BC2; - is_srgb_valid = TRUE; - goto out_word4; - case PIPE_FORMAT_DXT5_RGBA: - case PIPE_FORMAT_DXT5_SRGBA: - result = FMT_BC3; - is_srgb_valid = TRUE; - goto out_word4; - default: - goto out_unknown; - } - } - - if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) { - switch (format) { - case PIPE_FORMAT_R8G8_B8G8_UNORM: - case PIPE_FORMAT_G8R8_B8R8_UNORM: - result = FMT_GB_GR; - goto out_word4; - case PIPE_FORMAT_G8R8_G8B8_UNORM: - case PIPE_FORMAT_R8G8_R8B8_UNORM: - result = FMT_BG_RG; - goto out_word4; - default: - goto out_unknown; - } - } - - if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) { - result = FMT_5_9_9_9_SHAREDEXP; - goto out_word4; - } else if (format == PIPE_FORMAT_R11G11B10_FLOAT) { - result = FMT_10_11_11_FLOAT; - goto out_word4; - } - - - for (i = 0; i < desc->nr_channels; i++) { - if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { - word4 |= sign_bit[i]; - } - } - - /* R8G8Bx_SNORM - XXX CxV8U8 */ - - /* See whether the components are of the same size. */ - for (i = 1; i < desc->nr_channels; i++) { - uniform = uniform && desc->channel[0].size == desc->channel[i].size; - } - - /* Non-uniform formats. */ - if (!uniform) { - if (desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB && - desc->channel[0].pure_integer) - word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); - switch(desc->nr_channels) { - case 3: - if (desc->channel[0].size == 5 && - desc->channel[1].size == 6 && - desc->channel[2].size == 5) { - result = FMT_5_6_5; - goto out_word4; - } - goto out_unknown; - case 4: - if (desc->channel[0].size == 5 && - desc->channel[1].size == 5 && - desc->channel[2].size == 5 && - desc->channel[3].size == 1) { - result = FMT_1_5_5_5; - goto out_word4; - } - if (desc->channel[0].size == 10 && - desc->channel[1].size == 10 && - desc->channel[2].size == 10 && - desc->channel[3].size == 2) { - result = FMT_2_10_10_10; - goto out_word4; - } - goto out_unknown; - } - goto out_unknown; - } - - /* Find the first non-VOID channel. */ - for (i = 0; i < 4; i++) { - if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { - break; - } - } - - if (i == 4) - goto out_unknown; - - /* uniform formats */ - switch (desc->channel[i].type) { - case UTIL_FORMAT_TYPE_UNSIGNED: - case UTIL_FORMAT_TYPE_SIGNED: -#if 0 - if (!desc->channel[i].normalized && - desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) { - goto out_unknown; - } -#endif - if (desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB && - desc->channel[i].pure_integer) - word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); - - switch (desc->channel[i].size) { - case 4: - switch (desc->nr_channels) { - case 2: - result = FMT_4_4; - goto out_word4; - case 4: - result = FMT_4_4_4_4; - goto out_word4; - } - goto out_unknown; - case 8: - switch (desc->nr_channels) { - case 1: - result = FMT_8; - goto out_word4; - case 2: - result = FMT_8_8; - goto out_word4; - case 4: - result = FMT_8_8_8_8; - is_srgb_valid = TRUE; - goto out_word4; - } - goto out_unknown; - case 16: - switch (desc->nr_channels) { - case 1: - result = FMT_16; - goto out_word4; - case 2: - result = FMT_16_16; - goto out_word4; - case 4: - result = FMT_16_16_16_16; - goto out_word4; - } - goto out_unknown; - case 32: - switch (desc->nr_channels) { - case 1: - result = FMT_32; - goto out_word4; - case 2: - result = FMT_32_32; - goto out_word4; - case 4: - result = FMT_32_32_32_32; - goto out_word4; - } - } - goto out_unknown; - - case UTIL_FORMAT_TYPE_FLOAT: - switch (desc->channel[i].size) { - case 16: - switch (desc->nr_channels) { - case 1: - result = FMT_16_FLOAT; - goto out_word4; - case 2: - result = FMT_16_16_FLOAT; - goto out_word4; - case 4: - result = FMT_16_16_16_16_FLOAT; - goto out_word4; - } - goto out_unknown; - case 32: - switch (desc->nr_channels) { - case 1: - result = FMT_32_FLOAT; - goto out_word4; - case 2: - result = FMT_32_32_FLOAT; - goto out_word4; - case 4: - result = FMT_32_32_32_32_FLOAT; - goto out_word4; - } - } - goto out_unknown; - } - -out_word4: - - if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB && !is_srgb_valid) - return ~0; - if (word4_p) - *word4_p = word4; - if (yuv_format_p) - *yuv_format_p = yuv_format; - return result; -out_unknown: - /* R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); */ - return ~0; -} - static const struct u_resource_vtbl r600_texture_vtbl = { r600_texture_get_handle, /* get_handle */ |