Browse Source

HXSL: Added texture size method support (#911)

Pavel Alexandrov 4 năm trước cách đây
mục cha
commit
95174c9c8f
5 tập tin đã thay đổi với 82 bổ sung27 xóa
  1. 2 2
      hxsl/Ast.hx
  2. 25 11
      hxsl/Checker.hx
  3. 7 1
      hxsl/Dce.hx
  4. 27 4
      hxsl/GlslOut.hx
  5. 21 9
      hxsl/HlslOut.hx

+ 2 - 2
hxsl/Ast.hx

@@ -205,7 +205,7 @@ enum TGlobal {
 	Texture;
 	TextureLod;
 	Texel;
-	TexelLod;
+	TextureSize;
 	// ...other texture* operations
 	// constructors
 	ToInt;
@@ -240,7 +240,7 @@ enum TGlobal {
 	ChannelRead;
 	ChannelReadLod;
 	ChannelFetch;
-	ChannelFetchLod;
+	ChannelTextureSize;
 	Trace;
 	// instancing
 	VertexID;

+ 25 - 11
hxsl/Checker.hx

@@ -80,12 +80,18 @@ class Checker {
 			case Texel:
 				[
 					{ args : [ { name: "tex", type: TSampler2D }, { name: "pos", type: ivec2 } ], ret: vec4 },
-					{ args : [ { name: "tex", type: TSampler2DArray }, { name: "pos", type: ivec3 } ], ret: vec4 }
+					{ args : [ { name: "tex", type: TSampler2DArray }, { name: "pos", type: ivec3 } ], ret: vec4 },
+					{ args : [ { name: "tex", type: TSampler2D }, { name: "pos", type: ivec2 }, { name: "lod", type: TInt } ], ret: vec4 },
+					{ args : [ { name: "tex", type: TSampler2DArray }, { name: "pos", type: ivec3 }, { name: "lod", type: TInt } ], ret: vec4 },
 				];
-			case TexelLod:
+			case TextureSize:
 				[
-					{ args : [ { name: "tex", type: TSampler2D }, { name: "pos", type: ivec2 }, { name: "lod", type: TInt } ], ret: vec4 },
-					{ args : [ { name: "tex", type: TSampler2DArray }, { name: "pos", type: ivec3 }, { name: "lod", type: TInt } ], ret: vec4 }
+					{ args : [ { name: "tex", type: TSampler2D } ], ret: vec2 },
+					{ args : [ { name: "tex", type: TSampler2DArray } ], ret: vec3 },
+					{ args : [ { name: "tex", type: TSamplerCube } ], ret: vec2 },
+					{ args : [ { name: "tex", type: TSampler2D }, { name: "lod", type: TInt } ], ret: vec2 },
+					{ args : [ { name: "tex", type: TSampler2DArray }, { name: "lod", type: TInt } ], ret: vec3 },
+					{ args : [ { name: "tex", type: TSamplerCube }, { name: "lod", type: TInt } ], ret: vec2 },
 				];
 			case ToInt:
 				[for( t in baseType ) { args : [ { name : "value", type : t } ], ret : TInt } ];
@@ -155,14 +161,22 @@ class Checker {
 					{ args : [ { name : "channel", type : TChannel(2) }, { name : "pos", type : ivec2 } ], ret : vec2 },
 					{ args : [ { name : "channel", type : TChannel(3) }, { name : "pos", type : ivec2 } ], ret : vec3 },
 					{ args : [ { name : "channel", type : TChannel(4) }, { name : "pos", type : ivec2 } ], ret : vec4 },
-				];
-			case ChannelFetchLod:
-				[
 					{ args : [ { name : "channel", type : TChannel(1) }, { name : "pos", type : ivec2 }, { name : "lod", type : TInt } ], ret : TFloat },
 					{ args : [ { name : "channel", type : TChannel(2) }, { name : "pos", type : ivec2 }, { name : "lod", type : TInt } ], ret : vec2 },
 					{ args : [ { name : "channel", type : TChannel(3) }, { name : "pos", type : ivec2 }, { name : "lod", type : TInt } ], ret : vec3 },
 					{ args : [ { name : "channel", type : TChannel(4) }, { name : "pos", type : ivec2 }, { name : "lod", type : TInt } ], ret : vec4 },
 				];
+			case ChannelTextureSize:
+				[
+					{ args : [ { name: "channel", type: TChannel(1) } ], ret: vec2 },
+					{ args : [ { name: "channel", type: TChannel(2) } ], ret: vec2 },
+					{ args : [ { name: "channel", type: TChannel(3) } ], ret: vec2 },
+					{ args : [ { name: "channel", type: TChannel(4) } ], ret: vec2 },
+					{ args : [ { name: "channel", type: TChannel(1) }, { name : "lod", type : TInt } ], ret: vec2 },
+					{ args : [ { name: "channel", type: TChannel(2) }, { name : "lod", type : TInt } ], ret: vec2 },
+					{ args : [ { name: "channel", type: TChannel(3) }, { name : "lod", type : TInt } ], ret: vec2 },
+					{ args : [ { name: "channel", type: TChannel(4) }, { name : "lod", type : TInt } ], ret: vec2 },
+				];
 			case ScreenToUv:
 				[{ args : [{ name : "screenPos", type : vec2 }], ret : vec2 }];
 			case UvToScreen:
@@ -890,10 +904,10 @@ class Checker {
 			case ["get", TChannel(_)]: ChannelRead;
 			case ["getLod", TSampler2D|TSampler2DArray|TSamplerCube]: TextureLod;
 			case ["getLod", TChannel(_)]: ChannelReadLod;
-			case ["fetch", TSampler2D|TSampler2DArray]: Texel;
-			case ["fetch", TChannel(_)]: ChannelFetch;
-			case ["fetchLod", TSampler2D|TSampler2DArray]: TexelLod;
-			case ["fetchLod", TChannel(_)]: ChannelFetchLod;
+			case ["fetch"|"fetchLod", TSampler2D|TSampler2DArray]: Texel;
+			case ["fetch"|"fetchLod", TChannel(_)]: ChannelFetch;
+			case ["size", TSampler2D|TSampler2DArray|TSamplerCube]: TextureSize;
+			case ["size", TChannel(_)]: ChannelTextureSize;
 			default: null;
 			}
 			if( gl != null ) {

+ 7 - 1
hxsl/Dce.hx

@@ -235,9 +235,15 @@ class Dce {
 		case TCall({ e : TGlobal(ChannelFetch) }, [_, pos, { e : TConst(CInt(cid)) }]):
 			var c = channelVars[cid];
 			return { e : TCall({ e : TGlobal(Texel), p : e.p, t : TVoid }, [{ e : TVar(c), t : c.type, p : e.p }, mapExpr(pos,true)]), t : TVoid, p : e.p };
-		case TCall({ e : TGlobal(ChannelFetchLod) }, [_, pos, lod, { e : TConst(CInt(cid)) }]):
+		case TCall({ e : TGlobal(ChannelFetch) }, [_, pos, lod, { e : TConst(CInt(cid)) }]):
 			var c = channelVars[cid];
 			return { e : TCall({ e : TGlobal(Texel), p : e.p, t : TVoid }, [{ e : TVar(c), t : c.type, p : e.p }, mapExpr(pos,true), mapExpr(lod,true)]), t : TVoid, p : e.p };
+		case TCall({ e : TGlobal(ChannelTextureSize) }, [_, { e : TConst(CInt(cid)) }]):
+			var c = channelVars[cid];
+			return { e : TCall({ e : TGlobal(TextureSize), p : e.p, t : TVoid }, [{ e : TVar(c), t : c.type, p : e.p }]), t : TVoid, p : e.p };
+		case TCall({ e : TGlobal(ChannelTextureSize) }, [_, lod, { e : TConst(CInt(cid)) }]):
+			var c = channelVars[cid];
+			return { e : TCall({ e : TGlobal(TextureSize), p : e.p, t : TVoid }, [{ e : TVar(c), t : c.type, p : e.p }, mapExpr(lod,true)]), t : TVoid, p : e.p };
 		case TIf(e, econd, eelse):
 			var e = mapExpr(e, true);
 			var econd = mapExpr(econd, isVar);

+ 27 - 4
hxsl/GlslOut.hx

@@ -256,12 +256,17 @@ class GlslOut {
 				return "textureCubeLodEXT";
 			default:
 			}
-		case Texel, TexelLod:
+		case Texel:
 			// if ( isES2 )
 			// 	decl("vec4 _texelFetch(sampler2d tex, ivec2 pos, int lod) ...")
 			// 	return "_texelFetch";
 			// else
 				return "texelFetch";
+		case TextureSize:
+			decl("vec2 _textureSize(sampler2D sampler, int lod) { return vec2(textureSize(sampler, lod)); }");
+			decl("vec3 _textureSize(sampler2DArray sampler, int lod) { return vec3(textureSize(sampler, lod)); }");
+			decl("vec2 _textureSize(samplerCube sampler, int lod) { return vec2(textureSize(sampler, lod)); }");
+			return "_textureSize";
 		case Mod if( rt == TInt && isES ):
 			decl("int _imod( int x, int y ) { return int(mod(float(x),float(y))); }");
 			return "_imod";
@@ -385,11 +390,29 @@ class GlslOut {
 		case TCall({ e : TGlobal(g = Texel) }, args):
 			add(getFunName(g,args,e.t));
 			add("(");
-			for( e in args ) {
-				addValue(e, tabs);
+			addValue(args[0], tabs); // sampler
+			add(", ");
+			addValue(args[1], tabs); // uv
+			if ( args.length != 2 ) {
+				// with LOD argument
+				add(", ");
+				addValue(args[2], tabs);
+				add(")");
+			} else {
+				add(", 0)");
+			}
+		case TCall({ e : TGlobal(g = TextureSize) }, args):
+			add(getFunName(g,args,e.t));
+			add("(");
+			addValue(args[0], tabs);
+			if ( args.length != 1 ) {
+				// with LOD argument
 				add(", ");
+				addValue(args[1], tabs);
+				add(")");
+			} else {
+				add(", 0)");
 			}
-			add("0)");
 		case TCall(v, args):
 			switch( v.e ) {
 			case TGlobal(g):

+ 21 - 9
hxsl/HlslOut.hx

@@ -267,7 +267,7 @@ class HlslOut {
 			if( g == Texture && isVertex )
 				add(",0");
 			add(")");
-		case TCall({ e : TGlobal(g = (Texel | TexelLod)) }, args):
+		case TCall({ e : TGlobal(g = (Texel)) }, args):
 			addValue(args[0], tabs);
 			add(".Load(");
 			switch ( args[1].t ) {
@@ -279,16 +279,28 @@ class HlslOut {
 					throw "assert";
 			}
 			addValue(args[1],tabs);
-			switch( g ) {
-				case Texel:
-					add(", 0");
-				case TexelLod:
-					add(", ");
-					addValue(args[2],tabs);
-				default:
-					throw "assert";
+			if ( args.length != 2 ) {
+				// with LOD argument
+				add(", ");
+				addValue(args[2], tabs);
+			} else {
+				add(", 0");
 			}
 			add("))");
+		case TCall({ e : TGlobal(g = (TextureSize)) }, args):
+			decl("float2 textureSize(Texture2D tex, int lod) { float w; float h; tex.GetDimensions(tex, (uint)lod, out w, out h); return float2(w, h); }");
+			decl("float3 textureSize(Texture2DArray tex, int lod) { float w; float h; float els; tex.GetDimensions(tex, (uint)lod, out w, out h, out els); return float3(w, h, els); }");
+			decl("float2 textureSize(TextureCube tex, int lod) { float w; float h; tex.GetDimensions(tex, (uint)lod, out w, out h); return float2(w, h); }");
+			add("textureSize(");
+			addValue(args[0], tabs);
+			if (args.length != 1) {
+				// With LOD argument
+				add(", ");
+				addValue(args[1],tabs);
+			} else {
+				add(", 0");
+			}
+			add(")");
 		case TCall(e = { e : TGlobal(g) }, args):
 			switch( [g,args.length] ) {
 			case [Vec2, 1] if( args[0].t == TFloat ):