diff --git a/Source/WebGPU/WGSL/Overload.h b/Source/WebGPU/WGSL/Overload.h index bf4b5df3eeaa..3e226c212e65 100644 --- a/Source/WebGPU/WGSL/Overload.h +++ b/Source/WebGPU/WGSL/Overload.h @@ -45,8 +45,9 @@ struct TypeVariable { I32 = 1 << 3, U32 = 1 << 4, + ConcreteInteger = I32 | U32, AbstractInt = 1 << 5, - Integer = I32 | U32 | AbstractInt, + Integer = ConcreteInteger | AbstractInt, Number = Float | Integer, }; diff --git a/Source/WebGPU/WGSL/TypeDeclarations.rb b/Source/WebGPU/WGSL/TypeDeclarations.rb index 0f1f1e7f241d..4acde2bffdc2 100644 --- a/Source/WebGPU/WGSL/TypeDeclarations.rb +++ b/Source/WebGPU/WGSL/TypeDeclarations.rb @@ -11,3 +11,18 @@ [T < Float, C, R].(Matrix[T, C, R], Vector[T, C]) => Vector[T, R], [T < Float, C, R].(Vector[T, R], Matrix[T, C, R]) => Vector[T, C], } + +operator :textureSample, { + [].(Texture[F32, Texture1d], Sampler, F32) => Vector[F32, 4], + [].(Texture[F32, Texture2d], Sampler, Vector[F32, 2]) => Vector[F32, 4], + [].(Texture[F32, Texture2d], Sampler, Vector[F32, 2], Vector[I32, 2]) => Vector[F32, 4], + [T < ConcreteInteger].(Texture[F32, Texture2dArray], Sampler, Vector[F32, 2], T) => Vector[F32, 4], + [T < ConcreteInteger].(Texture[F32, Texture2dArray], Sampler, Vector[F32, 2], T, Vector[I32, 2]) => Vector[F32, 4], + [].(Texture[F32, Texture3d], Sampler, Vector[F32, 3]) => Vector[F32, 4], + [].(Texture[F32, TextureCube], Sampler, Vector[F32, 3]) => Vector[F32, 4], + [].(Texture[F32, Texture3d], Sampler, Vector[F32, 3], Vector[I32, 3]) => Vector[F32, 4], + [T < ConcreteInteger].(Texture[F32, TextureCubeArray], Sampler, Vector[F32, 3], T) => Vector[F32, 4], + + # FIXME: add overloads for texture_depth + # https://bugs.webkit.org/show_bug.cgi?id=254515 +} diff --git a/Source/WebGPU/WGSL/generator/main.rb b/Source/WebGPU/WGSL/generator/main.rb index 39edaf0a25f4..6207c3cc6854 100644 --- a/Source/WebGPU/WGSL/generator/main.rb +++ b/Source/WebGPU/WGSL/generator/main.rb @@ -75,6 +75,10 @@ def initialize(value) @value = value end + def to_s + value.to_s + end + def to_cpp "AbstractValue { #{value}u }" end @@ -88,7 +92,17 @@ def initialize(name) end def [](*arguments) - ParameterizedType.new(self, arguments) + # This is a bit hacky, but the idea is that types such as Vector can + # either become: + # 1) An AbstractType, if it receives a variable. This AbstractType will + # later be promoted to a concrete type once an overload is chosen. + # 2) A concrete type if it's given a concrete type. Since there are no + # variables involved, we can immediately construct a concrete type. + if arguments[0].is_a? Variable + ParameterizedAbstractType.new(self, arguments) + else + Constructor.new(@name.downcase)[*arguments] + end end def to_s @@ -96,6 +110,27 @@ def to_s end end +class Constructor + attr_reader :name, :arguments + + def initialize(name, arguments = nil) + @name = name + @arguments = arguments + end + + def [](*arguments) + return Constructor.new(@name, arguments) + end + + def to_s + "#{name.to_s}[#{arguments.map(&:to_s).join(", ")}]" + end + + def to_cpp + "AbstractType { m_types.#{name}Type(#{arguments.map { |a| a.respond_to? :to_cpp and a.to_cpp or a}.join ", "}) }" + end +end + class PrimitiveType attr_reader :name @@ -108,11 +143,11 @@ def to_s end def to_cpp - "AbstractType { m_types.#{name.downcase}Type() }" + "m_types.#{name.downcase}Type()" end end -class ParameterizedType +class ParameterizedAbstractType attr_reader :base, :arguments def initialize(base, arguments) @@ -229,10 +264,20 @@ def self.prologue Matrix = AbstractType.new(:Matrix) Array = AbstractType.new(:Array) + Texture = Constructor.new(:texture) + + Texture1d = Variable.new(:"Types::Texture::Kind::Texture1d", nil) + Texture2d = Variable.new(:"Types::Texture::Kind::Texture2d", nil) + Texture2dArray = Variable.new(:"Types::Texture::Kind::Texture2dArray", nil) + Texture3d = Variable.new(:"Types::Texture::Kind::Texture3d", nil) + TextureCube = Variable.new(:"Types::Texture::Kind::TextureCube", nil) + TextureCubeArray = Variable.new(:"Types::Texture::Kind::TextureCubeArray", nil) + Bool = PrimitiveType.new(:Bool) I32 = PrimitiveType.new(:I32) U32 = PrimitiveType.new(:U32) F32 = PrimitiveType.new(:F32) + Sampler = PrimitiveType.new(:Sampler) AbstractInt = PrimitiveType.new(:AbstractInt) @@ -243,6 +288,7 @@ def self.prologue Number = Constraint.new(:Number) Float = Constraint.new(:Float) + ConcreteInteger = Constraint.new(:ConcreteInteger) EOS end diff --git a/Source/WebGPU/WGSL/tests/valid/overload.wgsl b/Source/WebGPU/WGSL/tests/valid/overload.wgsl index 9523af099bac..aa769cb720c1 100644 --- a/Source/WebGPU/WGSL/tests/valid/overload.wgsl +++ b/Source/WebGPU/WGSL/tests/valid/overload.wgsl @@ -43,3 +43,59 @@ fn testMultiply() { let r1 = m * v2; let r2 = v4 * m; } + +fn testTextureSample() { + { + let t: texture_1d; + let s: sampler; + let r = textureSample(t, s, 1); + } + + { + let t: texture_2d; + let s: sampler; + let r = textureSample(t, s, vec2(0, 0)); + } + + { + let t: texture_2d; + let s: sampler; + let r = textureSample(t, s, vec2(0, 0), vec2(1, 1)); + } + + { + let t: texture_2d_array; + let s: sampler; + let r = textureSample(t, s, vec2(0, 0), 0); + } + + { + let t: texture_2d_array; + let s: sampler; + let r = textureSample(t, s, vec2(0, 0), 0, vec2(1, 1)); + } + + { + let t: texture_3d; + let s: sampler; + let r = textureSample(t, s, vec3(0, 0, 0)); + } + + { + let t: texture_cube; + let s: sampler; + let r = textureSample(t, s, vec3(0, 0, 0)); + } + + { + let t: texture_3d; + let s: sampler; + let r = textureSample(t, s, vec3(0, 0, 0), vec3(0, 0, 0)); + } + + { + let t: texture_cube_array; + let s: sampler; + let r = textureSample(t, s, vec3(0, 0, 0), 0); + } +}