浏览代码

Can read TBytes(4) from buffer in shaders.

clementlandrin 9 月之前
父节点
当前提交
ee269da000
共有 3 个文件被更改,包括 32 次插入3 次删除
  1. 2 0
      hxsl/Ast.hx
  2. 4 0
      hxsl/Checker.hx
  3. 26 3
      hxsl/Flatten.hx

+ 2 - 0
hxsl/Ast.hx

@@ -307,6 +307,8 @@ enum TGlobal {
 	//ComputeVar_WorkGroupSize - no DirectX support
 	AtomicAdd;
 	GroupMemoryBarrier;
+	UnpackSnorm4x8;
+	UnpackUnorm4x8;
 }
 
 enum Component {

+ 4 - 0
hxsl/Checker.hx

@@ -212,6 +212,10 @@ class Checker {
 				fname = fname.charAt(0).toLowerCase() + fname.substr(1);
 				vl.push({ name : fname, type : vt });
 				null;
+			case UnpackSnorm4x8:
+				[ { args : [ { name : "value", type : TInt } ], ret : vec4 } ];
+			case UnpackUnorm4x8:
+				[ { args : [ { name : "value", type : TInt } ], ret : vec4 } ];
 			default:
 				throw "Unsupported global "+g;
 			}

+ 26 - 3
hxsl/Flatten.hx

@@ -151,7 +151,7 @@ class Flatten {
 				case TBuffer(TInt|TFloat,_), TVec(_, VFloat|VInt):
 					e.map(mapExpr);
 				case TArray(t, _), TBuffer(t, _):
-					var stride = varSize(t, a.t);
+					var stride = varSize4Bytes(t, a.t);
 					if( stride == 0 || (v.type.match(TArray(_)) && stride & 3 != 0) ) throw new Error("Dynamic access to an Array which size is not 4 components-aligned is not allowed", e.p);
 					stride = (stride + 3) >> 2;
 					eindex = toInt(mapExpr(eindex));
@@ -178,7 +178,11 @@ class Flatten {
 			switch( e.t ) {
 			case TFloat:
 				readField(expr, pos, 1);
-			case TVec(size,VFloat), TBytes(size):
+			case TBytes(size):
+				{ e : TCall({ e : TGlobal(UnpackSnorm4x8), p : e.p, t : TVec(size, VFloat) }, [
+					floatBitsToUint(readField(expr, pos, 1))
+				]), t : e.t, p : e.p }
+			case TVec(size,VFloat):
 				var idx = pos >> 2;
 				var idx2 = ((pos + size - 1) >> 2);
 				if( idx == idx2 )
@@ -314,6 +318,10 @@ class Flatten {
 		}
 	}
 
+	function floatBitsToUint( e : TExpr ) {
+		return { e : TCall({ e : TGlobal(FloatBitsToUint), t : TFun([]), p : e.p }, [e]), t : TInt, p : e.p };
+	}
+
 	function toInt( e : TExpr ) {
 		if( e.t == TInt ) return e;
 		return { e : TCall({ e : TGlobal(ToInt), t : TFun([]), p : e.p }, [e]), t : TInt, p : e.p };
@@ -498,7 +506,7 @@ class Flatten {
 		return switch( v ) {
 		case TFloat, TInt if( t == VFloat ): 1;
 		case TVec(n, t2) if( t == t2 ): n;
-		case TBytes(n): n; 
+		case TBytes(n): n;
 		case TMat4 if( t == VFloat ): 16;
 		case TMat3, TMat3x4 if( t == VFloat ): 12;
 		case TArray(at, SConst(n)): varSize(at, t) * n;
@@ -512,6 +520,21 @@ class Flatten {
 		}
 	}
 
+	function varSize4Bytes( v : Type, t : VecType ) {
+		return switch ( v ) {
+		case TBytes(4): 1;
+		case TBytes(_): throw v.toString() + " 4 bytes size unknown for type" + t;
+		case TArray(at, SConst(n)): varSize4Bytes(at, t) * n;
+		case TStruct(vl):
+			var size = 0;
+			for( v in vl )
+				size += varSize4Bytes(v.type, t);
+			size;
+		default:
+			varSize(v, t);
+		}
+	}
+
 	function addTextureFormat(dim,arr,rw=0) {
 		for( f in textureFormats )
 			if( f.dim == dim && f.arr == arr && f.rw == rw )