Bug 92909 - [SNB] Offset/alignment issue with layout std140 and vec3
Summary: [SNB] Offset/alignment issue with layout std140 and vec3
Status: NEW
Alias: None
Product: Mesa
Classification: Unclassified
Component: Drivers/DRI/i965 (show other bugs)
Version: 11.0
Hardware: x86-64 (AMD64) Linux (All)
: medium normal
Assignee: Intel 3D Bugs Mailing List
QA Contact: Intel 3D Bugs Mailing List
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 93185
  Show dependency treegraph
 
Reported: 2015-11-11 22:42 UTC by Dimitri Sabadie
Modified: 2016-11-03 19:27 UTC (History)
2 users (show)

See Also:
i915 platform:
i915 features:


Attachments
source code with compilation line (first line) (3.80 KB, text/plain)
2015-11-11 22:42 UTC, Dimitri Sabadie
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dimitri Sabadie 2015-11-11 22:42:42 UTC
Created attachment 119574 [details]
source code with compilation line (first line)

When trying to compile an OpenGL 3.2 program to demonstrate the use of UBO (Uniform Buffer Objects), I got astonished my program worked on nvidia but not on i915. I spent days trying to fix my code, but I was eventually advised to submit a driver bug here.

The problem is there when trying to send three colors to fulfill a triangle (red, green and blue). I attached the code so that you can run it and test it; it’s rather small.

So, the shader defines a uniform block as:

struct Color {
  vec3 rgb;
  float k;
};

The rule 3 and rule 9 of the gl32 specs state that the scalar (float) should be aligned on a 4 bytes and that the vec3 should be aligned on 16 bytes. The vec3 rgb field is already aligned on 16 bytes (because its offset is 0) and the float k is already aligned as well (because its offset is 12, which is a multiple of 4). So no padding is needed and the structure’s size is 16 bytes. Though, I guess the driver tries to do different things on the GLSL side and I get wrong values for k (though the vec3 works, like, if I don’t use k in the fragment shader output, I get a correct behavior).
Comment 1 Kenneth Graunke 2015-11-11 22:57:03 UTC
Tracked this down.

The vec4 backend's UBO loading code is broken for indirect offsets that are not vec4 aligned (multiples of 16 bytes).  Notably, the scalar backend shifts right by 2 (bytes / 4 -> DWords), while the vector backend shifts right by 4 (bytes / 4 -> DWords, DWords / 4 -> vec4 blocks).  It tries to load a vec4, then swizzle the result...based on const_offset.  But we don't have any swizzling to compensate for offset % 16 != 0.

The app's second UBO load uses offsets of 12 and 44, which are not vec4-aligned, so it hits this bug.

Unfortunately, the fix isn't terribly simple.  One option is to try and add that swizzling...but this means having to do indirect addressing.  Another is to convert the vec4 backend to use DWord aligned surfaces, which is a pretty big change as well.
Comment 2 Kenneth Graunke 2015-11-12 00:17:28 UTC
If anyone on the team is feeling inspired to fix this, feel free - I'm not likely to get to it immediately.
Comment 3 Kenneth Graunke 2015-11-12 00:34:41 UTC
FWIW, the reporter is using Haswell (hence the vec4 backend).
Comment 4 Tapani Pälli 2015-11-12 06:34:08 UTC
maybe this is the same issue we have with CTS UBO tests on HSW (bug #92113)
Comment 5 Matt Turner 2015-11-12 18:57:48 UTC
Jason's got work-in-progress code that he says will fix this on everything but Sandybridge.
Comment 6 Jason Ekstrand 2015-12-10 22:09:43 UTC
This should now be fixed on IVB and later.


bug/show.html.tmpl processed on Feb 24, 2017 at 03:38:38.
(provided by the Example extension).