r600g: move r600g-specific functions out of r600_texture.c

This commit is contained in:
Marek Olšák 2013-09-21 20:50:33 +02:00
parent bfea9c498d
commit 6f21009cb3
4 changed files with 461 additions and 467 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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;
}

View File

@ -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 */