diff options
author | Niklas Haas <git@haasn.xyz> | 2018-09-29 02:20:56 +0200 |
---|---|---|
committer | sfan5 <sfan5@live.de> | 2018-09-29 20:15:10 +0200 |
commit | 730469cb29e96595adeaed46dd9b0c9c3386751e (patch) | |
tree | 3ff775ca5df05a764224e7af7480b8cb77b43865 /video/out | |
parent | 39d10e33595847e576b6b1c1379ba8d3f27d9323 (diff) |
vo_gpu: fix vec3 packing in UBOs/push_constants
For vec3, the alignment and size differ. The current code will pack a
struct like { vec3; float; vec2 } into 8 machine words, whereas the spec
would only use 6.
This actually fixes a real bug: The only place in the code I could find
where it was conceivably possible that a vec3 is followed by a float was
when using --gpu-dumb-mode in combination with --gamma-factor, and only
when --gpu-api=vulkan. So it's no surprised nobody ran into it yet.
Diffstat (limited to 'video/out')
-rw-r--r-- | video/out/gpu/utils.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/video/out/gpu/utils.c b/video/out/gpu/utils.c index 078a31c895..9234545a71 100644 --- a/video/out/gpu/utils.c +++ b/video/out/gpu/utils.c @@ -141,16 +141,17 @@ struct ra_layout std140_layout(struct ra_renderpass_input *inp) // the nearest multiple of vec4 // 4. Matrices are treated like arrays of vectors // 5. Arrays/matrices are laid out with a stride equal to the alignment - size_t size = el_size * inp->dim_v; + size_t stride = el_size * inp->dim_v; + size_t align = stride; if (inp->dim_v == 3) - size += el_size; + align += el_size; if (inp->dim_m > 1) - size = MP_ALIGN_UP(size, sizeof(float[4])); + stride = align = MP_ALIGN_UP(stride, sizeof(float[4])); return (struct ra_layout) { - .align = size, - .stride = size, - .size = size * inp->dim_m, + .align = align, + .stride = stride, + .size = stride * inp->dim_m, }; } @@ -160,14 +161,15 @@ struct ra_layout std430_layout(struct ra_renderpass_input *inp) // std430 packing rules: like std140, except arrays/matrices are always // "tightly" packed, even arrays/matrices of vec3s - size_t size = el_size * inp->dim_v; + size_t stride = el_size * inp->dim_v; + size_t align = stride; if (inp->dim_v == 3 && inp->dim_m == 1) - size += el_size; + align += el_size; return (struct ra_layout) { - .align = size, - .stride = size, - .size = size * inp->dim_m, + .align = align, + .stride = stride, + .size = stride * inp->dim_m, }; } |