nouveau: ppc, swap fragment programs on big endian systems.
authorDave Airlie <airlied@ppcg5.localdomain>
Thu, 1 Nov 2007 08:19:45 +0000 (19:19 +1100)
committerDave Airlie <airlied@ppcg5.localdomain>
Thu, 1 Nov 2007 08:19:45 +0000 (19:19 +1100)
Thanks to the PS3 RSX project for figuring this out.

src/mesa/drivers/dri/nouveau/nouveau_bufferobj.c
src/mesa/drivers/dri/nouveau/nouveau_bufferobj.h
src/mesa/drivers/dri/nouveau/nv30_fragprog.c

index be6455a01ed29d8f39d6a50ced86e800146115f9..25c7b8206a016ee3d8f31859f795d08c00cc802a 100644 (file)
@@ -224,7 +224,7 @@ nouveau_bo_init_storage(GLcontext *ctx,     GLuint valid_gpu_access,
                                        GLsizeiptrARB size,
                                        const GLvoid *data,
                                        GLenum usage,
-                                       struct gl_buffer_object *bo)
+                       struct gl_buffer_object *bo, int flags)
 {
        nouveau_buffer_object *nbo = (nouveau_buffer_object *)bo;
 
@@ -257,7 +257,18 @@ nouveau_bo_init_storage(GLcontext *ctx,    GLuint valid_gpu_access,
 
        if (data) {
                GLvoid *map = nouveau_bo_map(ctx, GL_WRITE_ONLY_ARB, bo);
-               _mesa_memcpy(map, data, size);
+#ifdef MESA_BIG_ENDIAN
+               int i;
+               if (flags) {
+                 for (i = 0; i < size; i+=4) {
+                   uint32_t _data = *(unsigned int *)(data+i);
+                   _data = ((_data >> 16) | ((_data & 0xffff) << 16));
+                   *(unsigned int *)(map+i) = _data;
+                 }
+               } else
+#endif
+                 _mesa_memcpy(map, data, size);
+               (void)flags; /* get rid of warning */
                nouveau_bo_dirty_all(ctx, GL_FALSE, bo);
                nouveau_bo_unmap(ctx, bo);
        }
@@ -514,7 +525,7 @@ nouveauBufferData(GLcontext *ctx, GLenum target, GLsizeiptrARB size,
                gpu_flags = NOUVEAU_BO_VRAM_OK | NOUVEAU_BO_GART_OK;
                break;
        }
-       nouveau_bo_init_storage(ctx, gpu_flags, size, data, usage, obj);
+       nouveau_bo_init_storage(ctx, gpu_flags, size, data, usage, obj, 0);
 }
 
 static void
index cbc89a151da61b141138ffec5d65d8e672052710..fb3afc1c300355b0985531e1c7d7d17e9c982218 100644 (file)
@@ -39,7 +39,7 @@ typedef struct nouveau_buffer_object_t {
 extern void
 nouveau_bo_init_storage(GLcontext *ctx, GLuint valid_gpu_access,
                        GLsizeiptrARB size, const GLvoid *data, GLenum usage,
-                       struct gl_buffer_object *bo);
+                       struct gl_buffer_object *bo, int flags);
 
 extern GLboolean
 nouveau_bo_move_in(GLcontext *ctx, struct gl_buffer_object *bo);
index e32452361e82592fec3df09cca77dd241df7c701..5f61f76a0ab2b2008332f8d79b86c1e468bfd646 100644 (file)
@@ -36,7 +36,7 @@ NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
                          nvs->program_size * sizeof(uint32_t),
                          (const GLvoid *)nvs->program,
                          GL_DYNAMIC_DRAW_ARB,
-                         nvs->program_buffer);
+                          nvs->program_buffer, 1);
 
    offset = nouveau_bo_gpu_ref(ctx, nvs->program_buffer);