svga: round UBO constant buffer size up/down to multiple of 16 bytes
authorBrian Paul <brianp@vmware.com>
Tue, 6 Oct 2015 22:55:39 +0000 (16:55 -0600)
committerBrian Paul <brianp@vmware.com>
Wed, 7 Oct 2015 14:45:56 +0000 (08:45 -0600)
The svga3d device requires constant buffers to be a multiple of 16 bytes
in size.  OpenGL UBOs may not fit that restriction.  As a work-around,
round the size up if possible, else round down.

Note that this patch only effects UBO constant buffers (index 1 or higher),
not the 0th/default constant buffer.

Fixes the game Grim Fandango Remastered.  VMware bug 1510130.

Reviewed-by: Charmaine Lee <charmainel@vmware.com>
Reviewed-by: José Fonseca <jfonseca@vmware.com>
src/gallium/drivers/svga/svga_state_constants.c

index b6d6de0dca329fd486244d4cb3c1dcd42872c9e5..75592d3bf8bdcf0f7c98447f4f06d96d6478bb8a 100644 (file)
@@ -704,6 +704,24 @@ emit_consts_vgpu10(struct svga_context *svga, unsigned shader)
          assert(size == 0);
       }
 
+      if (size % 16 != 0) {
+         /* GL's buffer range sizes can be any number of bytes but the
+          * SVGA3D device requires a multiple of 16 bytes.
+          */
+         const unsigned total_size = buffer->b.b.width0;
+
+         if (offset + align(size, 16) <= total_size) {
+            /* round up size to multiple of 16 */
+            size = align(size, 16);
+         }
+         else {
+            /* round down to mulitple of 16 (this may cause rendering problems
+             * but should avoid a device error).
+             */
+            size &= ~16;
+         }
+      }
+
       assert(size % 16 == 0);
       ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
                                                   index,