summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c1
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h22
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c451
-rw-r--r--src/gallium/drivers/r600/r600_texture.c454
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 */