Diff below is a fix for the regression [0] preventing the gallium r300 driver to work on big endian architectures. It has been written by Michel Dänzer [1] but never made it into Mesa.
This diff allows me to use OpenGL acceleration on macppc. ajacoutot@ also confirmed he can use GNOME3 on his PowerBook with it. So I'd like to hear from people using the gallium r300 driver on x86. If this diff does not introduce regression, I'd really appreciate to put it in instead of recompiling my Frankenstein xenocara. The diff also makes r600 build on macppc/sparc64, in the hope that it will allow other people to analyse/report/fix possible remaining issues. [0] https://bugs.freedesktop.org/show_bug.cgi?id=71789 [1] http://lists.freedesktop.org/archives/mesa-dev/2013-December/050218.html Index: dist/Mesa/src/gallium/drivers/r300/r300_blit.c =================================================================== RCS file: /cvs/xenocara/dist/Mesa/src/gallium/drivers/r300/r300_blit.c,v retrieving revision 1.7 diff -u -p -r1.7 r300_blit.c --- dist/Mesa/src/gallium/drivers/r300/r300_blit.c 20 Feb 2015 23:09:52 -0000 1.7 +++ dist/Mesa/src/gallium/drivers/r300/r300_blit.c 25 Jun 2015 13:01:25 -0000 @@ -185,7 +185,9 @@ static void r300_set_clear_color(struct 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) { Index: dist/Mesa/src/gallium/drivers/r300/r300_context.h =================================================================== RCS file: /cvs/xenocara/dist/Mesa/src/gallium/drivers/r300/r300_context.h,v retrieving revision 1.7 diff -u -p -r1.7 r300_context.h --- dist/Mesa/src/gallium/drivers/r300/r300_context.h 20 Feb 2015 23:09:52 -0000 1.7 +++ dist/Mesa/src/gallium/drivers/r300/r300_context.h 25 Jun 2015 13:01:25 -0000 @@ -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, Index: dist/Mesa/src/gallium/drivers/r300/r300_state.c =================================================================== RCS file: /cvs/xenocara/dist/Mesa/src/gallium/drivers/r300/r300_state.c,v retrieving revision 1.7 diff -u -p -r1.7 r300_state.c --- dist/Mesa/src/gallium/drivers/r300/r300_state.c 20 Feb 2015 23:09:52 -0000 1.7 +++ dist/Mesa/src/gallium/drivers/r300/r300_state.c 25 Jun 2015 13:01:25 -0000 @@ -225,6 +225,12 @@ static unsigned blend_discard_conditiona /* 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(str /* 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(str }; 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 p 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 p 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); } } Index: dist/Mesa/src/gallium/drivers/r300/r300_state_derived.c =================================================================== RCS file: /cvs/xenocara/dist/Mesa/src/gallium/drivers/r300/r300_state_derived.c,v retrieving revision 1.5 diff -u -p -r1.5 r300_state_derived.c --- dist/Mesa/src/gallium/drivers/r300/r300_state_derived.c 9 Jul 2014 21:08:54 -0000 1.5 +++ dist/Mesa/src/gallium/drivers/r300/r300_state_derived.c 25 Jun 2015 13:01:25 -0000 @@ -815,9 +815,12 @@ static void r300_merge_textures_and_samp 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_samp /* 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_samp 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_samp 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_samp } 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_samp } /* 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) { Index: dist/Mesa/src/gallium/drivers/r300/r300_texture.c =================================================================== RCS file: /cvs/xenocara/dist/Mesa/src/gallium/drivers/r300/r300_texture.c,v retrieving revision 1.7 diff -u -p -r1.7 r300_texture.c --- dist/Mesa/src/gallium/drivers/r300/r300_texture.c 20 Feb 2015 23:09:52 -0000 1.7 +++ dist/Mesa/src/gallium/drivers/r300/r300_texture.c 25 Jun 2015 13:01:25 -0000 @@ -90,6 +90,25 @@ unsigned r300_get_swizzle_combined(const 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_colorform 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(e 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 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( 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; } } Index: dist/Mesa/src/gallium/drivers/r300/r300_texture.h =================================================================== RCS file: /cvs/xenocara/dist/Mesa/src/gallium/drivers/r300/r300_texture.h,v retrieving revision 1.4 diff -u -p -r1.4 r300_texture.h --- dist/Mesa/src/gallium/drivers/r300/r300_texture.h 5 Sep 2013 14:00:58 -0000 1.4 +++ dist/Mesa/src/gallium/drivers/r300/r300_texture.h 25 Jun 2015 13:01:25 -0000 @@ -39,6 +39,9 @@ unsigned r300_get_swizzle_combined(const 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, Index: dist/Mesa/src/gallium/drivers/r300/r300_transfer.c =================================================================== RCS file: /cvs/xenocara/dist/Mesa/src/gallium/drivers/r300/r300_transfer.c,v retrieving revision 1.3 diff -u -p -r1.3 r300_transfer.c --- dist/Mesa/src/gallium/drivers/r300/r300_transfer.c 5 Sep 2013 14:00:59 -0000 1.3 +++ dist/Mesa/src/gallium/drivers/r300/r300_transfer.c 25 Jun 2015 13:01:25 -0000 @@ -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_co 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_co * 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) { Index: dist/Mesa/src/gallium/state_trackers/dri/common/dri_drawable.c =================================================================== RCS file: /cvs/xenocara/dist/Mesa/src/gallium/state_trackers/dri/common/dri_drawable.c,v retrieving revision 1.7 diff -u -p -r1.7 dri_drawable.c --- dist/Mesa/src/gallium/state_trackers/dri/common/dri_drawable.c 20 Feb 2015 23:09:53 -0000 1.7 +++ dist/Mesa/src/gallium/state_trackers/dri/common/dri_drawable.c 25 Jun 2015 13:01:26 -0000 @@ -231,11 +231,11 @@ dri_set_tex_buffer2(__DRIcontext *pDRICt 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; Index: dist/Mesa/src/gallium/state_trackers/dri/drm/dri2.c =================================================================== RCS file: /cvs/xenocara/dist/Mesa/src/gallium/state_trackers/dri/drm/dri2.c,v retrieving revision 1.8 diff -u -p -r1.8 dri2.c --- dist/Mesa/src/gallium/state_trackers/dri/drm/dri2.c 22 Feb 2015 09:30:34 -0000 1.8 +++ dist/Mesa/src/gallium/state_trackers/dri/drm/dri2.c 25 Jun 2015 13:01:26 -0000 @@ -162,10 +162,10 @@ dri2_drawable_get_buffers(struct dri_dra * 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(__DRIscree 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; Index: lib/libGL/dri/Makefile =================================================================== RCS file: /cvs/xenocara/lib/libGL/dri/Makefile,v retrieving revision 1.18 diff -u -p -r1.18 Makefile --- lib/libGL/dri/Makefile 5 Sep 2013 15:11:56 -0000 1.18 +++ lib/libGL/dri/Makefile 25 Jun 2015 13:01:28 -0000 @@ -14,7 +14,8 @@ SUBDIR+= radeon r200 .endif .if ${XENOCARA_BUILD_GALLIUM:L} == "yes" || ${XENOCARA_BUILD_GALLIUM} == "llvm" -.if ${MACHINE} == i386 || ${MACHINE} == amd64 +.if ${MACHINE} == i386 || ${MACHINE} == amd64 || \ + ${MACHINE} == macppc || ${MACHINE} == sparc64 SUBDIR+= r300g r600g .endif .endif Index: lib/libGL/gallium/winsys/Makefile =================================================================== RCS file: /cvs/xenocara/lib/libGL/gallium/winsys/Makefile,v retrieving revision 1.2 diff -u -p -r1.2 Makefile --- lib/libGL/gallium/winsys/Makefile 23 Feb 2015 23:39:27 -0000 1.2 +++ lib/libGL/gallium/winsys/Makefile 25 Jun 2015 13:01:29 -0000 @@ -1,6 +1,7 @@ # $OpenBSD: Makefile,v 1.2 2015/02/23 23:39:27 jsg Exp $ -.if ${MACHINE} == i386 || ${MACHINE} == amd64 +.if ${MACHINE} == i386 || ${MACHINE} == amd64 || \ + ${MACHINE} == macppc || ${MACHINE} == sparc64 SUBDIR= radeon .endif
