2
0
Эх сурвалжийг харах

basic params uniform buffer

Nicolas Cannasse 1 жил өмнө
parent
commit
f296fcbab9

+ 2 - 1
h3d/impl/WebGpuApi.hx

@@ -1631,7 +1631,8 @@ typedef GPUBufferBinding = {
 
 
 extern class GPUExternalTexture {}
 extern class GPUExternalTexture {}
 
 
-typedef GPUBindingResource = haxe.ds.Either<GPUSampler,haxe.ds.Either<GPUTextureView, haxe.ds.Either<GPUBufferBinding,GPUExternalTexture>>>;
+abstract GPUBindingResource(Dynamic) from GPUSampler from GPUTextureView from GPUBufferBinding from GPUExternalTexture {
+}
 
 
 
 
 typedef GPUBindGroupEntry = {
 typedef GPUBindGroupEntry = {

+ 92 - 13
h3d/impl/WebGpuDriver.hx

@@ -4,8 +4,20 @@ import h3d.impl.Driver;
 import h3d.impl.WebGpuApi;
 import h3d.impl.WebGpuApi;
 import h3d.mat.Pass;
 import h3d.mat.Pass;
 
 
+class WebGpuSubShader {
+	public var kind : GPUShaderStage;
+	public var module : GPUShaderModule;
+	public var groups : Array<GPUBindGroupLayout>;
+	public var paramsBufferSize : Int;
+	public function new() {
+	}
+}
+
 class WebGpuShader {
 class WebGpuShader {
 	public var format : hxd.BufferFormat;
 	public var format : hxd.BufferFormat;
+	public var vertex : WebGpuSubShader;
+	public var fragment : WebGpuSubShader;
+	public var layout : GPUPipelineLayout;
 	public var pipeline : GPURenderPipeline;
 	public var pipeline : GPURenderPipeline;
 	public function new() {
 	public function new() {
 	}
 	}
@@ -276,30 +288,53 @@ class WebGpuDriver extends h3d.impl.Driver {
 	}
 	}
 
 
 
 
-	function compile( shader : hxsl.RuntimeShader.RuntimeShaderData ) {
+	function compile( shader : hxsl.RuntimeShader.RuntimeShaderData, kind ) {
 		var comp = new hxsl.WgslOut();
 		var comp = new hxsl.WgslOut();
 		var source = comp.run(shader.data);
 		var source = comp.run(shader.data);
-		trace(source);
-		return device.createShaderModule({ code : source });
+		var sh = new WebGpuSubShader();
+		sh.kind = kind;
+		sh.module = device.createShaderModule({ code : source });
+		sh.groups = [];
+		for( v in shader.data.vars ) {
+			switch( v.kind ) {
+			case Param:
+				var size = hxsl.Ast.Tools.size(v.type) * 4;
+				var g = device.createBindGroupLayout({ entries : [{
+					binding: 0,
+					visibility : kind,
+					buffer : {
+						type : Uniform,
+						hasDynamicOffset : false,
+						minBindingSize: size,
+					}
+				}]});
+				sh.paramsBufferSize = size;
+				sh.groups.push(g);
+			default:
+			}
+		}
+		return sh;
 	}
 	}
 
 
 	function makeShader( shader : hxsl.RuntimeShader ) {
 	function makeShader( shader : hxsl.RuntimeShader ) {
 		var sh = new WebGpuShader();
 		var sh = new WebGpuShader();
 		var format : Array<hxd.BufferFormat.BufferInput> = [];
 		var format : Array<hxd.BufferFormat.BufferInput> = [];
 		for( v in shader.vertex.data.vars ) {
 		for( v in shader.vertex.data.vars ) {
-			if( v.kind != Input ) continue;
-			var t = hxd.BufferFormat.InputFormat.fromHXSL(v.type);
-			format.push({ name : v.name, type : t });
+			switch( v.kind ) {
+			case Input:
+				var t = hxd.BufferFormat.InputFormat.fromHXSL(v.type);
+				format.push({ name : v.name, type : t });
+			default:
+			}
 		}
 		}
 		sh.format = hxd.BufferFormat.make(format);
 		sh.format = hxd.BufferFormat.make(format);
+		sh.vertex = compile(shader.vertex,VERTEX);
+		sh.fragment = compile(shader.fragment,FRAGMENT);
+		sh.layout = device.createPipelineLayout({ bindGroupLayouts: sh.vertex.groups.concat(sh.fragment.groups) });
 
 
-		var vertex = compile(shader.vertex);
-		var fragment = compile(shader.fragment);
-
-		var layout = device.createPipelineLayout({ bindGroupLayouts: [] });
 		var pipeline = device.createRenderPipeline({
 		var pipeline = device.createRenderPipeline({
-			layout : layout,
-			vertex : { module : vertex, entryPoint : "main", buffers : [
+			layout : sh.layout,
+			vertex : { module : sh.vertex.module, entryPoint : "main", buffers : [
 				{
 				{
 					attributes: [{ shaderLocation : 0, offset : 0, format : Float32x3 }],
 					attributes: [{ shaderLocation : 0, offset : 0, format : Float32x3 }],
 					arrayStride: 4 * 6,
 					arrayStride: 4 * 6,
@@ -311,7 +346,7 @@ class WebGpuDriver extends h3d.impl.Driver {
 					stepMode: GPUVertexStepMode.Vertex
 					stepMode: GPUVertexStepMode.Vertex
 				}
 				}
 			]},
 			]},
-			fragment : { module : fragment, entryPoint : "main", targets : [{ format : Bgra8unorm }] },
+			fragment : { module : sh.fragment.module, entryPoint : "main", targets : [{ format : Bgra8unorm }] },
 			primitive : { frontFace : CW, cullMode : None, topology : Triangle_list },
 			primitive : { frontFace : CW, cullMode : None, topology : Triangle_list },
 			depthStencil : {
 			depthStencil : {
 				depthWriteEnabled: true,
 				depthWriteEnabled: true,
@@ -344,6 +379,50 @@ class WebGpuDriver extends h3d.impl.Driver {
 			renderPass.setVertexBuffer(i, b.vbuf);
 			renderPass.setVertexBuffer(i, b.vbuf);
 	}
 	}
 
 
+	override function uploadShaderBuffers(buffers:h3d.shader.Buffers, which:h3d.shader.Buffers.BufferKind) {
+		_uploadShaderBuffers(buffers.vertex, which, currentShader.vertex);
+		_uploadShaderBuffers(buffers.fragment, which, currentShader.fragment);
+	}
+
+	function _uploadShaderBuffers(buffers:h3d.shader.Buffers.ShaderBuffers, which:h3d.shader.Buffers.BufferKind, sh:WebGpuSubShader) {
+		switch( which ) {
+		case Globals:
+			if( buffers.globals.length == 0 )
+				return;
+			throw "TODO";
+		case Params:
+			if( buffers.params.length == 0 )
+				return;
+			var flags = new haxe.EnumFlags();
+			var buffer = device.createBuffer({
+				size : sh.paramsBufferSize,
+				usage : UNIFORM,
+				mappedAtCreation : true,
+			});
+			var map = buffer.getMappedRange();
+			new js.lib.Float32Array(map).set(cast buffers.params);
+			buffer.unmap();
+			var group = device.createBindGroup({
+				layout : sh.groups[0],
+				entries: [{
+					binding: 0,
+					resource: {
+						buffer : buffer,
+					}
+				}],
+			});
+			renderPass.setBindGroup(0, group);
+		case Textures:
+			if( buffers.tex.length == 0 )
+				return;
+			throw "TODO";
+		case Buffers:
+			if( buffers.buffers == null || buffers.buffers.length == 0 )
+				return;
+			throw "TODO";
+		}
+	}
+
 	override function draw(ibuf:IndexBuffer, startIndex:Int, ntriangles:Int) {
 	override function draw(ibuf:IndexBuffer, startIndex:Int, ntriangles:Int) {
 		renderPass.setIndexBuffer(ibuf.buf, ibuf.stride==2?Uint16:Uint32, startIndex*ibuf.stride);
 		renderPass.setIndexBuffer(ibuf.buf, ibuf.stride==2?Uint16:Uint32, startIndex*ibuf.stride);
 		renderPass.drawIndexed(ntriangles*3);
 		renderPass.drawIndexed(ntriangles*3);

+ 11 - 23
hxsl/WgslOut.hx

@@ -74,13 +74,13 @@ class WgslOut {
 			}
 			}
 			add('>');
 			add('>');
 		case TMat2:
 		case TMat2:
-			add("float2x2");
+			add("mat2x2f");
 		case TMat3:
 		case TMat3:
-			add("float3x3");
+			add("mat3x3f");
 		case TMat4:
 		case TMat4:
-			add("float4x4");
+			add("mat4x4f");
 		case TMat3x4:
 		case TMat3x4:
-			add("float4x3");
+			add("mat3x4f");
 		case TSampler2D:
 		case TSampler2D:
 			add("Texture2D");
 			add("Texture2D");
 		case TSamplerCube:
 		case TSamplerCube:
@@ -97,15 +97,16 @@ class WgslOut {
 		case TFun(_):
 		case TFun(_):
 			add("fn ");
 			add("fn ");
 		case TArray(t, size), TBuffer(t,size):
 		case TArray(t, size), TBuffer(t,size):
+			add("array<");
 			addType(t);
 			addType(t);
-			add("[");
+			add(",");
 			switch( size ) {
 			switch( size ) {
 			case SVar(v):
 			case SVar(v):
 				ident(v);
 				ident(v);
 			case SConst(v):
 			case SConst(v):
 				add(v);
 				add(v);
 			}
 			}
-			add("]");
+			add(">");
 		case TChannel(n):
 		case TChannel(n):
 			add("channel" + n);
 			add("channel" + n);
 		}
 		}
@@ -121,20 +122,9 @@ class WgslOut {
 	}
 	}
 
 
 	function addVar( v : TVar ) {
 	function addVar( v : TVar ) {
-		switch( v.type ) {
-		case TArray(t, size), TBuffer(t,size):
-			addVar({
-				id : v.id,
-				name : v.name,
-				type : t,
-				kind : v.kind,
-			});
-			addArraySize(size);
-		default:
-			ident(v);
-			add(" : ");
-			addType(v.type);
-		}
+		ident(v);
+		add(" : ");
+		addType(v.type);
 	}
 	}
 
 
 	function addValue( e : TExpr, tabs : String ) {
 	function addValue( e : TExpr, tabs : String ) {
@@ -486,7 +476,6 @@ class WgslOut {
 
 
 		var textures = [];
 		var textures = [];
 		var buffers = [];
 		var buffers = [];
-		add('struct _params {\n');
 		for( v in s.vars )
 		for( v in s.vars )
 			if( v.kind == Param ) {
 			if( v.kind == Param ) {
 				switch( v.type ) {
 				switch( v.type ) {
@@ -502,11 +491,10 @@ class WgslOut {
 						continue;
 						continue;
 					}
 					}
 				}
 				}
-				add("\t");
+				add("@group(0) @binding(0) var<uniform> ");
 				addVar(v);
 				addVar(v);
 				add(";\n");
 				add(";\n");
 			}
 			}
-		add("};\n\n");
 
 
 		var bufCount = 0;
 		var bufCount = 0;
 		for( b in buffers ) {
 		for( b in buffers ) {