Make the Gallium r300 works on big-endian architectures.

Diff provided by Michel Daenzer [0] as a possible solution for a
regression introduced in Mesa 9 [1].  This diff allows macppc
users to use OpenGL accelerated appplications (i.e. GNOME3).

As disucssed during c2k15 we won't try to keep this patch during
the next Mesa update.

[0] https://bugs.freedesktop.org/show_bug.cgi?id=71789
[1] http://lists.freedesktop.org/archives/mesa-dev/2013-December/050218.html

Tested by myself and ajacoutot@, regression test and ok jsg@
This commit is contained in:
mpi 2015-07-29 05:47:25 +00:00
parent 3ee4d65134
commit e5e91e484f
9 changed files with 91 additions and 31 deletions

View File

@ -185,7 +185,9 @@ static void r300_set_clear_color(struct r300_context *r300,
union util_color uc;
memset(&uc, 0, sizeof(uc));
util_pack_color(color->f, fb->cbufs[0]->format, &uc);
util_pack_color(color->f,
r300_get_hw_format(fb->cbufs[0]->format, PIPE_BIND_RENDER_TARGET),
&uc);
if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16X16_FLOAT) {

View File

@ -45,6 +45,8 @@ struct r300_vertex_shader;
struct r300_stencilref_context;
enum colormask_swizzle {
COLORMASK_ARGB,
COLORMASK_XRGB,
COLORMASK_BGRA,
COLORMASK_RGBA,
COLORMASK_RRRR,

View File

@ -225,6 +225,12 @@ static unsigned blend_discard_conditionally(unsigned eqRGB, unsigned eqA,
/* The hardware colormask is clunky a must be swizzled depending on the format.
* This was figured out by trial-and-error. */
static unsigned argb_cmask(unsigned mask)
{
return ((mask & (PIPE_MASK_R | PIPE_MASK_G | PIPE_MASK_B)) << 1) |
((mask & PIPE_MASK_A) >> 3);
}
static unsigned bgra_cmask(unsigned mask)
{
return ((mask & PIPE_MASK_R) << 2) |
@ -471,6 +477,8 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
/* Build a command buffer. */
{
unsigned (*func[COLORMASK_NUM_SWIZZLES])(unsigned) = {
argb_cmask,
argb_cmask,
bgra_cmask,
rgba_cmask,
rrrr_cmask,
@ -482,7 +490,8 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
};
for (i = 0; i < COLORMASK_NUM_SWIZZLES; i++) {
boolean has_alpha = i != COLORMASK_RGBX && i != COLORMASK_BGRX;
boolean has_alpha = i != COLORMASK_RGBX && i != COLORMASK_BGRX &&
i != COLORMASK_XRGB;
BEGIN_CB(blend->cb_clamp[i], 8);
OUT_CB_REG(R300_RB3D_ROPCNTL, rop);
@ -1667,6 +1676,7 @@ r300_create_sampler_view_custom(struct pipe_context *pipe,
boolean dxtc_swizzle = r300_screen(pipe->screen)->caps.dxtc_swizzle;
if (view) {
enum pipe_format format = r300_get_hw_format(templ->format, texture->bind);
unsigned hwformat;
view->base = *templ;
@ -1682,24 +1692,24 @@ r300_create_sampler_view_custom(struct pipe_context *pipe,
view->swizzle[2] = templ->swizzle_b;
view->swizzle[3] = templ->swizzle_a;
hwformat = r300_translate_texformat(templ->format,
hwformat = r300_translate_texformat(format,
view->swizzle,
is_r500,
dxtc_swizzle);
if (hwformat == ~0) {
fprintf(stderr, "r300: Ooops. Got unsupported format %s in %s.\n",
util_format_short_name(templ->format), __func__);
util_format_short_name(format), __func__);
}
assert(hwformat != ~0);
r300_texture_setup_format_state(r300_screen(pipe->screen), tex,
templ->format, 0,
format, 0,
width0_override, height0_override,
&view->format);
view->format.format1 |= hwformat;
if (is_r500) {
view->format.format2 |= r500_tx_format_msb_bit(templ->format);
view->format.format2 |= r500_tx_format_msb_bit(format);
}
}

View File

@ -815,9 +815,12 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
for (i = 0; i < count; i++) {
if (state->sampler_views[i] && state->sampler_states[i]) {
enum pipe_format format;
state->tx_enable |= 1 << i;
view = state->sampler_views[i];
format = r300_get_hw_format(view->base.format, view->base.texture->bind);
tex = r300_resource(view->base.texture);
sampler = state->sampler_states[i];
@ -828,7 +831,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
/* Set the border color. */
texstate->border_color =
r300_get_border_color(view->base.format,
r300_get_border_color(format,
sampler->state.border_color.f,
r300->screen->caps.is_r500);
@ -852,7 +855,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
offset = tex->tex.offset_in_bytes[base_level];
r300_texture_setup_format_state(r300->screen, tex,
view->base.format,
format,
base_level,
view->width0_override,
view->height0_override,
@ -865,11 +868,11 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
texstate->format.format1 |= view->texcache_region;
/* Depth textures are kinda special. */
if (util_format_is_depth_or_stencil(view->base.format)) {
if (util_format_is_depth_or_stencil(format)) {
unsigned char depth_swizzle[4];
if (!r300->screen->caps.is_r500 &&
util_format_get_blocksizebits(view->base.format) == 32) {
util_format_get_blocksizebits(format) == 32) {
/* X24x8 is sampled as Y16X16 on r3xx-r4xx.
* The depth here is at the Y component. */
for (j = 0; j < 4; j++)
@ -894,7 +897,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
}
if (r300->screen->caps.dxtc_swizzle &&
util_format_is_compressed(view->base.format)) {
util_format_is_compressed(format)) {
texstate->filter1 |= R400_DXTC_SWIZZLE_ENABLE;
}
@ -940,7 +943,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
}
/* Float textures only support nearest and mip-nearest filtering. */
if (util_format_is_float(view->base.format)) {
if (util_format_is_float(format)) {
/* No MAG linear filtering. */
if ((texstate->filter0 & R300_TX_MAG_FILTER_MASK) ==
R300_TX_MAG_FILTER_LINEAR) {

View File

@ -90,6 +90,25 @@ unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
return result;
}
enum pipe_format r300_get_hw_format(enum pipe_format api_format,
unsigned bind)
{
if (bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_SHARED) &&
!(bind & (PIPE_BIND_TRANSFER_READ | PIPE_BIND_TRANSFER_WRITE))) {
switch (api_format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
return PIPE_FORMAT_B8G8R8A8_UNORM;
case PIPE_FORMAT_X8R8G8B8_UNORM:
return PIPE_FORMAT_B8G8R8X8_UNORM;
default:
break;
}
}
return api_format;
}
/* Translate a pipe_format into a useful texture format for sampling.
*
* Some special formats are translated directly using R300_EASY_TX_FORMAT,
@ -444,10 +463,14 @@ static uint32_t r300_translate_colorformat(enum pipe_format format)
return R300_COLOR_FORMAT_ARGB4444;
/* 32-bit buffers. */
case PIPE_FORMAT_A8R8G8B8_UNORM:
/*case PIPE_FORMAT_A8R8G8B8_SNORM:*/
case PIPE_FORMAT_B8G8R8A8_UNORM:
/*case PIPE_FORMAT_B8G8R8A8_SNORM:*/
case PIPE_FORMAT_B8G8R8X8_UNORM:
/*case PIPE_FORMAT_B8G8R8X8_SNORM:*/
case PIPE_FORMAT_X8R8G8B8_UNORM:
/*case PIPE_FORMAT_X8R8G8B8_SNORM:*/
case PIPE_FORMAT_R8G8B8A8_UNORM:
case PIPE_FORMAT_R8G8B8A8_SNORM:
case PIPE_FORMAT_R8G8B8X8_UNORM:
@ -667,6 +690,10 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
R300_C2_SEL_R | R300_C3_SEL_A;
/* ARGB outputs. */
case PIPE_FORMAT_X8R8G8B8_UNORM:
/*case PIPE_FORMAT_X8R8G8B8_SNORM:*/
case PIPE_FORMAT_A8R8G8B8_UNORM:
/*case PIPE_FORMAT_A8R8G8B8_SNORM:*/
case PIPE_FORMAT_A16_UNORM:
case PIPE_FORMAT_A16_SNORM:
case PIPE_FORMAT_A16_FLOAT:
@ -770,6 +797,14 @@ static uint32_t r300_translate_colormask_swizzle(enum pipe_format format)
case PIPE_FORMAT_R32G32_FLOAT:
return COLORMASK_GRRG;
case PIPE_FORMAT_A8R8G8B8_UNORM:
/*case PIPE_FORMAT_A8R8G8B8_SNORM:*/
return COLORMASK_ARGB;
case PIPE_FORMAT_X8R8G8B8_UNORM:
/*case PIPE_FORMAT_X8R8G8B8_SNORM:*/
return COLORMASK_XRGB;
case PIPE_FORMAT_B5G5R5X1_UNORM:
case PIPE_FORMAT_B4G4R4X4_UNORM:
case PIPE_FORMAT_B8G8R8X8_UNORM:
@ -936,14 +971,17 @@ static void r300_texture_setup_fb_state(struct r300_surface *surf)
surf->pitch_zmask = tex->tex.zmask_stride_in_pixels[level];
surf->pitch_hiz = tex->tex.hiz_stride_in_pixels[level];
} else {
enum pipe_format hwformat = r300_get_hw_format(surf->base.format,
surf->base.texture->bind);
surf->pitch =
stride |
r300_translate_colorformat(surf->base.format) |
r300_translate_colorformat(hwformat) |
R300_COLOR_TILE(tex->tex.macrotile[level]) |
R300_COLOR_MICROTILE(tex->tex.microtile);
surf->format = r300_translate_out_fmt(surf->base.format);
surf->format = r300_translate_out_fmt(hwformat);
surf->colormask_swizzle =
r300_translate_colormask_swizzle(surf->base.format);
r300_translate_colormask_swizzle(hwformat);
surf->pitch_cmask = tex->tex.cmask_stride_in_pixels;
}
}

View File

@ -39,6 +39,9 @@ unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
const unsigned char *swizzle_view,
boolean dxtc_swizzle);
enum pipe_format r300_get_hw_format(enum pipe_format api_format,
unsigned bind);
uint32_t r300_translate_texformat(enum pipe_format format,
const unsigned char *swizzle_view,
boolean is_r500,

View File

@ -22,6 +22,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "r300_transfer.h"
#include "r300_texture.h"
#include "r300_texture_desc.h"
#include "r300_screen_buffer.h"
@ -110,8 +111,8 @@ r300_texture_transfer_map(struct pipe_context *ctx,
struct r300_context *r300 = r300_context(ctx);
struct r300_resource *tex = r300_resource(texture);
struct r300_transfer *trans;
enum pipe_format format = texture->format;
boolean referenced_cs, referenced_hw;
enum pipe_format format = tex->b.b.format;
char *map;
referenced_cs =
@ -135,8 +136,9 @@ r300_texture_transfer_map(struct pipe_context *ctx,
* for this transfer.
* Also make write transfers pipelined. */
if (tex->tex.microtile || tex->tex.macrotile[level] ||
r300_get_hw_format(format, texture->bind) != format ||
(referenced_hw && !(usage & PIPE_TRANSFER_READ) &&
r300_is_blit_supported(texture->format))) {
r300_is_blit_supported(format))) {
struct pipe_resource base;
if (r300->blitter->running) {

View File

@ -231,11 +231,11 @@ dri_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
if (format == __DRI_TEXTURE_FORMAT_RGB) {
/* only need to cover the formats recognized by dri_fill_st_visual */
switch (internal_format) {
case PIPE_FORMAT_B8G8R8A8_UNORM:
internal_format = PIPE_FORMAT_B8G8R8X8_UNORM;
case PIPE_FORMAT_BGRA8888_UNORM:
internal_format = PIPE_FORMAT_BGRX8888_UNORM;
break;
case PIPE_FORMAT_A8R8G8B8_UNORM:
internal_format = PIPE_FORMAT_X8R8G8B8_UNORM;
case PIPE_FORMAT_ARGB8888_UNORM:
internal_format = PIPE_FORMAT_XRGB8888_UNORM;
break;
default:
break;

View File

@ -162,10 +162,10 @@ dri2_drawable_get_buffers(struct dri_drawable *drawable,
* may occur as the stvis->color_format.
*/
switch(format) {
case PIPE_FORMAT_B8G8R8A8_UNORM:
case PIPE_FORMAT_BGRA8888_UNORM:
depth = 32;
break;
case PIPE_FORMAT_B8G8R8X8_UNORM:
case PIPE_FORMAT_BGRX8888_UNORM:
depth = 24;
break;
case PIPE_FORMAT_B5G6R5_UNORM:
@ -444,10 +444,10 @@ dri2_allocate_buffer(__DRIscreen *sPriv,
switch (format) {
case 32:
pf = PIPE_FORMAT_B8G8R8A8_UNORM;
pf = PIPE_FORMAT_BGRA8888_UNORM;
break;
case 24:
pf = PIPE_FORMAT_B8G8R8X8_UNORM;
pf = PIPE_FORMAT_BGRX8888_UNORM;
break;
case 16:
pf = PIPE_FORMAT_Z16_UNORM;
@ -590,13 +590,13 @@ dri2_create_image_from_winsys(__DRIscreen *_screen,
pf = PIPE_FORMAT_B5G6R5_UNORM;
break;
case __DRI_IMAGE_FORMAT_XRGB8888:
pf = PIPE_FORMAT_B8G8R8X8_UNORM;
pf = PIPE_FORMAT_BGRX8888_UNORM;
break;
case __DRI_IMAGE_FORMAT_ARGB8888:
pf = PIPE_FORMAT_B8G8R8A8_UNORM;
pf = PIPE_FORMAT_BGRA8888_UNORM;
break;
case __DRI_IMAGE_FORMAT_ABGR8888:
pf = PIPE_FORMAT_R8G8B8A8_UNORM;
pf = PIPE_FORMAT_RGBA8888_UNORM;
break;
default:
pf = PIPE_FORMAT_NONE;
@ -711,13 +711,13 @@ dri2_create_image(__DRIscreen *_screen,
pf = PIPE_FORMAT_B5G6R5_UNORM;
break;
case __DRI_IMAGE_FORMAT_XRGB8888:
pf = PIPE_FORMAT_B8G8R8X8_UNORM;
pf = PIPE_FORMAT_BGRX8888_UNORM;
break;
case __DRI_IMAGE_FORMAT_ARGB8888:
pf = PIPE_FORMAT_B8G8R8A8_UNORM;
pf = PIPE_FORMAT_BGRA8888_UNORM;
break;
case __DRI_IMAGE_FORMAT_ABGR8888:
pf = PIPE_FORMAT_R8G8B8A8_UNORM;
pf = PIPE_FORMAT_RGBA8888_UNORM;
break;
default:
pf = PIPE_FORMAT_NONE;