Browse Source

Disallow mat3 formats in shader storage buffers.

GLSL's std430 layout rules make it really unintuitive for users to deal with.
Alex Szpakowski 3 years ago
parent
commit
a3ff9999d1
1 changed files with 13 additions and 5 deletions
  1. 13 5
      src/modules/graphics/Buffer.cpp

+ 13 - 5
src/modules/graphics/Buffer.cpp

@@ -154,11 +154,19 @@ Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector<DataDe
 			// with R components each".
 			// "If the member is a three-component vector with components
 			// consuming N basic machine units, the base alignment is 4N."
-			int components = info.isMatrix ? info.matrixRows : info.components;
-			if (components == 3)
-				alignment = 4 * info.componentSize;
-			else
-				alignment = components * info.componentSize;
+			int c = info.isMatrix ? info.matrixRows : info.components;
+			alignment = c == 3 ? 4 * info.componentSize : c * info.componentSize;
+
+			// std430 will effectively turn a floatmat3x3 into a floatmat4x3
+			// because of its vec3 padding rules. For now we'd rather not
+			// support those formats at all, because it's not easy for users to
+			// deal with.
+			if (alignment != c * info.componentSize && (decl.arrayLength > 0 || info.isMatrix))
+			{
+				const char *fstr = "unknown";
+				getConstant(decl.format, fstr);
+				throw love::Exception("Data format %s%s is not currently supported in shader storage buffers.", fstr, decl.arrayLength > 0 ? " array" : "");
+			}
 
 			// "If the member is a structure, the base alignment of the structure
 			// is N, where N is the largest base alignment value of any of its