On Mon, 2013-12-16 at 17:05 +1000, Dave Airlie wrote:
> So the llvmpipe endian work broke the nouveau nv40 support for the
> nv43 in the ppc G5 a few people have,

Same for r300g: https://bugs.freedesktop.org/show_bug.cgi?id=71789


> Now I'm not really sure how this is supposed to be fixed,
> 
> the gallium driver exports the formats it supports, which doesn't
> include the translated formats for PIPE_FORMAT_BGRA8888 and
> PIPE_FORMAT_8BGRX8888 which end up like PIPE_FORMAT_A8R8G8B8_UNORM
> this. This means no 8-bit visuals and ensuing fail.
> 
> Now I'm not sure the hw has any swappers or anything to facilitate
> these formats for rendering to, so it seems to me the pipe driver is
> doing the right thing, so my thinking is the state tracker should
> probably be dealing with this better, but again I'm not really sure
> how, maybe this just all worked in the past by luck.

I'm afraid it did.

> So should dri_fill_in_modes be doing a bit more on big endian? so if
> it can't find any formats the way it wants, it tries the other way,
> and reports those back so X gets different visuals with the masks all
> moved about?

Not sure we can do anything about the visuals, as X11 requires that all
the non-alpha bits are packed in the least significant bits in host byte
order.

This could probably still be solved in the state trackers though, by
falling back to formats which don't match the APIs they're providing,
and fixing things up as necessary when copying data to/from transfers.
Note that this would require adding explicit-endianness variants of many
formats, such as e.g. PIPE_FORMAT_*32*, where the components are now
defined in host byte order.


I'm attaching WIP patches for a different approach with r300g. The
second patch makes r300g advertise PIPE_FORMAT_*8R8G8B8_UNORM, but
treats them like PIPE_FORMAT_B8G8R8*8_UNORM for actual rendering
operations, and only converts to the API-specified formats for transfer
access. This mirrors what the Xorg radeon driver does to translate
between what X11 imposes and what the hardware supports. I assume
xf86-video-nouveau might be doing something similar.


-- 
Earthling Michel Dänzer            |                  http://www.amd.com
Libre software enthusiast          |                Mesa and X developer
>From b3c5896e87036bdfd744e3b1b768a58c3e38ac2b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daen...@amd.com>
Date: Mon, 25 Nov 2013 10:13:42 +0900
Subject: [PATCH 1/2] st/dri: Use packed RGB formats
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Michel Dänzer <michel.daen...@amd.com>
---
 src/gallium/state_trackers/dri/common/dri_drawable.c |  8 ++++----
 src/gallium/state_trackers/dri/drm/dri2.c            | 20 ++++++++++----------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.c b/src/gallium/state_trackers/dri/common/dri_drawable.c
index f255108..cb94799 100644
--- a/src/gallium/state_trackers/dri/common/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/common/dri_drawable.c
@@ -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;
diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c
index 868cd25..06bdaa8 100644
--- a/src/gallium/state_trackers/dri/drm/dri2.c
+++ b/src/gallium/state_trackers/dri/drm/dri2.c
@@ -125,10 +125,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:
@@ -398,10 +398,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;
@@ -544,13 +544,13 @@ dri2_create_image_from_name(__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;
@@ -634,13 +634,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;
-- 
1.8.4.rc3

>From d159715c15cd8ce40bdc1e3386d84cc38576f43a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daen...@amd.com>
Date: Tue, 26 Nov 2013 19:46:55 +0900
Subject: [PATCH 2/2] r300g: Big endian fixes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Michel Dänzer <michel.daen...@amd.com>
---
 src/gallium/drivers/r300/r300_blit.c          |  4 ++-
 src/gallium/drivers/r300/r300_context.h       |  2 ++
 src/gallium/drivers/r300/r300_state.c         | 20 +++++++++---
 src/gallium/drivers/r300/r300_state_derived.c | 15 +++++----
 src/gallium/drivers/r300/r300_texture.c       | 44 +++++++++++++++++++++++++--
 src/gallium/drivers/r300/r300_texture.h       |  3 ++
 src/gallium/drivers/r300/r300_transfer.c      |  6 ++--
 7 files changed, 77 insertions(+), 17 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index 42410fe..06004e4 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -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) {
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index e6b0181..b10fbf6 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -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,
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 6840e8b..774520c 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -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);
@@ -1657,6 +1666,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;
@@ -1672,24 +1682,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);
         }
     }
 
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 1013557..c3bc9a1 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -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) {
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index b7fb081..a525f5e 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -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;
     }
 }
diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h
index 213bdff..d43bf6b 100644
--- a/src/gallium/drivers/r300/r300_texture.h
+++ b/src/gallium/drivers/r300/r300_texture.h
@@ -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,
diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c
index b87164b..7690da9 100644
--- a/src/gallium/drivers/r300/r300_transfer.c
+++ b/src/gallium/drivers/r300/r300_transfer.c
@@ -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) {
-- 
1.8.4.rc3

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to