[PATCH] Big endian support for RV730 (Gallium r600g)

Michel Dänzer michel at daenzer.net
Tue Apr 19 02:39:41 PDT 2011

[ Moving to the mesa-dev list ]

On Fre, 2011-04-15 at 18:20 +0200, Cédric Cano wrote: 
> Here you are a patch that adds big endian support for rv730 in r600 
> gallium driver.
> I used the mesa-demos to test the driver status on big endian platform. 
> Except with demos using accumulation buffer, the rendering is the same 
> as on Intel platform. Albeit there are still some artefacts with some 
> demos.
> I manage to fix accumulation buffer demos but then, glReadPixels demos 
> won't work. I still can figure out (like with r600c) what and when I 
> must enable swap. It will depends on object's domains. That's what I 
> tried to do in r600_cb and r600_create_sampler_view.

That's probably because it hasn't been fully thought through yet how to
deal with big endian CPUs vs. little endian GPUs in Gallium. When this
was discussed previously, the basic rule decided was that all data
passed across the Gallium driver interface was supposed to be little
endian. That should probably be feasible in general for at least
'standard' pixel formats, but I'm afraid it doesn't really work for
vertex data[0], which could be fed from the application (which will use
CPU native byte order) to the GPU more or less directly.

Maybe byte order should be handled explicitly by the Gallium format
definitions, and then it would be up to the state tracker to use the
appropriate byte order formats. José, have you had any further thoughts
on this?

[0] Though there might also be ambiguities e.g. with multi-byte
component pixel formats: Does the little endian rule apply to the pixel
value as a whole, or only for each component? 

> @@ -266,11 +268,31 @@ void r600_upload_const_buffer(struct r600_pipe_context *rctx, struct r600_resour
>                 uint8_t *ptr = (*rbuffer)->r.b.user_ptr;
>                 unsigned size = (*rbuffer)->r.b.b.b.width0;
>                 boolean flushed;
> +               int i;
> +               uint32_t *tmpPtr;
> +
> +               *rbuffer = NULL;
> +
> +               tmpPtr = (uint32_t *)malloc(size);
> +               /* big endian swap */
> +               if(tmpPtr == NULL) {
> +                       return;
> +               }
> +               for(i = 0; i < size / 4; i++) {
> +                       tmpPtr[i] = bswap_32(*((uint32_t *)ptr + i));
> +               }
> +       
> +               u_upload_data(rctx->vbuf_mgr->uploader, 0, size, tmpPtr, const_offset,
> +                             (struct pipe_resource**)rbuffer, &flushed);

Might be better to add a helper like u_upload_data_to_le32().

Earthling Michel Dänzer           |                http://www.vmware.com
Libre software enthusiast         |          Debian, X and DRI developer

More information about the dri-devel mailing list